myexperiment-hackers
[Top][All Lists]
Advanced

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

[myexperiment-hackers] [2681] branches/topics: cd branches/topics; svn m


From: noreply
Subject: [myexperiment-hackers] [2681] branches/topics: cd branches/topics; svn merge -r 2584:2680 svn+ssh: //address@hidden/var/svn/myexperiment/trunk
Date: Wed, 31 Aug 2011 11:23:15 -0400 (EDT)

Revision
2681
Author
dgc
Date
2011-08-31 11:23:15 -0400 (Wed, 31 Aug 2011)

Log Message

cd branches/topics; svn merge -r 2584:2680 svn+ssh://address@hidden/var/svn/myexperiment/trunk

Modified Paths

Added Paths

Removed Paths

Property Changed

Diff

Property changes: branches/topics


Modified: svn:ignore

+ index .project

Modified: branches/topics/Rakefile (2680 => 2681)


--- branches/topics/Rakefile	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/Rakefile	2011-08-31 15:23:15 UTC (rev 2681)
@@ -17,6 +17,7 @@
   User.rebuild_solr_index
   Network.rebuild_solr_index
   Pack.rebuild_solr_index
+  Service.rebuild_solr_index
 end
 
 desc 'Refresh contribution caches'
@@ -56,12 +57,34 @@
   Maintenance::Backup.restore
 end
 
-desc 'Load a controlled vocabulary file'
-task "myexp:vocab:load" do
+desc 'Load a SKOS concept schema'
+task "myexp:skos:load" do
   require File.dirname(__FILE__) + '/config/environment'
-  LoadVocabulary::load_vocabulary
+
+  file_name = ENV['FILE']
+
+  if file_name.nil?
+    puts "Missing file name."
+    return
+  end
+
+  LoadVocabulary::load_skos(YAML::load_file(file_name))
 end
 
+desc 'Load an OWL ontology'
+task "myexp:ontology:load" do
+  require File.dirname(__FILE__) + '/config/environment'
+
+  file_name = ENV['FILE']
+
+  if file_name.nil?
+    puts "Missing file name."
+    return
+  end
+
+  LoadVocabulary::load_ontology(YAML::load_file(file_name))
+end
+
 desc 'Refresh workflow metadata'
 task "myexp:refresh:workflows" do
   require File.dirname(__FILE__) + '/config/environment'
@@ -75,3 +98,31 @@
   end
 end
 
+desc 'Import data from BioCatalogue'
+task "myexp:import:biocat" do
+  require File.dirname(__FILE__) + '/config/environment'
+
+  Contribution.delete_all("contributable_type = 'Service'")
+
+  conn = ActiveRecord::Base.connection
+
+  BioCatalogueImport.import_biocatalogue
+end
+
+desc 'Update OAI static repository file'
+task "myexp:oai:static" do
+  require File.dirname(__FILE__) + '/config/environment'
+
+  # Obtain all public workflows
+
+  workflows = Workflow.find(:all).select do |workflow|
+    Authorization.check(:action ="" 'read', :object => workflow, :user => nil)
+  end
+
+  # Generate OAI static repository file
+
+  File::open('public/oai/static.xml', 'wb') do |f|
+    f.write(OAIStaticRepository.generate(workflows))
+  end
+end
+

Modified: branches/topics/app/controllers/application.rb (2680 => 2681)


--- branches/topics/app/controllers/application.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/controllers/application.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -385,6 +385,16 @@
     end
   end
 
+  def send_cached_data(file_name, *opts)
+
+    if !File.exists?(file_name)
+      FileUtils.mkdir_p(File.dirname(file_name))
+      File.open(file_name, "wb+") { |f| f.write(yield) }
+    end
+
+    send_file(file_name, *opts)
+  end
+
   # Pivot code
   
   def pivot_options
@@ -394,57 +404,57 @@
         {
           :option => 'rank',
           :label  => 'Rank',
-          :order  => 'rank DESC'
+          :order  => 'contributions.rank DESC'
         },
         
         {
           :option => 'title',
           :label  => 'Title',
-          :order  => 'label, rank DESC'
+          :order  => 'contributions.label, contributions.rank DESC'
         },
 
         {
           :option => 'latest',
           :label  => 'Latest',
-          :order  => 'created_at DESC, rank DESC'
+          :order  => 'contributions.created_at DESC, contributions.rank DESC'
         },
 
         {
           :option => 'last_updated',
           :label  => 'Last updated',
-          :order  => 'updated_at DESC, rank DESC'
+          :order  => 'contributions.updated_at DESC, contributions.rank DESC'
         },
 
         {
           :option => 'rating',
           :label  => 'Community rating',
-          :order  => 'rating DESC, rank DESC'
+          :order  => 'contributions.rating DESC, contributions.rank DESC'
         },
 
         {
           :option => 'viewings',
           :label  => 'Most viewed',
-          :order  => 'site_viewings_count DESC, rank DESC'
+          :order  => 'contributions.site_viewings_count DESC, contributions.rank DESC'
         },
 
         {
           :option => 'downloads',
           :label  => 'Most downloaded',
-          :order  => 'site_downloads_count DESC, rank DESC'
+          :order  => 'contributions.site_downloads_count DESC, contributions.rank DESC'
         },
 
         {
           :option => 'type',
           :label  => 'Type',
           :joins  => [ :content_types ],
-          :order  => 'content_types.title, rank DESC'
+          :order  => 'content_types.title, contributions.rank DESC'
         },
 
         {
           :option => 'licence',
           :label  => 'Licence',
           :joins  => [ :licences ],
-          :order  => 'licenses.title, rank DESC'
+          :order  => 'licenses.title, contributions.rank DESC'
         },
 
         {
@@ -462,8 +472,8 @@
         {
           :title        => 'category',
           :query_option => 'CATEGORY',
-          :id_column    => 'contributions.contributable_type',
-          :label_column => 'contributions.contributable_type',
+          :id_column    => :auth_type,
+          :label_column => :auth_type,
           :visible_name => true
         },
 
@@ -533,13 +543,13 @@
         :content_types       => "LEFT OUTER JOIN content_types ON contributions.content_type_id = content_types.id",
         :licences            => "LEFT OUTER JOIN licenses ON contributions.license_id = licenses.id",
         :users               => "INNER JOIN users ON contributions.contributor_type = 'User' AND contributions.contributor_id = users.id",
-        :taggings            => "LEFT OUTER JOIN taggings ON contributions.contributable_type = taggings.taggable_type AND contributions.contributable_id = taggings.taggable_id",
+        :taggings            => "LEFT OUTER JOIN taggings ON AUTH_TYPE = taggings.taggable_type AND AUTH_ID = taggings.taggable_id",
         :tags                => "INNER JOIN tags ON taggings.tag_id = tags.id",
         :networks            => "INNER JOIN networks ON permissions.contributor_type = 'Network' AND permissions.contributor_id = networks.id",
-        :credits             => "INNER JOIN creditations ON creditations.creditable_type = contributions.contributable_type AND creditations.creditable_id = contributions.contributable_id",
-        :curation_events     => "INNER JOIN curation_events ON curation_events.object_type = contributions.contributable_type AND curation_events.object_id = contributions.contributable_id",
-        :workflow_processors => "INNER JOIN workflow_processors ON contributions.contributable_type = 'Workflow' AND workflow_processors.workflow_id = contributions.contributable_id",
-        :search              => "RIGHT OUTER JOIN search_results ON search_results.result_type = contributions.contributable_type AND search_results.result_id = contributions.contributable_id",
+        :credits             => "INNER JOIN creditations ON creditations.creditable_type = AUTH_TYPE AND creditations.creditable_id = AUTH_ID",
+        :curation_events     => "INNER JOIN curation_events ON curation_events.object_type = AUTH_TYPE AND curation_events.object_id = AUTH_ID",
+        :workflow_processors => "INNER JOIN workflow_processors ON AUTH_TYPE = 'Workflow' AND workflow_processors.workflow_id = AUTH_ID",
+        :search              => "RIGHT OUTER JOIN search_results ON search_results.result_type = AUTH_TYPE AND search_results.result_id = AUTH_ID",
         :topic_workflow_map  => "INNER JOIN topic_workflow_map ON contributions.id = topic_workflow_map.workflow_id"
       }
     }
@@ -701,27 +711,27 @@
 
     def create_search_results_table(search_query, models)
 
-      solr_results = User.multi_solr_search(search_query,
+      solr_results = models.first.multi_solr_search(search_query,
           :models         => models,
           :results_format => :ids,
           :limit          => Conf.max_search_size)
 
       conn =  ActiveRecord::Base.connection
 
-      conn.execute("CREATE TEMPORARY TABLE search_results (result_type VARCHAR(255), result_id INT)")
+      conn.execute("CREATE TEMPORARY TABLE search_results (id INT AUTO_INCREMENT UNIQUE KEY, result_type VARCHAR(255), result_id INT)")
 
       # This next part converts the search results to SQL values
       #
       # from:  { "id" => "Workflow:4" }, { "id" => "Pack:6" }, ...
-      # to:    "('Workflow', '4'), ('Pack', '6'), ..."
+      # to:    "(NULL, 'Workflow', '4'), (NULL, 'Pack', '6'), ..."
 
       if solr_results.results.length > 0
         insert_part = solr_results.results.map do |result|
-          "(" + result["id"].split(":").map do |bit|
+          "(NULL, " + result["id"].split(":").map do |bit|
             "'#{bit}'"
           end.join(", ") + ")"
         end.join(", ")
-
+ 
         conn.execute("INSERT INTO search_results VALUES #{insert_part}")
       end
     end
@@ -747,6 +757,18 @@
       "HAVING " + having_bits.join(" OR ")
     end
 
+    def column(column, opts)
+      if column == :auth_type
+        if opts[:auth_type]
+          opts[:auth_type]
+        else
+          "contributions.contributable_type"
+        end
+      else
+        column
+      end
+    end
+
     def calculate_filter(params, filter, user, opts = {})
 
       # apply all the joins and conditions except for the current filter
@@ -757,97 +779,113 @@
       pivot_options[:filters].each do |other_filter|
         if filter_list = find_filter(opts[:filters], other_filter[:query_option])
           unless opts[:inhibit_other_conditions]
-            conditions << comparison(other_filter[:id_column], filter_list[:expr][:terms]) unless other_filter == filter
+            conditions << comparison(column(other_filter[:id_column], opts), filter_list[:expr][:terms]) unless other_filter == filter
           end
           joins += other_filter[:joins] if other_filter[:joins]
         end
       end
 
+      filter_id_column    = column(filter[:id_column],    opts)
+      filter_label_column = column(filter[:label_column], opts)
+
       joins += filter[:joins] if filter[:joins]
-      conditions << "#{filter[:id_column]} IS NOT NULL" if filter[:not_null]
+      conditions << "#{filter_id_column} IS NOT NULL" if filter[:not_null]
 
       unless opts[:inhibit_filter_query]
         if params[:filter_query]
-          conditions << "(#{filter[:label_column]} LIKE '%#{escape_sql(params[:filter_query])}%')"
+          conditions << "(#{filter_label_column} LIKE '%#{escape_sql(params[:filter_query])}%')"
         end
       end
 
-      joins.push(:search) if params[:query]
+      joins.push(:search) if params[:query] && !opts[:arbitrary_models]
 
       current = find_filter(opts[:filters], filter[:query_option]) ? find_filter(opts[:filters], filter[:query_option])[:expr][:terms] : []
 
       if opts[:ids].nil?
         limit = 10
       else
-        conditions << "(#{filter[:id_column]} IN ('#{opts[:ids].map do |id| escape_sql(id) end.join("','")}'))"
+        conditions << "(#{filter_id_column} IN ('#{opts[:ids].map do |id| escape_sql(id) end.join("','")}'))"
         limit = nil
       end
 
       conditions = conditions.length.zero? ? nil : conditions.join(" AND ")
 
-      objects = Authorization.authorised_index(Contribution,
+      if opts[:auth_type] && opts[:auth_id]
+        count_expr = "COUNT(DISTINCT #{opts[:auth_type]}, #{opts[:auth_id]})"
+      else
+        count_expr = "COUNT(DISTINCT contributions.contributable_type, contributions.contributable_id)"
+      end
+
+      objects = Authorization.authorised_index(params[:query] && opts[:arbitrary_models] ? SearchResult : Contribution,
           :all,
           :include_permissions => true,
-          :select => "#{filter[:id_column]} AS filter_id, #{filter[:label_column]} AS filter_label, COUNT(DISTINCT contributions.contributable_type, contributions.contributable_id) AS filter_count",
-          :joins => joins.length.zero? ? nil : joins.uniq.map do |j| pivot_options[:joins][j] end.join(" "),
+          :select => "#{filter_id_column} AS filter_id, #{filter_label_column} AS filter_label, #{count_expr} AS filter_count",
+          :arbitrary_models => opts[:arbitrary_models],
+          :auth_type => opts[:auth_type],
+          :auth_id => opts[:auth_id],
+          :joins => merge_joins(joins, :auth_type => opts[:auth_type], :auth_id => opts[:auth_id]),
           :conditions => conditions,
-          :group => "#{filter[:id_column]} #{calculate_having_clause(filter, opts)}",
+          :group => "#{filter_id_column} #{calculate_having_clause(filter, opts)}",
           :limit => limit,
-          :order => "COUNT(DISTINCT contributions.contributable_type, contributions.contributable_id) DESC, #{filter[:label_column]}",
-          :authorised_user => user).map do |object|
+          :order => "#{count_expr} DESC, #{filter_label_column}",
+          :authorised_user => user)
+      
+      objects = objects.select do |x| !x[:filter_id].nil? end
 
-            value = object.filter_id.to_s
-            selected = current.include?(value)
+      objects = objects.map do |object|
 
-            label_expr = deep_clone(opts[:filters])
-            label_expr -= [find_filter(label_expr, filter[:query_option])] if find_filter(label_expr, filter[:query_option])
+        value = object.filter_id.to_s
+        selected = current.include?(value)
 
-            unless selected && current.length == 1
-              label_expr << { :name => filter[:query_option], :expr => { :terms => [value] } }
-            end
+        label_expr = deep_clone(opts[:filters])
+        label_expr -= [find_filter(label_expr, filter[:query_option])] if find_filter(label_expr, filter[:query_option])
 
-            checkbox_expr = deep_clone(opts[:filters])
+        unless selected && current.length == 1
+          label_expr << { :name => filter[:query_option], :expr => { :terms => [value] } }
+        end
 
-            if expr_filter = find_filter(checkbox_expr, filter[:query_option])
+        checkbox_expr = deep_clone(opts[:filters])
 
-              if selected
-                expr_filter[:expr][:terms] -= [value]
-              else
-                expr_filter[:expr][:terms] += [value]
-              end
+        if expr_filter = find_filter(checkbox_expr, filter[:query_option])
 
-              checkbox_expr -= [expr_filter] if expr_filter[:expr][:terms].empty?
+          if selected
+            expr_filter[:expr][:terms] -= [value]
+          else
+            expr_filter[:expr][:terms] += [value]
+          end
 
-            else
-              checkbox_expr << { :name => filter[:query_option], :expr => { :terms => [value] } }
-            end
+          checkbox_expr -= [expr_filter] if expr_filter[:expr][:terms].empty?
 
-            label_uri = build_url(params, opts, label_expr, [:filter, :order], "page" => nil)
+        else
+          checkbox_expr << { :name => filter[:query_option], :expr => { :terms => [value] } }
+        end
 
-            checkbox_uri = build_url(params, opts, checkbox_expr, [:filter, :order], "page" => nil)
+        label_uri = build_url(params, opts, label_expr, [:filter, :order], "page" => nil)
 
-            label = object.filter_label.clone
-            label = visible_name(label) if filter[:visible_name]
-            label = label.capitalize    if filter[:capitalize]
+        checkbox_uri = build_url(params, opts, checkbox_expr, [:filter, :order], "page" => nil)
 
-            plain_label = object.filter_label
+        label = object.filter_label.clone
+        label = visible_name(label) if filter[:visible_name]
+        label = label.capitalize    if filter[:capitalize]
 
-            if params[:filter_query]
-              label.sub!(Regexp.new("(#{params[:filter_query]})", Regexp::IGNORECASE), '<b>\1</b>')
-            end
+        plain_label = object.filter_label
 
-            {
-              :object       => object,
-              :value        => value,
-              :label        => label,
-              :plain_label  => plain_label,
-              :count        => object.filter_count,
-              :checkbox_uri => checkbox_uri,
-              :label_uri    => label_uri,
-              :selected     => selected
-            }
-          end
+        if params[:filter_query]
+          label.sub!(Regexp.new("(#{params[:filter_query]})", Regexp::IGNORECASE), '<b>\1</b>')
+        end
 
+        {
+          :object       => object,
+          :value        => value,
+          :label        => label,
+          :plain_label  => plain_label,
+          :count        => object.filter_count,
+          :checkbox_uri => checkbox_uri,
+          :label_uri    => label_uri,
+          :selected     => selected
+        }
+      end
+
       [current, objects]
     end
 
@@ -898,6 +936,26 @@
       end
     end
 
+    def merge_joins(joins, opts = {})
+
+      opts[:auth_type] ||= 'contributions.contributable_type'
+      opts[:auth_id]   ||= 'contributions.contributable_id'
+
+      if joins.length.zero?
+        nil
+      else
+        joins.uniq.map do |j|
+          text = pivot_options[:joins][j]
+          text.gsub!(/AUTH_TYPE/, opts[:auth_type])
+          text.gsub!(/AUTH_ID/,   opts[:auth_id])
+          text
+        end.join(" ")
+      end
+    end
+
+    joins      = []
+    conditions = []
+
     # parse the filter _expression_ if provided.  convert filter _expression_ to
     # the old format.  this will need to be replaced eventually
 
@@ -919,14 +977,31 @@
       end
     end
 
+    # perform search if requested
+
+    group_by = "contributions.contributable_type, contributions.contributable_id"
+
+    if params["query"]
+      drop_search_results_table
+      create_search_results_table(params["query"], [Workflow, Blob, Pack, User, Network, Service])
+      joins.push(:search) unless opts[:arbitrary_models]
+    end
+
+    if opts[:arbitrary_models] && params[:query]
+      klass = SearchResult
+      contribution_records = false
+      auth_type = "search_results.result_type"
+      auth_id   = "search_results.result_id"
+      group_by  = "search_results.result_type, search_results.result_id"
+    else
+      contribution_records = true
+    end
+
     # determine joins, conditions and order for the main results
 
-    joins      = []
-    conditions = []
-
     pivot_options[:filters].each do |filter|
       if filter_list = find_filter(opts[:filters], filter[:query_option])
-        conditions << comparison(filter[:id_column], filter_list[:expr][:terms])
+        conditions << comparison(column(filter[:id_column], opts.merge( { :auth_type => auth_type, :auth_id => auth_id } )), filter_list[:expr][:terms])
         joins += filter[:joins] if filter[:joins]
       end
     end
@@ -939,14 +1014,6 @@
 
     joins += order_options[:joins] if order_options[:joins]
 
-    # perform search if requested
-
-    if params["query"]
-      drop_search_results_table
-      create_search_results_table(params["query"], [Workflow, Blob, Pack])
-      joins.push(:search)
-    end
-
     having_bits = []
 
 #   pivot_options[:filters].each do |filter|
@@ -967,11 +1034,14 @@
         :all,
         :authorised_user => user,
         :include_permissions => true,
-        :contribution_records => true,
+        :contribution_records => contribution_records,
+        :arbitrary_models => opts[:arbitrary_models],
+        :auth_type => auth_type,
+        :auth_id => auth_id,
         :page => { :size => params["num"] ? params["num"].to_i : nil, :current => params["page"] },
-        :joins => joins.length.zero? ? nil : joins.uniq.map do |j| pivot_options[:joins][j] end.join(" "),
+        :joins => merge_joins(joins, :auth_type => auth_type, :auth_id => auth_id),
         :conditions => conditions.length.zero? ? nil : conditions.join(" AND "),
-        :group => "contributions.contributable_type, contributions.contributable_id #{having_clause}",
+        :group => "#{group_by} #{having_clause}",
         :order => order_options[:order])
 
     # produce a query hash to match the current filters
@@ -987,13 +1057,16 @@
 
     # produce the filter list
 
-    filters, cancel_filter_query_url = calculate_filters(params, opts, user)
+    opts_for_filter_query = opts.merge( { :auth_type => auth_type,
+        :auth_id => auth_id, :group_by => group_by } )
 
+    filters, cancel_filter_query_url = calculate_filters(params, opts_for_filter_query, user)
+
     # produce the summary.  If a filter query is specified, then we need to
     # recalculate the filters without the query to get all of them.
 
     if params[:filter_query]
-      filters2 = calculate_filters(params, opts.merge( { :inhibit_filter_query => true } ), user)[0]
+      filters2 = calculate_filters(params, opts_for_filter_query.merge( { :inhibit_filter_query => true } ), user)[0]
     else
       filters2 = filters
     end

Modified: branches/topics/app/controllers/content_controller.rb (2680 => 2681)


--- branches/topics/app/controllers/content_controller.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/controllers/content_controller.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -21,7 +21,7 @@
         end
 
         @pivot = contributions_list(Contribution, params, current_user,
-            :filters => expr)
+            :filters => expr, :arbitrary_models => true)
 
         # index.rhtml
       end

