enju_standalone_interface 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +3 -0
  3. data/Rakefile +35 -0
  4. data/app/assets/javascripts/enju_standalone_interface/application.js +15 -0
  5. data/app/assets/javascripts/enju_standalone_interface/batch_action.js +2 -0
  6. data/app/assets/stylesheets/enju_standalone_interface/application.css +13 -0
  7. data/app/assets/stylesheets/enju_standalone_interface/batch_action.css +4 -0
  8. data/app/controllers/application_controller.rb +4 -0
  9. data/app/controllers/batch_action_controller.rb +9 -0
  10. data/app/helpers/enju_standalone_interface/application_helper.rb +4 -0
  11. data/app/helpers/enju_standalone_interface/batch_action_helper.rb +4 -0
  12. data/app/views/enju_standalone_interface/batch_action/recept.html.erb +1 -0
  13. data/app/views/layouts/enju_standalone_interface/application.html.erb +14 -0
  14. data/config/routes.rb +3 -0
  15. data/lib/enju_standalone_interface.rb +233 -0
  16. data/lib/enju_standalone_interface/engine.rb +5 -0
  17. data/lib/enju_standalone_interface/version.rb +3 -0
  18. data/lib/tasks/enju_standalone_interface_tasks.rake +4 -0
  19. data/spec/controllers/enju_standalone_interface/batch_action_controller_spec.rb +21 -0
  20. data/spec/dummy/README.rdoc +261 -0
  21. data/spec/dummy/Rakefile +7 -0
  22. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  23. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  24. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  25. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  26. data/spec/dummy/app/helpers/users_helper.rb +36 -0
  27. data/spec/dummy/app/models/basket.rb +70 -0
  28. data/spec/dummy/app/models/carrier_type.rb +33 -0
  29. data/spec/dummy/app/models/checked_item.rb +177 -0
  30. data/spec/dummy/app/models/checkout.rb +307 -0
  31. data/spec/dummy/app/models/checkout_type.rb +33 -0
  32. data/spec/dummy/app/models/circulation_status.rb +23 -0
  33. data/spec/dummy/app/models/event.rb +124 -0
  34. data/spec/dummy/app/models/item.rb +1234 -0
  35. data/spec/dummy/app/models/item_has_use_restriction.rb +23 -0
  36. data/spec/dummy/app/models/lending_policy.rb +32 -0
  37. data/spec/dummy/app/models/library.rb +105 -0
  38. data/spec/dummy/app/models/library_group.rb +88 -0
  39. data/spec/dummy/app/models/manifestation.rb +698 -0
  40. data/spec/dummy/app/models/patron.rb +342 -0
  41. data/spec/dummy/app/models/role.rb +47 -0
  42. data/spec/dummy/app/models/shelf.rb +83 -0
  43. data/spec/dummy/app/models/use_restriction.rb +22 -0
  44. data/spec/dummy/app/models/user.rb +580 -0
  45. data/spec/dummy/app/models/user_group.rb +43 -0
  46. data/spec/dummy/app/models/user_group_has_checkout_type.rb +80 -0
  47. data/spec/dummy/app/models/user_has_role.rb +4 -0
  48. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  49. data/spec/dummy/config.ru +4 -0
  50. data/spec/dummy/config/application.rb +57 -0
  51. data/spec/dummy/config/boot.rb +10 -0
  52. data/spec/dummy/config/database.yml +25 -0
  53. data/spec/dummy/config/environment.rb +5 -0
  54. data/spec/dummy/config/environments/development.rb +37 -0
  55. data/spec/dummy/config/environments/production.rb +67 -0
  56. data/spec/dummy/config/environments/test.rb +37 -0
  57. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  58. data/spec/dummy/config/initializers/inflections.rb +15 -0
  59. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  60. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  61. data/spec/dummy/config/initializers/session_store.rb +8 -0
  62. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  63. data/spec/dummy/config/locales/en.yml +5 -0
  64. data/spec/dummy/config/locales/translation_en.yml +1724 -0
  65. data/spec/dummy/config/locales/validates_timeliness.en.yml +16 -0
  66. data/spec/dummy/config/routes.rb +4 -0
  67. data/spec/dummy/db/development.sqlite3 +0 -0
  68. data/spec/dummy/db/migrate/20120322223037_create_users.rb +71 -0
  69. data/spec/dummy/db/migrate/20120323053037_create_roles.rb +15 -0
  70. data/spec/dummy/db/migrate/20120323060718_create_user_has_roles.rb +10 -0
  71. data/spec/dummy/db/migrate/20120323062239_create_libraries.rb +37 -0
  72. data/spec/dummy/db/migrate/20120323063602_create_items.rb +33 -0
  73. data/spec/dummy/db/migrate/20120323064619_craete_circulation_statuses.rb +13 -0
  74. data/spec/dummy/db/migrate/20120323065157_craete_checkout_types.rb +13 -0
  75. data/spec/dummy/db/migrate/20120323070102_craete_shelves.rb +17 -0
  76. data/spec/dummy/db/migrate/20120323071616_craete_library_groups.rb +24 -0
  77. data/spec/dummy/db/migrate/20120323073022_craete_patrons.rb +72 -0
  78. data/spec/dummy/db/migrate/20120323141030_create_manifestations.rb +97 -0
  79. data/spec/dummy/db/migrate/20120323142330_create_carrier_types.rb +12 -0
  80. data/spec/dummy/db/migrate/20120324132708_create_baskets.rb +20 -0
  81. data/spec/dummy/db/migrate/20120324135409_checked_items.rb +16 -0
  82. data/spec/dummy/db/migrate/20120324141007_create_user_groups.rb +22 -0
  83. data/spec/dummy/db/migrate/20120324141950_create_user_group_has_checkout_type.rb +26 -0
  84. data/spec/dummy/db/migrate/20120324151951_create_lending_policies.rb +22 -0
  85. data/spec/dummy/db/migrate/20120324153756_create_use_restrictions.rb +15 -0
  86. data/spec/dummy/db/migrate/20120324154009_create_item_has_use_restrictions.rb +16 -0
  87. data/spec/dummy/db/migrate/20120324164815_create_checkouts.rb +26 -0
  88. data/spec/dummy/db/migrate/20120325160112_create_events.rb +23 -0
  89. data/spec/dummy/db/schema.rb +518 -0
  90. data/spec/dummy/db/test.sqlite3 +0 -0
  91. data/spec/dummy/lib/enju_leaf.rb +6 -0
  92. data/spec/dummy/lib/enju_leaf/master_model.rb +41 -0
  93. data/spec/dummy/lib/enju_leaf/url_validator.rb +10 -0
  94. data/spec/dummy/log/development.log +116 -0
  95. data/spec/dummy/log/test.log +17849 -0
  96. data/spec/dummy/public/404.html +26 -0
  97. data/spec/dummy/public/422.html +26 -0
  98. data/spec/dummy/public/500.html +25 -0
  99. data/spec/dummy/public/favicon.ico +0 -0
  100. data/spec/dummy/script/rails +6 -0
  101. data/spec/factories/item.rb +9 -0
  102. data/spec/factories/manifestation.rb +6 -0
  103. data/spec/factories/user.rb +27 -0
  104. data/spec/fixtures/carrier_types.yml +38 -0
  105. data/spec/fixtures/checkout_types.yml +34 -0
  106. data/spec/fixtures/circulation_statuses.yml +135 -0
  107. data/spec/fixtures/libraries.yml +40 -0
  108. data/spec/fixtures/roles.yml +21 -0
  109. data/spec/fixtures/shelves.yml +53 -0
  110. data/spec/fixtures/user_group_has_checkout_types.yml +14 -0
  111. data/spec/fixtures/user_groups.yml +7 -0
  112. data/spec/libs/enju_standalone_interface_spec.rb +133 -0
  113. data/spec/spec_helper.rb +36 -0
  114. metadata +358 -0
