enju_standalone_interface 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+