Modified: branches/topics/app/controllers/oauth_controller.rb (2680 => 2681)


--- branches/topics/app/controllers/oauth_controller.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/controllers/oauth_controller.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -1,5 +1,6 @@
 class OauthController < ApplicationController
   before_filter :login_required,:except=>[:request_token,:access_token,:test_request]
+  before_filter :find_client_application_auth, : :edit, :update, :destroy]
   before_filter :login_or_oauth_required,:
   before_filter :verify_oauth_consumer_signature, :
   before_filter :verify_oauth_request_token, :
@@ -13,8 +14,8 @@
     else
       render :nothing => true, :status => 401
     end
-  end 
-  
+  end
+
   def access_token
     @token=current_token.exchange!
     if @token
@@ -27,14 +28,22 @@
   def test_request
     render :text=>params.collect{|k,v|"#{k}=#{v}"}.join("&")
   end
-  
+
   def authorize
     @client_applications=current_user.client_applications
     @token=RequestToken.find_by_token params[:oauth_token]
+    if @token.client_application.nil?
+       if redirect_url
+         redirect_to redirect_url+"?oauth_failure=1"
+       else
+         render :action=""
+       end
+    end
+    @address@hidden
     redirect_url=params[:oauth_callback]||@token.client_application.callback_url
-    if @client_applications.include?(@token.client_application)
-      unless @token.invalidated?    
-        if request.post? 
+    if (@token.client_application.key_type == 'System') || @client_applications.include?(@token.client_application)
+      unless @token.invalidated?
+        if request.post?
           if params[:authorize]=='1'
             @token.authorize!(current_user)
             if redirect_url
@@ -44,11 +53,11 @@
             end
           elsif params[:commit]=="Save Changes"
             @token.invalidate!
-	    if redirect_url
-	      redirect_to redirect_url+"?oauth_failure=1"
-	    else 
+            if redirect_url
+              redirect_to redirect_url+"?oauth_failure=1"
+            else
               render :action=""
-	    end
+            end
           end
         end
       else
@@ -66,7 +75,7 @@
        end
     end
   end
-  
+
   def revoke
     @token=current_user.tokens.find_by_token params[:token]
     if @token
@@ -75,7 +84,7 @@
     end
     redirect_to oauth_url
   end
-  
+
   def index
     @client_applications=current_user.client_applications
     @admin_client_applications=ClientApplication.find(:all, :conditions => ["user_id != ? and creator_id = ?", current_user.id, current_user.id])
@@ -92,9 +101,11 @@
   def create
     @client_application=current_user.client_applications.build(params[:client_application])
     if @client_application.save
-      for key_permission in params[:key_permissions] do
-        @key_permission = KeyPermission.new(:client_application_id => @client_application.id, :for ="" key_permission[0])
-        @key_permission.save
+      if params[:key_permissions] 
+        for key_permission in params[:key_permissions] do
+          @key_permission = KeyPermission.new(:client_application_id => @client_application.id, :for ="" key_permission[0])
+          @key_permission.save
+        end
       end
       flash[:notice]="Client Application successfully registered!"
       redirect_to :action=""
@@ -102,11 +113,10 @@
       render :action=""
     end
   end
-  
+
   def show
-    @client_application=ClientApplication.find(params[:id])
     if (!(@client_application.user_id == current_user.id or @client_application.creator_id == current_user.id))
-    	@client_application = nil
+      @client_application = nil
     end
     @address@hidden
   end
@@ -114,26 +124,23 @@
   def edit
     @permissions = TABLES['REST'][:data]
     @address@hidden
-    @client_application=ClientApplication.find(params[:id])
     if (!(@client_application.user_id == current_user.id or @client_application.creator_id == current_user.id))
         @client_application = nil
     end
     @address@hidden
     unless @client_application.nil?
-    	@address@hidden
+      @address@hidden
     end
   end
-  
+
   def update
-    @client_application=ClientApplication.find(params[:client_application][:id])
-    if (!(@client_application.user_id == current_user.id or @client_application.creator_id == current_user.id))
-        @client_application = nil
-    end
     if (current_user.admin? or @client_application.key_type=="User")
       @client_application.permissions.delete_all
-      for key_permission in params[:key_permissions] do
-        @key_permission = KeyPermission.new(:client_application_id => @client_application.id, :for ="" key_permission[0])
-         @key_permission.save
+      if params[:key_permissions] 
+        for key_permission in params[:key_permissions] do
+          @key_permission = KeyPermission.new(:client_application_id => @client_application.id, :for ="" key_permission[0])
+           @key_permission.save
+        end
       end
     end
     if @client_application.update_attributes(params[:client_application])
@@ -145,11 +152,39 @@
   end
 
   def destroy
-    @client_application=current_user.client_applications.find(params[:id])
     address@hidden
     @client_application.destroy
     flash[:notice]="Registration for Client Application '#{client_application_name}' has been removed!"
     redirect_to :action=""
   end
-  
+
+private
+
+  def find_client_application_auth
+    if action_name == 'update'
+      id = params[:client_application][:id]
+    else
+      id = params[:id]
+    end
+    begin
+      client_app=ClientApplication.find(id)
+      if Authorization.is_authorized?(action_name, nil, client_app, current_user)
+        @client_application = client_app
+      else
+        error("Client Application not found (id not authorized)", "is invalid (not authorized)")
+        return false
+      end
+    rescue ActiveRecord::RecordNotFound
+      error("Client Application not found", "is invalid")
+      return false
+    end
+  end
+
+  def error(notice, message, attr=:id)
+    flash[:error] = notice
+
+    respond_to do |format|
+      format.html { redirect_to oauth_url }
+    end
+  end
 end

Modified: branches/topics/app/controllers/pictures_controller.rb (2680 => 2681)


--- branches/topics/app/controllers/pictures_controller.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/controllers/pictures_controller.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -6,6 +6,7 @@
 class PicturesController < ApplicationController
   before_filter :login_required, :except => [:index, :show]
   
+  before_filter :find_picture, : [:show]
   before_filter :find_pictures, : [:index]
   before_filter :find_picture_auth, : [:select, :edit, :update, :destroy]
   
@@ -36,21 +37,36 @@
   # GET /users/1/pictures/1
   # GET /pictures/1
   def show
-    size = params[:size] || "200x200"
-    size = size[0..-($1.length.to_i + 2)] if size =~ /[0-9]+x[0-9]+\.([a-z0-9]+)/ # trim file extension
+
+    matches = params[:size].match("([0-9]+)x([0-9]+).*") if params[:size]
+
+    default_size = 200
+    min_size     = 16
+    max_size     = 200
+
+    if matches
+
+      width  = matches[1].to_i
+      height = matches[2].to_i
+
+      if ((width < min_size) || (width > max_size) || (height < min_size) || (height > max_size))
+        width  = default_size
+        height = default_size
+      end
+
+    else
+      width  = 200
+      height = 200
+    end
     
