sufia 6.5.0 → 6.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +9 -1
  3. data/Gemfile +1 -1
  4. data/History.md +13 -0
  5. data/README.md +104 -13
  6. data/SUFIA_VERSION +1 -1
  7. data/app/controllers/concerns/sufia/contact_form_controller_behavior.rb +1 -2
  8. data/app/controllers/concerns/sufia/files_controller_behavior.rb +1 -1
  9. data/app/controllers/concerns/sufia/my_controller_behavior.rb +1 -1
  10. data/app/controllers/concerns/sufia/users_controller_behavior.rb +5 -5
  11. data/app/helpers/batch_edits_helper.rb +1 -1
  12. data/app/helpers/concerns/sufia/facets_helper_behavior.rb +15 -0
  13. data/app/helpers/facets_helper.rb +1 -10
  14. data/app/helpers/sufia/sufia_helper_behavior.rb +13 -7
  15. data/app/models/contact_form.rb +1 -1
  16. data/app/models/content_block.rb +3 -3
  17. data/app/presenters/sufia/version_presenter.rb +1 -1
  18. data/app/views/records/show_fields/_rights.html.erb +1 -2
  19. data/app/views/users/_contributions.html.erb +0 -1
  20. data/app/views/users/_profile_tabs.html.erb +3 -3
  21. data/app/views/users/_proxies.html.erb +8 -7
  22. data/config/locales/sufia.en.yml +5 -0
  23. data/lib/generators/sufia/templates/catalog_controller.rb +1 -1
  24. data/lib/sufia.rb +13 -4
  25. data/lib/sufia/arkivo/metadata_munger.rb +2 -2
  26. data/lib/sufia/arkivo/schema_validator.rb +1 -1
  27. data/lib/sufia/version.rb +1 -1
  28. data/spec/controllers/generic_files_controller_spec.rb +8 -8
  29. data/spec/helpers/sufia_helper_spec.rb +13 -1
  30. data/spec/models/file_download_stat_spec.rb +4 -4
  31. data/spec/models/file_view_stat_spec.rb +4 -4
  32. data/spec/views/dashboard/index_spec.rb +3 -3
  33. data/spec/views/records/show_fields/_rights.html.erb_spec.rb +19 -0
  34. data/tasks/release.rake +1 -1
  35. metadata +8 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3e188dc963a308bd78feb2a92a99548eb2b641d6
4
- data.tar.gz: a5e2f06bbe6f5d816541b523f8346448958b00c2
3
+ metadata.gz: 9c1e5c64eca348793606e623debb1ad8bd047b46
4
+ data.tar.gz: 5f81c3cbf777333d417103baf8bea1d32dd087b2
5
5
  SHA512:
6
- metadata.gz: ee2f8d43dd936f3fe4586da46a0de8215f4abcac9f93728c5f7ea88fcde725d0aa12810bbe20b008dcc2212a7d038af3b0ac61be8d9c28997fabb30f17dac517
7
- data.tar.gz: 6ed19074ad147367a53b8d5a15d39ecab27aea1b2d2146dd71db9dceeaa1895cfccbc1e4e1281e35f04807fc591f31abf513ad32d8f2d7229e97450048f6a389
6
+ metadata.gz: 9ae3c7d7685f039792cceb23ae03c31d43e527e35235733a55cd050fd09fd66422825bbe10ba818c8f880b86ece6eb420425d41c96a3f1a097565cae7cf701d0
7
+ data.tar.gz: a3b315a19b8bee86f65455aa2bb686c2e41254f6e17d29d62c78c0a6698a3fe05909be953f9b7bfccb15eba8184b7cf8574648a371ed6bc8e3e246d0217f9ddd
@@ -1,7 +1,7 @@
1
1
  require: rubocop-rspec
2
2
 
3
3
  AllCops:
4
- RunRailsCops: true
4
+ TargetRubyVersion: 2.2
5
5
  DisplayCopNames: true
6
6
  Include:
7
7
  - '**/Rakefile'
@@ -13,6 +13,11 @@ AllCops:
13
13
  - 'spec/internal/**/*'
14
14
  - 'sufia-models/app/models/concerns/sufia/generic_file/export.rb'
15
15
 
16
+ Lint/ImplicitStringConcatenation:
17
+ Exclude:
18
+ - 'lib/generators/**/*'
19
+ - 'sufia-models/lib/generators/**/*'
20
+
16
21
  Metrics/LineLength:
17
22
  Enabled: false
18
23
 
@@ -119,6 +124,9 @@ Style/ClassVars:
119
124
  Style/SignalException:
120
125
  Enabled: false
121
126
 
127
+ Rails:
128
+ Enabled: true
129
+
122
130
  Rails/Output:
123
131
  Exclude:
124
132
  - 'lib/generators/**/*'
data/Gemfile CHANGED
@@ -12,7 +12,7 @@ group :development, :test do
12
12
  gem "simplecov", require: false
13
13
  gem 'byebug' unless ENV['CI']
14
14
  gem 'coveralls', require: false
15
- gem 'rubocop', require: false
15
+ gem 'rubocop', '~> 0.36', require: false
16
16
  gem 'rubocop-rspec', require: false
17
17
  end
18
18
 
data/History.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # History of Sufia releases
2
2
 
