Diff
Added: trunk/app/controllers/contributions_controller.rb (0 => 2315)
--- trunk/app/controllers/contributions_controller.rb (rev 0)
+++ trunk/app/controllers/contributions_controller.rb 2010-01-15 16:59:41 UTC (rev 2315)
@@ -0,0 +1,42 @@
+# myExperiment: app/controllers/contributions_controller.rb
+#
+# Copyright (c) 2009 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class ContributionsController < ApplicationController
+
+ before_filter :get_context, : [:curation]
+
+ def curation
+ @events = CurationEvent.find_all_by_object_type_and_object_id(@contributable.class.name, @contributable.id)
+ end
+
+private
+
+ def get_context
+ begin
+
+ # Determine the class name of the model
+ klass_name = params[:contributable_type].singularize.camelize
+
+ # Process model aliases (e.g. File => Blob)
+ klass_name = Conf.model_aliases[klass_name] if Conf.model_aliases[klass_name]
+
+ @contributable = Object.const_get(klass_name).find_by_id(params[:contributable_id])
+
+ # Abort if the contributable does not exist
+ return false if @contributable.nil?
+
+ # Abort if we're not allowed to see this contributable
+ return false unless Authorization.check(:action ="" 'view', :object => @contributable, :user => current_user)
+
+ rescue
+
+ # In case the const_get doesn't find anything
+ return false
+ end
+
+ return true
+ end
+end
+
Modified: trunk/app/models/blob.rb (2314 => 2315)
--- trunk/app/models/blob.rb 2010-01-14 11:36:04 UTC (rev 2314)
+++ trunk/app/models/blob.rb 2010-01-15 16:59:41 UTC (rev 2315)
@@ -54,10 +54,13 @@
def search_boost
# initial boost depends on viewings count
- boost = contribution.viewings_count
+ boost = contribution.viewings_count / 100
+ # Take curation events into account
+ boost += CurationEvent.curation_score(CurationEvent.find_all_by_object_type_and_object_id('Blob', id))
+
# penalty for no description
- boost = 0 if body.nil? || body.empty?
+ boost -= 20 if body.nil? || body.empty?
boost
end
Added: trunk/app/models/curation_event.rb (0 => 2315)
--- trunk/app/models/curation_event.rb (rev 0)
+++ trunk/app/models/curation_event.rb 2010-01-15 16:59:41 UTC (rev 2315)
@@ -0,0 +1,44 @@
+# myExperiment: app/models/curation_event.rb
+#
+# Copyright (c) 2009 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class CurationEvent < ActiveRecord::Base
+
+ belongs_to :user
+ belongs_to :object, :polymorphic => true
+
+ format_attribute :details
+
+ validates_presence_of :user, :category
+
+ def self.curation_score(events)
+
+ score = 0
+
+ events.each do|event|
+
+ case event.category
+ when 'example'
+ score += 40
+ when 'test'
+ score += 0
+ when 'component'
+ score += 45
+ when 'whole solution'
+ score += 50
+ when 'tutorial'
+ score += 30
+ when 'obsolete'
+ score += 20
+ when 'incomplete'
+ score += 10
+ when 'junk'
+ score -= 50
+ end
+ end
+
+ score
+ end
+end
+
Modified: trunk/app/models/pack.rb (2314 => 2315)
--- trunk/app/models/pack.rb 2010-01-14 11:36:04 UTC (rev 2314)
+++ trunk/app/models/pack.rb 2010-01-15 16:59:41 UTC (rev 2315)
@@ -896,11 +896,15 @@
def search_boost
# initial boost depends on viewings count
- boost = contribution.viewings_count
+ boost = contribution.viewings_count / 100
+ # Take curation events into account
+ boost += CurationEvent.curation_score(CurationEvent.find_all_by_object_type_and_object_id('Pack', id))
+
# penalty for no description
- boost = 0 if description.nil? || description.empty?
+ boost -= 20 if description.nil? || description.empty?
+ puts "id = #{id}, score = #{boost}"
boost
end
end
Modified: trunk/app/models/user.rb (2314 => 2315)
--- trunk/app/models/user.rb 2010-01-14 11:36:04 UTC (rev 2314)
+++ trunk/app/models/user.rb 2010-01-15 16:59:41 UTC (rev 2315)
@@ -25,6 +25,8 @@
has_many :experiments, :as => :contributor,
:conditions => ["contributor_type = ?", "User"]
+ has_many :curation_events, :dependent => :destroy
+
def self.most_recent(limit=5)
self.find(:all,
:order => "users.created_at DESC",
Modified: trunk/app/models/workflow.rb (2314 => 2315)
--- trunk/app/models/workflow.rb 2010-01-14 11:36:04 UTC (rev 2314)
+++ trunk/app/models/workflow.rb 2010-01-15 16:59:41 UTC (rev 2315)
@@ -286,10 +286,13 @@
def search_boost
# initial boost depends on viewings count
- boost = contribution.viewings_count
+ boost = contribution.viewings_count / 100
+ # Take curation events into account
+ boost += CurationEvent.curation_score(CurationEvent.find_all_by_object_type_and_object_id('Workflow', id))
+
# penalty for no description
- boost = 0 if body.nil? || body.empty?
+ boost -= 20 if body.nil? || body.empty?
boost
end
Modified: trunk/app/views/blobs/show.rhtml (2314 => 2315)
--- trunk/app/views/blobs/show.rhtml 2010-01-14 11:36:04 UTC (rev 2314)
+++ trunk/app/views/blobs/show.rhtml 2010-01-15 16:59:41 UTC (rev 2315)
@@ -106,6 +106,8 @@
<%= render :partial => "contributions/credits_attributions_box", :locals => { :contributable => @blob, :edit_path => edit_file_path(@blob) } %>
+ <%= render :partial => "contributions/curation_box", :locals => { :contributable => @blob } %>
+
<%= render :partial => "tags/tags_box", :locals => { :taggable => @blob,
:owner_id => ((@blob.contributor_type == 'User') ? @blob.contributor_id : nil),
:add_path => tag_file_path(@blob),
Modified: trunk/app/views/contributions/_breadcrumbs.rhtml (2314 => 2315)
--- trunk/app/views/contributions/_breadcrumbs.rhtml 2010-01-14 11:36:04 UTC (rev 2314)
+++ trunk/app/views/contributions/_breadcrumbs.rhtml 2010-01-15 16:59:41 UTC (rev 2315)
@@ -1,15 +1,8 @@
-<li><%= link_to 'Contributions', contributions_path %></li>
-
-<% if ["show", "new", "edit"].include? controller.action_name.to_s %>
+<% if controller.action_name == 'curation' %>
+ <li><%= link_to(params[:contributable_type].humanize.capitalize, "/#{params[:contributable_type]}") %></li>
<li><b>»</b></li>
-
- <% case controller.action_name.to_s; when "show" %>
- <li><%= link_to "View: #{contributable(@contribution.contributable_id, @contribution.contributable_type, false)}", contribution_path(@contribution) %></li>
- <% when "new" %>
- <li><%= link_to "New Contribution", new_contribution_path(@contribution) %></li>
- <% when "edit" %>
- <li><%= link_to "Edit: #{contributable(@contribution.contributable_id, @contribution.contributable_type, false)}", edit_contribution_path(@contribution) %>
- <% else %>
- <!-- no breadcrumb -->
- <% end %>
+ <li><%= link_to(@contributable.label, "/#{params[:contributable_type]}/#{params[:contributable_id]}") %></li>
+ <li><b>»</b></li>
+ <li>Curation</li>
<% end %>
+
Added: trunk/app/views/contributions/_curation_box.rhtml (0 => 2315)
--- trunk/app/views/contributions/_curation_box.rhtml (rev 0)
+++ trunk/app/views/contributions/_curation_box.rhtml 2010-01-15 16:59:41 UTC (rev 2315)
@@ -0,0 +1,28 @@
+<% if current_user.class == User && Conf.curators.include?(current_user.username) %>
+
+ <% curation_events = CurationEvent.find_all_by_object_type_and_object_id(contributable.class.name, contributable.id) %>
+
+ <div class="contribution_section_box">
+ <p class="heading" style="margin-bottom: 0; padding-bottom: 0;">
+ <%= info_icon_with_tooltip("How have the curators of #{Conf.sitename}" +
+ " classified this #{visible_name(contributable)}?") %>
+ Scope and Quality
+ </p>
+
+ <% if curation_events.length > 0 %>
+ <div style="font-size: 85%;">
+ <p>The scope and quality of this Workflow has been classified by our curators as:</p>
+ </div>
+ <br />
+ <% curation_events.group_by do |e| e.category end.keys.sort.each do |category| %>
+ <div class="quality"><%= category.capitalize %></div>
+ <% end %>
+ <br />
+ <div style="font-size: 85%;">
+ <%= link_to('See breakdown', url_for(:controller => 'contributions', :action ="" 'curation', :contributable_type => contributable.class.name.underscore.pluralize, :contributable_id => contributable.id)) %>
+ </div>
+ <% else %>
+ <p class="none_text">No curators have classified this <%= visible_name(contributable) %> yet.</p>
+ <% end %>
+ </div>
+<% end %>
Added: trunk/app/views/contributions/curation.rhtml (0 => 2315)
--- trunk/app/views/contributions/curation.rhtml (rev 0)
+++ trunk/app/views/contributions/curation.rhtml 2010-01-15 16:59:41 UTC (rev 2315)
@@ -0,0 +1,44 @@
+<% t "#{h @contributable.label} curation breakdown" -%>
+
+<h1>Curation breakdown</h1>
+
+<% if current_user != 0 && Conf.curators.include?(current_user.username) %>
+
+ <div class="curation_events">
+ <ul>
+ <% @events.each do |event| %>
+ <li>
+ <table class="comment">
+ <tr>
+ <td class="avatar" rowspan="3">
+ <%= contributor(event.user_id, 'User', true, 60) %>
+ </td>
+ <td class="header" height="1.2em">
+ <%= datetime event.created_at -%>
+ <% if event.updated_at != nil && event.updated_at != event.created_at %>
+ <b><br />Updated: <%= datetime event.updated_at -%></b>
+ <% end %>
+ </td>
+ </tr>
+ <tr>
+ <td class="content">
+ <div class="quality"><%= event.category.capitalize %></div>
+ <%= event.details_html %>
+ </td>
+ </tr>
+ <tr>
+ <td style="text-align: right; padding-right: 1em;">
+ </td>
+ </tr>
+ </table>
+ </li>
+ <% end %>
+
+ </ul>
+ </div>
+
+<% else %>
+
+ <p>You do not have permission to view this page.</p>
+
+<% end %>
Modified: trunk/app/views/packs/show.rhtml (2314 => 2315)
--- trunk/app/views/packs/show.rhtml 2010-01-14 11:36:04 UTC (rev 2314)
+++ trunk/app/views/packs/show.rhtml 2010-01-15 16:59:41 UTC (rev 2315)
@@ -122,6 +122,8 @@
</p>
</div>
+ <%= render :partial => "contributions/curation_box", :locals => { :contributable => @pack } %>
+
<%= render :partial => "tags/tags_box", :locals => { :taggable => @pack,
:owner_id => ((@pack.contributor_type == 'User') ? @pack.contributor_id : nil),
:add_path => tag_pack_path(@pack),
Modified: trunk/app/views/workflows/show.rhtml (2314 => 2315)
--- trunk/app/views/workflows/show.rhtml 2010-01-14 11:36:04 UTC (rev 2314)
+++ trunk/app/views/workflows/show.rhtml 2010-01-15 16:59:41 UTC (rev 2315)
@@ -271,6 +271,8 @@
<%= render :partial => "contributions/credits_attributions_box", :locals => { :contributable => @workflow, :edit_path => edit_workflow_path(@workflow) } %>
+ <%= render :partial => "contributions/curation_box", :locals => { :contributable => @workflow } %>
+
<%= render :partial => "tags/tags_box", :locals => { :taggable => @workflow,
:owner_id => ((@workflow.contribution.contributor_type == 'User') ? @workflow.contribution.contributor_id : nil),
:add_path => tag_workflow_path(@workflow),
Modified: trunk/config/default_settings.yml (2314 => 2315)
--- trunk/config/default_settings.yml 2010-01-14 11:36:04 UTC (rev 2314)
+++ trunk/config/default_settings.yml 2010-01-15 16:59:41 UTC (rev 2315)
@@ -65,6 +65,20 @@
curators: []
+# curation_types - The curation categories that are available for curators to
+# apply to content
+
+curation_types:
+
+ - example
+ - test
+ - component
+ - whole solution
+ - tutorial
+ - obsolete
+ - incomplete
+ - junk
+
# main_tabs - These are the main tabs of the website. Each entry requires at
# least a label and a link. If you specify a controller in a tab,
# then the tab is shown as selected when the page has been served by
Modified: trunk/config/routes.rb (2314 => 2315)
--- trunk/config/routes.rb 2010-01-14 11:36:04 UTC (rev 2314)
+++ trunk/config/routes.rb 2010-01-15 16:59:41 UTC (rev 2315)
@@ -86,6 +86,15 @@
workflow.resources :reviews
end
+ # curation
+ ['workflows', 'files', 'packs'].each do |contributable_type|
+ map.curation "#{contributable_type}/:contributable_id/curation",
+ :contributable_type => contributable_type,
+ :controller => 'contributions',
+ :action ="" 'curation',
+ :conditions => { :method => :get }
+ end
+
# files (downloadable)
map.resources :files,
:controller => :blobs,
Added: trunk/db/migrate/082_create_curation_events.rb (0 => 2315)
--- trunk/db/migrate/082_create_curation_events.rb (rev 0)
+++ trunk/db/migrate/082_create_curation_events.rb 2010-01-15 16:59:41 UTC (rev 2315)
@@ -0,0 +1,23 @@
+# myExperiment: db/migrate/db/migrate/082_create_curation_events.rb
+#
+# Copyright (c) 2009 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class CreateCurationEvents < ActiveRecord::Migration
+ def self.up
+ create_table :curation_events do |t|
+ t.column :user_id, :integer
+ t.column :category, :string
+ t.column :object_type, :string
+ t.column :object_id, :integer
+ t.column :details, :text
+ t.column :details_html, :text
+ t.column :created_at, :datetime
+ t.column :updated_at, :datetime
+ end
+ end
+
+ def self.down
+ drop_table :curation_events
+ end
+end
Modified: trunk/lib/authorization.rb (2314 => 2315)
--- trunk/lib/authorization.rb 2010-01-14 11:36:04 UTC (rev 2314)
+++ trunk/lib/authorization.rb 2010-01-15 16:59:41 UTC (rev 2315)
@@ -458,7 +458,7 @@
def Authorization.categorize_action(action_name)
case action_name
- when 'show', 'index', 'view', 'search', 'favourite', 'favourite_delete', 'comment', 'comment_delete', 'comments', 'comments_timeline', 'rate', 'tag', 'items', 'statistics', 'tag_suggestions', 'read', 'verify'
+ when 'show', 'index', 'view', 'search', 'favourite', 'favourite_delete', 'comment', 'comment_delete', 'comments', 'comments_timeline', 'rate', 'tag', 'items', 'statistics', 'curation', 'tag_suggestions', 'read', 'verify'
action = ''
when 'edit', 'new', 'create', 'update', 'new_version', 'create_version', 'destroy_version', 'edit_version', 'update_version', 'new_item', 'create_item', 'edit_item', 'update_item', 'quick_add', 'resolve_link', 'process_tag_suggestions'
action = ''
Modified: trunk/lib/conf.rb (2314 => 2315)
--- trunk/lib/conf.rb 2010-01-14 11:36:04 UTC (rev 2314)
+++ trunk/lib/conf.rb 2010-01-15 16:59:41 UTC (rev 2315)
@@ -117,6 +117,10 @@
self.fetch_entry('max_search_size')
end
+ def self.curation_types
+ self.fetch_entry('curation_types')
+ end
+
# This method is required to create an administrator in the test fixtures
def self.admins=(value)
Modified: trunk/lib/rest.rb (2314 => 2315)
--- trunk/lib/rest.rb 2010-01-14 11:36:04 UTC (rev 2314)
+++ trunk/lib/rest.rb 2010-01-15 16:59:41 UTC (rev 2315)
@@ -1636,6 +1636,60 @@
ob.commentable = subject
end
+ # Start of curation hack
+
+ if user && subject && Conf.curators.include?(user.username)
+
+ lines = comment.split("\n")
+ events = []
+ failed = false
+
+ if lines[0] && lines[0].downcase == 'c:'
+ lines[1..-1].each do |line|
+
+ line.strip!
+
+ bits = line.split(" - ")
+
+ if bits.length > 1
+ details = bits[1..-1].join(" - ")
+ else
+ details = nil
+ end
+
+ if bits.length > 0
+ bits[0].split(",").each do |bit|
+
+ bit.downcase!
+ bit.strip!
+
+ if Conf.curation_types.include?(bit)
+ events.push(CurationEvent.new(:category => bit,
+ :object => subject, :user => user, :details => details))
+ else
+ failed = true
+ end
+ end
+ end
+ end
+
+ if failed
+ return rest_response(400, :reason => 'Unrecognised curation term')
+ end
+
+ events.each do |event|
+ event.save
+ end
+
+ subject.solr_save
+
+ return rest_get_request(ob, "comment", user, rest_resource_uri(ob),
+ "comment", { "id" => ob.id.to_s })
+ end
+ end
+
+ # End of curation hack
+
return rest_response(400, :object => ob) unless ob.save
end
Modified: trunk/public/stylesheets/styles.css (2314 => 2315)
--- trunk/public/stylesheets/styles.css 2010-01-14 11:36:04 UTC (rev 2314)
+++ trunk/public/stylesheets/styles.css 2010-01-15 16:59:41 UTC (rev 2315)
@@ -1991,3 +1991,29 @@
white-space: nowrap;
}
+.classification {
+ border: 1px SOLID gray;
+ padding: 3px;
+ padding-left: 6px;
+ padding-right: 6px;
+ background: #ffffd0;
+}
+
+.quality {
+ width: 157px;
+ background: #EEA;
+ border: 1px solid #CCCCAA;
+ margin: 4px;
+ padding: 4px;
+ text-align: center;
+}
+
+.dependencies UL LI {
+ list-style: none;
+}
+
+.curation_events UL LI {
+ list-style: none;
+ padding-top: 1em;
+}
+