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.
- data/Gemfile +2 -5
- data/README.md +44 -12
- data/app/assets/javascripts/{scholarsphere.js → sufia.js} +0 -0
- data/app/assets/stylesheets/{scholarsphere.css → sufia.css} +0 -0
- data/app/controllers/batch_controller.rb +2 -3
- data/app/controllers/batch_edits_controller.rb +4 -4
- data/app/controllers/dashboard_controller.rb +5 -3
- data/app/controllers/generic_files_controller.rb +77 -41
- data/app/controllers/users_controller.rb +9 -21
- data/app/helpers/blacklight/render_constraints_helper_behavior.rb +2 -2
- data/app/helpers/sufia_helper.rb +23 -2
- data/app/models/datastreams/file_content_datastream.rb +17 -9
- data/app/models/generic_file.rb +1 -809
- data/app/views/_add_assets_links.html.erb +1 -1
- data/app/views/_user_util_links.html.erb +2 -2
- data/app/views/batch/_metadata.html.erb +16 -16
- data/app/views/batch/edit.html.erb +16 -10
- data/app/views/batch_edits/_metadata.html.erb +16 -16
- data/app/views/catalog/_index_partials/_list_files.html.erb +2 -2
- data/app/views/catalog/index.html.erb +5 -0
- data/app/views/dashboard/_facet_limit.html.erb +1 -1
- data/app/views/dashboard/_facet_pagination.html.erb +4 -4
- data/app/views/dashboard/_facet_selected.html.erb +1 -1
- data/app/views/dashboard/_index_partials/_list_files.html.erb +8 -8
- data/app/views/dashboard/_search_form.html.erb +1 -1
- data/app/views/dashboard/_sort_and_per_page.html.erb +1 -1
- data/app/views/dashboard/index.html.erb +0 -1
- data/app/views/generic_files/_breadcrumbs.html.erb +1 -1
- data/app/views/generic_files/_descriptions.html.erb +3 -3
- data/app/views/generic_files/_field_form +3 -3
- data/app/views/generic_files/_media_display.html.erb +5 -4
- data/app/views/generic_files/_permission.html.erb +5 -5
- data/app/views/generic_files/_versioning.html.erb +1 -1
- data/app/views/generic_files/edit.html.erb +2 -2
- data/app/views/generic_files/show.html.erb +3 -3
- data/app/views/static/versions.html.erb +1 -1
- data/app/views/users/edit.html.erb +5 -3
- data/app/views/users/index.html.erb +3 -3
- data/app/views/users/show.html.erb +6 -6
- data/config/jetty.yml +6 -0
- data/config/routes.rb +8 -4
- data/features/browse_dashboard_files.feature +11 -1
- data/features/browse_files.feature +6 -5
- data/features/contact_form.feature +4 -0
- data/features/display_dashboard.feature +6 -3
- data/features/ingest_upload_files.feature +2 -2
- data/features/step_definitions/fixture_steps.rb +6 -5
- data/features/step_definitions/scholarsphere.rb +24 -1
- data/features/step_definitions/user_steps.rb +2 -2
- data/features/step_definitions/web_steps.rb +1 -1
- data/features/support/env.rb +26 -0
- data/features/users.feature +18 -0
- data/lib/active_support/core_ext/marshal.rb +22 -0
- data/lib/generators/sufia/sufia_generator.rb +18 -2
- data/lib/generators/sufia/templates/catalog_controller.rb +3 -4
- data/{spec/support → lib/generators/sufia/templates}/config/redis.yml +0 -0
- data/lib/generators/sufia/templates/config/sufia.rb +68 -0
- data/lib/generators/sufia/templates/migrations/add_ldap_attrs_to_user.rb +41 -0
- data/lib/kaminari/helpers/tag.rb +11 -0
- data/lib/sufia.rb +30 -7
- data/lib/sufia/controller.rb +1 -5
- data/lib/sufia/generic_file.rb +200 -0
- data/lib/sufia/generic_file/audit.rb +119 -0
- data/lib/sufia/generic_file/characterization.rb +82 -0
- data/lib/sufia/generic_file/export.rb +339 -0
- data/lib/sufia/generic_file/permissions.rb +64 -0
- data/lib/sufia/generic_file/thumbnail.rb +68 -0
- data/{app/models → lib/sufia/jobs}/audit_job.rb +13 -3
- data/lib/sufia/jobs/batch_update_job.rb +86 -0
- data/lib/sufia/jobs/characterize_job.rb +35 -0
- data/{app/models → lib/sufia/jobs}/content_delete_event_job.rb +3 -1
- data/{app/models → lib/sufia/jobs}/content_deposit_event_job.rb +1 -1
- data/{app/models → lib/sufia/jobs}/content_new_version_event_job.rb +1 -1
- data/{app/models → lib/sufia/jobs}/content_restored_version_event_job.rb +8 -0
- data/{app/models → lib/sufia/jobs}/content_update_event_job.rb +1 -1
- data/{app/models → lib/sufia/jobs}/event_job.rb +7 -3
- data/{app/models → lib/sufia/jobs}/resolrize_job.rb +4 -2
- data/lib/sufia/jobs/transcode_video_job.rb +79 -0
- data/{app/models → lib/sufia/jobs}/unzip_job.rb +11 -3
- data/{app/models → lib/sufia/jobs}/user_edit_profile_event_job.rb +6 -0
- data/{app/models → lib/sufia/jobs}/user_follow_event_job.rb +9 -4
- data/{app/models → lib/sufia/jobs}/user_unfollow_event_job.rb +6 -0
- data/lib/sufia/queue/resque.rb +30 -0
- data/lib/sufia/role_mapper.rb +0 -1
- data/{app/models/characterize_job.rb → lib/sufia/solr_document_behavior.rb} +6 -7
- data/lib/sufia/user.rb +3 -3
- data/lib/sufia/version.rb +1 -1
- data/lib/tasks/fixtures.rake +38 -38
- data/lib/tasks/resque.rake +1 -0
- data/solr_conf/conf/solrconfig.xml +32 -1615
- data/solr_conf/solr.xml +1 -1
- data/spec/active_fedora/unsaved_digital_object_spec.rb +4 -4
- data/spec/config/host_to_vhost_spec.rb +4 -4
- data/spec/controllers/authorities_controller_spec.rb +1 -1
- data/spec/controllers/batch_controller_spec.rb +12 -10
- data/spec/controllers/catalog_controller_spec.rb +13 -13
- data/spec/controllers/dashboard_controller_spec.rb +15 -15
- data/spec/controllers/downloads_controller_spec.rb +14 -14
- data/spec/controllers/generic_files_controller_spec.rb +88 -46
- data/spec/controllers/mailbox_controller_spec.rb +2 -2
- data/spec/controllers/sessions_controller_spec.rb +1 -1
- data/spec/controllers/single_use_link_controller_spec.rb +18 -18
- data/spec/controllers/users_controller_spec.rb +47 -31
- data/spec/fixtures/countdown.avi +0 -0
- data/spec/fixtures/sufia/.gitignore +1 -0
- data/spec/fixtures/{scholarsphere → sufia}/bg_header.jpg +0 -0
- data/spec/fixtures/sufia/sufia_test1.descMeta.txt +12 -0
- data/spec/fixtures/{scholarsphere → sufia}/sufia_test1.foxml.erb +2 -2
- data/spec/fixtures/{scholarsphere/scholarsphere_test1.txt → sufia/sufia_test1.txt} +0 -0
- data/spec/fixtures/sufia/sufia_test2.descMeta.txt +12 -0
- data/spec/fixtures/{scholarsphere/scholarsphere_test2.docx → sufia/sufia_test2.docx} +0 -0
- data/spec/fixtures/{scholarsphere/scholarsphere_test2.foxml.erb → sufia/sufia_test2.foxml.erb} +6 -6
- data/spec/fixtures/sufia/sufia_test3.descMeta.txt +12 -0
- data/spec/fixtures/{scholarsphere/scholarsphere_test3.foxml.erb → sufia/sufia_test3.foxml.erb} +6 -6
- data/spec/fixtures/{scholarsphere/scholarsphere_test3.xls → sufia/sufia_test3.xls} +0 -0
- data/spec/fixtures/sufia/sufia_test4.descMeta.txt +12 -0
- data/spec/fixtures/{scholarsphere/scholarsphere_test4.foxml.erb → sufia/sufia_test4.foxml.erb} +6 -6
- data/spec/fixtures/{scholarsphere/scholarsphere_test4.pdf → sufia/sufia_test4.pdf} +0 -0
- data/spec/fixtures/sufia/sufia_test5.descMeta.txt +19 -0
- data/spec/fixtures/{scholarsphere → sufia}/sufia_test5.foxml.erb +3 -3
- data/spec/fixtures/{scholarsphere/scholarsphere_test5.mp3 → sufia/sufia_test5.mp3} +0 -0
- data/spec/fixtures/sufia/sufia_test5.txt +1 -0
- data/spec/fixtures/sufia/sufia_test6.descMeta.txt +12 -0
- data/spec/fixtures/{scholarsphere/scholarsphere_test6.foxml.erb → sufia/sufia_test6.foxml.erb} +6 -6
- data/spec/fixtures/{scholarsphere/scholarsphere_test6.jp2 → sufia/sufia_test6.jp2} +0 -0
- data/spec/fixtures/sufia/sufia_test6.txt +1 -0
- data/spec/fixtures/sufia_generic_stub.descMeta.txt +12 -0
- data/spec/fixtures/{scholarsphere_generic_stub.foxml.erb → sufia_generic_stub.foxml.erb} +3 -3
- data/spec/fixtures/sufia_generic_stub.txt +1 -0
- data/spec/lib/sufia/role_mapper_spec.rb +1 -1
- data/spec/models/audit_job_spec.rb +8 -11
- data/spec/models/batch_spec.rb +5 -5
- data/spec/models/batch_update_job_spec.rb +18 -15
- data/spec/models/checksum_audit_log_spec.rb +6 -19
- data/spec/models/event_jobs_spec.rb +23 -23
- data/spec/models/file_content_datastream_spec.rb +14 -14
- data/spec/models/fits_datastream_spec.rb +1 -1
- data/spec/models/generic_file_spec.rb +88 -41
- data/spec/models/single_use_link_spec.rb +3 -3
- data/spec/models/transcode_video_job_spec.rb +30 -0
- data/spec/models/unzip_job_spec.rb +6 -4
- data/spec/rake/{scholarsphere_fixtures_spec.rb → sufia_fixtures_spec.rb} +16 -16
- data/spec/routing/route_spec.rb +4 -8
- data/spec/spec_helper.rb +0 -7
- data/spec/support/Gemfile +4 -2
- data/spec/support/fedora_conf/fedora.fcfg +953 -0
- data/spec/support/lib/generators/test_app_generator.rb +1 -11
- data/sufia.gemspec +5 -3
- data/tasks/{scholarsphere-db.rake → sufia-db.rake} +1 -1
- data/tasks/{scholarsphere-dev.rake → sufia-dev.rake} +7 -3
- data/tasks/{scholarsphere-fixtures.rake → sufia-fixtures.rake} +43 -43
- data/tasks/{scholarsphere.rake → sufia.rake} +2 -2
- metadata +126 -95
- data/app/models/batch_update_job.rb +0 -82
- data/app/models/solr_document.rb +0 -50
- data/lib/sufia/permissions.rb +0 -43
- data/spec/fixtures/scholarsphere/scholarsphere_test1.descMeta.txt +0 -12
- data/spec/fixtures/scholarsphere/scholarsphere_test2.descMeta.txt +0 -12
- data/spec/fixtures/scholarsphere/scholarsphere_test3.descMeta.txt +0 -12
- data/spec/fixtures/scholarsphere/scholarsphere_test4.descMeta.txt +0 -12
- data/spec/fixtures/scholarsphere/scholarsphere_test5.descMeta.txt +0 -19
- data/spec/fixtures/scholarsphere/scholarsphere_test5.txt +0 -1
- data/spec/fixtures/scholarsphere/scholarsphere_test6.descMeta.txt +0 -12
- data/spec/fixtures/scholarsphere/scholarsphere_test6.txt +0 -1
- data/spec/fixtures/scholarsphere/sufia_scholarsphere1.descMeta.txt +0 -12
- data/spec/fixtures/scholarsphere/sufia_scholarsphere1.foxml.erb +0 -79
- data/spec/fixtures/scholarsphere/sufia_scholarsphere1.txt +0 -1
- data/spec/fixtures/scholarsphere_generic_stub.descMeta.txt +0 -12
- 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
|
-
|
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 "
|
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
|
data/features/support/env.rb
CHANGED
@@ -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.
|
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 :
|
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
|
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
|
35
|
+
CatalogController.solr_search_params_logic += [:exclude_unwanted_models]
|
37
36
|
|
38
37
|
skip_before_filter :default_html_head
|
39
38
|
|
File without changes
|
@@ -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
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
autoload :
|
54
|
-
autoload :
|
55
|
-
autoload :
|
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
|
|
data/lib/sufia/controller.rb
CHANGED
@@ -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
|