-    id = params[:id].to_i
-
-    send_cached_data("public/pictures/show/#{size}/#{id}.jpg",
+    send_cached_data("public/pictures/show/#{width.to_i}x#{height.to_i}/#{params[:id].to_i}.jpg",
         :type => 'image/jpeg', :disposition => 'inline') {
 
-      find_picture
+      img = Magick::Image.from_blob(@picture.data).first
+      img = img.change_geometry("#{width}x#{height}>") do |c, r, i| i.resize(c, r) end
 
-      # resize and encode the picture
-      @picture.resize!(:size => size)
-      @picture.to_jpg!
-
-      @picture.data
+      img.format = "jpg"
+      img.to_blob
     }
 
   end
@@ -70,7 +86,7 @@
   # POST /users/1/pictures
   # POST /pictures
   def create
-    @picture = Picture.create(:data ="" params[:picture][:data], :user_id => current_user.id)
+    @picture = Picture.create(:data ="" params[:picture][:data].read, :user_id => current_user.id)
 
     respond_to do |format|
       if @picture.save
@@ -157,17 +173,5 @@
       format.html { redirect_to logged_in? ? pictures_url(current_user) : '' }
     end
   end
-
-  # file system cache
-
-  def send_cached_data(file_name, *opts)
-
-    if !File.exists?(file_name)
-      FileUtils.mkdir_p(File.dirname(file_name))
-      File.open(file_name, "wb+") { |f| f.write(yield) }
-    end
-
-    send_file(file_name, *opts)
-  end
 end
 

Copied: branches/topics/app/controllers/previews_controller.rb (from rev 2680, trunk/app/controllers/previews_controller.rb) (0 => 2681)


--- branches/topics/app/controllers/previews_controller.rb	                        (rev 0)
+++ branches/topics/app/controllers/previews_controller.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -0,0 +1,94 @@
+# myExperiment: app/controllers/previews_controller.rb
+#
+# Copyright (c) 2011 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class PreviewsController < ApplicationController
+
+  before_filter :find_context
+
+  def show
+
+    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 user.nil?
+        render :nothing => true, :status => "401 Unauthorized"
+        response.headers['WWW-Authenticate'] = "Basic realm=\"#{Conf.sitename} REST API\""
+        return
+      end
+    end
+
+    if @context.preview.nil?
+      render :nothing => true, :status => "404 Not Found"
+      return
+    end
+
+    if @context.respond_to?("versioned_resource")
+      auth_object = @context.versioned_resource
+    else
+      auth_object = @context
+    end
+
+    if Authorization.check(:action ="" 'view', :object => auth_object, :user => user) == false
+      render :nothing => true, :status => "401 Unauthorized"
+      response.headers['WWW-Authenticate'] = "Basic realm=\"#{Conf.sitename} REST API\""
+      return
+    end
+
+    type = params[:id]
+
+    case type
+
+      when 'full';   name = 'full';   source = 'image'; size = nil; mime_type = 'image/jpeg'
+      when 'medium'; name = 'medium'; source = 'image'; size = 500; mime_type = 'image/jpeg'
+      when 'thumb';  name = 'thumb';  source = 'image'; size = 100; mime_type = 'image/jpeg'
+      when 'svg';    name = 'svg';    source = 'svg';   size = nil; mime_type = 'image/svg+xml'
+      else
+        render(:inline => 'Bad preview type', :status => "400 Bad Request")
+        return
+    end
+
+    file_name = @context.preview.file_name(type)
+
+    send_cached_data(file_name, :type => mime_type, :disposition => 'inline') {
+
+      case source
+        when 'image'; content_blob = @context.preview.image_blob
+        when 'svg';   content_blob = @context.preview.svg_blob
+      end
+
+      data = ""
+
+      if size
+
+        img = Magick::Image.from_blob(data).first
+        img = img.change_geometry("#{size}x#{size}>") do |c, r, i| i.resize(c, r) end
+
+        result = Magick::Image.new(img.columns, img.rows)
+        result = result.composite(img, 0, 0, Magick::OverCompositeOp)
+        result.format = "jpg"
+
+        data = ""
+      end
+
+      data
+    }
+  end
+
+  private
+
+  def find_context
+    @context = extract_resource_context(params)
+    return false unless @context
+
+    @context = @context.find_version(params[:version]) if params[:version]
+    return false unless @context
+  end
+
+end
+

Modified: branches/topics/app/controllers/relationships_controller.rb (2680 => 2681)


--- branches/topics/app/controllers/relationships_controller.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/controllers/relationships_controller.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -13,13 +13,11 @@
   # GET /:context_type/:context_id/edit_relationships
   def edit_relationships
 
-    @relationships = Relationship.find(:all, :conditions => ['pack_id = ?', @context.id])
+    @predicates = Ontology.find(:all).map do |o| o.predicates end.flatten
 
-    @concepts = Vocabulary.find(:all).map do |v| v.concepts end.flatten
-
     @pack_entries = @context.contributable_entries + @context.remote_entries
 
-    @pack_entry_select_options = @pack_entries.map do |pe|
+    @select_options = @pack_entries.map do |pe|
       if pe.class == PackContributableEntry
         [pe.contributable.label, "contributable:#{pe.id}"]
       else
@@ -34,17 +32,15 @@
     subject = @context.find_pack_item(params[:subject])
     objekt  = @context.find_pack_item(params[:objekt])
 
-    prefix, term = params[:predicate].split(":")
+    prefix, title = params[:predicate].split(":")
 
-    label = Label.find(:first, :conditions =>
-        ['label_type = ? AND vocabulary_id = ? AND text = ?',
-           'preferred',
-           Vocabulary.find_by_prefix(prefix).id,
-           term])
+    predicate = Predicate.find(:first, :conditions =>
+        [' AND title = ?',
+           Ontology.find_by_prefix(prefix).id, title])
 
-    raise("Invalid form data") if subject.nil? || objekt.nil? || label.nil?
+    raise("Invalid form data") if subject.nil? || objekt.nil? || predicate.nil?
 
-    @relationship = Relationship.new(:pack => @context, :concept => label.concept, :user => current_user)
+    @relationship = Relationship.new(:context => @context, :predicate => predicate, :user => current_user)
 
     @relationship.subject = subject
     @relationship.objekt  = objekt
@@ -62,7 +58,7 @@
     end
     
     render :partial => "relationships/relationships",
-           :locals  => { :relationships => @context.relationships }
+           :locals  => { :context => @context, :show_delete => true }
   end
 
   private
@@ -72,7 +68,7 @@
     @context      = extract_resource_context(params)
     @relationship = Relationship.find_by_id(params[:id])
 
-    return false if @relationship.nil? || @context.nil? || @relationship.pack != @context
+    return false if @relationship.nil? || @context.nil? || @relationship.context != @context
     return false if Authorization.is_authorized?('view', nil, @context, current_user) == false
   end
 

Modified: branches/topics/app/controllers/reviews_controller.rb (2680 => 2681)


--- branches/topics/app/controllers/reviews_controller.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/controllers/reviews_controller.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -137,7 +137,7 @@
           error("Workflow not found (id not authorized)", "is invalid (not authorized)")
           return false
         else
-          find_reviewable_auth if login_required
+          login_required
         end
       end
     rescue ActiveRecord::RecordNotFound
@@ -147,7 +147,11 @@
   end
   
   def find_reviews
-    @reviews = @reviewable.reviews
+    if @reviewable
+      @reviews = @reviewable.reviews
+    else
+      @reviews = []
+    end
   end
   
   def find_review

Modified: branches/topics/app/controllers/search_controller.rb (2680 => 2681)


--- branches/topics/app/controllers/search_controller.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/controllers/search_controller.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -4,6 +4,9 @@
 # See license.txt for details.
 
 class SearchController < ApplicationController
+
+  include ApplicationHelper
+
   def show
 
     if params[:query].nil? or params[:query] == ''
@@ -14,6 +17,8 @@
 
     @type = params[:type].to_s.downcase
     
+    @type = "all" if @type.nil? or @type == ""
+
     if !Conf.search_categories.include?(@type)
       error(@type)
       return false
@@ -168,63 +173,22 @@
   end
 
   def search_all
-    @query = params[:query] || ''
-    @query.strip!
 
-    @results = []
+    @query = params[:query]
 
-    if Conf.solr_enable && address@hidden
+    @pivot_options = pivot_options
 
-      categories = (Conf.search_categories - ['all']).map do |category|
-        if Conf.model_aliases.key?(category.camelize.singularize)
-          category = Conf.model_aliases[category.camelize.singularize].pluralize.underscore
-        end
-
-        category
-      end
-
-      models = categories.map do |category| eval(category.singularize.camelize) end
-
-      @total_count = 0
-
-      @infos = []
-
-      models.each do |model|
-
-        begin
-          model_results = model.find_by_solr(@query.downcase, :limit => 10)
-
-          results = model_results.results
-          count   = model_results.total
-        rescue
-          flash.now[:error] = "There was a problem with your search query."
-
-          results = []
-          count   = 0
-        end
-
-        search_type = model.name.downcase.pluralize
-
-        Conf.model_aliases.each do |k,v|
-          search_type = k.downcase.pluralize if model.name == v
-        end
-
-        if (results.length > 0)
-          @infos.push({
-            :search_type => search_type,
-            :model       => model,
-            :results     => results,
-            :total_count => count
-          })
-        end
-
-        @total_count += count
-      end
+    begin
+      expr = parse_filter_expression(params["filter"]) if params["filter"]
+    rescue Exception => ex
+      puts "ex = #{ex.inspect}"
+      flash.now[:error] = "Problem with query _expression_: #{ex}"
+      expr = nil
     end
 
-    respond_to do |format|
-      format.html # search.rhtml
-    end
+    @pivot = contributions_list(Contribution, params, current_user,
+        :filters => expr, :arbitrary_models => true)
+
   end
 
   def search_model

Copied: branches/topics/app/controllers/services_controller.rb (from rev 2680, trunk/app/controllers/services_controller.rb) (0 => 2681)


--- branches/topics/app/controllers/services_controller.rb	                        (rev 0)
+++ branches/topics/app/controllers/services_controller.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -0,0 +1,100 @@
+# myExperiment: app/controllers/services_controller.rb
+#
+# Copyright (c) 2010 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class ServicesController < ApplicationController
+
+  include ApplicationHelper
+
+#  before_filter :find_service,  : [:show]
+  before_filter :find_services, : [:all]
+  
+  # GET /algorithms;search
+  def search
+#   @query = params[:query] || ''
+#   @query.strip!
+#   
+#   @contributables = (Conf.solr_enable && address@hidden) ? Algorithm.find_by_solr(@query, :limit => 100).results : []
+#   @total_count = (Conf.solr_enable && address@hidden) ? Algorithm.count_by_solr(@query) : 0
+#   
+#   respond_to do |format|
+#     format.html # search.rhtml
+#   end
+  end
+  
+  # GET /services
+  def index
+    respond_to do |format|
+      format.html {
+        @pivot_options = pivot_options
+
+        begin
+          expr = parse_filter_expression(params["filter"]) if params["filter"]
+        rescue Exception => ex
+          puts "ex = #{ex.inspect}"
+          flash.now[:error] = "Problem with query _expression_: #{ex}"
+          expr = nil
+        end
+
+        @pivot = contributions_list(Contribution, params, current_user,
+            :lock_filter => { 'CATEGORY' => 'Service' },
+            :filters     => expr)
+
+        # index.rhtml
+      }
+    end
+  end
+  
+  # GET /services/all
+  def all
+    respond_to do |format|
+      format.html # all.rhtml
+    end
+  end
+  
+  # GET /service/1
+  def show
+    raise ActionController::UnknownAction.new
+  end
+  
+  protected
+  
+  def find_services
+    @contributables = Service.find(:all, 
+                       :order => "created_at DESC",
+                       :page => { :size => 20, 
+                       :current => params[:page] })
+  end
+  
+  def find_service
+#    begin
+#      service = Service.find(params[:id])
+#      
+#      @contributable = service
+#      
+#      @contributable_entry_url = url_for : false,
+#                          :host => base_host,
+#                          :id => @contributable.id
+#
+#      @contributable_label                = @contributable.name
+#      @contributable_path                 = service_path(@contributable)
+#
+#    rescue ActiveRecord::RecordNotFound
+#      error("Service not found", "is invalid")
+#      return false
+#    end
+  end
+  
+  private
+  
+  def error(notice, message, attr=:id)
+    flash[:error] = notice
+     (err = Service.new.errors).add(attr, message)
+    
+    respond_to do |format|
+      format.html { redirect_to services_url }
+    end
+  end
+end
+

Modified: branches/topics/app/controllers/session_controller.rb (2680 => 2681)


--- branches/topics/app/controllers/session_controller.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/controllers/session_controller.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -79,17 +79,21 @@
   protected
   
     def password_authentication
-      login, password = params[:session][:username], params[:session][:password]
-      
-      self.current_user = User.authenticate(login, password)
-      if logged_in?
-        if params[:session][:remember_me] == "1"
-          self.current_user.remember_me
-          cookies[:auth_token] = { :value => self.current_user.remember_token , :expires => self.current_user.remember_token_expires_at }
+      if params[:session]
+        login, password = params[:session][:username], params[:session][:password]
+
+        self.current_user = User.authenticate(login, password)
+        if logged_in?
+          if params[:session][:remember_me] == "1"
+            self.current_user.remember_me
+            cookies[:auth_token] = { :value => self.current_user.remember_token , :expires => self.current_user.remember_token_expires_at }
+          end
+          successful_login(self.current_user)
+        else
+          failed_login('Invalid username or password')
         end
-        successful_login(self.current_user)
       else
-        failed_login('Invalid username or password')
+        failed_login('Invalid request')
       end
     end
 

Copied: branches/topics/app/controllers/user_reports_controller.rb (from rev 2680, trunk/app/controllers/user_reports_controller.rb) (0 => 2681)


--- branches/topics/app/controllers/user_reports_controller.rb	                        (rev 0)
+++ branches/topics/app/controllers/user_reports_controller.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -0,0 +1,43 @@
+# myExperiment: app/controllers/user_reports_controller.rb
+#
+# Copyright (c) 2011 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class UserReportsController < ApplicationController
+
+  before_filter :find_object
+  
+  def create
+    UserReport.create(:user => current_user, :subject => @object)
+    render(:text => '[ reported ]')
+  end
+
+  private
+
+  def find_object
+
+    # ensure that user is logged in and that params[:user_id] matches
+    return error if (current_user == 0 || (current_user.id.to_s != params[:user_id]))
+
+    # ensure that the object type is valid
+    return error unless ["Comment", "Message"].include?(params[:subject_type])
+
+    object = Object.const_get(params[:subject_type]).find(params[:subject_id])
+
+    # ensure that the object exists
+    return error if object.nil?
+
+    # ensure that the object is visible to the user
+    return error unless Authorization.check(:action ="" 'read', :object => object, :user => current_user)
+
+    @object = object
+
+    true
+  end
+
+  def error
+    render(:text => '400 Bad Request', :status => "400 Bad Request")
+    false
+  end
+end
+

Modified: branches/topics/app/controllers/users_controller.rb (2680 => 2681)


--- branches/topics/app/controllers/users_controller.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/controllers/users_controller.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -11,8 +11,8 @@
   before_filter :login_required, :except => [:index, :new, :create, :search, :all, :confirm_email, :forgot_password, :reset_password] + show_actions
   
   before_filter :find_users, : [:all]
-  before_filter :find_user, : show_actions
-  before_filter :find_user_auth, : [:edit, :update, :destroy]
+  before_filter :find_user, : [:destroy] + show_actions
+  before_filter :find_user_auth, : [:edit, :update]
   
   # declare sweepers and which actions should invoke them
   cache_sweeper :user_sweeper, : [ :create, :update, :destroy ]
@@ -44,8 +44,6 @@
     @lod_rdf  = formatted_user_url(:id => @user.id, :format => 'rdf')
     @lod_xml  = formatted_user_url(:id => @user.id, :format => 'xml')
 
-    @tab = "News" if @tab.nil?
-
     @user.salt = nil
     @user.crypted_password = nil
     
@@ -147,10 +145,20 @@
     # check that captcha was entered correctly
 
     unless RAILS_ENV == 'test'
-      if !captcha_valid?(params[:validation][:captcha_id], params[:validation][:captcha_validation])
-        flash.now[:error] = 'Verification text was not entered correctly - please try again.'
-        render :action ="" 'new'
-        return
+      if true
+        if Conf.recaptcha_enable
+          if !verify_recaptcha(:private_key => Conf.recaptcha_private)
+            flash.now[:error] = 'Recaptcha text was not entered correctly - please try again.'
+            render :action ="" 'new'
+            return
+          end
+        end
+      else
+        if !captcha_valid?(params[:validation][:captcha_id], params[:validation][:captcha_validation])
+          flash.now[:error] = 'Verification text was not entered correctly - please try again.'
+          render :action ="" 'new'
+          return
+        end
       end
     end
 
@@ -245,20 +253,25 @@
 
   # DELETE /users/1
   def destroy
-    flash[:notice] = 'Please contact the administrator to have your account removed.'
-    redirect_to :action ="" :index
+
+    unless Authorization.check(:action ="" 'destroy', :object => @user, :user => current_user)
+      flash[:notice] = 'You do not have permission to delete this user.'
+      redirect_to :action ="" :index
+      return
+    end
     
-    address@hidden
+    @user.destroy
     
-    # the user MUST be logged in to destroy their account
+    # If the destroyed account belongs to the current user, then
     # it is important to log them out afterwards or they'll 
     # receive a nasty error message..
-    #session[:user_id] = nil
+
+    session[:user_id] = nil if @user == current_user
     
-    #respond_to do |format|
-    #  flash[:notice] = 'User was successfully destroyed'
-    #  format.html { redirect_to users_url }
-    #end
+    respond_to do |format|
+      flash[:notice] = 'User account was successfully deleted'
+      format.html { redirect_to(params[:return_to] ? "#{Conf.base_uri}#{params[:return_to]}" : users_url) }
+    end
   end
   
   # GET /users/confirm_email/:hash

Modified: branches/topics/app/controllers/workflows_controller.rb (2680 => 2681)


--- branches/topics/app/controllers/workflows_controller.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/controllers/workflows_controller.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -9,6 +9,7 @@
 
   before_filter :login_required, :except => [:index, :show, :download, :named_download, :galaxy_tool, :galaxy_tool_download, :statistics, :launch, :search]
   
+  before_filter :store_callback, : [:index, :search]
   before_filter :find_workflows_rss, : [:index]
   before_filter :find_workflow_auth, :except => [:search, :index, :new, :create]
   
@@ -116,14 +117,14 @@
       @download = Download.create(:contribution => @workflow.contribution, :user => (logged_in? ? current_user : nil), :user_agent => request.env['HTTP_USER_AGENT'], :accessed_from_site => accessed_from_website?())
     end
     
-    send_data(@viewing_version.content_blob.data, :filename => @workflow.filename(@viewing_version_number), :type => @workflow.content_type.mime_type)
+    send_data(@viewing_version.content_blob.data, :filename => @workflow.filename(@viewing_version_number), :type => @viewing_version.content_type.mime_type)
   end
   
   # GET /workflows/:id/download/:name
   def named_download
 
     # check that we got the right filename for this workflow
-    if params[:name] == @workflow.filename
+    if params[:name] == @workflow.filename(@viewing_version_number)
       download
     else
       render :nothing => true, :status => "404 Not Found"
@@ -232,8 +233,10 @@
       w.contribution
     end
 
-    @similar_services_limit = 10
+    @wsdls_filter = { :filter => 'WSDL_ENDPOINT=(' + @workflow.unique_wsdls.map do |wsdl| '"' + wsdl.gsub(/"/, '\"') + '"' end.join(" OR ") + ')' }
 
+    @similar_services_limit = 2
+
     respond_to do |format|
       format.html {
 
@@ -546,13 +549,16 @@
         logger.debug("Preview image provided. Attempting to set the version's preview image.")
         
         # Disable updating image on windows due to issues to do with file locking, that prevent file_column from working sometimes.
+        #
+        # The dependency on file_column has been removed, but this code remains
+        # disabled on Windows until it is confirmed as working.
         if RUBY_PLATFORM =~ /mswin32/
           success = false
         else
           success = @workflow.update_version(params[:version], 
                                              :title => params[:workflow][:title], 
                                              :body => params[:workflow][:body], 
-                                             :image => params[:workflow][:preview],
+                                             :image => params[:workflow][:preview].read,
                                              :last_edited_by => current_user.id)
         end
       end
@@ -643,6 +649,26 @@
 
 protected
 
+  def store_callback
+    if params[:callback]
+      session_object={ :url ="" params[:callback], :label => 'Launch', :additional => 'externally', :format => 'xml' }
+      if params[:callback_contenttypes]
+        session_object[:types] =
+            params[:callback_contenttypes].split(',').map {|x| x.to_i }
+      end
+      if params[:callback_label]
+        session_object[:label] = params[:callback_label]
+      end 
+      if params[:callback_additional]
+        session_object[:additional] = params[:callback_additional]
+      end 
+      if params[:callback_format]
+        session_object[:format] = params[:callback_format]
+      end 
+      session[:callback]=session_object
+    end
+  end
+
   def find_workflows_rss
     # Only carry out if request is for RSS
     if params[:format] and params[:format].downcase == 'rss'
@@ -694,7 +720,7 @@
                                 :id => @workflow.id, 
                                 :version => @viewing_version_number.to_s
         
-        @named_download_url = url_for @workflow.named_download_url + "address@hidden" 
+        @named_download_url = url_for @workflow.named_download_url(@viewing_version_number) + "address@hidden" 
                                       
         @launch_url = "/workflows/address@hidden/address@hidden"
 
@@ -895,8 +921,8 @@
           # Set the internal unique name for this particular workflow (or workflow_version).
           workflow_to_set.set_unique_name
           
-          workflow_to_set.image = processor_instance.get_preview_image if processor_class.can_generate_preview_image?
-          workflow_to_set.svg   = processor_instance.get_preview_svg   if processor_class.can_generate_preview_svg?
+          workflow_to_set.image = processor_instance.get_preview_image.read if processor_class.can_generate_preview_image?
+          workflow_to_set.svg   = processor_instance.get_preview_svg.read   if processor_class.can_generate_preview_svg?
         rescue Exception => ex
           worked = false
           err_msg = "ERROR: some processing failed in workflow processor '#{processor_class.to_s}'.\nEXCEPTION: #{ex}"
@@ -948,8 +974,11 @@
     
     # Preview image
     # TODO: kept getting permission denied errors from the file_column and rmagick code, so disable for windows, for now.
+    #
+    # The dependency on file_column has been removed, but this code remains
+    # disabled on Windows until it is confirmed as working.
     unless RUBY_PLATFORM =~ /mswin32/
-      workflow_to_set.image = params[:workflow][:preview]
+      workflow_to_set.image = params[:workflow][:preview] unless params[:workflow][:preview].empty?
     end
     
     # Set the internal unique name for this particular workflow (or workflow_version).

Modified: branches/topics/app/helpers/application_helper.rb (2680 => 2681)


--- branches/topics/app/helpers/application_helper.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/helpers/application_helper.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -349,6 +349,8 @@
       return nil unless network
       
       return title(network)
+    elsif contributortype.to_s == "FederationSource"
+      link_to "The BioCatalogue", "http://www.biocatalogue.org"
     else
       return nil
     end
@@ -365,6 +367,8 @@
       return nil unless network
       
       return h(network.title)
+    elsif contributortype.to_s == "FederationSource"
+      "The BioCatalogue"
     else
       return nil
     end
@@ -424,6 +428,13 @@
       else
         return nil
       end
+    when "Service"
+      if s = Service.find(:first, :conditions => ["id = ?", contributableid])
+        name = h(s.name)
+        return link ? link_to(name, service_url(s)) : name
+      else
+        return nil
+      end
     end
   end
   
@@ -774,6 +785,8 @@
       return "famfamfam_silk/award_star_add.png"
     when "remove_group_admin"
       return "famfamfam_silk/award_star_delete.png"
+    when "service"
+      return "biocat_icon.png"
     else
       return Conf.label_icons[method.to_s] if Conf.label_icons[method.to_s]
     end
@@ -1557,4 +1570,22 @@
     return "Your OpenID URL is: #{user.openid_url}" if user.openid_url
   end
 
+  def callback_url(item)
+    item_url = nil
+    if session && session[:callback]:
+      case session[:callback][:format]
+      when 'uri'
+        item_url = rest_resource_uri(item)
+      when 'xml'
+        item_url = rest_access_uri(item)
+      else
+        return nil
+      end
+    end
+    if item_url
+      return session[:callback][:url]+URI.escape(item_url,'?!#&/')
+    else
+      return nil
+    end
+  end
 end

Modified: branches/topics/app/models/blob.rb (2680 => 2681)


--- branches/topics/app/models/blob.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/models/blob.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -42,6 +42,12 @@
 
   validates_presence_of :title
 
+  validates_each :content_blob do |record, attr, value|
+    if value.data.size > Conf.max_upload_size
+      record.errors.add(:file, "is too big.  Maximum size is #{Conf.max_upload_size} bytes.")
+    end
+  end
+
   format_attribute :body
 
   def type

Modified: branches/topics/app/models/client_application.rb (2680 => 2681)


--- branches/topics/app/models/client_application.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/models/client_application.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -1,7 +1,7 @@
 require 'oauth'
 class ClientApplication < ActiveRecord::Base
   belongs_to :user
-  has_many :tokens,:class_name=>"OauthToken"
+  has_many :tokens,:class_name=>"OauthToken", :dependent => :destroy
   has_many :permissions,
            :class_name => "KeyPermission",
            :order => "key_permissions.for",

Copied: branches/topics/app/models/federation_source.rb (from rev 2680, trunk/app/models/federation_source.rb) (0 => 2681)


--- branches/topics/app/models/federation_source.rb	                        (rev 0)
+++ branches/topics/app/models/federation_source.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -0,0 +1,14 @@
+# myExperiment: app/models/federation_source.rb
+#
+# Copyright (c) 2007 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+require 'lib/acts_as_site_entity'
+require 'lib/acts_as_contributor'
+
+class FederationSource < ActiveRecord::Base
+  acts_as_site_entity
+  acts_as_contributor
+  acts_as_structured_data
+end
+

Copied: branches/topics/app/models/ontology.rb (from rev 2680, trunk/app/models/ontology.rb) (0 => 2681)


--- branches/topics/app/models/ontology.rb	                        (rev 0)
+++ branches/topics/app/models/ontology.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -0,0 +1,15 @@
+# myExperiment: app/models/ontology.rb
+#
+# Copyright (c) 2011 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class Ontology < ActiveRecord::Base
+
+  acts_as_structured_data
+
+  format_attribute(:description)
+
+  validates_presence_of(:uri, :title, :prefix)
+
+end
+

Modified: branches/topics/app/models/pack.rb (2680 => 2681)


--- branches/topics/app/models/pack.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/models/pack.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -45,7 +45,7 @@
            :dependent => :destroy
   
   def items_count
-    return contributable_entries_count + remote_entries_count
+    return contributable_entries.count + remote_entries.count
   end
   
   # returns packs that have largest total number of items

Modified: branches/topics/app/models/picture.rb (2680 => 2681)


--- branches/topics/app/models/picture.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/models/picture.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -3,8 +3,8 @@
 # Copyright (c) 2007 University of Manchester and the University of Southampton.
 # See license.txt for details.
 
-#class Picture < ActiveRecord::Base
-class Picture < FlexImage::Model
+class Picture < ActiveRecord::Base
+
   validates_associated :owner
   
   validates_presence_of :user_id, :data
@@ -32,12 +32,4 @@
   def selected?
     owner.profile.avatar? and owner.profile.picture.id.to_i == id.to_i
   end
-  
-  #file_column :data, :magick => {
-  #  :versions => {
-  #    :small    => { :size => "50x50!" }, 
-  #    :medium   => { :size => "100x100!" },
-  #    :large => { :size => "200x200!" }
-  #  }
-  #}
 end

Copied: branches/topics/app/models/predicate.rb (from rev 2680, trunk/app/models/predicate.rb) (0 => 2681)


--- branches/topics/app/models/predicate.rb	                        (rev 0)
+++ branches/topics/app/models/predicate.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -0,0 +1,15 @@
+# myExperiment: app/models/predicate.rb
+#
+# Copyright (c) 2011 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class Predicate < ActiveRecord::Base
+
+  acts_as_structured_data
+
+  format_attribute(:description)
+
+  validates_presence_of(:title)
+
+end
+

Copied: branches/topics/app/models/preview.rb (from rev 2680, trunk/app/models/preview.rb) (0 => 2681)


--- branches/topics/app/models/preview.rb	                        (rev 0)
+++ branches/topics/app/models/preview.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -0,0 +1,23 @@
+# myExperiment: app/models/preview.rb
+#
+# Copyright (c) 2011 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class Preview < ActiveRecord::Base
+
+  PREFIX = "tmp/previews"
+
+  acts_as_structured_data
+
+  # :dependent => :destroy is not supported in belongs_to in rails 1.2.6
+  after_destroy { |p| p.content_blob.destroy }
+
+  def file_name(type)
+    "#{PREFIX}/#{id}/#{type}"
+  end
+
+  def clear_cache
+    FileUtils.rm_rf("#{PREFIX}/#{id}")
+  end
+end
+

Modified: branches/topics/app/models/relationship.rb (2680 => 2681)


--- branches/topics/app/models/relationship.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/models/relationship.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -7,7 +7,7 @@
 
   acts_as_structured_data
 
-  validates_uniqueness_of :concept_id, :scope => [:subject_id, :objekt_id]
+  validates_uniqueness_of :predicate_id, :scope => [:subject_id, :objekt_id]
 
 end
 

Copied: branches/topics/app/models/search_result.rb (from rev 2680, trunk/app/models/search_result.rb) (0 => 2681)


--- branches/topics/app/models/search_result.rb	                        (rev 0)
+++ branches/topics/app/models/search_result.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -0,0 +1,9 @@
+# myExperiment: app/models/search_result.rb
+#
+# Copyright (c) 2011 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class SearchResult < ActiveRecord::Base
+  belongs_to(:result, :polymorphic => true)
+end
+

Copied: branches/topics/app/models/service.rb (from rev 2680, trunk/app/models/service.rb) (0 => 2681)


--- branches/topics/app/models/service.rb	                        (rev 0)
+++ branches/topics/app/models/service.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -0,0 +1,22 @@
+# myExperiment: app/models/service.rb
+#
+# Copyright (c) 2007 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+require 'lib/acts_as_site_entity'
+require 'lib/acts_as_contributable'
+
+class Service < ActiveRecord::Base
+  acts_as_site_entity
+  acts_as_contributable
+  acts_as_structured_data
+
+  acts_as_solr(:fields => [ :submitter_label, :name, :provider_label, :endpoint,
+      :wsdl, :city, :country, :description, :extra_search_terms ]) if Conf.solr_enable
+
+  def extra_search_terms
+    service_categories.map do |category| category.label end +
+    service_tags.map do |tag| tag.label end +
+    service_types.map do |types| types.label end
+  end
+end

Modified: branches/topics/app/models/workflow.rb (2680 => 2681)


--- branches/topics/app/models/workflow.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/models/workflow.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -11,6 +11,7 @@
 require 'explicit_versioning'
 require 'acts_as_reviewable'
 require 'acts_as_runnable'
+require 'lib/previews'
 
 require 'scufl/model'
 require 'scufl/parser'
@@ -50,20 +51,14 @@
   
   acts_as_reviewable
 
+  acts_as_structured_data
+
+  has_previews
+
   explicit_versioning(:version_column => "current_version", 
-                      :file_columns => ["image", "svg"], 
+                      :extra_attributes => ["image", "svg"],
                       :white_list_columns => ["body"]) do
     
-    file_column :image, :magick => {
-      :versions => {
-        :thumb    => { :size => "100x100" }, 
-        :medium   => { :size => "500x500>" },
-        :full     => { }
-      }
-    }
-  
-    file_column :svg
-    
     format_attribute :body
     
     belongs_to :content_blob
@@ -78,7 +73,9 @@
     # Update the parent contribution model buy only if this isn't the current version (because the workflow model will take care of that).
     # This is required to keep the contribution's updated_at field accurate.
     after_save { |wv| wv.workflow.contribution.save if wv.workflow.contribution && wv.version != wv.workflow.current_version }
-    
+
+    has_previews
+
     def components
       if workflow.processor_class
         workflow.processor_class.new(content_blob.data).get_components
@@ -86,9 +83,21 @@
         XML::Node.new('components')
       end
     end
+
+    def processor_class
+      if self.content_type
+          @processor_class ||= WorkflowTypesHandler.processor_class_for_type_display_name(self.content_type.title)
+      end
+    end
+
+    def display_data_format
+      klass = self.processor_class
+      @display_data_format = (klass.nil? ? self.file_ext : klass.display_data_format)
+    end
+
   end
   
-  non_versioned_columns.push("license_id", "tag_list")
+  non_versioned_columns.push("license_id", "tag_list", "preview_id")
   
   acts_as_solr(:fields => [ :title, :body, :tag_list, :contributor_name, :kind, :get_all_search_terms ],
                :boost => "rank",
@@ -106,16 +115,6 @@
   validates_presence_of :content_blob
   validates_presence_of :content_type
 
-  file_column :image, :magick => {
-    :versions => {
-      :thumb    => { :size => "100x100>" }, 
-      :medium   => { :size => "500x500>" },
-      :full     => { },
-    }
-  }
-  
-  file_column :svg
-  
   def tag_list_comma
     list = ''
     tags.each do |t|
@@ -176,7 +175,7 @@
     metadata
   end
 
-  # This method is called before save and attempts to pull out metadata if it
+  # This method is called before validation and attempts to pull out metadata if it
   # hasn't been set
 
   def apply_extracted_metadata
@@ -212,6 +211,11 @@
     @display_data_format = (klass.nil? ? self.file_ext : klass.display_data_format)
   end
   
+  def get_workflow_processor(version = current_version)
+    return nil unless (workflow_version = self.find_version(version))
+    return (self.processor_class.nil? ? nil : self.processor_class.new(workflow_version.content_blob.data))
+  end
+
   def get_workflow_model_object(version)
     return nil unless (workflow_version = self.find_version(version))
     return (self.processor_class.nil? ? nil : self.processor_class.new(workflow_version.content_blob.data).get_workflow_model_object)
@@ -236,12 +240,12 @@
       return "#{unique_name}.#{file_ext}"
     else
       return nil unless (workflow_version = self.find_version(version))
-      return "#{workflow_version.unique_name}.#{file_ext}"
+      return "#{workflow_version.unique_name}.#{workflow_version.file_ext}"
     end
   end
   
-  def named_download_url
-    "#{Conf.base_uri}/workflows/#{id}/download/#{filename}"
+  def named_download_url(version = nil)
+    "#{Conf.base_uri}/workflows/#{id}/download/#{filename(version)}"
   end
 
   def get_all_search_terms
@@ -326,6 +330,10 @@
       end
     end
   end
+  
+  def unique_wsdls
+    WorkflowProcessor.find(:all, :conditions => ['workflow_id = ? AND wsdl IS NOT NULL', 16]).map do |wp| wp.wsdl end.uniq
+  end
 
   def workflows_with_similar_services
 

Modified: branches/topics/app/views/blobs/_table.rhtml (2680 => 2681)


--- branches/topics/app/views/blobs/_table.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/blobs/_table.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -79,8 +79,8 @@
 						<p style="font-size:85%;"><b>File type: </b><%= h blob.content_type.title %></p>
 						
 						<p style="font-size: 85%;">
-							<a href="" file_path(blob) + '#ratings' -%>"><b>Rating: </b><%= number_with_precision(blob.rating, 1) %> / 5 (<%= pluralize blob.ratings_count, 'rating' %>)</a> |
-							<a href="" file_path(blob) + '#comments' -%>"><b>Comments: </b><%= blob.comments_count %></a> |
+							<a href="" file_path(blob) + '#ratings' -%>"><b>Rating: </b><%= number_with_precision(blob.rating, 1) %> / 5 (<%= pluralize blob.ratings.count, 'rating' %>)</a> |
+							<a href="" file_path(blob) + '#comments' -%>"><b>Comments: </b><%= blob.comments.count %></a> |
 							<b>Viewed:</b> <%=pluralize blob.contribution.site_viewings_count, "time" %> |
 				      <b>Downloaded:</b> <%=pluralize blob.contribution.site_downloads_count, "time" %>
 						</p>

Modified: branches/topics/app/views/comments/_comment.rhtml (2680 => 2681)


--- branches/topics/app/views/comments/_comment.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/comments/_comment.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -16,6 +16,7 @@
 	</tr>
 	<tr>
 		<td style="text-align: right; padding-right: 1em;">
+      <%= render(:partial => 'contributions/user_report', :locals => { :subject => comment, :user => current_user }) -%>
       <% if Authorization.check(:action ="" 'destroy', :object => comment, :user => current_user) %>
 				<small>
 					[

Modified: branches/topics/app/views/content/_index.rhtml (2680 => 2681)


--- branches/topics/app/views/content/_index.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/content/_index.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -1,48 +1,52 @@
 <div class="pivot">
   <div class="left">
-    <div class="category">Search filter terms</div>
-    <div class="search_filters">
-      <form action="" url_for(request.query_parameters) -%>" method="GET">
-        <div class="filter_search_box">
-          <input class="query" name="filter_query" value="<%= params[:filter_query] -%>" />
-          <% @pivot[:filter_query_url].each do |key, value| %>
-            <input name="<%= key -%>" type="hidden" value="<%= value.gsub('"', '&quot;') -%>" />
-          <% end %>
+    <% if @pivot[:filters].length > 0 %>
+      <div class="category">Search filter terms</div>
+      <div class="search_filters">
+        <form action="" url_for(request.query_parameters) -%>" method="GET">
+          <div class="filter_search_box">
+            <input class="query" name="filter_query" value="<%= params[:filter_query] -%>" />
+            <% @pivot[:filter_query_url].each do |key, value| %>
+              <input name="<%= key -%>" type="hidden" value="<%= value.gsub('"', '&quot;') -%>" />
+            <% end %>
+            <% if @pivot[:cancel_filter_query_url] %>
+              <%= link_to('<img src="" />',
+                  @pivot[:cancel_filter_query_url]) -%>
+            <% else %>
+              <input class="submit" type="image" src="" name="submit" />
+            <% end %>
+          </div>
+        </form>
+      </div>
+      <div class="filters">
+        <% @pivot[:filters].each do |filter| %>
+          <% query_name = "#{filter[:query_option]}_query" %>
           <% if @pivot[:cancel_filter_query_url] %>
-            <%= link_to('<img src="" />',
-                @pivot[:cancel_filter_query_url]) -%>
+            <div class="category"><%= filter[:title].capitalize -%> results</div>
           <% else %>
-            <input class="submit" type="image" src="" name="submit" />
+            <div class="category">Filter by <%= filter[:title] -%></div>
           <% end %>
-        </div>
-      </form>
-    </div>
-    <div class="filters">
-      <% @pivot[:filters].each do |filter| %>
-        <% query_name = "#{filter[:query_option]}_query" %>
-        <% if @pivot[:cancel_filter_query_url] %>
-          <div class="category"><%= filter[:title].capitalize -%> results</div>
-        <% else %>
-          <div class="category">Filter by <%= filter[:title] -%></div>
+          <div id="<%= query_name -%>" style="display: <%= @pivot[:cancel_filter_query_url] ? "block" : "none" -%>">
+          </div>
+          <div class="filter">
+            <div class="options">
+              <% filter[:objects].each do |object| %>
+                <div title='<%= h(object[:plain_label]) -%>'<%= object[:selected] ? ' class="selected"' : '' -%>>
+                  <input class='checkbox' type='checkbox'  <% if object[:selected] %> checked='checked' <% end %> />
+                  <%= link_to("<div class='count'>#{object[:count]}</div> <div class='label'><span class='truncate'>#{object[:label]}</span></div>", object[:label_uri]) -%>
+                </div>
+              <% end %>
+            </div>
+          </div>
         <% end %>
-        <div id="<%= query_name -%>" style="display: <%= @pivot[:cancel_filter_query_url] ? "block" : "none" -%>">
+      </div>
+      <% if @pivot[:cancel_filter_query_url] && @pivot[:filters].empty? %>
+        <div class="no-filter-query-results">
+          Your search did not match any filter terms.
         </div>
-        <div class="filter">
-          <div class="options">
-            <% filter[:objects].each do |object| %>
-              <div title='<%= h(object[:plain_label]) -%>'<%= object[:selected] ? ' class="selected"' : '' -%>>
-                <input class='checkbox' type='checkbox'  <% if object[:selected] %> checked='checked' <% end %> />
-                <%= link_to("<div class='count'>#{object[:count]}</div> <div class='label'><span class='truncate'>#{object[:label]}</span></div>", object[:label_uri]) -%>
-              </div>
-            <% end %>
-          </div>
-        </div>
       <% end %>
-    </div>
-    <% if @pivot[:cancel_filter_query_url] && @pivot[:filters].empty? %>
-      <div class="no-filter-query-results">
-        Your search did not match any filter terms.
-      </div>
+    <% else %>
+      <div class="category">No search filters available.</div>
     <% end %>
   </div>
   <div class="main">
@@ -73,7 +77,7 @@
             <% end %>
             <input class="submit" type="submit" value="Search"></input>
           </div>
-          <% if params[:query] %>
+          <% if params[:query] && controller.class != SearchController %>
             <div class="remove_search_query">
               <%= link_to("Remove search query", url_for(request.query_parameters.merge({ "query", nil }))) -%>
             </div>
@@ -98,7 +102,10 @@
       </div>
     <% else %>
       <div class="results">
-        <%= render :partial => "contributions/list", :locals => { :collection => @pivot[:results], :table => true } %>
+        <% @pivot[:results].each do |ob| %>
+          <% thing = ob.class == SearchResult ? ob.result : ob.contributable -%>
+          <%= render :partial => "#{thing.class.name.pluralize.downcase}/table", :locals => { :collection => [thing] } -%>
+        <% end %>
       </div>
     <% end %>
     <div>

Modified: branches/topics/app/views/content_types/index.rhtml (2680 => 2681)


--- branches/topics/app/views/content_types/index.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/content_types/index.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -15,6 +15,7 @@
       <thead>
         <tr>
           <td>Title</td>
+          <td>Count</td>
           <td>Category</td>
         </tr>
       </thead>
@@ -22,6 +23,7 @@
         <% @content_types.each do |ct| %>
           <tr>
             <td><%= link_to(h(ct.title), content_type_path(ct)) %></td>
+            <td style="text-align: right"><%= Contribution.count(:conditions => ['content_type_id = ?', ct.id]) -%></td>
             <td><%= visible_name(ct.category) %></td>
         <% end %>
       </tbody>

Modified: branches/topics/app/views/content_types/show.rhtml (2680 => 2681)


--- branches/topics/app/views/content_types/show.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/content_types/show.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -1,7 +1,8 @@
 <% t "#{h @content_type.title}" -%>
 
 <ul class="sectionIcons">
-  <li><%= icon('workflow', content_types_path, nil, nil, 'All Types')%></li>
+  <li><%= icon('workflow', content_types_path, nil, nil, 'Show all types')%></li>
+  <li><%= icon('workflow', "/address@hidden", nil, nil, 'Browse content')%></li>
   <% if Authorization.check(:action ="" 'edit', :object => @content_type, :user => current_user) %>
 		<li><%= icon('manage', edit_content_type_path(@content_type), nil, nil, 'Manage Content Type Entry')%></li>
 	<% end -%>

Modified: branches/topics/app/views/contributions/_list.rhtml (2680 => 2681)


--- branches/topics/app/views/contributions/_list.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/contributions/_list.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -10,9 +10,9 @@
 <% end %>
 
 <% if table %>
-	<%= render :partial => "#{klass.pluralize.downcase}/table", :locals => { :collection => contributables } %>
+	<%= render :partial => "#{klass.pluralize.underscore}/table", :locals => { :collection => contributables } %>
 <% else %>
-	<%= render :partial => "#{klass.pluralize.downcase}/#{klass.downcase}", :collection => contributables, :spacer_template => "contributions/list_spacer" %>
+	<%= render :partial => "#{klass.pluralize.underscore}/#{klass.downcase}", :collection => contributables, :spacer_template => "contributions/list_spacer" %>
 <% end %>
 
-<% end %>
\ No newline at end of file
+<% end %>

Modified: branches/topics/app/views/contributions/_ratings_box.rhtml (2680 => 2681)


--- branches/topics/app/views/contributions/_ratings_box.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/contributions/_ratings_box.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -1,7 +1,7 @@
 <div class="contribution_section_box">
 	<p class="heading">
 		<%= info_icon_with_tooltip("How does this #{visible_name contributable} rate overall?") %>
-		Ratings <font class="count_text">(<%= contributable.ratings_count -%>)</font>
+		Ratings <font class="count_text">(<%= contributable.ratings.count -%>)</font>
 	  <a name="ratings"></a>
 	</p>
 	
@@ -19,4 +19,4 @@
 			</div>
 		</div>
 	<% end %>
-</div>
\ No newline at end of file
+</div>

Modified: branches/topics/app/views/contributions/_statistics_box.rhtml (2680 => 2681)


--- branches/topics/app/views/contributions/_statistics_box.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/contributions/_statistics_box.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -30,13 +30,13 @@
 				
 				<% if favouritable? type -%>
 					<p>
-			      <a href="" pluralize contributable.bookmarks_count, "favourite" -%></a>
+			      <a href="" pluralize contributable.bookmarks.count, "favourite" -%></a>
 			    </p>
 				<% end -%>
 				
 				<% if rateable? type -%>
 					<p>
-			      <a href="" pluralize contributable.ratings_count, "rating" -%></a>
+			      <a href="" pluralize contributable.ratings.count, "rating" -%></a>
 			    </p>
 				<% end -%>
 				
@@ -44,19 +44,19 @@
 					<p>
 			      <!-- for this to work properly, view for every resource that supports citations will need to have -->
 						<!-- tab system with 'tabsContainer' element + anchor called 'citations' -->
-						<a href=""  pluralize contributable.citations_count, "citation" %></a>
+						<a href=""  pluralize contributable.citations.count, "citation" %></a>
 			    </p>
 				<% end %>
 				
 				<% if reviewable? type %>
 					<p>
-			      <a href="" pluralize contributable.reviews_count, "review" -%></a>
+			      <a href="" pluralize contributable.reviews.count, "review" -%></a>
 			    </p>
 				<% end %>
 				
 				<% if commentable? type -%>
 			    <p>
-			    	<a href="" pluralize contributable.comments_count, "comment" -%></a>
+			    	<a href="" pluralize contributable.comments.count, "comment" -%></a>
 			    </p>
 				<% end -%>
 			</div>
@@ -66,4 +66,4 @@
 		
 		
 	</div>
-</div>
\ No newline at end of file
+</div>

Copied: branches/topics/app/views/contributions/_user_report.rhtml (from rev 2680, trunk/app/views/contributions/_user_report.rhtml) (0 => 2681)


--- branches/topics/app/views/contributions/_user_report.rhtml	                        (rev 0)
+++ branches/topics/app/views/contributions/_user_report.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -0,0 +1,19 @@
+<% if user != 0 %>
+  <% div_name = "report#{subject.class.name}#{subject.id}" %>
+  <% if UserReport.find_by_user_id_and_subject_type_and_subject_id(user.id, subject.class.name, subject.id) %>
+    <small>
+      [ reported ]
+    </small>
+  <% else %>
+    <small id="<%= div_name -%>">
+      [
+      <%= link_to_remote('report',
+          :update => div_name, 
+          :url ="" "/users/#{user.id}/reports?subject_type=#{subject.class.name}&subject_id=#{subject.id}",
+          :method => :post,
+          :complete => "new Effect.Highlight('#{div_name}', { duration: 1.5 }); $('comment').value = '';",
+          :confirm => "Are you sure you want to report this?" ) %>
+      ]
+    </small>
+  <% end %>
+<% end %>

Modified: branches/topics/app/views/messages/show.rhtml (2680 => 2681)


--- branches/topics/app/views/messages/show.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/messages/show.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -59,6 +59,10 @@
 			<p class="none_text">No message body</p>
 		<% end %>
 	</div>
+
+  <div style="margin: 6px; text-align: right">
+    <%= render(:partial => 'contributions/user_report', :locals => { :subject => @message, :user => current_user }) -%>
+  </div>
 </div>
 
 <%= render :partial => "contributions/alternative_formats" %>

Modified: branches/topics/app/views/networks/_table.rhtml (2680 => 2681)


--- branches/topics/app/views/networks/_table.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/networks/_table.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -25,13 +25,15 @@
 							<b>Created: </b><%=datetime network.created_at, true -%>
 						</p>
 						
-						<div class="desc" style="font-size: 85%;">
+						<div class="desc">
+							<div style="font-size: 85%;">
 							<% if network.description and network.description.length > 0 -%>
 								<% desc = truncate(strip_html(network.description), 400) -%>
 								<%= query ? highlight_all(desc, query) : desc -%>
 							<% else -%>
 								<span class="none_text">No description</span>
 							<% end -%>
+							</div>
 						</div>
 						
 						<p class="standout" style="margin-top: 0.4em;">

Modified: branches/topics/app/views/oauth/_show_permissions.rhtml (2680 => 2681)


--- branches/topics/app/views/oauth/_show_permissions.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/oauth/_show_permissions.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -4,8 +4,13 @@
    <% if permissions.length > 0 %>
      <h3><%= category.capitalize %></h3>
      <p>
-     <% for permission in permissions -%>
-       <%= permission %><br/>
+     <% by_resource={};
+        permissions.each { |el| (k,v)=el.split(" ");
+                           by_resource[v]=[] unless by_resource[v];
+                           by_resource[v].push(k) }
+     -%>
+     <% for resource in by_resource.keys.sort -%>
+       <%= resource %> - <%= by_resource[resource].join(", ")%><br/>
      <% end -%>
      </p>
    <% end -%>

Modified: branches/topics/app/views/oauth/authorize.rhtml (2680 => 2681)


--- branches/topics/app/views/oauth/authorize.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/oauth/authorize.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -11,4 +11,5 @@
 <p>
 	<%=submit_tag%>
 </p>
-<%end%>
\ No newline at end of file
+<%end%>
+<%= render :partial => "show_permissions" -%>

Modified: branches/topics/app/views/packs/_table.rhtml (2680 => 2681)


--- branches/topics/app/views/packs/_table.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/packs/_table.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -46,7 +46,7 @@
 						</p>
 						
 						<p style="font-size: 85%;">
-							<a href="" pack_path(pack) + '#comments' -%>"><b>Comments: </b><%= pack.comments_count %></a> |
+							<a href="" pack_path(pack) + '#comments' -%>"><b>Comments: </b><%= pack.comments.count %></a> |
 							<b>Viewed:</b> <%=pluralize pack.contribution.site_viewings_count, "time" %> |
 				      <b>Downloaded:</b> <%=pluralize pack.contribution.site_downloads_count, "time" %>
 						</p>

Modified: branches/topics/app/views/packs/show.rhtml (2680 => 2681)


--- branches/topics/app/views/packs/show.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/packs/show.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -88,7 +88,7 @@
 				Relationships <span class="count_text">(<%= @pack.relationships.length -%>)</span>
 			</h4>
 
-			<%= render :partial => "relationships/relationships", :locals => { :relationships => @pack.relationships } -%>
+			<%= render :partial => "relationships/relationships", :locals => { :context => @pack, :show_delete => true } -%>
 			
       <% if @authorised_to_edit %>
         <br />

Modified: branches/topics/app/views/pictures/index.rhtml (2680 => 2681)


--- branches/topics/app/views/pictures/index.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/pictures/index.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -17,6 +17,7 @@
   
 <% odd_row = false -%>
 <% for picture in @pictures %>
+<% if Authorization.is_authorized?("view", nil, picture, current_user) %>
   <tr class="<%= (odd_row = !odd_row) ? "odd_row" : "even_row" %>">
     <td width="150">
       <% if picture.selected? %> 
@@ -45,6 +46,7 @@
     </td>
   </tr>
 <% end %>
+<% end %>
 </table>
 
 <% else %>

Modified: branches/topics/app/views/relationships/_breadcrumbs.rhtml (2680 => 2681)


--- branches/topics/app/views/relationships/_breadcrumbs.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/relationships/_breadcrumbs.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -0,0 +1,14 @@
+<li><%= link_to 'Packs', packs_path %></li>
+
+<% if ["edit_relationships"].include? controller.action_name.to_s %>
+  <li><b>&#187;</b></li>
+  
+  <% case controller.action_name.to_s; when "edit_relationships" %>
+		<li><%= link_to "#{h(@context.title)}", pack_path(@context) %></li>
+    <li><b>&#187;</b></li>
+    <li>Edit Relationships</li>
+  <% else %>
+    <!-- no breadcrumb -->
+  <% end %>
+<% end %>
+

Modified: branches/topics/app/views/relationships/_relationships.rhtml (2680 => 2681)


--- branches/topics/app/views/relationships/_relationships.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/relationships/_relationships.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -1,23 +1,33 @@
+<% can_edit = Authorization.check(:action ="" 'edit', :object => context, :user => current_user) %>
+<% relationships = context.relationships %>
+
 <% if relationships.empty? %>
 
-  <p><i>There are no relationships in this pack.</i></p>
+  <p><i>There are no relationships.</i></p>
 
 <% else %>
 
-  <ol>
+  <ol class="relationship_sentences">
     <% relationships.each do |relationship| %>
       <li>
         <%= pack_entry_link(relationship.subject) -%>
-        <%=h relationship.concept.preferred_label.text.underscore.humanize.downcase -%>
-        <%= pack_entry_link(relationship.objekt) -%>
 
-        <%= link_to_remote( "delete_relationship",
-            :update => "relationshipsElement", 
-            :url ="" pack_relationship_path(relationship.pack, relationship.id),
-            :method => :delete,
-            :complete => "new Effect.Highlight('relationshipsElement', { duration: 1.5 });",
-            :confirm => "Are you sure you want to delete this relationship?" ) %>
+        <% if relationship.predicate.phrase %>
+          <%=h relationship.predicate.phrase -%>
+        <% else %>
+          <%=h relationship.predicate.preferred_label.text.underscore.humanize.downcase -%>
+        <% end %>
 
+        <%= pack_entry_link(relationship.objekt) -%>.
+
+        <% if can_edit && defined?(show_delete) && show_delete %>
+          <%= link_to_remote("<img src='' />",
+              :update => "relationshipsElement", 
+              :url ="" pack_relationship_path(relationship.context, relationship.id),
+              :method => :delete,
+              :complete => "new Effect.Highlight('relationshipsElement', { duration: 1.5 });",
+              :confirm => "Are you sure you want to delete this relationship?" ) %>
+        <% end %>
       </li>
     <% end %>
 </ol>

Modified: branches/topics/app/views/relationships/edit_relationships.rhtml (2680 => 2681)


--- branches/topics/app/views/relationships/edit_relationships.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/relationships/edit_relationships.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -8,33 +8,38 @@
 
 <h2>Add new relationship</h2>
 
-<% if @pack_entry_select_options.length < 2 %>
+<% if @select_options.length < 2 %>
 
-  <p><i>There must be at least two entries in a pack before you can add relationships.</i></p>
+  <p><i>There must be at least two entries before you can add relationships.</i></p>
 
 <% else %>
 
-  <div>
+  <% form_tag("#{rest_resource_uri(@context)}/relationships") do -%>
 
-    <% form_tag("#{rest_resource_uri(@context)}/relationships") do -%>
+    <div class="edit_relationships">
+      <%= select_tag("subject", options_for_select(@select_options)) -%>
 
-      <%= select_tag("subject", options_for_select(@pack_entry_select_options)) -%>
+      <%= select_tag("predicate", options_for_select(@predicates.map do |p| [p.phrase, "#{p.ontology.prefix}:#{p.title}"] end)) -%>
 
-      <%= select_tag("predicate", options_for_select(@concepts.map do |c| "#{c.vocabulary.prefix}:#{c.preferred_labels.first.text}" end)) -%>
-
-      <%= select_tag("objekt", options_for_select(@pack_entry_select_options)) -%>
+      <%= select_tag("objekt", options_for_select(@select_options)) -%>
      
       <input type="submit" value="Add relationship"/>
 
-    <% end %>
+    </div>
 
-  </div>
+  <% end %>
 
 <% end %>
 
 <h2>Relationships</h2>
 
 <div id="relationshipsElement">
-  <%= render(:partial => "relationships", :locals => { :relationships => @relationships }) -%>
+  <%= render(:partial => "relationships", :locals => { :context => @context, :show_delete => true }) -%>
 </div>
 
+<p style="text-align: center">
+  <form action="" pack_path(@context) -%>" method="get">
+    <input type="submit" value="Back" />
+  </form>
+</p>
+

Modified: branches/topics/app/views/search/show.rhtml (2680 => 2681)


--- branches/topics/app/views/search/show.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/search/show.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -1,41 +1,16 @@
 <% t "Results" -%>
 
-<%= render :partial => 'extra_search_help' %>
-
 <h1>Search results for "<%= h @query -%>"</h1>
 
 <% if @total_count == 0 %>
 
   <p class="none_text">No search results.</p>
   
+  <%= render :partial => 'extra_search_help' %>
+
 <% else %>
 
-  <%= view_privileges_notice %>
-  <br/>
+  <%= render :partial => "content/index" -%>
 
-  <div id="tabsContainer" class="tabsContainer"></div>
-
-  <% @infos.each do |info| %>
-
-    <% name  = visible_name(info[:model]).pluralize
-       count = info[:results].length
-       total = info[:total_count] -%>
-
-    <div class="tabContainer">
-      <div class="tabTitle"><%= name %> (<%= count -%><% if count < total %> of <%= total -%><% end %>)</div>
-      <div class="tabContent">
-
-        <% if count < total %>
-          <p class="box_standout" style="font-size: 108%; margin-bottom: 1em; margin-top: 0.6em;"><b>
-            There are more results than shown here.  <a href="" search_path + "?type=#{info[:search_type]}&query=" + params[:query] -%>">See all <%= name %> results</a> for this query.
-          </b></p>
-        <% end %>
-
-        <%= render :partial => "#{info[:model].to_s.underscore.pluralize}/table", :locals => { :collection => info[:results], :query => @query } %>
-      </div>
-    </div>
-  <% end %>
-
 <% end %>
 
-<br />

Modified: branches/topics/app/views/topics/index.rhtml (2680 => 2681)


--- branches/topics/app/views/topics/index.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/topics/index.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -1,6 +1,6 @@
 <h1><%= feed_icon_tag "Latest Topics", formatted_workflows_path(:rss), "margin-right: 0.3em;" -%> Topics</h1>
 
-<div id="topic container">
+<div id="topic_container">
 	<% @curr_run.topics.each do |topic| -%>
            <% topicName = (if topic.name.blank? then "Topic #{topic.id}" else "#{topic.name}" end) -%>
 	   <h2>

Copied: branches/topics/app/views/users/_listing.rhtml (from rev 2680, trunk/app/views/users/_listing.rhtml) (0 => 2681)


--- branches/topics/app/views/users/_listing.rhtml	                        (rev 0)
+++ branches/topics/app/views/users/_listing.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -0,0 +1,93 @@
+<% cache(:controller => 'users_cache', :action ="" 'listing', :id => user.id) do -%>
+  <td style="width: 100px"><div style="text-align: center; font-weight: bold">Member</div><br /><br /><center><%= contributor(user.id, 'User', true, 60) %></center></td>
+  <td class="mid" style="text-align: left;">
+
+    <p style="margin-top:0; padding-top:0; font-weight:bold; font-size: 108%;">
+      <%= icon "user", nil, nil, nil, '' %>
+      <%= name user %>
+      <%= friend_badge(user) %>
+      <%= admin_badge(user) %>
+    </p>
+          
+    <% unless user.created_at.blank? %>
+      <p style="font-size: 85%;">
+        <b>Joined:</b>
+        <%= datetime user.created_at %>
+      </p>
+    <% end %>
+          
+    <div class="desc" style="font-size: 85%;">
+      <% unless user.profile.body.blank? %>
+        <% desc = truncate(strip_html(user.profile.body), 180) %>
+        <%= query ? highlight_all(desc, query) : desc %>
+      <% else -%>
+        <span class="none_text">No description</span>  
+      <% end %>
+    </div>
+          
+    <% unless user.last_seen_at.blank? %>
+      <p style="font-size: 85%;">
+        <b>Last active:</b>
+        <%= datetime user.last_seen_at %>
+      </p>
+    <% end %>
+          
+    <% if user.profile %>
+          
+      <p style="font-size: 85%;">
+        <% unless user.profile.website.blank? %>
+          <b>Website:</b>
+          <%= link_to h(user.profile.website), h(user.profile.website), :popup => true %>
+          |
+        <% end %>
+              
+        <% unless user.profile.email.blank? %>
+          <b>Email (public):</b>
+          <%= mail_to user.profile.email, nil, {  :encode => "hex", :replace_at => " [at] " } %>
+        <% end %>
+      </p>
+              
+      <p style="font-size: 85%;">
+        <% unless user.profile.field_or_industry.blank? %>
+          <b>Field/Industry:</b>
+          <%= h user.profile.field_or_industry %>
+          |
+        <% end %>
+              
+        <% unless user.profile.occupation_or_roles.blank? %>
+          <b>Occupation/Role(s):</b>
+          <%= h user.profile.occupation_or_roles %>
+        <% end %>
+      </p>
+
+    <% end %>
+  </td>
+<% end %>
+
+<td class="actions"  style="width: 90px;">
+  <%= icon "show", user_path(user.id), nil, nil, "View" %>
+  <% if mine? user %>
+    <%= icon "edit", edit_user_path(user), nil, nil, "Edit" %>
+  <% else %>
+    <!-- check if the profile that we are viewing now is a friend of current user -> stored for better performance -->
+    <% this_user_is_friend_of_current_user = (current_user != 0) && current_user.friend?(user.id) %>
+    <% unless !logged_in? || this_user_is_friend_of_current_user || current_user.friendship_pending?(user.id) %>
+      <%= icon "friendship", new_user_friendship_url(:user_id => user.id), nil, nil, "Request Friendship" %>
+    <% end %>
+
+    <%= icon "message", new_message_path(:user_id => user.id), nil, nil, "Message" %>
+
+    <% if logged_in? && this_user_is_friend_of_current_user %>
+      <% master_id, friendship_obj = current_user.friendship_from_self_id_and_friends_id(user.id) %>
+      <%= icon "friend_delete", user_friendship_path(master_id, friendship_obj) + "?return_to=" + currentusers_things_url('friends'), nil, {:confirm => "Are you sure you want to remove this user from your friend list?", :method => :delete}, "Cancel Friendship" %>
+    <% end %>
+  <% end %>
+
+  <% if Authorization.check(:action ="" 'destroy', :object => user, :user => current_user) %>
+    <%= icon "destroy", user_path(user) + "?return_to=" + CGI::escape(request.request_uri), nil, {
+      :confirm => "Are you sure you want to remove this user?", :method => :delete},
+      "Delete User" %>
+  <% end %>
+
+</td>
+

Modified: branches/topics/app/views/users/_table.rhtml (2680 => 2681)


--- branches/topics/app/views/users/_table.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/users/_table.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -1,96 +1,15 @@
 <% query ||= false -%>
 
 <% unless collection.empty? %>
-
-	<table class="alt_table">
-		<% odd_row = false -%> 
-		<% for user in collection %>
-			<% if user.activated? %>
-			  	<tr class="<%= (odd_row = !odd_row) ? "odd_row" : "even_row" %>">
-				<% cache(:controller => 'users_cache', :action ="" 'listing', :id => user.id) do -%>
-				    <td width="100px"><%= avatar user, 60 %></td>
-				    <td class="mid" style="text-align: left;">
-				    	<p style="margin-top:0; padding-top:0; font-weight:bold; font-size: 108%;">
-								<%= if user.profile then flag_icon(user.profile.location_country, user.profile.location) end %>
-								<%= name user %>
-								<%= friend_badge(user) %>
-								<%= admin_badge(user) %>
-							</p>
-						
-						<% unless user.created_at.blank? %>
-							<p style="font-size: 85%;">
-								<b>Joined:</b>
-								<%= datetime user.created_at %>
-							</p>
-						<% end %>
-						
-						<div class="desc" style="font-size: 85%;">
-							<% unless user.profile.body.blank? %>
-					  		<% desc = truncate(strip_html(user.profile.body), 180) %>
-								<%= query ? highlight_all(desc, query) : desc %>
-							<% else -%>
-								<span class="none_text">No description</span>	
-							<% end %>
-						</div>
-						
-						<% unless user.last_seen_at.blank? %>
-							<p style="font-size: 85%;">
-								<b>Last active:</b>
-								<%= datetime user.last_seen_at %>
-							</p>
-						<% end %>
-						
-						<% if user.profile %>
-						
-							<p style="font-size: 85%;">
-								<% unless user.profile.website.blank? %>
-									<b>Website:</b>
-									<%= link_to h(user.profile.website), h(user.profile.website), :popup => true %>
-									|
-								<% end %>
-								
-								<% unless user.profile.email.blank? %>
-									<b>Email (public):</b>
-						    	<%= mail_to user.profile.email, nil, {  :encode => "hex", :replace_at => " [at] " } %>
-								<% end %>
-							</p>
-								
-							<p style="font-size: 85%;">
-								<% unless user.profile.field_or_industry.blank? %>
-							    <b>Field/Industry:</b>
-									<%= h user.profile.field_or_industry %>
-									|
-							  <% end %>
-								
-								<% unless user.profile.occupation_or_roles.blank? %>
-							    <b>Occupation/Role(s):</b>
-									<%= h user.profile.occupation_or_roles %>
-							  <% end %>
-							</p>
-						
-						<% end %>
-					</td>
-				<% end %>
-				    <td class="actions"  style="width: 130px;">
-			      	<%= icon "show", user_path(user.id), nil, nil, "View Profile" %>
-			      	<% if mine? user %>
-				       	<%= icon "edit", edit_user_path(user), nil, nil, "Edit" %>
-						  <% else %>
-							  <!-- check if the profile that we are viewing now is a friend of current user -> stored for better performance -->
-			          <% this_user_is_friend_of_current_user = (current_user != 0) && current_user.friend?(user.id) %>
-								<% unless !logged_in? || this_user_is_friend_of_current_user || current_user.friendship_pending?(user.id) %>
-							  	<%= icon "friendship", new_user_friendship_url(:user_id => user.id), nil, nil, "Request Friendship" %>
-							  <% end %>
-							  <%= icon "message", new_message_path(:user_id => user.id), nil, nil, "Send Message" %>
-								<% if logged_in? && this_user_is_friend_of_current_user %>
-								  <% master_id, friendship_obj = current_user.friendship_from_self_id_and_friends_id(user.id) %>
-									<%= icon "friend_delete", user_friendship_path(master_id, friendship_obj) + "?return_to=" + currentusers_things_url('friends'), nil, {:confirm => "Are you sure you want to remove this user from your friend list?", :method => :delete}, "Cancel Friendship" %>
-								<% end %>
-			      	<% end %>
-			    	</td>
-			  	</tr>
-			<% end %>
-		<% end %>
-	</table>
-
+  <table class="alt_table">
+    <% odd_row = false -%> 
+    <% for user in collection %>
+      <% if user.activated? %>
+        <tr class="<%= (odd_row = !odd_row) ? "odd_row" : "even_row" %>">
+          <%= render :partial => "users/listing", :locals => { :user => user, :query => query } %>
+        </tr>
+      <% end %>
+    <% end %>
+  </table>
 <% end %>
+

Modified: branches/topics/app/views/users/edit.rhtml (2680 => 2681)


--- branches/topics/app/views/users/edit.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/users/edit.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -160,6 +160,12 @@
 <% end %>
 <br/>
 <br/>
+<h2>Client Applications</h2>
+
+<%= link_to "Manage", :controller => "oauth", :action ="" "index" -%> other
+websites and applications that access <%= Conf.sitename %> on your behalf
+via the <a href="" standard.
+
 <h2>Unregister</h2>
 <p>
   If you would like to unregister from <%= Conf.sitename %>, send us a message through the

Modified: branches/topics/app/views/users/index.rhtml (2680 => 2681)


--- branches/topics/app/views/users/index.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/users/index.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -6,6 +6,7 @@
 
 <div id="tabsContainer" class="tabsContainer" style="margin-top: 2.5em;"></div>
 
+<% if false %>
 <% unless (recent = User.most_recent(6)).empty? %>
   <div class="tabContainer">
   	<div class="tabTitle">Most Recent</div>
@@ -14,6 +15,7 @@
   	</div>
   </div>
 <% end %>
+<% end %>
 
 <% if false -%>
 <% unless (updated = User.last_updated(10)).empty? %>
@@ -60,4 +62,4 @@
 	    <%= render :partial => "users/table", :locals => { :collection => top_rated } %>
   	</div>
   </div>
-<% end %>
\ No newline at end of file
+<% end %>

Modified: branches/topics/app/views/users/new.rhtml (2680 => 2681)


--- branches/topics/app/views/users/new.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/users/new.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -28,6 +28,9 @@
 
   <center>
     <h2>Anti-spam verification</h2>
+  <% if true -%>
+    <%= recaptcha_tags(:public_key => Conf.recaptcha_public) if Conf.recaptcha_enable -%> 
+  <% else -%>
     <table style="margin-top: 2em;">
       <tr>
         <td>
@@ -41,6 +44,7 @@
         </td>
       </tr>
     </table>
+  <% end -%>
   </center>
       
   <br />

Modified: branches/topics/app/views/users/show.rhtml (2680 => 2681)


--- branches/topics/app/views/users/show.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/users/show.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -58,6 +58,12 @@
 				<% end %>
 			  <li><%= icon('history', userhistory_path(@user), nil, nil, 'View My History')%></li>
 	    <% end %>
+
+      <% if Authorization.check(:action ="" 'destroy', :object => @user, :user => current_user) %>
+					<li><%= icon "destroy", user_path(@user), nil, {
+            :confirm => "Are you sure you want to remove this user?", :method => :delete},
+            "Delete User" %></li>
+      <% end %>
 	</ul>
 <% end %>
 
@@ -213,13 +219,13 @@
 					
 					<p>
 			      <b>
-			      	<%= link_to(pluralize(@user.networks_owned_count, "Group") + " (admin)", url_for(:action ="" 'groups')) -%>
+			      	<%= link_to(pluralize(@user.networks_owned.count, "Group") + " (admin)", url_for(:action ="" 'groups')) -%>
 						</b> 
 			    </p>
 					
 					<p>
 			      <b>
-			      	<%= link_to(pluralize(@user.networks_count, "Group") + " (member)", url_for(:action ="" 'groups')) -%>
+			      	<%= link_to(pluralize(@user.networks.length, "Group") + " (member)", url_for(:action ="" 'groups')) -%>
 						</b> 
 			    </p>
 					
@@ -233,7 +239,7 @@
 					
 					<p>
 			      <b>
-			      	<%= link_to(pluralize(@user.bookmarks_count, "Favourite"), url_for(:action ="" 'favourites')) -%>
+			      	<%= link_to(pluralize(@user.bookmarks.count, "Favourite"), url_for(:action ="" 'favourites')) -%>
 						</b> 
 			    </p>
 				</div>	
@@ -354,7 +360,7 @@
 
 <% tabnav :user do %>
 
-  <% case @tab; when "News" %>
+  <% case (@tab||"News"); when "News" %>
 
     <%= render :partial => "layouts/news", :locals => { :collection => news(@user, true) } %>
 

Modified: branches/topics/app/views/workflows/_table.rhtml (2680 => 2681)


--- branches/topics/app/views/workflows/_table.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/workflows/_table.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -78,7 +78,7 @@
 
             <% unless workflow.image.nil? -%>
               <p style="margin: 0; border: 0; width: 101px; float: left">
-                <%= link_to image_tag(url_for_file_column(workflow, "image", "thumb"), :class => 'framed_nospace'), workflow_path(workflow) %>
+                <%= link_to image_tag(workflow_preview_path(workflow, 'thumb'), :class => 'framed_nospace'), workflow_path(workflow) %>
               </p>
 
               <% desc_style << " margin-left: 110px; width: 250px;" %>
@@ -98,11 +98,11 @@
             <div style="clear: both"></div>
 
 					  <p style="font-size: 85%;">
-							<a href="" workflow_path(workflow) + '#ratings' -%>"><b>Rating: </b><%= number_with_precision(workflow.rating, 1) %> / 5 (<%= pluralize workflow.ratings_count, 'rating' %>)</a> |
-							<a href="" workflow_path(workflow) + '#versions' -%>"><b>Versions: </b><%= workflow.versions_count %></a> |
-							<a href="" workflow_path(workflow) + '#reviews' -%>"><b>Reviews: </b><%= workflow.reviews_count %></a> |
-							<a href="" workflow_path(workflow) + '#comments' -%>"><b>Comments: </b><%= workflow.comments_count %></a> |
-							<a href="" workflow_path(workflow) + '#citations' -%>"><b>Citations: </b><%= workflow.citations_count %></a>
+							<a href="" workflow_path(workflow) + '#ratings' -%>"><b>Rating: </b><%= number_with_precision(workflow.rating, 1) %> / 5 (<%= pluralize workflow.ratings.count, 'rating' %>)</a> |
+							<a href="" workflow_path(workflow) + '#versions' -%>"><b>Versions: </b><%= workflow.versions.count %></a> |
+							<a href="" workflow_path(workflow) + '#reviews' -%>"><b>Reviews: </b><%= workflow.reviews.count %></a> |
+							<a href="" workflow_path(workflow) + '#comments' -%>"><b>Comments: </b><%= workflow.comments.count %></a> |
+							<a href="" workflow_path(workflow) + '#citations' -%>"><b>Citations: </b><%= workflow.citations.count %></a>
 					  </p>
 						
 						<p style="font-size: 85%;">
@@ -120,7 +120,12 @@
 			<% end -%>
 			    <td class="actions" style="width: 120px;">
 			      <%= icon "show", workflow_path(workflow), nil, nil, "View" %>
-				  	<% if Authorization.is_authorized?("download", nil, workflow, current_user) %><%= icon "download", download_workflow_path(workflow), nil, nil, "Download (v#{workflow.versions.count})" %><% end %>
+				  	<% if Authorization.is_authorized?("download", nil, workflow, current_user) -%>
+						<%= icon "download", download_workflow_path(workflow), nil, nil, "Download (v#{workflow.versions.count})" %>
+						<% if ( session[:callback] && (session[:callback][:types].include?(workflow.content_type_id))) -%>
+							<%= icon "download", callback_url(workflow).to_s, nil, {:rel => 'nofollow'}, session[:callback][:label] -%>
+						<% end %>
+					<% end %>
 			      <% if mine?(workflow) %><%= icon "manage", edit_workflow_path(workflow), nil, nil, "Manage" %><% end %>
 						<br/><br/>
 						

Modified: branches/topics/app/views/workflows/galaxy_tool.rhtml (2680 => 2681)


--- branches/topics/app/views/workflows/galaxy_tool.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/workflows/galaxy_tool.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -59,7 +59,7 @@
 
 <p>The URL to the test Taverna 2 server is:
 
-<div style="padding: 1em; font-family: monospace">http://taverna-server.biosemantics.org/</div>
+<div style="padding: 1em; font-family: monospace">http://test.mybiobank.org/taverna-server</div>
 </p>
 
 <h2>Further information</h2>

Modified: branches/topics/app/views/workflows/show.rhtml (2680 => 2681)


--- branches/topics/app/views/workflows/show.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/workflows/show.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -148,7 +148,7 @@
 			
 			<p>
 				<b>Type:</b>
-				<%= link_to(h(@workflow.content_type.title), content_type_path(@workflow.content_type)) %>
+				<%= link_to(h(@viewing_version.content_type.title), content_type_path(@viewing_version.content_type)) %>
 			</p>
 			
 			<br/>
@@ -164,7 +164,7 @@
 				</p>
 				<div class="contribution_preview" style="width: 100%;">
 					<center>
-						<%= link_to image_tag(url_for_file_column(@viewing_version, "image", "medium")), url_for_file_column(@viewing_version, "image"), :popup => true %>
+						<%= link_to image_tag(workflow_version_preview_path(@workflow, @viewing_version.version, 'medium')), workflow_version_preview_path(@workflow, @viewing_version.version, 'full'), :popup => true %>
 					</center>
 				</div>
 				<% if @authorised_to_edit %>
@@ -184,7 +184,7 @@
 			
 			<% unless @viewing_version.svg.nil? %>
 				<ul class="sectionIcons">
-					<li style="margin-left: 0;"><%= icon('picture', url_for_file_column(@viewing_version, "svg"), nil, nil, 'Download Scalable Diagram (SVG)') %></li>
+					<li style="margin-left: 0;"><%= icon('picture', workflow_version_preview_path(@workflow, @viewing_version.version, 'svg'), nil, nil, 'Download Scalable Diagram (SVG)') %></li>
 				</ul>
 			<% end %>
 			
@@ -222,11 +222,17 @@
           <br />
 
           <ul class="sectionIcons">
-            <li style="margin-left: 0;"><%= icon('workflow', @named_download_url, "Download Workflow file/package (for version address@hidden)", nil, "Download Workflow File/Package (address@hidden)") -%></li>
+            <li style="margin-left: 0;"><%= icon('workflow', @named_download_url, "Download Workflow file/package (for version address@hidden)", nil, "Download Workflow File/Package (address@hidden)") -%></li>
           </ul>
-
-          <% if @workflow.content_type.title == "Taverna 2" %>
+          <% if session[:callback] &&
+                session[:callback][:types].include?(@workflow.content_type_id) -%>
             <br />
+            <ul class="sectionIcons">
+              <li style="margin-left: 0;"><%= icon('workflow', callback_url(@workflow).to_s, "#{session[:callback][:label]} Workflow file/package (for version address@hidden)", {:rel => 'nofollow'}, "#{session[:callback][:label]} Workflow #{session[:callback][:additional]}") -%></li>
+            </ul>
+          <% end %>
+          <% if @viewing_version.content_type.title == "Taverna 2" %>
+            <br />
 
             <ul class="sectionIcons">
               <li style="margin-left: 0;"><%= icon('workflow', galaxy_tool_path(:id => @workflow.id, :version => @viewing_version_number.to_s), "Download Workflow file/package (for version address@hidden)", nil, "Download Workflow as a Galaxy tool") -%></li>
@@ -291,7 +297,7 @@
 <div class="contribution_right_box">
 	<div class="contribution_section_box" style= "font-size: 100%; padding: 0.7em 0.9em; font-weight: bold;">
 		<p><%= info_icon_with_tooltip("The type of workflow system that this Workflow is designed for.") %> Workflow Type</p>
-    <p><%= link_to(h(@workflow.content_type.title), content_type_path(@workflow.content_type)) %></p>
+    <p><%= link_to(h(@viewing_version.content_type.title), content_type_path(@viewing_version.content_type)) %></p>
 	</div>
 	
 	<%= render :partial => "contributions/uploader_box", :locals => { :contributable => @workflow } %>
@@ -388,6 +394,29 @@
 	<%= render :partial => "comments/comments", :locals => { :commentable => @workflow } %>
 </div>
 
+<!-- Other workflows that use a service this workflow users -->
+
+<br />
+<br />
+
+<h2>
+	<%= icon "workflow", nil, nil, { :style => "vertical-align: middle;" }, "" -%>
+	<span style="vertical-align: middle;">Other workflows that use similar services</span>
+	<span class="count_text" style="vertical-align: middle;">(<%= @contributions_with_similar_services.length %>)</span>
+</h2>
+
+<% if @contributions_with_similar_services.length > @similar_services_limit %>
+  <p><i>Only the first <%= @similar_services_limit %> workflows that use similar services are shown</i>.   <a href="" workflows_path(@wsdls_filter) -%>">View all workflows that use these services</a>.</p>
+  <br />
+<% end %>
+
+<% if @contributions_with_similar_services.length > 0 %>
+  <%= render :partial => "contributions/list", :locals => { :collection => @address@hidden - 1], :table => true } %>
+<% else %>
+  <p>There are no workflows in <%= Conf.sitename %> that use similar services to this Workflow.</p>
+<% end %>
+
+
 <%= render :partial => "contributions/alternative_formats" %>
 
 <!-- OpenURL context object -->

Modified: branches/topics/app/views/workflows/taverna2/_internals.rhtml (2680 => 2681)


--- branches/topics/app/views/workflows/taverna2/_internals.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/workflows/taverna2/_internals.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -120,7 +120,14 @@
               <tr>
                 <td><b><%= h p.name -%></b></td>
                 <td><%= h p.type -%></td>
-                <td><%= h p.description -%></td>
+                <td><%= h p.description -%>
+                  <% if p.wsdl %>
+                    <% if service = Service.find_by_wsdl(p.wsdl) %>
+                      <br /><p>See the <%= link_to('Service entry', service.uri) %>
+                      for this web service.</p>
+                    <% end %>
+                  <% end %>
+                </td>
               </tr>
             <% end %>
           </table>

Modified: branches/topics/app/views/workflows/taverna_scufl/_internals.rhtml (2680 => 2681)


--- branches/topics/app/views/workflows/taverna_scufl/_internals.rhtml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/app/views/workflows/taverna_scufl/_internals.rhtml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -48,7 +48,14 @@
 						  <tr>
 						    <td><b><%= h p.name -%></b></td>
 								<td><%= h p.type -%></td>
-						    <td><%= h p.description -%></td>
+						    <td><%= h p.description -%>
+                <% if p.wsdl %>
+                  <% if service = Service.find_by_wsdl(p.wsdl) %>
+                    <br /><p>See the <%= link_to('Service entry', service.uri) %>
+                    for this web service.</p>
+                  <% end %>
+                <% end %>
+                </td>
 						  </tr>
 						<% end %>
 					</table>

Deleted: branches/topics/backup.sh (2680 => 2681)


--- branches/topics/backup.sh	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/backup.sh	2011-08-31 15:23:15 UTC (rev 2681)
@@ -1,18 +0,0 @@
-#!/bin/bash
-
-RAILS_ROOT="/var/www/m2"
-DB="m2_production"
-DIRS="public/pictures public/workflow"
-USER="backup"
-BACKUP_DIR="/home/backup"
-
-SQL_DUMP="${BACKUP_DIR}/myexp-$(date +%Y-%m-%d).sql"
-PUB_DUMP="${BACKUP_DIR}/myexp-$(date +%Y-%m-%d).tgz"
-SQL_LINK="${BACKUP_DIR}/myexp.sql"
-PUB_LINK="${BACKUP_DIR}/myexp.tgz"
-
-/usr/bin/mysqldump ${DB} > ${SQL_DUMP}
-/bin/tar Cczf ${RAILS_ROOT} ${PUB_DUMP} ${DIRS}
-/bin/ln -sf ${SQL_DUMP} ${SQL_LINK}
-/bin/ln -sf ${PUB_DUMP} ${PUB_LINK}
-/bin/chown -h ${USER}:${USER} ${SQL_DUMP} ${PUB_DUMP} ${SQL_LINK} ${PUB_LINK}

Property changes: branches/topics/config


Added: svn:ignore

settings.yml captcha.yml

Modified: branches/topics/config/base_schema.xml (2680 => 2681)


--- branches/topics/config/base_schema.xml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/config/base_schema.xml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -38,7 +38,7 @@
     <column type="integer"  name="user_id"/>
     <column type="datetime" name="created_at"/>
     <column type="string"   name="user_agent"/>
-    <column type="boolean"  name="accessed_from_site" default="0"/>
+    <column type="boolean"  name="accessed_from_site" default="false"/>
     <column type="string"   name="kind"/>
 
     <index>
@@ -59,6 +59,31 @@
     <column type="datetime" name="updated_at"/>
 
   </table>
-  
+
+  <table name="user_reports">
+
+    <column type="integer"  name="user_id"/>
+    <column type="string"   name="subject_type"/>
+    <column type="integer"  name="subject_id"/>
+    <column type="text"     name="content"/>
+    <column type="text"     name="report"/>
+    <column type="datetime" name="created_at"/>
+
+    <belongs-to target="users"/>
+    <belongs-to target="subject" polymorphic="true"/>
+
+  </table>
+
+  <table name="previews">
+
+    <column type="integer"  name="image_blob_id"/>
+    <column type="integer"  name="svg_blob_id"/>
+    <column type="datetime" name="created_at"/>
+
+    <belongs-to target="image_blob" class_name="ContentBlob" foreign_key="image_blob_id"/>
+    <belongs-to target="svg_blob"   class_name="ContentBlob" foreign_key="svg_blob_id"/>
+
+  </table>
+
 </schema>
 

Modified: branches/topics/config/default_settings.yml (2680 => 2681)


--- branches/topics/config/default_settings.yml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/config/default_settings.yml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -106,6 +106,7 @@
   - obsolete
   - incomplete
   - junk
+  - decommissioned services
 
 # main_tabs - These are the main tabs of the website.  Each entry requires at
 #             least a label and a link.  If you specify a controller in a tab,
@@ -234,7 +235,7 @@
 # search_categories - These are the search categories shown in the search bar
 #                     just under the main tabs.
 
-search_categories: [all, users, groups, workflows, files, packs]
+search_categories: [all, users, groups, workflows, services, files, packs]
 
 # default_search_size - The default number of items shown in each search result
 #                       page.
@@ -244,7 +245,7 @@
 # max_search_size - The maximum number of items shown in each search result
 #                   page.
 
-max_search_size: 100
+max_search_size: 5000
 
 # email - These are the email addresses used for sending notifications and the
 #         email address to send feedback entered from the web site.
@@ -440,3 +441,15 @@
 rdfgen_enable: false
 
 rdfgen_tool:
+
+# recaptcha_enable - This enables the ReCaptcha system.  Be sure to set
+#                    recaptcha_public and recaptcha_private to the public key
+#                    and private keys from the ReCaptcha website if this is
+#                    enabled.
+
+recaptcha_enable: false
+
+recaptcha_public:
+
+recaptcha_private:
+

Modified: branches/topics/config/environment.rb (2680 => 2681)


--- branches/topics/config/environment.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/config/environment.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -83,5 +83,14 @@
 
 ActionMailer::Base.smtp_settings = Conf.smtp
 
+# don't require actual keys for recaptcha during tests
+
+if RAILS_ENV == 'test'
+  Recaptcha.configure do |config|
+    config.public_key  = ''
+    config.private_key = ''
+  end
+end
+
 load 'config/environment_private.rb' if FileTest.exist?('config/environment_private.rb')
 

Modified: branches/topics/config/routes.rb (2680 => 2681)


--- branches/topics/config/routes.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/config/routes.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -117,6 +117,7 @@
     # workflows have nested citations
     workflow.resources :citations
     workflow.resources :reviews
+    workflow.resources :previews
     workflow.resources :comments, :collection => { :timeline => :get }
   end
 
@@ -124,6 +125,16 @@
   map.workflow_version           '/workflows/:id/versions/:version',         :conditions => { :method => :get }, :controller => 'workflows', :action ="" 'show'
   map.formatted_workflow_version '/workflows/:id/versions/:version.:format', :conditions => { :method => :get }, :controller => 'workflows', :action ="" 'show'
 
+  # versioned preview images
+  ['workflow'].each do |x|
+
+    eval("map.#{x}_version_preview '/#{x.pluralize}/:#{x}_id/versions/:version/previews/:id'," +
+        " :conditions => { :method => :get}, :controller => 'previews', :action ="" 'show'")
+
+    eval("map.formatted_#{x}_version_preview '/#{x.pluralize}/:#{x}_id/versions/:version/previews/:id.:format'," +
+        " :conditions => { :method => :get}, :controller => 'previews', :action ="" 'show'")
+  end
+
   map.galaxy_tool 'workflows/:id/versions/:version/galaxy_tool', :controller => 'workflows', :action ="" 'galaxy_tool'
   map.galaxy_tool_download 'workflows/:id/versions/:version/galaxy_tool_download', :controller => 'workflows', :action ="" 'galaxy_tool_download'
 
@@ -158,6 +169,9 @@
     # blogs have nested posts
     blog.resources :blog_posts
   end
+
+  # services
+  map.resources :services, :collection => { :search => :get }
   
   # content_types
   map.resources :content_types
@@ -213,6 +227,9 @@
     
     # user's history
     user.resource :userhistory, :controller => :userhistory
+
+    # user's reports of inappropriate content
+    user.resources :reports, :controller => :user_reports
   end
 
   map.resources :groups, 

Copied: branches/topics/config/schema.d/federation.xml (from rev 2680, trunk/config/schema.d/federation.xml) (0 => 2681)


--- branches/topics/config/schema.d/federation.xml	                        (rev 0)
+++ branches/topics/config/schema.d/federation.xml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<schema>
+
+  <table name="federation_sources">
+
+    <column type="string"     name="name"/>
+
+  </table>
+
+</schema>
+

Copied: branches/topics/config/schema.d/owl.xml (from rev 2680, trunk/config/schema.d/owl.xml) (0 => 2681)


--- branches/topics/config/schema.d/owl.xml	                        (rev 0)
+++ branches/topics/config/schema.d/owl.xml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<schema>
+
+  <table name="ontologies">
+
+    <column type="integer"  name="user_id"/>
+    <column type="string"   name="uri"/>
+    <column type="string"   name="title"/>
+    <column type="string"   name="prefix"/>
+    <column type="text"     name="description"/>
+    <column type="text"     name="description_html"/>
+    <column type="datetime" name="created_at"/>
+    <column type="datetime" name="updated_at"/>
+
+    <has-many target="predicates" foreign_key="ontology_id"/>
+
+  </table>
+
+  <table name="predicates">
+
+    <column type="integer"  name="ontology_id"/>
+    <column type="string"   name="title"/>
+    <column type="string"   name="phrase"/>
+    <column type="text"     name="description"/>
+    <column type="text"     name="description_html"/>
+    <column type="text"     name="equivalent_to"/>
+    <column type="datetime" name="created_at"/>
+    <column type="datetime" name="updated_at"/>
+
+    <belongs-to target="ontology"/>
+
+  </table>
+
+</schema>
+

Modified: branches/topics/config/schema.d/packs.xml (2680 => 2681)


--- branches/topics/config/schema.d/packs.xml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/config/schema.d/packs.xml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -11,7 +11,7 @@
     <column type="datetime" name="created_at"/>
     <column type="datetime" name="updated_at"/>
 
-    <has-many target="relationships" dependent="destroy"/>
+    <has-many target="relationships" as="context" dependent="destroy"/>
 
   </table>
 
@@ -43,22 +43,23 @@
 
   <table name="relationships">
 
-    <column type="integer"  name="pack_id"/>
+    <column type="integer"  name="context_id"/>
+    <column type="string"   name="context_type"/>
     <column type="integer"  name="user_id"/>
-    <column type="integer"  name="concept_id"/>
+    <column type="integer"  name="predicate_id"/>
     <column type="string"   name="subject_type"/>
     <column type="integer"  name="subject_id"/>
     <column type="string"   name="objekt_type"/>
     <column type="integer"  name="objekt_id"/>
     <column type="datetime" name="created_at"/>
 
+    <belongs-to target="users"/>
+    <belongs-to target="contexts" polymorphic="true"/>
+
     <belongs-to target="subjects" polymorphic="true"/>
+    <belongs-to target="predicates"/>
     <belongs-to target="objekts"  polymorphic="true"/>
 
-    <belongs-to target="packs"/>
-    <belongs-to target="users"/>
-    <belongs-to target="concepts"/>
-
   </table>
  
 </schema>

Copied: branches/topics/config/schema.d/services.xml (from rev 2680, trunk/config/schema.d/services.xml) (0 => 2681)


--- branches/topics/config/schema.d/services.xml	                        (rev 0)
+++ branches/topics/config/schema.d/services.xml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -0,0 +1,146 @@
+<?xml version="1.0"?>
+<schema>
+
+  <!-- BioCatalogue services -->
+
+  <table name="services">
+
+    <column type="integer"  name="contributor_id"/>
+    <column type="string"   name="contributor_type"/>
+
+    <column type="datetime" name="created_at"/>
+    <column type="datetime" name="updated_at"/>
+    <column type="datetime" name="retrieved_at"/>
+
+    <!-- from the service index listing -->
+
+    <column type="string"   name="uri"/>
+    <column type="string"   name="submitter_label"/>
+    <column type="datetime" name="created"/>
+    <column type="string"   name="submitter_uri"/>
+
+    <!-- service summary -->
+
+    <column type="string"   name="name"/>
+    <column type="string"   name="provider_uri"/>
+    <column type="string"   name="provider_label"/>
+    <column type="string"   name="endpoint"/>
+    <column type="string"   name="wsdl"/>
+    <column type="string"   name="city"/>
+    <column type="string"   name="country"/>
+    <column type="string"   name="iso3166_country_code"/>
+    <column type="string"   name="flag_url"/>
+    <column type="string"   name="documentation_uri"/>
+    <column type="text"     name="description"/>
+
+    <!-- service monitoring -->
+
+    <column type="string"   name="monitor_label"/>
+    <column type="text"     name="monitor_message"/>
+    <column type="string"   name="monitor_symbol_url"/>
+    <column type="string"   name="monitor_small_symbol_url"/>
+    <column type="datetime" name="monitor_last_checked"/>
+
+    <has-many target="service_categories"/>
+    <has-many target="service_types"/>
+    <has-many target="service_tags"/>
+    <has-many target="service_deployments"/>
+
+  </table>
+
+  <!-- BioCatalogue service categories -->
+
+  <table name="service_categories">
+
+    <column type="datetime" name="created_at"/>
+    <column type="datetime" name="updated_at"/>
+    <column type="datetime" name="retrieved_at"/>
+
+    <column type="integer"  name="service_id"/>
+    <column type="string"   name="uri"/>
+    <column type="string"   name="label"/>
+
+    <belongs-to target="service"/>
+
+  </table>
+    
+  <!-- BioCatalogue service types -->
+
+  <table name="service_types">
+
+    <column type="datetime" name="created_at"/>
+    <column type="datetime" name="updated_at"/>
+    <column type="datetime" name="retrieved_at"/>
+
+    <column type="integer"  name="service_id"/>
+    <column type="string"   name="label"/>
+
+    <belongs-to target="service"/>
+
+  </table>
+
+  <!-- BioCatalogue service tags -->
+
+  <table name="service_tags">
+
+    <column type="datetime" name="created_at"/>
+    <column type="datetime" name="updated_at"/>
+    <column type="datetime" name="retrieved_at"/>
+
+    <column type="integer"  name="service_id"/>
+    <column type="string"   name="uri"/>
+    <column type="string"   name="label"/>
+
+    <belongs-to target="service"/>
+
+  </table>
+
+  <!-- BioCatalogue service deployments -->
+
+  <table name="service_deployments">
+
+    <column type="datetime" name="created_at"/>
+    <column type="datetime" name="updated_at"/>
+    <column type="datetime" name="retrieved_at"/>
+
+    <column type="string"   name="uri"/>
+    <column type="string"   name="endpoint"/>
+
+    <column type="string"   name="city"/>
+    <column type="string"   name="country"/>
+    <column type="string"   name="iso3166_country_code"/>
+    <column type="string"   name="flag_url"/>
+
+    <column type="string"   name="submitter_label"/>
+    <column type="string"   name="submitter_uri"/>
+
+    <column type="datetime" name="created"/>
+
+    <column type="integer"  name="service_id"/>
+    <column type="integer"  name="service_provider_id"/>
+
+    <belongs-to target="service_provider"/>
+    <belongs-to target="service"/>
+
+  </table>
+
+  <!-- BioCatalogue service providers -->
+
+  <table name="service_providers">
+
+    <column type="datetime" name="created_at"/>
+    <column type="datetime" name="updated_at"/>
+    <column type="datetime" name="retrieved_at"/>
+
+    <column type="string"   name="uri"/>
+    <column type="string"   name="name"/>
+    <column type="text"     name="description"/>
+
+    <column type="datetime" name="created"/>
+
+    <has-many target="service_deployments" foreign_key="service_provider_id"/>
+
+  </table>
+
+</schema>
+

Modified: branches/topics/config/schema.d/skos.xml (2680 => 2681)


--- branches/topics/config/schema.d/skos.xml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/config/schema.d/skos.xml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -19,7 +19,7 @@
   <table name="concepts">
 
     <column type="integer"  name="vocabulary_id"/>
-    <column type="string"   name="title"/>
+    <column type="string"   name="phrase"/>
     <column type="text"     name="description"/>
     <column type="text"     name="description_html"/>
     <column type="datetime" name="created_at"/>

Modified: branches/topics/config/schema.d/workflows.xml (2680 => 2681)


--- branches/topics/config/schema.d/workflows.xml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/config/schema.d/workflows.xml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -1,6 +1,56 @@
 <?xml version="1.0"?>
 <schema>
 
+  <table name="workflows">
+
+    <column type="integer"    name="contributor_id"/>
+    <column type="string"     name="contributor_type"/>
+    <column type="string"     name="title"/>
+    <column type="string"     name="unique_name"/>
+    <column type="text"       name="body"/>
+    <column type="text"       name="body_html"/>
+    <column type="datetime"   name="created_at"/>
+    <column type="datetime"   name="updated_at"/>
+    <column type="string"     name="image"/>
+    <column type="string"     name="svg"/>
+    <column type="integer"    name="current_version"/>
+    <column type="integer"    name="content_blob_id"/>
+    <column type="string"     name="file_ext"/>
+    <column type="string"     name="last_edited_by"/>
+    <column type="integer"    name="content_type_id"/>
+    <column type="integer"    name="license_id"/>
+    <column type="integer"    name="preview_id"/>
+
+  </table>
+
+  <table name="workflow_versions">
+
+    <column type="integer"    name="workflow_id"/>
+    <column type="integer"    name="version"/>
+    <column type="text"       name="revision_comments"/>
+    <column type="integer"    name="contributor_id"/>
+    <column type="string"     name="contributor_type"/>
+    <column type="string"     name="title"/>
+    <column type="string"     name="unique_name"/>
+    <column type="text"       name="body"/>
+    <column type="text"       name="body_html"/>
+    <column type="datetime"   name="created_at"/>
+    <column type="datetime"   name="updated_at"/>
+    <column type="string"     name="image"/>
+    <column type="string"     name="svg"/>
+    <column type="string"     name="license"/>
+    <column type="integer"    name="content_blob_id"/>
+    <column type="string"     name="file_ext"/>
+    <column type="string"     name="last_edited_by"/>
+    <column type="integer"    name="content_type_id"/>
+    <column type="integer"    name="preview_id"/>
+
+    <index>
+      <column name="workflow_id"/>
+    </index>
+
+  </table>
+
   <table name="workflow_processors">
 
     <column type="integer"    name="workflow_id"/>

Modified: branches/topics/config/tables.xml


(Binary files differ)

Copied: branches/topics/db/migrate/090_adjust_pictures.rb (from rev 2680, trunk/db/migrate/090_adjust_pictures.rb) (0 => 2681)


--- branches/topics/db/migrate/090_adjust_pictures.rb	                        (rev 0)
+++ branches/topics/db/migrate/090_adjust_pictures.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -0,0 +1,67 @@
+# myExperiment: db/migrate/090_adjust_pictures.rb
+#
+# Copyright (c) 2007 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class AdjustPictures < ActiveRecord::Migration
+  def self.up
+
+    conn = ActiveRecord::Base.connection
+
+    # collect all the file_column paths
+
+    workflow_image         = {}
+    workflow_svg           = {}
+    workflow_version_image = {}
+    workflow_version_svg   = {}
+
+    Workflow.find(:all, :select => 'id, image AS image_fc, svg AS svg_fc').each do |workflow|
+      workflow_image[workflow.id] = workflow.image_fc
+      workflow_svg[workflow.id]   = workflow.svg_fc
+    end
+
+    Workflow::Version.find(:all, :select => 'id, image AS image_fc, svg AS svg_fc').each do |workflow_version|
+      workflow_version_image[workflow_version.id] = workflow_version.image_fc
+      workflow_version_svg[workflow_version.id]   = workflow_version.svg_fc
+    end
+
+    # save the previews into the database
+
+    Workflow.find(:all).each do |workflow|
+
+      if workflow_image[workflow.id] || workflow_svg[workflow.id]
+
+        if workflow_image[workflow.id]
+          workflow.image = File.new("public/workflow/image/#{workflow.id}/#{workflow_image[workflow.id]}").read
+        end
+
+        if workflow_svg[workflow.id]
+          workflow.svg = File.new("public/workflow/svg/#{workflow.id}/#{workflow_svg[workflow.id]}").read
+        end
+
+        workflow.preview.save
+        conn.execute("UPDATE workflows SET preview_id = #{workflow.preview.id} WHERE id = #{workflow.id}")
+      end
+    end
+      
+    Workflow::Version.find(:all).each do |workflow_version|
+
+      if workflow_version_image[workflow_version.id] || workflow_version_svg[workflow_version.id]
+
+        if workflow_version_image[workflow_version.id]
+          workflow_version.image = File.new("public/workflow/version/image/#{workflow_version.id}/#{workflow_version_image[workflow_version.id]}").read
+        end
+
+        if workflow_version_svg[workflow_version.id]
+          workflow_version.svg = File.new("public/workflow/version/svg/#{workflow_version.id}/#{workflow_version_svg[workflow_version.id]}").read
+        end
+
+        workflow_version.preview.save
+        conn.execute("UPDATE workflow_versions SET preview_id = #{workflow_version.preview.id} WHERE id = #{workflow_version.id}")
+      end
+    end
+  end
+
+  def self.down
+  end
+end

Copied: branches/topics/db/migrate/091_fix_orphaned_oauth_tokens.rb (from rev 2680, trunk/db/migrate/091_fix_orphaned_oauth_tokens.rb) (0 => 2681)


--- branches/topics/db/migrate/091_fix_orphaned_oauth_tokens.rb	                        (rev 0)
+++ branches/topics/db/migrate/091_fix_orphaned_oauth_tokens.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -0,0 +1,18 @@
+# myExperiment: db/migrate/091_fix_orphaned_oauth_tokens.rb
+#
+# Copyright (c) 2010 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class FixOrphanedOauthTokens < ActiveRecord::Migration
+  def self.up
+
+    OauthToken.find(:all).each do |t|
+      if t.client_application.nil?
+        t.destroy()
+      end
+    end
+  end
+
+  def self.down
+  end
+end

Modified: branches/topics/lib/authorization.rb (2680 => 2681)


--- branches/topics/lib/authorization.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/lib/authorization.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -102,6 +102,8 @@
 
     raise "Missing action in authorisation check" if opts[:action].nil?
 
+    opts[:user] = nil if opts[:user] == 0
+
     if opts[:model].nil? && opts[:object].nil? && (opts[:object_type].nil? || opts[:object_id])
       raise "Missing object / model in authorisation check"
     end
@@ -297,7 +299,7 @@
     # this is required to get "policy_id" for policy-based aurhorized objects (like workflows / blobs / packs / contributions)
     # and to get objects themself for other object types (networks, experiments, jobs, tavernaenactors, runners)
     if (thing_contribution.nil? && ["Workflow", "Blog", "Blob", "Pack", "Contribution"].include?(thing_type)) || 
-       (thing_instance.nil? && ["Network", "Comment", "Bookmark", "Experiment", "Job", "TavernaEnactor", "Runner"].include?(thing_type))
+       (thing_instance.nil? && ["Network", "Comment", "Bookmark", "Experiment", "Job", "TavernaEnactor", "Runner", "Picture", "ClientApplication"].include?(thing_type))
       
       found_thing = find_thing(thing_type, thing_id)
       
@@ -485,6 +487,43 @@
             is_authorized = false
         end
 
+      when "User"
+
+        case action
+
+          when "view"
+            # everyone can view users
+            is_authorized = true
+
+          when "edit"
+            # the owner of a user record can edit
+            is_authorized = !user.nil? && user_id == thing_id
+
+          when "destroy"
+            # only adminstrators can delete accounts at present
+            is_authorized = user_is_administrator?(user)
+        end
+
+      when "Picture"
+
+        case action
+
+          when "view"
+            # owner can view all their pictures
+            return true if is_owner?(user_id, thing_instance)
+
+            # anyone can view a user's selected pictures
+            is_authorized = thing_instance.selected?
+
+          when "edit", "destroy"
+            # only the owner of a picture can edit/destroy
+            is_authorized = is_owner?(user_id, thing_instance)
+        end
+
+      when "ClientApplication"
+
+          is_authorized = is_owner?(user_id, thing_instance)
+
       else
         # don't recognise the kind of "thing" that is being authorized, so
         # we don't specifically know that it needs to be blocked;
@@ -552,6 +591,10 @@
           found_instance = TavernaEnactor.find(thing_id)
         when "ContentType"
           found_instance = ContentType.find(thing_id)
+        when "Picture"
+          found_instance = Picture.find(thing_id)
+        when "ClientApplication"
+          found_instance = ClientApplication.find(thing_id)
       end
     rescue ActiveRecord::RecordNotFound
       # do nothing; makes sure that app won't crash when the required object is not found;
@@ -578,6 +621,10 @@
         is_authorized = (thing.user_id == user_id)
       when "Bookmark"
         is_authorized = (thing.user_id == user_id)
+      when "Picture"
+        is_authorized = (thing.user_id == user_id)
+      when "ClientApplication"
+        is_authorized = (thing.user_id == user_id)
       #else
         # do nothing -- unknown "thing" types are not authorized by default 
     end
@@ -781,7 +828,7 @@
 
     def self.view_conditions(user_id = nil, friends = nil, networks = nil)
 
-      return "(share_mode = 0 OR share_mode = 1 OR share_mode = 2)" if user_id.nil?
+      return "((contributions.id IS NULL) OR (share_mode = 0 OR share_mode = 1 OR share_mode = 2))" if user_id.nil?
 
       policy_part =
         "((contributions.contributor_type = 'User' AND contributions.contributor_id = #{user_id}) OR
@@ -789,12 +836,12 @@
           ((share_mode = 1 OR share_mode = 3 OR share_mode = 4 OR update_mode = 1 OR (update_mode = 0 AND (share_mode = 1 OR share_mode = 3))) AND
            (contributions.contributor_type = 'User' AND contributions.contributor_id IN #{friends})))"
 
-      "(#{policy_part} OR #{permission_part(['view', 'download', 'edit'], user_id, networks)})"
+      "((contributions.id IS NULL) OR (#{policy_part} OR #{permission_part(['view', 'download', 'edit'], user_id, networks)}))"
     end
 
     def self.download_conditions(user_id = nil, friends = nil, networks = nil)
 
-      return "(share_mode = 0)" if user_id.nil?
+      return "((contributions.id IS NULL) OR (share_mode = 0))" if user_id.nil?
 
       policy_part = 
         "((contributions.contributor_type = 'User' AND contributions.contributor_id = #{user_id}) OR
@@ -802,12 +849,12 @@
           ((share_mode = 1 OR share_mode = 3 OR update_mode = 1 OR (update_mode = 0 AND (share_mode = 1 OR share_mode = 3))) AND
            (contributions.contributor_type = 'User' AND contributions.contributor_id IN #{friends})))"
 
-      "(#{policy_part} OR #{permission_part(['download', 'edit'], user_id, networks)})"
+      "((contributions.id IS NULL) OR (#{policy_part} OR #{permission_part(['download', 'edit'], user_id, networks)}))"
     end
 
     def self.edit_conditions(user_id = nil, friends = nil, networks = nil)
 
-      return "(share_mode = 0 AND update_mode = 0)" if user_id.nil?
+      return "((contributions.id IS NULL) OR (share_mode = 0 AND update_mode = 0))" if user_id.nil?
 
       policy_part =
         "((contributions.contributor_type = 'User' AND contributions.contributor_id = #{user_id}) OR
@@ -815,7 +862,7 @@
           ((update_mode = 1 OR (update_mode = 0 AND (share_mode = 1 OR share_mode = 3))) AND
            (contributions.contributor_type = 'User' AND contributions.contributor_id IN #{friends})))"
 
-      "(#{policy_part} OR #{permission_part(['edit'], user_id, networks)})"
+      "((contributions.id IS NULL) OR (#{policy_part} OR #{permission_part(['edit'], user_id, networks)}))"
     end
 
     def self.permission_part(permissions, user_id, networks)
@@ -855,7 +902,7 @@
     auth_type = opts.delete(:auth_type) || "'#{model.name}'"
 
     conditions.push(view_conditions(user_id, friends, networks))
-    conditions.push("contributions.contributable_type = #{auth_type}") if model != Contribution
+    conditions.push("contributions.contributable_type = #{auth_type}") if !opts.delete(:arbitrary_models) && model != Contribution
 
     # result model
 

Copied: branches/topics/lib/bio_catalogue_import.rb (from rev 2680, trunk/lib/bio_catalogue_import.rb) (0 => 2681)


--- branches/topics/lib/bio_catalogue_import.rb	                        (rev 0)
+++ branches/topics/lib/bio_catalogue_import.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -0,0 +1,328 @@
+# myExperiment: lib/biocatalog_import.rb
+#
+# Copyright (c) 2010 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+class BioCatalogueImport
+
+  require 'xml/libxml'
+  require 'open-uri'
+
+  @@biocat_base_uri        = 'http://www.biocatalogue.org/'
+  @@biocat_ns              = { "bc" => "http://www.biocatalogue.org/2009/xml/rest" }
+  @@biocat_wait_in_seconds = 10
+
+  def self.fetch_uri(uri)
+
+    if @documents.nil?
+      if File.exists?(@@biocat_document_cache)
+        @documents = YAML::load_file(@@biocat_document_cache)
+      else
+        @documents = { :retrieved_at => { } }
+      end
+    end
+
+    return @documents[uri] if @documents[uri]
+
+    rest_uri = URI.parse(uri)
+    rest_uri.path = rest_uri.path + ".xml"
+
+    puts "Fetching URI: #{rest_uri}"
+
+    @documents[uri] = open(rest_uri.to_s).read.to_s
+    @documents[:retrieved_at][uri] = Time.now
+
+    Kernel.sleep(@@biocat_wait_in_seconds)
+
+    @documents[uri]
+  end
+
+  def self.uri_retrieved_at(uri)
+    @documents[:retrieved_at][uri]
+  end
+
+  def self.save_document_cache
+    file = File.open(@@biocat_document_cache, "w+") do |file|
+      file.rewind
+      file.puts(@documents.to_yaml)
+    end
+  end
+
+  def self.get_text(element, query)
+    response = element.find(query, @@biocat_ns)
+    response[0].to_s unless response.length.zero?
+  end
+
+  def self.get_attr(element, query)
+    response = element.find(query, @@biocat_ns)
+    response[0].value unless response.length.zero?
+  end
+
+  def self.get_link(element, query)
+    response = element.find(query, @@biocat_ns)
+    (URI.parse(@@biocat_base_uri) + response[0].value).to_s unless response.length.zero?
+  end
+
+  def self.import_service(service_element, index_uri)
+
+    summary_element = service_element.find('bc:summary', @@biocat_ns)[0]
+
+    # Service
+
+    service_uri = get_link(service_element, '@xlink:href')
+
+#return service_uri unless service_uri.ends_with?("/2")
+    service = Service.find_by_uri(service_uri)
+
+    service = Service.new if service.nil?
+
+    service.attributes = {
+
+      :contributor              => @federation_source,
+
+      :uri                      => service_uri,
+      :name                     => get_text(service_element, 'bc:name/text()'),
+      :submitter_label          => get_attr(service_element, 'bc:originalSubmitter/@resourceName'),
+      :created                  => get_text(service_element, 'dcterms:created/text()'),
+      :submitter_uri            => get_attr(service_element, 'bc:originalSubmitter/@xlink:href'),
+
+      :provider_uri             => get_link(summary_element, 'bc:provider/@xlink:href'),
+      :provider_label           => get_text(summary_element, 'bc:provider/bc:name/text()'),
+      :endpoint                 => get_text(summary_element, 'bc:endpoint/text()'),
+      :wsdl                     => get_text(summary_element, 'bc:wsdl/text()'),
+      :city                     => get_text(summary_element, 'bc:location/bc:city/text()'),
+      :country                  => get_text(summary_element, 'bc:location/bc:country/text()'),
+      :iso3166_country_code     => get_text(summary_element, 'bc:location/bc:iso3166CountryCode/text()'),
+      :flag_url                 => get_link(summary_element, 'bc:location/bc:flag/@xlink:href'),
+      :documentation_uri        => get_text(summary_element, 'bc:documentationUrl/text()'),
+      :description              => get_text(summary_element, 'dc:description/text()'),
+      
+      :monitor_label            => get_text(service_element, 'bc:latestMonitoringStatus/bc:label/text()'),
+      :monitor_message          => get_text(service_element, 'bc:latestMonitoringStatus/bc:message/text()'),
+      :monitor_symbol_url       => get_link(service_element, 'bc:latestMonitoringStatus/bc:symbol/@xlink:href'),
+      :monitor_small_symbol_url => get_link(service_element, 'bc:latestMonitoringStatus/bc:smallSymbol/@xlink:href'),
+      :monitor_last_checked     => get_text(service_element, 'bc:latestMonitoringStatus/bc:lastChecked/text()')
+    }
+
+    service.save if service.changed?
+
+    if service.contribution.nil?
+      service.contribution = Contribution.create(:contributor => @federation_source)
+      service.contribution.policy = create_default_policy(@federation_source)
+      service.contribution.policy.share_mode = 0 # Make public
+      service.contribution.policy.save
+      service.contribution.save
+    end
+
+    # Service categories
+
+    existing_service_categories = ServiceCategory.find_all_by_service_id(service.id)
+
+    current_service_category_uris = []
+
+    summary_element.find('bc:category', @@biocat_ns).each do |category_element|
+
+      service_category_uri = get_link(category_element, '@xlink:href')
+
+      service_category = ServiceCategory.find_by_service_id_and_uri(service.id, service_category_uri)
+
+      service_category = ServiceCategory.new if service_category.nil?
+
+      service_category.attributes = {
+        :service       => service,
+        :retrieved_at  => uri_retrieved_at(index_uri),
+        :uri           => service_category_uri,
+        :label         => get_text(category_element, 'text()')
+      }
+
+      service_category.save if service_category.changed?
+
+      current_service_category_uris << service_category_uri
+    end
+
+    existing_service_categories.each do |service_category|
+      next if current_service_category_uris.include?(service_category.uri)
+      service_category.destroy
+    end
+
+    # Service technology types
+
+    existing_service_types = ServiceType.find_all_by_service_id(service.id)
+
+    current_types = []
+
+    service_element.find('bc:serviceTechnologyTypes/bc:type', @@biocat_ns).each do |type_element|
+
+      type_text = get_text(type_element, 'text()')
+
+      service_type = ServiceType.find_by_service_id_and_label(service.id, type_text)
+
+      service_type = ServiceType.new if service_type.nil?
+
+      service_type.attributes = {
+        :service       => service,
+        :retrieved_at  => uri_retrieved_at(index_uri),
+        :label         => type_text
+      }
+
+      service_type.save if service_type.changed?
+
+      current_types << type_text
+    end
+
+    existing_service_types.each do |service_type|
+      next if current_types.include?(service_type.label)
+      service_type.destroy
+    end
+
+    # Service tags
+
+    existing_service_tags = ServiceTag.find_all_by_service_id(service.id)
+
+    current_service_tag_uris = []
+
+    summary_element.find('bc:tag', @@biocat_ns).each do |tag_element|
+
+      service_tag_uri   = get_link(tag_element, '@xlink:href')
+      service_tag_label = get_text(tag_element, 'text()')
+
+      service_tag = ServiceTag.find_by_service_id_and_uri(service.id, service_tag_uri)
+
+      service_tag = ServiceTag.new if service_tag.nil?
+
+      service_tag.attributes = {
+        :service       => service,
+        :retrieved_at  => uri_retrieved_at(index_uri),
+        :uri           => service_tag_uri,
+        :label         => service_tag_label
+      }
+
+      service_tag.save if service_tag.changed?
+
+      current_service_tag_uris << service_tag_uri
+    end
+
+    existing_service_tags.each do |service_tag|
+      next if current_service_tag_uris.include?(service_tag.uri)
+      service_tag.destroy
+    end
+
+    # deployments and providers
+
+    existing_service_providers = ServiceProvider.find(:all)
+    existing_service_deployments = ServiceDeployment.find_all_by_service_id(service.id)
+
+    current_service_deployments = []
+
+    service_element.find('bc:deployments/bc:serviceDeployment', @@biocat_ns).each do |deployment_element|
+      
+      # provider
+
+      provider_uri   = get_link(deployment_element, 'bc:serviceProvider/@xlink:href')
+      deployment_uri = get_link(deployment_element, '@xlink:href')
+
+
+      service_provider = ServiceProvider.find_by_uri(provider_uri)
+
+      service_provider = ServiceProvider.new if service_provider.nil?
+
+      service_provider.attributes = {
+        :uri          => provider_uri,
+        :retrieved_at => uri_retrieved_at(index_uri),
+        :name         => get_text(deployment_element, 'bc:serviceProvider/bc:name/text()'),
+        :description  => get_text(deployment_element, 'bc:serviceProvider/dc:description/text()'),
+        :created      => get_text(deployment_element, 'bc:serviceProvider/dcterms:created/text()')
+      }
+
+      service_provider.save if service_provider.changed?
+
+      # deployment
+
+      service_deployment = ServiceDeployment.find_by_service_id_and_uri(service.id, deployment_uri)
+
+      service_deployment = ServiceDeployment.new if service_deployment.nil?
+
+      service_deployment.attributes = {
+        :service              => service,
+        :service_provider     => service_provider,
+        :retrieved_at         => uri_retrieved_at(index_uri),
+        :uri                  => get_link(deployment_element, '@xlink:href'),
+        :endpoint             => get_text(deployment_element, 'bc:endpoint/text()'),
+        :city                 => get_text(deployment_element, 'bc:location/bc:city/text()'),
+        :country              => get_text(deployment_element, 'bc:location/bc:country/text()'),
+        :iso3166_country_code => get_text(deployment_element, 'bc:location/bc:iso3166CountryCode/text()'),
+        :flag_url             => get_link(deployment_element, 'bc:location/bc:flag/@xlink:href'),
+        :submitter_label      => get_attr(deployment_element, 'bc:submitter/@resourceName'),
+        :submitter_uri        => get_attr(deployment_element, 'bc:submitter/@xlink:href'),
+        :created              => get_text(deployment_element, 'dcterms:created/text()')
+      }
+
+      service_deployment.save if service_deployment.changed?
+
+      current_service_deployments << deployment_uri
+    end
+
+    existing_service_deployments.each do |service_deployment|
+      next if current_service_deployments.include?(service_deployment.uri)
+      service_deployment.destroy
+    end
+
+    # update the retrieved_at attribute
+
+    ActiveRecord::Base.record_timestamps = false
+    service.update_attribute(:retrieved_at, uri_retrieved_at(index_uri))
+    ActiveRecord::Base.record_timestamps = true
+
+    service_uri
+  end
+
+  def self.import_biocatalogue_services(uri)
+
+    current_service_uris = []
+
+    while true
+      doc = LibXML::XML::Parser.string(fetch_uri(uri)).parse.root
+
+      doc.find("/bc:services/bc:results/bc:service", @@biocat_ns).each do |service_element|
+        current_service_uris << import_service(service_element, uri)
+      end
+
+      next_doc = doc.find("/bc:services/bc:related/bc:next/@xlink:href", @@biocat_ns)
+
+      break if next_doc.length.zero?
+
+      uri = next_doc[0].value
+    end
+
+    Service.find(:all).each do |service|
+
+      next if current_service_uris.include?(service.uri)
+
+      service.destroy
+    end
+
+    # destroy unused service providers
+
+    current_service_providers = ServiceDeployment.find(:all).map do |sd| sd.service_provider end.uniq
+
+    (ServiceProvider.find(:all) - current_service_providers).each do |service_provider|
+      service_provider.destroy
+    end
+
+    save_document_cache
+  end
+
+  def self.import_biocatalogue
+
+    if FederationSource.find_by_name("BioCatalogue").nil?
+      FederationSource.create(:name => "BioCatalogue")
+    end
+
+    @@biocat_document_cache = ENV['FILE'] ? ENV['FILE'] : "tmp/biocatalogue.yml"
+
+    @federation_source = FederationSource.find_by_name("BioCatalogue")
+
+    import_biocatalogue_services("http://www.biocatalogue.org/services?include=summary,deployments&sort_order=asc")
+  end
+end
+

Modified: branches/topics/lib/conf.rb (2680 => 2681)


--- branches/topics/lib/conf.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/lib/conf.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -153,6 +153,18 @@
     self.fetch_entry('rdfgen_tool')
   end
 
+  def self.recaptcha_enable
+    self.fetch_entry('recaptcha_enable')
+  end
+
+  def self.recaptcha_public
+    self.fetch_entry('recaptcha_public')
+  end
+
+  def self.recaptcha_private
+    self.fetch_entry('recaptcha_private')
+  end
+
   # This method is required to create an administrator in the test fixtures
 
   def self.admins=(value)
@@ -231,6 +243,5 @@
 
     default
   end
-
 end
 

Modified: branches/topics/lib/explicit_versioning.rb (2680 => 2681)


--- branches/topics/lib/explicit_versioning.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/lib/explicit_versioning.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -15,7 +15,7 @@
           send :include, Jits::Acts::ExplicitVersioning::ActMethods
           
           cattr_accessor :versioned_class_name, :versioned_foreign_key, :versioned_table_name, :versioned_inheritance_column, 
-            :version_column, :version_sequence_name, :non_versioned_columns, :file_columns, :white_list_columns, :revision_comments_column, 
+            :version_column, :version_sequence_name, :non_versioned_columns, :file_columns, :extra_attributes, :white_list_columns, :revision_comments_column, 
             :version_association_options, :timestamp_columns, :sync_ignore_columns
             
           self.versioned_class_name         = options[:class_name]  || "Version"
@@ -25,6 +25,7 @@
           self.version_column               = options[:version_column]     || 'version'
           self.non_versioned_columns        = [self.primary_key, inheritance_column, 'version', 'lock_version', versioned_inheritance_column, version_column]
           self.file_columns                 = options[:file_columns] || []
+          self.extra_attributes             = options[:extra_attributes] || []
           self.white_list_columns           = options[:white_list_columns] || []
           self.revision_comments_column     = options[:revision_comments_column]  || "revision_comments"
           self.version_association_options  = {
@@ -159,10 +160,10 @@
           # Saves a version of the model in the versioned table. This is called in the after_create callback by default
           def save_version_on_create(revision_comment=nil)
             rev = self.class.versioned_class.new
-            self.clone_versioned_model(self, rev)
             rev.version = send(self.class.version_column)
             rev.send("#{self.class.revision_comments_column}=", revision_comment)
             rev.send("#{self.class.versioned_foreign_key}=", self.id)
+            self.clone_versioned_model(self, rev)
             saved = rev.save
             
             if saved
@@ -282,7 +283,7 @@
           
           # Returns an array of attribute keys that are versioned.  See non_versioned_columns
           def versioned_attributes
-            self.attributes.keys.select { |k| !self.class.non_versioned_columns.include?(k) }
+            self.attributes.keys.select { |k| !self.class.non_versioned_columns.include?(k) } + extra_attributes
           end
         
         module ClassMethods

Modified: branches/topics/lib/load_vocabulary.rb (2680 => 2681)


--- branches/topics/lib/load_vocabulary.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/lib/load_vocabulary.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -5,17 +5,8 @@
 
 module LoadVocabulary
 
-  def self.load_vocabulary
+  def self.load_skos(data)
 
-    file_name = ENV['FILE']
-
-    if file_name.nil?
-      puts "Missing file name."
-      return
-    end
-
-    data = ""
-
     exising_vocabulary = Vocabulary.find_by_uri(data["uri"])
     exising_vocabulary.destroy if exising_vocabulary
 
@@ -28,7 +19,7 @@
     data["concepts"].each do |concept|
       
       c = Concept.create(
-          :title => concept["title"],
+          :phrase      => concept["phrase"],
           :description => concept["description"])
 
       c.labels << Label.create(
@@ -64,5 +55,28 @@
     end
   end
 
+  def self.load_ontology(data)
+
+    existing_ontology = Ontology.find_by_uri(data["uri"])
+    existing_ontology.destroy if existing_ontology
+
+    
+        :uri         => data["uri"],
+        :title       => data["title"],
+        :prefix      => data["prefix"],
+        :description => data["description"])
+
+    data["predicates"].each do |predicate|
+      
+      p = Predicate.create(
+          :title         => predicate["title"],
+          :phrase        => predicate["phrase"],
+          :description   => predicate["description"],
+          :equivalent_to => predicate["equivalent_to"])
+
+      ontology.predicates << p
+
+    end
+  end
 end
 

Copied: branches/topics/lib/oai_static_repository.rb (from rev 2680, trunk/lib/oai_static_repository.rb) (0 => 2681)


--- branches/topics/lib/oai_static_repository.rb	                        (rev 0)
+++ branches/topics/lib/oai_static_repository.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -0,0 +1,106 @@
+# myExperiment: lib/static_oai.rb
+#
+# Copyright (c) 2009 University of Manchester and the University of Southampton.
+# See license.txt for details.
+
+require 'xml/libxml'
+
+include LibXML::XML
+
+module OAIStaticRepository
+
+  def self.generate_workflow_id(workflow)
+    "oai:myexperiment.org:workflow/#{workflow.id}"
+  end
+
+  def self.generate(workflows)
+
+    def self.build(name, text = nil, &blk)
+      node = Node.new(name)
+      node << text if text
+      yield(node) if blk
+      node
+    end
+
+    if workflows.length > 0
+      earliest_datestamp = workflows.first.created_at
+      workflows.each do |w|
+        earliest_datestamp = w.created_at if w.created_at < earliest_datestamp
+      end
+    end
+
+    repository_name    = "myExperiment"
+    base_url           = "http://www.myexperiment.org/oai/static.xml"
+    protocol_version   = "2.0"
+    admin_email        = "address@hidden"
+    deleted_record     = "no"
+
+    doc = Document.new
+
+    doc.root = build("Repository") { |repository|
+
+      repository["xmlns"]              = "http://www.openarchives.org/OAI/2.0/static-repository" 
+      repository["xmlns:oai"]          = "http://www.openarchives.org/OAI/2.0/" 
+      repository["xmlns:xsi"]          = "http://www.w3.org/2001/XMLSchema-instance" 
+      repository["xsi:schemaLocation"] = "http://www.openarchives.org/OAI/2.0/static-repository " +
+                                "http://www.openarchives.org/OAI/2.0/static-repository.xsd"
+
+      repository << build("Identify") { |identify|
+
+        identify << build("oai:repositoryName",    repository_name)
+        identify << build("oai:baseURL",           base_url)
+        identify << build("oai:protocolVersion",   protocol_version)
+        identify << build("oai:adminEmail",        admin_email)
+        identify << build("oai:earliestDatestamp", earliest_datestamp.strftime("%Y-%m-%d"))
+        identify << build("oai:deletedRecord",     deleted_record)
+        identify << build("oai:granularity",       "YYYY-MM-DD")
+      }
+
+      repository << build("ListMetadataFormats") { |list_metadata_formats|
+
+        list_metadata_formats << build("oai:metadataFormat") { |metadata_format|
+          
+           metadata_format << build("oai:metadataPrefix",    "oai_dc")
+           metadata_format << build("oai:schema",            "http://www.openarchives.org/OAI/2.0/oai_dc.xsd")
+           metadata_format << build("oai:metadataNamespace", "http://www.openarchives.org/OAI/2.0/oai_dc/")
+        }
+      }
+
+      repository << build("ListRecords") { |list_records|
+
+        list_records["metadataPrefix"] = "oai_dc"
+
+        workflows.each do |workflow|
+
+          list_records << build("oai:record") { |record|
+
+            record << build("oai:header") { |header|
+
+              header << build("oai:identifier", generate_workflow_id(workflow))
+              header << build("oai:datestamp", workflow.created_at.strftime("%Y-%m-%d"))
+            }
+
+            record << build("oai:metadata") { |metadata|
+
+              metadata << build("oai_dc:dc") { |dc|
+
+                dc["xmlns:oai_dc"]       = "http://www.openarchives.org/OAI/2.0/oai_dc/" 
+                dc["xmlns:dc"]           = "http://purl.org/dc/elements/1.1/" 
+                dc["xmlns:xsi"]          = "http://www.w3.org/2001/XMLSchema-instance" 
+                dc["xsi:schemaLocation"] = "http://www.openarchives.org/OAI/2.0/oai_dc/ " +
+                                           "http://www.openarchives.org/OAI/2.0/oai_dc.xsd"
+
+                dc << build("dc:title",       workflow.title)
+                dc << build("dc:description", workflow.body)
+                dc << build("dc:creator",     workflow.contributor.name)
+                dc << build("dc:date",        workflow.created_at.strftime("%Y-%m-%d"))
+              }
+            }
+          }
+        end
+      }
+    }
+
+    doc
+  end
+end

Copied: branches/topics/lib/previews.rb (from rev 2680, trunk/lib/previews.rb) (0 => 2681)


--- branches/topics/lib/previews.rb	                        (rev 0)
+++ branches/topics/lib/previews.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -0,0 +1,59 @@
+
+class ActiveRecord::Base
+
+  def self.has_previews
+
+    self.class_eval do
+
+      belongs_to :preview
+
+      def image
+        preview.image_blob.data if preview && preview.image_blob
+      end
+
+      def svg
+        preview.svg_blob.data if preview && preview.svg_blob
+      end
+
+      def image=(x)
+
+        self.preview = Preview.new if self.preview.nil?
+        self.preview.image_blob = ContentBlob.new if self.preview.image_blob.nil?
+
+        self.preview.image_blob.data = x
+      end
+
+      def svg=(x)
+
+        self.preview = Preview.new if self.preview.nil?
+        self.preview.svg_blob = ContentBlob.new if self.preview.svg_blob.nil?
+
+        self.preview.svg_blob.data = x
+      end
+
+      after_save { |ob|
+      
+        p = ob.preview
+
+        if p
+
+          ib = p.image_blob
+          sb = p.svg_blob
+
+          if ib && ib.data_changed?
+            ib.save
+            ob.preview.clear_cache
+          end
+
+          if sb && sb.data_changed?
+            sb.save
+            ob.preview.clear_cache
+          end
+          
+          p.save
+        end
+      }
+    end
+  end
+end
+

Modified: branches/topics/lib/rest.rb (2680 => 2681)


--- branches/topics/lib/rest.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/lib/rest.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -98,13 +98,11 @@
   render(:xml => doc.to_s, :status => "#{code} #{message}")
 end
 
-def file_column_url(ob, field)
-
-  fields = (field.split('/').map do |f| "'#{f}'" end).join(', ')
-
-  path = eval("ActionView::Base.new.url_for_file_column(ob, #{fields})")
-
-  "#{request.protocol}#{request.host_with_port}#{path}"
+def preview_url(ob, type)
+  url = ""
+  url.path << "/versions/#{ob.current_version}" if ob.respond_to?('current_version')
+  url.path << "/previews/#{type}"
+  url.to_s
 end
 
 def model_entity_to_rest_entity(model_entity)
@@ -241,9 +239,9 @@
 
       else 
 
-        if model_data['Encoding'][i] == 'file-column'
+        if model_data['Encoding'][i] == 'preview'
 
-          text = file_column_url(ob, model_data['Accessor'][i])
+          text = preview_url(ob, model_data['Accessor'][i])
 
         else
 
@@ -574,7 +572,7 @@
     when 'Job';                    return experiment_job_url(ob.experiment, ob)
     when 'PackContributableEntry'; return rest_resource_uri(ob.contributable)
     when 'PackRemoteEntry';        return ob.uri
-    when 'ContentType';            return nil
+    when 'ContentType';            return content_type_url(ob)
     when 'License';                return license_url(ob)
     when 'CurationEvent';          return nil
 
@@ -958,17 +956,7 @@
     end
 
     if preview
-
-      image = Tempfile.new('image')
-      image.write(preview)
-      image.rewind
-
-      image.extend FileUpload
-      image.original_filename = 'preview'
-      
-      ob.image = image
-
-      image.close
+      ob.image = preview
     end
 
     if svg.nil? and content
@@ -977,17 +965,7 @@
     end
 
     if svg
-
-      svg_file = Tempfile.new('image')
-      svg_file.write(svg)
-      svg_file.rewind
-
-      svg_file.extend FileUpload
-      svg_file.original_filename = 'svg'
-      
-      ob.svg = svg_file
-
-      svg_file.close
+      ob.svg = svg
     end
 
     success = if (action == 'create' and opts[:query]['id'])

Modified: branches/topics/lib/workflow_processors/blog2_template.rb (2680 => 2681)


--- branches/topics/lib/workflow_processors/blog2_template.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/lib/workflow_processors/blog2_template.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -17,7 +17,7 @@
     
     # MUST be unique across all processors
     def self.display_name
-      "Blog2 Template"
+      "LabTrove Template"
     end
     
     def self.display_data_format

Copied: branches/topics/public/images/biocat_icon.png (from rev 2680, trunk/public/images/biocat_icon.png)


(Binary files differ)

Copied: branches/topics/public/images/biocat_logo.png (from rev 2680, trunk/public/images/biocat_logo.png)


(Binary files differ)

Modified: branches/topics/public/stylesheets/styles.css (2680 => 2681)


--- branches/topics/public/stylesheets/styles.css	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/public/stylesheets/styles.css	2011-08-31 15:23:15 UTC (rev 2681)
@@ -838,6 +838,7 @@
 	margin-bottom: 0.5em;
 	padding: 1em 0.5em;
 	vertical-align: top;
+  width: 737px;
 }
 
 table.alt_table tr.odd_row td {
@@ -855,7 +856,8 @@
 }
 
 table.alt_table .mid {
-	text-align: left :
+	text-align: left;
+  width: 390px;
 }
 
 table.alt_table tr td.actions { /*width: 135px;*/
@@ -893,13 +895,14 @@
 table.alt_table .standout {
 	border: 1px dotted #999999;
 	margin: 0.2em 0;
-	padding: 0.5em 0.6em;
+	padding: 0.4em 0.6em;
 	background-color: #FFFFCC;
 	text-align: left;
 	line-height: 1;
 	font-size: 93%;
 	font-weight: bold;
 	color: #333333;
+	width: 360px;
 }
 
 table.alt_table tr td.contributable {
@@ -2067,6 +2070,10 @@
   width: 40%;
 }
 
+#topic_container .hTagcloud {
+/*  width: 225px; */
+}
+
 /* End syles related to topics */
 
 /* pivot */
@@ -2254,3 +2261,16 @@
   width: 450px;
 }
 
+.edit_relationships {
+  margin: 20px;
+}
+
+.edit_relationships > * {
+  display: block;
+  margin-bottom: 10px;
+}
+
+.relationship_sentences * {
+  vertical-align: middle;
+}
+

Modified: branches/topics/test/fixtures/workflow_versions.yml (2680 => 2681)


--- branches/topics/test/fixtures/workflow_versions.yml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/test/fixtures/workflow_versions.yml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -5,8 +5,6 @@
   version: 1
   contributor_id: 1
   contributor_type: User
-  image: 
-  svg:
   title: Get Dilbert
   unique_name: get_dilbert
   body: Gets todays dilbert cartoon
@@ -22,8 +20,6 @@
   version: 1
   contributor_id: 2
   contributor_type: User
-  image: 
-  svg:
   title: Conditional branch choice
   unique_name: branch_choice
   body: Does something, probably chooses a branch based on a condition...

Modified: branches/topics/test/fixtures/workflows.yml (2680 => 2681)


--- branches/topics/test/fixtures/workflows.yml	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/test/fixtures/workflows.yml	2011-08-31 15:23:15 UTC (rev 2681)
@@ -3,8 +3,6 @@
   id: 1
   contributor_id: 1
   contributor_type: User
-  image: 
-  svg:
   title: Get Dilbert
   unique_name: get_dilbert
   body: Gets todays dilbert cartoon
@@ -19,8 +17,6 @@
   id: 2
   contributor_id: 2
   contributor_type: User
-  image: 
-  svg:
   title: Conditional branch choice
   unique_name: branch_choice
   body: Does something, probably chooses a branch based on a condition...

Modified: branches/topics/test/functional/users_controller_test.rb (2680 => 2681)


--- branches/topics/test/functional/users_controller_test.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/test/functional/users_controller_test.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -65,6 +65,6 @@
     delete :destroy, :id => 1
 
     assert_redirected_to :action ="" :index
-    assert_equal "Please contact the administrator to have your account removed.", flash[:notice]
+    assert_equal "You do not have permission to delete this user.", flash[:notice]
   end
 end

Property changes: branches/topics/tmp


Added: svn:ignore

Property changes: branches/topics/vendor/plugins/acts_as_solr/solr/solr


Added: svn:ignore

Modified: branches/topics/vendor/plugins/structured_data/lib/auto_migrate.rb (2680 => 2681)


--- branches/topics/vendor/plugins/structured_data/lib/auto_migrate.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/vendor/plugins/structured_data/lib/auto_migrate.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -1,4 +1,4 @@
-# myExperiment: vendor/plugins/structured_data/lib/auto_migrate.rb)
+# myExperiment: vendor/plugins/structured_data/lib/auto_migrate.rb
 #
 # Copyright (c) 2009 University of Manchester and the University of Southampton.
 # See license.txt for details.
@@ -7,12 +7,12 @@
 
 class AutoMigrate
 
-  AUTO_TABLE_NAME       = "auto_tables"
-  SCHEMA                = "config/base_schema.xml"
-  SCHEMA_D              = "config/schema.d"
-  COLUMN_ATTRIBUTES     = ['name', 'type', 'default']
+  AUTO_TABLE_NAME     = "auto_tables"
+  SCHEMA              = "config/base_schema.xml"
+  SCHEMA_D            = "config/schema.d"
+  COLUMN_ATTRIBUTES     = ['name', 'type', 'default', 'limit']
   BELONGS_TO_ATTRIBUTES = ['polymorphic', 'class_name', 'foreign_key']
-  HAS_MANY_ATTRIBUTES   = ['target', 'through', 'foreign_key', 'source', 'dependent', 'conditions', 'class_name']
+  HAS_MANY_ATTRIBUTES   = ['target', 'through', 'foreign_key', 'source', 'dependent', 'conditions', 'class_name', 'as']
 
   def self.schema
 
@@ -42,6 +42,19 @@
 
   def self.migrate
 
+    def self.column_default(column)
+      if column['default']
+        case column['type']
+        when 'boolean'
+          return false if column['default'] == 'false'
+          return true  if column['default'] == 'true'
+          raise "Default values for boolean types must be either 'true' or 'false'"
+        else
+          column['default'].to_s
+        end
+      end
+    end
+
     conn = ActiveRecord::Base.connection
 
     # ensure that the auto_tables table exists
@@ -104,9 +117,8 @@
       # add columns
 
       (new_columns - old_columns).each do |column_name|
-        default = new_tables[table_name][:columns][column_name]['default']
-        default = default.to_s unless default.nil?
-        conn.add_column(table_name, column_name, new_tables[table_name][:columns][column_name]["type"].to_sym, :default => default)
+        default = column_default(new_tables[table_name][:columns][column_name])
+        conn.add_column(table_name, column_name, new_tables[table_name][:columns][column_name]["type"].to_sym, :default => default, :limit => new_tables[table_name][:columns][column_name]['limit'])
       end
 
       # modify existing columns
@@ -114,7 +126,7 @@
       (old_columns & new_columns).each do |column_name|
 
         old_default = old_column_info[column_name].default
-        new_default = new_tables[table_name][:columns][column_name]['default']
+        new_default = column_default(new_tables[table_name][:columns][column_name])
 
         old_default = old_default.to_s unless old_default.nil?
         new_default = new_default.to_s unless new_default.nil?

Modified: branches/topics/vendor/plugins/structured_data/lib/structured_data.rb (2680 => 2681)


--- branches/topics/vendor/plugins/structured_data/lib/structured_data.rb	2011-08-24 08:44:27 UTC (rev 2680)
+++ branches/topics/vendor/plugins/structured_data/lib/structured_data.rb	2011-08-31 15:23:15 UTC (rev 2681)
@@ -28,6 +28,7 @@
           bits.push(":dependent => :#{association[:dependent]}") if association[:dependent]
           bits.push(":conditions => \"#{association[:conditions]}\"") if association[:conditions]
           bits.push(":class_name => \"#{association[:class_name]}\"") if association[:class_name]
+          bits.push(":as => :#{association[:as]}") if association[:as]
 
           line = "has_many #{bits.join(', ')}"
           self.class_eval(line)

reply via email to

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