From 97ee2e7bfcdb17fd195382b22a15f0f2752b8007 Mon Sep 17 00:00:00 2001 From: Tom Clegg Date: Thu, 13 Jun 2013 15:30:55 -0400 Subject: [PATCH] add tutorials and references to home page --- apps/workbench/Gemfile | 1 + apps/workbench/Gemfile.lock | 2 + .../app/controllers/application_controller.rb | 6 ++ .../app/controllers/users_controller.rb | 23 +++++- .../app/helpers/application_helper.rb | 5 ++ apps/workbench/app/models/arvados_base.rb | 3 + .../app/models/arvados_resource_list.rb | 6 ++ apps/workbench/app/models/user.rb | 7 ++ .../application/_arvados_object.html.erb | 16 ++++ .../app/views/application/show.html.erb | 24 ++++++ .../app/views/layouts/application.html.erb | 8 +- apps/workbench/app/views/users/home.html.erb | 79 ++++++++++++++++--- doc/install/index.md | 1 + .../arvados/v1/users_controller.rb | 4 + .../api/app/helpers/application_helper.rb | 24 +----- services/api/config/routes.rb | 1 + services/api/lib/current_api_client.rb | 29 +++++++ 17 files changed, 204 insertions(+), 35 deletions(-) diff --git a/apps/workbench/Gemfile b/apps/workbench/Gemfile index 1a516a5d71..dde019e7d9 100644 --- a/apps/workbench/Gemfile +++ b/apps/workbench/Gemfile @@ -50,3 +50,4 @@ gem 'rvm-capistrano', :group => :test gem 'passenger', :group => :production gem 'andand' +gem 'RedCloth' diff --git a/apps/workbench/Gemfile.lock b/apps/workbench/Gemfile.lock index a52b11956b..f1ec82a855 100644 --- a/apps/workbench/Gemfile.lock +++ b/apps/workbench/Gemfile.lock @@ -1,6 +1,7 @@ GEM remote: https://rubygems.org/ specs: + RedCloth (4.2.9) actionmailer (3.2.11) actionpack (= 3.2.11) mail (~> 2.4.4) @@ -151,6 +152,7 @@ PLATFORMS ruby DEPENDENCIES + RedCloth andand anjlab-bootstrap-rails (>= 2.2) bootstrap-editable-rails diff --git a/apps/workbench/app/controllers/application_controller.rb b/apps/workbench/app/controllers/application_controller.rb index 1cef3d947d..3cae2dcbd7 100644 --- a/apps/workbench/app/controllers/application_controller.rb +++ b/apps/workbench/app/controllers/application_controller.rb @@ -66,6 +66,12 @@ class ApplicationController < ActionController::Base end end + def render_content + if !@object + return render_not_found("object not found") + end + end + def new @object = model_class.new end diff --git a/apps/workbench/app/controllers/users_controller.rb b/apps/workbench/app/controllers/users_controller.rb index ef527a5591..62007ff1c7 100644 --- a/apps/workbench/app/controllers/users_controller.rb +++ b/apps/workbench/app/controllers/users_controller.rb @@ -10,8 +10,29 @@ class UsersController < ApplicationController end def home - @my_ssh_keys = AuthorizedKey.where(authorized_user: current_user.uuid) + @my_ssh_keys = AuthorizedKey.where(authorized_user_uuid: current_user.uuid) @my_vm_perms = Link.where(tail_uuid: current_user.uuid, head_kind: 'arvados#virtual_machine', link_class: 'permission', name: 'can_login') @my_repo_perms = Link.where(tail_uuid: current_user.uuid, head_kind: 'arvados#repository', link_class: 'permission', name: 'can_write') + @my_last_job = Job. + limit(1). + order(:created_at). + where(created_by: current_user.uuid). + last + + # A Tutorial is a Link which has link_class "resources" and name + # "wants", and is owned by the Tutorials Group (i.e., named + # "Arvados Tutorials" and owned by the system user). + @tutorial_group = Group.where(owner: User.system.uuid, + name: 'Arvados Tutorials').first + if @tutorial_group + @tutorial_links = Link.where(tail_uuid: @tutorial_group.uuid, + link_class: 'resources', + name: 'wants') + else + @tutorial_links = [] + end + @tutorial_complete = { + 'Run a job' => @my_last_job + } end end diff --git a/apps/workbench/app/helpers/application_helper.rb b/apps/workbench/app/helpers/application_helper.rb index 916e4b20db..78504655a8 100644 --- a/apps/workbench/app/helpers/application_helper.rb +++ b/apps/workbench/app/helpers/application_helper.rb @@ -2,6 +2,11 @@ module ApplicationHelper def current_user controller.current_user end + + def render_content_from_database(markup) + raw RedCloth.new(markup).to_html + end + def human_readable_bytes_html(n) return h(n) unless n.is_a? Fixnum raw = n.to_s diff --git a/apps/workbench/app/models/arvados_base.rb b/apps/workbench/app/models/arvados_base.rb index 267a4a9133..2aa91f735e 100644 --- a/apps/workbench/app/models/arvados_base.rb +++ b/apps/workbench/app/models/arvados_base.rb @@ -73,6 +73,9 @@ class ArvadosBase < ActiveRecord::Base end new.private_reload(uuid) end + def self.order(*args) + ArvadosResourceList.new(self).order(*args) + end def self.where(*args) ArvadosResourceList.new(self).where(*args) end diff --git a/apps/workbench/app/models/arvados_resource_list.rb b/apps/workbench/app/models/arvados_resource_list.rb index c8e6de6302..b1c1561787 100644 --- a/apps/workbench/app/models/arvados_resource_list.rb +++ b/apps/workbench/app/models/arvados_resource_list.rb @@ -15,6 +15,11 @@ class ArvadosResourceList self end + def order(orderby_spec) + @orderby_spec = orderby_spec + self + end + def where(cond) cond = cond.dup cond.keys.each do |uuid_key| @@ -46,6 +51,7 @@ class ArvadosResourceList } api_params[:eager] = '1' if @eager api_params[:limit] = @limit if @limit + api_params[:order] = @orderby_spec if @orderby_spec res = $arvados_api_client.api @resource_class, '', api_params @results = $arvados_api_client.unpack_api_response res self diff --git a/apps/workbench/app/models/user.rb b/apps/workbench/app/models/user.rb index 0dec2e0ba8..47b0af38a8 100644 --- a/apps/workbench/app/models/user.rb +++ b/apps/workbench/app/models/user.rb @@ -10,6 +10,13 @@ class User < ArvadosBase $arvados_api_client.unpack_api_response(res) end + def self.system + $arvados_system_user ||= begin + res = $arvados_api_client.api self, '/system' + $arvados_api_client.unpack_api_response(res) + end + end + def full_name (self.first_name || "") + " " + (self.last_name || "") end diff --git a/apps/workbench/app/views/application/_arvados_object.html.erb b/apps/workbench/app/views/application/_arvados_object.html.erb index 4f7570ea01..34f20b502f 100644 --- a/apps/workbench/app/views/application/_arvados_object.html.erb +++ b/apps/workbench/app/views/application/_arvados_object.html.erb @@ -1,3 +1,4 @@ +<% content_for :arvados_object_table do %> <%= form_for @object do |f| %> @@ -9,15 +10,30 @@
<% end %> +<% end %> + +<% if content_for? :page_content %> +<%= yield :page_content %> +<% else %> +<%= yield :arvados_object_table %> +<% end %>
+ <% if content_for? :page_content %> +
+ <%= yield :arvados_object_table %> +
+ <% end %>
 <%= JSON.pretty_generate(@object.attributes.reject { |k,v| k == 'id' }) rescue nil %>
