File download (primitive implementation)
This commit is contained in:
parent
9d90901cd0
commit
e9a419c40f
6 changed files with 73 additions and 55 deletions
|
@ -25,12 +25,38 @@ class ApplicationController < ActionController::Base
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def wiki
|
def authorized?
|
||||||
$instiki_wiki_service
|
@web.nil? ||
|
||||||
|
@web.password.nil? ||
|
||||||
|
cookies['web_address'] == @web.password ||
|
||||||
|
password_check(@params['password'])
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_authorization
|
||||||
|
if in_a_web? and
|
||||||
|
not authorized? and
|
||||||
|
not %w( login authenticate published ).include?(@action_name)
|
||||||
|
redirect_to :action => 'login'
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def connect_to_model
|
||||||
|
@action_name = @params['action'] || 'index'
|
||||||
|
@web_name = @params['web']
|
||||||
|
@wiki = wiki
|
||||||
|
@web = @wiki.webs[@web_name] unless @web_name.nil?
|
||||||
|
@page_name = @file_name = @params['id']
|
||||||
|
@page = @wiki.read_page(@web_name, @page_name) unless @page_name.nil?
|
||||||
|
@author = cookies['author'] || 'AnonymousCoward'
|
||||||
|
check_authorization
|
||||||
|
end
|
||||||
|
|
||||||
|
def in_a_web?
|
||||||
|
not @web_name.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
@@REMEMBER_NOT = ['locked', 'save']
|
@@REMEMBER_NOT = ['locked', 'save']
|
||||||
|
|
||||||
def remember_location
|
def remember_location
|
||||||
if @response.headers['Status'] == '200 OK'
|
if @response.headers['Status'] == '200 OK'
|
||||||
unless @@REMEMBER_NOT.include? action_name or @request.method != :get
|
unless @@REMEMBER_NOT.include? action_name or @request.method != :get
|
||||||
|
@ -58,28 +84,8 @@ class ApplicationController < ActionController::Base
|
||||||
@response.headers['Content-Type'] = 'text/html; charset=UTF-8'
|
@response.headers['Content-Type'] = 'text/html; charset=UTF-8'
|
||||||
end
|
end
|
||||||
|
|
||||||
def connect_to_model
|
def wiki
|
||||||
@action_name = @params['action'] || 'index'
|
$instiki_wiki_service
|
||||||
@web_name = @params['web']
|
|
||||||
@wiki = wiki
|
|
||||||
@web = @wiki.webs[@web_name] unless @web_name.nil?
|
|
||||||
@page_name = @params['id']
|
|
||||||
@page = @wiki.read_page(@web_name, @page_name) unless @page_name.nil?
|
|
||||||
@author = cookies['author'] || 'AnonymousCoward'
|
|
||||||
check_authorization(@action_name)
|
|
||||||
end
|
|
||||||
|
|
||||||
def check_authorization(action_name)
|
|
||||||
if in_a_web? and
|
|
||||||
not authorized? and
|
|
||||||
not %w( login authenticate published ).include?(action_name)
|
|
||||||
redirect_to :action => 'login'
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def in_a_web?
|
|
||||||
not @web_name.nil?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,31 +1,45 @@
|
||||||
|
require 'fileutils'
|
||||||
require 'application'
|
require 'application'
|
||||||
|
require 'instiki_errors'
|
||||||
|
|
||||||
class FileController < ApplicationController
|
class FileController < ApplicationController
|
||||||
|
|
||||||
layout 'default', :except => [:rss_feed, :rss_with_headlines, :tex, :export_tex, :export_html]
|
layout 'default', :except => [:rss_feed, :rss_with_headlines, :tex, :export_tex, :export_html]
|
||||||
|
|
||||||
def file
|
def file
|
||||||
if have_file?(@params['id'])
|
if have_file?
|
||||||
render_text 'Download file'
|
send_file(file_path)
|
||||||
else
|
else
|
||||||
render_text 'form'
|
render_text 'form'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def have_file?(file_name)
|
def have_file?
|
||||||
sanitize_file_name(file_name)
|
sanitize_file_name
|
||||||
@wiki.storage_path
|
File.file?(file_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
SANE_FILE_NAME = /[-_A-Za-z0-9]{1,255}/
|
SANE_FILE_NAME = /[-_A-Za-z0-9]{1,255}/
|
||||||
def sanitize_file_name(file_name)
|
|
||||||
unless file_name =~ SANE_FILE_NAME
|
def sanitize_file_name
|
||||||
raise "Invalid file name: '#{file_name}'.\n" +
|
raise Instiki::ValidationError.new("Invalid path") unless @file_name
|
||||||
"Only latin characters, digits, underscores and dashes are accepted."
|
unless @file_name =~ SANE_FILE_NAME
|
||||||
|
raise ValidationError.new("Invalid file name: '#{@file_name}'.\n" +
|
||||||
|
"Only latin characters, digits, underscores and dashes are accepted.")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
def file_area
|
||||||
|
raise Instiki::ValidationError.new("Invalid path") unless @web_name
|
||||||
|
file_area = File.expand_path("#{@wiki.storage_path}/#{@web_name}")
|
||||||
|
FileUtils.mkdir_p(file_area) unless File.directory?(file_area)
|
||||||
|
file_area
|
||||||
|
end
|
||||||
|
|
||||||
|
def file_path
|
||||||
|
"#{file_area}/#{@file_name}"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
|
@ -80,7 +80,7 @@ class WikiController < ApplicationController
|
||||||
|
|
||||||
def export_pdf
|
def export_pdf
|
||||||
file_name = "#{@web.address}-tex-#{@web.revised_on.strftime('%Y-%m-%d-%H-%M-%S')}"
|
file_name = "#{@web.address}-tex-#{@web.revised_on.strftime('%Y-%m-%d-%H-%M-%S')}"
|
||||||
file_path = WikiService.storage_path + file_name
|
file_path = @wiki.storage_path + file_name
|
||||||
|
|
||||||
export_web_to_tex "#{file_path}.tex" unless FileTest.exists? "#{file_path}.tex"
|
export_web_to_tex "#{file_path}.tex" unless FileTest.exists? "#{file_path}.tex"
|
||||||
convert_tex_to_pdf "#{file_path}.tex"
|
convert_tex_to_pdf "#{file_path}.tex"
|
||||||
|
@ -89,7 +89,7 @@ class WikiController < ApplicationController
|
||||||
|
|
||||||
def export_tex
|
def export_tex
|
||||||
file_name = "#{@web.address}-tex-#{@web.revised_on.strftime('%Y-%m-%d-%H-%M-%S')}.tex"
|
file_name = "#{@web.address}-tex-#{@web.revised_on.strftime('%Y-%m-%d-%H-%M-%S')}.tex"
|
||||||
file_path = WikiService.storage_path + file_name
|
file_path = @wiki.storage_path + file_name
|
||||||
|
|
||||||
export_web_to_tex(file_path) unless FileTest.exists?(file_path)
|
export_web_to_tex(file_path) unless FileTest.exists?(file_path)
|
||||||
send_file(file_path)
|
send_file(file_path)
|
||||||
|
@ -182,7 +182,7 @@ class WikiController < ApplicationController
|
||||||
page = wiki.read_page(@web_name, @page_name)
|
page = wiki.read_page(@web_name, @page_name)
|
||||||
safe_page_name = @page.name.gsub(/\W/, '')
|
safe_page_name = @page.name.gsub(/\W/, '')
|
||||||
file_name = "#{safe_page_name}-#{@web.address}-#{@page.created_at.strftime('%Y-%m-%d-%H-%M-%S')}"
|
file_name = "#{safe_page_name}-#{@web.address}-#{@page.created_at.strftime('%Y-%m-%d-%H-%M-%S')}"
|
||||||
file_path = WikiService.storage_path + file_name
|
file_path = @wiki.storage_path + file_name
|
||||||
|
|
||||||
export_page_to_tex(file_path + '.tex') unless FileTest.exists?(file_path + '.tex')
|
export_page_to_tex(file_path + '.tex') unless FileTest.exists?(file_path + '.tex')
|
||||||
# NB: this is _very_ slow
|
# NB: this is _very_ slow
|
||||||
|
@ -263,13 +263,6 @@ class WikiController < ApplicationController
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def authorized?
|
|
||||||
@web.nil? ||
|
|
||||||
@web.password.nil? ||
|
|
||||||
cookies['web_address'] == @web.password ||
|
|
||||||
password_check(@params['password'])
|
|
||||||
end
|
|
||||||
|
|
||||||
def convert_tex_to_pdf(tex_path)
|
def convert_tex_to_pdf(tex_path)
|
||||||
# TODO remove earlier PDF files with the same prefix
|
# TODO remove earlier PDF files with the same prefix
|
||||||
# TODO handle gracefully situation where pdflatex is not available
|
# TODO handle gracefully situation where pdflatex is not available
|
||||||
|
@ -285,7 +278,7 @@ class WikiController < ApplicationController
|
||||||
|
|
||||||
file_prefix = "#{@web.address}-#{file_type}-"
|
file_prefix = "#{@web.address}-#{file_type}-"
|
||||||
timestamp = @web.revised_on.strftime('%Y-%m-%d-%H-%M-%S')
|
timestamp = @web.revised_on.strftime('%Y-%m-%d-%H-%M-%S')
|
||||||
file_path = WikiService.storage_path + file_prefix + timestamp + '.zip'
|
file_path = @wiki.storage_path + file_prefix + timestamp + '.zip'
|
||||||
tmp_path = "#{file_path}.tmp"
|
tmp_path = "#{file_path}.tmp"
|
||||||
|
|
||||||
Zip::ZipOutputStream.open(tmp_path) do |zip_out|
|
Zip::ZipOutputStream.open(tmp_path) do |zip_out|
|
||||||
|
@ -305,7 +298,7 @@ class WikiController < ApplicationController
|
||||||
EOL
|
EOL
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
FileUtils.rm_rf(Dir[WikiService.storage_path + file_prefix + '*.zip'])
|
FileUtils.rm_rf(Dir[@wiki.storage_path + file_prefix + '*.zip'])
|
||||||
FileUtils.mv(tmp_path, file_path)
|
FileUtils.mv(tmp_path, file_path)
|
||||||
send_file(file_path, :type => 'application/zip')
|
send_file(file_path, :type => 'application/zip')
|
||||||
end
|
end
|
||||||
|
|
|
@ -90,6 +90,10 @@ module AbstractWikiService
|
||||||
@webs[web_address].add_page(page)
|
@webs[web_address].add_page(page)
|
||||||
page
|
page
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def storage_path
|
||||||
|
self.class.storage_path
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def settings_changed?(web, markup, safe_mode, brackets_only)
|
def settings_changed?(web, markup, safe_mode, brackets_only)
|
||||||
|
@ -106,19 +110,20 @@ class WikiService
|
||||||
|
|
||||||
# These methods do not change the state of persistent objects, and
|
# These methods do not change the state of persistent objects, and
|
||||||
# should not be ogged by Madeleine
|
# should not be ogged by Madeleine
|
||||||
automatic_read_only :authenticate, :read_page, :setup?, :webs
|
automatic_read_only :authenticate, :read_page, :setup?, :webs, :storage_path
|
||||||
|
|
||||||
@@storage_path = './storage/'
|
@@storage_path = './storage/'
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
def storage_path
|
|
||||||
@@storage_path
|
|
||||||
end
|
|
||||||
|
|
||||||
def storage_path=(storage_path)
|
def storage_path=(storage_path)
|
||||||
@@storage_path = storage_path
|
@@storage_path = storage_path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def storage_path
|
||||||
|
@@storage_path
|
||||||
|
end
|
||||||
|
|
||||||
def clean_storage
|
def clean_storage
|
||||||
MadeleineServer.clean_storage(self)
|
MadeleineServer.clean_storage(self)
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,7 +18,7 @@ class FileControllerTest < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_file
|
def test_file
|
||||||
process 'file', 'id' => 'foo.tgz'
|
process 'file', 'web' => 'wiki', 'id' => 'foo.tgz'
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -56,7 +56,7 @@ class WikiServiceWithNoPersistence
|
||||||
end
|
end
|
||||||
|
|
||||||
def storage_path
|
def storage_path
|
||||||
RAILS_ROOT + '/storage/test'
|
RAILS_ROOT + '/storage/test/'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue