sufia 0.0.1.pre2 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (169) hide show
  1. data/Gemfile +2 -5
  2. data/README.md +44 -12
  3. data/app/assets/javascripts/{scholarsphere.js → sufia.js} +0 -0
  4. data/app/assets/stylesheets/{scholarsphere.css → sufia.css} +0 -0
  5. data/app/controllers/batch_controller.rb +2 -3
  6. data/app/controllers/batch_edits_controller.rb +4 -4
  7. data/app/controllers/dashboard_controller.rb +5 -3
  8. data/app/controllers/generic_files_controller.rb +77 -41
  9. data/app/controllers/users_controller.rb +9 -21
  10. data/app/helpers/blacklight/render_constraints_helper_behavior.rb +2 -2
  11. data/app/helpers/sufia_helper.rb +23 -2
  12. data/app/models/datastreams/file_content_datastream.rb +17 -9
  13. data/app/models/generic_file.rb +1 -809
  14. data/app/views/_add_assets_links.html.erb +1 -1
  15. data/app/views/_user_util_links.html.erb +2 -2
  16. data/app/views/batch/_metadata.html.erb +16 -16
  17. data/app/views/batch/edit.html.erb +16 -10
  18. data/app/views/batch_edits/_metadata.html.erb +16 -16
  19. data/app/views/catalog/_index_partials/_list_files.html.erb +2 -2
  20. data/app/views/catalog/index.html.erb +5 -0
  21. data/app/views/dashboard/_facet_limit.html.erb +1 -1
  22. data/app/views/dashboard/_facet_pagination.html.erb +4 -4
  23. data/app/views/dashboard/_facet_selected.html.erb +1 -1
  24. data/app/views/dashboard/_index_partials/_list_files.html.erb +8 -8
  25. data/app/views/dashboard/_search_form.html.erb +1 -1
  26. data/app/views/dashboard/_sort_and_per_page.html.erb +1 -1
  27. data/app/views/dashboard/index.html.erb +0 -1
  28. data/app/views/generic_files/_breadcrumbs.html.erb +1 -1
  29. data/app/views/generic_files/_descriptions.html.erb +3 -3
  30. data/app/views/generic_files/_field_form +3 -3
  31. data/app/views/generic_files/_media_display.html.erb +5 -4
  32. data/app/views/generic_files/_permission.html.erb +5 -5
  33. data/app/views/generic_files/_versioning.html.erb +1 -1
  34. data/app/views/generic_files/edit.html.erb +2 -2
  35. data/app/views/generic_files/show.html.erb +3 -3
  36. data/app/views/static/versions.html.erb +1 -1
  37. data/app/views/users/edit.html.erb +5 -3
  38. data/app/views/users/index.html.erb +3 -3
  39. data/app/views/users/show.html.erb +6 -6
  40. data/config/jetty.yml +6 -0
  41. data/config/routes.rb +8 -4
  42. data/features/browse_dashboard_files.feature +11 -1
  43. data/features/browse_files.feature +6 -5
  44. data/features/contact_form.feature +4 -0
  45. data/features/display_dashboard.feature +6 -3
  46. data/features/ingest_upload_files.feature +2 -2
  47. data/features/step_definitions/fixture_steps.rb +6 -5
  48. data/features/step_definitions/scholarsphere.rb +24 -1
  49. data/features/step_definitions/user_steps.rb +2 -2
  50. data/features/step_definitions/web_steps.rb +1 -1
  51. data/features/support/env.rb +26 -0
  52. data/features/users.feature +18 -0
  53. data/lib/active_support/core_ext/marshal.rb +22 -0
  54. data/lib/generators/sufia/sufia_generator.rb +18 -2
  55. data/lib/generators/sufia/templates/catalog_controller.rb +3 -4
  56. data/{spec/support → lib/generators/sufia/templates}/config/redis.yml +0 -0
  57. data/lib/generators/sufia/templates/config/sufia.rb +68 -0
  58. data/lib/generators/sufia/templates/migrations/add_ldap_attrs_to_user.rb +41 -0
  59. data/lib/kaminari/helpers/tag.rb +11 -0
  60. data/lib/sufia.rb +30 -7
  61. data/lib/sufia/controller.rb +1 -5
  62. data/lib/sufia/generic_file.rb +200 -0
  63. data/lib/sufia/generic_file/audit.rb +119 -0
  64. data/lib/sufia/generic_file/characterization.rb +82 -0
  65. data/lib/sufia/generic_file/export.rb +339 -0
  66. data/lib/sufia/generic_file/permissions.rb +64 -0
  67. data/lib/sufia/generic_file/thumbnail.rb +68 -0
  68. data/{app/models → lib/sufia/jobs}/audit_job.rb +13 -3
  69. data/lib/sufia/jobs/batch_update_job.rb +86 -0
  70. data/lib/sufia/jobs/characterize_job.rb +35 -0
  71. data/{app/models → lib/sufia/jobs}/content_delete_event_job.rb +3 -1
  72. data/{app/models → lib/sufia/jobs}/content_deposit_event_job.rb +1 -1
  73. data/{app/models → lib/sufia/jobs}/content_new_version_event_job.rb +1 -1
  74. data/{app/models → lib/sufia/jobs}/content_restored_version_event_job.rb +8 -0
  75. data/{app/models → lib/sufia/jobs}/content_update_event_job.rb +1 -1
  76. data/{app/models → lib/sufia/jobs}/event_job.rb +7 -3
  77. data/{app/models → lib/sufia/jobs}/resolrize_job.rb +4 -2
  78. data/lib/sufia/jobs/transcode_video_job.rb +79 -0
  79. data/{app/models → lib/sufia/jobs}/unzip_job.rb +11 -3
  80. data/{app/models → lib/sufia/jobs}/user_edit_profile_event_job.rb +6 -0
  81. data/{app/models → lib/sufia/jobs}/user_follow_event_job.rb +9 -4
  82. data/{app/models → lib/sufia/jobs}/user_unfollow_event_job.rb +6 -0
  83. data/lib/sufia/queue/resque.rb +30 -0
  84. data/lib/sufia/role_mapper.rb +0 -1
  85. data/{app/models/characterize_job.rb → lib/sufia/solr_document_behavior.rb} +6 -7
  86. data/lib/sufia/user.rb +3 -3
  87. data/lib/sufia/version.rb +1 -1
  88. data/lib/tasks/fixtures.rake +38 -38
  89. data/lib/tasks/resque.rake +1 -0
  90. data/solr_conf/conf/solrconfig.xml +32 -1615
  91. data/solr_conf/solr.xml +1 -1
  92. data/spec/active_fedora/unsaved_digital_object_spec.rb +4 -4
  93. data/spec/config/host_to_vhost_spec.rb +4 -4
  94. data/spec/controllers/authorities_controller_spec.rb +1 -1
  95. data/spec/controllers/batch_controller_spec.rb +12 -10
  96. data/spec/controllers/catalog_controller_spec.rb +13 -13
  97. data/spec/controllers/dashboard_controller_spec.rb +15 -15
  98. data/spec/controllers/downloads_controller_spec.rb +14 -14
  99. data/spec/controllers/generic_files_controller_spec.rb +88 -46
  100. data/spec/controllers/mailbox_controller_spec.rb +2 -2
  101. data/spec/controllers/sessions_controller_spec.rb +1 -1
  102. data/spec/controllers/single_use_link_controller_spec.rb +18 -18
  103. data/spec/controllers/users_controller_spec.rb +47 -31
  104. data/spec/fixtures/countdown.avi +0 -0
  105. data/spec/fixtures/sufia/.gitignore +1 -0
  106. data/spec/fixtures/{scholarsphere → sufia}/bg_header.jpg +0 -0
  107. data/spec/fixtures/sufia/sufia_test1.descMeta.txt +12 -0
  108. data/spec/fixtures/{scholarsphere → sufia}/sufia_test1.foxml.erb +2 -2
  109. data/spec/fixtures/{scholarsphere/scholarsphere_test1.txt → sufia/sufia_test1.txt} +0 -0
  110. data/spec/fixtures/sufia/sufia_test2.descMeta.txt +12 -0
  111. data/spec/fixtures/{scholarsphere/scholarsphere_test2.docx → sufia/sufia_test2.docx} +0 -0
  112. data/spec/fixtures/{scholarsphere/scholarsphere_test2.foxml.erb → sufia/sufia_test2.foxml.erb} +6 -6
  113. data/spec/fixtures/sufia/sufia_test3.descMeta.txt +12 -0
  114. data/spec/fixtures/{scholarsphere/scholarsphere_test3.foxml.erb → sufia/sufia_test3.foxml.erb} +6 -6
  115. data/spec/fixtures/{scholarsphere/scholarsphere_test3.xls → sufia/sufia_test3.xls} +0 -0
  116. data/spec/fixtures/sufia/sufia_test4.descMeta.txt +12 -0
  117. data/spec/fixtures/{scholarsphere/scholarsphere_test4.foxml.erb → sufia/sufia_test4.foxml.erb} +6 -6
  118. data/spec/fixtures/{scholarsphere/scholarsphere_test4.pdf → sufia/sufia_test4.pdf} +0 -0
  119. data/spec/fixtures/sufia/sufia_test5.descMeta.txt +19 -0
  120. data/spec/fixtures/{scholarsphere → sufia}/sufia_test5.foxml.erb +3 -3
  121. data/spec/fixtures/{scholarsphere/scholarsphere_test5.mp3 → sufia/sufia_test5.mp3} +0 -0
  122. data/spec/fixtures/sufia/sufia_test5.txt +1 -0
  123. data/spec/fixtures/sufia/sufia_test6.descMeta.txt +12 -0
  124. data/spec/fixtures/{scholarsphere/scholarsphere_test6.foxml.erb → sufia/sufia_test6.foxml.erb} +6 -6
  125. data/spec/fixtures/{scholarsphere/scholarsphere_test6.jp2 → sufia/sufia_test6.jp2} +0 -0
  126. data/spec/fixtures/sufia/sufia_test6.txt +1 -0
  127. data/spec/fixtures/sufia_generic_stub.descMeta.txt +12 -0
  128. data/spec/fixtures/{scholarsphere_generic_stub.foxml.erb → sufia_generic_stub.foxml.erb} +3 -3
  129. data/spec/fixtures/sufia_generic_stub.txt +1 -0
  130. data/spec/lib/sufia/role_mapper_spec.rb +1 -1
  131. data/spec/models/audit_job_spec.rb +8 -11
  132. data/spec/models/batch_spec.rb +5 -5
  133. data/spec/models/batch_update_job_spec.rb +18 -15
  134. data/spec/models/checksum_audit_log_spec.rb +6 -19
  135. data/spec/models/event_jobs_spec.rb +23 -23
  136. data/spec/models/file_content_datastream_spec.rb +14 -14
  137. data/spec/models/fits_datastream_spec.rb +1 -1
  138. data/spec/models/generic_file_spec.rb +88 -41
  139. data/spec/models/single_use_link_spec.rb +3 -3
  140. data/spec/models/transcode_video_job_spec.rb +30 -0
  141. data/spec/models/unzip_job_spec.rb +6 -4
  142. data/spec/rake/{scholarsphere_fixtures_spec.rb → sufia_fixtures_spec.rb} +16 -16
  143. data/spec/routing/route_spec.rb +4 -8
  144. data/spec/spec_helper.rb +0 -7
  145. data/spec/support/Gemfile +4 -2
  146. data/spec/support/fedora_conf/fedora.fcfg +953 -0
  147. data/spec/support/lib/generators/test_app_generator.rb +1 -11
  148. data/sufia.gemspec +5 -3
  149. data/tasks/{scholarsphere-db.rake → sufia-db.rake} +1 -1
  150. data/tasks/{scholarsphere-dev.rake → sufia-dev.rake} +7 -3
  151. data/tasks/{scholarsphere-fixtures.rake → sufia-fixtures.rake} +43 -43
  152. data/tasks/{scholarsphere.rake → sufia.rake} +2 -2
  153. metadata +126 -95
  154. data/app/models/batch_update_job.rb +0 -82
  155. data/app/models/solr_document.rb +0 -50
  156. data/lib/sufia/permissions.rb +0 -43
  157. data/spec/fixtures/scholarsphere/scholarsphere_test1.descMeta.txt +0 -12
  158. data/spec/fixtures/scholarsphere/scholarsphere_test2.descMeta.txt +0 -12
  159. data/spec/fixtures/scholarsphere/scholarsphere_test3.descMeta.txt +0 -12
  160. data/spec/fixtures/scholarsphere/scholarsphere_test4.descMeta.txt +0 -12
  161. data/spec/fixtures/scholarsphere/scholarsphere_test5.descMeta.txt +0 -19
  162. data/spec/fixtures/scholarsphere/scholarsphere_test5.txt +0 -1
  163. data/spec/fixtures/scholarsphere/scholarsphere_test6.descMeta.txt +0 -12
  164. data/spec/fixtures/scholarsphere/scholarsphere_test6.txt +0 -1
  165. data/spec/fixtures/scholarsphere/sufia_scholarsphere1.descMeta.txt +0 -12
  166. data/spec/fixtures/scholarsphere/sufia_scholarsphere1.foxml.erb +0 -79
  167. data/spec/fixtures/scholarsphere/sufia_scholarsphere1.txt +0 -1
  168. data/spec/fixtures/scholarsphere_generic_stub.descMeta.txt +0 -12
  169. data/spec/fixtures/scholarsphere_generic_stub.txt +0 -1
