myexperiment-hackers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[myexperiment-hackers] [3768] branches/packs: cd ^/branches/packs ; svn


From: noreply
Subject: [myexperiment-hackers] [3768] branches/packs: cd ^/branches/packs ; svn merge -r3667:3767 ^/trunk
Date: Sun, 3 Nov 2013 11:12:47 +0000 (UTC)

Revision
3768
Author
dgc
Date
2013-11-03 11:12:46 +0000 (Sun, 03 Nov 2013)

Log Message

cd ^/branches/packs ; svn merge -r3667:3767 ^/trunk

Modified Paths

Added Paths

Removed Paths

Diff

Modified: branches/packs/Gemfile (3767 => 3768)


--- branches/packs/Gemfile	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/Gemfile	2013-11-03 11:12:46 UTC (rev 3768)
@@ -30,6 +30,7 @@
 gem "open_id_authentication", "~> 1.1.0"
 gem "simple-rss", "~> 1.2.3"
 gem "net-http-persistent", "~> 2.8"
+gem "delayed_job", "~>2.0.4"
 gem "wf4ever-transformation-client", "~> 0.3.0"
 gem "sanitize", "~> 2.0.6"
 

Modified: branches/packs/Rakefile (3767 => 3768)


--- branches/packs/Rakefile	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/Rakefile	2013-11-03 11:12:46 UTC (rev 3768)
@@ -11,6 +11,13 @@
 require 'sunspot/rails/tasks'
 require 'sunspot/solr/tasks'
 
+begin
+  gem 'delayed_job', '~>2.0.4'
+  require 'delayed/tasks'
+rescue LoadError
+  STDERR.puts "Run `rake gems:install` to install delayed_job"
+end
+
 desc 'Rebuild Solr index'
 task "myexp:refresh:solr" do
   require File.dirname(__FILE__) + '/config/environment'
@@ -22,6 +29,28 @@
   Service.solr_reindex
 end
 
+desc 'Start the search engine'
+task "myexp:search:start" do
+  require File.dirname(__FILE__) + '/config/environment'
+
+  search_start
+end
+
+desc 'Stop the search engine'
+task "myexp:search:stop" do
+  require File.dirname(__FILE__) + '/config/environment'
+
+  search_stop
+end
+
+desc 'Restart the search engine'
+task "myexp:search:restart" do
+  require File.dirname(__FILE__) + '/config/environment'
+
+  search_stop
+  search_start
+end
+
 desc 'Refresh contribution caches'
 task "myexp:refresh:contributions" do
   require File.dirname(__FILE__) + '/config/environment'
@@ -360,6 +389,16 @@
   conn.execute('UPDATE content_blobs SET sha1 = SHA1(data), md5 = MD5(data)')
 end
 
+def search_start
+  port = YAML.load(File.read("config/sunspot.yml"))[Rails.env]["solr"]["port"]
+  `sunspot-solr start -p #{port} -s solr -d solr/data --log-file log/sunspot.log >> log/sunspot-solr.out`
+end
+
+def search_stop
+  port = YAML.load(File.read("config/sunspot.yml"))[Rails.env]["solr"]["port"]
+  `sunspot-solr stop -p #{port}`
+end
+
 desc 'Run out-of-date checklists'
 task "myexp:checklists:update" do
   require File.dirname(__FILE__) + '/config/environment'

Modified: branches/packs/app/controllers/previews_controller.rb (3767 => 3768)


--- branches/packs/app/controllers/previews_controller.rb	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/app/controllers/previews_controller.rb	2013-11-03 11:12:46 UTC (rev 3768)
@@ -11,36 +11,42 @@
 
   def show
 
-    auth = request.env["HTTP_AUTHORIZATION"]
-    user = current_user
+# FIXME: This is the temporary workaround for the issue described in 
+#        http://dev.mygrid.org.uk/issues/browse/MYEXP-67 
+#
+#   auth = request.env["HTTP_AUTHORIZATION"]
+#   user = current_user
 
-    if auth and auth.starts_with?("Basic ")
-      credentials = Base64.decode64(auth.sub(/^Basic /, '')).split(':')
-      user = User.authenticate(credentials[0], credentials[1])
+#   if auth and auth.starts_with?("Basic ")
+#     credentials = Base64.decode64(auth.sub(/^Basic /, '')).split(':')
+#     user = User.authenticate(credentials[0], credentials[1])
 
-      if user.nil?
-        render :nothing => true, :status => 401
-        response.headers['WWW-Authenticate'] = "Basic realm=\"#{Conf.sitename} REST API\""
-        return
-      end
-    end
+#     if user.nil?
+#       render :nothing => true, :status => 401
+#       response.headers['WWW-Authenticate'] = "Basic realm=\"#{Conf.sitename} REST API\""
+#       return
+#     end
+#   end
 
     if @context.preview.nil?
       render :nothing => true, :status => 404
       return
     end
 
-    if @context.respond_to?("versioned_resource")
-      auth_object = @context.versioned_resource
-    else
-      auth_object = @context
-    end
+# FIXME: The other part of the temporary workaround decribed in
+#        http://dev.mygrid.org.uk/issues/browse/MYEXP-67 
+#
+#   if @context.respond_to?("versioned_resource")
+#     auth_object = @context.versioned_resource
+#   else
+#     auth_object = @context
+#   end
 
-    if Authorization.check('view', auth_object, user) == false
-      render :nothing => true, :status => 401
-      response.headers['WWW-Authenticate'] = "Basic realm=\"#{Conf.sitename} REST API\""
-      return
-    end
+#   if Authorization.check('view', auth_object, user) == false
+#     render :nothing => true, :status => 401
+#     response.headers['WWW-Authenticate'] = "Basic realm=\"#{Conf.sitename} REST API\""
+#     return
+#   end
 
     type = params[:id]
 

Modified: branches/packs/app/controllers/sessions_controller.rb (3767 => 3768)


--- branches/packs/app/controllers/sessions_controller.rb	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/app/controllers/sessions_controller.rb	2013-11-03 11:12:46 UTC (rev 3768)
@@ -66,7 +66,15 @@
       registration_info = OpenID::SReg::Response.from_success_response(response).data
 
       name = registration_info["fullname"]
+
+      given_name  = session["given_name"].strip
+      family_name = session["family_name"].strip
+
       unless name
+        name = "#{given_name} #{family_name}".strip
+      end
+
+      unless name && !name.empty?
         flash[:notice] ||= ""
         flash[:notice] << "Please enter your name to be displayed to other users of the site.<br/>"
         name = "OpenID User"
@@ -86,6 +94,7 @@
       #end
 
       @user = User.new(:openid_url => response.identity_url, :name => name, #:email => email_to_use
+                       :given_name => given_name, :family_name => family_name,
                        :activated_at => Time.now, :last_seen_at => Time.now)
 
       @user.save
@@ -128,6 +137,9 @@
 
     def open_id_authentication
       openid_url = params[:openid_url]
+
+      session["given_name"] = params[:given_name]
+      session["family_name"] = params[:family_name]
       
       begin
         if request.post?
@@ -160,7 +172,10 @@
   
     def successful_login(user)
       # update "last seen" attribute
-      user.update_attribute(:last_seen_at, Time.now)
+      begin
+        user.update_attribute(:last_seen_at, Time.now)
+      rescue
+      end
       respond_to do |format|
         flash[:notice] = "Logged in successfully. Welcome to #{Conf.sitename}!"
         home_url = url_for(:controller => 'home')

Modified: branches/packs/app/controllers/users_controller.rb (3767 => 3768)


--- branches/packs/app/controllers/users_controller.rb	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/app/controllers/users_controller.rb	2013-11-03 11:12:46 UTC (rev 3768)
@@ -157,11 +157,7 @@
     end
     
     unless params[:user][:name]
-      if params[:user][:username]
-        params[:user][:name] = params[:user][:username].humanize # initializes username (if one isn't entered)
-      else
-        params[:user][:name] = params[:user][:openid_url]
-      end
+      params[:user][:name] = "#{params[:user][:given_name]} #{params[:user][:family_name]}"
     end
     
     # Reset certain fields (to prevent injecting the values)
@@ -254,7 +250,7 @@
           elsif params[:update_type]
             case params[:update_type]
               when "upd_t_up"; flash.now[:notice] = 'You have successfully updated your password'
-              when "upd_t_displname"; flash.now[:notice] = 'You have successfully updated your display name'
+              when "upd_t_name"; flash.now[:notice] = 'You have successfully updated your name'
               when "upd_t_notify"; flash.now[:notice] = 'You have successfully updated notification options'
             end
           else

Modified: branches/packs/app/models/blob.rb (3767 => 3768)


--- branches/packs/app/models/blob.rb	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/app/models/blob.rb	2013-11-03 11:12:46 UTC (rev 3768)
@@ -29,7 +29,7 @@
 
   acts_as_attributor
   acts_as_attributable
