@@ -43,6 +43,9 class AttachmentsController < ApplicationController | |||||
43 | private |
|
43 | private | |
44 | def find_project |
|
44 | def find_project | |
45 | @attachment = Attachment.find(params[:id]) |
|
45 | @attachment = Attachment.find(params[:id]) | |
|
46 | # Show 404 if the filename in the url is wrong | |||
|
47 | raise ActiveRecord::RecordNotFound if params[:filename] && params[:filename] != @attachment.filename | |||
|
48 | ||||
46 | @project = @attachment.project |
|
49 | @project = @attachment.project | |
47 | permission = @attachment.container.is_a?(Version) ? :view_files : "view_#{@attachment.container.class.name.underscore.pluralize}".to_sym |
|
50 | permission = @attachment.container.is_a?(Version) ? :view_files : "view_#{@attachment.container.class.name.underscore.pluralize}".to_sym | |
48 | allowed = User.current.allowed_to?(permission, @project) |
|
51 | allowed = User.current.allowed_to?(permission, @project) |
@@ -47,6 +47,17 module ApplicationHelper | |||||
47 | link_to "#{issue.tracker.name} ##{issue.id}", {:controller => "issues", :action => "show", :id => issue}, options |
|
47 | link_to "#{issue.tracker.name} ##{issue.id}", {:controller => "issues", :action => "show", :id => issue}, options | |
48 | end |
|
48 | end | |
49 |
|
49 | |||
|
50 | # Generates a link to an attachment. | |||
|
51 | # Options: | |||
|
52 | # * :text - Link text (default to attachment filename) | |||
|
53 | # * :download - Force download (default: false) | |||
|
54 | def link_to_attachment(attachment, options={}) | |||
|
55 | text = options.delete(:text) || attachment.filename | |||
|
56 | action = options.delete(:download) ? 'download' : 'show' | |||
|
57 | ||||
|
58 | link_to(h(text), {:controller => 'attachments', :action => action, :id => attachment, :filename => attachment.filename }, options) | |||
|
59 | end | |||
|
60 | ||||
50 | def toggle_link(name, id, options={}) |
|
61 | def toggle_link(name, id, options={}) | |
51 | onclick = "Element.toggle('#{id}'); " |
|
62 | onclick = "Element.toggle('#{id}'); " | |
52 | onclick << (options[:focus] ? "Form.Element.focus('#{options[:focus]}'); " : "this.blur(); ") |
|
63 | onclick << (options[:focus] ? "Form.Element.focus('#{options[:focus]}'); " : "this.blur(); ") |
@@ -95,9 +95,9 module IssuesHelper | |||||
95 | label = content_tag('strong', label) |
|
95 | label = content_tag('strong', label) | |
96 | old_value = content_tag("i", h(old_value)) if detail.old_value |
|
96 | old_value = content_tag("i", h(old_value)) if detail.old_value | |
97 | old_value = content_tag("strike", old_value) if detail.old_value and (!detail.value or detail.value.empty?) |
|
97 | old_value = content_tag("strike", old_value) if detail.old_value and (!detail.value or detail.value.empty?) | |
98 | if detail.property == 'attachment' && !value.blank? && Attachment.find_by_id(detail.prop_key) |
|
98 | if detail.property == 'attachment' && !value.blank? && a = Attachment.find_by_id(detail.prop_key) | |
99 | # Link to the attachment if it has not been removed |
|
99 | # Link to the attachment if it has not been removed | |
100 | value = link_to(value, :controller => 'attachments', :action => 'show', :id => detail.prop_key) |
|
100 | value = link_to_attachment(a) | |
101 | else |
|
101 | else | |
102 | value = content_tag("i", h(value)) if value |
|
102 | value = content_tag("i", h(value)) if value | |
103 | end |
|
103 | end |
@@ -26,7 +26,7 class Attachment < ActiveRecord::Base | |||||
26 | validates_length_of :disk_filename, :maximum => 255 |
|
26 | validates_length_of :disk_filename, :maximum => 255 | |
27 |
|
27 | |||
28 | acts_as_event :title => :filename, |
|
28 | acts_as_event :title => :filename, | |
29 | :url => Proc.new {|o| {:controller => 'attachments', :action => 'download', :id => o.id}} |
|
29 | :url => Proc.new {|o| {:controller => 'attachments', :action => 'download', :id => o.id, :filename => o.filename}} | |
30 |
|
30 | |||
31 | cattr_accessor :storage_path |
|
31 | cattr_accessor :storage_path | |
32 | @@storage_path = "#{RAILS_ROOT}/files" |
|
32 | @@storage_path = "#{RAILS_ROOT}/files" |
@@ -1,6 +1,6 | |||||
1 | <div class="attachments"> |
|
1 | <div class="attachments"> | |
2 | <% for attachment in attachments %> |
|
2 | <% for attachment in attachments %> | |
3 | <p><%= link_to attachment.filename, {:controller => 'attachments', :action => 'show', :id => attachment }, :class => 'icon icon-attachment' -%> |
|
3 | <p><%= link_to_attachment attachment, :class => 'icon icon-attachment' -%> | |
4 | <%= h(" - #{attachment.description}") unless attachment.description.blank? %> |
|
4 | <%= h(" - #{attachment.description}") unless attachment.description.blank? %> | |
5 | <span class="size">(<%= number_to_human_size attachment.filesize %>)</span> |
|
5 | <span class="size">(<%= number_to_human_size attachment.filesize %>)</span> | |
6 | <% if options[:delete_url] %> |
|
6 | <% if options[:delete_url] %> |
@@ -3,7 +3,7 | |||||
3 | <div class="attachments"> |
|
3 | <div class="attachments"> | |
4 | <p><%= h("#{@attachment.description} - ") unless @attachment.description.blank? %> |
|
4 | <p><%= h("#{@attachment.description} - ") unless @attachment.description.blank? %> | |
5 | <span class="author"><%= @attachment.author %>, <%= format_time(@attachment.created_on) %></span></p> |
|
5 | <span class="author"><%= @attachment.author %>, <%= format_time(@attachment.created_on) %></span></p> | |
6 | <p><%= link_to l(:button_download), {:controller => 'attachments', :action => 'download', :id => @attachment } -%> |
|
6 | <p><%= link_to_attachment @attachment, :text => l(:button_download), :download => true -%> | |
7 | <span class="size">(<%= number_to_human_size @attachment.filesize %>)</span></p> |
|
7 | <span class="size">(<%= number_to_human_size @attachment.filesize %>)</span></p> | |
8 |
|
8 | |||
9 | </div> |
|
9 | </div> |
@@ -3,7 +3,7 | |||||
3 | <div class="attachments"> |
|
3 | <div class="attachments"> | |
4 | <p><%= h("#{@attachment.description} - ") unless @attachment.description.blank? %> |
|
4 | <p><%= h("#{@attachment.description} - ") unless @attachment.description.blank? %> | |
5 | <span class="author"><%= @attachment.author %>, <%= format_time(@attachment.created_on) %></span></p> |
|
5 | <span class="author"><%= @attachment.author %>, <%= format_time(@attachment.created_on) %></span></p> | |
6 | <p><%= link_to l(:button_download), {:controller => 'attachments', :action => 'download', :id => @attachment } -%> |
|
6 | <p><%= link_to_attachment @attachment, :text => l(:button_download), :download => true -%> | |
7 | <span class="size">(<%= number_to_human_size @attachment.filesize %>)</span></p> |
|
7 | <span class="size">(<%= number_to_human_size @attachment.filesize %>)</span></p> | |
8 |
|
8 | |||
9 | </div> |
|
9 | </div> |
@@ -23,8 +23,7 | |||||
23 | <% for file in version.attachments %> |
|
23 | <% for file in version.attachments %> | |
24 | <tr class="<%= cycle("odd", "even") %>"> |
|
24 | <tr class="<%= cycle("odd", "even") %>"> | |
25 | <td></td> |
|
25 | <td></td> | |
26 | <td><%= link_to(h(file.filename), {:controller => 'attachments', :action => 'download', :id => file}, |
|
26 | <td><%= link_to_attachment file, :download => true, :title => file.description %></td> | |
27 | :title => file.description) %></td> |
|
|||
28 | <td align="center"><%= format_time(file.created_on) %></td> |
|
27 | <td align="center"><%= format_time(file.created_on) %></td> | |
29 | <td align="center"><%= number_to_human_size(file.filesize) %></td> |
|
28 | <td align="center"><%= number_to_human_size(file.filesize) %></td> | |
30 | <td align="center"><%= file.downloads %></td> |
|
29 | <td align="center"><%= file.downloads %></td> |
@@ -32,8 +32,10 ActionController::Routing::Routes.draw do |map| | |||||
32 | omap.repositories_revision 'repositories/revision/:id/:rev', :action => 'revision' |
|
32 | omap.repositories_revision 'repositories/revision/:id/:rev', :action => 'revision' | |
33 | end |
|
33 | end | |
34 |
|
34 | |||
35 | map.connect 'attachments/:id', :controller => 'attachments', :action => 'show' |
|
35 | map.connect 'attachments/:id', :controller => 'attachments', :action => 'show', :id => /\d+/ | |
36 |
|
36 | map.connect 'attachments/:id/:filename', :controller => 'attachments', :action => 'show', :id => /\d+/, :filename => /.*/ | ||
|
37 | map.connect 'attachments/download/:id/:filename', :controller => 'attachments', :action => 'download', :id => /\d+/, :filename => /.*/ | |||
|
38 | ||||
37 | # Allow downloading Web Service WSDL as a file with an extension |
|
39 | # Allow downloading Web Service WSDL as a file with an extension | |
38 | # instead of a file named 'wsdl' |
|
40 | # instead of a file named 'wsdl' | |
39 | map.connect ':controller/service.wsdl', :action => 'wsdl' |
|
41 | map.connect ':controller/service.wsdl', :action => 'wsdl' |
@@ -33,6 +33,21 class AttachmentsControllerTest < Test::Unit::TestCase | |||||
33 | User.current = nil |
|
33 | User.current = nil | |
34 | end |
|
34 | end | |
35 |
|
35 | |||
|
36 | def test_routing | |||
|
37 | assert_routing('/attachments/1', :controller => 'attachments', :action => 'show', :id => '1') | |||
|
38 | assert_routing('/attachments/1/filename.ext', :controller => 'attachments', :action => 'show', :id => '1', :filename => 'filename.ext') | |||
|
39 | assert_routing('/attachments/download/1', :controller => 'attachments', :action => 'download', :id => '1') | |||
|
40 | assert_routing('/attachments/download/1/filename.ext', :controller => 'attachments', :action => 'download', :id => '1', :filename => 'filename.ext') | |||
|
41 | end | |||
|
42 | ||||
|
43 | def test_recognizes | |||
|
44 | assert_recognizes({:controller => 'attachments', :action => 'show', :id => '1'}, '/attachments/1') | |||
|
45 | assert_recognizes({:controller => 'attachments', :action => 'show', :id => '1'}, '/attachments/show/1') | |||
|
46 | assert_recognizes({:controller => 'attachments', :action => 'show', :id => '1', :filename => 'filename.ext'}, '/attachments/1/filename.ext') | |||
|
47 | assert_recognizes({:controller => 'attachments', :action => 'download', :id => '1'}, '/attachments/download/1') | |||
|
48 | assert_recognizes({:controller => 'attachments', :action => 'download', :id => '1', :filename => 'filename.ext'},'/attachments/download/1/filename.ext') | |||
|
49 | end | |||
|
50 | ||||
36 | def test_show_diff |
|
51 | def test_show_diff | |
37 | get :show, :id => 5 |
|
52 | get :show, :id => 5 | |
38 | assert_response :success |
|
53 | assert_response :success |
General Comments 0
You need to be logged in to leave comments.
Login now