3
+ ## 6.6.0
4
+ * Update background workers doc [E. Lynette Rayle]
5
+ * Replaces table rows with an unordered list to make html valid, fixes #1058 [Adam Wead]
6
+ * Fix duplicative labels on show pages [Adam Wead]
7
+ * Add default metadata help for collection fixes #1057 [Adam Wead]
8
+ * Pin Sufia 6 to hydra-head 9.5 [Adam Wead]
9
+ * Updating to Rubocop 0.36 [Adam Wead]
10
+ * Reindex generic_files in background from batch_update_job [E. Lynette Rayle]
11
+ * Include the name of the file if it fails to upload [Adam Wead]
12
+ * Fix intermittent failure to add file to collection [E. Lynette Rayle]
13
+ * Don't generate auto_link on a non-url rights statement, fixes projecthydra/sufia#1356 [Anna Headley]
14
+ * Use lockable module to prevent race conditions in Batches. [Michael J. Giarlo]
15
+
3
16
  ## 6.5.0
4
17
  * Remove unnecessary require [Justin Coyne]
5
18
  * Option to show collection facet in Dashboard and search results [E. Lynette Rayle]
data/README.md CHANGED
@@ -26,8 +26,13 @@
26
26
  * [Install Sufia](#install-sufia)
27
27
  * [Database tables and indexes](#database-tables-and-indexes)
28
28
  * [Solr and Fedora](#solr-and-fedora)
29
- * [Start background workers](#start-background-workers)
30
- * [Monitor background workers](#monitor-background-workers)
29
+ * [Background Workers](#background-workers)
30
+ * [Resque Terminology](#resque-terminology)
31
+ * [Configure Resque](#configure-resque)
32
+ * [Start Worker Pool](#start-worker-pool)
33
+ * [Restarting Worker Pool](#restarting-worker-pool)
34
+ * [Expected processes for Resque -- Resolving Unexpected Behaviors and Failures](#expected-processes-for-resque----resolving-unexpected-behaviors-and-failures)
35
+ * [Monitor background workers](#monitor-background-workers)
31
36
  * [Audiovisual transcoding](#audiovisual-transcoding)
32
37
  * [User interface](#user-interface)
33
38
  * [Integration with Dropbox, Box, etc.](#integration-with-dropbox-box-etc)
@@ -90,7 +95,7 @@ If you have questions or need help, please email [the Hydra community tech list]
90
95
  # Creating a Sufia-based app
91
96
 
92
97
  This document contains instructions specific to setting up an app with __Sufia
93
- v6.5.0__. If you are looking for instructions on installing a different
98
+ v6.6.0__. If you are looking for instructions on installing a different
94
99
  version, be sure to select the appropriate branch or tag from the drop-down
95
100
  menu above.
96
101
 
@@ -142,7 +147,7 @@ rails new my_app
142
147
  Add the following lines to your application's Gemfile.
143
148
 
144
149
  ```
145
- gem 'sufia', '6.5.0'
150
+ gem 'sufia', '6.6.0'
146
151
  gem 'kaminari', github: 'jcoyne/kaminari', branch: 'sufia' # required to handle pagination properly in dashboard. See https://github.com/amatsuda/kaminari/pull/322
147
152
  ```
148
153
 
@@ -181,33 +186,119 @@ rake sufia:jetty:config
181
186
  rake jetty:start
182
187
  ```
183
188
 
184
- ## Start background workers
189
+ ## Background Workers
185
190
 
186
- Sufia uses a queuing system named Resque to manage long-running or slow processes. Resque relies on the [Redis](http://redis.io/) key-value store, so [Redis](http://redis.io/) must be installed *and running* on your system in order for background workers to pick up jobs.
191
+ Reference: https://github.com/resque/resque
187
192
 
188
- Unless Redis has already been started, you will want to start it up. You can do this either by calling the `redis-server` command, or if you're on certain Linuxes, you can do this via `sudo service redis-server start`.
193
+ ### Resque Terminology
189
194
 
190
- Next you will need to start up the Resque workers provided by Sufia. The following command will run until you stop it, so you may want to do this in a dedicated terminal.
195
+ <dl>
196
+ <dt>resque</dt>
197
+ <dd>resque is a <a href="https://en.wikipedia.org/wiki/Message_queue">message queue</a> that is used by Sufia to manage long-running or slow processes.</dd>
191
198
 
199
+ <dt>pools</dt>
200
+ <dd>resque-pool is a tool for managing (starting, stopping) and configuring a bunch of resque worker processes. See Configure Resque below for more information.</dd>
201
+
202
+ <dt>workers</dt>
203
+ <dd>Workers run the background jobs. Each worker has a copy of the rails-app which has the jobs code in `app/jobs` or `sufia-models/app/jobs`. The workers listen to queues (by polling redis) and pull off messages waiting on the queue. Once a worker pulls a message, it will execute the background job encoded in the json message. A worker can be dedicated to a single queue or may listen to multiple queues. Multiple workers can listen to the same queue.</dd>
204
+
205
+ <dt>queue</dt>
206
+ <dd>Messages are sent to a queue where they wait until a worker is ready to process the message. Sufia defines a number of queues for processing different background jobs (e.g. batch_update, characterize, etc.). There could have been one queue to process all messages, but Sufia decided to have specialized queues.</dd>
207
+
208
+ <dt>message</dt>
209
+ <dd>Messages encode in json what job should be run. It includes the name of the method to execute in background and any parameters to pass to the method.</dd>
210
+
211
+ <dt>redis</dt>
212
+ <dd><a href="http://redis.io/">Redis</a> is a key-value store. Resque uses redis to track messages in the queue.</dd>
213
+ </dl>
214
+
215
+ ### Configure Resque
216
+
217
+ Configuration File: `config/resque-pool.yml`.
218
+
219
+ Minimal configuration: Create 1 worker and all queues are processed by this worker.
220
+
221
+ ```
222
+ "*": 1
223
+ ```
224
+
225
+ Typical configuration: ([Scholarsphere example](https://github.com/psu-stewardship/scholarsphere/blob/develop/config/resque-pool.yml))
226
+
227
+ ```
228
+ batch_update: 3
229
+ derivatives: 1
230
+ resolrize: 1
231
+ audit: 2
232
+ event: 5
233
+ import_url: 3
234
+ sufia: 1
235
+ "*": 1
236
+ ```
237
+
238
+ Each line defines a queue name and how many workers should be created to process that queue.
239
+
240
+ ### Start Worker Pool
241
+
242
+ **Prerequisite:** [Redis](http://redis.io/) must be installed *and running* on your system in order for background workers to pick up jobs. Unless Redis has already been started, you will want to start it up. You can do this either by calling the `redis-server` command, or if you're on certain Linuxes, you can do this via `sudo service redis-server start`.
243
+
244
+ OPTION 1: Start 1 worker (ignores the configuration file): The following command will run until you stop it, so you may want to do this in a dedicated terminal and would typically be used during development only.
245
+
246
+ **IMPORTANT:** Change directories to the root of the rails app before executing.
192
247
  ```
193
248
  RUN_AT_EXIT_HOOKS=true TERM_CHILD=1 QUEUE=* rake environment resque:work
194
249
  ```
195
250
 
196
- Or, if you prefer (e.g., in production-like environments), you may want to set up a `config/resque-pool.yml` file -- [here is a simple example](https://github.com/projecthydra/sufia/blob/master/sufia-models/lib/generators/sufia/models/templates/config/resque-pool.yml) -- and run `resque-pool` (at the root of your rails app) which will manage your background workers in a dedicated process.
251
+ OPTION 2: Start workers based on configuration: Typically used for production, and can be used for development. See configuration examples above.
197
252
 
253
+ **IMPORTANT:** Change directories to the root of the rails app before executing.
198
254
  ```
199
255
  RUN_AT_EXIT_HOOKS=true TERM_CHILD=1 bundle exec resque-pool --daemon --environment development start
200
256
  ```
201
257
 
202
258
  Occasionally, Resque may not give background jobs a chance to clean up temporary files. The `RUN_AT_EXIT_HOOKS` variable allows Resque to do so. The `TERM_CHILD` variable allows workers to terminate gracefully rather than interrupting currently running workers. For more information on the signals that Resque responds to, see the [resque-pool documentation](https://github.com/nevans/resque-pool#signals).
203
259
 
204
- See https://github.com/defunkt/resque for more options. If you use resque-pool, you may also be interested in a shell script to help manage it. [Here is an example](https://github.com/psu-stewardship/scholarsphere/blob/develop/script/restart_resque.sh) which you can adapt for your own needs.
260
+ ### Restarting Worker Pool
261
+
262
+ **IMPORTANT:** Change directories to the root of the rails app before executing.
263
+
264
+ Script to restart worker pool: [restart-pool](https://github.com/psu-stewardship/scholarsphere/blob/develop/script/restart_resque.sh)
265
+
266
+ You may want to adjust it to meet your needs.
267
+
268
+ NOTE: The default location for the pid file is the tmp directory. You will want to update RESQUE_POOL_PIDFILE to point to the location where your pid file is generated if you use a location other than the default.
269
+
270
+ ### Expected processes for Resque -- Resolving Unexpected Behaviors and Failures
271
+
272
+ The code executed by workers should stay in sync with changes you make to your rails app. If the code isn't staying in sync, you may have more than one resque-pool process running. You can also see unusual behaviors if more than one redis-server is running. The information below describes the processes that will be running when everything is operating correctly.
273
+
274
+ You should see 1 redis-server process.
275
+ ```
276
+ $ ps -ef | grep redis-server
277
+ user1 7982 7882 0 01:26 pts/3 00:00:00 grep redis-server
278
+ root 8398 1 0 00:08 ? 00:00:04 /usr/local/bin/redis-server 0.0.0.0:6379
279
+ ```
280
+ NOTE: If you see multiple redis-server processes running, kill each and start redis-server again. You should only have one redis-server process running.
281
+
282
+
283
+ You should see 1 resque-pool process.
284
+ ```
285
+ $$ ps -ef | grep resque-pool
286
+ user1 8059 7882 0 01:27 pts/3 00:00:00 grep resque-pool
287
+ root 8416 1 0 00:08 ? 00:00:08 resque-pool-master[agriknowledge]: managing [8653]
288
+ ```
289
+
290
+ You should see at least one worker process waiting.
291
+ ```
292
+ $$ ps -ef | grep resque | grep Waiting
293
+ root 8653 8416 0 00:08 ? 00:00:01 resque-1.25.2: Waiting for *
294
+ ```
295
+ NOTE: If you see multiple resque-pool processes running, kill each AND all the resque Waiting processes as well. Start resque-pool again. You should only have one resque-pool process running. But you may have multiple worker processes running.
205
296
 
206
- ## Monitor background workers
297
+ ### Monitor background workers
207
298
 
208
- Edit config/initializers/resque_admin.rb so that ResqueAdmin#matches? returns a true value for the user/s who should be able to access this page. One fast way to do this is to return current_user.admin? and add an admin? method to your user model which checks for specific emails.
299
+ Edit `config/initializers/resque_admin.rb` so that ResqueAdmin#matches? returns a true value for the user/s who should be able to access this page. One fast way to do this is to return current_user.admin? and add an admin? method to your user model which checks for specific emails or the admin role. See [Admin Users](#admin-users) for information on how to add users with the admin role.
209
300
 
210
- Then you can view jobs at the admin/queues route.
301
+ Then you can view jobs at the `admin/queues` route.
211
302
 
212
303
  ## Audiovisual transcoding
213
304
 
@@ -1 +1 @@
1
- 6.5.0
1
+ 6.6.0
@@ -12,12 +12,11 @@ module Sufia
12
12
  flash.now[:notice] = 'Thank you for your message!'
13
13
  after_deliver
14
14
  @contact_form = ContactForm.new
15
- render :new
16
15
  else
17
16
  flash.now[:error] = 'Sorry, this message was not sent successfully. '
18
17
  flash.now[:error] << @contact_form.errors.full_messages.map(&:to_s).join(",")
19
- render :new
20
18
  end
19
+ render :new
21
20
  rescue
22
21
  flash.now[:error] = 'Sorry, this message was not delivered.'
23
22
  render :new
@@ -106,7 +106,7 @@ module Sufia
106
106
  end
107
107
  rescue => error
108
108
  logger.error "GenericFilesController::create rescued #{error.class}\n\t#{error}\n #{error.backtrace.join("\n")}\n\n"
109
- json_error "Error occurred while creating generic file."
109
+ json_error "Error occurred while creating generic file.", file.original_filename
110
110
  ensure
111
111
  # remove the tempfile (only if it is a temp file)
112
112
  file.tempfile.delete if file.respond_to?(:tempfile)
@@ -48,7 +48,7 @@ module Sufia
48
48
  @all_checked = (count_on_page == @document_list.count)
49
49
  @entire_result_set_selected = @response.response["numFound"] == batch_size
50
50
  @batch_size_on_other_page = batch_size - count_on_page
51
- @batch_part_on_other_page = (@batch_size_on_other_page) > 0
51
+ @batch_part_on_other_page = @batch_size_on_other_page > 0
52
52
 
53
53
  @add_files_to_collection = params.fetch(:add_files_to_collection, '')
54
54
 
@@ -28,11 +28,11 @@ module Sufia::UsersControllerBehavior
28
28
 
29
29
  # Display user profile
30
30
  def show
31
- if @user.respond_to? :profile_events
32
- @events = @user.profile_events(100)
33
- else
34
- @events = []
35
- end
31
+ @events = if @user.respond_to? :profile_events
32
+ @user.profile_events(100)
33
+ else
34
+ []
35
+ end
36
36
  @trophies = @user.trophy_files
37
37
  @followers = @user.followers
38
38
  @following = @user.all_following
@@ -6,6 +6,6 @@ module BatchEditsHelper
6
6
  end
7
7
 
8
8
  def render_check_all
9
- render partial: 'batch_edits/check_all' unless params[:controller].match("my/collections")
9
+ render partial: 'batch_edits/check_all' unless params[:controller] =~ /my\/collections/
10
10
  end
11
11
  end
@@ -0,0 +1,15 @@
1
+ module Sufia
2
+ module FacetsHelperBehavior
3
+ extend ActiveSupport::Concern
4
+
5
+ def display_collection_facet
6
+ if Sufia.config.collection_facet == :public
7
+ true
8
+ elsif Sufia.config.collection_facet == :user && current_user
9
+ true
10
+ else
11
+ false
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,13 +1,4 @@
1
1
  module FacetsHelper
2
2
  include Blacklight::FacetsHelperBehavior
3
-
4
- def display_collection_facet
5
- if Sufia.config.collection_facet == :public
6
- true
7
- elsif Sufia.config.collection_facet == :user && current_user
8
- true
9
- else
10
- false
11
- end
12
- end
3
+ include Sufia::FacetsHelperBehavior
13
4
  end
@@ -113,14 +113,19 @@ module Sufia
113
113
  link_to(display, link_url)
114
114
  end
115
115
 
116
- def iconify_auto_link(text, showLink = true)
116
+ def iconify_auto_link(text, show_link = true)
117
117
  # this block is only executed when a link is inserted;
118
118
  # if we pass text containing no links, it just returns text.
119
119
  auto_link(text) do |value|
120
- "<i class='glyphicon glyphicon-new-window'></i>#{('&nbsp;' + value) if showLink}<br />"
120
+ "<i class='glyphicon glyphicon-new-window'></i>#{('&nbsp;' + value) if show_link}<br />"
121
121
  end
122
122
  end
123
123
 
124
+ def iconify_link(text)
125
+ # different from above in that if text is not a url, return nil.
126
+ iconify_auto_link(text, false) if is_url?(text)
127
+ end
128
+
124
129
  def link_to_profile(login)
125
130
  user = ::User.find_by_user_key(login)
126
131
  return login if user.nil?
@@ -152,11 +157,8 @@ module Sufia
152
157
  # If they are in the dashboard, then the search defaults to the user's files and not
153
158
  # all of Sufia.
154
159
  def current_search_parameters
155
- if on_the_dashboard?
156
- return nil
157
- else
158
- return params[:q]
159
- end
160
+ return if on_the_dashboard?
161
+ params[:q]
160
162
  end
161
163
 
162
164
  # Depending on which page we're landed on, we'll need to set the appropriate action url for
@@ -191,6 +193,10 @@ module Sufia
191
193
  user.respond_to?(:name) ? "#{user.name} (#{user_key})" : user_key
192
194
  end
193
195
 
196
+ def is_url?(str)
197
+ str =~ /\A#{URI.regexp(['http', 'https'])}\z/
198
+ end
199
+
194
200
  private
195
201
 
196
202
  def search_action_for_dashboard
@@ -7,7 +7,7 @@ class ContactForm < MailForm::Base
7
7
  ["Browsing and searching", "Browsing and searching"],
8
8
  ["Reporting a problem", "Reporting a problem"],
9
9
  ["General inquiry or request", "General inquiry or request"]
10
- ]
10
+ ].freeze
11
11
  attribute :contact_method, captcha: true
12
12
  attribute :category, validate: true
13
13
  attribute :name, validate: true
@@ -1,7 +1,7 @@
1
1
  class ContentBlock < ActiveRecord::Base
2
- MARKETING = 'marketing_text'
3
- RESEARCHER = 'featured_researcher'
4
- ANNOUNCEMENT = 'announcement_text'
2
+ MARKETING = 'marketing_text'.freeze
3
+ RESEARCHER = 'featured_researcher'.freeze
4
+ ANNOUNCEMENT = 'announcement_text'.freeze
5
5
 
6
6
  def self.recent_researchers
7
7
  where(name: RESEARCHER).order('created_at DESC')
@@ -8,7 +8,7 @@ module Sufia
8
8
  end
9
9
 
10
10
  delegate :label, :uri, to: :version
11
- alias_method :current?, :current
11
+ alias current? current
12
12
 
13
13
  def current!
14
14
  @current = true
@@ -1,4 +1,3 @@
1
1
  <% record.rights.each do |r| %>
2
- <%=link_to_field('rights',r, Sufia.config.cc_licenses_reverse[r])%> <%= iconify_auto_link(r,false) %><br />
2
+ <%=link_to_field('rights',r, Sufia.config.cc_licenses_reverse[r])%> <%=iconify_link(r) %><br />
3
3
  <% end %>
4
-
@@ -1,5 +1,4 @@
1
1
  <div class="tab-pane active" id="contributions">
2
- <i class="glyphicon glyphicon-star trophy-on"></i> <strong>Highlighted Files</strong>
3
2
  <% if @trophies.count > 0 %>
4
3
  <table>
5
4
  <% @trophies.each do |t| %>
@@ -1,7 +1,7 @@
1
1
  <ul class="nav nav-tabs" id="myTab">
2
- <li class="active"><a href="#contributions"><i class="glyphicon glyphicon-star"></i> Contributions</a></li>
3
- <li><a href="#profile"><i class="glyphicon glyphicon-info-sign"></i> Profile</a></li>
4
- <li><a href="#activity_log" ><i class="glyphicon glyphicon-calendar"></i> Activity</a></li>
2
+ <li class="active"><a href="#contributions"><i class="glyphicon glyphicon-star"></i> <%= I18n.t('sufia.user_profile.tab_highlighted') %></a></li>
3
+ <li><a href="#profile"><i class="glyphicon glyphicon-info-sign"></i> <%= I18n.t('sufia.user_profile.tab_profile') %></a></li>
4
+ <li><a href="#activity_log" ><i class="glyphicon glyphicon-calendar"></i> <%= I18n.t('sufia.user_profile.tab_activity') %></a></li>
5
5
  </ul>
6
6
 
7
7
  <div class="tab-content">
@@ -1,8 +1,9 @@
1
- <div class="tab-pane" id="proxies">
2
- <h2>Proxies</h2>
3
- <% @user.can_receive_deposits_from.each do |depositor| %>
4
- <tr><td><%= link_to_profile depositor.user_key %></td>
5
- </tr>
6
- <% end %>
1
+ <div class="tab-pane" id="proxies">
2
+ <h2>Proxies</h2>
3
+ <ul>
4
+ <% @user.can_receive_deposits_from.each do |depositor| %>
5
+ <li><%= link_to_profile depositor.user_key %></li>
6
+ <% end %>
7
+ </ul>
7
8
 
8
- </div> <!-- /profile -->
9
+ </div> <!-- /profile -->
@@ -146,6 +146,9 @@ en:
146
146
  label: "Zotero Profile"
147
147
  connected: "Connected!"
148
148
  unlinked: "Link with Zotero"
149
+ tab_highlighted: "Highlighted"
150
+ tab_profile: "Profile"
151
+ tab_activity: "Activity"
149
152
  batch:
150
153
  help:
151
154
  title: "Filename will be the default title. Please provide a more meaningful title, and filenames will still be preserved by the system."
@@ -227,6 +230,8 @@ en:
227
230
  language: "The language of the file content."
228
231
  publisher: "The person or group making the file available. Generally this is the institution."
229
232
  rights: "Licensing and distribution information governing access to the file. Select from the provided drop-down list. &lt;em&gt;This is a required field&lt;/em&gt;."
233
+ collection:
234
+ creator_html: 'The person or group responsible for the collection. Usually this is the author of the collected content. Personal names should be entered with the last name first, e.g. "Smith, John." <em>This is a required field</em>.'
230
235
 
231
236
  aria_label:
232
237
  generic_file:
@@ -124,7 +124,7 @@ class CatalogController < ApplicationController
124
124
  title_name = solr_name("title", :stored_searchable)
125
125
  field.solr_parameters = {
126
126
  qf: "#{all_names} file_format_tesim all_text_timv",
127
- pf: "#{title_name}"
127
+ pf: title_name.to_s
128
128
  }
129
129
  end
130
130
 
@@ -32,13 +32,22 @@ module Sufia
32
32
 
33
33
  config.autoload_paths += %W(
34
34
  #{config.root}/app/controllers/concerns
35
+ #{config.root}/app/helpers/concerns
35
36
  #{config.root}/app/models/concerns
36
37
  #{Hydra::Engine.root}/app/models/concerns
37
38
  )
38
39
 
39
- config.assets.paths << config.root.join('vendor', 'assets', 'fonts')
40
- config.assets.precompile << /vjs\.(?:eot|ttf|woff)$/
41
- config.assets.precompile << /fontawesome-webfont\.(?:svg|ttf|woff)$/
42
- config.assets.precompile += %w( ZeroClipboard.swf )
40
+ initializer 'sufia.assets.precompile' do |app|
41
+ app.config.assets.paths << config.root.join('vendor', 'assets', 'fonts')
42
+ app.config.assets.paths << config.root.join('app', 'assets', 'images')
43
+ app.config.assets.paths << config.root.join('app', 'assets', 'images', 'blacklight')
44
+ app.config.assets.paths << config.root.join('app', 'assets', 'images', 'hydra')
45
+ app.config.assets.paths << config.root.join('app', 'assets', 'images', 'site_images')
46
+
47
+ app.config.assets.precompile << /vjs\.(?:eot|ttf|woff)$/
48
+ app.config.assets.precompile << /fontawesome-webfont\.(?:svg|ttf|woff)$/
49
+ app.config.assets.precompile += %w( ZeroClipboard.swf )
50
+ app.config.assets.precompile += %w(*.png *.jpg *.ico *.gif *.svg)
51
+ end
43
52
  end
44
53
  end
@@ -3,13 +3,13 @@ module Sufia
3
3
  CREATOR_TYPES = ['author', 'interviewer', 'director', 'scriptwriter',
4
4
  'inventor', 'composer', 'cartographer', 'programmer', 'artist',
5
5
  'bookAuthor'
6
- ]
6
+ ].freeze
7
7
 
8
8
  CONTRIBUTOR_TYPES = ['contributor', 'editor', 'translator', 'seriesEditor',
9
9
  'interviewee', 'producer', 'castMember', 'sponsor', 'counsel',
10
10
  'attorneyAgent', 'recipient', 'performer', 'wordsBy', 'commenter',
11
11
  'presenter', 'guest', 'podcaster', 'reviewedAuthor', 'cosponsor'
12
- ]
12
+ ].freeze
13
13
 
14
14
  class MetadataMunger
15
15
  def initialize(metadata)
@@ -33,7 +33,7 @@ module Sufia
33
33
  }
34
34
  }
35
35
  }
36
- }
36
+ }.freeze
37
37
 
38
38
  class InvalidItem < RuntimeError
39
39
  end
@@ -1,3 +1,3 @@
1
1
  module Sufia
2
- VERSION = "6.5.0"
2
+ VERSION = "6.6.0".freeze
3
3
  end
@@ -133,7 +133,7 @@ describe GenericFilesController do
133
133
 
134
134
  file = fixture_file_upload('/world.png', 'image/png')
135
135
  xhr :post, :create, files: [file], Filename: "The world", batch_id: "sample_batch_id", permission: { "group" => { "public" => "read" } }, terms_of_service: "1"
136
- expect(response.body).to include("Error occurred while creating generic file.")
136
+ expect(response.body).to include("Error occurred while creating generic file.", "world.png")
137
137
  end
138
138
  end
139
139
  end
@@ -334,11 +334,11 @@ describe GenericFilesController do
334
334
  sign_in user
335
335
  mock_query = double('query')
336
336
  allow(mock_query).to receive(:for_path).and_return([
337
- OpenStruct.new(date: '2014-01-01', pageviews: 4),
338
- OpenStruct.new(date: '2014-01-02', pageviews: 8),
339
- OpenStruct.new(date: '2014-01-03', pageviews: 6),
340
- OpenStruct.new(date: '2014-01-04', pageviews: 10),
341
- OpenStruct.new(date: '2014-01-05', pageviews: 2)])
337
+ OpenStruct.new(date: '2014-01-01', pageviews: 4),
338
+ OpenStruct.new(date: '2014-01-02', pageviews: 8),
339
+ OpenStruct.new(date: '2014-01-03', pageviews: 6),
340
+ OpenStruct.new(date: '2014-01-04', pageviews: 10),
341
+ OpenStruct.new(date: '2014-01-05', pageviews: 2)])
342
342
  allow(mock_query).to receive(:map).and_return(mock_query.for_path.map(&:marshal_dump))
343
343
  profile = double('profile')
344
344
  allow(profile).to receive(:sufia__pageview).and_return(mock_query)
@@ -346,8 +346,8 @@ describe GenericFilesController do
346
346
 
347
347
  download_query = double('query')
348
348
  allow(download_query).to receive(:for_file).and_return([
349
- OpenStruct.new(eventCategory: "Files", eventAction: "Downloaded", eventLabel: "123456789", totalEvents: "3")
350
- ])
349
+ OpenStruct.new(eventCategory: "Files", eventAction: "Downloaded", eventLabel: "123456789", totalEvents: "3")
350
+ ])
351
351
  allow(download_query).to receive(:map).and_return(download_query.for_file.map(&:marshal_dump))
352
352
  allow(profile).to receive(:sufia__download).and_return(download_query)
353
353
  end
@@ -52,7 +52,7 @@ describe SufiaHelper, type: :helper do
52
52
  let(:document) { SolrDocument.new(mime_type_tesim: 'audio/x-wave', id: '1234') }
53
53
  it "shows the audio thumbnail" do
54
54
  rendered = helper.sufia_thumbnail_tag(document, {})
55
- expect(rendered).to match(/src="\/assets\/audio.png"/)
55
+ expect(rendered).to match(/src="\/assets\/audio-.*.png"/)
56
56
  end
57
57
  end
58
58
  context "for an document object" do
@@ -186,4 +186,16 @@ describe SufiaHelper, type: :helper do
186
186
  conn.commit
187
187
  end
188
188
  end
189
+
190
+ describe "#is_url?" do
191
+ it "returns false for non-url string" do
192
+ url = 'all rights reserved'
193
+ expect(helper.is_url?(url)).to be_falsey
194
+ end
195
+
196
+ it "returns true for url" do
197
+ url = 'http://creativecommons.org/licenses/by/3.0/us/'
198
+ expect(helper.is_url?(url)).to be_truthy
199
+ end
200
+ end
189
201
  end
@@ -50,17 +50,17 @@ RSpec.describe FileDownloadStat, type: :model do
50
50
  end
51
51
 
52
52
  it "includes cached ga data" do
53
- expect(described_class.to_flots stats).to include(*download_output)
53
+ expect(described_class.to_flots(stats)).to include(*download_output)
54
54
  end
55
55
 
56
56
  it "caches data" do
57
- expect(described_class.to_flots stats).to include(*download_output)
57
+ expect(described_class.to_flots(stats)).to include(*download_output)
58
58
 
59
59
  # at this point all data should be cached
60
60
  allow(described_class).to receive(:ga_statistics).with(Date.today, file_id).and_raise("We should not call Google Analytics All data should be cached!")
61
61
 
62
62
  stats2 = described_class.statistics(file_id, Date.today - 4.days)
63
- expect(described_class.to_flots stats2).to include(*download_output)
63
+ expect(described_class.to_flots(stats2)).to include(*download_output)
64
64
  end
65
65
  end
66
66
 
@@ -73,7 +73,7 @@ RSpec.describe FileDownloadStat, type: :model do
73
73
  end
74
74
 
75
75
  it "includes cached data" do
76
- expect(described_class.to_flots stats).to include([file_download_stat.date.to_i * 1000, file_download_stat.downloads], *download_output)
76
+ expect(described_class.to_flots(stats)).to include([file_download_stat.date.to_i * 1000, file_download_stat.downloads], *download_output)
77
77
  end
78
78
  end
79
79
  end
@@ -51,18 +51,18 @@ RSpec.describe FileViewStat, type: :model do
51
51
  end
52
52
 
53
53
  it "includes cached ga data" do
54
- expect(described_class.to_flots stats).to include(*view_output)
54
+ expect(described_class.to_flots(stats)).to include(*view_output)
55
55
  end
56
56
 
57
57
  it "caches data" do
58
- expect(described_class.to_flots stats).to include(*view_output)
58
+ expect(described_class.to_flots(stats)).to include(*view_output)
59
59
  expect(stats.first.user_id).to eq user_id
60
60
 
61
61
  # at this point all data should be cached
62
62
  allow(described_class).to receive(:ga_statistics).with(Date.today, file_id).and_raise("We should not call Google Analytics All data should be cached!")
63
63
 
64
64
  stats2 = described_class.statistics(file_id, Date.today - 5.days)
65
- expect(described_class.to_flots stats2).to include(*view_output)
65
+ expect(described_class.to_flots(stats2)).to include(*view_output)
66
66
  end
67
67
  end
68
68
 
@@ -75,7 +75,7 @@ RSpec.describe FileViewStat, type: :model do
75
75
  end
76
76
 
77
77
  it "includes cached data" do
78
- expect(described_class.to_flots stats).to include([file_view_stat.date.to_i * 1000, file_view_stat.views], *view_output)
78
+ expect(described_class.to_flots(stats)).to include([file_view_stat.date.to_i * 1000, file_view_stat.views], *view_output)
79
79
  end
80
80
  end
81
81
  end
@@ -93,9 +93,9 @@ describe "dashboard/index.html.erb", type: :view do
93
93
  before do
94
94
  @now = DateTime.now.to_i
95
95
  assign(:activity, [
96
- { action: 'so and so edited their profile', timestamp: @now },
97
- { action: 'so and so uploaded a file', timestamp: (@now - 360) }
98
- ])
96
+ { action: 'so and so edited their profile', timestamp: @now },
97
+ { action: 'so and so uploaded a file', timestamp: (@now - 360) }
98
+ ])
99
99
  end
100
100
 
101
101
  it "includes recent activities and notifications" do
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe "records/show_fields/_rights.html.erb" do
4
+ let(:file) { object_double(GenericFile.new) }
5
+
6
+ it 'displays links as icons' do
7
+ allow(file).to receive(:[]).with(:rights).and_return(['http://example.org/rights/1'])
8
+ record = Sufia::GenericFilePresenter.new(file)
9
+ render partial: "records/show_fields/rights", locals: { record: record }
10
+ expect(rendered).to include('<a href="http://example.org/rights/1"><i class="glyphicon glyphicon-new-window"></i><br></a>')
11
+ end
12
+
13
+ it 'does not display a link for non-urls' do
14
+ allow(file).to receive(:[]).with(:rights).and_return(['all rights reserved'])
15
+ record = Sufia::GenericFilePresenter.new(file)
16
+ render partial: "records/show_fields/rights", locals: { record: record }
17
+ expect(rendered).not_to include('<i class="glyphicon glyphicon-new-window">')
18
+ end
19
+ end
@@ -29,7 +29,7 @@ directory 'pkg'
29
29
  major, minor, tiny, pre = version.split('.')
30
30
  pre = pre ? pre.inspect : "nil"
31
31
 
32
- ruby.gsub!(/^(\s*)VERSION = ".*?"$/, "\\1VERSION = \"#{version}\"")
32
+ ruby.gsub!(/^(\s*)VERSION = ".*?"\.freeze$/, "\\1VERSION = \"#{version}\".freeze")
33
33
  raise "Could not insert VERSION in #{file}" unless $1
34
34
  File.open(file, 'w') { |f| f.write ruby }
35
35
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sufia
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.5.0
4
+ version: 6.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Coyne
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-12-10 00:00:00.000000000 Z
12
+ date: 2016-01-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sufia-models
@@ -17,14 +17,14 @@ dependencies:
17
17
  requirements:
18
18
  - - '='
19
19
  - !ruby/object:Gem::Version
20
- version: 6.5.0
20
+ version: 6.6.0
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - '='
26
26
  - !ruby/object:Gem::Version
27
- version: 6.5.0
27
+ version: 6.6.0
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: blacklight_advanced_search
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -654,6 +654,7 @@ files:
654
654
  - app/forms/sufia/forms/collection_edit_form.rb
655
655
  - app/forms/sufia/forms/generic_file_edit_form.rb
656
656
  - app/helpers/batch_edits_helper.rb
657
+ - app/helpers/concerns/sufia/facets_helper_behavior.rb
657
658
  - app/helpers/contact_form_helper.rb
658
659
  - app/helpers/content_block_helper.rb
659
660
  - app/helpers/dashboard_helper.rb
@@ -1172,6 +1173,7 @@ files:
1172
1173
  - spec/views/homepage/_featured_works.html.erb_spec.rb
1173
1174
  - spec/views/homepage/_home_header.html.erb_spec.rb
1174
1175
  - spec/views/my/facet.html.erb_spec.rb
1176
+ - spec/views/records/show_fields/_rights.html.erb_spec.rb
1175
1177
  - spec/views/single_use_links/new_download.html.erb_spec.rb
1176
1178
  - spec/views/single_use_links_viewer/show.html.erb_spec.rb
1177
1179
  - spec/views/users/_follower_modal.html.erb_spec.rb
@@ -1245,7 +1247,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1245
1247
  version: '0'
1246
1248
  requirements: []
1247
1249
  rubyforge_project:
1248
- rubygems_version: 2.4.5
1250
+ rubygems_version: 2.2.2
1249
1251
  signing_key:
1250
1252
  specification_version: 4
1251
1253
  summary: Sufia was extracted from ScholarSphere developed by Penn State University
@@ -1458,6 +1460,7 @@ test_files:
1458
1460
  - spec/views/homepage/_featured_works.html.erb_spec.rb
1459
1461
  - spec/views/homepage/_home_header.html.erb_spec.rb
1460
1462
  - spec/views/my/facet.html.erb_spec.rb
1463
+ - spec/views/records/show_fields/_rights.html.erb_spec.rb
1461
1464
  - spec/views/single_use_links/new_download.html.erb_spec.rb
1462
1465
  - spec/views/single_use_links_viewer/show.html.erb_spec.rb
1463
1466
  - spec/views/users/_follower_modal.html.erb_spec.rb