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,196 +0,0 @@
1
- # Copyright (C) 2004-2006 Laurent Sansonetti
2
- # Copyright (C) 2011, 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.
13
- #
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.
18
-
19
- require 'thread'
20
-
21
- class Alexandria::ImportFilter
22
- def to_filefilter
23
- filefilter = Gtk::FileFilter.new
24
- filefilter.name = name
25
- patterns.each { |x| filefilter.add_pattern(x) }
26
- filefilter
27
- end
28
- end
29
-
30
- module Alexandria
31
- module UI
32
- class SkipEntryDialog < AlertDialog
33
- include GetText
34
- GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: 'UTF-8')
35
-
36
- def initialize(parent, message)
37
- super(parent, _('Error while importing'),
38
- Gtk::Stock::DIALOG_QUESTION,
39
- [[Gtk::Stock::CANCEL, :cancel],
40
- [_('_Continue'), :ok]],
41
- message)
42
- puts "Opened SkipEntryDialog #{inspect}" if $DEBUG
43
- self.default_response = Gtk::ResponseType::CANCEL
44
- show_all && (@response = run)
45
- destroy
46
- end
47
-
48
- def continue?
49
- @response == :ok
50
- end
51
- end
52
-
53
- class ImportDialog < Gtk::FileChooserDialog
54
- include GetText
55
- include Logging
56
-
57
- GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: 'UTF-8')
58
-
59
- FILTERS = Alexandria::ImportFilter.all
60
-
61
- def initialize(parent)
62
- super()
63
- puts 'ImportDialog opened.' if $DEBUG
64
- @destroyed = false
65
- self.title = _('Import a Library')
66
- self.action = :open
67
- self.transient_for = parent
68
- # self.deletable = false
69
- running = false
70
- add_button(Gtk::Stock::HELP, :help)
71
- add_button(Gtk::Stock::CANCEL, :cancel)
72
- import_button = add_button(_('_Import'),
73
- :accept)
74
- import_button.sensitive = false
75
-
76
- signal_connect('destroy') {
77
- if running
78
- @destroyed = true
79
-
80
- else
81
- destroy
82
- end
83
- # self.destroy unless running
84
- }
85
-
86
- filters = {}
87
- FILTERS.each do |filter|
88
- filefilter = filter.to_filefilter
89
- add_filter(filefilter)
90
- puts "Added ImportFilter #{filefilter} -- #{filefilter.name}" if $DEBUG
91
- filters[filefilter] = filter
92
- end
93
-
94
- signal_connect('selection_changed') do
95
- import_button.sensitive = filename && File.file?(filename)
96
- end
97
-
98
- # before adding the (hidden) progress bar, we must re-set the
99
- # packing of the button box (currently packed at the end),
100
- # because the progressbar will be *after* the button box.
101
- buttonbox = child.children.last
102
- child.set_child_packing(buttonbox, pack_type: :start)
103
- child.reorder_child(buttonbox, 1)
104
-
105
- pbar = Gtk::ProgressBar.new
106
- pbar.show_text = true
107
- child.pack_start(pbar, expand: false)
108
-
109
- on_progress = proc do |fraction|
110
- begin
111
- pbar.show unless pbar.visible?
112
- pbar.fraction = fraction
113
- rescue
114
- # TODO: check if destroyed instead...
115
- end
116
- end
117
-
118
- on_error = proc do |message|
119
- SkipEntryDialog.new(parent, message).continue?
120
- end
121
-
122
- exec_queue = ExecutionQueue.new
123
-
124
- while !@destroyed &&
125
- ((response = run) != :cancel) &&
126
- (response != :delete_event)
127
-
128
- if response == :help
129
- Alexandria::UI.display_help(self, 'import-library')
130
- next
131
- end
132
- file = File.basename(filename, '.*')
133
- base = GLib.locale_to_utf8(file)
134
- new_library_name = Library.generate_new_name(
135
- Libraries.instance.all_libraries,
136
- base)
137
-
138
- filter = filters[self.filter]
139
- puts "Going forward with filter: #{filter.name}" if $DEBUG
140
- self.sensitive = false
141
-
142
- filter.on_iterate do |n, total|
143
- unless @destroyed
144
- fraction = n * 1.0 / total
145
- puts "#{inspect} fraction: #{fraction}" if $DEBUG
146
- exec_queue.call(on_progress, fraction)
147
- end
148
- end
149
-
150
- not_cancelled = true
151
- filter.on_error do |message|
152
- not_cancelled = exec_queue.sync_call(on_error, message)
153
- puts "#{inspect} cancel state: #{not_cancelled}" if $DEBUG
154
- end
155
-
156
- library = nil
157
- @bad_isbns = nil
158
- @failed_isbns = nil
159
- thread = Thread.start do
160
- begin
161
- library, @bad_isbns, @failed_isbns = filter.invoke(new_library_name,
162
- filename)
163
- rescue => ex
164
- trace = ex.backtrace.join("\n> ")
165
- log.error { "Import failed: #{ex.message} #{trace}" }
166
- end
167
- end
168
-
169
- while thread.alive? && !@destroyed
170
- # puts "Thread #{thread} still alive."
171
- running = true
172
- exec_queue.iterate
173
- Gtk.main_iteration_do(false)
174
- end
175
-
176
- unless @destroyed
177
- if library
178
- yield(library, @bad_isbns, @failed_isbns)
179
- break
180
- elsif not_cancelled
181
- puts "Raising ErrorDialog because not_cancelled is #{not_cancelled}" if $DEBUG
182
- ErrorDialog.new(parent,
183
- _("Couldn't import the library"),
184
- _('The format of the file you ' \
185
- 'provided is unknown. Please ' \
186
- 'retry with another file.'))
187
- end
188
- pbar.hide
189
- self.sensitive = true
190
- end
191
- end
192
- destroy unless @destroyed
193
- end
194
- end
195
- end
196
- end
@@ -1,85 +0,0 @@
1
- # Copyright (C) 2007 Joseph Method
2
- #
3
- # Alexandria is free software; you can redistribute it and/or
4
- # modify it under the terms of the GNU General Public License as
5
- # published by the Free Software Foundation; either version 2 of the
6
- # License, or (at your option) any later version.
7
- #
8
- # Alexandria is distributed in the hope that it will be useful,
9
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
- # General Public License for more details.
12
- #
13
- # You should have received a copy of the GNU General Public
14
- # License along with Alexandria; see the file COPYING. If not,
15
- # write to the Free Software Foundation, Inc., 51 Franklin Street,
16
- # Fifth Floor, Boston, MA 02110-1301 USA.
17
-
18
- module Alexandria
19
- module UI
20
- class ConflictWhileCopyingDialog < AlertDialog
21
- include GetText
22
- GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: 'UTF-8')
23
-
24
- def initialize(parent, library, book)
25
- super(parent,
26
- _("The book '%s' already exists in '%s'. Would you like " \
27
- 'to replace it?') % [book.title, library.name],
28
- Gtk::Stock::DIALOG_QUESTION,
29
- [[_('_Skip'), :cancel],
30
- [_('_Replace'), :ok]],
31
- _('If you replace the existing book, its contents will ' \
32
- 'be overwritten.'))
33
- self.default_response = Gtk::ResponseType::CANCEL
34
- show_all && (@response = run)
35
- destroy
36
- end
37
-
38
- def replace?
39
- @response == :ok
40
- end
41
- end
42
-
43
- class ReallyDeleteDialog < AlertDialog
44
- include GetText
45
- GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: 'UTF-8')
46
-
47
- def initialize(parent, library, books = nil)
48
- # Deleting a library.
49
- if books.nil?
50
- message = _("Are you sure you want to delete '%s'?") % library.name
51
- description = if library.is_a?(SmartLibrary) || library.empty?
52
- nil
53
- else
54
- n_('If you continue, %d book will be deleted.',
55
- 'If you continue, %d books will be deleted.',
56
- library.size) % library.size
57
- end
58
- # Deleting books.
59
- else
60
- message = if books.length == 1
61
- _("Are you sure you want to delete '%s' " \
62
- "from '%s'?") % [books.first.title, library.name]
63
- else
64
- _('Are you sure you want to delete the ' \
65
- "selected books from '%s'?") % library.name
66
- end
67
- description = nil
68
- end
69
-
70
- super(parent, message, Gtk::Stock::DIALOG_QUESTION,
71
- [[Gtk::Stock::CANCEL, :cancel],
72
- [Gtk::Stock::DELETE, :ok]],
73
- description)
74
-
75
- self.default_response = Gtk::ResponseType::CANCEL
76
- show_all && (@response = run)
77
- destroy
78
- end
79
-
80
- def ok?
81
- @response == :ok
82
- end
83
- end
84
- end
85
- end
@@ -1,154 +0,0 @@
1
- # Copyright (C) 2004-2006 Laurent Sansonetti
2
- # Copyright (C) 2011, 2014 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.
13
- #
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.
18
-
19
- module Alexandria
20
- module UI
21
- class NewBookDialogManual < BookPropertiesDialogBase
22
- include GetText
23
- extend GetText
24
- GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: 'UTF-8')
25
-
26
- TMP_COVER_FILE = File.join(Dir.tmpdir, 'tmp_cover')
27
- def initialize(parent, library, &on_add_cb)
28
- super(parent, TMP_COVER_FILE)
29
-
30
- @library = library
31
- @on_add_cb = on_add_cb
32
- FileUtils.rm_f(TMP_COVER_FILE)
33
-
34
- cancel_button = Gtk::Button.new(Gtk::Stock::CANCEL)
35
- cancel_button.signal_connect('clicked') { on_cancel }
36
- cancel_button.show
37
- @button_box << cancel_button
38
-
39
- add_button = Gtk::Button.new(Gtk::Stock::ADD)
40
- add_button.signal_connect('clicked') { on_add }
41
- add_button.show
42
- @button_box << add_button
43
-
44
- help_button = Gtk::Button.new(Gtk::Stock::HELP)
45
- help_button.signal_connect('clicked') { on_help }
46
- help_button.show
47
- @button_box << help_button
48
- @button_box.set_child_secondary(help_button, true)
49
-
50
- self.rating = Book::DEFAULT_RATING
51
- self.cover = Icons::BOOK_ICON
52
-
53
- on_title_changed
54
- end
55
-
56
- def on_title_changed
57
- title = @entry_title.text.strip
58
- begin
59
- @book_properties_dialog.title = if title.empty?
60
- _('Adding a Book')
61
- else
62
- _("Adding '%s'") % title
63
- end
64
- rescue
65
- raise "There's a problem with a book somewhere"
66
- end
67
- end
68
-
69
- private
70
-
71
- def on_cancel
72
- @book_properties_dialog.destroy
73
- end
74
-
75
- class AddError < StandardError
76
- end
77
-
78
- def on_add
79
- if (title = @entry_title.text.strip).empty?
80
- raise AddError, _('A title must be provided.')
81
- end
82
- isbn = nil
83
- if @entry_isbn.text != ''
84
- ary = @library.select { |book|
85
- book.ident == @entry_isbn.text
86
- }
87
- unless ary.empty?
88
- raise AddError, _('The EAN/ISBN you provided is already used in this library.')
89
- end
90
- isbn = begin
91
- Library.canonicalise_isbn(@entry_isbn.text)
92
- rescue Alexandria::Library::InvalidISBNError
93
- raise AddError, _("Couldn't validate the " \
94
- 'EAN/ISBN you provided. Make ' \
95
- 'sure it is written correcty, ' \
96
- 'and try again.')
97
- end
98
- end
99
- if (publisher = @entry_publisher.text.strip).empty?
100
- raise AddError, _('A publisher must be provided.')
101
- end
102
- publishing_year = @entry_publish_date.text.to_i
103
- # TODO: Get rid of this silly requirement
104
- if (edition = @entry_edition.text.strip).empty?
105
- raise AddError, _('A binding must be provided.')
106
- end
107
- authors = []
108
- @treeview_authors.model.each { |_m, _p, i| authors << i[0] }
109
- if authors.empty?
110
- raise AddError, _('At least one author must be ' \
111
- 'provided.')
112
- end
113
- book = Book.new(title, authors, isbn, publisher,
114
- publishing_year.zero? ? nil : publishing_year,
115
- edition)
116
- book.rating = @current_rating
117
- book.notes = @textview_notes.buffer.text
118
- book.loaned = @checkbutton_loaned.active?
119
- book.loaned_to = @entry_loaned_to.text
120
- # book.loaned_since = Time.at(@date_loaned_since.time)
121
- book.loaned_since = parse_date(@date_loaned_since.text)
122
- book.redd = @checkbutton_redd.active?
123
- book.own = @checkbutton_own.active?
124
- book.want = @checkbutton_want.active?
125
- book.tags = @entry_tags.text.split
126
- @library << book
127
- @library.save(book)
128
- if File.exist?(TMP_COVER_FILE) && !@delete_cover_file
129
- FileUtils.cp(TMP_COVER_FILE, @library.cover(book))
130
- end
131
- @on_add_cb.call(book)
132
- @book_properties_dialog.destroy
133
- rescue AddError => e
134
- ErrorDialog.new(@parent, _("Couldn't add the book"),
135
- e.message)
136
- end
137
-
138
- # COPIED from book_properties_dialog_base
139
- def parse_date(datestring)
140
- date_format = '%d/%m/%Y'
141
- begin
142
- d = Date.strptime(datestring, date_format)
143
- Time.gm(d.year, d.month, d.day)
144
- rescue
145
- nil
146
- end
147
- end
148
-
149
- def on_help
150
- Alexandria::UI.display_help(@preferences_dialog, 'add-book-manually')
151
- end
152
- end
153
- end
154
- end
@@ -1,74 +0,0 @@
1
- # Copyright (C) 2004-2006 Laurent Sansonetti
2
- # Copyright (C) 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.
13
- #
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.
18
-
19
- module Alexandria
20
- module UI
21
- class NewSmartLibraryDialog < SmartLibraryPropertiesDialogBase
22
- include GetText
23
- GetText.bindtextdomain(Alexandria::TEXTDOMAIN, charset: 'UTF-8')
24
-
25
- def initialize(parent)
26
- super(parent)
27
-
28
- add_buttons([Gtk::Stock::CANCEL, :cancel],
29
- [Gtk::Stock::NEW, :ok])
30
-
31
- self.title = _('New Smart Library')
32
- # FIXME: Should accept just :cancel
33
- self.default_response = Gtk::ResponseType::CANCEL
34
-
35
- show_all
36
- insert_new_rule
37
-
38
- while ((response = run) != :cancel) &&
39
- (response != :delete_event)
40
-
41
- if response == :help
42
- Alexandria::UI.display_help(self, 'new-smart-library')
43
- elsif response == :ok
44
- if user_confirms_possible_weirdnesses_before_saving?
45
- rules = smart_library_rules
46
- basename = smart_library_base_name(rules) || _('Smart Library')
47
- name = Library.generate_new_name(
48
- Libraries.instance.all_libraries,
49
- basename)
50
- library = SmartLibrary.new(name,
51
- rules,
52
- predicate_operator_rule)
53
- yield(library)
54
- break
55
- end
56
- end
57
- end
58
-
59
- destroy
60
- end
61
-
62
- private
63
-
64
- def smart_library_base_name(rules)
65
- if rules.length == 1
66
- value = rules.first.value
67
- if value.is_a?(String) && !value.strip.empty?
68
- return value
69
- end
70
- end
71
- end
72
- end
73
- end
74
- end