alexandria-book-collection-manager 0.6.9.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (293) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rubocop.yml +68 -0
  4. data/.rubocop_todo.yml +200 -0
  5. data/CHANGELOG.md +23 -0
  6. data/COPYING +339 -0
  7. data/ChangeLog.0 +3598 -0
  8. data/Gemfile +9 -0
  9. data/INSTALL.rdoc +156 -0
  10. data/PACKAGING +36 -0
  11. data/README.md +88 -0
  12. data/RELEASE_CHECKLIST +18 -0
  13. data/Rakefile +264 -0
  14. data/TODO +24 -0
  15. data/alexandria-book-collection-manager.gemspec +35 -0
  16. data/alexandria.desktop.in +10 -0
  17. data/bin/alexandria +82 -0
  18. data/doc/AUTHORS +60 -0
  19. data/doc/BUGS +31 -0
  20. data/doc/FAQ +369 -0
  21. data/doc/HACKING +19 -0
  22. data/doc/NEWS +341 -0
  23. data/doc/alexandria.1 +120 -0
  24. data/doc/cuecat_support.rdoc +67 -0
  25. data/lib/alexandria.rb +85 -0
  26. data/lib/alexandria/about.rb +82 -0
  27. data/lib/alexandria/book_providers.rb +411 -0
  28. data/lib/alexandria/book_providers/adlibris.rb +235 -0
  29. data/lib/alexandria/book_providers/amazon_aws.rb +261 -0
  30. data/lib/alexandria/book_providers/amazon_ecs_util.rb +405 -0
  31. data/lib/alexandria/book_providers/barnes_and_noble.rb +229 -0
  32. data/lib/alexandria/book_providers/bol_it.rb +162 -0
  33. data/lib/alexandria/book_providers/deastore.rb +277 -0
  34. data/lib/alexandria/book_providers/douban.rb +135 -0
  35. data/lib/alexandria/book_providers/ibs_it.rb +149 -0
  36. data/lib/alexandria/book_providers/mcu.rb +177 -0
  37. data/lib/alexandria/book_providers/proxis.rb +205 -0
  38. data/lib/alexandria/book_providers/pseudomarc.rb +185 -0
  39. data/lib/alexandria/book_providers/renaud.rb +142 -0
  40. data/lib/alexandria/book_providers/siciliano.rb +271 -0
  41. data/lib/alexandria/book_providers/thalia.rb +197 -0
  42. data/lib/alexandria/book_providers/web.rb +59 -0
  43. data/lib/alexandria/book_providers/webster_it.rb +173 -0
  44. data/lib/alexandria/book_providers/worldcat.rb +251 -0
  45. data/lib/alexandria/book_providers/z3950.rb +422 -0
  46. data/lib/alexandria/config.rb +8 -0
  47. data/lib/alexandria/console.rb +31 -0
  48. data/lib/alexandria/execution_queue.rb +96 -0
  49. data/lib/alexandria/export_library.rb +536 -0
  50. data/lib/alexandria/import_library.rb +316 -0
  51. data/lib/alexandria/import_library_csv.rb +270 -0
  52. data/lib/alexandria/logging.rb +159 -0
  53. data/lib/alexandria/models/book.rb +72 -0
  54. data/lib/alexandria/models/library.rb +714 -0
  55. data/lib/alexandria/net.rb +53 -0
  56. data/lib/alexandria/preferences.rb +324 -0
  57. data/lib/alexandria/scanners.rb +42 -0
  58. data/lib/alexandria/scanners/cuecat.rb +118 -0
  59. data/lib/alexandria/scanners/keyboard.rb +57 -0
  60. data/lib/alexandria/smart_library.rb +525 -0
  61. data/lib/alexandria/ui.rb +53 -0
  62. data/lib/alexandria/ui/builder_base.rb +43 -0
  63. data/lib/alexandria/ui/callbacks.rb +389 -0
  64. data/lib/alexandria/ui/completion_models.rb +228 -0
  65. data/lib/alexandria/ui/dialogs/about_dialog.rb +59 -0
  66. data/lib/alexandria/ui/dialogs/acquire_dialog.rb +640 -0
  67. data/lib/alexandria/ui/dialogs/alert_dialog.rb +68 -0
  68. data/lib/alexandria/ui/dialogs/bad_isbns_dialog.rb +43 -0
  69. data/lib/alexandria/ui/dialogs/barcode_animation.rb +159 -0
  70. data/lib/alexandria/ui/dialogs/book_properties_dialog.rb +210 -0
  71. data/lib/alexandria/ui/dialogs/book_properties_dialog_base.rb +432 -0
  72. data/lib/alexandria/ui/dialogs/export_dialog.rb +172 -0
  73. data/lib/alexandria/ui/dialogs/import_dialog.rb +205 -0
  74. data/lib/alexandria/ui/dialogs/misc_dialogs.rb +85 -0
  75. data/lib/alexandria/ui/dialogs/new_book_dialog.rb +639 -0
  76. data/lib/alexandria/ui/dialogs/new_book_dialog_manual.rb +153 -0
  77. data/lib/alexandria/ui/dialogs/new_smart_library_dialog.rb +67 -0
  78. data/lib/alexandria/ui/dialogs/preferences_dialog.rb +587 -0
  79. data/lib/alexandria/ui/dialogs/smart_library_properties_dialog.rb +56 -0
  80. data/lib/alexandria/ui/dialogs/smart_library_properties_dialog_base.rb +432 -0
  81. data/lib/alexandria/ui/dndable.rb +81 -0
  82. data/lib/alexandria/ui/gtk_thread_help.rb +88 -0
  83. data/lib/alexandria/ui/icons.rb +100 -0
  84. data/lib/alexandria/ui/iconview.rb +91 -0
  85. data/lib/alexandria/ui/iconview_tooltips.rb +162 -0
  86. data/lib/alexandria/ui/init.rb +93 -0
  87. data/lib/alexandria/ui/libraries_combo.rb +75 -0
  88. data/lib/alexandria/ui/listview.rb +310 -0
  89. data/lib/alexandria/ui/main_app.rb +67 -0
  90. data/lib/alexandria/ui/multi_drag_treeview.rb +150 -0
  91. data/lib/alexandria/ui/sidepane.rb +194 -0
  92. data/lib/alexandria/ui/sound.rb +107 -0
  93. data/lib/alexandria/ui/ui_manager.rb +1308 -0
  94. data/lib/alexandria/undo_manager.rb +78 -0
  95. data/lib/alexandria/utils.rb +30 -0
  96. data/lib/alexandria/version.rb +24 -0
  97. data/lib/alexandria/web_themes.rb +75 -0
  98. data/misc/sounds/README +15 -0
  99. data/misc/sounds/bad_scan.csd +62 -0
  100. data/misc/sounds/good_scan.csd +61 -0
  101. data/misc/sounds/scanning.csd +46 -0
  102. data/po/ChangeLog +488 -0
  103. data/po/Makefile +44 -0
  104. data/po/README +29 -0
  105. data/po/commit-po +72 -0
  106. data/po/cs.po +1437 -0
  107. data/po/cy.po +1521 -0
  108. data/po/de.po +1400 -0
  109. data/po/el.po +1379 -0
  110. data/po/es.po +1376 -0
  111. data/po/fr.po +1420 -0
  112. data/po/ga.po +1359 -0
  113. data/po/gl.po +1397 -0
  114. data/po/it.po +1406 -0
  115. data/po/ja.po +1355 -0
  116. data/po/mk.po +1373 -0
  117. data/po/nb.po +1386 -0
  118. data/po/nl.po +1405 -0
  119. data/po/pl.po +1373 -0
  120. data/po/pt.po +1398 -0
  121. data/po/pt_BR.po +1409 -0
  122. data/po/ru.po +1372 -0
  123. data/po/sk.po +1380 -0
  124. data/po/sv.po +1402 -0
  125. data/po/uk.po +1423 -0
  126. data/po/zh_TW.po +1394 -0
  127. data/schemas/alexandria.schemas +300 -0
  128. data/share/alexandria/glade/acquire_dialog__builder.glade +201 -0
  129. data/share/alexandria/glade/book_properties_dialog__builder.glade +910 -0
  130. data/share/alexandria/glade/main_app__builder.glade +229 -0
  131. data/share/alexandria/glade/new_book_dialog__builder.glade +379 -0
  132. data/share/alexandria/glade/preferences_dialog__builder.glade +733 -0
  133. data/share/alexandria/icons/alexandria.png +0 -0
  134. data/share/alexandria/icons/alexandria_small.png +0 -0
  135. data/share/alexandria/icons/book.png +0 -0
  136. data/share/alexandria/icons/book_icon.png +0 -0
  137. data/share/alexandria/icons/book_small.png +0 -0
  138. data/share/alexandria/icons/cuecat.png +0 -0
  139. data/share/alexandria/icons/cuecat_inactive.png +0 -0
  140. data/share/alexandria/icons/favorite_tag.png +0 -0
  141. data/share/alexandria/icons/less.png +0 -0
  142. data/share/alexandria/icons/library.png +0 -0
  143. data/share/alexandria/icons/library_small.png +0 -0
  144. data/share/alexandria/icons/lookup.png +0 -0
  145. data/share/alexandria/icons/more.png +0 -0
  146. data/share/alexandria/icons/no_cover.png +0 -0
  147. data/share/alexandria/icons/smart_library.png +0 -0
  148. data/share/alexandria/icons/smart_library_small.png +0 -0
  149. data/share/alexandria/icons/star_set.png +0 -0
  150. data/share/alexandria/icons/star_unset.png +0 -0
  151. data/share/alexandria/icons/view_as_icons.png +0 -0
  152. data/share/alexandria/icons/view_as_list.png +0 -0
  153. data/share/alexandria/ui/menus.xml +91 -0
  154. data/share/alexandria/ui/popups.xml +91 -0
  155. data/share/alexandria/web-themes/clean/clean.css +85 -0
  156. data/share/alexandria/web-themes/clean/preview.jpg +0 -0
  157. data/share/alexandria/web-themes/list/list.css +105 -0
  158. data/share/alexandria/web-themes/list/preview.jpg +0 -0
  159. data/share/app-icon/16x16/alexandria.png +0 -0
  160. data/share/app-icon/16x16/alexandria.svg +263 -0
  161. data/share/app-icon/22x22/alexandria.png +0 -0
  162. data/share/app-icon/22x22/alexandria.svg +465 -0
  163. data/share/app-icon/24x24/alexandria.png +0 -0
  164. data/share/app-icon/32x32/alexandria.png +0 -0
  165. data/share/app-icon/32x32/alexandria.svg +813 -0
  166. data/share/app-icon/32x32/alexandria.xpm +241 -0
  167. data/share/app-icon/48x48/alexandria.png +0 -0
  168. data/share/app-icon/scalable/alexandria.svg +700 -0
  169. data/share/gnome/help/alexandria/C/about.xml +44 -0
  170. data/share/gnome/help/alexandria/C/adding-books.xml +339 -0
  171. data/share/gnome/help/alexandria/C/alexandria.xml +185 -0
  172. data/share/gnome/help/alexandria/C/bugs.xml +18 -0
  173. data/share/gnome/help/alexandria/C/editing-book-properties.xml +124 -0
  174. data/share/gnome/help/alexandria/C/exporting.xml +81 -0
  175. data/share/gnome/help/alexandria/C/figures/adding_books_acquire_from_scanner_process.png +0 -0
  176. data/share/gnome/help/alexandria/C/figures/adding_books_add_by_isbn.png +0 -0
  177. data/share/gnome/help/alexandria/C/figures/adding_books_isbn_import.png +0 -0
  178. data/share/gnome/help/alexandria/C/figures/adding_books_manual_details.png +0 -0
  179. data/share/gnome/help/alexandria/C/figures/adding_books_rename_library_after_import.png +0 -0
  180. data/share/gnome/help/alexandria/C/figures/adding_books_search_results.png +0 -0
  181. data/share/gnome/help/alexandria/C/figures/editing_book_properties_info.png +0 -0
  182. data/share/gnome/help/alexandria/C/figures/editing_book_properties_loaning.png +0 -0
  183. data/share/gnome/help/alexandria/C/figures/exporting_information_html.png +0 -0
  184. data/share/gnome/help/alexandria/C/figures/getting_started_first_launched.png +0 -0
  185. data/share/gnome/help/alexandria/C/figures/searching_filtering_views_list_view.png +0 -0
  186. data/share/gnome/help/alexandria/C/figures/searching_filtering_views_list_view_search.png +0 -0
  187. data/share/gnome/help/alexandria/C/figures/settings_providers_new_z3950.png +0 -0
  188. data/share/gnome/help/alexandria/C/figures/smart_libraries_new_smart_library.png +0 -0
  189. data/share/gnome/help/alexandria/C/figures/working_with_libraries_library_pane.png +0 -0
  190. data/share/gnome/help/alexandria/C/getting-started.xml +154 -0
  191. data/share/gnome/help/alexandria/C/gnu-fdl-1.2.xml +543 -0
  192. data/share/gnome/help/alexandria/C/introduction.xml +142 -0
  193. data/share/gnome/help/alexandria/C/searching.xml +90 -0
  194. data/share/gnome/help/alexandria/C/settings.xml +140 -0
  195. data/share/gnome/help/alexandria/C/smart-libraries.xml +160 -0
  196. data/share/gnome/help/alexandria/C/working-with-libraries.xml +76 -0
  197. data/share/gnome/help/alexandria/ChangeLog +99 -0
  198. data/share/gnome/help/alexandria/fr/alexandria.xml +2292 -0
  199. data/share/gnome/help/alexandria/fr/figures/alexandria_add_button.png +0 -0
  200. data/share/gnome/help/alexandria/fr/figures/alexandria_add_by_isbn_1.png +0 -0
  201. data/share/gnome/help/alexandria/fr/figures/alexandria_add_by_search_1.png +0 -0
  202. data/share/gnome/help/alexandria/fr/figures/alexandria_add_manually.png +0 -0
  203. data/share/gnome/help/alexandria/fr/figures/alexandria_add_z3950.png +0 -0
  204. data/share/gnome/help/alexandria/fr/figures/alexandria_close_button.png +0 -0
  205. data/share/gnome/help/alexandria/fr/figures/alexandria_edit_info.png +0 -0
  206. data/share/gnome/help/alexandria/fr/figures/alexandria_export_web_page.png +0 -0
  207. data/share/gnome/help/alexandria/fr/figures/alexandria_importing.png +0 -0
  208. data/share/gnome/help/alexandria/fr/figures/alexandria_library_pane.png +0 -0
  209. data/share/gnome/help/alexandria/fr/figures/alexandria_list_view.png +0 -0
  210. data/share/gnome/help/alexandria/fr/figures/alexandria_list_view_search.png +0 -0
  211. data/share/gnome/help/alexandria/fr/figures/alexandria_loaning.png +0 -0
  212. data/share/gnome/help/alexandria/fr/figures/alexandria_main_window.png +0 -0
  213. data/share/gnome/help/alexandria/fr/figures/alexandria_remove_button.png +0 -0
  214. data/share/gnome/help/alexandria/ja/about.xml +33 -0
  215. data/share/gnome/help/alexandria/ja/adding-books.xml +314 -0
  216. data/share/gnome/help/alexandria/ja/alexandria.xml +172 -0
  217. data/share/gnome/help/alexandria/ja/bugs.xml +11 -0
  218. data/share/gnome/help/alexandria/ja/editing-book-properties.xml +100 -0
  219. data/share/gnome/help/alexandria/ja/exporting.xml +98 -0
  220. data/share/gnome/help/alexandria/ja/figures/adding_books_acquire_from_scanner_process.png +0 -0
  221. data/share/gnome/help/alexandria/ja/figures/adding_books_add_by_isbn.png +0 -0
  222. data/share/gnome/help/alexandria/ja/figures/adding_books_isbn_import.png +0 -0
  223. data/share/gnome/help/alexandria/ja/figures/adding_books_manual_details.png +0 -0
  224. data/share/gnome/help/alexandria/ja/figures/adding_books_rename_library_after_import.png +0 -0
  225. data/share/gnome/help/alexandria/ja/figures/adding_books_search_results.png +0 -0
  226. data/share/gnome/help/alexandria/ja/figures/editing_book_properties_info.png +0 -0
  227. data/share/gnome/help/alexandria/ja/figures/editing_book_properties_loaning.png +0 -0
  228. data/share/gnome/help/alexandria/ja/figures/exporting_information_html.png +0 -0
  229. data/share/gnome/help/alexandria/ja/figures/getting_started_first_launched.png +0 -0
  230. data/share/gnome/help/alexandria/ja/figures/searching_filtering_views_list_view.png +0 -0
  231. data/share/gnome/help/alexandria/ja/figures/searching_filtering_views_list_view_search.png +0 -0
  232. data/share/gnome/help/alexandria/ja/figures/settings_providers_new_z3950.png +0 -0
  233. data/share/gnome/help/alexandria/ja/figures/smart_libraries_new_smart_library.png +0 -0
  234. data/share/gnome/help/alexandria/ja/figures/working_with_libraries_library_pane.png +0 -0
  235. data/share/gnome/help/alexandria/ja/getting-started.xml +144 -0
  236. data/share/gnome/help/alexandria/ja/gnu-fdl-1.2.xml +541 -0
  237. data/share/gnome/help/alexandria/ja/introduction.xml +134 -0
  238. data/share/gnome/help/alexandria/ja/searching.xml +104 -0
  239. data/share/gnome/help/alexandria/ja/settings.xml +129 -0
  240. data/share/gnome/help/alexandria/ja/smart-libraries.xml +140 -0
  241. data/share/gnome/help/alexandria/ja/working-with-libraries.xml +88 -0
  242. data/share/menu/alexandria +7 -0
  243. data/share/omf/alexandria/alexandria-C.omf.in +27 -0
  244. data/share/omf/alexandria/alexandria-fr.omf.in +30 -0
  245. data/share/sounds/alexandria/bad_scan.ogg +0 -0
  246. data/share/sounds/alexandria/bad_scan.wav +0 -0
  247. data/share/sounds/alexandria/good_scan.ogg +0 -0
  248. data/share/sounds/alexandria/good_scan.wav +0 -0
  249. data/share/sounds/alexandria/scanning.ogg +0 -0
  250. data/share/sounds/alexandria/scanning.wav +0 -0
  251. data/spec/alexandria/library_spec.rb +205 -0
  252. data/spec/alexandria/preferences_spec.rb +22 -0
  253. data/spec/alexandria/scanners/cuecat_spec.rb +68 -0
  254. data/spec/alexandria/smart_library_spec.rb +22 -0
  255. data/spec/alexandria/ui/dialogs_spec.rb +90 -0
  256. data/spec/alexandria/ui/iconview_spec.rb +27 -0
  257. data/spec/alexandria/ui/listview_spec.rb +28 -0
  258. data/spec/alexandria/ui/main_app_spec.rb +48 -0
  259. data/spec/alexandria/ui/sidepane_spec.rb +27 -0
  260. data/spec/alexandria/ui/ui_manager_spec.rb +26 -0
  261. data/spec/alexandria/ui/ui_utilities_spec.rb +60 -0
  262. data/spec/alexandria/utilities_spec.rb +50 -0
  263. data/spec/data/libraries/0.6.1-noisbn/My Library/0201398257.yaml +10 -0
  264. data/spec/data/libraries/0.6.1-noisbn/My Library/1565920007.yaml +10 -0
  265. data/spec/data/libraries/0.6.1/My Library/0192812173.yaml +9 -0
  266. data/spec/data/libraries/0.6.1/My Library/0201398257.cover +0 -0
  267. data/spec/data/libraries/0.6.1/My Library/0201398257.yaml +10 -0
  268. data/spec/data/libraries/0.6.1/My Library/1565920007.yaml +10 -0
  269. data/spec/data/libraries/0.6.2/My Library/9780140266146.cover +0 -0
  270. data/spec/data/libraries/0.6.2/My Library/9780140266146.yaml +16 -0
  271. data/spec/data/libraries/0.6.2/My Library/9780140278781.cover +0 -0
  272. data/spec/data/libraries/0.6.2/My Library/9780140278781.yaml +21 -0
  273. data/spec/data/libraries/0.6.2/My Library/9780571147168.cover +0 -0
  274. data/spec/data/libraries/0.6.2/My Library/9780571147168.yaml +20 -0
  275. data/spec/data/libraries/0.6.2/My Library/9780575079038.cover +0 -0
  276. data/spec/data/libraries/0.6.2/My Library/9780575079038.yaml +20 -0
  277. data/spec/data/libraries/0.6.2/My Library/9780755322800.cover +0 -0
  278. data/spec/data/libraries/0.6.2/My Library/9780755322800.yaml +20 -0
  279. data/spec/spec_helper.rb +46 -0
  280. data/tasks/rdoc.rake +6 -0
  281. data/tasks/setup.rb +30 -0
  282. data/tasks/spec.rake +29 -0
  283. data/tasks/test.rake +38 -0
  284. data/test/application_test.rb +39 -0
  285. data/test/book_test.rb +34 -0
  286. data/test/data/isbns.txt +3 -0
  287. data/test/isbn_test.rb +68 -0
  288. data/test/providers_test.rb +254 -0
  289. data/test/test_helper.rb +42 -0
  290. data/util/rake/fileinstall.rb +313 -0
  291. data/util/rake/gettextgenerate.rb +158 -0
  292. data/util/rake/omfgenerate.rb +79 -0
  293. metadata +452 -0