@@ -25,12 +25,12 @@ Given /^I (?:am )?log(?:ged)? in as "([^\"]*)"$/ do |login|
25
25
  user = User.where(:email=>login).first || FactoryGirl.create(:user, :email=>login)
26
26
  User.find_by_user_key(login).should_not be_nil
27
27
  visit "/"
28
- step %{And I click the anchor "Login"}
28
+ find("a[href=\"/users/sign_in\"]").click
29
29
  fill_in 'Email', with: login
30
30
  fill_in 'Password', with: 'password'
31
31
  click_button 'Sign in'
32
32
 
33
- step %{And I click the anchor "#{login}"}
33
+ step %{And I click within the anchor "i.icon-user"}
34
34
  step %{I should see a link to "ingest" with label "upload"}
35
35
  step %{I should see a link to "dashboard" with label "dashboard"}
36
36
  # step %{I should see a link to "logout"}
@@ -24,7 +24,7 @@ require 'cgi'
24
24
  require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
25
25
 
26
26
  module WithinHelpers
27
- Hydra::LDAP.stubs(:does_user_exist?).returns(true)
27
+ # Hydra::LDAP.stubs(:does_user_exist?).returns(true)
28
28
 
29
29
  def with_scope(locator)
30
30
  locator ? within(locator) { yield } : yield
