From 80a7486f95a39ad3fc0946fad17fe51cff01cec6 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Lang Date: Mon, 9 Jun 2008 18:40:59 +0000 Subject: [PATCH] File viewer for attached text files. git-svn-id: http://redmine.rubyforge.org/svn/trunk@1520 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- app/controllers/attachments_controller.rb | 11 ++-- app/helpers/application_helper.rb | 8 +++ app/helpers/repositories_helper.rb | 7 --- app/models/attachment.rb | 4 ++ app/views/attachments/file.rhtml | 15 +++++ test/fixtures/attachments.yml | 38 ++++++++++- test/fixtures/files/060719210727_archive.zip | Bin 0 -> 157 bytes .../files/060719210727_changeset.diff | 13 ++++ test/fixtures/files/060719210727_source.rb | 10 +++ .../functional/attachments_controller_test.rb | 59 ++++++++++++++++++ test/functional/documents_controller_test.rb | 2 + test/functional/issues_controller_test.rb | 2 + test/integration/issues_test.rb | 18 ++++++ test/test_helper.rb | 6 ++ 14 files changed, 181 insertions(+), 12 deletions(-) create mode 100644 app/views/attachments/file.rhtml create mode 100644 test/fixtures/files/060719210727_archive.zip create mode 100644 test/fixtures/files/060719210727_changeset.diff create mode 100644 test/fixtures/files/060719210727_source.rb create mode 100644 test/functional/attachments_controller_test.rb diff --git a/app/controllers/attachments_controller.rb b/app/controllers/attachments_controller.rb index cfc15669f..9ea9ac48e 100644 --- a/app/controllers/attachments_controller.rb +++ b/app/controllers/attachments_controller.rb @@ -23,7 +23,10 @@ class AttachmentsController < ApplicationController if @attachment.is_diff? @diff = File.new(@attachment.diskfile, "rb").read render :action => 'diff' - else + elsif @attachment.is_text? + @content = File.new(@attachment.diskfile, "rb").read + render :action => 'file' + elsif download end end @@ -38,9 +41,9 @@ class AttachmentsController < ApplicationController private def find_project @attachment = Attachment.find(params[:id]) - render_404 and return false unless File.readable?(@attachment.diskfile) + #render_404 and return false unless File.readable?(@attachment.diskfile) @project = @attachment.project - rescue - render_404 + #rescue + # render_404 end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 405c5bf44..16904c251 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -15,6 +15,9 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +require 'coderay' +require 'coderay/helpers/file_type' + module ApplicationHelper include Redmine::WikiFormatting::Macros::Definitions @@ -116,6 +119,11 @@ module ApplicationHelper l(:actionview_datehelper_select_month_names).split(',')[month-1] end + def syntax_highlight(name, content) + type = CodeRay::FileType[name] + type ? CodeRay.scan(content, type).html : h(content) + end + def pagination_links_full(paginator, count=nil, options={}) page_param = options.delete(:page_param) || :page url_param = params.dup diff --git a/app/helpers/repositories_helper.rb b/app/helpers/repositories_helper.rb index 10f6e7396..e94ae2e7f 100644 --- a/app/helpers/repositories_helper.rb +++ b/app/helpers/repositories_helper.rb @@ -15,16 +15,9 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -require 'coderay' -require 'coderay/helpers/file_type' require 'iconv' module RepositoriesHelper - def syntax_highlight(name, content) - type = CodeRay::FileType[name] - type ? CodeRay.scan(content, type).html : h(content) - end - def format_revision(txt) txt.to_s[0,8] end diff --git a/app/models/attachment.rb b/app/models/attachment.rb index 95de4837a..7d6a74ebb 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -88,6 +88,10 @@ class Attachment < ActiveRecord::Base self.filename =~ /\.(jpe?g|gif|png)$/i end + def is_text? + Redmine::MimeType.is_type?('text', filename) + end + def is_diff? self.filename =~ /\.(patch|diff)$/i end diff --git a/app/views/attachments/file.rhtml b/app/views/attachments/file.rhtml new file mode 100644 index 000000000..7988d0aed --- /dev/null +++ b/app/views/attachments/file.rhtml @@ -0,0 +1,15 @@ +

<%=h @attachment.filename %>

+ +
+

<%= h("#{@attachment.description} - ") unless @attachment.description.blank? %> + <%= @attachment.author %>, <%= format_time(@attachment.created_on) %>

+

<%= link_to l(:button_download), {:controller => 'attachments', :action => 'download', :id => @attachment } -%> + (<%= number_to_human_size @attachment.filesize %>)

