enju_library 0.2.0.beta.1 → 0.2.0.beta.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (175) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/concerns/enju_library/controller.rb +218 -0
  3. data/app/controllers/user_export_files_controller.rb +116 -0
  4. data/app/controllers/user_groups_controller.rb +118 -0
  5. data/app/controllers/user_import_files_controller.rb +129 -0
  6. data/app/controllers/user_import_results_controller.rb +57 -0
  7. data/app/mailers/notifier.rb +30 -0
  8. data/app/models/user_export_file.rb +67 -0
  9. data/app/models/user_export_file_state_machine.rb +15 -0
  10. data/app/models/user_export_file_transition.rb +20 -0
  11. data/app/models/user_group.rb +29 -0
  12. data/app/models/user_import_file.rb +352 -0
  13. data/app/models/user_import_file_state_machine.rb +19 -0
  14. data/app/models/user_import_file_transition.rb +20 -0
  15. data/app/models/user_import_result.rb +20 -0
  16. data/app/policies/user_export_file_policy.rb +21 -0
  17. data/app/policies/user_group_policy.rb +22 -0
  18. data/app/policies/user_import_file_policy.rb +21 -0
  19. data/app/policies/user_import_result_policy.rb +21 -0
  20. data/app/views/accepts/index.js.slim +3 -0
  21. data/app/views/libraries/_map.html+phone.slim +4 -0
  22. data/app/views/libraries/show.html+phone.slim +32 -0
  23. data/app/views/libraries/show.js.slim +3 -0
  24. data/app/views/shelves/show.html+phone.slim +33 -0
  25. data/app/views/user_export_files/_form.html.erb +12 -0
  26. data/app/views/user_export_files/edit.html.erb +6 -0
  27. data/app/views/user_export_files/index.html.erb +44 -0
  28. data/app/views/user_export_files/new.html.erb +16 -0
  29. data/app/views/user_export_files/show.html.erb +36 -0
  30. data/app/views/user_groups/_form.html.erb +40 -0
  31. data/app/views/user_groups/edit.html.erb +13 -0
  32. data/app/views/user_groups/index.html.erb +51 -0
  33. data/app/views/user_groups/new.html.erb +12 -0
  34. data/app/views/user_groups/show.html.erb +68 -0
  35. data/app/views/user_import_files/_form.html.erb +61 -0
  36. data/app/views/user_import_files/_results.html.erb +22 -0
  37. data/app/views/user_import_files/edit.html.erb +6 -0
  38. data/app/views/user_import_files/index.html.erb +45 -0
  39. data/app/views/user_import_files/new.html.erb +60 -0
  40. data/app/views/user_import_files/show.html.erb +85 -0
  41. data/app/views/user_import_results/_form.html.erb +29 -0
  42. data/app/views/user_import_results/_list.html.erb +22 -0
  43. data/app/views/user_import_results/_list_lines.html.erb +24 -0
  44. data/app/views/user_import_results/index.html.erb +25 -0
  45. data/app/views/user_import_results/index.txt.erb +3 -0
  46. data/app/views/user_import_results/show.html.erb +33 -0
  47. data/{spec/dummy/db → db}/migrate/077_create_user_groups.rb +0 -0
  48. data/{spec/dummy/db → db}/migrate/20110318183304_add_valid_period_for_new_user_to_user_group.rb +0 -0
  49. data/{spec/dummy/db → db}/migrate/20140110122216_create_user_import_files.rb +1 -1
  50. data/{spec/dummy/db → db}/migrate/20140110131010_create_user_import_results.rb +0 -0
  51. data/{spec/dummy/db → db}/migrate/20140524074813_create_user_import_file_transitions.rb +0 -0
  52. data/{spec/dummy/db → db}/migrate/20140628072217_add_user_encoding_to_user_import_file.rb +0 -0
  53. data/{spec/dummy/db → db}/migrate/20140709113413_create_user_export_files.rb +0 -0
  54. data/{spec/dummy/db → db}/migrate/20140709113905_create_user_export_file_transitions.rb +0 -0
  55. data/{spec/dummy/db → db}/migrate/20140720170714_add_default_library_id_to_user_import_file.rb +0 -0
  56. data/{spec/dummy/db → db}/migrate/20140720170735_add_default_user_group_id_to_user_import_file.rb +0 -0
  57. data/db/migrate/20150506105356_add_error_message_to_user_import_result.rb +5 -0
  58. data/db/migrate/20160610093229_add_html_snippet_to_library_group.rb +5 -0
  59. data/db/migrate/20160627232219_add_most_recent_to_user_import_file_transitions.rb +9 -0
  60. data/db/migrate/20160627232316_add_most_recent_to_user_export_file_transitions.rb +9 -0
  61. data/lib/enju_library/engine.rb +3 -1
  62. data/lib/enju_library/version.rb +1 -1
  63. data/spec/controllers/user_export_files_controller_spec.rb +296 -0
  64. data/spec/controllers/user_groups_controller_spec.rb +443 -0
  65. data/spec/controllers/user_import_files_controller_spec.rb +305 -0
  66. data/spec/controllers/user_import_results_controller_spec.rb +154 -0
  67. data/spec/dummy/app/controllers/application_controller.rb +2 -2
  68. data/spec/dummy/config/application.rb +0 -2
  69. data/spec/dummy/db/migrate/055_create_bookmarks.rb +22 -0
  70. data/spec/dummy/db/migrate/090_create_search_histories.rb +31 -0
  71. data/spec/dummy/db/migrate/20081212151614_create_bookmark_stats.rb +13 -0
  72. data/spec/dummy/db/migrate/20081212151820_create_bookmark_stat_has_manifestations.rb +13 -0
  73. data/spec/dummy/db/migrate/20100222124420_add_allow_bookmark_external_url_to_library_group.rb +9 -0
  74. data/spec/dummy/db/migrate/20100525171356_acts_as_taggable_on_migration.rb +30 -0
  75. data/spec/dummy/db/migrate/20100623173800_rename_search_history_version_to_sru_version.rb +9 -0
  76. data/spec/dummy/db/migrate/20111129044509_add_pickup_location_to_reserve.rb +6 -0
  77. data/spec/dummy/db/migrate/20120418121539_add_save_search_history_to_user.rb +5 -0
  78. data/spec/dummy/db/migrate/20140524135607_create_bookmark_stat_transitions.rb +18 -0
  79. data/spec/dummy/db/migrate/20140811132912_add_save_search_history_to_profile.rb +5 -0
  80. data/spec/dummy/db/migrate/20140812093836_add_share_bookmarks_to_profile.rb +5 -0
  81. data/spec/dummy/db/migrate/20150106001709_create_demands.rb +14 -0
  82. data/spec/dummy/db/migrate/20150421023923_create_identities.rb +15 -0
  83. data/spec/dummy/db/migrate/20151126005552_add_provider_to_identity.rb +5 -0
  84. data/spec/dummy/db/migrate/20160703184619_add_most_recent_to_reserve_transitions.rb +9 -0
  85. data/spec/dummy/db/migrate/20160703184650_add_most_recent_to_manifestation_checkout_stat_transitions.rb +9 -0
  86. data/spec/dummy/db/migrate/20160703184723_add_most_recent_to_manifestation_reserve_stat_transitions.rb +9 -0
  87. data/spec/dummy/db/migrate/20160703184747_add_most_recent_to_user_checkout_stat_transitions.rb +9 -0
  88. data/spec/dummy/db/migrate/20160703184805_add_most_recent_to_user_reserve_stat_transitions.rb +9 -0
  89. data/spec/dummy/db/migrate/20160703190209_add_foreign_key_on_manifestation_id_to_reserve.rb +5 -0
  90. data/spec/dummy/db/schema.rb +141 -6
  91. data/spec/dummy/db/test.sqlite3 +0 -0
  92. data/spec/dummy/private/system/user_export_files/user_exports/000/000/001/original/user_export_file_20160808-8463-13fk7qo.txt +8 -0
  93. data/spec/dummy/private/system/user_export_files/user_exports/000/000/001/original/user_export_file_20160808-8463-y41sj6.txt +8 -0
  94. data/spec/dummy/private/system/user_export_files/user_exports/000/000/001/original/user_export_file_20160808-8517-1tzre93.txt +8 -0
  95. data/spec/dummy/private/system/user_export_files/user_exports/000/000/001/original/user_export_file_20160808-8517-qait5x.txt +8 -0
  96. data/spec/dummy/private/system/user_export_files/user_exports/000/000/001/original/user_export_file_20160808-8605-17zb3sz.txt +8 -0
  97. data/spec/dummy/private/system/user_export_files/user_exports/000/000/001/original/user_export_file_20160808-8605-1bpp9w8.txt +8 -0
  98. data/spec/dummy/private/system/user_export_files/user_exports/000/000/003/original/user_export_file_20160808-10113-ycu8m8.txt +8 -0
  99. data/spec/dummy/private/system/user_export_files/user_exports/000/000/003/original/user_export_file_20160808-10296-1w0qa4q.txt +8 -0
  100. data/spec/dummy/private/system/user_export_files/user_exports/000/000/003/original/user_export_file_20160808-10532-3gf0e4.txt +8 -0
  101. data/spec/dummy/private/system/user_export_files/user_exports/000/000/003/original/user_export_file_20160808-10743-1986tss.txt +8 -0
  102. data/spec/dummy/private/system/user_export_files/user_exports/000/000/003/original/user_export_file_20160808-10850-131ca5h.txt +8 -0
  103. data/spec/dummy/private/system/user_export_files/user_exports/000/000/003/original/user_export_file_20160808-11057-lrwhh.txt +8 -0
  104. data/spec/dummy/private/system/user_export_files/user_exports/000/000/003/original/user_export_file_20160808-11201-1j3f8z4.txt +8 -0
  105. data/spec/dummy/private/system/user_export_files/user_exports/000/000/003/original/user_export_file_20160808-8698-1cv7l1l.txt +8 -0
  106. data/spec/dummy/private/system/user_export_files/user_exports/000/000/003/original/user_export_file_20160808-8788-1j021tn.txt +8 -0
  107. data/spec/dummy/private/system/user_export_files/user_exports/000/000/003/original/user_export_file_20160808-8964-10it3ay.txt +8 -0
  108. data/spec/dummy/private/system/user_export_files/user_exports/000/000/003/original/user_export_file_20160808-9184-ramwb2.txt +8 -0
  109. data/spec/dummy/private/system/user_export_files/user_exports/000/000/003/original/user_export_file_20160808-9381-1ltvlr5.txt +8 -0
  110. data/spec/dummy/private/system/user_export_files/user_exports/000/000/003/original/user_export_file_20160808-9568-1xno5kz.txt +8 -0
  111. data/spec/dummy/private/system/user_export_files/user_exports/000/000/003/original/user_export_file_20160808-9694-1xvbn9r.txt +8 -0
  112. data/spec/dummy/private/system/user_export_files/user_exports/000/000/003/original/user_export_file_20160808-9796-1s8wttm.txt +8 -0
  113. data/spec/dummy/private/system/user_export_files/user_exports/000/000/003/original/user_export_file_20160808-9976-os18dm.txt +8 -0
  114. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-10113-i50cx9.txt +8 -0
  115. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-10113-yfyk1q.txt +8 -0
  116. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-10296-mwlqee.txt +8 -0
  117. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-10296-q7cj81.txt +8 -0
  118. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-10532-11e6ke6.txt +8 -0
  119. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-10532-19zrpc6.txt +8 -0
  120. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-10743-126qknn.txt +8 -0
  121. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-10743-1yr9gk3.txt +8 -0
  122. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-10850-1h0ufaw.txt +8 -0
  123. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-10850-1j6rz0a.txt +8 -0
  124. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-11057-4u0q76.txt +8 -0
  125. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-11057-xkxnw0.txt +8 -0
  126. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-11201-1pbhweq.txt +8 -0
  127. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-11201-oe7c58.txt +8 -0
  128. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-8698-becrga.txt +8 -0
  129. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-8698-n6a7dl.txt +8 -0
  130. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-8788-kcq4ud.txt +8 -0
  131. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-8788-pk5u5w.txt +8 -0
  132. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-8964-1it6ent.txt +8 -0
  133. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-8964-sevvj9.txt +8 -0
  134. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-9184-1wya34t.txt +8 -0
  135. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-9184-53qr2e.txt +8 -0
  136. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-9381-18m5cay.txt +8 -0
  137. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-9381-1o6dbyx.txt +8 -0
  138. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-9568-1rg8mif.txt +8 -0
  139. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-9568-p2ibx2.txt +8 -0
  140. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-9694-1lpp5g6.txt +8 -0
  141. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-9694-1vbkp9i.txt +8 -0
  142. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-9796-4auzfe.txt +8 -0
  143. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-9796-is0c1e.txt +8 -0
  144. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-9976-1n5tevc.txt +8 -0
  145. data/spec/dummy/private/system/user_export_files/user_exports/000/000/004/original/user_export_file_20160808-9976-1ygxnz1.txt +8 -0
  146. data/spec/dummy/private/system/user_import_files/user_imports/000/000/001/original/user_import_file_sample.tsv +10 -0
  147. data/spec/dummy/private/system/user_import_files/user_imports/000/000/001/original/user_import_file_sample_long.tsv +15 -0
  148. data/spec/dummy/private/system/user_import_files/user_imports/000/000/001/original/user_update_file.tsv +4 -0
  149. data/spec/dummy/private/system/user_import_files/user_imports/000/000/001/original/user_update_file2.tsv +2 -0
  150. data/spec/dummy/private/system/user_import_files/user_imports/000/000/001/original/user_update_file3.tsv +2 -0
  151. data/spec/dummy/private/system/user_import_files/user_imports/000/000/001/original/user_update_file4.tsv +2 -0
  152. data/spec/dummy/private/system/user_import_files/user_imports/000/000/003/original/user_import_file_sample.tsv +10 -0
  153. data/spec/dummy/private/system/user_import_files/user_imports/000/000/003/original/user_import_file_sample_long.tsv +15 -0
  154. data/spec/dummy/private/system/user_import_files/user_imports/000/000/003/original/user_update_file.tsv +4 -0
  155. data/spec/dummy/private/system/user_import_files/user_imports/000/000/003/original/user_update_file2.tsv +2 -0
  156. data/spec/dummy/private/system/user_import_files/user_imports/000/000/003/original/user_update_file3.tsv +2 -0
  157. data/spec/dummy/private/system/user_import_files/user_imports/000/000/003/original/user_update_file4.tsv +2 -0
  158. data/spec/dummy/private/system/user_import_files/user_imports/000/000/004/original/user_delete_file.tsv +4 -0
  159. data/spec/factories/checkout.rb +9 -0
  160. data/spec/factories/user_group.rb +5 -0
  161. data/spec/fixtures/message_templates.yml +41 -20
  162. data/spec/fixtures/user_export_files.yml +25 -0
  163. data/spec/fixtures/user_groups.yml +19 -0
  164. data/spec/fixtures/user_import_files.yml +51 -0
  165. data/spec/fixtures/user_import_results.yml +26 -0
  166. data/spec/fixtures/user_reserve_stats.yml +2 -3
  167. data/spec/models/user_export_file_spec.rb +30 -0
  168. data/spec/models/user_group_spec.rb +37 -0
  169. data/spec/models/user_import_file_spec.rb +220 -0
  170. data/spec/models/user_import_result_spec.rb +20 -0
  171. data/spec/support/devise.rb +2 -2
  172. data/spec/views/user_export_files/new.html.erb_spec.rb +19 -0
  173. data/spec/views/user_import_results/index.html.erb_spec.rb +29 -0
  174. metadata +358 -30
  175. data/spec/dummy/tmp/cache/4AD/470/country_all +0 -0