@@ -3,6 +3,7 @@
3
3
  # newer version of cucumber-rails. Consider adding your own code to a new file
4
4
  # instead of editing this one. Cucumber will automatically load all features/**/*.rb
5
5
  # files.
6
+ require "rake"
6
7
 
7
8
  #require 'capybara'
8
9
  ENV["RAILS_ENV"] ||= "test"
@@ -62,3 +63,28 @@ end
62
63
  # The :transaction strategy is faster, but might give you threading problems.
63
64
  # See https://github.com/cucumber/cucumber-rails/blob/master/features/choose_javascript_database_strategy.feature
64
65
  Cucumber::Rails::Database.javascript_strategy = :truncation
66
+
67
+ #load fixtures for cucumber tests
68
+ def loaded_files_excluding_current_rake_file
69
+ $".reject { |file| file.include? "lib/tasks/fixtures" }
70
+ end
71
+ def activefedora_path
72
+ Gem.loaded_specs['active-fedora'].full_gem_path
73
+ end
74
+ def load_rake
75
+ @rake = Rake::Application.new
76
+ Rake.application = @rake
77
+ Rake.application.rake_require("tasks/sufia-fixtures", ["."], loaded_files_excluding_current_rake_file)
78
+ Rake.application.rake_require("lib/tasks/fixtures", ["."], loaded_files_excluding_current_rake_file)
79
+ Rake.application.rake_require("lib/tasks/active_fedora", [activefedora_path], loaded_files_excluding_current_rake_file)
80
+ Rake::Task.define_task(:environment)
81
+ end
82
+ load_rake
83
+ @rake['sufia:fixtures:refresh'].invoke
84
+ @rake['sufia:fixtures:fix'].invoke
85
+
86
+ at_exit do
87
+ load_rake
88
+ @rake['sufia:fixtures:delete'].invoke
89
+ end
90
+
@@ -0,0 +1,18 @@
1
+ Feature: User Profile
2
+
3
+ Scenario: Show my profile
4
+ Given I load users
5
+ Given I am logged in as "curator1@example.com"
6
+ And I follow "curator1@example.com"
7
+ Then I should see "Edit Your Profile"
8
+
9
+ Scenario: Edit my profile
10
+ Given I load users
11
+ Given I am logged in as "curator1@example.com"
12
+ And I follow "curator1@example.com"
13
+ And I follow "Edit Your Profile"
14
+ And I fill in "user_twitter_handle" with "curatorOfData"
15
+ And I press "Save Profile"
16
+ Then I should see "Your profile has been updated"
17
+ And I should see "curatorOfData"
18
+
@@ -0,0 +1,22 @@
1
+ ### This patch is going into active-support (rails 4). https://github.com/rails/rails/pull/8246
2
+ module Marshal
3
+ class << self
4
+ def load_with_autoloading(source)
5
+ begin
6
+ load_without_autoloading(source)
7
+ rescue ArgumentError, NameError => exc
8
+ if exc.message.match(%r|undefined class/module (.+)|)
9
+ # try loading the class/module
10
+ $1.constantize
11
+ # if it is a IO we need to go back to read the object
12
+ source.rewind if source.respond_to?(:rewind)
13
+ retry
14
+ else
15
+ raise exc
16
+ end
17
+ end
18
+ end
19
+
20
+ alias_method_chain :load, :autoloading
21
+ end
22
+ end
@@ -15,7 +15,8 @@ This generator makes the following changes to your application:
15
15
  3. Adds controller behavior to the application controller
