Compare commits

..

1 Commits
0.8.5 ... 0.8.3

Author SHA1 Message Date
Jean-Philippe Lang
79c85c8da0 tagged version 0.8.3
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/tags/0.8.3@2658 e93f8b46-1217-0410-a6f0-8f06a7374b81
2009-04-05 12:59:46 +00:00
49 changed files with 73 additions and 323 deletions

View File

@@ -23,7 +23,7 @@ class IssuesController < ApplicationController
before_filter :find_project, :only => [:new, :update_form, :preview]
before_filter :authorize, :except => [:index, :changes, :gantt, :calendar, :preview, :update_form, :context_menu]
before_filter :find_optional_project, :only => [:index, :changes, :gantt, :calendar]
accept_key_auth :index, :show, :changes
accept_key_auth :index, :changes
helper :journals
helper :projects
@@ -343,12 +343,10 @@ class IssuesController < ApplicationController
@gantt.events = events
end
basename = (@project ? "#{@project.identifier}-" : '') + 'gantt'
respond_to do |format|
format.html { render :template => "issues/gantt.rhtml", :layout => !request.xhr? }
format.png { send_data(@gantt.to_image, :disposition => 'inline', :type => 'image/png', :filename => "#{basename}.png") } if @gantt.respond_to?('to_image')
format.pdf { send_data(gantt_to_pdf(@gantt, @project), :type => 'application/pdf', :filename => "#{basename}.pdf") }
format.png { send_data(@gantt.to_image, :disposition => 'inline', :type => 'image/png', :filename => "#{@project.identifier}-gantt.png") } if @gantt.respond_to?('to_image')
format.pdf { send_data(gantt_to_pdf(@gantt, @project), :type => 'application/pdf', :filename => "#{@project.nil? ? '' : "#{@project.identifier}-" }gantt.pdf") }
end
end

View File

@@ -46,7 +46,6 @@ class MessagesController < ApplicationController
@message.sticky = params[:message]['sticky']
end
if request.post? && @message.save
call_hook(:controller_messages_new_after_save, { :params => params, :message => @message})
attach_files(@message, params[:attachments])
redirect_to :action => 'show', :id => @message
end
@@ -59,7 +58,6 @@ class MessagesController < ApplicationController
@reply.board = @board
@topic.children << @reply
if !@reply.new_record?
call_hook(:controller_messages_reply_after_save, { :params => params, :message => @reply})
attach_files(@reply, params[:attachments])
end
redirect_to :action => 'show', :id => @topic

View File

@@ -65,7 +65,6 @@ class NewsController < ApplicationController
flash[:notice] = l(:label_comment_added)
redirect_to :action => 'show', :id => @news
else
show
render :action => 'show'
end
end

View File

@@ -197,9 +197,6 @@ class TimelogController < ApplicationController
render_403 and return if @time_entry && !@time_entry.editable_by?(User.current)
@time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => Date.today)
@time_entry.attributes = params[:time_entry]
call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
if request.post? and @time_entry.save
flash[:notice] = l(:notice_successful_update)
redirect_back_or_default :action => 'details', :project_id => @time_entry.project

View File

@@ -82,7 +82,6 @@ class WikiController < ApplicationController
@content.author = User.current
# if page is new @page.save will also save content, but not if page isn't a new record
if (@page.new_record? ? @page.save : @content.save)
call_hook(:controller_wiki_edit_after_save, { :params => params, :page => @page})
redirect_to :action => 'index', :id => @project, :page => @page.title
end
end

View File

@@ -385,7 +385,7 @@ module ApplicationHelper
# export:some/file -> Force the download of the file
# Forum messages:
# message#1218 -> Link to message with id 1218
text = text.gsub(%r{([\s\(,\-\>]|^)(!)?(attachment|document|version|commit|source|export|message)?((#|r)(\d+)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]]\W)|,|\s|<|$)}) do |m|
text = text.gsub(%r{([\s\(,\-\>]|^)(!)?(attachment|document|version|commit|source|export|message)?((#|r)(\d+)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]]\W)|\s|<|$)}) do |m|
leading, esc, prefix, sep, oid = $1, $2, $3, $5 || $7, $6 || $8
link = nil
if esc.nil?

View File

@@ -42,12 +42,6 @@ module QueriesHelper
when :subject
h((!@project.nil? && @project != issue.project) ? "#{issue.project.name} - " : '') +
link_to(h(value), :controller => 'issues', :action => 'show', :id => issue)
when :project
link_to(h(value), :controller => 'projects', :action => 'show', :id => value)
when :assigned_to
link_to(h(value), :controller => 'account', :action => 'show', :id => value)
when :author
link_to(h(value), :controller => 'account', :action => 'show', :id => value)
when :done_ratio
progress_bar(value, :width => '80px')
when :fixed_version

View File

@@ -147,7 +147,7 @@ module RepositoriesHelper
def subversion_field_tags(form, repository)
content_tag('p', form.text_field(:url, :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)) +
'<br />(file:///, http://, https://, svn://, svn+[tunnelscheme]://)') +
'<br />(http://, https://, svn://, file:///)') +
content_tag('p', form.text_field(:login, :size => 30)) +
content_tag('p', form.password_field(:password, :size => 30, :name => 'ignore',
:value => ((repository.new_record? || repository.password.blank?) ? '' : ('x'*15)),

View File

@@ -36,7 +36,7 @@ module WikiHelper
words_add += 1
else
del_at = pos unless del_at
deleted << ' ' + h(change[2])
deleted << ' ' + change[2]
words_del += 1
end
end

View File

@@ -65,20 +65,14 @@ class Attachment < ActiveRecord::Base
nil
end
# Copies the temporary file to its final location
# and computes its MD5 hash
# Copy temp file to its final location
def before_save
if @temp_file && (@temp_file.size > 0)
logger.debug("saving '#{self.diskfile}'")
md5 = Digest::MD5.new
File.open(diskfile, "wb") do |f|
buffer = ""
while (buffer = @temp_file.read(8192))
f.write(buffer)
md5.update(buffer)
end
f.write(@temp_file.read)
end
self.digest = md5.hexdigest
self.digest = self.class.digest(diskfile)
end
# Don't save the content type if it's longer than the authorized length
if self.content_type && self.content_type.length > 255
@@ -147,4 +141,11 @@ private
end
df
end
# Returns the MD5 digest of the file at given path
def self.digest(filename)
File.open(filename, 'rb') do |f|
Digest::MD5.hexdigest(f.read)
end
end
end

View File

@@ -112,8 +112,6 @@ class Changeset < ActiveRecord::Base
journal = issue.init_journal(user || User.anonymous, l(:text_status_changed_by_changeset, csettext))
issue.status = fix_status
issue.done_ratio = done_ratio if done_ratio
Redmine::Hook.call_hook(:model_changeset_scan_commit_for_issue_ids_pre_issue_update,
{ :changeset => self, :issue => issue })
issue.save
Mailer.deliver_issue_edit(journal) if Setting.notified_events.include?('issue_updated')
end

View File

@@ -168,7 +168,7 @@ class MailHandler < ActionMailer::Base
@keywords[attr]
else
@keywords[attr] = begin
if (options[:override] || @@handler_options[:allow_override].include?(attr.to_s)) && plain_text_body.gsub!(/^#{attr}[ \t]*:[ \t]*(.+)\s*$/i, '')
if (options[:override] || @@handler_options[:allow_override].include?(attr.to_s)) && plain_text_body.gsub!(/^#{attr}:[ \t]*(.+)\s*$/i, '')
$1.strip
elsif !@@handler_options[:issue][attr].blank?
@@handler_options[:issue][attr]

View File

@@ -368,9 +368,9 @@ class Query < ActiveRecord::Base
Time.now.at_beginning_of_week
sql = "#{db_table}.#{db_field} BETWEEN '%s' AND '%s'" % [connection.quoted_date(from), connection.quoted_date(from + 7.days)]
when "~"
sql = "LOWER(#{db_table}.#{db_field}) LIKE '%#{connection.quote_string(value.first.to_s.downcase)}%'"
sql = "#{db_table}.#{db_field} LIKE '%#{connection.quote_string(value.first)}%'"
when "!~"
sql = "LOWER(#{db_table}.#{db_field}) NOT LIKE '%#{connection.quote_string(value.first.to_s.downcase)}%'"
sql = "#{db_table}.#{db_field} NOT LIKE '%#{connection.quote_string(value.first)}%'"
end
return sql

View File

@@ -20,7 +20,7 @@ require 'redmine/scm/adapters/subversion_adapter'
class Repository::Subversion < Repository
attr_protected :root_url
validates_presence_of :url
validates_format_of :url, :with => /^(http|https|svn(\+[^\s:\/\\]+)?|file):\/\/.+/i
validates_format_of :url, :with => /^(http|https|svn|svn\+ssh|file):\/\/.+/i
def scm_adapter
Redmine::Scm::Adapters::SubversionAdapter

View File

@@ -15,11 +15,8 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require 'rails_generator/secret_key_generator'
class Token < ActiveRecord::Base
belongs_to :user
validates_uniqueness_of :value
@@validity_time = 1.day
@@ -39,7 +36,9 @@ class Token < ActiveRecord::Base
private
def self.generate_token_value
s = Rails::SecretKeyGenerator.new(object_id).generate_secret
s[0, 40]
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
token_value = ''
40.times { |i| token_value << chars[rand(chars.size-1)] }
token_value
end
end

View File

@@ -175,14 +175,8 @@ class User < ActiveRecord::Base
end
def self.find_by_autologin_key(key)
tokens = Token.find_all_by_action_and_value('autologin', key)
# Make sure there's only 1 token that matches the key
if tokens.size == 1
token = tokens.first
if (token.created_on > Setting.autologin.to_i.day.ago) && token.user && token.user.active?
token.user
end
end
token = Token.find_by_action_and_value('autologin', key)
token && (token.created_on > Setting.autologin.to_i.day.ago) && token.user.active? ? token.user : nil
end
# Makes find_by_mail case-insensitive

View File

@@ -22,7 +22,6 @@ class WikiContent < ActiveRecord::Base
belongs_to :page, :class_name => 'WikiPage', :foreign_key => 'page_id'
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
validates_presence_of :text
validates_length_of :comments, :maximum => 255, :allow_nil => true
acts_as_versioned
class Version

View File

@@ -29,7 +29,6 @@
<% end %>
</ul>
<% end %>
<%= call_hook :view_account_left_bottom, :user => @user %>
</div>
<div class="splitcontentright">
@@ -65,7 +64,6 @@
<%= auto_discovery_link_tag(:atom, :controller => 'projects', :action => 'activity', :user_id => @user, :format => :atom, :key => User.current.rss_key) %>
<% end %>
<% end %>
<%= call_hook :view_account_right_bottom, :user => @user %>
</div>
<% html_title @user.name %>

View File

@@ -1,8 +1,8 @@
xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
xml.title truncate_single_line(@title, 100)
xml.link "rel" => "self", "href" => url_for(params.merge(:only_path => false))
xml.link "rel" => "alternate", "href" => url_for(params.merge(:only_path => false, :format => nil, :key => nil))
xml.link "rel" => "self", "href" => url_for(params.merge({:format => nil, :only_path => false}))
xml.link "rel" => "alternate", "href" => url_for(:controller => 'welcome', :only_path => false)
xml.id url_for(:controller => 'welcome', :only_path => false)
xml.updated((@items.first ? @items.first.event_datetime : Time.now).xmlschema)
xml.author { xml.name "#{Setting.app_title}" }
@@ -21,10 +21,10 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
author = item.event_author if item.respond_to?(:event_author)
xml.author do
xml.name(author)
xml.email(author.mail) if author.is_a?(User) && !author.mail.blank? && !author.pref.hide_mail
xml.email(author.mail) if author.respond_to?(:mail) && !author.mail.blank?
end if author
xml.content "type" => "html" do
xml.text! textilizable(item, :event_description, :only_path => false)
xml.text! textilizable(item.event_description)
end
end
end

View File

@@ -15,7 +15,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
xml.updated change.created_on.xmlschema
xml.author do
xml.name change.user.name
xml.email(change.user.mail) if change.user.is_a?(User) && !change.user.mail.blank? && !change.user.pref.hide_mail
xml.email(change.user.mail)
end
xml.content "type" => "html" do
xml.text! '<ul>'
@@ -23,7 +23,7 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
xml.text! '<li>' + show_detail(detail, false) + '</li>'
end
xml.text! '</ul>'
xml.text! textilizable(change, :notes, :only_path => false) unless change.notes.blank?
xml.text! textilizable(change.notes) unless change.notes.blank?
end
end
end

View File

@@ -45,7 +45,7 @@
</tr>
<tr>
<% n = 0 -%>
<% @issue.custom_field_values.each do |value| -%>
<% @issue.custom_values.each do |value| -%>
<td valign="top"><b><%=h value.custom_field.name %>:</b></td><td valign="top"><%= simple_format(h(show_value(value))) %></td>
<% n = n + 1
if (n > 1)

View File

@@ -2,7 +2,7 @@
<ul>
<% @issues.each do |issue| -%>
<li><%=h issue.project %> - <%=link_to("#{issue.tracker} ##{issue.id}", :controller => 'issues', :action => 'show', :id => issue, :only_path => false)%>: <%=h issue.subject %></li>
<li><%=h "#{issue.project} - #{issue.tracker} ##{issue.id}: #{issue.subject}" %></li>
<% end -%>
</ul>

View File

@@ -1,8 +1,6 @@
<h2><%=l(:label_settings)%></h2>
<% tabs = project_settings_tabs %>
<% if tabs.any? %>
<% selected_tab = params[:tab] ? params[:tab].to_s : tabs.first[:name] %>
<div class="tabs">
@@ -22,8 +20,5 @@
:style => (tab[:name] != selected_tab ? 'display:none' : nil),
:class => 'tab-content') %>
<% end -%>
<% else %>
<p class="nodata"><%= l(:label_no_data) %></p>
<% end %>
<% html_title(l(:label_settings)) -%>

View File

@@ -32,7 +32,6 @@
<p><%= link_to l(:label_issue_view_all), :controller => 'issues', :action => 'index', :project_id => @project, :set_filter => 1 %></p>
</div>
<% end %>
<%= call_hook(:view_projects_show_left, :project => @project) %>
</div>
<div class="splitcontentright">
@@ -54,7 +53,6 @@
<p><%= link_to l(:label_news_view_all), :controller => 'news', :action => 'index', :project_id => @project %></p>
</div>
<% end %>
<%= call_hook(:view_projects_show_right, :project => @project) %>
</div>
<% content_for :sidebar do %>

View File

@@ -4,7 +4,6 @@
<th><%= l(:label_project) %></th>
<th><%= l(:label_role) %></th>
<th style="width:15%"></th>
<%= call_hook(:view_users_memberships_table_header, :user => @user )%>
</thead>
<tbody>
<% @memberships.each do |membership| %>
@@ -20,7 +19,6 @@
<td align="center">
<%= link_to l(:button_delete), {:action => 'destroy_membership', :id => @user, :membership_id => membership }, :method => :post, :class => 'icon icon-del' %>
</td>
<%= call_hook(:view_users_memberships_table_row, :user => @user, :membership => membership, :roles => @roles, :projects => @projects )%>
</tr>
</tbody>
<% end; reset_cycle %>

View File

@@ -1,6 +1,5 @@
<div class="contextual">
<%= link_to_if_authorized l(:button_edit), {:controller => 'versions', :action => 'edit', :id => @version}, :class => 'icon icon-edit' %>
<%= call_hook(:view_versions_show_contextual, { :version => @version, :project => @project }) %>
</div>
<h2><%= h(@version.name) %></h2>

View File

@@ -9,7 +9,6 @@
<%= link_to l(:label_news_view_all), :controller => 'news' %>
</div>
<% end %>
<%= call_hook(:view_welcome_index_left, :projects => @projects) %>
</div>
<div class="splitcontentright">
@@ -26,7 +25,6 @@
</ul>
</div>
<% end %>
<%= call_hook(:view_welcome_index_right, :projects => @projects) %>
</div>
<% content_for :header_tags do %>

View File

@@ -20,11 +20,11 @@
<% unless @pages.empty? %>
<p class="other-formats">
<%= l(:label_export_to) %>
<span><%= link_to 'Atom', {:controller => 'projects', :action => 'activity', :id => @project, :show_wiki_edits => 1, :format => 'atom', :key => User.current.rss_key}, :class => 'feed' %></span>
<span><%= link_to 'Atom', {:controller => 'projects', :action => 'activity', :id => @project, :show_wiki_pages => 1, :format => 'atom', :key => User.current.rss_key}, :class => 'feed' %></span>
<span><%= link_to 'HTML', {:action => 'special', :page => 'export'}, :class => 'html' %></span>
</p>
<% end %>
<% content_for :header_tags do %>
<%= auto_discovery_link_tag(:atom, :controller => 'projects', :action => 'activity', :id => @project, :show_wiki_edits => 1, :format => 'atom', :key => User.current.rss_key) %>
<%= auto_discovery_link_tag(:atom, :controller => 'projects', :action => 'activity', :id => @project, :show_wiki_pages => 1, :format => 'atom', :key => User.current.rss_key) %>
<% end %>

View File

@@ -13,11 +13,11 @@
<% unless @pages.empty? %>
<p class="other-formats">
<%= l(:label_export_to) %>
<span><%= link_to 'Atom', {:controller => 'projects', :action => 'activity', :id => @project, :show_wiki_edits => 1, :format => 'atom', :key => User.current.rss_key}, :class => 'feed' %></span>
<span><%= link_to 'Atom', {:controller => 'projects', :action => 'activity', :id => @project, :show_wiki_pages => 1, :format => 'atom', :key => User.current.rss_key}, :class => 'feed' %></span>
<span><%= link_to 'HTML', {:action => 'special', :page => 'export'} %></span>
</p>
<% end %>
<% content_for :header_tags do %>
<%= auto_discovery_link_tag(:atom, :controller => 'projects', :action => 'activity', :id => @project, :show_wiki_edits => 1, :format => 'atom', :key => User.current.rss_key) %>
<%= auto_discovery_link_tag(:atom, :controller => 'projects', :action => 'activity', :id => @project, :show_wiki_pages => 1, :format => 'atom', :key => User.current.rss_key) %>
<% end %>

View File

@@ -1,30 +0,0 @@
# Copyright (c) 2009 Michael Koziarski <michael@koziarski.com>
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
require 'bigdecimal'
alias BigDecimalUnsafe BigDecimal
# This fixes CVE-2009-1904 however it removes legitimate functionality that your
# application may depend on. You are *strongly* advised to upgrade your ruby
# rather than relying on this fix for an extended period of time.
def BigDecimal(initial, digits=0)
if initial.size > 255 || initial =~ /e/i
raise "Invalid big Decimal Value"
end
BigDecimalUnsafe(initial, digits)
end

View File

@@ -5,37 +5,6 @@ Copyright (C) 2006-2009 Jean-Philippe Lang
http://www.redmine.org/
== 2009-09-13 v0.8.5
* Incoming mail handler : Allow spaces between keywords and colon
* Do not require a non-word character after a comma in Redmine links
* Include issue hyperlinks in reminder emails
* Prevent nil error when retrieving svn version
* Various plugin hooks added
* Add plugins information to script/about
* Fixed: 500 Internal Server Error is raised if add an empty comment to the news
* Fixed: Atom links for wiki pages are not correct
* Fixed: Atom feeds leak email address
* Fixed: Case sensitivity in Issue filtering
* Fixed: When reading RSS feed, the inline-embedded images are not properly shown
== 2009-05-17 v0.8.4
* Allow textile mailto links
* Fixed: memory consumption when uploading file
* Fixed: Mercurial integration doesn't work if Redmine is installed in folder path containing space
* Fixed: an error is raised when no tab is available on project settings
* Fixed: insert image macro corrupts urls with excalamation marks
* Fixed: error on cross-project gantt PNG export
* Fixed: self and alternate links in atom feeds do not respect Atom specs
* Fixed: accept any svn tunnel scheme in repository URL
* Fixed: issues/show should accept user's rss key
* Fixed: consistency of custom fields display on the issue detail view
* Fixed: wiki comments length validation is missing
* Fixed: weak autologin token generation algorithm causes duplicate tokens
== 2009-04-05 v0.8.3
* Separate project field and subject in cross-project issue view

View File

@@ -681,6 +681,6 @@ text_user_mail_option: "De los proyectos no seleccionados, sólo recibirá notif
text_user_wrote: '%s escribió:'
text_wiki_destroy_confirmation: ¿Seguro que quiere borrar el wiki y todo su contenido?
text_workflow_edit: Seleccionar un flujo de trabajo para actualizar
text_plugin_assets_writable: Se puede escribir en el directorio de extensiones activas
warning_attachments_not_saved: "No pudieron guardarse %d fichero(s)."
button_create_and_continue: Crear y continuar
text_plugin_assets_writable: Plugin assets directory writable
warning_attachments_not_saved: "%d file(s) could not be saved."
button_create_and_continue: Create and continue

View File

@@ -792,7 +792,7 @@ class RedCloth3 < String
(?:\(([^)]+?)\)(?="))? # $title
":
( # $url
(\/|[a-zA-Z]+:\/\/|www\.|mailto:) # $proto
(\/|[a-zA-Z]+:\/\/|www\.) # $proto
[\w\/]\S+?
)
(\/)? # $slash
@@ -907,7 +907,7 @@ class RedCloth3 < String
end
IMAGE_RE = /
(<p>|\s|^) # start of line?
(<p>|.|^) # start of line?
\! # opening
(\<|\=|\>)? # optional alignment atts
(#{C}) # optional style,class atts

View File

@@ -1,16 +0,0 @@
module Redmine
class About
def self.print_plugin_info
plugins = Redmine::Plugin.registered_plugins
if !plugins.empty?
column_with = plugins.map {|internal_name, plugin| plugin.name.length}.max
puts "\nAbout your Redmine plugins"
plugins.each do |internal_name, plugin|
puts sprintf("%-#{column_with}s %s", plugin.name, plugin.version)
end
end
end
end
end

View File

@@ -105,7 +105,7 @@ module Redmine
# makes Mercurial produce a xml output.
def revisions(path=nil, identifier_from=nil, identifier_to=nil, options={})
revisions = Revisions.new
cmd = "#{HG_BIN} --debug --encoding utf8 -R #{target('')} log -C --style #{shell_quote self.class.template_path}"
cmd = "#{HG_BIN} --debug --encoding utf8 -R #{target('')} log -C --style #{self.class.template_path}"
if identifier_from && identifier_to
cmd << " -r #{identifier_from.to_i}:#{identifier_to.to_i}"
elsif identifier_from

View File

@@ -37,7 +37,7 @@ module Redmine
version = nil
shellout(cmd) do |io|
# Read svn version in first returned line
if m = io.gets.to_s.match(%r{((\d+\.)+\d+)})
if m = io.gets.match(%r{((\d+\.)+\d+)})
version = m[0].scan(%r{\d+}).collect(&:to_i)
end
end

View File

@@ -4,7 +4,7 @@ module Redmine
module VERSION #:nodoc:
MAJOR = 0
MINOR = 8
TINY = 4
TINY = 3
# Branch values:
# * official release: nil

View File

@@ -195,13 +195,8 @@ task :migrate_from_mantis => :environment do
file_type
end
def read(*args)
if @read_finished
nil
else
@read_finished = true
content
end
def read
content
end
end

View File

@@ -135,15 +135,8 @@ namespace :redmine do
File.file? trac_fullpath
end
def open
File.open("#{trac_fullpath}", 'rb') {|f|
@file = f
yield self
}
end
def read(*args)
@file.read(*args)
def read
File.open("#{trac_fullpath}", 'rb').read
end
def description
@@ -513,14 +506,12 @@ namespace :redmine do
# Attachments
ticket.attachments.each do |attachment|
next unless attachment.exist?
attachment.open {
a = Attachment.new :created_on => attachment.time
a.file = attachment
a.author = find_or_create_user(attachment.author)
a.container = i
a.description = attachment.description
migrated_ticket_attachments += 1 if a.save
}
a = Attachment.new :created_on => attachment.time
a.file = attachment
a.author = find_or_create_user(attachment.author)
a.container = i
a.description = attachment.description
migrated_ticket_attachments += 1 if a.save
end
# Custom fields
@@ -565,14 +556,12 @@ namespace :redmine do
page.attachments.each do |attachment|
next unless attachment.exist?
next if p.attachments.find_by_filename(attachment.filename.gsub(/^.*(\\|\/)/, '').gsub(/[^\w\.\-]/,'_')) #add only once per page
attachment.open {
a = Attachment.new :created_on => attachment.time
a.file = attachment
a.author = find_or_create_user(attachment.author)
a.description = attachment.description
a.container = p
migrated_wiki_attachments += 1 if a.save
}
a = Attachment.new :created_on => attachment.time
a.file = attachment
a.author = find_or_create_user(attachment.author)
a.description = attachment.description
a.container = p
migrated_wiki_attachments += 1 if a.save
end
end

View File

@@ -1,6 +1,3 @@
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../config/boot'
$LOAD_PATH.unshift "#{RAILTIES_PATH}/builtin/rails_info"
require 'commands/about'
Redmine::About.print_plugin_info
require 'commands/about'

View File

@@ -109,16 +109,4 @@ attachments_009:
filename: version_file.zip
author_id: 2
content_type: application/octet-stream
attachments_010:
created_on: 2006-07-19 21:07:27 +02:00
container_type: Issue
container_id: 2
downloads: 0
disk_filename: 060719210727_picture.jpg
digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
id: 10
filesize: 452
filename: picture.jpg
author_id: 2
content_type: image/jpeg

View File

@@ -13,11 +13,4 @@ journals_002:
journalized_type: Issue
user_id: 2
journalized_id: 1
journals_003:
created_on: <%= 1.days.ago.to_date.to_s(:db) %>
notes: "A comment with inline image: !picture.jpg!"
id: 3
journalized_type: Issue
user_id: 2
journalized_id: 2

View File

@@ -1,43 +0,0 @@
Return-Path: <jsmith@somenet.foo>
Received: from osiris ([127.0.0.1])
by OSIRIS
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
From: "John Smith" <jsmith@somenet.foo>
To: <redmine@somenet.foo>
Subject: New ticket on a given project
Date: Sun, 22 Jun 2008 12:28:07 +0200
MIME-Version: 1.0
Content-Type: text/plain;
format=flowed;
charset="iso-8859-1";
reply-type=original
Content-Transfer-Encoding: 7bit
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In
in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras
sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum
id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus
eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique
sed, mauris. Pellentesque habitant morbi tristique senectus et netus et
malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse
platea dictumst.
Nulla et nunc. Duis pede. Donec et ipsum. Nam ut dui tincidunt neque
sollicitudin iaculis. Duis vitae dolor. Vestibulum eget massa. Sed lorem.
Nullam volutpat cursus erat. Cras felis dolor, lacinia quis, rutrum et,
dictum et, ligula. Sed erat nibh, gravida in, accumsan non, placerat sed,
massa. Sed sodales, ante fermentum ultricies sollicitudin, massa leo
pulvinar dui, a gravida orci mi eget odio. Nunc a lacus.
Project : onlinestore
Tracker: Feature request
category : Stock management
priority: Urgent

View File

@@ -255,14 +255,6 @@ class IssuesControllerTest < Test::Unit::TestCase
:child => { :tag => 'legend',
:content => /Notes/ } }
end
def test_show_atom
get :show, :id => 2, :format => 'atom'
assert_response :success
assert_template 'changes'
# Inline image
assert @response.body.include?("&lt;img src=\"http://test.host/attachments/download/10\" alt=\"\" /&gt;")
end
def test_show_export_to_pdf
get :show, :id => 3, :format => 'pdf'

View File

@@ -118,15 +118,6 @@ class NewsControllerTest < Test::Unit::TestCase
assert_equal User.find(2), comment.author
end
def test_empty_comment_should_not_be_added
@request.session[:user_id] = 2
assert_no_difference 'Comment.count' do
post :add_comment, :id => 1, :comment => { :comments => '' }
assert_response :success
assert_template 'show'
end
end
def test_destroy_comment
comments_count = News.find(1).comments.size
@request.session[:user_id] = 2

View File

@@ -22,19 +22,6 @@ class AttachmentTest < Test::Unit::TestCase
def setup
end
def test_create
a = Attachment.new(:container => Issue.find(1),
:file => test_uploaded_file("testfile.txt", "text/plain"),
:author => User.find(1))
assert a.save
assert_equal 'testfile.txt', a.filename
assert_equal 59, a.filesize
assert_equal 'text/plain', a.content_type
assert_equal 0, a.downloads
assert_equal Digest::MD5.hexdigest(test_uploaded_file("testfile.txt", "text/plain").read), a.digest
assert File.exist?(a.diskfile)
end
def test_diskfilename
assert Attachment.disk_filename("test_file.txt") =~ /^\d{12}_test_file.txt$/
@@ -43,4 +30,8 @@ class AttachmentTest < Test::Unit::TestCase
assert_equal 'f8139524ebb8f32e51976982cd20a85d', Attachment.disk_filename("test_accentué")[13..-1]
assert_equal 'cbb5b0f30978ba03731d61f9f6d10011', Attachment.disk_filename("test_accentué.ça")[13..-1]
end
def test_digest
assert_equal '1478adae0d4eb06d35897518540e25d6', Attachment.digest(Test::Unit::TestCase.fixture_path + "/files/testfile.txt")
end
end

View File

@@ -55,8 +55,6 @@ class ApplicationHelperTest < HelperTestCase
'ftp://foo.bar' => '<a class="external" href="ftp://foo.bar">ftp://foo.bar</a>',
'ftps://foo.bar' => '<a class="external" href="ftps://foo.bar">ftps://foo.bar</a>',
'sftp://foo.bar' => '<a class="external" href="sftp://foo.bar">sftp://foo.bar</a>',
# two exclamation marks
'http://example.net/path!602815048C7B5C20!302.html' => '<a class="external" href="http://example.net/path!602815048C7B5C20!302.html">http://example.net/path!602815048C7B5C20!302.html</a>',
}
to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
end
@@ -107,11 +105,7 @@ class ApplicationHelperTest < HelperTestCase
'"link (Link title with "double-quotes")":http://foo.bar' => '<a href="http://foo.bar" title="Link title with &quot;double-quotes&quot;" class="external">link</a>',
"This is not a \"Link\":\n\nAnother paragraph" => "This is not a \"Link\":</p>\n\n\n\t<p>Another paragraph",
# no multiline link text
"This is a double quote \"on the first line\nand another on a second line\":test" => "This is a double quote \"on the first line<br />\nand another on a second line\":test",
# mailto link
"\"system administrator\":mailto:sysadmin@example.com?subject=redmine%20permissions" => "<a href=\"mailto:sysadmin@example.com?subject=redmine%20permissions\">system administrator</a>",
# two exclamation marks
'"a link":http://example.net/path!602815048C7B5C20!302.html' => '<a href="http://example.net/path!602815048C7B5C20!302.html" class="external">a link</a>',
"This is a double quote \"on the first line\nand another on a second line\":test" => "This is a double quote \"on the first line<br />\nand another on a second line\":test"
}
to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
end
@@ -122,8 +116,6 @@ class ApplicationHelperTest < HelperTestCase
changeset_link = link_to('r1', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 1},
:class => 'changeset', :title => 'My very first commit')
changeset_link2 = link_to('r2', {:controller => 'repositories', :action => 'revision', :id => 'ecookbook', :rev => 2},
:class => 'changeset', :title => 'This commit fixes #1, #2 and references #1 & #3')
document_link = link_to('Test document', {:controller => 'documents', :action => 'show', :id => 1},
:class => 'document')
@@ -141,9 +133,6 @@ class ApplicationHelperTest < HelperTestCase
'#3, #3 and #3.' => "#{issue_link}, #{issue_link} and #{issue_link}.",
# changesets
'r1' => changeset_link,
'r1.' => "#{changeset_link}.",
'r1, r2' => "#{changeset_link}, #{changeset_link2}",
'r1,r2' => "#{changeset_link},#{changeset_link2}",
# documents
'document#1' => document_link,
'document:"Test document"' => document_link,

View File

@@ -92,21 +92,6 @@ class MailHandlerTest < Test::Unit::TestCase
assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
end
def test_add_issue_with_spaces_between_attribute_and_separator
issue = submit_email('ticket_with_spaces_between_attribute_and_separator.eml', :allow_override => 'tracker,category,priority')
assert issue.is_a?(Issue)
assert !issue.new_record?
issue.reload
assert_equal 'New ticket on a given project', issue.subject
assert_equal User.find_by_login('jsmith'), issue.author
assert_equal Project.find(2), issue.project
assert_equal 'Feature request', issue.tracker.to_s
assert_equal 'Stock management', issue.category.to_s
assert_equal 'Urgent', issue.priority.to_s
assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
end
def test_add_issue_with_attachment_to_specific_project
issue = submit_email('ticket_with_attachment.eml', :issue => {:project => 'onlinestore'})
assert issue.is_a?(Issue)

View File

@@ -150,17 +150,15 @@ class QueryTest < Test::Unit::TestCase
def test_operator_contains
query = Query.new(:project => Project.find(1), :name => '_')
query.add_filter('subject', '~', ['uNable'])
assert query.statement.include?("LOWER(#{Issue.table_name}.subject) LIKE '%unable%'")
result = find_issues_with_query(query)
assert result.empty?
result.each {|issue| assert issue.subject.downcase.include?('unable') }
query.add_filter('subject', '~', ['string'])
assert query.statement.include?("#{Issue.table_name}.subject LIKE '%string%'")
find_issues_with_query(query)
end
def test_operator_does_not_contains
query = Query.new(:project => Project.find(1), :name => '_')
query.add_filter('subject', '!~', ['uNable'])
assert query.statement.include?("LOWER(#{Issue.table_name}.subject) NOT LIKE '%unable%'")
query.add_filter('subject', '!~', ['string'])
assert query.statement.include?("#{Issue.table_name}.subject NOT LIKE '%string%'")
find_issues_with_query(query)
end