@@ -0,0 +1,67 @@
1
+ class UserExportFile < ActiveRecord::Base
2
+ include Statesman::Adapters::ActiveRecordQueries
3
+ include ExportFile
4
+
5
+ if ENV['ENJU_STORAGE'] == 's3'
6
+ has_attached_file :user_export, storage: :s3,
7
+ s3_credentials: {
8
+ access_key: ENV['AWS_ACCESS_KEY_ID'],
9
+ secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
10
+ bucket: ENV['S3_BUCKET_NAME'],
11
+ s3_host_name: ENV['S3_HOST_NAME']
12
+ },
13
+ s3_permissions: :private
14
+ else
15
+ has_attached_file :user_export,
16
+ path: ":rails_root/private/system/:class/:attachment/:id_partition/:style/:filename"
17
+ end
18
+ validates_attachment_content_type :user_export, content_type: /\Atext\/plain\Z/
19
+
20
+ has_many :user_export_file_transitions
21
+
22
+ def state_machine
23
+ UserExportFileStateMachine.new(self, transition_class: UserExportFileTransition)
24
+ end
25
+
26
+ delegate :can_transition_to?, :transition_to!, :transition_to, :current_state,
27
+ to: :state_machine
28
+
29
+ # エクスポートの処理を実行します。
30
+ def export!
31
+ transition_to!(:started)
32
+ tempfile = Tempfile.new(['user_export_file_', '.txt'])
33
+ file = User.export(format: :txt)
34
+ tempfile.puts(file)
35
+ tempfile.close
36
+ self.user_export = File.new(tempfile.path, 'r')
37
+ if save
38
+ send_message
39
+ end
40
+ transition_to!(:completed)
41
+ rescue => e
42
+ transition_to!(:failed)
43
+ raise e
44
+ end
45
+
46
+ def self.transition_class
47
+ UserExportFileTransition
48
+ end
49
+
50
+ def self.initial_state
51
+ :pending
52
+ end
53
+ end
54
+
55
+ # == Schema Information
56
+ #
57
+ # Table name: user_export_files
58
+ #
59
+ # id :integer not null, primary key
60
+ # user_id :integer
61
+ # executed_at :datetime
62
+ # created_at :datetime
63
+ # updated_at :datetime
64
+ # user_export_id :string
65
+ # user_export_size :integer
66
+ # user_import_filename :string
67
+ #
@@ -0,0 +1,15 @@
1
+ class UserExportFileStateMachine
2
+ include Statesman::Machine
3
+
4
+ state :pending, initial: true
5
+ state :started
6
+ state :completed
7
+ state :failed
8
+
9
+ transition from: :pending, to: :started
10
+ transition from: :started, to: [:completed, :failed]
11
+
12
+ after_transition(from: :pending, to: :started) do |user_export_file|
13
+ user_export_file.update_column(:executed_at, Time.zone.now)
14
+ end
15
+ end
@@ -0,0 +1,20 @@
1
+ class UserExportFileTransition < ActiveRecord::Base
2
+ include Statesman::Adapters::ActiveRecordTransition
3
+
4
+
5
+ belongs_to :user_export_file, inverse_of: :user_export_file_transitions
6
+ #attr_accessible :to_state, :sort_key, :metadata
7
+ end
8
+
9
+ # == Schema Information
10
+ #
11
+ # Table name: user_export_file_transitions
12
+ #
13
+ # id :integer not null, primary key
14
+ # to_state :string
15
+ # metadata :text default({})
16
+ # sort_key :integer
17
+ # user_export_file_id :integer
18
+ # created_at :datetime
19
+ # updated_at :datetime
20
+ #
@@ -0,0 +1,29 @@
1
+ class UserGroup < ActiveRecord::Base
2
+ include MasterModel
3
+ has_many :profiles
4
+
5
+ validates_numericality_of :valid_period_for_new_user,
6
+ greater_than_or_equal_to: 0,
7
+ allow_blank: true
8
+
9
+ paginates_per 10
10
+ end
11
+
12
+ # == Schema Information
13
+ #
14
+ # Table name: user_groups
15
+ #
16
+ # id :integer not null, primary key
17
+ # name :string
18
+ # display_name :text
19
+ # note :text
20
+ # position :integer
21
+ # created_at :datetime
22
+ # updated_at :datetime
23
+ # deleted_at :datetime
24
+ # valid_period_for_new_user :integer default(0), not null
25
+ # expired_at :datetime
26
+ # number_of_day_to_notify_overdue :integer default(1), not null
27
+ # number_of_day_to_notify_due_date :integer default(7), not null
28
+ # number_of_time_to_notify_overdue :integer default(3), not null
29
+ #
@@ -0,0 +1,352 @@
1
+ class UserImportFile < ActiveRecord::Base
2
+ include Statesman::Adapters::ActiveRecordQueries
3
+ include ImportFile
4
+ default_scope {order('user_import_files.id DESC')}
5
+ scope :not_imported, -> { in_state(:pending) }
6
+ scope :stucked, -> { in_state(:pending).where('user_import_files.created_at < ?', 1.hour.ago) }
7
+
8
+ if ENV['ENJU_STORAGE'] == 's3'
9
+ has_attached_file :user_import, storage: :s3,
10
+ s3_credentials: {
11
+ access_key: ENV['AWS_ACCESS_KEY_ID'],
12
+ secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
13
+ bucket: ENV['S3_BUCKET_NAME'],
14
+ s3_host_name: ENV['S3_HOST_NAME']
15
+ },
16
+ s3_permissions: :private
17
+ else
18
+ has_attached_file :user_import,
19
+ path: ":rails_root/private/system/:class/:attachment/:id_partition/:style/:filename"
20
+ end
21
+ validates_attachment_content_type :user_import, content_type: [
22
+ 'text/csv',
23
+ 'text/plain',
24
+ 'text/tab-separated-values',
25
+ 'application/octet-stream',
26
+ 'application/vnd.ms-excel'
27
+ ]
28
+ validates_attachment_presence :user_import
29
+ belongs_to :user, validate: true
30
+ belongs_to :default_user_group, class_name: 'UserGroup'
31
+ belongs_to :default_library, class_name: 'Library'
32
+ has_many :user_import_results
33
+
34
+ has_many :user_import_file_transitions
35
+
36
+ attr_accessor :mode
37
+
38
+ def state_machine
39
+ UserImportFileStateMachine.new(self, transition_class: UserImportFileTransition)
40
+ end
41
+
42
+ delegate :can_transition_to?, :transition_to!, :transition_to, :current_state,
43
+ to: :state_machine
44
+
45
+ # 利用者情報をTSVファイルを用いて作成します。
46
+ def import
47
+ transition_to!(:started)
48
+ num = { user_imported: 0, user_found: 0, failed: 0, error: 0 }
49
+ rows = open_import_file(create_import_temp_file(user_import))
50
+ row_num = 1
51
+
52
+ field = rows.first
53
+ if [field['username']].reject{ |f| f.to_s.strip == "" }.empty?
54
+ raise "username column is not found"
55
+ end
56
+
57
+ rows.each do |row|
58
+ row_num += 1
59
+ import_result = UserImportResult.create!(
60
+ user_import_file_id: id, body: row.fields.join("\t")
61
+ )
62
+ next if row['dummy'].to_s.strip.present?
63
+
64
+ username = row['username']
65
+ new_user = User.where(username: username).first
66
+ if new_user
67
+ import_result.user = new_user
68
+ import_result.save
69
+ num[:user_found] += 1
70
+ else
71
+ new_user = User.new
72
+ new_user.role = Role.where(name: row['role']).first
73
+ if new_user.role
74
+ unless user.has_role?(new_user.role.name)
75
+ num[:failed] += 1
76
+ next
77
+ end
78
+ else
79
+ new_user.role = Role.find(2) # User
80
+ end
81
+ new_user.username = username
82
+ new_user.assign_attributes(set_user_params(row))
83
+ profile = Profile.new
84
+ profile.assign_attributes(set_profile_params(row))
85
+
86
+ Profile.transaction do
87
+ if new_user.valid? and profile.valid?
88
+ new_user.profile = profile
89
+ import_result.user = new_user
90
+ import_result.save!
91
+ num[:user_imported] += 1
92
+ else
93
+ error_message = "line #{row_num}: "
94
+ error_message += new_user.errors.full_messages.join(" ")
95
+ error_message += profile.errors.full_messages.join(" ")
96
+ import_result.error_message = error_message
97
+ import_result.save
98
+ num[:error] += 1
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ Sunspot.commit
105
+ rows.close
106
+ error_messages = user_import_results.order(:id).pluck(:error_message).compact
107
+ unless error_messages.empty?
108
+ self.error_message = '' if error_message.nil?
109
+ self.error_message += "\n"
110
+ self.error_message += error_messages.join("\n")
111
+ end
112
+ save
113
+ if num[:error] >= 1
114
+ transition_to!(:failed)
115
+ else
116
+ transition_to!(:completed)
117
+ end
118
+ send_message
119
+ num
120
+ rescue => e
121
+ transition_to!(:failed)
122
+ raise e
123
+ end
124
+
125
+ # 利用者情報をTSVファイルを用いて更新します。
126
+ def modify
127
+ transition_to!(:started)
128
+ num = { user_updated: 0, user_not_found: 0, failed: 0 }
129
+ rows = open_import_file(create_import_temp_file(user_import))
130
+ row_num = 1
131
+
132
+ field = rows.first
133
+ if [field['username']].reject{|f| f.to_s.strip == ""}.empty?
134
+ raise "username column is not found"
135
+ end
136
+
137
+ rows.each do |row|
138
+ row_num += 1
139
+ next if row['dummy'].to_s.strip.present?
140
+ import_result = UserImportResult.create!(
141
+ user_import_file_id: id, body: row.fields.join("\t")
142
+ )
143
+
144
+ username = row['username']
145
+ new_user = User.where(username: username).first
146
+ if new_user.try(:profile)
147
+ new_user.assign_attributes(set_user_params(row))
148
+ new_user.profile.assign_attributes(set_profile_params(row))
149
+ Profile.transaction do
150
+ if new_user.save and new_user.profile.save
151
+ num[:user_updated] += 1
152
+ import_result.user = new_user
153
+ import_result.save!
154
+ else
155
+ num[:failed] += 1
156
+ end
157
+ end
158
+ else
159
+ num[:user_not_found] += 1
160
+ end
161
+ end
162
+
163
+ rows.close
164
+ transition_to!(:completed)
165
+ Sunspot.commit
166
+ send_message
167
+ num
168
+ rescue => e
169
+ self.error_message = "line #{row_num}: #{e.message}"
170
+ save
171
+ transition_to!(:failed)
172
+ raise e
173
+ end
174
+
175
+ # 利用者情報をTSVファイルを用いて削除します。
176
+ def remove
177
+ transition_to!(:started)
178
+ row_num = 1
179
+ rows = open_import_file(create_import_temp_file(user_import))
180
+
181
+ field = rows.first
182
+ if [field['username']].reject{ |f| f.to_s.strip == "" }.empty?
183
+ raise "username column is not found"
184
+ end
185
+
186
+ rows.each do |row|
187
+ row_num += 1
188
+ username = row['username'].to_s.strip
189
+ remove_user = User.where(username: username).first
190
+ if remove_user.try(:deletable_by?, user)
191
+ UserImportFile.transaction do
192
+ remove_user.destroy
193
+ remove_user.profile.destroy
194
+ end
195
+ end
196
+ end
197
+ transition_to!(:completed)
198
+ send_message
199
+ rescue => e
200
+ self.error_message = "line #{row_num}: #{e.message}"
201
+ save
202
+ transition_to!(:failed)
203
+ raise e
204
+ end
205
+
206
+ private
207
+ def self.transition_class
208
+ UserImportFileTransition
209
+ end
210
+
211
+ def self.initial_state
212
+ :pending
213
+ end
214
+
215
+ # インポート作業用のファイルを読み込みます。
216
+ # @param [File] tempfile 作業用のファイル
217
+ def open_import_file(tempfile)
218
+ file = CSV.open(tempfile.path, 'r:utf-8', col_sep: "\t")
219
+ header_columns = %w(
220
+ username role email password user_group user_number expired_at
221
+ full_name full_name_transcription required_role locked
222
+ keyword_list note locale library dummy
223
+ )
224
+ if defined?(EnjuCirculation)
225
+ header_columns += %w(checkout_icalendar_token save_checkout_history)
226
+ end
227
+ if defined?(EnjuSearchLog)
228
+ header_columns += %w(save_search_history)
229
+ end
230
+ if defined?(EnjuBookmark)
231
+ header_columns += %w(share_bookmarks)
232
+ end
233
+
234
+ header = file.first
235
+ ignored_columns = header - header_columns
236
+ unless ignored_columns.empty?
237
+ self.error_message = I18n.t('import.following_column_were_ignored', column: ignored_columns.join(', '))
238
+ save!
239
+ end
240
+ rows = CSV.open(tempfile.path, 'r:utf-8', headers: header, col_sep: "\t")
241
+ UserImportResult.create!(user_import_file_id: id, body: header.join("\t"))
242
+ tempfile.close(true)
243
+ file.close
244
+ rows
245
+ end
246
+
247
+ # 未処理のインポート作業用のファイルを一括で処理します。
248
+ def self.import
249
+ UserImportFile.not_imported.each do |file|
250
+ file.import_start
251
+ end
252
+ rescue
253
+ Rails.logger.info "#{Time.zone.now} importing resources failed!"
254
+ end
255
+
256
+ private
257
+ # ユーザ情報のパラメータを設定します。
258
+ # @param [Hash] row 利用者情報のハッシュ
259
+ def set_user_params(row)
260
+ params = {}
261
+ params[:email] = row['email'] if row['email'].present?
262
+
263
+ if row['password'].present?
264
+ params[:password] = row['password']
265
+ else
266
+ params[:password] = Devise.friendly_token[0..7]
267
+ end
268
+
269
+ if %w(t true).include?(row['locked'].to_s.downcase.strip)
270
+ params[:locked] = '1'
271
+ end
272
+
273
+ params
274
+ end
275
+
276
+ # 利用者情報のパラメータを設定します。
277
+ # @param [Hash] row 利用者情報のハッシュ
278
+ def set_profile_params(row)
279
+ params = {}
280
+ user_group = UserGroup.where(name: row['user_group']).first
281
+ unless user_group
282
+ user_group = default_user_group
283
+ end
284
+ params[:user_group_id] = user_group.id if user_group
285
+
286
+ required_role = Role.where(name: row['required_role']).first
287
+ unless required_role
288
+ required_role = Role.where(name: 'Librarian').first
289
+ end
290
+ params[:required_role_id] = required_role.id if required_role
291
+
292
+ params[:user_number] = row['user_number'] if row['user_number']
293
+ params[:full_name] = row['full_name'] if row['full_name']
294
+ params[:full_name_transcription] = row['full_name_transcription'] if row['full_name_transcription']
295
+
296
+ if row['expired_at'].present?
297
+ params[:expired_at] = Time.zone.parse(row['expired_at']).end_of_day
298
+ end
299
+
300
+ if row['keyword_list'].present?
301
+ params[:keyword_list] = row['keyword_list'].split('//').join("\n")
302
+ end
303
+
304
+ params[:note] = row['note'] if row['note']
305
+
306
+ if I18n.available_locales.include?(row['locale'].to_s.to_sym)
307
+ params[:locale] = row['locale']
308
+ end
309
+
310
+ library = Library.where(name: row['library'].to_s.strip).first
311
+ unless library
312
+ library = default_library || Library.web
313
+ end
314
+ params[:library_id] = library.id if library
315
+
316
+ if defined?(EnjuCirculation)
317
+ params[:checkout_icalendar_token] = row['checkout_icalendar_token'] if row['checkout_icalendar_token'].present?
318
+ params[:save_checkout_history] = row['save_checkout_history'] if row['save_checkout_history'].present?
319
+ end
320
+ if defined?(EnjuSearchLog)
321
+ params[:save_search_history] = row['save_search_history'] if row['save_search_history'].present?
322
+ end
323
+ if defined?(EnjuBookmark)
324
+ params[:share_bookmarks] = row['share_bookmarks'] if row['share_bookmarks'].present?
325
+ end
326
+ params
327
+ end
328
+ end
329
+
330
+ # == Schema Information
331
+ #
332
+ # Table name: user_import_files
333
+ #
334
+ # id :integer not null, primary key
335
+ # user_id :integer
336
+ # note :text
337
+ # executed_at :datetime
338
+ # user_import_file_name :string
339
+ # user_import_content_type :string
340
+ # user_import_file_size :integer
341
+ # user_import_updated_at :datetime
342
+ # user_import_fingerprint :string
343
+ # edit_mode :string
344
+ # error_message :text
345
+ # created_at :datetime
346
+ # updated_at :datetime
347
+ # user_encoding :string
348
+ # default_library_id :integer
349
+ # default_user_group_id :integer
350
+ # user_import_id :string
351
+ # user_import_size :integer
352
+ #
@@ -0,0 +1,19 @@
1
+ class UserImportFileStateMachine
2
+ include Statesman::Machine
3
+
4
+ state :pending, initial: true
5
+ state :started
6
+ state :completed
7
+ state :failed
8
+
9
+ transition from: :pending, to: :started
10
+ transition from: :started, to: [:completed, :failed]
11
+
12
+ after_transition(from: :pending, to: :started) do |user_import_file|
13
+ user_import_file.update_column(:executed_at, Time.zone.now)
14
+ end
15
+
16
+ before_transition(from: :started, to: :completed) do |user_import_file|
17
+ user_import_file.error_message = nil
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ class UserImportFileTransition < ActiveRecord::Base
2
+ include Statesman::Adapters::ActiveRecordTransition
3
+
4
+
5
+ belongs_to :user_import_file, inverse_of: :user_import_file_transitions
6
+ #attr_accessible :to_state, :sort_key, :metadata
7
+ end
8
+
9
+ # == Schema Information
10
+ #
11
+ # Table name: user_import_file_transitions
12
+ #
13
+ # id :integer not null, primary key
14
+ # to_state :string
15
+ # metadata :text default({})
16
+ # sort_key :integer
17
+ # user_import_file_id :integer
18
+ # created_at :datetime
19
+ # updated_at :datetime
20
+ #
@@ -0,0 +1,20 @@
1
+ class UserImportResult < ActiveRecord::Base
2
+ scope :file_id, proc{ |file_id| where(user_import_file_id: file_id) }
3
+ scope :failed, -> { where(user_id: nil) }
4
+
5
+ belongs_to :user_import_file
6
+ belongs_to :user
7
+ end
8
+
9
+ # == Schema Information
10
+ #
11
+ # Table name: user_import_results
12
+ #
13
+ # id :integer not null, primary key
14
+ # user_import_file_id :integer
15
+ # user_id :integer
16
+ # body :text
17
+ # created_at :datetime
18
+ # updated_at :datetime
19
+ # error_message :text
20
+ #
@@ -0,0 +1,21 @@
1
+ class UserExportFilePolicy < ApplicationPolicy
2
+ def index?
3
+ true if user.try(:has_role?, 'Administrator')
4
+ end
5
+
6
+ def show?
7
+ true if user.try(:has_role?, 'Administrator')
8
+ end
9
+
10
+ def create?
11
+ true if user.try(:has_role?, 'Administrator')
12
+ end
13
+
14
+ def update?
15
+ true if user.try(:has_role?, 'Administrator')
16
+ end
17
+
18
+ def destroy?
19
+ true if user.try(:has_role?, 'Administrator')
20
+ end
21
+ end
@@ -0,0 +1,22 @@
1
+ class UserGroupPolicy < ApplicationPolicy
2
+ def index?
3
+ true
4
+ end
5
+
6
+ def show?
7
+ true
8
+ end
9
+
10
+ def create?
11
+ true if user.try(:has_role?, 'Administrator')
12
+ end
13
+
14
+ def update?
15
+ true if user.try(:has_role?, 'Administrator')
16
+ end
17
+
18
+ def destroy?
19
+ return false unless record.profiles.empty?
20
+ user.try(:has_role?, 'Administrator')
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ class UserImportFilePolicy < ApplicationPolicy
2
+ def index?
3
+ true if user.try(:has_role?, 'Librarian')
4
+ end
5
+
6
+ def show?
7
+ true if user.try(:has_role?, 'Librarian')
8
+ end
9
+
10
+ def create?
11
+ true if user.try(:has_role?, 'Librarian')
12
+ end
13
+
14
+ def update?
15
+ true if user.try(:has_role?, 'Librarian')
16
+ end
17
+
18
+ def destroy?
19
+ true if user.try(:has_role?, 'Librarian')
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ class UserImportResultPolicy < ApplicationPolicy
2
+ def index?
3
+ true if user.try(:has_role?, 'Librarian')
4
+ end
5
+
6
+ def show?
7
+ true if user.try(:has_role?, 'Librarian')
8
+ end
9
+
10
+ def create?
11
+ false
12
+ end
13
+
14
+ def update?
15
+ false
16
+ end
17
+
18
+ def destroy?
19
+ false
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ | $("#accept_list").html("
2
+ = escape_javascript(render('accepts/list'))
3
+ | ");
@@ -0,0 +1,4 @@
1
+ script[type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"]
2
+ script[type="text/javascript"]
3
+ | google.maps.event.addDomListener(window, 'load', function() { var latlng = new google.maps.LatLng(<ruby code="= library.latitude"></ruby>, <ruby code="= library.longitude"></ruby>); var options = { zoom: 16, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP, scaleControl: true }; var map = new google.maps.Map(document.getElementById("library_map"), options); var marker = new google.maps.Marker({ position: latlng, map: map, title: '<ruby code="= library.display_name.localize"></ruby>' }); var infowindow = new google.maps.InfoWindow({ content: '<ruby code="= library.display_name.localize"></ruby>' }); google.maps.event.addListener(marker, 'click', function() { infowindow.open(map,marker); }); });
4
+ #library_map[style="width: 500px; height: 500px;"]
@@ -0,0 +1,32 @@
1
+ div[data-role="header"]
2
+ a.ui-btn-left[href="javascript:history.back()" data-icon="back" data-iconpos="notext"]
3
+ = t('page.back')
4
+ .panel-heading
5
+ = @library.display_name.localize
6
+ div[data-role="content"]
7
+ #detail
8
+ p
9
+ = t('activerecord.attributes.library.name')
10
+ | :
11
+ = @library.name
12
+ - unless @library.web?
13
+ p
14
+ = t('library.address')
15
+ | :
16
+ = @library.zip_code
17
+ = @library.address
18
+ br
19
+ = t('activerecord.attributes.library.telephone_number_1')
20
+ | :
21
+ = @library.telephone_number_1
22
+ = t('activerecord.attributes.library.telephone_number_2')
23
+ | :
24
+ = @library.telephone_number_2
25
+ br
26
+ = t('activerecord.attributes.library.fax_number')
27
+ | :
28
+ = @library.fax_number
29
+ p
30
+ = @library.opening_hour
31
+ p
32
+ = @library.note
@@ -0,0 +1,3 @@
1
+ | $("#library_calendar").html("
2
+ = escape_javascript(render("calendar"))
3
+ | ");