+ +
+  +<%= render :partial => 'common/file', :locals => {:content => @content, :filename => @attachment.filename} %> + +<% content_for :header_tags do -%> + <%= stylesheet_link_tag "scm" -%> +<% end -%> diff --git a/test/fixtures/attachments.yml b/test/fixtures/attachments.yml index 162d44720..a73d6b385 100644 --- a/test/fixtures/attachments.yml +++ b/test/fixtures/attachments.yml @@ -36,4 +36,40 @@ attachments_003: filename: logo.gif description: This is a logo author_id: 2 - \ No newline at end of file +attachments_004: + created_on: 2006-07-19 21:07:27 +02:00 + container_type: Issue + container_id: 3 + downloads: 0 + disk_filename: 060719210727_source.rb + digest: b91e08d0cf966d5c6ff411bd8c4cc3a2 + id: 4 + filesize: 153 + filename: source.rb + author_id: 2 + description: This is a Ruby source file + content_type: application/x-ruby +attachments_005: + created_on: 2006-07-19 21:07:27 +02:00 + container_type: Issue + container_id: 3 + downloads: 0 + disk_filename: 060719210727_changeset.diff + digest: b91e08d0cf966d5c6ff411bd8c4cc3a2 + id: 5 + filesize: 687 + filename: changeset.diff + author_id: 2 + content_type: text/x-diff +attachments_006: + created_on: 2006-07-19 21:07:27 +02:00 + container_type: Issue + container_id: 3 + downloads: 0 + disk_filename: 060719210727_archive.zip + digest: b91e08d0cf966d5c6ff411bd8c4cc3a2 + id: 6 + filesize: 157 + filename: archive.zip + author_id: 2 + content_type: application/octet-stream diff --git a/test/fixtures/files/060719210727_archive.zip b/test/fixtures/files/060719210727_archive.zip new file mode 100644 index 0000000000000000000000000000000000000000..5467885d4b28eedd531d78c32380ffd3e69eded0 GIT binary patch literal 157 zcmWIWW@Zs#U|`^2Fv$%vtB#e4Q3moW^-3yAv`?PU31e8~(mLr% zmr(1LGjl>(xBO9Rz0@@4&k>OY35A}93<2JZOd<@pjRTs 'issues', :action => 'show', :id => @issue, :project_id => @project ++ redirect_to :controller => 'issues', :action => 'show', :id => @issue + return + end + end diff --git a/test/fixtures/files/060719210727_source.rb b/test/fixtures/files/060719210727_source.rb new file mode 100644 index 000000000..dccb59165 --- /dev/null +++ b/test/fixtures/files/060719210727_source.rb @@ -0,0 +1,10 @@ +# The Greeter class +class Greeter + def initialize(name) + @name = name.capitalize + end + + def salute + puts "Hello #{@name}!" + end +end diff --git a/test/functional/attachments_controller_test.rb b/test/functional/attachments_controller_test.rb new file mode 100644 index 000000000..d088c0b0f --- /dev/null +++ b/test/functional/attachments_controller_test.rb @@ -0,0 +1,59 @@ +# redMine - project management software +# Copyright (C) 2006-2008 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +require File.dirname(__FILE__) + '/../test_helper' +require 'attachments_controller' + +# Re-raise errors caught by the controller. +class AttachmentsController; def rescue_action(e) raise e end; end + + +class AttachmentsControllerTest < Test::Unit::TestCase + fixtures :users, :projects, :issues, :attachments + + def setup + @controller = AttachmentsController.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + Attachment.storage_path = "#{RAILS_ROOT}/test/fixtures/files" + User.current = nil + end + + def test_show_diff + get :show, :id => 5 + assert_response :success + assert_template 'diff' + end + + def test_show_text_file + get :show, :id => 4 + assert_response :success + assert_template 'file' + end + + def test_show_other + get :show, :id => 6 + assert_response :success + assert_equal 'application/octet-stream', @response.content_type + end + + def test_download_text_file + get :download, :id => 4 + assert_response :success + assert_equal 'application/x-ruby', @response.content_type + end +end diff --git a/test/functional/documents_controller_test.rb b/test/functional/documents_controller_test.rb index f150a5b7a..7c1f0213a 100644 --- a/test/functional/documents_controller_test.rb +++ b/test/functional/documents_controller_test.rb @@ -40,6 +40,8 @@ class DocumentsControllerTest < Test::Unit::TestCase def test_new_with_one_attachment @request.session[:user_id] = 2 + set_tmp_attachments_directory + post :new, :project_id => 'ecookbook', :document => { :title => 'DocumentsControllerTest#test_post_new', :description => 'This is a new document', diff --git a/test/functional/issues_controller_test.rb b/test/functional/issues_controller_test.rb index 582c27d9b..32d2a7f41 100644 --- a/test/functional/issues_controller_test.rb +++ b/test/functional/issues_controller_test.rb @@ -361,6 +361,8 @@ class IssuesControllerTest < Test::Unit::TestCase end def test_post_edit_with_attachment_only + set_tmp_attachments_directory + # anonymous user post :edit, :id => 1, diff --git a/test/integration/issues_test.rb b/test/integration/issues_test.rb index b9e21719c..1b57ba8f8 100644 --- a/test/integration/issues_test.rb +++ b/test/integration/issues_test.rb @@ -1,3 +1,20 @@ +# redMine - project management software +# Copyright (C) 2006-2008 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + require "#{File.dirname(__FILE__)}/../test_helper" class IssuesTest < ActionController::IntegrationTest @@ -47,6 +64,7 @@ class IssuesTest < ActionController::IntegrationTest # add then remove 2 attachments to an issue def test_issue_attachements log_user('jsmith', 'jsmith') + set_tmp_attachments_directory post 'issues/edit/1', :notes => 'Some notes', diff --git a/test/test_helper.rb b/test/test_helper.rb index 61670318a..150b063e8 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -57,6 +57,12 @@ class Test::Unit::TestCase def test_uploaded_file(name, mime) ActionController::TestUploadedFile.new(Test::Unit::TestCase.fixture_path + "/files/#{name}", mime) end + + # Use a temporary directory for attachment related tests + def set_tmp_attachments_directory + Dir.mkdir "#{RAILS_ROOT}/tmp/test/attachments" unless File.directory?("#{RAILS_ROOT}/tmp/test/attachments") + Attachment.storage_path = "#{RAILS_ROOT}/tmp/test/attachments" + end end -- 2.39.5