@@ -0,0 +1,53 @@
1
+ # Copyright (C) 2009 Cathal Mc Ginley
2
+ # Copyright (C) 2014 Matijs van Zuijlen
3
+ #
4
+ # This file is part of Alexandria.
5
+ #
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.
20
+
21
+ module Alexandria
22
+ class WWWAgent
23
+ def initialize
24
+ user_agent = "Ruby #{RUBY_VERSION} #{Alexandria::TITLE}/#{Alexandria::VERSION}"
25
+ @extra_request_headers = { 'User-Agent' => user_agent }
26
+ end
27
+
28
+ def self.transport
29
+ config = Alexandria::Preferences.instance.http_proxy_config
30
+ config ? Net::HTTP.Proxy(*config) : Net::HTTP
31
+ end
32
+
33
+ def get(url)
34
+ uri = URI.parse(url)
35
+ req = Net::HTTP::Get.new(uri.request_uri)
36
+ @extra_request_headers.each_pair do |header_name, value|
37
+ req.add_field(header_name, value)
38
+ end
39
+ res = WWWAgent.transport.start(uri.host, uri.port) {|http|
40
+ http.request(req)
41
+ }
42
+ res
43
+ end
44
+
45
+ def language=(lang)
46
+ @extra_request_headers['Accept-Language'] = lang.to_s
47
+ end
48
+
49
+ def user_agent=(agent_string)
50
+ @extra_request_headers['User-Agent'] = agent_string
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,324 @@
1
+ # Copyright (C) 2004-2006 Laurent Sansonetti
2
+ # Copyright (C) 2011 Cathal Mc Ginley
3
+ # Modifications Copyright (C) 2011 Matijs van Zuijlen
4
+ #
5
+ # Alexandria is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU General Public License as
7
+ # published by the Free Software Foundation; either version 2 of the
8
+ # License, or (at your option) any later version.
9
+ #
10
+ # Alexandria is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ # General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public
16
+ # License along with Alexandria; see the file COPYING. If not,
17
+ # write to the Free Software Foundation, Inc., 51 Franklin Street,
18
+ # Fifth Floor, Boston, MA 02110-1301 USA.
19
+
20
+ require 'singleton'
21
+ require 'set'
22
+ require 'alexandria/default_preferences'
23
+
24
+ module Alexandria
25
+ class Preferences
26
+ include Singleton
27
+ include Logging
28
+
29
+ APP_DIR = '/apps/alexandria'
30
+ HTTP_PROXY_DIR = '/system/http_proxy'
31
+ HTTP_PROXY_MODE = '/system/proxy/mode'
32
+ URL_HANDLERS_DIR = '/desktop/gnome/url-handlers'
33
+
34
+ GCONFTOOL = 'gconftool-2'
35
+
36
+ def initialize
37
+ @alexandria_settings = {}
38
+ @changed_settings = Set.new
39
+
40
+ @url_handlers_loaded = false
41
+ @http_command = nil
42
+ @mailto_command = nil
43
+
44
+ @http_proxy_loaded = false
45
+ @use_http_proxy = false
46
+ @proxy_host = nil
47
+ @proxy_port = nil
48
+ @proxy_user = nil
49
+ @proxy_password = nil
50
+
51
+ load_alexandria_settings
52
+ # load_system_settings
53
+ end
54
+
55
+ def www_browser
56
+ unless @url_handlers_loaded
57
+ load_url_handler_settings
58
+ end
59
+ puts @http_command
60
+ @http_command
61
+ end
62
+
63
+ def email_client
64
+ unless @url_handlers_loaded
65
+ load_url_handler_settings
66
+ end
67
+ puts @mailto_command
68
+ @mailto_command
69
+ end
70
+
71
+ def http_proxy_config
72
+ unless @http_proxy_loaded
73
+ load_http_proxy_settings
74
+ end
75
+ if @use_http_proxy && @proxy_host && @proxy_port
76
+ [@proxy_host, @proxy_port, @proxy_user, @proxy_password]
77
+ end
78
+ end
79
+
80
+ def save!
81
+ log.debug { 'preferences save!' }
82
+ @changed_settings.each do |variable_name|
83
+ log.debug { "saving preference #{variable_name} / #{@alexandria_settings[variable_name].class}" }
84
+ generic_save_setting(variable_name, @alexandria_settings[variable_name])
85
+ end
86
+ @changed_settings.clear
87
+ end
88
+
89
+ def method_missing(id, *args)
90
+ method = id.id2name
91
+ if (match = /(.*)=$/.match(method))
92
+ if args.length != 1
93
+ raise "Set method #{method} should be called with " \
94
+ "only one argument (was called with #{args.length})"
95
+ end
96
+ variable_name = match[1]
97
+ new_value = args.first
98
+ generic_setter(variable_name, new_value)
99
+ else
100
+ unless args.empty?
101
+ raise "Get method #{method} should be called " \
102
+ "without argument (was called with #{args.length})"
103
+ end
104
+ generic_getter(method)
105
+ end
106
+ end
107
+
108
+ def remove_preference(variable_name)
109
+ @alexandria_settings.delete(variable_name)
110
+ @changed_settings << variable_name
111
+ end
112
+
113
+ private
114
+
115
+ ##
116
+ ## GENERIC GETTER and SETTER CODE
117
+ ##
118
+
119
+ def generic_getter(variable_name)
120
+ value = @alexandria_settings[variable_name]
121
+ if value.nil?
122
+ value = DEFAULT_VALUES[variable_name]
123
+ unless value.nil?
124
+ @alexandria_settings[variable_name] = value
125
+ @changed_settings << variable_name
126
+ end
127
+ end
128
+ value
129
+ end
130
+
131
+ def generic_setter(variable_name, new_value)
132
+ if new_value.is_a?(Array)
133
+ # when setting array, first remove nil elements (fixing #9007)
134
+ new_value.compact!
135
+ end
136
+ old_value = @alexandria_settings[variable_name]
137
+ @alexandria_settings[variable_name] = new_value
138
+ unless new_value == old_value
139
+ @changed_settings << variable_name
140
+ end
141
+ end
142
+
143
+ def generic_save_setting(variable_name, new_value)
144
+ var_path = APP_DIR + '/' + variable_name
145
+ if new_value.is_a?(Array)
146
+ # when setting array, first remove nil elements (fixing #9007)
147
+ new_value.compact!
148
+ if new_value.empty?
149
+ exec_gconf_unset(variable_name)
150
+ else
151
+ # set list value
152
+ exec_gconf_set_list(var_path, new_value)
153
+ end
154
+ else
155
+ # set non-list value
156
+ if new_value.nil?
157
+ exec_gconf_unset(variable_name)
158
+ else
159
+ exec_gconf_set(var_path, new_value)
160
+ end
161
+ end
162
+ rescue => ex
163
+ log.debug { new_value.inspect }
164
+ log.error { "Could not set GConf setting #{variable_name} to value: #{new_value.inspect}" }
165
+ log << ex.message
166
+ log << ex
167
+ end
168
+
169
+ ##
170
+ ## GCONFTOOL SET and SET LIST and SET PAIR and UNSET
171
+ ##
172
+
173
+ def get_gconf_type(value)
174
+ if value.is_a?(String)
175
+ 'string'
176
+ elsif value.is_a?(Fixnum)
177
+ 'int'
178
+ elsif value.is_a?(TrueClass) || value.is_a?(FalseClass)
179
+ 'bool'
180
+ else
181
+ 'string'
182
+ end
183
+ end
184
+
185
+ def exec_gconf_set_list(var_path, new_list)
186
+ # NOTE we must check between list and pair...
187
+
188
+ list_type = get_gconf_type(new_list.first)
189
+ if list_type == 'int' && new_list.size == 2
190
+ # treat this as a pair of int
191
+ a = new_list[0]
192
+ b = new_list[1]
193
+ pair = "(#{a},#{b})"
194
+ `gconftool-2 --type pair --car-type int --cdr-type int --set #{var_path} "#{pair}"`
195
+ else
196
+ list = make_list_string(new_list)
197
+ `gconftool-2 --type list --list-type #{list_type} --set #{var_path} "#{list}"`
198
+ end
199
+ end
200
+
201
+ def make_list_string(list)
202
+ if get_gconf_type(list.first) == 'string'
203
+ list.map! { |x| x.gsub(/\"/, "\\\"") }
204
+ end
205
+ contents = list.join(',')
206
+ '[' + contents + ']'
207
+ end
208
+
209
+ def exec_gconf_set(var_path, new_value)
210
+ if /cols_width/ =~ var_path
211
+ puts new_value
212
+
213
+ # new_value = {}
214
+ end
215
+ type = get_gconf_type(new_value)
216
+ value_str = new_value
217
+ if new_value.is_a? String
218
+ new_value.gsub!(/\"/, "\\\"")
219
+ value_str = "\"#{new_value}\""
220
+ end
221
+ if /cols_width/ =~ var_path
222
+ puts value_str
223
+ end
224
+ `gconftool-2 --type #{type} --set #{var_path} #{value_str}`
225
+ end
226
+
227
+ def exec_gconf_unset(variable_name)
228
+ `#{GCONFTOOL} --unset #{APP_DIR + '/' + variable_name}`
229
+ end
230
+
231
+ ##
232
+ ## GCONFTOOL LOAD RECURSIVE...
233
+ ##
234
+
235
+ # Since the ruby library 'gconf2' is deprecated, we call the
236
+ # 'gconftool' executable. Doing so one --get at a time is slow,
237
+ # so we use --recursive-list to get everything at once.
238
+ def load_alexandria_settings
239
+ all_vals = `#{GCONFTOOL} --recursive-list #{APP_DIR}`
240
+ @alexandria_settings.merge!(gconftool_values_to_hash(all_vals))
241
+ end
242
+
243
+ # May be useful to pre-load these settings
244
+ def load_system_settings
245
+ load_url_handler_settingss
246
+ load_http_proxy_settings
247
+ end
248
+
249
+ # Called at most once, by #web_browser or #email_client
250
+ # TODO: Enforce this.
251
+ def load_url_handler_settings
252
+ # /desktop/gnome/url-handlers/http
253
+ http_handler_vars = `#{GCONFTOOL} --recursive-list #{URL_HANDLERS_DIR + '/http'}`
254
+ http_handler = gconftool_values_to_hash(http_handler_vars)
255
+ if http_handler['enabled']
256
+ @http_command = http_handler['command']
257
+ end
258
+
259
+ mailto_handler_vars = `#{GCONFTOOL} --recursive-list #{URL_HANDLERS_DIR + '/mailto'}`
260
+ mailto_handler = gconftool_values_to_hash(mailto_handler_vars)
261
+ if mailto_handler['enabled']
262
+ @mailto_command = mailto_handler['command']
263
+ end
264
+ @url_handlers_loaded = true
265
+ end
266
+
267
+ # Called at most once, by #http_proxy_config
268
+ # TODO: Enforce this.
269
+ def load_http_proxy_settings
270
+ http_proxy_vars = `#{GCONFTOOL} --recursive-list #{HTTP_PROXY_DIR}`
271
+ http_proxy = gconftool_values_to_hash(http_proxy_vars)
272
+ if http_proxy['use_http_proxy']
273
+ proxy_mode = `#{GCONFTOOL} --get #{HTTP_PROXY_MODE}`.chomp
274
+ if proxy_mode == 'manual'
275
+ @use_http_proxy = true
276
+ @proxy_host = http_proxy['host']
277
+ @proxy_port = http_proxy['port']
278
+ @proxy_user = http_proxy['authentication_user']
279
+ @proxy_password = http_proxy['authentication_n_password']
280
+ end
281
+ end
282
+ @http_proxy_loaded = true
283
+ end
284
+
285
+ # 'gconftool -R' returns keys and values, one per line, with one
286
+ # leading space, separated with " = " This method parses the keys
287
+ # and values (guessing the type of the value using the
288
+ # #discriminate method) and returns them in a Hash.
289
+ def gconftool_values_to_hash(all_vals)
290
+ hash = {}
291
+ vals = all_vals.split(/$/)
292
+ vals.each do |val|
293
+ if /([a-z_]+) = (.*)/ =~ val
294
+ hash[Regexp.last_match[1]] = discriminate(Regexp.last_match[2])
295
+ end
296
+ end
297
+ hash
298
+ end
299
+
300
+ # Make a judgement about the type of the settings we get back from
301
+ # gconftool. This is not fool-proof, but it *does* work for the
302
+ # range of values used by Alexandria.
303
+ def discriminate(value)
304
+ if value == 'true' # bool
305
+ return true
306
+ elsif value == 'false' # bool
307
+ return false
308
+ elsif value =~ /^[0-9]+$/ # int
309
+ return value.to_i
310
+ elsif value =~ /^\[(.*)\]$/ # list (assume of type String)
311
+ return Regexp.last_match[1].split(',')
312
+ elsif value =~ /^\((.*)\)$/ # pair (assume of type int)
313
+ begin
314
+ pair = Regexp.last_match[1].split(',')
315
+ return [discriminate(pair.first), discriminate(pair.last)]
316
+ rescue
317
+ return [0, 0]
318
+ end
319
+ else
320
+ return value # string
321
+ end
322
+ end
323
+ end
324
+ end
@@ -0,0 +1,42 @@
1
+ # Copyright (C) 2005-2006 Christopher Cyll
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
+ # Scanners should respond to name(), match?(data), and decode(data).
19
+ # They should add an instance of themselves to the Scanner Registry
20
+ # on module load.
21
+
22
+ module Alexandria
23
+ module Scanners
24
+ REGISTRY = []
25
+
26
+ def self.register scanner
27
+ REGISTRY.push(scanner)
28
+ end
29
+
30
+ def self.default_scanner
31
+ REGISTRY.first
32
+ end
33
+
34
+ def self.find_scanner name
35
+ REGISTRY.find { |scanner| scanner.name == name }
36
+ end
37
+
38
+ def each_scanner
39
+ REGISTRY.each { |scanner| yield scanner }
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,118 @@
1
+ # Copyright (C) 2005-2006 Christopher Cyll
2
+ # Modifications Copyright (C) 2011 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 'alexandria/scanners'
20
+
21
+ module Alexandria
22
+ module Scanners
23
+ class CueCat
24
+ include Alexandria::Logging
25
+
26
+ def name
27
+ 'CueCat'
28
+ end
29
+
30
+ def display_name
31
+ 'CueCat'
32
+ end
33
+
34
+ # Checks if data looks like cuecat input
35
+ def match?(data)
36
+ data.chomp!
37
+ return false if data[-1] != '.'
38
+ fields = data.split('.')
39
+ return false if fields.size != 4
40
+ return false if fields[2].size != 4
41
+ true
42
+ end
43
+
44
+ # Decodes CueCat input into ISBN
45
+ # The following code is adapted from Skip Rosebaugh's public
46
+ # domain perl implementation.
47
+ def decode(data)
48
+ data.chomp!
49
+ fields = data.split('.')
50
+ fields.shift # First part is gibberish
51
+ fields.shift # Second part is cuecat serial number
52
+ type, code = fields.map { |field| decode_field(field) }
53
+
54
+ if type == 'IB5'
55
+ type = 'IBN'
56
+ code = code[0, 13]
57
+ end
58
+
59
+ begin
60
+ if Library.valid_upc? code
61
+ isbn13 = Library.canonicalise_ean(code)
62
+ code = isbn13
63
+ type = 'IBN'
64
+ end
65
+ rescue
66
+ log.debug { "Cannot translate UPC (#{type}) code #{code} to ISBN" }
67
+ end
68
+
69
+ return code if type == 'IBN'
70
+
71
+ raise "Don't know how to handle type #{type} (barcode: #{code})"
72
+ end
73
+
74
+ private
75
+
76
+ def decode_field(encoded)
77
+ seq = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-'
78
+
79
+ chars = encoded.split(//)
80
+ values = chars.map { |c| seq.index(c) }
81
+
82
+ padding = pad(values)
83
+ result = calc(values)
84
+ result = result[0, result.length - padding]
85
+ result
86
+ end
87
+
88
+ def calc(values)
89
+ result = ''
90
+ while values.length > 0
91
+ num = ((values[0] << 6 | values[1]) << 6 | values[2]) << 6 | values[3]
92
+ result += ((num >> 16) ^ 67).chr
93
+ result += ((num >> 8 & 255) ^ 67).chr
94
+ result += ((num & 255) ^ 67).chr
95
+
96
+ values = values[4, values.length]
97
+ end
98
+ result
99
+ end
100
+
101
+ def pad(array)
102
+ length = array.length % 4
103
+
104
+ if length != 0
105
+ raise 'Error parsing CueCat input' if length == 1
106
+
107
+ length = 4 - length
108
+ length.times { array.push(0) }
109
+ end
110
+
111
+ length
112
+ end
113
+ end
114
+
115
+ # Register a cuecat scanner with the Scanner Registry
116
+ register CueCat.new
117
+ end
118
+ end