diff --git a/apps/workbench/app/views/application/show.html.erb b/apps/workbench/app/views/application/show.html.erb
index 90790856ae..ad7e53c1fe 100644
--- a/apps/workbench/app/views/application/show.html.erb
+++ b/apps/workbench/app/views/application/show.html.erb
@@ -1 +1,25 @@
+<% if @object.respond_to? :properties %>
+
+<% content_for :page_title do %>
+<%= @object.properties[:page_title] || @object.uuid %>
+<% end %>
+
+<% if @object.properties[:page_content] %>
+<% content_for :page_content do %>
+

+<%= render_content_from_database(@object.properties[:page_title] || @object.uuid) %> +

+ +<% if @object.properties[:page_subtitle] %> +

+<%= render_content_from_database @object.properties[:page_subtitle] %> +

+<% end %> + +<%= render_content_from_database @object.properties[:page_content] %> +<% end %> +<% end %> +<% end %> + + <%= render :partial => 'application/arvados_object' %> diff --git a/apps/workbench/app/views/layouts/application.html.erb b/apps/workbench/app/views/layouts/application.html.erb index 747f1d6fb2..56ac2cbacb 100644 --- a/apps/workbench/app/views/layouts/application.html.erb +++ b/apps/workbench/app/views/layouts/application.html.erb @@ -2,7 +2,13 @@ - <%= Rails.configuration.site_name rescue Rails.application.class.parent_name %> + + <% if content_for? :page_title %> + <%= yield :page_title %> + <% else %> + <%= Rails.configuration.site_name rescue Rails.application.class.parent_name %> + <% end %> + diff --git a/apps/workbench/app/views/users/home.html.erb b/apps/workbench/app/views/users/home.html.erb index 2a69b06804..6f52694070 100644 --- a/apps/workbench/app/views/users/home.html.erb +++ b/apps/workbench/app/views/users/home.html.erb @@ -1,7 +1,56 @@ +<% if @tutorial_links.any? %> +<% content_for :tutorials do %> +

Tutorials

+<% @tutorial_links.each do |tut| %> +
+
+ <%= tut.properties[:page_title] %> + <% if @tutorial_complete[tut.properties[:page_title]] %> + + <% else %> + + <% end %> +
+ <%= render_content_from_database tut.properties[:page_subtitle] %> +
+ <%= link_to raw('Tutorial: ' + tut.properties[:page_title] + ' ➜'), link_path(tut.uuid), class: "pull-right btn btn-primary" %> +
+<% end %> +<% end %> +<% end %> + +<% content_for :references do %> +

References

+
+
+ API Reference +
+ API calls for running jobs, building pipelines, and developing apps. +
+ <%= link_to raw('API Reference ➜'), 'http://doc.arvados.org/api/', class: "pull-right btn" %> +
+
+
+ User Guide +
+ Getting acquainted with the Arvados platform. +
+ <%= link_to raw('User Guide ➜'), 'http://doc.arvados.org/user/', class: "pull-right btn" %> +
+
+
+ arvados.org +
+ Project home page: developer docs, source code, background. +
+ <%= link_to raw('arvados.org ➜'), 'https://arvados.org/', class: "pull-right btn" %> +
+<% end %> +

Setup

-
+
SSH keys <%= @my_ssh_keys.count %> @@ -9,9 +58,9 @@ You’ll use public key authentication when logging in to a VM or use a hosted git repository.
- <%= link_to raw('Add/edit keys ➜'), authorized_keys_path, class: "btn #{'btn-primary' if @my_ssh_keys.empty?}" %> + <%= link_to raw('Add/edit keys ➜'), authorized_keys_path, class: "pull-right btn #{'btn-primary' if @my_ssh_keys.empty?}" %>
-
+
Virtual machines <%= @my_vm_perms.collect(&:head_uuid).uniq.count %> @@ -19,14 +68,14 @@ Arvados includes virtual machines with SDKs installed and ready to use.
<% if @my_vm_perms.any? %> - <%= link_to raw('Show VMs ➜'), virtual_machines_path, class: "btn" %> + <%= link_to raw('Show VMs ➜'), virtual_machines_path, class: "pull-right btn" %> <% elsif @my_ssh_keys.any? %> - <%= link_to raw('Request a VM ➜'), virtual_machines_path, class: "btn btn-primary" %> + <%= link_to raw('Request a VM ➜'), virtual_machines_path, class: "pull-right btn btn-primary" %> <% else %> - <%= link_to raw('Request a VM ➜'), virtual_machines_path, { :class => "btn disabled", :"data-toggle" => "tooltip", :"data-placement" => "bottom", :title => "Add an SSH public key first!" } %> + <%= link_to raw('Request a VM ➜'), virtual_machines_path, { :class => "pull-right btn disabled", :"data-toggle" => "tooltip", :"data-placement" => "bottom", :title => "Add an SSH public key first!" } %> <% end %>
-
+
Git repositories <%= @my_repo_perms.collect(&:head_uuid).uniq.count %> @@ -34,12 +83,22 @@ In order to run jobs using your own code, you need to push your code to a git repository. We provide hosted git repositories to make this easy.
<% if @my_repo_perms.any? %> - <%= link_to raw('Show repositories ➜'), repositories_path, class: "btn" %> + <%= link_to raw('Show repositories ➜'), repositories_path, class: "pull-right btn" %> <% elsif @my_ssh_keys.any? %> - <%= link_to raw('Request a repository ➜'), repositories_path, class: "btn btn-primary" %> + <%= link_to raw('Request a repository ➜'), repositories_path, class: "pull-right btn btn-primary" %> <% else %> - <%= link_to raw('Request a repository ➜'), repositories_path, { :class => "btn disabled", :"data-toggle" => "tooltip", :"data-placement" => "bottom", :title => "Add an SSH public key first!" } %> + <%= link_to raw('Request a repository ➜'), repositories_path, { :class => "pull-right btn disabled", :"data-toggle" => "tooltip", :"data-placement" => "bottom", :title => "Add an SSH public key first!" } %> <% end %>
+ + <% if content_for? :tutorials %> +
+ <%= yield :tutorials %> +
+ <% end %> + +
+ <%= yield :references %> +
diff --git a/doc/install/index.md b/doc/install/index.md index ea7dca8a1e..95edd74d73 100644 --- a/doc/install/index.md +++ b/doc/install/index.md @@ -14,3 +14,4 @@ navorder: 0 1. [Install the Arvados REST API server](install-api-server.html) 1. [Install the Arvados workbench application](install-workbench-app.html) 1. Set up the Job manager +1. Create a Group named "Arvados Tutorials", owned by the system user. Create Links (link_class "resources", name "wants") from the tutorials group to sample data collections. Edit page_content, page_title, and page_subtitle properties to suit. These will be listed in the Tutorials section of your users' home pages. diff --git a/services/api/app/controllers/arvados/v1/users_controller.rb b/services/api/app/controllers/arvados/v1/users_controller.rb index b6266f7047..d8f6a98f42 100644 --- a/services/api/app/controllers/arvados/v1/users_controller.rb +++ b/services/api/app/controllers/arvados/v1/users_controller.rb @@ -3,4 +3,8 @@ class Arvados::V1::UsersController < ApplicationController @object = current_user show end + def system + @object = system_user + show + end end diff --git a/services/api/app/helpers/application_helper.rb b/services/api/app/helpers/application_helper.rb index 385477562d..c5999b3714 100644 --- a/services/api/app/helpers/application_helper.rb +++ b/services/api/app/helpers/application_helper.rb @@ -1,25 +1,3 @@ module ApplicationHelper - def current_user - controller.current_user - end - - def act_as_system_user - if not $system_user - Thread.current[:user] = User.new(is_admin: true) - sysuser_id = [Server::Application.config.uuid_prefix, - User.uuid_prefix, - '000000000000000'].join('-') - $system_user = User.where('uuid=?', sysuser_id).first - if !$system_user - $system_user = User.new(uuid: sysuser_id, - is_admin: true, - email: 'root', - first_name: 'root', - last_name: '') - $system_user.save! - $system_user.reload - end - end - Thread.current[:user] = $system_user - end + include CurrentApiClient end diff --git a/services/api/config/routes.rb b/services/api/config/routes.rb index 4ab7b60fd6..398645462a 100644 --- a/services/api/config/routes.rb +++ b/services/api/config/routes.rb @@ -82,6 +82,7 @@ Server::Application.routes.draw do match '/keep_disks/ping' => 'keep_disks#ping', :as => :ping_keep_disk match '/links/from/:tail_uuid' => 'links#index', :as => :arvados_v1_links_from match '/users/current' => 'users#current' + match '/users/system' => 'users#system' match '/jobs/queue' => 'jobs#queue' match '/virtual_machines/get_all_logins' => 'virtual_machines#get_all_logins' match '/repositories/get_all_permissions' => 'repositories#get_all_permissions' diff --git a/services/api/lib/current_api_client.rb b/services/api/lib/current_api_client.rb index 24d8b3ada9..ab6d624ea5 100644 --- a/services/api/lib/current_api_client.rb +++ b/services/api/lib/current_api_client.rb @@ -30,4 +30,33 @@ module CurrentApiClient def current_api_client_trusted Thread.current[:api_client_trusted] end + + def system_user_uuid + [Server::Application.config.uuid_prefix, + User.uuid_prefix, + '000000000000000'].join('-') + end + + def system_user + if not $system_user + real_current_user = Thread.current[:user] + Thread.current[:user] = User.new(is_admin: true) + $system_user = User.where('uuid=?', system_user_uuid).first + if !$system_user + $system_user = User.new(uuid: system_user_uuid, + is_admin: true, + email: 'root', + first_name: 'root', + last_name: '') + $system_user.save! + $system_user.reload + end + Thread.current[:user] = real_current_user + end + $system_user + end + + def act_as_system_user + Thread.current[:user] = system_user + end end -- 2.30.2