@@ -0,0 +1,23 @@
1
+ class ItemHasUseRestriction < ActiveRecord::Base
2
+ belongs_to :item, :validate => true
3
+ belongs_to :use_restriction, :validate => true
4
+
5
+ def self.per_page
6
+ 10
7
+ end
8
+
9
+ validates_associated :item, :use_restriction
10
+ validates_presence_of :item, :use_restriction
11
+ end
12
+
13
+ # == Schema Information
14
+ #
15
+ # Table name: item_has_use_restrictions
16
+ #
17
+ # id :integer not null, primary key
18
+ # item_id :integer not null
19
+ # use_restriction_id :integer not null
20
+ # created_at :datetime
21
+ # updated_at :datetime
22
+ #
23
+
@@ -0,0 +1,32 @@
1
+ class LendingPolicy < ActiveRecord::Base
2
+ default_scope :order => 'position'
3
+ belongs_to :item
4
+ belongs_to :user_group
5
+
6
+ validates_presence_of :item, :user_group
7
+ validates_uniqueness_of :user_group_id, :scope => :item_id
8
+
9
+ def self.per_page
10
+ 10
11
+ end
12
+
13
+ acts_as_list :scope => :item_id
14
+ end
15
+
16
+ # == Schema Information
17
+ #
18
+ # Table name: lending_policies
19
+ #
20
+ # id :integer not null, primary key
21
+ # item_id :integer not null
22
+ # user_group_id :integer not null
23
+ # loan_period :integer default(0), not null
24
+ # fixed_due_date :datetime
25
+ # renewal :integer default(0), not null
26
+ # fine :decimal(, ) default(0.0), not null
27
+ # note :text
28
+ # position :integer
29
+ # created_at :datetime
30
+ # updated_at :datetime
31
+ #
32
+
@@ -0,0 +1,105 @@
1
+ # -*- encoding: utf-8 -*-
2
+ class Library < ActiveRecord::Base
3
+ include MasterModel
4
+ default_scope :order => 'libraries.position'
5
+ scope :real, where('id != 1')
6
+ has_many :shelves, :order => 'shelves.position'
7
+ belongs_to :library_group, :validate => true
8
+ has_many :events, :include => :event_category
9
+ #belongs_to :holding_patron, :polymorphic => true, :validate => true
10
+ belongs_to :patron #, :validate => true
11
+ has_many :inter_library_loans, :foreign_key => 'borrowing_library_id'
12
+ has_many :users
13
+ belongs_to :country
14
+
15
+ validates_presence_of :short_display_name, :library_group, :patron
16
+ validates_uniqueness_of :short_display_name, :case_sensitive => false
17
+ validates :display_name, :uniqueness => true
18
+ validates :name, :format => {:with => /^[a-z][0-9a-z]{2,254}$/}
19
+
20
+ def self.all_cache
21
+ if Rails.env == 'production'
22
+ Rails.cache.fetch('library_all'){Library.all}
23
+ else
24
+ Library.all
25
+ end
26
+ end
27
+
28
+ def clear_all_cache
29
+ Rails.cache.delete('library_all')
30
+ end
31
+
32
+ def set_patron
33
+ self.patron = Patron.new(
34
+ :full_name => self.name
35
+ )
36
+ end
37
+
38
+ def create_shelf
39
+ Shelf.create!(:name => "#{self.name}_default", :library => self)
40
+ end
41
+
42
+ def closed?(date)
43
+ events.closing_days.collect{|c| c.start_at.beginning_of_day}.include?(date.beginning_of_day)
44
+ end
45
+
46
+ def web?
47
+ return true if self.id == 1
48
+ false
49
+ end
50
+
51
+ def self.web
52
+ Library.find(1)
53
+ end
54
+
55
+ def address(locale = I18n.locale)
56
+ case locale.to_sym
57
+ when :ja
58
+ "#{self.region.to_s.localize(locale)}#{self.locality.to_s.localize(locale)}#{self.street.to_s.localize(locale)}"
59
+ else
60
+ "#{self.street.to_s.localize(locale)} #{self.locality.to_s.localize(locale)} #{self.region.to_s.localize(locale)}"
61
+ end
62
+ rescue
63
+ nil
64
+ end
65
+
66
+ def address_changed?
67
+ return true if region_changed? or locality_changed? or street_changed?
68
+ false
69
+ end
70
+ end
71
+
72
+ # == Schema Information
73
+ #
74
+ # Table name: libraries
75
+ #
76
+ # id :integer not null, primary key
77
+ # patron_id :integer
78
+ # patron_type :string(255)
79
+ # name :string(255) not null
80
+ # display_name :text
81
+ # short_display_name :string(255) not null
82
+ # zip_code :string(255)
83
+ # street :text
84
+ # locality :text
85
+ # region :text
86
+ # telephone_number_1 :string(255)
87
+ # telephone_number_2 :string(255)
88
+ # fax_number :string(255)
89
+ # note :text
90
+ # call_number_rows :integer default(1), not null
91
+ # call_number_delimiter :string(255) default("|"), not null
92
+ # library_group_id :integer default(1), not null
93
+ # users_count :integer default(0), not null
94
+ # position :integer
95
+ # country_id :integer
96
+ # created_at :datetime
97
+ # updated_at :datetime
98
+ # deleted_at :datetime
99
+ # opening_hour :text
100
+ # latitude :float
101
+ # longitude :float
102
+ # calil_systemid :string(255)
103
+ # calil_neighborhood_systemid :text
104
+ #
105
+
@@ -0,0 +1,88 @@
1
+ # -*- encoding: utf-8 -*-
2
+ class LibraryGroup < ActiveRecord::Base
3
+ #include Singleton
4
+ #include Configurator
5
+ include MasterModel
6
+
7
+ has_many :libraries
8
+ has_many :search_engines
9
+ #has_many :news_feeds
10
+ belongs_to :country
11
+
12
+ validates :email, :format => {:with => /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\z/i}, :presence => true
13
+ validates :url, :presence => true, :url => true
14
+ after_save :clear_site_config_cache
15
+
16
+ def clear_site_config_cache
17
+ Rails.cache.delete('library_site_config')
18
+ end
19
+
20
+ def self.site_config
21
+ #if Rails.env == 'production'
22
+ # Rails.cache.fetch('library_site_config'){LibraryGroup.find(1)}
23
+ #else
24
+ LibraryGroup.find(1)
25
+ #end
26
+ rescue
27
+ nil
28
+ end
29
+
30
+ def self.system_name(locale = I18n.locale)
31
+ LibraryGroup.site_config.display_name.localize(locale)
32
+ end
33
+
34
+ def config?
35
+ true if self == LibraryGroup.site_config
36
+ end
37
+
38
+ def real_libraries
39
+ # 物理的な図書館 = IDが1以外
40
+ libraries.where('id != 1').all
41
+ end
42
+
43
+ def network_access_allowed?(ip_address, options = {})
44
+ options = {:network_type => 'lan'}.merge(options)
45
+ client_ip = IPAddr.new(ip_address)
46
+ case options[:network_type]
47
+ when 'admin'
48
+ allowed_networks = self.admin_networks.to_s.split
49
+ else
50
+ allowed_networks = self.my_networks.to_s.split
51
+ end
52
+ allowed_networks.each do |allowed_network|
53
+ begin
54
+ network = IPAddr.new(allowed_network)
55
+ return true if network.include?(client_ip)
56
+ rescue ArgumentError
57
+ nil
58
+ end
59
+ end
60
+ return false
61
+ end
62
+
63
+ end
64
+
65
+ # == Schema Information
66
+ #
67
+ # Table name: library_groups
68
+ #
69
+ # id :integer not null, primary key
70
+ # name :string(255) not null
71
+ # display_name :text
72
+ # short_name :string(255) not null
73
+ # email :string(255)
74
+ # my_networks :text
75
+ # use_dsbl :boolean default(FALSE), not null
76
+ # dsbl_list :text
77
+ # login_banner :text
78
+ # note :text
79
+ # post_to_union_catalog :boolean default(FALSE), not null
80
+ # country_id :integer
81
+ # created_at :datetime
82
+ # updated_at :datetime
83
+ # admin_networks :text
84
+ # allow_bookmark_external_url :boolean default(FALSE), not null
85
+ # position :integer
86
+ # url :string(255) default("http://localhost:3000/")
87
+ #
88
+
@@ -0,0 +1,698 @@
1
+ class Manifestation < ActiveRecord::Base
2
+ scope :periodical_master, where(:periodical_master => true)
3
+ scope :periodical_children, where(:periodical_master => false)
4
+ has_many :creates, :dependent => :destroy, :foreign_key => 'work_id'
5
+ has_many :creators, :through => :creates, :source => :patron
6
+ has_many :realizes, :dependent => :destroy, :foreign_key => 'expression_id'
7
+ has_many :contributors, :through => :realizes, :source => :patron
8
+ has_many :produces, :dependent => :destroy, :foreign_key => 'manifestation_id'
9
+ has_many :publishers, :through => :produces, :source => :patron
10
+ has_many :exemplifies, :foreign_key => 'manifestation_id'
11
+ has_many :items, :through => :exemplifies #, :foreign_key => 'manifestation_id'
12
+ has_many :children, :foreign_key => 'parent_id', :class_name => 'ManifestationRelationship', :dependent => :destroy
13
+ has_many :parents, :foreign_key => 'child_id', :class_name => 'ManifestationRelationship', :dependent => :destroy
14
+ has_many :derived_manifestations, :through => :children, :source => :child
15
+ has_many :original_manifestations, :through => :parents, :source => :parent
16
+ has_many :work_has_subjects, :foreign_key => 'work_id', :dependent => :destroy
17
+ has_many :subjects, :through => :work_has_subjects
18
+ has_many :bookmarks, :include => :tags, :dependent => :destroy, :foreign_key => :manifestation_id
19
+ has_many :users, :through => :bookmarks
20
+ has_many :reserves, :foreign_key => :manifestation_id, :order => :position
21
+ has_many :picture_files, :as => :picture_attachable, :dependent => :destroy
22
+ #belongs_to :language
23
+ belongs_to :carrier_type
24
+ belongs_to :content_type
25
+ has_one :series_has_manifestation
26
+ has_one :series_statement, :through => :series_has_manifestation
27
+ belongs_to :manifestation_relationship_type
28
+ belongs_to :frequency
29
+ belongs_to :required_role, :class_name => 'Role', :foreign_key => 'required_role_id', :validate => true
30
+ has_one :resource_import_result
31
+ has_many :purchase_requests
32
+ has_many :table_of_contents
33
+
34
+ def parent_of_series
35
+ original_manifestations
36
+ end
37
+
38
+ def next_reservation
39
+ self.reserves.not_retained.order('reserves.position ASC').first
40
+ end
41
+
42
+ def next_reserve
43
+ self.reserves.not_retained.order('reserves.position ASC').first
44
+ end
45
+
46
+ def serial?
47
+ if series_statement.try(:periodical) and !periodical_master
48
+ return true unless series_statement.initial_manifestation == self
49
+ end
50
+ false
51
+ end
52
+
53
+ def number_of_pages
54
+ if self.start_page and self.end_page
55
+ page = self.end_page.to_i - self.start_page.to_i + 1
56
+ end
57
+ end
58
+
59
+ def tags
60
+ if self.bookmarks.first
61
+ self.bookmarks.tag_counts
62
+ else
63
+ []
64
+ end
65
+ end
66
+
67
+ def titles
68
+ title = []
69
+ title << original_title.to_s.strip
70
+ title << title_transcription.to_s.strip
71
+ title << title_alternative.to_s.strip
72
+ #title << original_title.wakati
73
+ #title << title_transcription.wakati rescue nil
74
+ #title << title_alternative.wakati rescue nil
75
+ title
76
+ end
77
+
78
+ def url
79
+ #access_address
80
+ "#{LibraryGroup.site_config.url}#{self.class.to_s.tableize}/#{self.id}"
81
+ end
82
+
83
+ def available_checkout_types(user)
84
+ if user
85
+ user.user_group.user_group_has_checkout_types.available_for_carrier_type(self.carrier_type)
86
+ end
87
+ end
88
+
89
+ def new_serial?
90
+ return false unless self.serial?
91
+ unless self.serial_number.blank?
92
+ return true if self == self.series_statement.last_issue
93
+ else
94
+ return true if self == self.series_statement.last_issue_with_issue_number
95
+ end
96
+ end
97
+
98
+ def checkout_period(user)
99
+ if available_checkout_types(user)
100
+ available_checkout_types(user).collect(&:checkout_period).max || 0
101
+ end
102
+ end
103
+
104
+ def reservation_expired_period(user)
105
+ if available_checkout_types(user)
106
+ available_checkout_types(user).collect(&:reservation_expired_period).max || 0
107
+ end
108
+ end
109
+
110
+ def patrons
111
+ (creators + contributors + publishers).flatten
112
+ end
113
+
114
+ def bookmarked?(user)
115
+ self.users.include?(user)
116
+ end
117
+
118
+ def set_serial_number
119
+ if m = series_statement.try(:last_issue)
120
+ self.original_title = m.original_title
121
+ self.title_transcription = m.title_transcription
122
+ self.title_alternative = m.title_alternative
123
+ self.issn = m.issn
124
+ unless m.serial_number_string.blank?
125
+ self.serial_number_string = m.serial_number_string.to_i + 1
126
+ unless m.issue_number.blank?
127
+ # self.issue_number = m.issue_number.split.last.to_i + 1
128
+ self.issue_number = m.issue_number.last.to_i + 1
129
+ else
130
+ self.issue_number = m.issue_number
131
+ end
132
+ self.volume_number = m.volume_number
133
+ else
134
+ unless m.issue_number.blank?
135
+ # self.issue_number = m.issue_number.split.last.to_i + 1
136
+ self.issue_number = m.issue_number.last.to_i + 1
137
+ self.volume_number = m.volume_number_string
138
+ else
139
+ unless m.volume_number.blank?
140
+ # self.volume_number = m.volume_number.split.last.to_i + 1
141
+ self.volume_number = m.volume_number.last.to_i + 1
142
+ end
143
+ end
144
+ end
145
+ end
146
+ self
147
+ end
148
+
149
+ def set_new_serial_number
150
+ self.serial_number = self.serial_number_string.gsub(/\D/, "").to_i if self.serial_number_string rescue nil
151
+ end
152
+
153
+ def set_volume_issue_number
154
+ self.volume_number = self.volume_number_string.gsub(/\D/, "").to_i if self.volume_number_string rescue nil
155
+ self.issue_number = self.issue_number_string.gsub(/\D/, "").to_i if self.issue_number_string rescue nil
156
+ end
157
+
158
+ def reservable_with_item?(user = nil)
159
+ if SystemConfiguration.get("reserve.not_reserve_on_loan").nil?
160
+ return true
161
+ end
162
+ if SystemConfiguration.get("reserve.not_reserve_on_loan")
163
+ if user.try(:has_role?, 'Librarian')
164
+ return true
165
+ end
166
+ if items.index {|item| item.available_for_reserve_with_config? }
167
+ return true
168
+ else
169
+ return false
170
+ end
171
+ end
172
+ return true
173
+ end
174
+
175
+ def reservable?
176
+ unless SystemConfiguration.get("reserves.able_for_not_item")
177
+ return false if items.for_checkout.empty?
178
+ end
179
+ return false if self.periodical_master?
180
+ true
181
+ end
182
+
183
+ def is_reserved_by(user = nil)
184
+ if user
185
+ Reserve.waiting.where(:user_id => user.id, :manifestation_id => self.id).first
186
+ else
187
+ false
188
+ end
189
+ end
190
+
191
+ def is_reserved?
192
+ if self.reserves.present?
193
+ true
194
+ else
195
+ false
196
+ end
197
+ end
198
+
199
+ def checkouts(start_date, end_date)
200
+ Checkout.completed(start_date, end_date).where(:item_id => self.items.collect(&:id))
201
+ end
202
+
203
+ def creator
204
+ creators.collect(&:name).flatten
205
+ end
206
+
207
+ def contributor
208
+ contributors.collect(&:name).flatten
209
+ end
210
+
211
+ def publisher
212
+ publishers.collect(&:name).flatten
213
+ end
214
+
215
+ def title
216
+ titles
217
+ end
218
+
219
+ def hyphenated_isbn
220
+ ISBN_Tools.hyphenate(isbn)
221
+ end
222
+
223
+ # TODO: よりよい推薦方法
224
+ def self.pickup(keyword = nil)
225
+ return nil if self.cached_numdocs < 5
226
+ manifestation = nil
227
+ # TODO: ヒット件数が0件のキーワードがあるときに指摘する
228
+ response = Manifestation.search(:include => [:creators, :contributors, :publishers, :subjects, :items]) do
229
+ fulltext keyword if keyword
230
+ order_by(:random)
231
+ paginate :page => 1, :per_page => 1
232
+ end
233
+ manifestation = response.results.first
234
+ end
235
+
236
+ def set_digest(options = {:type => 'sha1'})
237
+ if attachment.queued_for_write[:original]
238
+ if File.exists?(attachment.queued_for_write[:original])
239
+ self.file_hash = Digest::SHA1.hexdigest(File.open(attachment.queued_for_write[:original].path, 'rb').read)
240
+ end
241
+ end
242
+ end
243
+
244
+ def extract_text
245
+ return nil unless attachment.path
246
+ # TODO: S3 support
247
+ response = `curl "#{Sunspot.config.solr.url}/update/extract?&extractOnly=true&wt=ruby" --data-binary @#{attachment.path} -H "Content-type:text/html"`
248
+ self.fulltext = eval(response)[""]
249
+ save(:validate => false)
250
+ end
251
+
252
+ def created(patron)
253
+ creates.where(:patron_id => patron.id).first
254
+ end
255
+
256
+ def realized(patron)
257
+ realizes.where(:patron_id => patron.id).first
258
+ end
259
+
260
+ def produced(patron)
261
+ produces.where(:patron_id => patron.id).first
262
+ end
263
+
264
+ def sort_title
265
+ NKF.nkf('-w --katakana', title_transcription) if title_transcription
266
+ end
267
+
268
+ def classifications
269
+ subjects.collect(&:classifications).flatten
270
+ end
271
+
272
+ def volume_number
273
+ volume_number_string.gsub(/\D/, ' ').split(" ") if volume_number_string
274
+ end
275
+
276
+ def issue_number
277
+ issue_number_string.gsub(/\D/, ' ').split(" ") if issue_number_string
278
+ end
279
+
280
+ def serial_number
281
+ serial_number_string.gsub(/\D/, ' ').split(" ") if serial_number_string
282
+ end
283
+
284
+ def questions(options = {})
285
+ id = self.id
286
+ options = {:page => 1, :per_page => Question.per_page}.merge(options)
287
+ page = options[:page]
288
+ per_page = options[:per_page]
289
+ user = options[:user]
290
+ Question.search do
291
+ with(:manifestation_id).equal_to id
292
+ any_of do
293
+ unless user.try(:has_role?, 'Librarian')
294
+ with(:shared).equal_to true
295
+ # with(:username).equal_to user.try(:username)
296
+ end
297
+ end
298
+ paginate :page => page, :per_page => per_page
299
+ end.results
300
+ end
301
+
302
+ def web_item
303
+ items.where(:shelf_id => Shelf.web.id).first
304
+ end
305
+
306
+ def self.find_by_isbn(isbn)
307
+ if ISBN_Tools.is_valid?(isbn)
308
+ ISBN_Tools.cleanup!(isbn)
309
+ if isbn.size == 10
310
+ Manifestation.where(:isbn => ISBN_Tools.isbn10_to_isbn13(isbn)).first || Manifestation.where(:isbn => isbn).first
311
+ else
312
+ Manifestation.where(:isbn => isbn).first || Manifestation.where(:isbn => ISBN_Tools.isbn13_to_isbn10(isbn)).first
313
+ end
314
+ end
315
+ end
316
+
317
+ def index_series_statement
318
+ series_statement.try(:index)
319
+ end
320
+
321
+ def acquired_at
322
+ items.order(:acquired_at).first.try(:acquired_at)
323
+ end
324
+
325
+ def set_series_statement
326
+ if self.series_statement_id
327
+ series_statement = SeriesStatement.find(self.series_statement_id)
328
+ self.series_statement = series_statement unless series_statement.blank?
329
+ end
330
+ end
331
+
332
+ def delete_attachment
333
+ @delete_attachment ||= "0"
334
+ end
335
+
336
+ def delete_attachment=(value)
337
+ @delete_attachment = value
338
+ end
339
+
340
+ def last_checkout_datetime
341
+ Manifestation.find(:last, :include => [:items, :items => :checkouts], :conditions => {:manifestations => {:id => self.id}}, :order => 'items.created_at DESC').items.first.checkouts.first.created_at rescue nil
342
+ end
343
+
344
+ def reserve_count(type)
345
+ sum = 0
346
+ case type
347
+ when nil
348
+ when :all
349
+ sum = Reserve.where(:manifestation_id=>self.id).count
350
+ when :previous_term
351
+ term = Term.previous_term
352
+ if term
353
+ sum = Reserve.where("manifestation_id = ? AND created_at >= ? AND created_at <= ?", self.id, term.start_at, term.end_at).count
354
+ end
355
+ when :current_term
356
+ term = Term.current_term
357
+ if term
358
+ sum = Reserve.where("manifestation_id = ? AND created_at >= ? AND created_at <= ?", self.id, term.start_at, term.end_at).count
359
+ end
360
+ end
361
+ return sum
362
+ end
363
+
364
+ def checkout_count(type)
365
+ sum = 0
366
+ case type
367
+ when nil
368
+ when :all
369
+ self.items.all.each {|item| sum += Checkout.where(:item_id=>item.id).count}
370
+ when :previous_term
371
+ term = Term.previous_term
372
+ if term
373
+ self.items.all.each {|item| sum += Checkout.where("item_id = ? AND created_at >= ? AND created_at <= ?", item.id, term.start_at, term.end_at).count }
374
+ end
375
+ when :current_term
376
+ term = Term.current_term
377
+ if term
378
+ self.items.all.each {|item| sum += Checkout.where("item_id = ? AND created_at >= ? AND created_at <= ?", item.id, term.start_at, term.end_at).count }
379
+ end
380
+ end
381
+ return sum
382
+ end
383
+
384
+ def next_item_for_retain(lib)
385
+ items = self.items_ordered_for_retain(lib)
386
+ items.each do |item|
387
+ return item if item.available_for_checkout? && item.circulation_status != CirculationStatus.find(:first, :conditions => ["name = ?", 'Available For Pickup'])
388
+ end
389
+ return nil
390
+ end
391
+
392
+ def items_ordered_for_retain(lib = nil)
393
+ if lib.nil?
394
+ items = self.items
395
+ else
396
+ items = self.items.for_retain_from_own(lib).concat(self.items.for_retain_from_others(lib)).flatten
397
+ end
398
+ end
399
+
400
+ def ordered?
401
+ self.purchase_requests.each do |p|
402
+ return true if p.state == "ordered"
403
+ end
404
+ return false
405
+ end
406
+
407
+ private
408
+ def delete_attachment?
409
+ self.attachment.clear if @delete_attachment == "1"
410
+ end
411
+
412
+ def self.get_manifestation_list_pdf(manifestations, current_user)
413
+ report = ThinReports::Report.new :layout => File.join(Rails.root, 'report', 'searchlist.tlf')
414
+
415
+ # set page_num
416
+ report.events.on :page_create do |e|
417
+ e.page.item(:page).value(e.page.no)
418
+ end
419
+ report.events.on :generate do |e|
420
+ e.pages.each do |page|
421
+ page.item(:total).value(e.report.page_count)
422
+ end
423
+ end
424
+
425
+ report.start_new_page do |page|
426
+ page.item(:date).value(Time.now)
427
+ manifestations.each do |manifestation|
428
+ page.list(:list).add_row do |row|
429
+ # modified data format
430
+ item_identifiers = manifestation.items.map{|item| item.item_identifier}
431
+ creator = manifestation.creators.readable_by(current_user).map{|patron| patron.full_name}
432
+ contributor = manifestation.contributors.readable_by(current_user).map{|patron| patron.full_name}
433
+ publisher = manifestation.publishers.readable_by(current_user).map{|patron| patron.full_name}
434
+ # set list
435
+ row.item(:title).value(manifestation.original_title)
436
+ row.item(:item_identifier).value(item_identifiers.join(','))
437
+ row.item(:creator).value(creator.join(','))
438
+ row.item(:contributor).value(contributor.join(','))
439
+ row.item(:publisher).value(publisher.join(','))
440
+ row.item(:pub_date).value(manifestation.pub_date)
441
+ row.item(:reserves_num).value(Reserve.waiting.where(:manifestation_id => manifestation.id, :checked_out_at => nil).count)
442
+ end
443
+ end
444
+ end
445
+ return report
446
+ end
447
+
448
+ def self.get_manifestation_list_tsv(manifestations, current_user)
449
+ data = String.new
450
+ data << "\xEF\xBB\xBF".force_encoding("UTF-8") + "\n"
451
+
452
+ columns = [
453
+ [:title, 'activerecord.attributes.manifestation.original_title'],
454
+ [:item_identifier, 'activerecord.attributes.item.item_identifier'],
455
+ [:creator, 'patron.creator'],
456
+ [:contributor, 'patron.contributor'],
457
+ [:publisher, 'patron.publisher'],
458
+ [:pub_date, 'activerecord.attributes.manifestation.pub_date'],
459
+ [:reserves_num, 'activerecord.attributes.manifestation.reserves_number']
460
+ ]
461
+
462
+ # title column
463
+ row = columns.map{|column| I18n.t(column[1])}
464
+ data << '"' + row.join("\"\t\"") +"\"\n"
465
+
466
+ manifestations.each do |manifestation|
467
+ row = []
468
+ columns.each do |column|
469
+ case column[0]
470
+ when :title
471
+ row << manifestation.original_title
472
+ when :item_identifier
473
+ item_identifiers = manifestation.items.map{|item| item.item_identifier}
474
+ row << item_identifiers.join(',')
475
+ when :creator
476
+ creator = manifestation.creators.readable_by(current_user).map{|patron| patron.full_name}
477
+ row << creator.join(',')
478
+ when :contributor
479
+ contributor = manifestation.contributors.readable_by(current_user).map{|patron| patron.full_name}
480
+ row << contributor.join(',')
481
+ when :publisher
482
+ publisher = manifestation.publishers.readable_by(current_user).map{|patron| patron.full_name}
483
+ row << publisher.join(',')
484
+ when :pub_date
485
+ row << manifestation.pub_date
486
+ when :reserves_num
487
+ row << Reserve.waiting.where(:manifestation_id => manifestation.id, :checked_out_at => nil).count
488
+ end
489
+ end
490
+ data << '"' + row.join("\"\t\"") +"\"\n"
491
+ end
492
+ return data
493
+ end
494
+
495
+ def self.get_manifestation_locate(manifestation, current_user)
496
+ report = ThinReports::Report.new :layout => File.join(Rails.root, 'report', 'manifestation.tlf')
497
+
498
+ # footer
499
+ report.layout.config.list(:list) do
500
+ use_stores :total => 0
501
+ events.on :footer_insert do |e|
502
+ e.section.item(:date).value(Time.now.strftime('%Y/%m/%d %H:%M'))
503
+ end
504
+ end
505
+ # main
506
+ report.start_new_page do |page|
507
+ # set manifestation_information
508
+ 7.times { |i|
509
+ label, data = "", ""
510
+ page.list(:list).add_row do |row|
511
+ case i
512
+ when 0
513
+ label = I18n.t('activerecord.attributes.manifestation.original_title')
514
+ data = manifestation.original_title
515
+ when 1
516
+ label = I18n.t('patron.creator')
517
+ data = manifestation.creators.readable_by(current_user).map{|patron| patron.full_name}
518
+ data = data.join(",")
519
+ when 2
520
+ label = I18n.t('patron.publisher')
521
+ data = manifestation.publishers.readable_by(current_user).map{|patron| patron.full_name}
522
+ data = data.join(",")
523
+ when 3
524
+ label = I18n.t('activerecord.attributes.manifestation.price')
525
+ data = manifestation.price
526
+ when 4
527
+ label = I18n.t('activerecord.attributes.manifestation.page')
528
+ data = manifestation.number_of_pages.to_s + 'p' if manifestation.number_of_pages
529
+ when 5
530
+ label = I18n.t('activerecord.attributes.manifestation.size')
531
+ data = manifestation.height.to_s + 'cm' if manifestation.height
532
+ when 6
533
+ label = I18n.t('activerecord.attributes.series_statement.original_title')
534
+ data = manifestation.series_statement.original_title if manifestation.series_statement
535
+ when 7
536
+ label = I18n.t('activerecord.attributes.manifestation.isbn')
537
+ data = manifestation.isbn
538
+ end
539
+ row.item(:label).show
540
+ row.item(:data).show
541
+ row.item(:dot_line).hide
542
+ row.item(:description).hide
543
+ row.item(:label).value(label.to_s + ":")
544
+ row.item(:data).value(data)
545
+ end
546
+ }
547
+
548
+ # set description
549
+ if manifestation.description
550
+ # make space
551
+ page.list(:list).add_row do |row|
552
+ row.item(:label).hide
553
+ row.item(:data).hide
554
+ row.item(:dot_line).hide
555
+ row.item(:description).hide
556
+ end
557
+ # set
558
+ max_column = 20
559
+ cnt, str_num = 0.0, 0
560
+ str = manifestation.description
561
+ while str.length > max_column
562
+ str.length.times do |i|
563
+ cnt += 0.5 if str[i] =~ /^[\s0-9A-Za-z]+$/
564
+ cnt += 1 unless str[i] =~ /^[\s0-9A-Za-z]+$/
565
+ if cnt.to_f >= max_column or str[i+1].nil? or str[i] =~ /^[\n]+$/
566
+ str_num = i + 1 if cnt.to_f == max_column or str[i+1].nil? or str[i] =~ /^[\n]+$/
567
+ str_num = i if cnt.to_f > max_column
568
+ page.list(:list).add_row do |row|
569
+ row.item(:label).hide
570
+ row.item(:data).hide
571
+ row.item(:dot_line).hide
572
+ row.item(:description).show
573
+ row.item(:description).value(str[0...str_num].chomp)
574
+ end
575
+ str = str[str_num...str.length]
576
+ cnt, str_num = 0.0, 0
577
+ break
578
+ end
579
+ end
580
+ end
581
+ page.list(:list).add_row do |row|
582
+ row.item(:label).hide
583
+ row.item(:data).hide
584
+ row.item(:dot_line).hide
585
+ row.item(:description).show
586
+ row.item(:description).value(str)
587
+ end
588
+ end
589
+
590
+ # set item_information
591
+ manifestation.items.each do |item|
592
+ 6.times { |i|
593
+ label, data = "", ""
594
+ page.list(:list).add_row do |row|
595
+ row.item(:label).show
596
+ row.item(:data).show
597
+ row.item(:dot_line).hide
598
+ row.item(:description).hide
599
+ case i
600
+ when 0
601
+ row.item(:label).hide
602
+ row.item(:data).hide
603
+ row.item(:dot_line).show
604
+ when 1
605
+ label = I18n.t('activerecord.models.library')
606
+ data = item.shelf.library.display_name.localize
607
+ when 2
608
+ label = I18n.t('activerecord.models.shelf')
609
+ data = item.shelf.display_name.localize
610
+ when 3
611
+ label = I18n.t('activerecord.attributes.item.call_number')
612
+ data = item.call_number
613
+ when 4
614
+ label = I18n.t('activerecord.attributes.item.item_identifier')
615
+ data = item.item_identifier
616
+ when 5
617
+ label = I18n.t('activerecord.models.circulation_status')
618
+ data = item.circulation_status.display_name.localize
619
+ end
620
+ row.item(:label).value(label.to_s + ":")
621
+ row.item(:data).value(data)
622
+ end
623
+ }
624
+ end
625
+ end
626
+ return report
627
+ end
628
+ end
629
+
630
+ # == Schema Information
631
+ #
632
+ # Table name: manifestations
633
+ #
634
+ # id :integer not null, primary key
635
+ # original_title :text not null
636
+ # title_alternative :text
637
+ # title_transcription :text
638
+ # classification_number :string(255)
639
+ # identifier :string(255)
640
+ # date_of_publication :datetime
641
+ # date_copyrighted :datetime
642
+ # created_at :datetime
643
+ # updated_at :datetime
644
+ # deleted_at :datetime
645
+ # access_address :string(255)
646
+ # language_id :integer default(1), not null
647
+ # carrier_type_id :integer default(1), not null
648
+ # extent_id :integer default(1), not null
649
+ # start_page :integer
650
+ # end_page :integer
651
+ # height :decimal(, )
652
+ # width :decimal(, )
653
+ # depth :decimal(, )
654
+ # isbn :string(255)
655
+ # isbn10 :string(255)
656
+ # wrong_isbn :string(255)
657
+ # nbn :string(255)
658
+ # lccn :string(255)
659
+ # oclc_number :string(255)
660
+ # issn :string(255)
661
+ # price :integer
662
+ # fulltext :text
663
+ # volume_number_string :string(255)
664
+ # issue_number_string :string(255)
665
+ # serial_number_string :string(255)
666
+ # edition :integer
667
+ # note :text
668
+ # produces_count :integer default(0), not null
669
+ # exemplifies_count :integer default(0), not null
670
+ # embodies_count :integer default(0), not null
671
+ # work_has_subjects_count :integer default(0), not null
672
+ # repository_content :boolean default(FALSE), not null
673
+ # lock_version :integer default(0), not null
674
+ # required_role_id :integer default(1), not null
675
+ # state :string(255)
676
+ # required_score :integer default(0), not null
677
+ # frequency_id :integer default(1), not null
678
+ # subscription_master :boolean default(FALSE), not null
679
+ # ipaper_id :integer
680
+ # ipaper_access_key :string(255)
681
+ # attachment_file_name :string(255)
682
+ # attachment_content_type :string(255)
683
+ # attachment_file_size :integer
684
+ # attachment_updated_at :datetime
685
+ # nii_type_id :integer
686
+ # title_alternative_transcription :text
687
+ # description :text
688
+ # abstract :text
689
+ # available_at :datetime
690
+ # valid_until :datetime
691
+ # date_submitted :datetime
692
+ # date_accepted :datetime
693
+ # date_caputured :datetime
694
+ # file_hash :string(255)
695
+ # pub_date :string(255)
696
+ # periodical_master :boolean default(FALSE), not null
697
+ #
698
+