-  
+
   has_versions :blob_versions,
 
     :attributes => [ :title, :body, :body_html, :content_type, :content_blob,
@@ -107,6 +107,13 @@
     APIStatistics.statistics(self)
   end
 
+  named_scope :component_profiles, :include => :content_type,
+              :conditions => "content_types.mime_type = 'application/vnd.taverna.component-profile+xml'"
+
+  def component_profile?
+    content_type.mime_type == 'application/vnd.taverna.component-profile+xml'
+  end
+
   def create_research_object
 
     user_path = "/users/#{contributor_id}"

Modified: branches/packs/app/models/curation_event.rb (3767 => 3768)


--- branches/packs/app/models/curation_event.rb	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/app/models/curation_event.rb	2013-11-03 11:12:46 UTC (rev 3768)
@@ -10,7 +10,7 @@
 
   format_attribute :details
 
-  validates_presence_of :user, :category
+  validates_presence_of :category
 
   def label
     category

Modified: branches/packs/app/models/pack.rb (3767 => 3768)


--- branches/packs/app/models/pack.rb	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/app/models/pack.rb	2013-11-03 11:12:46 UTC (rev 3768)
@@ -715,6 +715,22 @@
     return ""
   end
 
+  named_scope :component_families, :include => :tags, :conditions => "tags.name = 'component family'"
+
+  def component_family?
+    tags.any? { |t| t.name == 'component family' }
+  end
+
+  def component_profile
+    entry = contributable_entries.detect { |e| e.contributable_type == 'Blob' && e.contributable && e.contributable.component_profile? }
+    if entry
+      profile = ""
+      profile.find_version(entry.contributable_version) if entry.contributable_version
+    else
+      nil
+    end
+  end
+
   def update_annotations_from_model(user)
 
     title_annotation = research_object.annotations_of_type("title").first

Modified: branches/packs/app/models/user.rb (3767 => 3768)


--- branches/packs/app/models/user.rb	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/app/models/user.rb	2013-11-03 11:12:46 UTC (rev 3768)
@@ -111,6 +111,8 @@
   
   # BEGIN RESTful Authentication #
   attr_accessor :password
+
+  validates_presence_of     :name
   
   validates_presence_of     :username,                   :if => :not_openid?
   validates_presence_of     :password,                   :if => :password_required?
@@ -301,6 +303,8 @@
   if Conf.solr_enable
     searchable :if => :activated_at do
       text :name, :as => 'name', :boost => 2.0
+      text :given_name, :as => 'given_name'
+      text :family_name, :as => 'family_name'
       text :email, :as => 'email' do profile.email end
       text :website, :as => 'website' do profile.website end
       text :body, :as => 'description' do profile.body end

Modified: branches/packs/app/models/workflow.rb (3767 => 3768)


--- branches/packs/app/models/workflow.rb	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/app/models/workflow.rb	2013-11-03 11:12:46 UTC (rev 3768)
@@ -34,6 +34,9 @@
   has_many :workflow_processors, :dependent => :destroy
   has_many :workflow_ports, :dependent => :destroy
   has_many :semantic_annotations, :as => :subject, :dependent => :destroy
+  has_many :curation_events, :as => :object
+  has_many :pack_entries, :as => :contributable, :class_name => 'PackContributableEntry'
+  has_many :packs, :through => :pack_entries
 
   before_validation :check_unique_name
   before_validation :apply_extracted_metadata
@@ -433,6 +436,17 @@
     WsdlDeprecation.find_all_by_wsdl(workflow_processors.map {|wp| wp.wsdl}).group_by {|wd| wd.deprecation_event}
   end
 
+  # TODO: Don't use tags for this
+  named_scope :components, :include => :tags, :conditions => "tags.name = 'component'"
+
+  def component?
+    tags.any? { |t| t.name == 'component' }
+  end
+
+  def component_families
+    self.packs.select { |p| p.component_family? }
+  end
+
   def create_research_object
 
     user_path = "/users/#{contributor_id}"

Modified: branches/packs/app/views/contributions/curation.rhtml (3767 => 3768)


--- branches/packs/app/views/contributions/curation.rhtml	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/app/views/contributions/curation.rhtml	2013-11-03 11:12:46 UTC (rev 3768)
@@ -11,7 +11,11 @@
         <table class="comment">
           <tr>
             <td class="avatar" rowspan="3">
-              <%= contributor(event.user_id, 'User', true, 60) %>
+              <% if event.user %>
+                <%= contributor(event.user_id, 'User', true, 60) %>
+              <% else %>
+                System
+              <% end %>
             </td>
             <td class="header" height="1.2em">
               <%= datetime event.created_at -%>

Modified: branches/packs/app/views/layouts/_myexperiment.html.erb (3767 => 3768)


--- branches/packs/app/views/layouts/_myexperiment.html.erb	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/app/views/layouts/_myexperiment.html.erb	2013-11-03 11:12:46 UTC (rev 3768)
@@ -4,6 +4,9 @@
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
   <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
+  <% unless Conf.google_site_verification.nil? %>
+  <meta name="google-site-verification" content="<%= Conf.google_site_verification -%>" />
+  <% end %>
   <%= t :site => "#{Conf.sitename} &#45; #{controller_visible_name(controller.controller_name.humanize)}", :separator => "&#45;" %>
   <% if @lod_rdf %><link rel="alternate" href="" @lod_rdf -%>" type="application/rdf+xml" title="RDF+XML" /><% end %>
   <% if @lod_xml %><link rel="alternate" href="" @lod_xml -%>" type="application/xml" title="REST XML" /><% end %>

Modified: branches/packs/app/views/users/edit.rhtml (3767 => 3768)


--- branches/packs/app/views/users/edit.rhtml	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/app/views/users/edit.rhtml	2013-11-03 11:12:46 UTC (rev 3768)
@@ -4,13 +4,26 @@
 <% unless @user.errors.empty? -%>
 	<%= link_to "Reset the form to the last saved correct state", edit_user_path(@user) -%>
 <% end -%>
-<h2>Display Name</h2>
+<h2>Name</h2>
 <% form_for(:user, :url ="" user_path(@user), :html => { :method => :put }) do |f| %>
-<%= hidden_field_tag(:update_type, "upd_t_displname") -%>
+<%= hidden_field_tag(:update_type, "upd_t_name") -%>
 <p style="margin-left: 0.1cm">
+    <b>Given Name:</b>
+    <br/>
+    <%= f.text_field :given_name %>
+    <br/>
+    <br/>
+    <b>Family Name:</b>
+    <br/>
+    <%= f.text_field :family_name %>
+    <br/>
+    <br/>
     <b>Display Name:</b>
     <br/>
     <%= f.text_field :name %>
+    <%= info_icon_with_tooltip("The display name is used to show your name in #{Conf.sitename}.  You can change it directly if your name does not follow the form: given name, space, family name.") -%>
+    <br />
+    <br />
 </p>
 <p style="margin-left: 0.1cm">
     <%= submit_tag "Save", :disable_with => 'Saving...' %>

Modified: branches/packs/app/views/users/index.rhtml (3767 => 3768)


--- branches/packs/app/views/users/index.rhtml	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/app/views/users/index.rhtml	2013-11-03 11:12:46 UTC (rev 3768)
@@ -28,13 +28,15 @@
 <% end %>
 <% end -%>
 
-<% unless (active = User.last_active(10)).empty? %>
-  <div class="tabContainer">
-  	<div class="tabTitle">Last Active</div>
-  	<div class="tabContent">
-	    <%= render :partial => "users/table", :locals => { :collection => active } %>
-  	</div>
-  </div>
+<% if admin? %>
+  <% unless (active = User.last_active(10)).empty? %>
+    <div class="tabContainer">
+      <div class="tabTitle">Last Active</div>
+      <div class="tabContent">
+        <%= render :partial => "users/table", :locals => { :collection => active } %>
+      </div>
+    </div>
+  <% end %>
 <% end %>
 
 <% unless (friendliest = User.most_friends).empty? %>

Modified: branches/packs/app/views/users/new.rhtml (3767 => 3768)


--- branches/packs/app/views/users/new.rhtml	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/app/views/users/new.rhtml	2013-11-03 11:12:46 UTC (rev 3768)
@@ -50,7 +50,17 @@
 							<div class="box_simple">
 								<p style="color: #990000; font-weight: bold; font-size: 108%;">First...</p>
 								<p>
-									Provide an <b>email address</b>:
+								  <b>Given name</b>
+									<br />
+								  <%= f.text_field :given_name %>
+								</p>
+								<p>
+								  <b>Family name</b>
+									<br />
+								  <%= f.text_field :family_name %>
+								</p>
+								<p>
+									<b>Email address</b>:
 									<span style="margin-left: 0.5em; font-size: 85%; vertical-align: middle;"><%= link_to_function "Why?" + expand_image("0.2em"), visual_effect(:toggle_blind, "email_why", :duration => 0.3) %></span>
 								</p>
 								<div id="email_why" class="box_dynamic_help" style="display: none;">
@@ -174,6 +184,16 @@
 			
 			<p><b>Don't have an OpenID? Get one FREE from <%= link_to 'myOpenID', "https://www.myopenid.com/" %> or <%= link_to 'other providers', "http://openiddirectory.com/openid-providers-c-1.html" %>.</b></p>
 			
+      <p>
+        <strong>Given name</strong>
+        <br />
+        <%= text_field_tag :given_name, nil, :size => 32 %>
+      </p>
+      <p>
+        <strong>Family name</strong>
+        <br />
+        <%= text_field_tag :family_name, nil, :size => 32 %>
+      </p>
 			<p>
 				<strong>OpenID</strong><br/>
 				<%= text_field_tag 'openid_url', nil, :size => 35 %>

Modified: branches/packs/app/views/workflows/_deprecation_event.html.erb (3767 => 3768)


--- branches/packs/app/views/workflows/_deprecation_event.html.erb	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/app/views/workflows/_deprecation_event.html.erb	2013-11-03 11:12:46 UTC (rev 3768)
@@ -4,7 +4,7 @@
 <% time_string = deprecation_event.date.strftime("#{deprecation_event.date.day.ordinalize} %B %Y") -%>
 <div class="deprecation_event">
   <p>
-    <img src="" style="vertical-align: middle; float: left; margin: 0.5em"/>
+    <img src="" style="vertical-align: middle;"/>
     This workflow uses one or more services that
     <% if deprecation_event.date.past? %>
       are deprecated as of <strong><%= time_string -%></strong>

Copied: branches/packs/config/content_types.yml (from rev 3767, trunk/config/content_types.yml) (0 => 3768)


--- branches/packs/config/content_types.yml	                        (rev 0)
+++ branches/packs/config/content_types.yml	2013-11-03 11:12:46 UTC (rev 3768)
@@ -0,0 +1,4 @@
+component_profile:
+  title: Taverna Component Profile
+  mime_type: application/vnd.taverna.component-profile+xml
+  category: Blob
\ No newline at end of file

Modified: branches/packs/config/default_settings.yml (3767 => 3768)


--- branches/packs/config/default_settings.yml	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/config/default_settings.yml	2013-11-03 11:12:46 UTC (rev 3768)
@@ -339,6 +339,11 @@
 
 cookie_verifier_secret: 64a59b43e7aa93e55a5db119180a2973b584555f71e87388de5c27682407987446a0293dab64f5913cb19ead617893546b3646c98672905a38e6dfbfb5871034
 
+# google_site_verification - Use this to insert a Google site verification code
+#                            into the headers.
+
+google_site_verification:
+
 # google_web_analytics - Enable this to enable Google web analytics.
 
 google_web_analytics:
@@ -540,7 +545,6 @@
     topic_workflow_map: INNER JOIN topic_workflow_map ON contributions.id = topic_workflow_map.workflow_id
     users: INNER JOIN users ON contributions.contributor_type = 'User' AND contributions.contributor_id = users.id
     licences: LEFT OUTER JOIN licenses ON contributions.license_id = licenses.id
-    component_profiles: LEFT OUTER JOIN workflows ON RESULT_TYPE = 'Workflow' AND workflows.id = RESULT_ID LEFT OUTER JOIN component_profiles ON workflows.component_profile_id = component_profiles.id
 
   order:
 
@@ -664,12 +668,6 @@
     label_column: services.monitor_label
     joins: [services]
 
-  - query_option: COMPONENT_PROFILE_ID
-    title: component profile
-    id_column: component_profiles.id
-    label_column: component_profiles.name
-    joins: [component_profiles]
-
   num_options: ["10", "20", "25", "50", "100"]
 
 # initial_filter_size - The number of entries shown for each pivot filter by

Copied: branches/packs/config/initializers/default_content_types.rb (from rev 3767, trunk/config/initializers/default_content_types.rb) (0 => 3768)


--- branches/packs/config/initializers/default_content_types.rb	                        (rev 0)
+++ branches/packs/config/initializers/default_content_types.rb	2013-11-03 11:12:46 UTC (rev 3768)
@@ -0,0 +1,20 @@
+# myExperiment: config/initializers/content_types.rb
+#
+# Copyright (c) 2013 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+# Loads a set default content_types into the database
+
+if ActiveRecord::Base.connection.table_exists?('content_types')
+  content_types = YAML::load_file("config/content_types.yml")
+
+  Rails.logger.debug('Loading content types...')
+  ContentType.transaction do
+    content_types.each do |k,v|
+      unless ContentType.find_by_title_and_mime_type_and_category(v['title'], v['mime_type'], v['category'])
+        Rails.logger.debug("\tCreating content type #{v['title']}: #{v['mime_type']}")
+        ContentType.create(v)
+      end
+    end
+  end
+end

Copied: branches/packs/config/initializers/service_deprecation_watcher.rb (from rev 3767, trunk/config/initializers/service_deprecation_watcher.rb) (0 => 3768)


--- branches/packs/config/initializers/service_deprecation_watcher.rb	                        (rev 0)
+++ branches/packs/config/initializers/service_deprecation_watcher.rb	2013-11-03 11:12:46 UTC (rev 3768)
@@ -0,0 +1,12 @@
+# myExperiment: config/initializers/service_deprecation_watcher.rb
+#
+# Copyright (c) 2013 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+if ActiveRecord::Base.connection.table_exists?('delayed_jobs')
+  Delayed::Worker.backend = :active_record
+
+  unless Delayed::Job.exists?(:handler => ServiceDeprecationJob.new.to_yaml)
+    Delayed::Job.enqueue(ServiceDeprecationJob.new, 1, 5.minutes.from_now)
+  end
+end

Deleted: branches/packs/config/sunspot.yml (3767 => 3768)


--- branches/packs/config/sunspot.yml	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/config/sunspot.yml	2013-11-03 11:12:46 UTC (rev 3768)
@@ -1,18 +0,0 @@
-production:
-  solr:
-    hostname: localhost
-    port: 8983
-    log_level: WARNING
-
-development:
-  solr:
-    hostname: localhost
-    port: 8982
-    log_level: INFO
-
-test:
-  solr:
-    hostname: localhost
-    port: 8981
-    log_level: WARNING
-    

Copied: branches/packs/config/sunspot.yml.pre (from rev 3767, trunk/config/sunspot.yml.pre) (0 => 3768)


--- branches/packs/config/sunspot.yml.pre	                        (rev 0)
+++ branches/packs/config/sunspot.yml.pre	2013-11-03 11:12:46 UTC (rev 3768)
@@ -0,0 +1,18 @@
+production:
+  solr:
+    hostname: localhost
+    port: 8983
+    log_level: WARNING
+
+development:
+  solr:
+    hostname: localhost
+    port: 8982
+    log_level: INFO
+
+test:
+  solr:
+    hostname: localhost
+    port: 8981
+    log_level: WARNING
+    

Modified: branches/packs/config/tables.xml


(Binary files differ)

Copied: branches/packs/db/migrate/20130910094137_create_delayed_jobs.rb (from rev 3767, trunk/db/migrate/20130910094137_create_delayed_jobs.rb) (0 => 3768)


--- branches/packs/db/migrate/20130910094137_create_delayed_jobs.rb	                        (rev 0)
+++ branches/packs/db/migrate/20130910094137_create_delayed_jobs.rb	2013-11-03 11:12:46 UTC (rev 3768)
@@ -0,0 +1,21 @@
+class CreateDelayedJobs < ActiveRecord::Migration
+  def self.up
+    create_table :delayed_jobs, :force => true do |table|
+      table.integer  :priority, :default => 0      # Allows some jobs to jump to the front of the queue
+      table.integer  :attempts, :default => 0      # Provides for retries, but still fail eventually.
+      table.text     :handler                      # YAML-encoded string of the object that will do work
+      table.text     :last_error                   # reason for last failure (See Note below)
+      table.datetime :run_at                       # When to run. Could be Time.zone.now for immediately, or sometime in the future.
+      table.datetime :locked_at                    # Set when a client is working on this object
+      table.datetime :failed_at                    # Set when all retries have failed (actually, by default, the record is deleted instead)
+      table.string   :locked_by                    # Who is working on this object (if locked)
+      table.timestamps
+    end
+	
+    add_index :delayed_jobs, [:priority, :run_at], :name => 'delayed_jobs_priority'
+  end
+  
+  def self.down
+    drop_table :delayed_jobs  
+  end
+end
\ No newline at end of file

Copied: branches/packs/db/migrate/20130930140455_add_given_and_family_name.rb (from rev 3767, trunk/db/migrate/20130930140455_add_given_and_family_name.rb) (0 => 3768)


--- branches/packs/db/migrate/20130930140455_add_given_and_family_name.rb	                        (rev 0)
+++ branches/packs/db/migrate/20130930140455_add_given_and_family_name.rb	2013-11-03 11:12:46 UTC (rev 3768)
@@ -0,0 +1,16 @@
+# myExperiment: db/migrate/20130930140455_add_given_and_family_name.rb
+#
+# Copyright (c) 2007-2013 The University of Manchester, the University of
+# Oxford, and the University of Southampton.  See license.txt for details.
+
+class AddGivenAndFamilyName < ActiveRecord::Migration
+  def self.up
+    add_column :users, :given_name, :string
+    add_column :users, :family_name, :string
+  end
+
+  def self.down
+    remove_column :users, :given_name
+    remove_column :users, :family_name
+  end
+end

Modified: branches/packs/db/schema.rb (3767 => 3768)


--- branches/packs/db/schema.rb	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/db/schema.rb	2013-11-03 11:12:46 UTC (rev 3768)
@@ -9,7 +9,7 @@
 #
 # It's strongly recommended to check this file into your version control system.
 
-ActiveRecord::Schema.define(:version => 20130924164435) do
+ActiveRecord::Schema.define(:version => 20130930140455) do
 
   create_table "activities", :force => true do |t|
     t.string   "subject_type"
@@ -241,6 +241,21 @@
     t.datetime "updated_at"
   end
 
+  create_table "delayed_jobs", :force => true do |t|
+    t.integer  "priority",   :default => 0
+    t.integer  "attempts",   :default => 0
+    t.text     "handler"
+    t.text     "last_error"
+    t.datetime "run_at"
+    t.datetime "locked_at"
+    t.datetime "failed_at"
+    t.string   "locked_by"
+    t.datetime "created_at"
+    t.datetime "updated_at"
+  end
+
+  add_index "delayed_jobs", ["priority", "run_at"], :name => "delayed_jobs_priority"
+
   create_table "deprecation_events", :force => true do |t|
     t.string   "title"
     t.datetime "date"
@@ -878,6 +893,8 @@
     t.datetime "reset_password_code_until"
     t.string   "account_status"
     t.integer  "spam_score"
+    t.string   "given_name"
+    t.string   "family_name"
   end
 
   create_table "viewings", :force => true do |t|

Modified: branches/packs/lib/rest.rb (3767 => 3768)


--- branches/packs/lib/rest.rb	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/lib/rest.rb	2013-11-03 11:12:46 UTC (rev 3768)
@@ -9,6 +9,7 @@
 require 'uri'
 require 'pivoting'
 require 'will_paginate'
+Dir.glob(RAILS_ROOT + '/lib/api/resources/*') {|file| require file}
 
 include LibXML
 
@@ -228,6 +229,7 @@
 
               item_attrs['resource'] = item_uri if item_uri && query["show-resource"] != "no"
               item_attrs['uri'] = rest_access_uri(item) if query["show-uri"] != "no"
+              item_attrs['id'] = item.id.to_s if query["show-id"] != "no"
 
               item_attrs.each do |key,value|
                 el[key] = value
@@ -296,6 +298,7 @@
           resource_uri = rest_resource_uri(item)
           el['resource'] = resource_uri if resource_uri && query["show-resource"] != "no"
           el['uri'] = rest_access_uri(item) if query["show-uri"] != "no"
+          el['id'] = item.id.to_s if query["show-id"] != "no"
           el << item.label if item.respond_to?(:label) && item.label
         end
 
@@ -367,6 +370,7 @@
 
   entity['uri'     ] = uri      if uri && query["show-uri"] != "no"
   entity['resource'] = resource if resource && query["show-resource"] != "no"
+  entity['id'] = ob.id.to_s if query["show-id"] != "no"
   entity['version' ] = version  if version && query["show-version"] != "no"
 
   TABLES['Model'][:data][rest_entity]['REST Attribute'].each do |rest_attribute|
@@ -687,15 +691,12 @@
     when 'Ontology';               return ontology_url(ob)
     when 'Predicate';              return predicate_url(ob)
     when 'Relationship';           return nil
-
     when 'Creditation';            return nil
     when 'Attribution';            return nil
     when 'Tagging';                return nil
-
     when 'WorkflowVersion';        return "#{rest_resource_uri(ob.workflow)}?version=#{ob.version}"
     when 'BlobVersion';            return "#{rest_resource_uri(ob.blob)}?version=#{ob.version}"
     when 'PackVersion';            return pack_version_url(ob, ob.version)
-
     when 'Policy';                 return policy_url(ob)
   end
 
@@ -828,6 +829,7 @@
 
   el['resource'] = resource_uri if resource_uri && query["show-resource"] != "no"
   el['uri'     ] = rest_access_uri(ob) if query["show-uri"] != "no"
+  el['id'] = ob.id.to_s if query["show-id"] != "no"
   el['version' ] = ob.current_version.to_s if ob.respond_to?('current_version') && query["show-version"] != "no"
 
   el << rest_object_label_text(ob) if !skip_text
@@ -835,7 +837,7 @@
   el
 end
 
-def parse_resource_uri(str)
+def  parse_resource_uri(str)
 
   base_uri = URI.parse("#{Conf.base_uri}/")
   uri      = base_uri.merge(str)
@@ -1042,603 +1044,6 @@
   end
 end
 
-def workflow_aux(action, opts = {})
-
-  # Obtain object
-
-  case action
-    when 'create';
-      return rest_response(401, :reason => "Not authorised to create a workflow") unless Authorization.check('create', Workflow, opts[:user], nil)
-      if opts[:query]['id']
-        ob, error = obtain_rest_resource('Workflow', opts[:query]['id'], opts[:query]['version'], opts[:user], action)
-      else
-        ob = Workflow.new(:contributor => opts[:user])
-      end
-    when 'view', 'edit', 'destroy';
-      ob, error = obtain_rest_resource('Workflow', opts[:query]['id'], opts[:query]['version'], opts[:user], action)
-    else
-      raise "Invalid action '#{action}'"
-  end
-
-  return error if ob.nil? # appropriate rest response already given
-
-  if action == "destroy"
-
-    return rest_response(400, :reason => "Cannot delete individual versions") if opts[:query]['version']
-      
-    ob.destroy
-
-  else
-
-    data = ""
-
-    title            = parse_element(data, :text,   '/workflow/title')
-    description      = parse_element(data, :text,   '/workflow/description')
-    license_type     = parse_element(data, :text,   '/workflow/license-type')
-    type             = parse_element(data, :text,   '/workflow/type')
-    content_type     = parse_element(data, :text,   '/workflow/content-type')
-    content          = parse_element(data, :binary, '/workflow/content')
-    preview          = parse_element(data, :binary, '/workflow/preview')
-    svg              = parse_element(data, :text,   '/workflow/svg')
-    revision_comment = parse_element(data, :text,   '/workflow/revision-comment')
-
-    permissions  = data.find_first('/workflow/permissions')
-
-    # build the contributable
-
-    if license_type 
-      if license_type == ""
-        ob.license = nil
-      else
-        ob.license = License.find_by_unique_name(license_type)
-
-        if ob.license.nil?
-          ob.errors.add("License type")
-          return rest_response(400, :object => ob)
-        end
-      end
-    end
-
-    # handle workflow type
-
-    if type
-
-      ob.content_type = ContentType.find_by_title(type)
-
-      if ob.content_type.nil?
-        ob.errors.add("Type")
-        return rest_response(400, :object => ob)
-      end
-
-    elsif content_type
-
-      content_types = ContentType.find_all_by_mime_type(content_type)
-  
-      if content_types.length == 1
-        ob.content_type = content_types.first
-      else
-        if content_types.empty?
-          ob.errors.add("Content type")
-        else
-          ob.errors.add("Content type", "matches more than one registered content type")
-        end
-
-        return rest_response(400, :object => ob)
-      end
-    end
-
-    ob.content_blob_id = ContentBlob.create(:data ="" content).id if content
-
-    # Handle versioned metadata.  Priority:
-    #
-    #   1st = elements in REST request
-    #   2nd = extracted metadata from workflow processor
-    #   3rd = values from previous version
-
-    metadata = Workflow.extract_metadata(:type => ob.content_type.title, :data ="" content)
-
-    if title
-      ob.title = title
-    elsif metadata["title"]
-      ob.title = metadata["title"]
-    end
-
-    if description
-      ob.body = description
-    elsif metadata["description"]
-      ob.body = metadata["description"]
-    end
-
-    # Handle the preview and svg images.  If there's a preview supplied, use
-    # it.  Otherwise auto-generate one if we can.
-
-    begin
-      if preview.nil? and content
-        metadata = Workflow.extract_metadata(:type => ob.content_type.title, :data ="" content)
-        preview = metadata["image"].read if metadata["image"]
-      end
-
-      if preview
-        ob.image = preview
-      end
-
-      if svg.nil? and content
-        metadata = Workflow.extract_metadata(:type => ob.content_type.title, :data ="" content)
-        svg = metadata["image"].read if metadata["image"]
-      end
-
-      if svg
-        ob.svg = svg
-      end
-
-    rescue
-      return rest_response(500, :reason => "Unable to extract metadata")
-    end
-
-    new_version  = action == 'create' && opts[:query]['id'] != nil
-    edit_version = action == 'edit'   && opts[:query]['version'] != nil
-
-    if new_version
-      ob.preview = nil
-      ob[:revision_comments] = revision_comment
-    end
-
-    success = ob.save
-
-    if success
-      case "#{action} #{new_version || edit_version}"
-      when "create false"; Activity.create(:subject => opts[:user], :action ="" 'create', :objekt => ob, :auth => ob)
-      when "create true";  Activity.create(:subject => opts[:user], :action ="" 'create', :objekt => ob.versions.last, :auth => ob)
-      when "edit false";   Activity.create(:subject => opts[:user], :action ="" 'edit', :objekt => ob, :auth => ob)
-      when "edit true";    Activity.create(:subject => opts[:user], :action ="" 'edit', :objekt => ob, :extra => ob.version, :auth => ob.workflow)
-      end
-    end
-
-    return rest_response(400, :object => ob) unless success
-
-    # Elements to update if we're not dealing with a workflow version
-
-    if opts[:query]['version'].nil?
-      update_permissions(ob, permissions, opts[:user])
-    end
-
-    # Extract internals and stuff
-    if ob.is_a?(WorkflowVersion)
-      ob.workflow.extract_metadata
-    else
-      ob.extract_metadata
-    end
-  end
-
-  ob = ob.versioned_resource if ob.respond_to?("versioned_resource")
-
-  rest_get_request(ob, opts[:user], { "id" => ob.id.to_s })
-end
-
-def post_workflow(opts)
-  workflow_aux('create', opts)
-end
-
-def put_workflow(opts)
-  workflow_aux('edit', opts)
-end
-
-def delete_workflow(opts)
-  workflow_aux('destroy', opts)
-end
-
-# file handling
-
-def file_aux(action, opts = {})
-
-  # Obtain object
-
-  case action
-    when 'create';
-      return rest_response(401, :reason => "Not authorised to create a file") unless Authorization.check('create', Blob, opts[:user], nil)
-      if opts[:query]['id']
-        ob, error = obtain_rest_resource('Blob', opts[:query]['id'], opts[:query]['version'], opts[:user], action)
-      else
-        ob = Blob.new(:contributor => opts[:user])
-      end
-    when 'view', 'edit', 'destroy';
-      ob, error = obtain_rest_resource('Blob', opts[:query]['id'], opts[:query]['version'], opts[:user], action)
-    else
-      raise "Invalid action '#{action}'"
-  end
-
-  return error if ob.nil? # appropriate rest response already given
-
-  if action == "destroy"
-
-    return rest_response(400, :reason => "Cannot delete individual versions") if opts[:query]['version']
-      
-    ob.destroy
-
-  else
-
-    data = ""
-
-    title            = parse_element(data, :text,   '/file/title')
-    description      = parse_element(data, :text,   '/file/description')
-    license_type     = parse_element(data, :text,   '/file/license-type')
-    type             = parse_element(data, :text,   '/file/type')
-    filename         = parse_element(data, :text,   '/file/filename')
-    content_type     = parse_element(data, :text,   '/file/content-type')
-    content          = parse_element(data, :binary, '/file/content')
-    revision_comment = parse_element(data, :text,   '/file/revision-comment')
-
-    permissions  = data.find_first('/file/permissions')
-
-    # build the contributable
-
-    ob.title        = title        if title
-    ob.body         = description  if description
-
-    if license_type 
-      if license_type == ""
-        ob.license = nil
-      else
-        ob.license = License.find_by_unique_name(license_type)
-
-        if ob.license.nil?
-          ob.errors.add("License type")
-          return rest_response(400, :object => ob)
-        end
-      end
-    end
-
-    # file name
-
-    if filename && !filename.blank?
-      ob.local_name = filename
-    else
-      if ob.local_name.blank?
-        ob.errors.add("Filename", "missing")
-        return rest_response(400, :object => ob)
-      end
-    end
-   
-    # handle type
-
-    if type
-
-      ob.content_type = ContentType.find_by_title(type)
-
-      if ob.content_type.nil?
-        ob.errors.add("Type")
-        return rest_response(400, :object => ob)
-      end
-
-    elsif content_type
-
-      content_types = ContentType.find_all_by_mime_type(content_type)
-  
-      if content_types.length == 1
-        ob.content_type = content_types.first
-      else
-        if content_types.empty?
-          ob.errors.add("Content type")
-        else
-          ob.errors.add("Content type", "matches more than one registered content type")
-        end
-
-        return rest_response(400, :object => ob)
-      end
-    end
-
-    ob.content_blob = ContentBlob.new(:data ="" content) if content
-
-    new_version  = action == 'create' && opts[:query]['id'] != nil
-    edit_version = action == 'edit'   && opts[:query]['version'] != nil
-
-    if new_version
-      ob[:revision_comments] = revision_comment
-    end
-
-    success = ob.save
-
-    if success
-      case "#{action} #{new_version || edit_version}"
-      when "create false"; Activity.create(:subject => opts[:user], :action ="" 'create', :objekt => ob, :auth => ob)
-      when "create true";  Activity.create(:subject => opts[:user], :action ="" 'create', :objekt => ob.versions.last, :auth => ob)
-      when "edit false";   Activity.create(:subject => opts[:user], :action ="" 'edit', :objekt => ob, :auth => ob)
-      when "edit true";    Activity.create(:subject => opts[:user], :action ="" 'edit', :objekt => ob, :extra => ob.version, :auth => ob.blob)
-      end
-    end
-
-    return rest_response(400, :object => ob) unless success
-
-    if opts[:query]['version'].nil?
-      update_permissions(ob, permissions, opts[:user])
-    end
-  end
-
-  ob = ob.versioned_resource if ob.respond_to?("versioned_resource")
-
-  rest_get_request(ob, opts[:user], { "id" => ob.id.to_s })
-end
-
-def post_file(opts)
-  file_aux('create', opts)
-end
-
-def put_file(opts)
-  file_aux('edit', opts)
-end
-
-def delete_file(opts)
-  file_aux('destroy', opts)
-end
-
-# pack handling
-
-def pack_aux(action, opts = {})
-
-  # Obtain object
-
-  case action
-    when 'create';
-      return rest_response(401, :reason => "Not authorised to create a pack") unless Authorization.check('create', Pack, opts[:user], nil)
-      if id = opts[:query]['id']
-        ob = Pack.find_by_id(id)
-        if ob.nil?
-          return rest_response(404, :reason => "Couldn't find a Pack with id #{id}")
-        else
-          if Authorization.check('edit', ob, opts[:user])
-            ob.snapshot!
-            return rest_get_request(ob, opts[:user], { "id" => ob.id.to_s })
-          else
-            return rest_response(401, :reason => "Not authorised to snapshot pack #{id}")
-          end
-        end
-      else
-        ob = Pack.new(:contributor => opts[:user])
-      end
-
-    when 'view', 'edit', 'destroy';
-      ob, error = obtain_rest_resource('Pack', opts[:query]['id'], opts[:query]['version'], opts[:user], action)
-    else
-      raise "Invalid action '#{action}'"
-  end
-
-  return error if ob.nil? # appropriate rest response already given
-
-  if action == "destroy"
-
-    ob.destroy
-
-  else
-
-    data = ""
-
-    title        = parse_element(data, :text,   '/pack/title')
-    description  = parse_element(data, :text,   '/pack/description')
-
-    permissions  = data.find_first('/pack/permissions')
-
-    if license_type = parse_element(data, :text,   '/pack/license-type')
-      if license_type == ""
-        ob.license = nil
-      else
-        ob.license = License.find_by_unique_name(license_type)
-
-        if ob.license.nil?
-          ob.errors.add("License type")
-          return rest_response(400, :object => ob)
-        end
-      end
-    end
-
-    # build the contributable
-
-    ob.title       = title        if title
-    ob.description = description  if description
-
-    if not ob.save
-      return rest_response(400, :object => ob)
-    end
-
-    update_permissions(ob, permissions, opts[:user])
-  end
-
-  rest_get_request(ob, opts[:user], { "id" => ob.id.to_s })
-end
-
-def post_pack(opts)
-  pack_aux('create', opts)
-end
-
-def put_pack(opts)
-  pack_aux('edit', opts)
-end
-
-def delete_pack(opts)
-  pack_aux('destroy', opts)
-end
-
-def external_pack_item_aux(action, opts = {})
-
-  unless action == 'destroy'
-
-    data = ""
-
-    pack          = parse_element(data, :resource, '/external-pack-item/pack')
-    title         = parse_element(data, :text,     '/external-pack-item/title')
-    uri           = parse_element(data, :text,     '/external-pack-item/uri')
-    alternate_uri = parse_element(data, :text,     '/external-pack-item/alternate-uri')
-    comment       = parse_element(data, :text,     '/external-pack-item/comment')
-  end
-
-  # Obtain object
-
-  case action
-    when 'create';
-
-      return rest_response(401, :reason => "Not authorised to create an external pack item") unless Authorization.check('create', PackRemoteEntry, opts[:user], pack)
-      return rest_response(400, :reason => "Pack not found") if pack.nil?
-      return rest_response(401, :reason => "Not authorised to change the specified pack") unless Authorization.check('edit', pack, opts[:user])
-
-      ob = PackRemoteEntry.new(:user => opts[:user],
-          :pack          => pack,
-          :title         => title,
-          :uri           => uri,
-          :alternate_uri => alternate_uri,
-          :comment       => comment)
-
-    when 'view', 'edit', 'destroy';
-
-      ob, error = obtain_rest_resource('PackRemoteEntry', opts[:query]['id'], opts[:query]['version'], opts[:user], action)
-
-      if ob
-        return rest_response(401, :reason => "Not authorised to change the specified pack") unless Authorization.check('edit', ob.pack, opts[:user])
-      end
-
-    else
-      raise "Invalid action '#{action}'"
-  end
-
-  return error if ob.nil? # appropriate rest response already given
-
-  if action == "destroy"
-
-    ob.destroy
-
-  else
-
-    ob.title         = title         if title
-    ob.uri           = uri           if uri
-    ob.alternate_uri = alternate_uri if alternate_uri
-    ob.comment       = comment       if comment
-
-    if not ob.save
-      return rest_response(400, :object => ob)
-    end
-  end
-
-  rest_get_request(ob, opts[:user], { "id" => ob.id.to_s })
-end
-
-def post_external_pack_item(opts)
-  external_pack_item_aux('create', opts)
-end
-
-def put_external_pack_item(opts)
-  external_pack_item_aux('edit', opts)
-end
-
-def delete_external_pack_item(opts)
-  external_pack_item_aux('destroy', opts)
-end
-
-def internal_pack_item_aux(action, opts = {})
-
-  unless action == 'destroy'
-
-    data = ""
-
-    pack          = parse_element(data, :resource, '/internal-pack-item/pack')
-    item          = parse_element(data, :resource, '/internal-pack-item/item')
-    comment       = parse_element(data, :text,     '/internal-pack-item/comment')
-
-    version_node  = data.find_first('/internal-pack-item/item/@version')
-    version       = version_node ? version_node.value.to_i : nil
-  end
-
-  # Obtain object
-
-  case action
-    when 'create';
-
-      return rest_response(401, :reason => "Not authorised to create an internal pack item") unless Authorization.check('create', PackContributableEntry, opts[:user], pack)
-      return rest_response(400, :reason => "Pack not found") if pack.nil?
-
-      ob = PackContributableEntry.new(:user => opts[:user],
-          :pack          => pack,
-          :contributable => item,
-          :comment       => comment,
-          :contributable_version => version)
-
-    when 'view', 'edit', 'destroy';
-
-      ob, error = obtain_rest_resource('PackContributableEntry', opts[:query]['id'], opts[:query]['version'], opts[:user], action)
-
-    else
-      raise "Invalid action '#{action}'"
-  end
-
-  return error if ob.nil? # appropriate rest response already given
-
-  if action == "destroy"
-
-    ob.destroy
-
-  else
-
-    ob.comment = comment if comment
-
-    if not ob.save
-      return rest_response(400, :object => ob)
-    end
-  end
-
-  rest_get_request(ob, opts[:user], { "id" => ob.id.to_s })
-end
-
-def post_internal_pack_item(opts)
-  internal_pack_item_aux('create', opts)
-end
-
-def put_internal_pack_item(opts)
-  internal_pack_item_aux('edit', opts)
-end
-
-def delete_internal_pack_item(opts)
-  internal_pack_item_aux('destroy', opts)
-end
-
-# def post_job(opts)
-#
-#   title       = params["job"]["title"]
-#   description = params["job"]["description"]
-#
-#   experiment_bits = parse_resource_uri(params["job"]["experiment"])
-#   runner_bits     = parse_resource_uri(params["job"]["runner"])
-#   runnable_bits   = parse_resource_uri(params["job"]["runnable"])
-#
-#   return rest_response(400) if title.nil?
-#   return rest_response(400) if description.nil?
-#
-#   return rest_response(400) if experiment_bits.nil? or experiment_bits[0] != 'Experiment'
-#   return rest_response(400) if runner_bits.nil?     or runner_bits[0]     != 'TavernaEnactor'
-#   return rest_response(400) if runnable_bits.nil?   or runnable_bits[0]   != 'Workflow'
-#
-#   experiment = Experiment.find_by_id(experiment_bits[1].to_i)
-#   runner     = TavernaEnactor.find_by_id(runner_bits[1].to_i)
-#   runnable   = Workflow.find_by_id(runnable_bits[1].to_i)
-#
-#   return rest_response(400) if experiment.nil? or not Authorization.check('edit', experiment, opts[:user])
-#   return rest_response(400) if runner.nil?     or not Authorization.check('download', runner, opts[:user])
-#   return rest_response(400) if runnable.nil?   or not Authorization.check('view', runnable, opts[:user])
-#
-#   puts "#{params[:job]}"
-#
-#   job = Job.new(:title => title, :description => description, :runnable => runnable, 
-#       :experiment => experiment, :runner => runner, :user => opts[:user],
-#       :runnable_version => runnable.current_version)
-#
-#   inputs = { "Tags" => "aa,bb,aa,cc,aa" }
-#
-#   job.inputs_data = inputs
-#
-#   success = job.submit_and_run!
-#
-#   return rest_response(500) if not success
-#
-#   return "<yes/>"
-#
-# end
-
 def paginated_search_index(query, models, num, page, user)
 
   return [] if not Conf.solr_enable or query.nil? or query == ""
@@ -1734,123 +1139,6 @@
   end
 end
 
-def user_count(opts)
-  
-  users = User.find(:all).select do |user| user.activated? end
-
-  root = LibXML::XML::Node.new('user-count')
-  root << users.length.to_s
-
-  doc = LibXML::XML::Document.new
-  doc.root = root
-
-  { :xml => doc }
-end
-
-def group_count(opts)
-  
-  root = LibXML::XML::Node.new('group-count')
-  root << Network.count.to_s
-
-  doc = LibXML::XML::Document.new
-  doc.root = root
-
-  { :xml => doc }
-end
-
-def workflow_count(opts)
-  
-  workflows = Workflow.find(:all).select do |w|
-    Authorization.check('view', w, opts[:user])
-  end
-
-  root = LibXML::XML::Node.new('workflow-count')
-  root << workflows.length.to_s
-
-  doc = LibXML::XML::Document.new
-  doc.root = root
-
-  { :xml => doc }
-end
-
-def pack_count(opts)
-  
-  packs = Pack.find(:all).select do |p|
-    Authorization.check('view', p, opts[:user])
-  end
-
-  root = LibXML::XML::Node.new('pack-count')
-  root << packs.length.to_s
-
-  doc = LibXML::XML::Document.new
-  doc.root = root
-
-  { :xml => doc }
-end
-
-def content_type_count(opts)
-
-  root = LibXML::XML::Node.new('type-count')
-  root << ContentType.count.to_s
-
-  doc = LibXML::XML::Document.new
-  doc.root = root
-
-  { :xml => doc }
-end
-
-def get_tagged(opts)
-
-  return rest_response(400, :reason => "Did not specify a tag") if opts[:query]['tag'].nil?
-
-  tag = Tag.find_by_name(opts[:query]['tag'])
-
-  obs = tag ? tag.tagged : []
-
-  # filter out ones they are not allowed to get
-  obs = (obs.select do |c| c.respond_to?('contribution') == false or Authorization.check("view", c, opts[:user]) end)
-
-  produce_rest_list("tagged", opts[:rules], opts[:query], obs, 'tagged', [], opts[:user])
-end
-
-def tag_cloud(opts)
-
-  num  = 25
-  type = nil
-
-  if opts[:query]['num']
-    if opts[:query]['num'] == 'all'
-      num = nil
-    else
-      num = opts[:query]['num'].to_i
-    end
-  end
-
-  if opts[:query]['type'] and opts[:query]['type'] != 'all'
-    type = opts[:query]['type'].camelize
-
-    type = 'Network' if type == 'Group'
-    type = 'Blob'    if type == 'File'
-  end
-
-  tags = Tag.find_by_tag_count(num, type)
-
-  doc = LibXML::XML::Document.new()
-
-  root = LibXML::XML::Node.new('tag-cloud')
-  doc.root = root
-
-  root['type'] = opts[:query]['type'] ? opts[:query]['type'] : 'all'
-
-  tags.each do |tag|
-    tag_node = rest_reference(tag, opts[:query])
-    tag_node['count'] = tag.taggings_count.to_s
-    root << tag_node
-  end
-
-  { :xml => doc }
-end
-
 def whoami_redirect(opts)
   if opts[:user].class == User
     case opts[:format]
@@ -1976,6 +1264,7 @@
   unless ob.is_a?(Policy)
     permissions['uri'] = rest_access_uri(policy)
     permissions['resource'] = rest_resource_uri(policy)
+    permissions['id'] = policy.id.to_s
     permissions['policy-type'] = policy.group_policy? ? 'group' : 'user-specified'
   end
 
@@ -1987,590 +1276,18 @@
   permissions
 end
 
-# Comments
-
-def comment_aux(action, opts)
-
-  unless action == "destroy"
-
-    data = ""
-
-    comment = parse_element(data, :text,     '/comment/comment')
-    subject = parse_element(data, :resource, '/comment/subject')
-  end
-
-  # Obtain object
-
-  case action
-    when 'create';
-      return rest_response(401, :reason => "Not authorised to create a comment") unless Authorization.check('create', Comment, opts[:user], subject)
-
-      ob = Comment.new(:user => opts[:user])
-    when 'view', 'edit', 'destroy';
-      ob, error = obtain_rest_resource('Comment', opts[:query]['id'], opts[:query]['version'], opts[:user], action)
-    else
-      raise "Invalid action '#{action}'"
-  end
-
-  return error if ob.nil? # appropriate rest response already given
-
-  if action == "destroy"
-
-    ob.destroy
-
-  else
-
-    ob.comment = comment if comment
-
-    if subject
-      return rest_response(400, :reason => "Specified resource does not support comments") unless [Blob, Network, Pack, Workflow].include?(subject.class)
-      return rest_response(401, :reason => "Not authorised to add a comment to the specified resource") unless Authorization.check(action, Comment, opts[:user], subject)
-      ob.commentable = subject
-    end
-
-    # Start of curation hack
-
-    def match_tag_name(name)
-
-      name.sub!(/^c:/, '')
-
-      matches = []
-
-      Conf.curation_types.each do |type|
-        matches.push type if type.starts_with?(name)
-      end
-
-      return matches[0] if matches.length == 1
-    end
-
-    if comment[0..1].downcase == 'c:' && opts[:user] && subject &&
-        Conf.curators.include?(opts[:user].username)
-
-      comment = comment[2..-1].strip
-
-      lines  = comment.split("\n")
-      events = []
-      failed = false
-
-      lines.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!
-
-            curation_type = match_tag_name(bit)
-
-            if curation_type
-              events.push(CurationEvent.new(:category => curation_type,
-                    :object => subject, :user => opts[: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_index
-
-      return rest_get_request(ob, opts[:user], { "id" => ob.id.to_s })
-    end
-
-    # End of curation hack
-
-    success = ob.save
-
-    if success
-      case action
-      when "create"; Activity.create(:subject => opts[:user], :action ="" 'create', :objekt => ob)
-      when "edit";   Activity.create(:subject => opts[:user], :action ="" 'edit', :objekt => ob)
-      end
-    end
-
-    return rest_response(400, :object => ob) unless success
-  end
-
-  rest_get_request(ob, opts[:user], { "id" => ob.id.to_s })
-end
-
-def post_comment(opts)
-  comment_aux('create', opts)
-end
-
-def put_comment(opts)
-  comment_aux('edit', opts)
-end
-
-def delete_comment(opts)
-  comment_aux('destroy', opts)
-end
-
-# Favourites
-
-def favourite_aux(action, opts)
-
-  unless action == "destroy"
-
-    data = ""
-
-    target = parse_element(data, :resource, '/favourite/object')
-  end
-
-  # Obtain object
-
-  case action
-    when 'create';
-      return rest_response(401, :reason => "Not authorised to create a favourite") unless Authorization.check('create', Bookmark, opts[:user], target)
-
-      ob = Bookmark.new(:user => opts[:user])
-    when 'view', 'edit', 'destroy';
-      ob, error = obtain_rest_resource('Bookmark', opts[:query]['id'], opts[:query]['version'], opts[:user], action)
-    else
-      raise "Invalid action '#{action}'"
-  end
-
-  return error if ob.nil? # appropriate rest response already given
-
-  if action == "destroy"
-
-    ob.destroy
-
-  else
-
-    if target
-      return rest_response(400, :reason => "Specified resource is not a valid favourite target") unless [Blob, Pack, Workflow].include?(target.class)
-      return rest_response(401, :reason => "Not authorised to create the favourite") unless Authorization.check(action, Bookmark, opts[:user], target)
-      ob.bookmarkable = target
-    end
-
-    success = ob.save
-
-    if success
-      Activity.create(:subject => current_user, :action ="" 'create', :objekt => ob)
-    end
-
-    return rest_response(400, :object => ob) unless success
-  end
-
-  rest_get_request(ob, opts[:user], { "id" => ob.id.to_s })
-end
-
-def post_favourite(opts)
-  favourite_aux('create', opts)
-end
-
-def put_favourite(opts)
-  favourite_aux('edit', opts)
-end
-
-def delete_favourite(opts)
-  favourite_aux('destroy', opts)
-end
-
-# Ratings
-
-def rating_aux(action, opts)
-
-  unless action == "destroy"
-
-    data = ""
-
-    rating  = parse_element(data, :text,     '/rating/rating')
-    subject = parse_element(data, :resource, '/rating/subject')
-  end
-
-  # Obtain object
-
-  case action
-    when 'create';
-      return rest_response(401, :reason => "Not authorised to create a rating") unless Authorization.check('create', Rating, opts[:user], subject)
-
-      ob = Rating.new(:user => opts[:user])
-    when 'view', 'edit', 'destroy';
-      ob, error = obtain_rest_resource('Rating', opts[:query]['id'], opts[:query]['version'], opts[:user], action)
-    else
-      raise "Invalid action '#{action}'"
-  end
-
-  return error if ob.nil? # appropriate rest response already given
-
-  if action == "destroy"
-
-    ob.destroy
-
-  else
-
-    ob.rating = rating if rating
-
-    if subject
-      return rest_response(400, :reason => "Specified resource does not support ratings") unless [Blob, Network, Pack, Workflow].include?(subject.class)
-      return rest_response(401, :reason => "Not authorised for the specified resource") unless Authorization.check(action, Rating, opts[:user], subject)
-      ob.rateable = subject
-    end
-
-    success = ob.save
-
-    if success
-      Activity.create(:subject => opts[:user], :action ="" 'create', :objekt => ob, :auth => subject)
-    end
-
-    return rest_response(400, :object => ob) unless success
-  end
-
-  rest_get_request(ob, opts[:user], { "id" => ob.id.to_s })
-end
-
-def post_rating(opts)
-  rating_aux('create', opts)
-end
-
-def put_rating(opts)
-  rating_aux('edit', opts)
-end
-
-def delete_rating(opts)
-  rating_aux('destroy', opts)
-end
-
-# Taggings
-
-def tagging_aux(action, opts)
-
-  unless action == "destroy"
-
-    data = ""
-
-    subject = parse_element(data, :resource, '/tagging/subject')
-    label   = parse_element(data, :text,     '/tagging/label')
-    tag     = parse_element(data, :resource, '/tagging/tag')
-  end
-
-  # Obtain object
-
-  case action
-    when 'create';
-      return rest_response(401, :reason => "Not authorised to create a tagging") unless Authorization.check('create', Tagging, opts[:user], subject)
-
-      ob = Tagging.new(:user => opts[:user])
-    when 'view', 'edit', 'destroy';
-      ob, error = obtain_rest_resource('Tagging', opts[:query]['id'], opts[:query]['version'], opts[:user], action)
-    else
-      raise "Invalid action '#{action}'"
-  end
-
-  return error if ob.nil? # appropriate rest response already given
-
-  if action == "destroy"
-
-    ob.destroy
-
-  else
-
-    ob.label    = label   if label
-    ob.tag      = tag     if tag
-
-    if subject
-      return rest_response(401, :reason => "Not authorised for the specified resource") unless Authorization.check(action, Tagging, opts[:user], subject)
-      ob.taggable = subject
-    end
-
-    success = ob.save
-
-    if success && action == "create"
-      Activity.create(:subject => opts[:user], :action ="" 'create', :objekt => ob, :auth => subject)
-    end
-
-    return rest_response(400, :object => ob) unless success
-  end
-
-  rest_get_request(ob, opts[:user], { "id" => ob.id.to_s })
-end
-
-def post_tagging(opts)
-  tagging_aux('create', opts)
-end
-
-def delete_tagging(opts)
-  tagging_aux('destroy', opts)
-end
-
-# Ontologies
-
-def ontology_aux(action, opts)
-
-  # Obtain object
-
-  case action
-    when 'create';
-      return rest_response(401, :reason => "Not authorised to create an ontology") unless Authorization.check('create', Ontology, opts[:user], nil)
-      ob = Ontology.new(:user => opts[:user])
-    when 'view', 'edit', 'destroy';
-      ob, error = obtain_rest_resource('Ontology', opts[:query]['id'], opts[:query]['version'], opts[:user], action)
-    else
-      raise "Invalid action '#{action}'"
-  end
-
-  return error if ob.nil? # appropriate rest response already given
-
-  if action == "destroy"
-
-    ob.destroy
-
-  else
-
-    data = ""
-
-    title        = parse_element(data, :text, '/ontology/title')
-    description  = parse_element(data, :text, '/ontology/description')
-    uri          = parse_element(data, :text, '/ontology/uri')
-    prefix       = parse_element(data, :text, '/ontology/prefix')
-
-    # build the contributable
-
-    ob.title       = title       if title
-    ob.description = description if description
-    ob.uri         = uri         if uri
-    ob.prefix      = prefix      if prefix
-
-    if not ob.save
-      return rest_response(400, :object => ob)
-    end
-  end
-
-  rest_get_request(ob, opts[:user], { "id" => ob.id.to_s })
-end
-
-def post_ontology(opts)
-  ontology_aux('create', opts)
-end
-
-def put_ontology(opts)
-  ontology_aux('edit', opts)
-end
-
-def delete_ontology(opts)
-  ontology_aux('destroy', opts)
-end
-
-# Predicates
-
-def predicate_aux(action, opts)
-
-  if action != "destroy"
-
-    data = ""
-
-    title         = parse_element(data, :text,     '/predicate/title')
-     :resource, '/predicate/ontology')
-    description   = parse_element(data, :text,     '/predicate/description')
-    phrase        = parse_element(data, :text,     '/predicate/phrase')
-    equivalent_to = parse_element(data, :text,     '/predicate/equivalent-to')
-
-  end
-
-  # Obtain object
-
-  case action
-    when 'create';
-      return rest_response(401, :reason => "Not authorised to create a predicate") unless Authorization.check('create', Predicate, opts[:user], ontology)
-      ob = Predicate.new
-    when 'view', 'edit', 'destroy';
-      ob, error = obtain_rest_resource('Predicate', opts[:query]['id'], opts[:query]['version'], opts[:user], action)
-    else
-      raise "Invalid action '#{action}'"
-  end
-
-  return error if ob.nil? # appropriate rest response already given
-
-  if action == "destroy"
-
-    ob.destroy
-
-  else
-
-    # build it
-
-    ob.title         = title         if title
-    ob.description   = description   if description
-    ob.phrase        = phrase        if phrase
-    ob.equivalent_to = equivalent_to if equivalent_to
-    ob.      if ontology
-
-    if not ob.save
-      return rest_response(400, :object => ob)
-    end
-  end
-
-  rest_get_request(ob, opts[:user], { "id" => ob.id.to_s })
-end
-
-def post_predicate(opts)
-  predicate_aux('create', opts)
-end
-
-def put_predicate(opts)
-  predicate_aux('edit', opts)
-end
-
-def delete_predicate(opts)
-  predicate_aux('destroy', opts)
-end
-
-# Relationships
-
-def relationship_aux(action, opts)
-
-  if action != "destroy"
-
-    data = ""
-
-    subject     = parse_element(data, :resource, '/relationship/subject')
-    predicate   = parse_element(data, :resource, '/relationship/predicate')
-    objekt      = parse_element(data, :resource, '/relationship/object')
-    context     = parse_element(data, :resource, '/relationship/context')
-  end
-
-  # Obtain object
-
-  case action
-    when 'create';
-      return rest_response(401, :reason => "Not authorised to create a relationship") unless Authorization.check('create', Relationship, opts[:user], context)
-      ob = Relationship.new(:user => opts[:user])
-    when 'view', 'edit', 'destroy';
-      ob, error = obtain_rest_resource('Relationship', opts[:query]['id'], opts[:query]['version'], opts[:user], action)
-    else
-      raise "Invalid action '#{action}'"
-  end
-
-  return error if ob.nil? # appropriate rest response already given
-
-  if action == "destroy"
-
-    ob.destroy
-
-  else
-
-    # build it
-
-    ob.subject   = subject   if subject
-    ob.predicate = predicate if predicate
-    ob.objekt    = objekt    if objekt
-    ob.context   = context   if context
-
-    if not ob.save
-      return rest_response(400, :object => ob)
-    end
-  end
-
-  rest_get_request(ob, opts[:user], { "id" => ob.id.to_s })
-end
-
-def post_relationship(opts)
-  relationship_aux('create', opts)
-end
-
-def put_relationship(opts)
-  relationship_aux('edit', opts)
-end
-
-def delete_relationship(opts)
-  relationship_aux('destroy', opts)
-end
-
 # Call dispatcher
 
 def rest_call_request(opts)
   begin
     send(opts[:rules]['Function'], opts)
-  rescue
+  rescue Exception => e
     if Rails.env == "production"
+      logger.info e.message
+      logger.info e.backtrace.join("\n")
       return rest_response(500)
     else
       raise
     end
   end
 end
-
-# Component Querying
-def get_components(opts)
-  return rest_response(404) if TripleStore.instance.nil?
-
-  sparql_prefixes = CGI.unescape(opts[:query]["prefixes"] || '')
-  sparql_query = CGI.unescape(opts[:query]["query"] || '')
-
-  # Prevent subversion of SELECT template
-  if sparql_prefixes.downcase.include?("select")
-    return rest_response(400, :reason => "Invalid prefix syntax")
-  end
-
-  template = %(
-  PREFIX rdfs:<http://www.w3.org/2000/01/rdf-schema#>
-  PREFIX wfdesc:<http://purl.org/wf4ever/wfdesc#>
-  PREFIX wf4ever:<http://purl.org/wf4ever/wf4ever#>
-  #{sparql_prefixes}
-
-  SELECT DISTINCT ?workflow_uri WHERE {
-    GRAPH ?workflow_uri {
-      ?w a wfdesc:Workflow .
-      #{sparql_query}
-    }
-  })
-
-  # Perform query
-  begin
-    sparql_results = TripleStore.instance.query(template)
-  rescue Sesame::QueryException => e
-    return rest_response(400, :reason => "SPARQL Error: #{e.message}")
-  end
-
-  # Remove results not from this host
-  # TODO: do this in the query?
-  base_uri = URI(Conf.base_uri)
-  results = sparql_results.select do |r|
-    r[:workflow_uri].host == base_uri.host && r[:workflow_uri].port == base_uri.port
-  end
-
-  # Find the workflows in the database
-  results = results.map do |r|
-    Workflow.find_by_id(r[:workflow_uri].request_uri.to_s.sub('/workflows/', '').to_i)
-  end
-
-  # Perform auth on workflow set
-  results = results.select { |r| Authorization.check("view", r, opts[:user]) }
-
-  # Render results
-  produce_rest_list(opts[:uri], opts[:rules], opts[:query], results, "workflows", [], opts[:user])
-end
-
-def get_policies(opts)
-  policies = []
-
-  if opts[:user].is_a?(User)
-    if opts[:query]["type"] == 'group'
-      policies = opts[:user].group_policies
-    else
-      policies = opts[:user].policies + opts[:user].group_policies
-    end
-  end
-
-  produce_rest_list(opts[:uri], opts[:rules], opts[:query], policies, "policies", [], opts[:user])
-end

Copied: branches/packs/lib/service_deprecation_job.rb (from rev 3767, trunk/lib/service_deprecation_job.rb) (0 => 3768)


--- branches/packs/lib/service_deprecation_job.rb	                        (rev 0)
+++ branches/packs/lib/service_deprecation_job.rb	2013-11-03 11:12:46 UTC (rev 3768)
@@ -0,0 +1,24 @@
+# myExperiment: lib/service_deprecation_job.rb
+#
+# Copyright (c) 2013 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class ServiceDeprecationJob
+  def perform
+    Rails.logger.info("Checking for workflows with deprecated services...")
+    DeprecationEvent.all.each do |event|
+      if event.date.past?
+        event.affected_workflows.each do |workflow|
+          unless workflow.curation_events.exists?(:category => 'decommissioned services')
+            Rails.logger.info("Workflow #{workflow.id} has deprecated services (Deprecation Event #{event.id})")
+            details = "Deprecation Event #{event.id}: #{event.details}"
+            CurationEvent.create(:category => 'decommissioned services', :object => workflow, :details => details)
+          end
+        end
+      end
+    end
+
+    # Do it again
+    Delayed::Job.enqueue(ServiceDeprecationJob.new, 1, 1.day.from_now)
+  end
+end
\ No newline at end of file

Modified: branches/packs/lib/sesame.rb (3767 => 3768)


--- branches/packs/lib/sesame.rb	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/lib/sesame.rb	2013-11-03 11:12:46 UTC (rev 3768)
@@ -24,7 +24,11 @@
       request.body = rdf
       request.content_type = content_type
 
-      response = @connection.request url, request   #Net::HTTP::Persistent::Error if can't connect
+      begin
+        response = @connection.request url, request   #Net::HTTP::Persistent::Error if can't connect
+      rescue Net::HTTP::Persistent::Error
+        raise ConnectionException.new, "Couldn't connect to address@hidden"
+      end
 
       case response.code
         when '204'
@@ -40,7 +44,11 @@
       url = ""
       request =  Net::HTTP::Get.new url.request_uri
       request['accept'] = 'application/sparql-results+xml'
-      response = @connection.request url, request
+      begin
+        response = @connection.request url, request
+      rescue Net::HTTP::Persistent::Error
+        raise ConnectionException.new, "Couldn't connect to address@hidden"
+      end
 
       case response.code
         when '200'
@@ -64,7 +72,11 @@
 
       url = ""
       request = Net::HTTP::Delete.new url.request_uri
-      response = @connection.request url, request
+      begin
+        response = @connection.request url, request
+      rescue Net::HTTP::Persistent::Error
+        raise ConnectionException.new, "Couldn't connect to address@hidden"
+      end
 
       case response.code
         when '204'
@@ -76,6 +88,8 @@
 
   end
 
+  class ConnectionException < Exception;  end
+
   class RequestException < Exception
     attr_reader :code
 

Modified: branches/packs/lib/workflow_processors/statjr_ebook.rb (3767 => 3768)


--- branches/packs/lib/workflow_processors/statjr_ebook.rb	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/lib/workflow_processors/statjr_ebook.rb	2013-11-03 11:12:46 UTC (rev 3768)
@@ -4,7 +4,8 @@
 # See license.txt for details.
 
 require "zip/zip"
-require 'rdf/raptor'
+require 'rdf'
+require 'rdf/turtle'
 
 module WorkflowProcessors
 

Modified: branches/packs/public/robots.txt (3767 => 3768)


--- branches/packs/public/robots.txt	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/public/robots.txt	2013-11-03 11:12:46 UTC (rev 3768)
@@ -1 +1,3 @@
-# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
\ No newline at end of file
+# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
+User-agent: *
+Disallow: /policies/

Copied: branches/packs/script/delayed_job (from rev 3767, trunk/script/delayed_job) (0 => 3768)


--- branches/packs/script/delayed_job	                        (rev 0)
+++ branches/packs/script/delayed_job	2013-11-03 11:12:46 UTC (rev 3768)
@@ -0,0 +1,5 @@
+#!/usr/bin/env ruby
+
+require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment'))
+require 'delayed/command'
+Delayed::Command.new(ARGV).daemonize

Modified: branches/packs/solr/conf/schema.xml (3767 => 3768)


--- branches/packs/solr/conf/schema.xml	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/solr/conf/schema.xml	2013-11-03 11:12:46 UTC (rev 3768)
@@ -228,6 +228,8 @@
 
     <field name="title"              stored="false" type="text" multiValued="true" indexed="true"/>
     <field name="name"               stored="false" type="text" multiValued="true" indexed="true"/>
+    <field name="given_name"         stored="false" type="text" multiValued="true" indexed="true"/>
+    <field name="family_name"        stored="false" type="text" multiValued="true" indexed="true"/>
     <field name="email"              stored="false" type="text" multiValued="true" indexed="true"/>
     <field name="website"            stored="false" type="text" multiValued="true" indexed="true"/>
     <field name="field_or_industry"  stored="false" type="text" multiValued="true" indexed="true"/>

Modified: branches/packs/test/fixtures/blobs.yml (3767 => 3768)


--- branches/packs/test/fixtures/blobs.yml	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/test/fixtures/blobs.yml	2013-11-03 11:12:46 UTC (rev 3768)
@@ -104,3 +104,28 @@
   content_type_id: 1
   content_blob_id: 1
 
+component_profile:
+  id: 9
+  current_version: 1
+  contributor_id: 1
+  contributor_type: User
+  local_name: component_profile.xml
+  title: A component profile
+  body: some text
+  created_at: 2013-06-12 10:51:01
+  license_id: 2
+  content_type_id: 5
+  content_blob_id: 1
+
+unused_component_profile:
+  id: 10
+  current_version: 1
+  contributor_id: 1
+  contributor_type: User
+  local_name: component_profile.xml
+  title: A component profile
+  body: some text
+  created_at: 2013-06-12 10:51:01
+  license_id: 2
+  content_type_id: 5
+  content_blob_id: 1

Modified: branches/packs/test/fixtures/content_blobs.yml (3767 => 3768)


--- branches/packs/test/fixtures/content_blobs.yml	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/test/fixtures/content_blobs.yml	2013-11-03 11:12:46 UTC (rev 3768)
@@ -27,3 +27,11 @@
 component_workflow_blob:
   id: 5
   data: <%= load_blob_data('image_to_tiff_migration.t2flow') %>
+
+private_workflow_blob:
+  id: 6
+  data: <%= load_blob_data('image_to_tiff_migration.t2flow') %>
+
+component_profile_blob:
+  id: 7
+  data: <%= load_blob_data('image_to_tiff_migration.t2flow') %>
\ No newline at end of file

Modified: branches/packs/test/fixtures/content_types.yml (3767 => 3768)


--- branches/packs/test/fixtures/content_types.yml	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/test/fixtures/content_types.yml	2013-11-03 11:12:46 UTC (rev 3768)
@@ -41,3 +41,11 @@
   created_at: 2008-04-22 15:32:01
   updated_at: 2008-04-22 15:32:01
 
+component_profile_type:
+  id: 5
+  title: Taverna Component Profile
+  mime_type: application/vnd.taverna.component-profile+xml
+  created_at: 2008-04-22 15:32:01
+  updated_at: 2008-04-22 15:32:01
+
+

Modified: branches/packs/test/fixtures/contributions.yml (3767 => 3768)


--- branches/packs/test/fixtures/contributions.yml	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/test/fixtures/contributions.yml	2013-11-03 11:12:46 UTC (rev 3768)
@@ -155,3 +155,62 @@
   downloads_count: 1
   viewings_count: 1
 
+contribution_for_private_workflow:
+  id: 14
+  contributor_id: 1
+  contributor_type: User
+  contributable_id: 5
+  contributable_type: Workflow
+  policy_id: 11
+  created_at: 2008-08-07 23:53:46
+  updated_at: 2008-08-07 23:53:46
+  downloads_count: 1
+  viewings_count: 1
+
+contribution_component_profile:
+  id: 15
+  contributor_id: 1
+  contributor_type: User
+  contributable_id: 9
+  contributable_type: Blob
+  policy_id: 12
+  created_at: 2013-06-12 10:51:01
+  updated_at: 2013-06-12 10:51:01
+  downloads_count: 123
+  viewings_count: 156
+
+contribution_component_family:
+  id: 16
+  contributor_id: 1
+  contributor_type: User
+  contributable_id: 3
+  contributable_type: Pack
+  policy_id: 13
+  created_at: 2013-06-13 13:12:32
+  updated_at: 2013-06-13 13:12:32
+  downloads_count: 123
+  viewings_count: 156
+
+contribution_protected_component_family:
+  id: 17
+  contributor_id: 1
+  contributor_type: User
+  contributable_id: 4
+  contributable_type: Pack
+  policy_id: 14
+  created_at: 2013-06-13 13:12:32
+  updated_at: 2013-06-13 13:12:32
+  downloads_count: 123
+  viewings_count: 156
+
+contribution_unused_component_profile:
+  id: 18
+  contributor_id: 1
+  contributor_type: User
+  contributable_id: 10
+  contributable_type: Blob
+  policy_id: 15
+  created_at: 2013-06-12 10:51:01
+  updated_at: 2013-06-12 10:51:01
+  downloads_count: 123
+  viewings_count: 156

Modified: branches/packs/test/fixtures/pack_contributable_entries.yml (3767 => 3768)


--- branches/packs/test/fixtures/pack_contributable_entries.yml	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/test/fixtures/pack_contributable_entries.yml	2013-11-03 11:12:46 UTC (rev 3768)
@@ -20,3 +20,74 @@
   user_id: 2
   created_at: 2008-04-05 06:07:08
   updated_at: 2008-04-05 06:07:08
+
+component_family_entry:
+  id: 3
+  pack_id: 3
+  contributable_id: 3
+  contributable_type: Workflow
+  comment:
+  user_id: 1
+  created_at: 2013-06-13 11:02:54
+  updated_at: 2013-06-13 11:02:54
+
+component_family_entry2:
+  id: 4
+  pack_id: 3
+  contributable_id: 5
+  contributable_type: Workflow
+  comment:
+  user_id: 1
+  created_at: 2013-06-13 11:02:55
+  updated_at: 2013-06-13 11:02:55
+
+component_family_profile_entry:
+  id: 5
+  pack_id: 3
+  contributable_id: 9
+  contributable_type: Blob
+  comment:
+  user_id: 1
+  created_at: 2013-06-13 11:02:54
+  updated_at: 2013-06-13 11:02:54
+
+protected_component_family_entry:
+  id: 6
+  pack_id: 4
+  contributable_id: 5
+  contributable_type: Workflow
+  comment:
+  user_id: 1
+  created_at: 2013-06-13 11:02:55
+  updated_at: 2013-06-13 11:02:55
+
+protected_component_family_profile_entry:
+  id: 7
+  pack_id: 4
+  contributable_id: 9
+  contributable_type: Blob
+  comment:
+  user_id: 1
+  created_at: 2013-06-13 11:02:54
+  updated_at: 2013-06-13 11:02:54
+
+communal_component_family_profile_entry:
+  id: 8
+  pack_id: 5
+  contributable_id: 9
+  contributable_type: Blob
+  comment:
+  user_id: 1
+  created_at: 2013-06-13 11:02:54
+  updated_at: 2013-06-13 11:02:54
+
+
+communal_component_family_entry:
+  id: 9
+  pack_id: 5
+  contributable_id: 4
+  contributable_type: Workflow
+  comment:
+  user_id: 1
+  created_at: 2013-06-13 11:02:54
+  updated_at: 2013-06-13 11:02:54

Modified: branches/packs/test/fixtures/packs.yml (3767 => 3768)


--- branches/packs/test/fixtures/packs.yml	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/test/fixtures/packs.yml	2013-11-03 11:12:46 UTC (rev 3768)
@@ -18,3 +18,27 @@
   description_html: another pack <br />
   created_at: 2008-04-06 15:54:35
   updated_at: 2008-04-06 15:54:35
+
+component_family:
+  id: 3
+  contributor_id: 1
+  contributor_type: User
+  title: A family of components
+  created_at: 2013-06-13 13:12:32
+  updated_at: 2013-06-13 13:12:32
+
+protected_component_family:
+  id: 4
+  contributor_id: 1
+  contributor_type: User
+  title: A family of components that only John can access
+  created_at: 2013-06-13 13:12:32
+  updated_at: 2013-06-13 13:12:32
+
+communal_component_family:
+  id: 5
+  contributor_id: 1
+  contributor_type: User
+  title: A family containing components from multiple users
+  created_at: 2013-06-13 13:12:32
+  updated_at: 2013-06-13 13:12:32

Modified: branches/packs/test/fixtures/policies.yml (3767 => 3768)


--- branches/packs/test/fixtures/policies.yml	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/test/fixtures/policies.yml	2013-11-03 11:12:46 UTC (rev 3768)
@@ -95,6 +95,57 @@
   contributor_type: User
   name: auto
   share_mode: 0
+  update_mode: 6
+  created_at: 2007-10-22 18:54:22
+  updated_at: 2008-01-09 12:12:12
+
+private_policy:
+  id: 11
+  contributor_id: 1
+  contributor_type: User
+  name: auto
+  share_mode: 7
+  update_mode: 6
+  created_at: 2007-10-22 18:54:22
+  updated_at: 2008-01-09 12:12:12
+
+component_profile_policy:
+  id: 12
+  contributor_id: 1
+  contributor_type: User
+  name: auto
+  share_mode: 0
   update_mode: 0
-  created_at: 2007-10-22 18:54:22
-  updated_at: 2008-01-09 12:12:12
\ No newline at end of file
+  created_at: 2013-06-12 10:51:01
+  updated_at: 2013-06-12 10:51:01
+
+
+component_family_policy:
+  id: 13
+  contributor_id: 1
+  contributor_type: User
+  name: auto
+  share_mode: 0
+  update_mode: 0
+  created_at: 2013-06-12 10:51:01
+  updated_at: 2013-06-12 10:51:01
+
+protected_component_family_policy:
+  id: 14
+  contributor_id: 1
+  contributor_type: User
+  name: auto
+  share_mode: 7
+  update_mode: 6
+  created_at: 2013-06-12 10:51:01
+  updated_at: 2013-06-12 10:51:01
+
+unused_component_profile_policy:
+  id: 15
+  contributor_id: 1
+  contributor_type: User
+  name: auto
+  share_mode: 0
+  update_mode: 0
+  created_at: 2013-06-12 10:51:01
+  updated_at: 2013-06-12 10:51:01

Copied: branches/packs/test/fixtures/taggings.yml (from rev 3767, trunk/test/fixtures/taggings.yml) (0 => 3768)


--- branches/packs/test/fixtures/taggings.yml	                        (rev 0)
+++ branches/packs/test/fixtures/taggings.yml	2013-11-03 11:12:46 UTC (rev 3768)
@@ -0,0 +1,43 @@
+component_tag_on_component_workflow:
+  tag_id: 1
+  taggable_id: 3
+  taggable_type: Workflow
+  user: john
+  created_at: 2013-06-13 08:24:43
+
+component_tag_on_component_workflow2:
+  tag_id: 1
+  taggable_id: 4
+  taggable_type: Workflow
+  user: john
+  created_at: 2013-06-13 08:24:43
+
+component_tag_on_private_component_workflow:
+  tag_id: 1
+  taggable_id: 5
+  taggable_type: Workflow
+  user: john
+  created_at: 2013-06-13 07:24:43
+
+component_family_tag_on_component_family:
+  tag_id: 2
+  taggable_id: 3
+  taggable_type: Pack
+  user: john
+  created_at: 2013-06-13 07:24:43
+
+component_family_tag_on_component_family2:
+  tag_id: 2
+  taggable_id: 4
+  taggable_type: Pack
+  user: john
+  created_at: 2013-06-13 07:24:43
+
+component_family_tag_on_component_family3:
+  tag_id: 2
+  taggable_id: 5
+  taggable_type: Pack
+  user: john
+  created_at: 2013-06-13 07:24:43
+
+

Copied: branches/packs/test/fixtures/tags.yml (from rev 3767, trunk/test/fixtures/tags.yml) (0 => 3768)


--- branches/packs/test/fixtures/tags.yml	                        (rev 0)
+++ branches/packs/test/fixtures/tags.yml	2013-11-03 11:12:46 UTC (rev 3768)
@@ -0,0 +1,11 @@
+component:
+  id: 1
+  name: component
+  created_at: 2013-06-12 09:18:25
+  updated_at: 2013-06-12 09:18:25
+
+component_family:
+  id: 2
+  name: component family
+  created_at: 2013-06-12 09:18:25
+  updated_at: 2013-06-12 09:18:25
\ No newline at end of file

Modified: branches/packs/test/fixtures/workflows.yml (3767 => 3768)


--- branches/packs/test/fixtures/workflows.yml	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/test/fixtures/workflows.yml	2013-11-03 11:12:46 UTC (rev 3768)
@@ -55,3 +55,16 @@
   content_type_id: 4
   content_blob_id: 5
 
+private_component_workflow:
+  id: 5
+  contributor_id: 1
+  contributor_type: User
+  title: Private workflow
+  unique_name: private_workflow
+  body: A private component workflow
+  created_at: 2008-04-11 22:19:33
+  updated_at: 2008-05-14 06:45:08
+  license_id: 2
+  current_version: 1
+  content_type_id: 4
+  content_blob_id: 6

Modified: branches/packs/test/functional/api_controller_test.rb (3767 => 3768)


--- branches/packs/test/functional/api_controller_test.rb	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/test/functional/api_controller_test.rb	2013-11-03 11:12:46 UTC (rev 3768)
@@ -14,7 +14,7 @@
     @response   = ActionController::TestResponse.new
   end
 
-  fixtures :workflows, :users, :content_types, :licenses, :ontologies, :predicates, :packs
+  fixtures :workflows, :users, :content_types, :licenses, :ontologies, :predicates, :packs, :tags, :taggings
 
   def test_workflows
 
@@ -1131,13 +1131,14 @@
     assert_response(:not_found)
   end
 
-  # Component querying
+  # Components
 
-  def test_basic_component_query # not a great test, but should pick up any major errors
+  test "can create components" do
     login_as(:john)
 
     # Check empty
-    resp = rest_request(:get, 'components', nil, {'prefixes' => '', 'query' => ''})
+    TripleStore.instance.repo = {}
+    resp = rest_request(:get, 'components')
     assert_response(:success)
     assert_equal 0, resp.find('//workflow').size
 
@@ -1145,11 +1146,12 @@
     license_type = "by-sa"
     content_type = "application/vnd.taverna.t2flow+xml"
     content = Base64.encode64(File.read('test/fixtures/files/image_to_tiff_migration.t2flow'))
-
-    rest_request(:post, 'workflow', "<?xml version='1.0'?>
+    family = packs(:component_family)
+    workflow_resp = rest_request(:post, 'component', "<?xml version='1.0'?>
       <workflow>
         <title>Test Component</title>
         <description>123</description>
+        <component-family>#{polymorphic_url(family)}</component-family>
         <license-type>#{license_type}</license-type>
         <content-type>#{content_type}</content-type>
         <content>#{content}</content>
@@ -1157,12 +1159,429 @@
 
     assert_response(:success)
 
-    # Check result returned
+    # Get the newly created component
+    uri = workflow_resp.find_first('//workflow')['resource']
+    component = Workflow.find(uri.split('/').last.to_i)
+
+    # Check it was added to the family
+    assert_includes family.contributable_entries.map { |e| e.contributable }, component
+
+    # Check it was tagged
+    assert component.component?
+
+    # Check it's retrievable
+    query_resp = rest_request(:get, 'components')
+    assert_response(:success)
+    assert_equal 1, query_resp.find('//workflow').size
+    assert_equal uri, query_resp.find_first('//workflow')['resource']
+  end
+
+  test "can't create component if family doesn't exist" do
+    login_as(:john)
+
+    # Upload a component workflow
+    license_type = "by-sa"
+    content_type = "application/vnd.taverna.t2flow+xml"
+    content = Base64.encode64(File.read('test/fixtures/files/image_to_tiff_migration.t2flow'))
+    assert_no_difference('Workflow.count') do
+      rest_request(:post, 'component', "<?xml version='1.0'?>
+        <workflow>
+          <title>Test Component</title>
+          <description>123</description>
+          <component-family>http://www.example.com/families/123</component-family>
+          <license-type>#{license_type}</license-type>
+          <content-type>#{content_type}</content-type>
+          <content>#{content}</content>
+        </workflow>")
+    end
+
+    assert_response(404)
+  end
+
+  test "can't create component if family url points to non-family resource" do
+    login_as(:john)
+
+    # Upload a component workflow
+    license_type = "by-sa"
+    content_type = "application/vnd.taverna.t2flow+xml"
+    content = Base64.encode64(File.read('test/fixtures/files/image_to_tiff_migration.t2flow'))
+    assert_no_difference('Workflow.count') do
+      rest_request(:post, 'component', "<?xml version='1.0'?>
+        <workflow>
+          <title>Test Component</title>
+          <description>123</description>
+          <component-family>#{polymorphic_url(packs(:pack_1))}</component-family>
+          <license-type>#{license_type}</license-type>
+          <content-type>#{content_type}</content-type>
+          <content>#{content}</content>
+        </workflow>")
+    end
+
+    assert_response(400)
+  end
+
+  test "can't create components in protected family" do
+    login_as(:jane)
+
+    # Upload a component workflow
+    license_type = "by-sa"
+    content_type = "application/vnd.taverna.t2flow+xml"
+    content = Base64.encode64(File.read('test/fixtures/files/image_to_tiff_migration.t2flow'))
+    family = packs(:protected_component_family)
+    assert_no_difference('Workflow.count') do
+      rest_request(:post, 'component', "<?xml version='1.0'?>
+        <workflow>
+          <title>Test Component</title>
+          <description>123</description>
+          <component-family>#{polymorphic_url(family)}</component-family>
+          <license-type>#{license_type}</license-type>
+          <content-type>#{content_type}</content-type>
+          <content>#{content}</content>
+        </workflow>")
+    end
+
+    assert_response(401)
+  end
+
+  test "can create component versions" do
+    login_as(:john)
+
+    # Set up
+    component = workflows(:component_workflow)
+    version_count = WorkflowVersion.count
+    # Put in triplestore
+    TripleStore.instance.repo = {}
+    TripleStore.instance.insert("", "<#{polymorphic_url(component)}>")
+
+    # Check its there
+    resp = rest_request(:get, 'components')
+    assert_response(:success)
+    assert_equal 1, resp.find('//workflow').size
+    assert_equal "", TripleStore.instance.repo["<#{polymorphic_url(component)}>"]
+
+    # Post new version
+    content = Base64.encode64(File.read('test/fixtures/files/image_to_tiff_migration.t2flow'))
+
+    workflow_resp = rest_request(:post, 'component', "<?xml version='1.0'?>
+      <workflow>
+        <title>Test Component II</title>
+        <description>456</description>
+        <content>#{content}</content>
+      </workflow>", {'id' => component.id})
+
+    assert_response(:success)
+
+    # Get the newly created component
+    uri = workflow_resp.find_first('//workflow')['resource']
+    component = Workflow.find(uri.split('/').last.to_i)
+
+    # Check the version was created
+    assert_equal version_count+1, WorkflowVersion.count
+    assert_equal 'Test Component II', component.title
+
+    # Check there's still only one component in the triplestore
+    query_resp = rest_request(:get, 'components')
+    assert_response(:success)
+    assert_equal 1, query_resp.find('//workflow').size
+    assert_equal uri, query_resp.find_first('//workflow')['resource']
+    assert_not_equal "", TripleStore.instance.repo["<#{polymorphic_url(component)}>"]
+  end
+
+  test "can query components by family" do
+    component_uri2 = polymorphic_url(workflows(:component_workflow2))
+    component_uri = polymorphic_url(workflows(:component_workflow))
+    private_component_uri = polymorphic_url(workflows(:private_component_workflow))
+    family_uri = polymorphic_url(packs(:component_family))
+
+    TripleStore.instance.repo = {}
+    TripleStore.instance.insert("", "<#{component_uri2}>") # Not in the family
+    TripleStore.instance.insert("", "<#{private_component_uri}>") # In the family, but not viewable
+    TripleStore.instance.insert("", "<#{component_uri}>") # In the family
+
+    # Should only return one result
+    resp = rest_request(:get, 'components', nil, {'component-family' => family_uri})
+    assert_response(:success)
+    assert_equal 3, TripleStore.instance.repo.keys.size
+    assert_equal 1, resp.find('//workflow').size
+    assert_equal component_uri, resp.find_first('//workflow')['resource']
+
+    # Clean up
+    TripleStore.instance.repo = {}
+  end
+
+  test "component query only returns local results" do
+    # Set up
+    login_as(:john)
+
+    uri = polymorphic_url(workflows(:component_workflow))
+
+    TripleStore.instance.repo = {}
+    TripleStore.instance.insert("", "<http://www.google.com/>")
+    TripleStore.instance.insert("", "<http://www.example.com/workflows/456>")
+    TripleStore.instance.insert("", "<#{uri}>")
+
+    # Should only return one result
     resp = rest_request(:get, 'components', nil, {'prefixes' => '', 'query' => ''})
     assert_response(:success)
+    assert_equal 3, TripleStore.instance.repo.keys.size
     assert_equal 1, resp.find('//workflow').size
+    assert_equal uri, resp.find_first('//workflow')['resource']
+
+    # Clean up
+    TripleStore.instance.repo = {}
   end
 
+  test "component query doesn't return private components" do
+    # Set up
+    TripleStore.instance.repo = {}
+    TripleStore.instance.insert("", "<#{polymorphic_url(workflows(:private_component_workflow))}>")
+
+    # Should only return one result
+    resp = rest_request(:get, 'components', nil, {'prefixes' => '', 'query' => ''})
+    assert_response(:success)
+    assert_equal 1, TripleStore.instance.repo.keys.size
+    assert_equal 0, resp.find('//workflow').size
+
+    # Clean up
+    TripleStore.instance.repo = {}
+  end
+
+  test "component query does return private components for authorized user" do
+    # Set up
+    login_as(:john)
+
+    uri = polymorphic_url(workflows(:private_component_workflow))
+
+    TripleStore.instance.repo = {}
+    TripleStore.instance.insert("", "<#{uri}>")
+
+    # Should only return one result
+    resp = rest_request(:get, 'components', nil, {'prefixes' => '', 'query' => ''})
+    assert_response(:success)
+    assert_equal 1, TripleStore.instance.repo.keys.size
+    assert_equal 1, resp.find('//workflow').size
+    assert_equal uri, resp.find_first('//workflow')['resource']
+
+    # Clean up
+    TripleStore.instance.repo = {}
+  end
+
+  test "can get list of component profiles" do
+    login_as(:john)
+
+    profile_count = Blob.all.select { |b| b.component_profile? }.size
+
+    resp = rest_request(:get, 'component-profiles')
+    assert_response(:success)
+
+    assert_equal profile_count, resp.find('//file').size
+    profiles = resp.find('//file').map { |f| Blob.find(f['resource'].split('/').last.to_i) }
+    assert_includes profiles, blobs(:component_profile)
+  end
+
+  test "can create component profile" do
+    login_as(:john)
+
+    # Get list of profiles first
+    resp = rest_request(:get, 'component-profiles')
+    assert_response(:success)
+    profile_count = resp.find('//file').size
+
+    content = Base64.encode64(File.read('test/fixtures/files/workflow_dilbert.xml'))
+    body = %(
+      <file>
+        <title>Component Profile</title>
+        <filename>profile.xml</filename>
+        <description>It's for components</description>
+        <content-type>application/vnd.taverna.component-profile+xml</content-type>
+        <content>#{content}</content>
+        <license-type>by-sa</license-type>
+      </file>
+    )
+
+    resp = rest_request(:post, 'component-profile', body)
+    assert_response(:success)
+
+    uri = resp.find_first('//file')['resource']
+    profile = ""
+    assert_not_nil profile
+    assert_includes profile.tags.map {|t| t.name }, 'component profile'
+
+    # Check new family returned in list
+    resp = rest_request(:get, 'component-profiles')
+    assert_response(:success)
+    assert_equal profile_count+1, resp.find('//file').size
+    assert_includes resp.find('//file').map {|f| f['resource']}, uri
+  end
+
+  test "can delete component profile that isn't used in any families" do
+    login_as(:john)
+
+    profile = ""
+
+    assert_difference('Blob.count', -1) do
+      rest_request(:delete, 'component-profile', nil, 'id' => profile.id)
+    end
+
+    assert_response(:success)
+  end
+
+  test "can't delete component profile that is used" do
+    login_as(:john)
+
+    profile = ""
+
+    assert_no_difference('Blob.count') do
+      rest_request(:delete, 'component-profile', nil, 'id' => profile.id)
+    end
+
+    assert_response(400)
+  end
+
+  test "can get list of component families" do
+    login_as(:john)
+
+    family_count = Pack.all.select { |p| p.component_family? }.size
+
+    resp = rest_request(:get, 'component-families')
+    assert_response(:success)
+
+    assert_equal family_count, resp.find('//pack').size
+    families = resp.find('//pack').map { |f| Pack.find(f['resource'].split('/').last.to_i) }
+    assert_includes families, packs(:component_family)
+  end
+
+  test "can create component family" do
+    login_as(:john)
+
+    family_count = Pack.all.select { |p| p.component_family? }.size
+
+    body = %(
+      <pack>
+        <title>A Component Family</title>
+        <description>It's for components</description>
+        <component-profile>#{polymorphic_url(blobs(:component_profile))}</component-profile>
+        <license-type>by-sa</license-type>
+      </pack>
+    )
+
+    resp = rest_request(:post, 'component-family', body)
+    assert_response(:success)
+
+    uri = resp.find_first('//pack')['resource']
+    family = Pack.find_by_id(uri.split('/').last.to_i)
+    assert_not_nil family
+    assert_includes family.tags.map {|t| t.name }, 'component family'
+
+    resp = rest_request(:get, 'component-families')
+    assert_response(:success)
+    assert_equal family_count+1, resp.find('//pack').size
+    assert_includes resp.find('//pack').map { |p| p['resource'] }, uri
+  end
+
+  test "can't create component family with missing profile uri" do
+    login_as(:john)
+
+    body = %(
+      <pack>
+        <title>A Component Family</title>
+        <description>It's for components</description>
+        <license-type>by-sa</license-type>
+      </pack>
+    )
+
+    assert_no_difference('Pack.count') do
+      rest_request(:post, 'component-family', body)
+    end
+
+    assert_response(400)
+  end
+
+  test "can't create component family with invalid profile uri" do
+    login_as(:john)
+
+    body = %(
+      <pack>
+        <title>A Component Family</title>
+        <description>It's for components</description>
+        <component-profile>http://www.example.com/profiles/241</component-profile>
+        <license-type>by-sa</license-type>
+      </pack>
+    )
+
+    assert_no_difference('Pack.count') do
+      rest_request(:post, 'component-family', body)
+    end
+
+    assert_response(404)
+  end
+
+
+  test "can't create component family with profile uri pointing to non-profile resources" do
+    login_as(:john)
+
+    body = %(
+      <pack>
+        <title>A Component Family</title>
+        <description>It's for components</description>
+        <component-profile>#{polymorphic_url(blobs(:picture))}</component-profile>
+        <license-type>by-sa</license-type>
+      </pack>
+    )
+
+    assert_no_difference('Pack.count') do
+      rest_request(:post, 'component-family', body)
+    end
+
+    assert_response(400)
+
+    body = %(
+      <pack>
+        <title>A Component Family</title>
+        <description>It's for components</description>
+        <component-profile>#{polymorphic_url(workflows(:workflow_dilbert))}</component-profile>
+        <license-type>by-sa</license-type>
+      </pack>
+    )
+
+    assert_no_difference('Pack.count') do
+      rest_request(:post, 'component-family', body)
+    end
+
+    assert_response(400)
+  end
+
+  test "can delete component family and components" do
+    login_as(:john)
+
+    family = packs(:protected_component_family)
+    component_count = family.contributable_entries.select { |e| e.contributable_type == 'Workflow' && e.contributable.component? }.size
+
+    assert_no_difference('Blob.count') do # Profile not deleted
+    assert_difference('Workflow.count', -component_count) do # Components deleted
+    assert_difference('Pack.count', -1) do # Family deleted
+      rest_request(:delete, 'component-family', nil, 'id' => family.id)
+    end
+    end
+    end
+
+    assert_response(:success)
+  end
+
+  test "can't delete component family containing other people's components" do
+    login_as(:john)
+
+    assert_no_difference('Blob.count') do
+    assert_no_difference('Workflow.count') do
+    assert_no_difference('Pack.count') do
+      rest_request(:delete, 'component-family', nil, 'id' => packs(:communal_component_family).id)
+    end
+    end
+    end
+
+    assert_response(401)
+  end
+
   private
 
   def rest_request(method, uri, data = "" query = {})

Modified: branches/packs/test/functional/users_controller_test.rb (3767 => 3768)


--- branches/packs/test/functional/users_controller_test.rb	2013-11-01 15:58:35 UTC (rev 3767)
+++ branches/packs/test/functional/users_controller_test.rb	2013-11-03 11:12:46 UTC (rev 3768)
@@ -23,7 +23,7 @@
   def test_should_create_user
     old_count = User.count
 
-    post :create, :user => { :unconfirmed_email => 'address@hidden', :username => 'new_user', :password => 'secret', :password_confirmation => 'secret' }
+    post :create, :user => { :name => "John Doe", :unconfirmed_email => 'address@hidden', :username => 'new_user', :password => 'secret', :password_confirmation => 'secret' }
 
     assert_equal old_count+1, User.count    
     assert_redirected_to :action ="" :index

reply via email to

[Prev in Thread] Current Thread [Next in Thread]