Folderized homework submissions for Google Drive.
Fixes PLAT-912 Fixes PLAT-915 Fixes PLAT-916 Fixes PLAT-922 Test Plan: - Go to submit an assignment. - Test plan for Authorization in Popup Modal: - Make sure Google Drive service is inactive - Go to Google Drive tab and make sure it asks for authorization - Make sure when “Authorize” button is clicked, Google’s OAuth opens in modal - After authorized, make sure the panel reloads with the correct content. - Test plan for folderifying documents: - Make sure Google Drive submissions displays the correct folders and icons - Test plan for preview fix: - Make sure when you go to preview an assignment for Google Docs, it launches the correct url. - Test plan for submissions: - Make sure you can submit assignments via Google Drive - Test plan for UI/UX: - Make sure anything that uses _inst_tree.sass looks correct Change-Id: Iba790947cefac1420d8d3261865a52f82484a0ef Reviewed-on: https://gerrit.instructure.com/48981 Tested-by: Jenkins Reviewed-by: Brad Horrocks <bhorrocks@instructure.com> Reviewed-by: Brad Humphrey <brad@instructure.com> QA-Review: Derek Hansen <dhansen@instructure.com> Product-Review: Brad Horrocks <bhorrocks@instructure.com>
This commit is contained in:
parent
ec96119429
commit
fda594ba10
|
@ -132,12 +132,13 @@ class AssignmentsController < ApplicationController
|
|||
google_docs = google_service_connection
|
||||
@google_service = google_docs.service_type
|
||||
@google_docs_token = google_docs.retrieve_access_token
|
||||
@google_drive_upgrade = logged_in_user && Canvas::Plugin.find(:google_drive).try(:settings) &&
|
||||
(!logged_in_user.user_services.where(service: 'google_drive').first || !(google_drive_connection.verify_access_token rescue false))
|
||||
rescue GoogleDocs::NoTokenError
|
||||
#do nothing
|
||||
# Just fail I guess.
|
||||
end
|
||||
|
||||
@google_drive_upgrade = !!(logged_in_user && Canvas::Plugin.find(:google_drive).try(:settings) &&
|
||||
(!logged_in_user.user_services.where(service: 'google_drive').first || !(google_docs.verify_access_token rescue false)))
|
||||
|
||||
|
||||
add_crumb(@assignment.title, polymorphic_url([@context, @assignment]))
|
||||
log_asset_access(@assignment, "assignments", @assignment.assignment_group)
|
||||
|
|
|
@ -21,6 +21,7 @@ ul.instTree
|
|||
position: relative
|
||||
border-radius: 3px
|
||||
background: 13px top no-repeat
|
||||
background-size: 16px 16px
|
||||
|
||||
&.separator
|
||||
min-height: 2px
|
||||
|
@ -28,17 +29,18 @@ ul.instTree
|
|||
font-size: 2px
|
||||
|
||||
&.node
|
||||
background-image: url(/images/inst_tree/folder.png)
|
||||
background-image: image-url("mimeClassIcons/folder.svg")
|
||||
|
||||
&.collaborations
|
||||
background-image: url(/images/collaboration_folder.png)
|
||||
background-image: image-url('collaboration_folder.png')
|
||||
|
||||
&.groups
|
||||
background-image: url(/images/groups_folder.png)
|
||||
background-image: image-url('groups_folder.png')
|
||||
|
||||
// &.open
|
||||
&.leaf
|
||||
background-image: url(/images/inst_tree/file_types/page_white.png)
|
||||
background-image: image-url('mimeClassIcons/file.svg')
|
||||
|
||||
|
||||
&:hover
|
||||
background-color: #eee
|
||||
|
@ -73,10 +75,10 @@ ul.instTree
|
|||
top: 0
|
||||
|
||||
&.plus
|
||||
background: url(/images/inst_tree/plus.gif) 5px 50% no-repeat
|
||||
background: image-url('inst_tree/plus.gif') 5px 50% no-repeat
|
||||
|
||||
&.minus
|
||||
background: url(/images/inst_tree/minus.gif) 5px 50% no-repeat
|
||||
background: image-url('inst_tree/minus.gif') 5px 50% no-repeat
|
||||
|
||||
input
|
||||
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif
|
||||
|
@ -87,57 +89,57 @@ ul.instTree
|
|||
|
||||
|
||||
#instTree-drag
|
||||
padding: 3px
|
||||
padding-left: 30px
|
||||
padding: 3px 3px 3px 30px
|
||||
z-index: 1000
|
||||
position: absolute
|
||||
|
||||
&.node
|
||||
background: #C3E1FF url(/images/inst_tree/node-drag.gif) left 3px no-repeat
|
||||
background: #C3E1FF image-url('inst_tree/node-drag.gif') left 3px no-repeat
|
||||
|
||||
&.leaf
|
||||
background: #C3E1FF url(/images/inst_tree/leaf-drag.gif) left 3px no-repeat
|
||||
background: #C3E1FF image-url('inst_tree/leaf-drag.gif') left 3px no-repeat
|
||||
|
||||
|
||||
ul.instTree
|
||||
li.separator.dd-hover
|
||||
background: transparent url(/images/inst_tree/separator-drag.gif) 3px 1px no-repeat
|
||||
background: transparent image-url('inst_tree/separator-drag.gif') 3px 1px no-repeat
|
||||
|
||||
.dd-hover
|
||||
background-color: yellow
|
||||
li.leaf
|
||||
&.dd-hover
|
||||
background-color: yellow
|
||||
|
||||
.pdf
|
||||
background-image: url('/images/inst_tree/file_types/page_white_acrobat.png') !important
|
||||
&.pdf
|
||||
background-image: image-url('mimeClassIcons/pdf.svg')
|
||||
|
||||
.image
|
||||
background-image: url('/images/inst_tree/file_types/page_white_picture.png') !important
|
||||
&.image, &.jpeg, &.jpg, &.png, &.svg
|
||||
background-image: image-url('mimeClassIcons/image.svg')
|
||||
|
||||
.xls
|
||||
background-image: url('/images/inst_tree/file_types/page_white_excel.png') !important
|
||||
&.xls, &.xlsx, &.spreadsheet
|
||||
background-image: image-url('mimeClassIcons/xls.svg')
|
||||
|
||||
.word, .doc
|
||||
background-image: url('/images/inst_tree/file_types/page_white_word.png') !important
|
||||
&.word, &.doc, &.docx
|
||||
background-image: image-url('mimeClassIcons/doc.svg')
|
||||
|
||||
.ppt
|
||||
background-image: url('/images/inst_tree/file_types/page_white_powerpoint.png') !important
|
||||
&.ppt, &.pptx
|
||||
background-image: image-url('mimeClassIcons/ppt.svg')
|
||||
|
||||
.zip
|
||||
background-image: url('/images/inst_tree/file_types/page_white_zip.png') !important
|
||||
&.audio
|
||||
background-image: image-url('mimeClassIcons/audio.svg')
|
||||
|
||||
.video
|
||||
background-image: url('/images/inst_tree/file_types/page_white_camera.png') !important
|
||||
&.zip
|
||||
background-image: image-url('mimeClassIcons/zip.svg')
|
||||
|
||||
.html
|
||||
background-image: url('/images/inst_tree/file_types/page_white_world.png') !important
|
||||
&.video
|
||||
background-image: image-url('mimeClassIcons/video.svg')
|
||||
|
||||
.spreadsheet
|
||||
background-image: url('/images/inst_tree/file_types/page_white_excel.png') !important
|
||||
&.html
|
||||
background-image: image-url('mimeClassIcons/html.svg')
|
||||
|
||||
.google_docs
|
||||
background-image: url('/images/google_docs_icon.ico') !important
|
||||
&.google_docs
|
||||
background-image: image-url('google_docs_icon.ico')
|
||||
|
||||
.etherpad
|
||||
background-image: url('/images/etherpad_icon.ico') !important
|
||||
&.etherpad
|
||||
background-image: image-url('etherpad_icon.ico')
|
||||
|
||||
.loading
|
||||
background-image: url('/images/ajax-loader-small.gif') !important
|
||||
&.loading
|
||||
background-image: image-url('ajax-loader-small.gif')
|
|
@ -44,6 +44,16 @@
|
|||
|
||||
&.service-hover .delete_service_link {
|
||||
display: inline;
|
||||
|
||||
img {
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +65,8 @@
|
|||
|
||||
img {
|
||||
vertical-align: middle;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -201,88 +201,90 @@
|
|||
#google_docs_tree li.file .popout {
|
||||
float: right;
|
||||
}
|
||||
.google_doc_form.hide {
|
||||
display:none !important;
|
||||
}
|
||||
</style>
|
||||
<% if show_google_docs %>
|
||||
<% if @google_docs_token and not @google_drive_upgrade%>
|
||||
<% if @domain_root_account.feature_enabled?(:google_docs_domain_restriction) &&
|
||||
@domain_root_account.settings[:google_docs_domain] &&
|
||||
!@current_user.gmail.match(%r{@#{@domain_root_account.settings[:google_docs_domain]}$}) %>
|
||||
<div id="submit_google_doc_form">
|
||||
<p class="alert alert-error">
|
||||
<i class="icon-warning"></i>
|
||||
<%= t(:invalid_google_docs_domain, 'Invalid domain') %>
|
||||
</p>
|
||||
<% if @domain_root_account.feature_enabled?(:google_docs_domain_restriction) &&
|
||||
@domain_root_account.settings[:google_docs_domain] &&
|
||||
!@current_user.gmail.match(%r{@#{@domain_root_account.settings[:google_docs_domain]}$}) %>
|
||||
<div id="submit_google_doc_form" class="google_doc_form <%= @google_docs_token ? '' : 'hide' %>">
|
||||
<p class="alert alert-error">
|
||||
<i class="icon-warning"></i>
|
||||
<%= t(:invalid_google_docs_domain, 'Invalid domain') %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%= t(:gmail_restriction_description, <<-END, domain: @domain_root_account.settings[:google_docs_domain])
|
||||
Your account has restricted Google Doc submissions to Google accounts
|
||||
on the %{domain} domain. To submit this assignment with a Google Doc,
|
||||
you will need to reconfigure the Google Docs integration on your
|
||||
user settings page.
|
||||
END
|
||||
%>
|
||||
</p>
|
||||
</div>
|
||||
<% else %>
|
||||
<%= form_tag(context_url(@context, :controller => :submissions, :assignment_id => @assignment.id, :action => :create), {:id => "submit_google_doc_form", :class => "submit_assignment_form"}) do %>
|
||||
<%= hidden_field :submission, :submission_type, :value => "google_doc" %>
|
||||
<%= hidden_field :google_doc, :document_id, :value => "", :class => "google_doc_id" %>
|
||||
<table class="formtable" style="width: 100%;">
|
||||
<tr>
|
||||
<td style="padding-bottom: 10px;" colspan="2">
|
||||
<%= t 'instructions.google_docs', "Select the file from the list below." %>
|
||||
<%= render :partial => "assignments/group_submission_reminder" if @assignment.has_group_category? %>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td colspan="2">
|
||||
<div id="google_docs_container" style="height: 200px; overflow: auto;">
|
||||
<div style="text-align: center; margin: 10px;">
|
||||
<%= image_tag "ajax-loader-bar.gif" %>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td colspan="2" style="text-align: center;">
|
||||
<div style="text-align: left;">
|
||||
<%= text_area :submission, :comment, :class => 'submission_comment_textarea', :placeholder => t('comments_placeholder', 'Comments...'), :title => t('additional_comments', 'Additional comments') %>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<%= render :partial => "group_comment" %>
|
||||
<% if @assignment.turnitin_enabled? %>
|
||||
<%= render :partial => "turnitin" %>
|
||||
<% end %>
|
||||
<tr>
|
||||
<td colspan="2" class='button-container'>
|
||||
<button type="button" class='cancel_button btn'><%= t '#buttons.cancel', "Cancel" %></button>
|
||||
<button type="submit" class="btn btn-primary"><%= t 'buttons.submit_assignment', "Submit Assignment" %></button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div id="uploading_google_doc_message" style="display: none;">
|
||||
<%= t 'messages.uploading', "Retrieving a copy of your Google Doc to submit for this assignment. This may take a little while, depending on the size of the file..." %>
|
||||
<div style="text-align: center; margin: 10px;">
|
||||
<%= image_tag "ajax-loader-bar.gif" %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% elsif @google_drive_upgrade %>
|
||||
<div id="submit_google_doc_form">
|
||||
<%= t 'messages.google_drives_auth_required', "Before you can submit assignments directly from Google Drive you need to authorize Canvas to access your Google Drive account:" %>
|
||||
<div style="font-size: 1.1em; text-align: center; margin: 10px;">
|
||||
<a class="btn" href="<%= oauth_url(:service => :google_drive, :return_to => (request.url + "#submit_google_doc_form")) %>"><%= t 'links.authorize_google_drive', "Authorize Google Drive Access" %></a>
|
||||
</div>
|
||||
<p>
|
||||
<%= t(:gmail_restriction_description, <<-END, domain: @domain_root_account.settings[:google_docs_domain])
|
||||
Your account has restricted Google Doc submissions to Google accounts
|
||||
on the %{domain} domain. To submit this assignment with a Google Doc,
|
||||
you will need to reconfigure the Google Docs integration on your
|
||||
user settings page.
|
||||
END
|
||||
%>
|
||||
</p>
|
||||
</div>
|
||||
<% else %>
|
||||
<div id="submit_google_doc_form">
|
||||
<%= t 'messages.google_docs_auth_required', "Before you can submit assignments directly from Google Docs you need to authorize Canvas to access your Google Docs account:" %>
|
||||
<div style="font-size: 1.1em; text-align: center; margin: 10px;">
|
||||
<a class="btn" href="<%= oauth_url(:service => :google_docs, :return_to => (request.url + "#submit_google_doc_form")) %>"><%= t 'links.authorize_google_docs', "Authorize Google Docs Access" %></a>
|
||||
<% else %>
|
||||
<%= form_tag(context_url(@context, :controller => :submissions, :assignment_id => @assignment.id, :action => :create), { :id => "submit_google_doc_form", :class => "submit_assignment_form google_doc_form #{@google_docs_token ? '' : 'hide'}"}) do %>
|
||||
<%= hidden_field :submission, :submission_type, :value => "google_doc" %>
|
||||
<%= hidden_field :google_doc, :document_id, :value => "", :class => "google_doc_id" %>
|
||||
<table class="formtable" style="width: 100%;">
|
||||
<tr>
|
||||
<td style="padding-bottom: 10px;" colspan="2">
|
||||
<%= t 'instructions.google_docs', "Select the file from the list below." %>
|
||||
<%= render :partial => "assignments/group_submission_reminder" if @assignment.has_group_category? %>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td colspan="2">
|
||||
<div id="google_docs_container" style="height: 200px; overflow: auto;">
|
||||
<div style="text-align: center; margin: 10px;">
|
||||
<%= image_tag "ajax-loader-bar.gif" %>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr><tr>
|
||||
<td colspan="2" style="text-align: center;">
|
||||
<div style="text-align: left;">
|
||||
<%= text_area :submission, :comment, :class => 'submission_comment_textarea', :placeholder => t('comments_placeholder', 'Comments...'), :title => t('additional_comments', 'Additional comments') %>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<%= render :partial => "group_comment" %>
|
||||
<% if @assignment.turnitin_enabled? %>
|
||||
<%= render :partial => "turnitin" %>
|
||||
<% end %>
|
||||
<tr>
|
||||
<td colspan="2" class='button-container'>
|
||||
<button type="button" class='cancel_button btn'><%= t '#buttons.cancel', "Cancel" %></button>
|
||||
<button type="submit" class="btn btn-primary"><%= t 'buttons.submit_assignment', "Submit Assignment" %></button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div id="uploading_google_doc_message" style="display: none;">
|
||||
<%= t 'messages.uploading', "Retrieving a copy of your Google Doc to submit for this assignment. This may take a little while, depending on the size of the file..." %>
|
||||
<div style="text-align: center; margin: 10px;">
|
||||
<%= image_tag "ajax-loader-bar.gif" %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if @google_drive_upgrade %>
|
||||
<div id="submit_google_doc_form" class="google_doc_form auth <%= @google_docs_token ? 'hide' : '' %>">
|
||||
<%= t 'messages.google_drives_auth_required', "Before you can submit assignments directly from Google Drive you need to authorize Canvas to access your Google Drive account:" %>
|
||||
<div style="font-size: 1.1em; text-align: center; margin: 10px;">
|
||||
<a class="btn" id="auth-google" href="<%= oauth_url(:service => :google_drive, :return_to => (request.url + "#submit_google_doc_form")) %>"><%= t 'links.authorize_google_drive', "Authorize Google Drive Access" %></a>
|
||||
</div>
|
||||
</div>
|
||||
<% else %>
|
||||
<div id="submit_google_doc_form" class="google_doc_form auth <%= @google_docs_token ? 'hide' : '' %>">
|
||||
<%= t 'messages.google_docs_auth_required', "Before you can submit assignments directly from Google Docs you need to authorize Canvas to access your Google Docs account:" %>
|
||||
<div style="font-size: 1.1em; text-align: center; margin: 10px;">
|
||||
<a class="btn" id="auth-google" href="<%= oauth_url(:service => :google_docs, :return_to => (request.url + "#submit_google_doc_form")) %>"><%= t 'links.authorize_google_docs', "Authorize Google Docs Access" %></a>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% if @assignment.submission_types && @assignment.submission_types.match(/media_recording/) %>
|
||||
<% if !feature_enabled?(:kaltura) %>
|
||||
|
|
|
@ -5,6 +5,8 @@ require 'uri'
|
|||
module GoogleDocs
|
||||
require "google_docs/connection"
|
||||
require "google_docs/drive_connection"
|
||||
require "google_docs/drive_entry"
|
||||
require "google_docs/drive_folder"
|
||||
require "google_docs/entry"
|
||||
require "google_docs/folder"
|
||||
require "google_docs/no_token_error"
|
||||
|
|
|
@ -33,7 +33,7 @@ module GoogleDocs
|
|||
end
|
||||
|
||||
def service_type
|
||||
:google_drive
|
||||
'google_drive'
|
||||
end
|
||||
|
||||
def download(document_id)
|
||||
|
@ -43,7 +43,7 @@ module GoogleDocs
|
|||
)
|
||||
|
||||
file = response.data
|
||||
file_info = get_file_info(file)
|
||||
file_info = GoogleDocs::DriveEntry.get_file_data(file)
|
||||
result = api_client.execute(:uri => file_info[:url])
|
||||
if result.status == 200
|
||||
|
||||
|
@ -139,7 +139,7 @@ module GoogleDocs
|
|||
|
||||
def verify_access_token
|
||||
api_client.authorization.update_token!
|
||||
return api_client.execute(:api_method => drive.about.get).status == 200
|
||||
api_client.execute(:api_method => drive.about.get).status == 200
|
||||
end
|
||||
|
||||
def self.config_check(settings)
|
||||
|
@ -158,26 +158,40 @@ module GoogleDocs
|
|||
end
|
||||
|
||||
private
|
||||
def list(extensions)
|
||||
documents = api_client.execute!(:api_method => drive.files.list).data.to_hash
|
||||
{
|
||||
:name => '/',
|
||||
:folders => [],
|
||||
:files => documents['items'].map do |doc|
|
||||
doc_info = get_file_info(doc)
|
||||
|
||||
if extensions.include?(doc_info[:ext])
|
||||
{
|
||||
:name => doc['title'],
|
||||
:document_id => doc['id'],
|
||||
:extension => doc_info[:ext],
|
||||
:alternate_url => {
|
||||
:href => doc_info[:url]
|
||||
}
|
||||
}
|
||||
end
|
||||
end.compact!
|
||||
}
|
||||
def list(extensions)
|
||||
folderize_list(api_client.execute!(:api_method => drive.files.list, :parameters => {:maxResults => 0}).data.to_hash, extensions)
|
||||
end
|
||||
|
||||
|
||||
def folderize_list(documents, extensions)
|
||||
root = GoogleDocs::DriveFolder.new('/')
|
||||
folders = {nil => root}
|
||||
|
||||
documents['items'].each do |doc_entry|
|
||||
entry = GoogleDocs::DriveEntry.new(doc_entry)
|
||||
if folders.has_key?(entry.folder)
|
||||
folder = folders[entry.folder]
|
||||
else
|
||||
folder = GoogleDocs::DriveFolder.new(get_folder_name_by_id(documents['items'], entry.folder))
|
||||
root.add_folder folder
|
||||
folders[entry.folder] = folder
|
||||
end
|
||||
folder.add_file(entry) unless doc_entry['mimeType'] && doc_entry['mimeType'] == 'application/vnd.google-apps.folder'
|
||||
end
|
||||
|
||||
if extensions && extensions.length > 0
|
||||
root.select { |e| extensions.include?(e.extension) }
|
||||
else
|
||||
root
|
||||
end
|
||||
end
|
||||
|
||||
def get_folder_name_by_id(entries, folder_id)
|
||||
elements = entries.select do |entry|
|
||||
entry['id'] == folder_id
|
||||
end
|
||||
elements.first ? elements.first['title'] : 'Unknown Folder'
|
||||
end
|
||||
|
||||
def api_client
|
||||
|
@ -189,26 +203,6 @@ module GoogleDocs
|
|||
api_client.discovered_api('drive', 'v2')
|
||||
end
|
||||
|
||||
def get_file_info(file)
|
||||
file_ext = {
|
||||
".docx" => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
".xlsx" => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
".pdf" => 'application/pdf',
|
||||
}
|
||||
|
||||
e = file_ext.find {|extension, mime_type| file['exportLinks'] && file['exportLinks'][mime_type] }
|
||||
if e.present?
|
||||
{
|
||||
url: file['exportLinks'][e.last],
|
||||
ext: e.first
|
||||
}
|
||||
else
|
||||
{
|
||||
url: file['downloadUrl'],
|
||||
ext: ".none"
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
#
|
||||
# Copyright (C) 2011 Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
module GoogleDocs
|
||||
class DriveEntry
|
||||
|
||||
attr_reader :document_id, :folder, :entry
|
||||
|
||||
def initialize(google_drive_entry)
|
||||
@entry = google_drive_entry
|
||||
@document_id = @entry['id']
|
||||
parent = @entry['parents'].length > 0 ? @entry['parents'][0] : nil
|
||||
@folder = (parent == nil || parent['isRoot'] ? nil : parent['id'])
|
||||
end
|
||||
|
||||
def alternate_url
|
||||
@entry['alternateLink'] || 'http://docs.google.com'
|
||||
end
|
||||
|
||||
def edit_url
|
||||
alternate_url rescue "https://docs.google.com/document/d/#{@document_id}/edit?usp=drivesdk"
|
||||
end
|
||||
|
||||
|
||||
def self.get_file_data(file)
|
||||
|
||||
# Order is important.
|
||||
|
||||
file_ext = {
|
||||
#documents
|
||||
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'doc' => 'application/vnd.oasis.opendocument.text',
|
||||
|
||||
#presentations
|
||||
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||
|
||||
#sheets
|
||||
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'xls' => 'application/x-vnd.oasis.opendocument.spreadsheet',
|
||||
|
||||
#PDF
|
||||
'pdf' => 'application/pdf',
|
||||
|
||||
#zip
|
||||
'zip' => 'application/zip',
|
||||
}
|
||||
|
||||
e = file_ext.find do |extension, mime_type|
|
||||
|
||||
(file['exportLinks'] && file['exportLinks'][mime_type]) ||
|
||||
(file['downloadUrl'] && mime_type.match(file['mimeType']))
|
||||
|
||||
end
|
||||
if e.present?
|
||||
{
|
||||
url: (file['exportLinks'] && file['exportLinks'][e.last]) || file['downloadUrl'],
|
||||
ext: e.first
|
||||
}
|
||||
else
|
||||
{
|
||||
url: file['downloadUrl'],
|
||||
ext: 'none'
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def extension
|
||||
GoogleDocs::DriveEntry.get_file_data(@entry)[:ext]
|
||||
end
|
||||
|
||||
def display_name
|
||||
@entry['title'] || "google_doc.#{extension}"
|
||||
end
|
||||
|
||||
def download_url
|
||||
GoogleDocs::DriveEntry.get_file_data(@entry)[:url]
|
||||
end
|
||||
|
||||
def to_hash
|
||||
{
|
||||
:name => display_name,
|
||||
:document_id => @document_id,
|
||||
:extension => extension,
|
||||
:alternate_url => {:href => alternate_url}
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,41 @@
|
|||
module GoogleDocs
|
||||
class DriveFolder
|
||||
attr_reader :name, :folders, :files
|
||||
|
||||
def initialize(name, folders=[], files=[])
|
||||
@name = name
|
||||
@folders, @files = folders, files
|
||||
end
|
||||
|
||||
def add_file(file)
|
||||
@files << file
|
||||
end
|
||||
|
||||
def add_folder(folder)
|
||||
@folders << folder
|
||||
end
|
||||
|
||||
def select(&block)
|
||||
DriveFolder.new(@name,
|
||||
@folders.map { |f| f.select(&block) }.select { |f| !f.files.empty? },
|
||||
@files.select(&block))
|
||||
end
|
||||
|
||||
def map(&block)
|
||||
@folders.map { |f| f.map(&block) }.flatten +
|
||||
@files.map(&block)
|
||||
end
|
||||
|
||||
def flatten
|
||||
@folders.flatten + @files
|
||||
end
|
||||
|
||||
def to_hash
|
||||
{
|
||||
:name => @name,
|
||||
:folders => @folders.map { |sf| sf.to_hash },
|
||||
:files => @files.map { |f| f.to_hash }
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
|
@ -159,7 +159,7 @@ define([
|
|||
if(hash && hash.indexOf("#submit") == 0) {
|
||||
$(".submit_assignment_link").triggerHandler('click', true);
|
||||
if(hash == "#submit_google_doc") {
|
||||
$("#submit_assignment_tabs").tabs('select', "#submit_google_doc_form");
|
||||
$("#submit_assignment_tabs").tabs('select', ".google_doc_form");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -280,6 +280,53 @@ define([
|
|||
listGoogleDocs();
|
||||
}
|
||||
|
||||
$("#auth-google").live('click', function(e){
|
||||
e.preventDefault();
|
||||
var href = $(this).attr("href");
|
||||
reauth(href);
|
||||
});
|
||||
|
||||
// Yay for IE!
|
||||
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
|
||||
var eventHandler = window[eventMethod];
|
||||
var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
|
||||
|
||||
|
||||
// Post message for anybody to listen to //
|
||||
if (window.opener)
|
||||
window.opener.postMessage({
|
||||
type: "event",
|
||||
payload: "done"
|
||||
}, window.location.origin);
|
||||
|
||||
|
||||
function reauth(auth_url) {
|
||||
var modal;
|
||||
|
||||
if(window.showModalDialog) {
|
||||
modal = window.showModalDialog(auth_url, "Authorize Google Docs");
|
||||
} else {
|
||||
modal = window.open(auth_url, "Authorize Google Docs", 'menubar=no;directories=no;location=no;modal=yes');
|
||||
}
|
||||
|
||||
eventHandler(messageEvent, function(event) {
|
||||
if(!event || !event.data || event.origin !== window.location.origin) return;
|
||||
|
||||
if(event.data.type == "event" && event.data.payload == "done") {
|
||||
if (modal)
|
||||
modal.close();
|
||||
reloadGoogleDrive();
|
||||
}
|
||||
}, false);
|
||||
|
||||
}
|
||||
|
||||
function reloadGoogleDrive() {
|
||||
$("#submit_google_doc_form.auth").hide();
|
||||
$("#submit_google_doc_form.submit_assignment_form").removeClass('hide');
|
||||
listGoogleDocs();
|
||||
}
|
||||
|
||||
function toggleRemoveAttachmentLinks(){
|
||||
$('#submit_online_upload_form .remove_attachment_link').showIf($('#submit_online_upload_form .submission_attachment:not(#submission_attachment_blank)').length > 1);
|
||||
}
|
||||
|
|
|
@ -68,7 +68,9 @@ describe "assignments" do
|
|||
|
||||
get "/courses/#{@course.id}/assignments/#{assignment.id}"
|
||||
|
||||
expect(ffj('.formtable input[name="submission[group_comment]"]').size).to eq 3
|
||||
acceptable_tabs = ffj('#submit_online_upload_form,#submit_online_text_entry_form,#submit_online_url_form')
|
||||
expect(acceptable_tabs.size).to be 3
|
||||
acceptable_tabs.each { |tabby| expect(ffj('.formtable input[name="submission[group_comment]"]', tabby).size).to be 1 }
|
||||
end
|
||||
|
||||
it "should not show assignments in an unpublished course" do
|
||||
|
|
Loading…
Reference in New Issue