Skip to content

Commit

Permalink
modifying controller functions to make html preview
Browse files Browse the repository at this point in the history
  • Loading branch information
soheegoo committed Jan 28, 2025
1 parent 050ed7f commit 8c95009
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 9 deletions.
4 changes: 2 additions & 2 deletions app/controllers/annotations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def add_existing_annotation
page: params[:page],
**base_attributes
)
elsif submission_file.is_pynb?
elsif submission_file.is_pynb? || submission_file.is_rmd?
@annotation = result.annotations.create!(
type: 'HtmlAnnotation',
start_node: params[:start_node],
Expand Down Expand Up @@ -107,7 +107,7 @@ def create
page: params[:page],
**base_attributes
)
elsif submission_file.is_pynb?
elsif submission_file.is_pynb? || submission_file.is_rmd?
@annotation = result.annotations.create!(
type: 'HtmlAnnotation',
start_node: params[:start_node],
Expand Down
59 changes: 52 additions & 7 deletions app/controllers/submissions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ class SubmissionsController < ApplicationController
p.frame_src(*PERMITTED_IFRAME_SRC)
end

content_security_policy_report_only only: :html_content
content_security_policy only: :html_content do |p|
p.style_src :self, "'unsafe-inline'"
end

def index
respond_to do |format|
Expand Down Expand Up @@ -55,9 +57,9 @@ def repo_browser
end
# store the displayed revision
if @revision.nil? && ((params[:revision_identifier] &&
params[:revision_identifier] == revision.revision_identifier.to_s) ||
(params[:revision_timestamp] &&
Time.zone.parse(params[:revision_timestamp]).in_time_zone >= revision.server_timestamp))
params[:revision_identifier] == revision.revision_identifier.to_s) ||
(params[:revision_timestamp] &&
Time.zone.parse(params[:revision_timestamp]).in_time_zone >= revision.server_timestamp))
@revision = revision
end
end
Expand Down Expand Up @@ -482,7 +484,8 @@ def download_file
return head :not_found
end

if params[:show_in_browser] == 'true' && file.is_pynb? && Rails.application.config.nbconvert_enabled
if params[:show_in_browser] == 'true' &&
((file.is_pynb? && Rails.application.config.nbconvert_enabled) || file.is_rmd?)
redirect_to html_content_course_assignment_submissions_url(current_course,
record.grouping.assignment,
select_file_id: params[:select_file_id])
Expand Down Expand Up @@ -559,8 +562,9 @@ def download_file_zip
def download
preview = params[:preview] == 'true'
nbconvert_enabled = Rails.application.config.nbconvert_enabled
file_type = FileHelper.get_file_type(params[:file_name])

if FileHelper.get_file_type(params[:file_name]) == 'jupyter-notebook' && preview && nbconvert_enabled
if ((file_type == 'jupyter-notebook' && nbconvert_enabled) || file_type == 'markdown') && preview
redirect_to action: :html_content,
course_id: current_course.id,
assignment_id: params[:assignment_id],
Expand Down Expand Up @@ -678,7 +682,11 @@ def html_content
else
sanitized_filename = ActiveStorage::Filename.new("#{filename}.#{revision_identifier}").sanitized
unique_path = File.join(grouping.group.repo_name, path, sanitized_filename)
@html_content = notebook_to_html(file_contents, unique_path, @file_type)
if @file_type == 'markdown'
@html_content = rmd_to_html(file_contents, unique_path)
else
@html_content = notebook_to_html(file_contents, unique_path, @notebook_type)
end
end
render layout: 'html_content'
end
Expand Down Expand Up @@ -945,6 +953,43 @@ def notebook_to_html(file_contents, unique_path, type)
File.read(cache_file)
end

def rmd_to_html(file_contents, unique_path)
cache_file = Pathname.new('tmp/rmd_html_cache') + "#{unique_path}.html"
unless File.exist? cache_file
FileUtils.mkdir_p(cache_file.dirname)
begin
temp_rmd_file = Tempfile.new(['temp_rmd_content', '.Rmd'], 'tmp/rmd_html_cache')
file_contents.gsub!(/```{r[^\}]*?(echo|eval|include)\s*=\s*(TRUE|FALSE)[^\}]*?}/, '```{r}')
temp_rmd_file.write(file_contents)
temp_rmd_file.close

args = [
'Rscript', '-e',
"library(rmarkdown); library(knitr); knitr::opts_chunk$set(eval = FALSE, echo = TRUE, include = TRUE); \
rmarkdown::render('#{temp_rmd_file.path}', output_format = 'html_document', \
output_file = '#{Rails.root.join(cache_file)}')"
]

_stdout, stderr, status = Open3.capture3(*args)
return "#{I18n.t('submissions.cannot_display')}<br/><br/>#{stderr.lines.last}" unless status.exitstatus.zero?
rescue StandardError => e
return "#{I18n.t('submissions.invalid_rmd_content')}: #{e}"
ensure
temp_rmd_file&.unlink
end

html = Nokogiri::HTML.parse(File.read(cache_file))
current_ids = html.xpath('//*[@id]').pluck(:id).to_set # rubocop:disable Rails/PluckId
html.xpath('//*[not(@id)]').map do |elem|
unique_id = elem.path
unique_id += '-next' while current_ids.include? unique_id
elem.set_attribute(:id, unique_id)
end
File.write(cache_file, html.to_html)
end
File.read(cache_file)
end

# Return a relative path to a temporary zip file (which may or may not exists).
# The name of this file is unique by the +assignment+ and current user.
def zipped_grouping_file_name(assignment)
Expand Down

0 comments on commit 8c95009

Please sign in to comment.