From 0b1a80a852916a7250c05dd2ea4ac65c83fd704e Mon Sep 17 00:00:00 2001
From: Alexey Verkhovsky
Date: Mon, 14 Nov 2005 08:38:37 +0000
Subject: [PATCH] [BUILD STILL BROKEN] File uploads roughly speaking work (to
about same extent as in 0.10)
---
app/controllers/application.rb | 2 -
app/controllers/file_controller.rb | 22 ++-
app/controllers/wiki_controller.rb | 9 +-
app/models/web.rb | 42 ++--
app/models/wiki_file.rb | 13 +-
app/views/admin/edit_web.rhtml | 4 -
app/views/file/file.rhtml | 39 ++--
app/views/layouts/default.rhtml | 9 +-
lib/url_generator.rb | 6 +-
public/stylesheets/instiki.css | 245 +++++-------------------
test/functional/file_controller_test.rb | 66 ++++---
test/test_helper.rb | 4 +-
test/unit/page_renderer_test.rb | 8 +-
13 files changed, 172 insertions(+), 297 deletions(-)
diff --git a/app/controllers/application.rb b/app/controllers/application.rb
index 362558fe..e43b0d8e 100644
--- a/app/controllers/application.rb
+++ b/app/controllers/application.rb
@@ -38,8 +38,6 @@ class ApplicationController < ActionController::Base
return false
end
end
- @page_name = @file_name = @params['id']
- @page = @wiki.read_page(@web_name, @page_name) unless @page_name.nil?
@author = cookies['author'] || 'AnonymousCoward'
end
diff --git a/app/controllers/file_controller.rb b/app/controllers/file_controller.rb
index fdf3b8ae..724e6b4c 100644
--- a/app/controllers/file_controller.rb
+++ b/app/controllers/file_controller.rb
@@ -9,23 +9,26 @@ class FileController < ApplicationController
def file
if @params['file']
# form supplied
- new_file = upload_file(@file_name, @params['file'])
+ new_file = @web.wiki_files.create(@params['file'])
if new_file.valid?
flash[:info] = "File '#{@file_name}' successfully uploaded"
return_to_last_remembered
else
- # FIXME handle validation errors more gracefully
- flash[:errors] = new_file.errors.to_s
+ # pass the file with errors back into the form
+ @file = new_file
+ render
end
- else
+ else
+ (render(:status => 404, :text => 'Unspecified file name') and return) unless @file_name
# no form supplied, this is a request to download the file
file = WikiFile.find_by_file_name(@file_name)
if file
send_data(file.content, :filename => @file_name, :type => content_type_header(@file_name))
+ else
+ @file = WikiFile.new(:file_name => @file_name)
+ render
end
end
- # if it's neither a supplied form for upload, nor a request for a known file,
- # display the file/file.rhtml template (which happens to be an upload form)
end
def cancel_upload
@@ -41,7 +44,7 @@ class FileController < ApplicationController
if @problems.empty?
flash[:info] = 'Import successfully finished'
else
- flash[:error] = "Import finished, but some pages were not imported:" +
+ flash[:error] = 'Import finished, but some pages were not imported: ' +
@problems.join(' ') + ' '
end
return_to_last_remembered
@@ -60,6 +63,11 @@ class FileController < ApplicationController
return false
end
end
+
+ def connect_to_model
+ super
+ @file_name = @params['id']
+ end
private
diff --git a/app/controllers/wiki_controller.rb b/app/controllers/wiki_controller.rb
index 2e7eb3b7..dbed5666 100644
--- a/app/controllers/wiki_controller.rb
+++ b/app/controllers/wiki_controller.rb
@@ -272,9 +272,16 @@ class WikiController < ApplicationController
@tex_content = RedClothForTex.new(@page.content).to_tex
end
+ protected
+
+ def connect_to_model
+ super
+ @page_name = @params['id']
+ @page = @wiki.read_page(@web_name, @page_name) if @page_name
+ end
private
-
+
def convert_tex_to_pdf(tex_path)
# TODO remove earlier PDF files with the same prefix
# TODO handle gracefully situation where pdflatex is not available
diff --git a/app/models/web.rb b/app/models/web.rb
index 1ca17a9e..b37811a6 100644
--- a/app/models/web.rb
+++ b/app/models/web.rb
@@ -6,10 +6,6 @@ class Web < ActiveRecord::Base
Wiki.new
end
- def file_yard
- @file_yard ||= FileYard.new("#{Wiki.storage_path}/#{address}", max_upload_size)
- end
-
def settings_changed?(markup, safe_mode, brackets_only)
self.markup != markup ||
self.safe_mode != safe_mode ||
@@ -84,6 +80,23 @@ class Web < ActiveRecord::Base
address
end
+ def create_files_directory
+ return unless allow_uploads == 1
+ dummy_file = self.wiki_files.build(:file_name => '0', :description => '0', :content => '0')
+ dir = File.dirname(dummy_file.content_path)
+ begin
+ require 'fileutils'
+ FileUtils.mkdir_p dir
+ dummy_file.save
+ dummy_file.destroy
+ rescue => e
+ logger.error("Failed create files directory for #{self.address}: #{e}")
+ raise "Instiki could not create directory to store uploaded files. " +
+ "Please make sure that Instiki is allowed to create directory " +
+ "#{File.expand_path(dir)} and add files to it."
+ end
+ end
+
private
# Returns an array of all the wiki words in any current revision
@@ -114,32 +127,15 @@ class Web < ActiveRecord::Base
end
end
- def create_files_directory
- return unless allow_uploads == 1
- dummy_file = self.wiki_files.build(:file_name => '0', :description => '0', :content => '0')
- dir = File.dirname(dummy_file.content_path)
- begin
- require 'fileutils'
- FileUtils.mkdir_p dir
- dummy_file.save
- dummy_file.destroy
- rescue => e
- logger.error("Failed create files directory for #{self.address}: #{e}")
- raise "Instiki could not create directory to store uploaded files. " +
- "Please make sure that Instiki is allowed to create directory " +
- "#{File.expand_path(dir)} and add files to it."
- end
- end
-
def default_web?
defined? DEFAULT_WEB and self.address == DEFAULT_WEB
end
def files_path
if default_web?
- "#{RAILS_ROOT}/public/#{self.address}/files"
- else
"#{RAILS_ROOT}/public/files"
+ else
+ "#{RAILS_ROOT}/public/#{self.address}/files"
end
end
end
diff --git a/app/models/wiki_file.rb b/app/models/wiki_file.rb
index 89b166c0..635025e5 100644
--- a/app/models/wiki_file.rb
+++ b/app/models/wiki_file.rb
@@ -4,9 +4,9 @@ class WikiFile < ActiveRecord::Base
before_save :write_content_to_file
before_destroy :delete_content_file
- validates_presence_of %w( web file_name description )
+ validates_presence_of %w( web file_name )
validates_length_of :file_name, :within=>1..50
- validates_length_of :description, :within=>1..255
+ validates_length_of :description, :maximum=>255
def self.find_by_file_name(file_name)
find(:first, :conditions => ['file_name = ?', file_name])
@@ -34,7 +34,11 @@ class WikiFile < ActiveRecord::Base
end
def content=(content)
- @content = content
+ if content.respond_to? :read
+ @content = content.read
+ else
+ @content = content
+ end
end
def content
@@ -46,6 +50,7 @@ class WikiFile < ActiveRecord::Base
end
def write_content_to_file
+ web.create_files_directory unless File.exists?(web.files_path)
File.open(self.content_path, 'wb') { |f| f.write(@content) }
end
@@ -54,4 +59,6 @@ class WikiFile < ActiveRecord::Base
FileUtils.rm_f(content_path) if File.exists?(content_path)
end
+
+
end
diff --git a/app/views/admin/edit_web.rhtml b/app/views/admin/edit_web.rhtml
index 558ef68a..58734136 100644
--- a/app/views/admin/edit_web.rhtml
+++ b/app/views/admin/edit_web.rhtml
@@ -48,9 +48,6 @@
/>
Count pages
-
diff --git a/app/views/file/file.rhtml b/app/views/file/file.rhtml
index 63c188eb..4216a9ed 100644
--- a/app/views/file/file.rhtml
+++ b/app/views/file/file.rhtml
@@ -1,19 +1,32 @@
<%
- @title = "Upload #{@file_name}"
+ @title = "Upload #{h @file_name}"
@hide_navigation = false
%>
-
+<%= error_messages_for 'file' %>
+
<%= form_tag({:controller => 'file', :web => @web_name, :action => 'file'}, {:multipart => true}) %>
-
- File to upload:
+ <%= hidden_field 'file', 'file_name' %>
+
+
+ Description (optional) :
+
+ <%= text_field "file", "description", "size" => 40 %>
+
+
+ as
+ <%= text_field_tag :author, @author,
+ :onfocus => "this.value == 'AnonymousCoward' ? this.value = '' : true;",
+ :onblur => "this.value == '' ? this.value = 'AnonymousCoward' : true" %>
+
+<%= end_form_tag %>
\ No newline at end of file
diff --git a/app/views/layouts/default.rhtml b/app/views/layouts/default.rhtml
index fb5e550e..d43208fa 100644
--- a/app/views/layouts/default.rhtml
+++ b/app/views/layouts/default.rhtml
@@ -55,15 +55,16 @@ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
<% end %>
-<% if @error or @flash[:error] %>
-
<%= escape_preserving_linefeeds(@error || @flash[:error]) %>
-<% end %>
-
<% if @flash[:info] %>
<%= escape_preserving_linefeeds @flash[:info] %>
<% end %>
<%= render 'navigation' unless @web.nil? || @hide_navigation %>
+
+<% if @error or @flash[:error] %>
+ <%= escape_preserving_linefeeds(@error || @flash[:error]) %>
+<% end %>
+
<%= @content_for_layout %>
<% if @show_footer %>
diff --git a/lib/url_generator.rb b/lib/url_generator.rb
index fcc08312..ed4da4c4 100644
--- a/lib/url_generator.rb
+++ b/lib/url_generator.rb
@@ -47,14 +47,14 @@ class UrlGenerator < AbstractUrlGenerator
end
when :publish
if known_file
- href = @controller.url_for :controller => 'wiki', :web => web_address, :action => 'published',
+ href = @controller.url_for :controller => 'file', :web => web_address, :action => 'file',
:id => name
%{#{text} }
else
%{#{text} }
end
else
- href = @controller.url_for :controller => 'wiki', :web => web_address, :action => 'file',
+ href = @controller.url_for :controller => 'file', :web => web_address, :action => 'file',
:id => name
if known_file
%{#{text} }
@@ -108,7 +108,7 @@ class UrlGenerator < AbstractUrlGenerator
%{#{text} }
end
else
- href = @controller.url_for @controller => 'file', :web => web_address, :action => 'pic',
+ href = @controller.url_for :controller => 'file', :web => web_address, :action => 'file',
:id => name
if known_pic
%{ }
diff --git a/public/stylesheets/instiki.css b/public/stylesheets/instiki.css
index e1bcb19c..667fb8e9 100644
--- a/public/stylesheets/instiki.css
+++ b/public/stylesheets/instiki.css
@@ -1,31 +1,12 @@
-#Container {
- float: none;
- margin: 0 auto;
- text-align: center;
-}
-
-#Content {
- margin: 0;
- padding: 5px;
- text-align: left;
- border-top: none;
- float: left;
-}
-
body { background-color: #fff; color: #333; }
+body, p, ol, ul, td { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 18px; }
-body, p, ol, ul, td {
- font-family: verdana, arial, helvetica, sans-serif;
- font-size: 13px;
- line-height: 18px;
-}
+#Container { float: none; margin: 0 auto; text-align: center; }
+#Content { margin: 0; padding: 5px; text-align: left; border-top: none; float: left; }
a { color: #000; }
a:visited { color: #666; }
-a:hover {
- color: #fff;
- background-color:#000;
-}
+a:hover { color: #fff; background-color:#000; }
.newWikiWord { background-color: #eee; }
.newWikiWord a:hover { background-color: white; }
@@ -35,208 +16,72 @@ h1 { font-size: 28px }
h2 { font-size: 19px }
h3 { font-size: 16px }
-h1#pageName {
- margin: 5px 0 0;
- padding: 0;
- line-height: 28px;
-}
-
-h1#pageName small {
- color: #444;
- line-height: 10px;
- font-size: 10px;
- padding: 0;
-}
+h1#pageName { margin: 5px 0 0; padding: 0; line-height: 28px; }
+h1#pageName small { color: #444; line-height: 10px; font-size: 10px; padding: 0; }
a.nav, a.nav:link, a.nav:visited { color: #000; }
a.nav:hover { color: #fff; background-color:#000; }
li { margin-bottom: 7px }
-.navigation {
- margin-top: 5px;
- font-size : 12px;
- color: #999;
-}
-
+.navigation { margin-top: 5px; font-size : 12px; color: #999; }
.navigation a:hover { color: #fff; background-color:#000; }
-
-.navigation a {
- font-size: 11px;
- color: black;
- font-weight: bold;
-}
-
-.navigation small a {
- font-weight: normal;
- font-size: 11px;
-}
+.navigation a { font-size: 11px; color: black; font-weight: bold; }
+.navigation small a { font-weight: normal; font-size: 11px; }
-.navOn{
- font-size: 11px;
- color: #444;
- font-weight: bold;
- text-decoration: none;
-}
+.navOn{ font-size: 11px; color: #444; font-weight: bold; text-decoration: none; }
-.help {
- font-family: verdana, arial, helvetica, sans-serif;
- font-size: 11px;
-}
+.help { font-family: verdana, arial, helvetica, sans-serif; font-size: 11px; }
-.inputBox {
- font-family: verdana, arial, helvetica, sans-serif;
- font-size: 11px;
- background-color: #eee;
- padding: 5px;
- margin-bottom: 20px;
-}
+.inputBox { font-family: verdana, arial, helvetica, sans-serif; font-size: 11px; background-color: #eee; padding: 5px; margin-bottom: 20px; }
-blockquote {
- display: block;
- margin: 0px 0px 20px 0px;
- padding: 0px 30px;
- font-size:11px;
- line-height:17px;
- font-style: italic;
-}
+blockquote { display: block; margin: 0px 0px 20px 0px; padding: 0px 30px; font-size:11px; line-height:17px; font-style: italic; }
-pre {
- background-color: #eee;
- padding: 10px;
- font-size: 11px;
- overflow: auto;
-}
+pre { background-color: #eee; padding: 10px; font-size: 11px; overflow: auto; }
-ol.setup {
- font-size: 19px;
- font-family: georgia, verdana, sans-serif;
- padding-left: 25px;
-}
+ol.setup { font-size: 19px; font-family: georgia, verdana, sans-serif; padding-left: 25px; }
+ol.setup li { margin-bottom: 20px }
-ol.setup li {
- margin-bottom: 20px
-}
+.byline { font-size: 10px; font-style: italic; margin-bottom: 10px; color: #999; }
-.byline {
- font-size: 10px;
- font-style: italic;
- margin-bottom: 10px;
- color: #999;
-}
+.references { font-size: 10px; }
-.references {
- font-size: 10px;
-}
+.diffdel, del.diffmod { background: pink; }
+.diffins, ins.diffmod { background: lightgreen; }
-.diffdel, del.diffmod {
- background: pink;
-}
+#footer { height: 14px; padding: .25em 0; }
+#footer p { font-size: 10px; color: gray; font-style: italic; margin: 0; float: right; text-align: right; }
-.diffins, ins.diffmod {
- background: lightgreen;
-}
+div.inputFieldWithPrompt { margin: 0.75em 0; }
-#footer {
- height: 14px;
- padding: .25em 0;
-}
-#footer p {
- font-size: 10px;
- color: gray;
- font-style: italic;
- margin: 0;
- float: right;
- text-align: right;
-}
+div.errorExplanation { color: #900; font-style: italic; font-weight: bold; margin: 1.5em 0; padding: 1em; background: #FFA; }
+div.errorExplanation h2 { display: none; }
+div.errorExplanation p { padding: 0; margin: 0; border: none; }
+div.errorExplanation ul { padding: 0; margin: 0.5em 0 0 2em; border: none; }
+div.errorExplanation li { padding 0; margin: 0; border: none; }
+div.fieldWithErrors input { border: 1px solid #900; }
-#error {
- color: #900;
- font-style: italic;
- font-weight: bold;
- width: 600px;
-}
-#info {
- color: #060;
- font-style: italic;
- width: 600px;
-}
-#TextileHelp table {
- margin-bottom: 0;
-}
+#info { color: #060; font-style: italic; width: 600px; }
+#TextileHelp table { margin-bottom: 0; }
+#TextileHelp table+h3 { margin-top: 11px; }
+#TextileHelp table td { font-size: 11px; padding: 3px; vertical-align: top; border-top: 1px dotted #ccc; }
+#TextileHelp table td.arrow { padding-right: 5px; padding-left: 10px; color: #999; }
+#TextileHelp table td.label { font-weight: bold; white-space: nowrap; font-size: 10px; padding-right: 15px; color: #000; }
+#TextileHelp h3 { font-size: 11px; font-weight: bold; font-weight: normal; margin: 0 0 5px 0; padding: 5px 0 0 0; }
+#TextileHelp p { font-size: 10px; }
-#TextileHelp table+h3 {
- margin-top: 11px;
-}
+.rightHandSide { float: right; width: 147px; margin-left: 10px; padding-left: 20px; border-left: 1px dotted #ccc; }
+.rightHandSide p { font-size: 10px; }
-#TextileHelp table td {
- font-size: 11px;
- padding: 3px;
- vertical-align: top;
- border-top: 1px dotted #ccc;
-}
+.newsList { margin-top: 20px; }
+.newsList p { margin-bottom:30px; }
-#TextileHelp table td.arrow {
- padding-right: 5px;
- padding-left: 10px;
- color: #999;
-}
-
-#TextileHelp table td.label {
- font-weight: bold;
- white-space: nowrap;
- font-size: 10px;
- padding-right: 15px;
- color: #000;
-}
-
-#TextileHelp h3 {
- font-size: 11px;
- font-weight: bold;
- font-weight: normal;
- margin: 0 0 5px 0;
- padding: 5px 0 0 0;
-}
-
-#TextileHelp p {
- font-size: 10px;
-}
-
-.rightHandSide {
- float: right;
- width: 147px;
- margin-left: 10px;
- padding-left: 20px;
- border-left: 1px dotted #ccc;
-}
-
-.rightHandSide p {
- font-size: 10px;
-}
-
-.newsList {
- margin-top: 20px;
-}
-
-.newsList p {
- margin-bottom:30px
-}
-
-td {border:thin solid grey;}
-table {
- border: double black;
- border-collapse: collapse;
-}
-
-.byline {
- padding-top: 15px;
-}
+table { border: double black; border-collapse: collapse; }
+td { border:thin solid grey; }
+.byline { padding-top: 15px; }
/* Affects the display of "category: ..." */
-.property {
- color: grey;
- font-size: 10px;
-}
+.property { color: grey; font-size: 10px; }
diff --git a/test/functional/file_controller_test.rb b/test/functional/file_controller_test.rb
index b18862c0..4c6f4909 100755
--- a/test/functional/file_controller_test.rb
+++ b/test/functional/file_controller_test.rb
@@ -16,6 +16,7 @@ class FileControllerTest < Test::Unit::TestCase
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@web = webs(:test_wiki)
+ @wiki = Wiki.new
WikiFile.delete_all
require 'fileutils'
FileUtils.rm_rf("#{RAILS_ROOT}/public/wiki1/files/*")
@@ -61,37 +62,40 @@ class FileControllerTest < Test::Unit::TestCase
assert_equal pic, r.body
end
-# def test_pic_unknown_pic
-# r = process 'pic', 'web' => 'wiki1', 'id' => 'non-existant.gif'
-#
-# assert_success
-# assert_rendered_file 'file/file'
-# end
-#
-# def test_pic_upload_end_to_end
-# # edit and re-render home page so that it has an "unknown file" link to 'rails-e2e.gif'
-# @wiki.revise_page('wiki1', 'HomePage', '[[rails-e2e.gif:pic]]', Time.now, 'AnonymousBrave')
-# assert_equal "rails-e2e.gif" +
-# "?
",
-# @home.display_content
-#
-# # rails-e2e.gif is unknown to the system, so pic action goes to the file [upload] form
-# r = process 'pic', 'web' => 'wiki1', 'id' => 'rails-e2e.gif'
-# assert_success
-# assert_rendered_file 'file/file'
-#
-# # User uploads the picture
-# picture = File.read("#{RAILS_ROOT}/test/fixtures/rails.gif")
-# r = process 'pic', 'web' => 'wiki1', 'id' => 'rails-e2e.gif', 'file' => StringIO.new(picture)
-# assert_redirect_url '/'
-# assert @wiki.file_yard(@web).has_file?('rails-e2e.gif')
-# assert_equal(picture, File.read("#{RAILS_ROOT}/storage/test/wiki1/rails-e2e.gif"))
-#
-# # this should refresh the page display content (cached)
-# assert_equal "
",
-# @home.display_content
-# end
-#
+ def test_pic_unknown_pic
+ r = get :file, :web => 'wiki1', :id => 'non-existant.gif'
+
+ assert_success
+ assert_rendered_file 'file/file'
+ end
+
+ def test_pic_upload_end_to_end
+ # edit and re-render home page so that it has an "unknown file" link to 'rails-e2e.gif'
+ PageRenderer.setup_url_generator(StubUrlGenerator.new)
+ renderer = PageRenderer.new
+ @wiki.revise_page('wiki1', 'HomePage', '[[rails-e2e.gif:pic]]',
+ Time.now, 'AnonymousBrave', renderer)
+ assert_equal "rails-e2e.gif" +
+ "?
",
+ renderer.display_content
+
+ # rails-e2e.gif is unknown to the system, so pic action goes to the file [upload] form
+ r = get :file, :web => 'wiki1', :id => 'rails-e2e.gif'
+ assert_success
+ assert_rendered_file 'file/file'
+
+ # User uploads the picture
+ picture = File.read("#{RAILS_ROOT}/test/fixtures/rails.gif")
+ r = get :file, :web => 'wiki1', :id => 'rails-e2e.gif', :file => StringIO.new(picture)
+ assert_redirect_url '/'
+ assert @web.has_file?('rails-e2e.gif')
+ assert_equal(picture, File.read("#{RAILS_ROOT}/public/file/rails-e2e.gif"))
+
+ # this should refresh the page display content (cached)
+ assert_equal "
",
+ @home.display_content
+ end
+
# def test_pic_upload_end_to_end
# # edit and re-render home page so that it has an "unknown file" link to 'rails-e2e.gif'
# @wiki.revise_page('wiki1', 'HomePage', '[[instiki-e2e.txt:file]]', Time.now, 'AnonymousBrave',
diff --git a/test/test_helper.rb b/test/test_helper.rb
index fc2079f3..2dae41c9 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -150,8 +150,8 @@ class StubUrlGenerator < AbstractUrlGenerator
if known_pic then %{ }
else %{#{text} } end
else
- if known_pic then %{ }
- else %{#{text}? } end
+ if known_pic then %{ }
+ else %{#{text}? } end
end
end
end
diff --git a/test/unit/page_renderer_test.rb b/test/unit/page_renderer_test.rb
index 00746bff..aabaccf3 100644
--- a/test/unit/page_renderer_test.rb
+++ b/test/unit/page_renderer_test.rb
@@ -282,20 +282,20 @@ class PageRendererTest < Test::Unit::TestCase
FileUtils.rm_rf("#{RAILS_ROOT}/public/wiki1/files/*")
@web.wiki_files.create(:file_name => 'square.jpg', :description => 'Square', :content => 'never mind')
assert_markup_parsed_as(
- '
',
+ '
',
'[[square.jpg|Square:pic]]')
assert_markup_parsed_as(
- '
',
+ '
',
'[[square.jpg:pic]]')
end
def test_link_to_non_existant_pic
assert_markup_parsed_as(
- 'NonExistant? ' +
+ 'NonExistant? ' +
'
',
'[[NonExistant.jpg|NonExistant:pic]]')
assert_markup_parsed_as(
- 'NonExistant.jpg? ' +
+ 'NonExistant.jpg? ' +
'
',
'[[NonExistant.jpg:pic]]')
end