16
16
  4. Creates the sufia.rb configuration file
17
17
  5. Copies the catalog controller into the local app
18
- 6. Generates mailboxer
18
+ 6. Adds Sufia::SolrDocumentBehavior to app/models/solr_document.rb
19
+ 7. Generates mailboxer
19
20
  """
20
21
 
21
22
  # Implement the required interface for Rails::Generators::Migration.
@@ -32,7 +33,7 @@ This generator makes the following changes to your application:
32
33
  # Setup the database migrations
33
34
  def copy_migrations
34
35
  # Can't get this any more DRY, because we need this order.
35
- %w{acts_as_follower_migration.rb add_social_to_users.rb create_single_use_links.rb
36
+ %w{acts_as_follower_migration.rb add_social_to_users.rb create_single_use_links.rb add_ldap_attrs_to_user.rb
36
37
  add_avatars_to_users.rb create_checksum_audit_logs.rb create_version_committers.rb
37
38
  add_groups_to_users.rb create_local_authorities.rb}.each do |f|
38
39
  better_migration_template f
@@ -61,6 +62,7 @@ add_groups_to_users.rb create_local_authorities.rb}.each do |f|
61
62
  " \n# Adds Sufia behaviors into the application controller \n" +
62
63
  " include Sufia::Controller\n"
63
64
  end
65
+ gsub_file file_path, "layout 'blacklight'", "layout 'hydra-head'"
64
66
  else
65
67
  puts " \e[31mFailure\e[0m Could not find #{file_path}. To add Sufia behaviors to your Controllers, you must include the Sufia::Controller module in the Controller class definition."
66
68
  end
@@ -68,6 +70,7 @@ add_groups_to_users.rb create_local_authorities.rb}.each do |f|
68
70
 
69
71
  def create_configuration_files
70
72
  copy_file "config/sufia.rb", "config/initializers/sufia.rb"
73
+ copy_file "config/redis.yml", "config/redis.yml"
71
74
  copy_file "config/redis_config.rb", "config/initializers/redis_config.rb"
72
75
  end
73
76
 
@@ -88,6 +91,19 @@ add_groups_to_users.rb create_local_authorities.rb}.each do |f|
88
91
 
89
92
  end
90
93
 
94
+ # Add behaviors to the SolrDocument model
95
+ def inject_sufia_solr_document_behavior
96
+ file_path = "app/models/solr_document.rb"
97
+ if File.exists?(file_path)
98
+ inject_into_class file_path, "SolrDocument" do
99
+ " # Adds Sufia behaviors to the SolrDocument.\n" +
100
+ " include Sufia::SolrDocumentBehavior\n"
101
+ end
102
+ else
103
+ puts " \e[31mFailure\e[0m Sufia requires a SolrDocument object. This generators assumes that the model is defined in the file #{file_path}, which does not exist."
104
+ end
105
+ end
106
+
91
107
  def install_mailboxer
92
108
  generate "mailboxer:install"
93
109
  end
@@ -28,12 +28,11 @@ class CatalogController < ApplicationController
28
28
  include BlacklightAdvancedSearch::ParseBasicQ
29
29
 
30
30
  # These before_filters apply the hydra access controls
31
- before_filter :enforce_access_controls
32
- before_filter :enforce_viewing_context_for_show_requests, :only=>:show
31
+ before_filter :enforce_show_permissions, :only=>:show
33
32
  # This applies appropriate access controls to all solr queries
34
- CatalogController.solr_search_params_logic << :add_access_controls_to_solr_params
33
+ CatalogController.solr_search_params_logic += [:add_access_controls_to_solr_params]
35
34
  # This filters out objects that you want to exclude from search results, like FileAssets
36
- CatalogController.solr_search_params_logic << :exclude_unwanted_models
35
+ CatalogController.solr_search_params_logic += [:exclude_unwanted_models]
37
36
 
38
37
  skip_before_filter :default_html_head
39
38
 
@@ -27,6 +27,74 @@ Sufia.config do |config|
27
27
  # TODO move these to an HttpAuth initializer
28
28
  config.logout_url = "https://webaccess.psu.edu/cgi-bin/logout?#{Sufia::HttpHeaderAuth.get_vhost_by_host(config)[1]}"
29
29
  config.login_url = "https://webaccess.psu.edu?cosign-#{Sufia::HttpHeaderAuth.get_vhost_by_host(config)[0]}&#{Sufia::HttpHeaderAuth.get_vhost_by_host(config)[1]}"
30
+
31
+ config.cc_licenses = {
32
+ 'Attribution 3.0 United States' => 'http://creativecommons.org/licenses/by/3.0/us/',
33
+ 'Attribution-ShareAlike 3.0 United States' => 'http://creativecommons.org/licenses/by-sa/3.0/us/',
34
+ 'Attribution-NonCommercial 3.0 United States' => 'http://creativecommons.org/licenses/by-nc/3.0/us/',
35
+ 'Attribution-NoDerivs 3.0 United States' => 'http://creativecommons.org/licenses/by-nd/3.0/us/',
36
+ 'Attribution-NonCommercial-NoDerivs 3.0 United States' => 'http://creativecommons.org/licenses/by-nc-nd/3.0/us/',
37
+ 'Attribution-NonCommercial-ShareAlike 3.0 United States' => 'http://creativecommons.org/licenses/by-nc-sa/3.0/us/',
38
+ 'Public Domain Mark 1.0' => 'http://creativecommons.org/publicdomain/mark/1.0/',
39
+ 'CC0 1.0 Universal' => 'http://creativecommons.org/publicdomain/zero/1.0/',
40
+ 'All rights reserved' => 'All rights reserved'
41
+ }
42
+
43
+ config.cc_licenses_reverse = Hash[*config.cc_licenses.to_a.flatten.reverse]
44
+
45
+ config.resource_types = {
46
+ "Article" => "Article",
47
+ "Audio" => "Audio",
48
+ "Book" => "Book",
49
+ "Capstone Project" => "Capstone Project",
50
+ "Conference Proceeding" => "Conference Proceeding",
51
+ "Dataset" => "Dataset",
52
+ "Dissertation" => "Dissertation",
53
+ "Image" => "Image",
54
+ "Journal" => "Journal",
55
+ "Map or Cartographic Material" => "Map or Cartographic Material",
56
+ "Masters Thesis" => "Masters Thesis",
57
+ "Part of Book" => "Part of Book",
58
+ "Poster" => "Poster",
59
+ "Presentation" => "Presentation",
60
+ "Project" => "Project",
61
+ "Report" => "Report",
62
+ "Research Paper" => "Research Paper",
63
+ "Software or Program Code" => "Software or Program Code",
64
+ "Video" => "Video",
65
+ "Other" => "Other",
66
+ }
67
+
68
+ # reflect a field name change (should one happen) in the generic file datastream
69
+ config.metadata_help = {
70
+ "generic_file_resource_type" => "Pre-defined categories to describe the type of file content being uploaded, such as \"article\" or \"dataset.\" More than one type may be selected.",
71
+ "generic_file_title" => "A name for the file to aid in identifying it. Defaults to the file name, though a more descriptive title is encouraged. <em>This is a required field</em>.",
72
+ "generic_file_tag" => "Words or phrases you select to describe what the file is about. These are used to search for content. <em>This is a required field</em>.",
73
+ "generic_file_subject" => "Headings or index terms describing what the file is about; these <em>do</em> need to conform to an existing vocabulary. Currently ScholarSphere supports Library of Congress Subject Headings.",
74
+ "generic_file_creator" => "The person or group responsible for the file being uploaded. Usually this is the author of the content. Personal names should be entered with the last name first, e.g. \"Smith, John.\" <em>This is a required field</em>.",
75
+ "generic_file_related_url" => "A link to a website or other specific content (audio, video, PDF document) related to the file. An example is the URL of a research project from which the file was derived.",
76
+ "generic_file_based_near" => "A place name related to the file, such as its site of publication, or the city, state, or country the file's contents are about. Calls upon the GeoNames web service (<a href=\"http://www.geonames.org\">http://www.geonames.org</a>).",
77
+ "generic_file_contributor" => "A person or group you want to recognize for playing a role in the creation of the file, but not the primary role. If there is a specific role you would like noted, include it in parentheses, e.g. \"Jones, Mary (advisor).\"",
78
+ "generic_file_date_created" => "The date on which the file was generated. Dates are accepted in the form YYYY-MM-DD, e.g. 1776-07-04.",
79
+ "generic_file_description" => "Free-text notes about the file itself. Examples include abstracts of a paper, citation information for a journal article, or a tag indicating a larger collection to which the file belongs.",
80
+ "generic_file_identifier" => "A unique handle describing the file. An example would be a DOI for a journal article, or an ISBN or OCLC number for a book.",
81
+ "generic_file_language" => " The language of the file content.",
82
+ "generic_file_publisher" => "The person or group making the file available. Generally this is Penn State or the Penn State University Libraries.",
83
+ "generic_file_rights" => "Licensing and distribution information governing access to the file. Select from the provided drop-down list. <em>This is a required field</em>."
84
+ }
85
+
86
+ config.permission_levels = {
87
+ "Choose Access"=>"none",
88
+ "View/Download" => "read",
89
+ "Edit" => "edit"
90
+ }
91
+
92
+ config.owner_permission_levels = {
93
+ "Edit" => "edit"
94
+ }
95
+
96
+ config.queue = Sufia::Resque::Queue
97
+
30
98
  end
31
99
 
32
100
 
@@ -0,0 +1,41 @@
1
+ # Copyright © 2012 The Pennsylvania State University
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ class AddLdapAttrsToUser < ActiveRecord::Migration
16
+ def self.up
17
+ add_column :users, :display_name, :string
18
+ add_column :users, :address, :string
19
+ add_column :users, :admin_area, :string
20
+ add_column :users, :department, :string
21
+ add_column :users, :title, :string
22
+ add_column :users, :office, :string
23
+ add_column :users, :chat_id, :string
24
+ add_column :users, :website, :string
25
+ add_column :users, :affiliation, :string
26
+ add_column :users, :telephone, :string
27
+ end
28
+
29
+ def self.down
30
+ remove_column :users, :display_name
31
+ remove_column :users, :address
32
+ remove_column :users, :admin_area
33
+ remove_column :users, :department
34
+ remove_column :users, :title
35
+ remove_column :users, :office
36
+ remove_column :users, :chat_id
37
+ remove_column :users, :website
38
+ remove_column :users, :affiliation
39
+ remove_column :users, :telephone
40
+ end
41
+ end
@@ -0,0 +1,11 @@
1
+ # Monkey patch so that it uses the engine routes. See https://github.com/amatsuda/kaminari/issues/323
2
+ module Kaminari
3
+ module Helpers
4
+ class Tag
5
+ def page_url_for(page)
6
+ #@template.url_for @params.merge(@param_name => (page <= 1 ? nil : page)).symbolize_keys
7
+ Sufia::Engine.routes.url_helpers.url_for @params.merge(@param_name => (page <= 1 ? nil : page), :only_path=>true).symbolize_keys
8
+ end
9
+ end
10
+ end
11
+ end
data/lib/sufia.rb CHANGED
@@ -12,17 +12,34 @@ require 'will_paginate'
12
12
  require 'nest'
13
13
  require 'RMagick'
14
14
  require 'activerecord-import'
15
+ require 'rails_autolink'
15
16
 
16
17
  autoload :Zip, 'zipruby'
17
18
  module Sufia
19
+ extend ActiveSupport::Autoload
20
+
21
+ autoload :Resque, 'sufia/queue/resque'
22
+
23
+ attr_accessor :queue
18
24
 
19
25
  class Engine < ::Rails::Engine
20
26
  engine_name 'sufia'
21
27
 
28
+ config.queue = Sufia::Resque::Queue
29
+ config.ffmpeg_path = 'ffmpeg'
30
+ config.fits_message_length = 5
31
+
32
+
33
+ config.autoload_paths << File.expand_path("../sufia/jobs", __FILE__)
34
+
22
35
  initializer "Patch active_fedora" do
23
36
  require 'sufia/active_fedora/redis'
24
37
  end
25
38
 
39
+ initializer "Patch kaminari" do
40
+ require "kaminari/helpers/tag"
41
+ end
42
+
26
43
  initializer "Patch active_record" do
27
44
  require 'sufia/active_record/redis'
28
45
  end
@@ -46,12 +63,18 @@ module Sufia
46
63
  return @@config
47
64
  end
48
65
 
49
- autoload :Controller, 'sufia/controller'
50
- autoload :Utils, 'sufia/utils'
51
- autoload :User, 'sufia/user'
52
- autoload :ModelMethods, 'sufia/model_methods'
53
- autoload :Noid, 'sufia/noid'
54
- autoload :IdService, 'sufia/id_service'
55
- autoload :HttpHeaderAuth,'sufia/http_header_auth'
66
+ def self.queue
67
+ @queue ||= config.queue.new('sufia')
68
+ end
69
+
70
+ autoload :GenericFile
71
+ autoload :Controller, 'sufia/controller'
72
+ autoload :Utils, 'sufia/utils'
73
+ autoload :User, 'sufia/user'
74
+ autoload :ModelMethods, 'sufia/model_methods'
75
+ autoload :Noid, 'sufia/noid'
76
+ autoload :IdService, 'sufia/id_service'
77
+ autoload :HttpHeaderAuth, 'sufia/http_header_auth'
78
+ autoload :SolrDocumentBehavior, 'sufia/solr_document_behavior'
56
79
  end
57
80
 
@@ -23,12 +23,8 @@ module Sufia::Controller
23
23
 
24
24
  end
25
25
 
26
- def layout_name
27
- 'hydra-head'
28
- end
29
-
30
26
  def current_ability
31
- current_user.ability
27
+ current_user ? current_user.ability : super
32
28
  end
33
29
 
34
30
  def render_404(exception)
@@ -0,0 +1,200 @@
1
+ require 'datastreams/generic_file_rdf_datastream'
2
+ require 'datastreams/properties_datastream'
3
+ require 'datastreams/file_content_datastream'
4
+
5
+ module Sufia
6
+ module GenericFile
7
+ extend ActiveSupport::Concern
8
+ extend ActiveSupport::Autoload
9
+ autoload :Export
10
+ autoload :Thumbnail
11
+ autoload :Characterization
12
+ autoload :Audit
13
+ autoload :Permissions
14
+ include Sufia::ModelMethods
15
+ include Sufia::Noid
16
+ include Sufia::GenericFile::Thumbnail
17
+ include Sufia::GenericFile::Export
18
+ include Sufia::GenericFile::Characterization
19
+ include Sufia::GenericFile::Audit
20
+ include Sufia::GenericFile::Permissions
21
+
22
+ @@FIELD_LABEL_MAP = {"based_near"=>"Location", 'description'=>"Abstract or Summary", 'tag'=>"Keyword", 'date_created'=>"Date Created", 'related_url'=>"Related URL"}
23
+
24
+ included do
25
+ has_metadata :name => "descMetadata", :type => GenericFileRdfDatastream
26
+ has_metadata :name => "properties", :type => PropertiesDatastream
27
+ has_file_datastream :name => "content", :type => FileContentDatastream
28
+ has_file_datastream :name => "thumbnail", :type => FileContentDatastream
29
+
30
+ belongs_to :batch, :property => :is_part_of
31
+
32
+ delegate_to :properties, [:relative_path, :depositor], :unique => true
33
+ delegate_to :descMetadata, [:date_uploaded, :date_modified], :unique => true
34
+ delegate_to :descMetadata, [:related_url, :based_near, :part_of, :creator,
35
+ :contributor, :title, :tag, :description, :rights,
36
+ :publisher, :date_created, :subject, :format,
37
+ :resource_type, :identifier, :language]
38
+ around_save :characterize_if_changed, :retry_warming
39
+
40
+ #make sure the terms of service is present and set to 1 before saving
41
+ # note GenericFile.create will no longer save a GenericFile as the terms_of_service will not be set
42
+ terms_of_service = nil
43
+ validates_acceptance_of :terms_of_service, :allow_nil => false
44
+ end
45
+
46
+ def pdf?
47
+ ["application/pdf"].include? self.mime_type
48
+ end
49
+
50
+ def image?
51
+ ["image/png","image/jpeg", 'image/jpg', 'image/bmp', "image/gif"].include? self.mime_type
52
+ end
53
+
54
+ def video?
55
+ ["video/mpeg", "video/mp4", "video/x-msvideo", "video/avi", "video/quicktime"].include? self.mime_type
56
+ end
57
+
58
+ def persistent_url
59
+ "#{Sufia::Engine.config.persistent_hostpath}#{noid}"
60
+ end
61
+
62
+ def retry_warming
63
+ save_tries = 0
64
+ conflict_tries = 0
65
+ begin
66
+ yield
67
+ rescue RSolr::Error::Http => error
68
+ save_tries += 1
69
+ logger.warn "Retry Solr caught RSOLR error on #{self.pid}: #{error.inspect}"
70
+ # fail for good if the tries is greater than 3
71
+ raise if save_tries >=3
72
+ sleep 0.01
73
+ retry
74
+ rescue ActiveResource::ResourceConflict => error
75
+ conflict_tries += 1
76
+ logger.warn "Retry caught Active Resource Conflict #{self.pid}: #{error.inspect}"
77
+ raise if conflict_tries >=10
78
+ sleep 0.01
79
+ retry
80
+ rescue =>error
81
+ if (error.to_s.downcase.include? "conflict")
82
+ conflict_tries += 1
83
+ logger.warn "Retry caught Active Resource Conflict #{self.pid}: #{error.inspect}"
84
+ raise if conflict_tries >=10
85
+ sleep 0.01
86
+ retry
87
+ else
88
+ raise
89
+ end
90
+
91
+ end
92
+ end
93
+
94
+ def related_files
95
+ relateds = begin
96
+ self.batch.generic_files
97
+ rescue NoMethodError => e
98
+ #batch is nil
99
+ batch_id = self.object_relations["isPartOf"].first || self.object_relations[:is_part_of].first
100
+ return [] if batch_id.nil?
101
+ self.class.find(:is_part_of_s => batch_id)
102
+ end
103
+ relateds.reject { |gf| gf.pid == self.pid }
104
+ end
105
+
106
+
107
+ def to_solr(solr_doc={}, opts={})
108
+ super(solr_doc, opts)
109
+ solr_doc["label_t"] = self.label
110
+ solr_doc["noid_s"] = noid
111
+ solr_doc["file_format_t"] = file_format
112
+ solr_doc["file_format_facet"] = solr_doc["file_format_t"]
113
+ # remap dates as a valid xml date not to_s
114
+ solr_doc['generic_file__date_uploaded_dt'] = Time.parse(date_uploaded).utc.to_s.sub(' ','T').sub(' UTC','Z') rescue Time.new(date_uploaded).utc.to_s.sub(' ','T').sub(' UTC','Z') unless date_uploaded.blank?
115
+ solr_doc['generic_file__date_modified_dt'] = Time.parse(date_modified).utc.to_s.sub(' ','T').sub(' UTC','Z') rescue Time.new(date_modified).utc.to_s.sub(' ','T').sub(' UTC','Z') unless date_modified.blank?
116
+ return solr_doc
117
+ end
118
+
119
+ def file_format
120
+ return nil if self.mime_type.blank? and self.format_label.blank?
121
+ return self.mime_type.split('/')[1]+ " ("+self.format_label.join(", ")+")" unless self.mime_type.blank? or self.format_label.blank?
122
+ return self.mime_type.split('/')[1] unless self.mime_type.blank?
123
+ return self.format_label
124
+ end
125
+
126
+ # Redefine this for more intuitive keys in Redis
127
+ def to_param
128
+ noid
129
+ end
130
+
131
+ def label=(new_label)
132
+ @inner_object.label = new_label
133
+ if self.title.empty?
134
+ self.title = new_label
135
+ end
136
+ end
137
+
138
+ def to_jq_upload
139
+ return {
140
+ "name" => self.title,
141
+ "size" => self.file_size,
142
+ "url" => "/files/#{noid}",
143
+ "thumbnail_url" => self.pid,
144
+ "delete_url" => "deleteme", # generic_file_path(:id => id),
145
+ "delete_type" => "DELETE"
146
+ }
147
+ end
148
+
149
+ def get_terms
150
+ terms = []
151
+ self.descMetadata.class.config[:predicate_mapping].each do |uri, mappings|
152
+ new_terms = mappings.keys.map(&:to_s).select do |term|
153
+ term.start_with? "generic_file__" and !['type', 'behaviors'].include? term.split('__').last
154
+ end
155
+ terms.concat(new_terms)
156
+ end
157
+ terms
158
+ end
159
+
160
+ def get_values
161
+ terms = get_terms
162
+ values = {}
163
+ terms.each do |t|
164
+ next if t.empty?
165
+ key = t.to_s.split("generic_file__").last
166
+ next if ['part_of', 'date_modified', 'date_uploaded', 'format'].include?(key)
167
+ values[key] = self.send(key) if self.respond_to?(key)
168
+ end
169
+ return values
170
+ end
171
+
172
+ # Is this file in the middle of being processed by a batch?
173
+ def processing?
174
+ return false if self.batch.blank?
175
+ return false if !self.batch.methods.include? :status
176
+ return (!self.batch.status.empty?) && (self.batch.status.count == 1) && (self.batch.status[0] == "processing")
177
+ end
178
+
179
+ module ClassMethods
180
+ def get_label(key)
181
+ label = @@FIELD_LABEL_MAP[key]
182
+ label = key.gsub('_',' ').titleize if label.blank?
183
+ return label
184
+ end
185
+
186
+ # redefine find so that it sets the terms of service
187
+ def find(args, opts={})
188
+ gf = super
189
+ # use the field type to see if the return will be one item or multiple
190
+ if args.is_a? String
191
+ gf.terms_of_service = '1'
192
+ elsif gf.respond_to? :each
193
+ gf.each {|f| f.terms_of_service = '1'}
194
+ end
195
+ return gf
196
+ end
197
+ end
198
+
199
+ end
200
+ end