Compare commits

...
84 Commits
Author SHA1 Message Date
Toshi MARUYAMA 5cefd924a2 Merged r10689 from trunk to 2.0-stable
Partial backout r10263.

Backout replacing shoulda context of test/unit/helpers/issues_helper_test.rb.
Test methods in shoulda context do not run on Ruby 1.8.7-p370.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10695 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-10-22 03:34:29 +00:00
Toshi MARUYAMA 1d888f25f6 Merged r10688 from trunk to 2.0-stable
Backout r10253.

Backout replacing shoulda context of test/unit/helpers/issues_helper_test.rb.
Test methods in shoulda context do not run on Ruby 1.8.7-p370.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10694 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-10-22 03:34:02 +00:00
Jean-Philippe Lang 45b297f3ae Updates for 2.0.4 release.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10393 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-09-16 12:44:38 +00:00
Jean-Philippe Lang 0dc0860226 XML output broken with builder 3.0.1.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10307 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-09-06 22:34:40 +00:00
Jean-Philippe Lang 1c0ef8a0c2 Merged r10304 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10305 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-09-06 17:34:40 +00:00
Jean-Philippe Lang dd3bd9a708 Merged r10134 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10303 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-09-06 17:30:59 +00:00
Jean-Philippe Lang 9ab59b43b8 Merged r10147 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10302 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-09-06 17:30:01 +00:00
Jean-Philippe Lang e56a1c98e3 Merged r9738, r10135 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10301 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-09-06 17:28:51 +00:00
Jean-Philippe Lang 4233589ee1 Merged r10294 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10298 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-09-06 17:21:53 +00:00
Toshi MARUYAMA 4d325a3b8a Merged r10287 from trunk to 2.0-stable
fix redmine_plugin generator output in USAGE.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10289 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-09-03 17:19:25 +00:00
Toshi MARUYAMA 16e4bdbc8a Merged r10286 from trunk to 2.0-stable
fix plugin generator script name of USAGE on Rails3.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10288 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-09-03 17:19:10 +00:00
Toshi MARUYAMA 2558ad0845 Merged r10252 from trunk to 2.0-stable (#11752)
scm: git: use with_settings at test_diff_truncated of functional test.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10274 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-09-01 07:26:15 +00:00
Toshi MARUYAMA 08ce7df5ea Merged r10251 from trunk to 2.0-stable (#11752)
scm: git: use diff_max_lines_displayed setting at test_diff_with_rev_and_path of functional test.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10273 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-09-01 07:26:00 +00:00
Toshi MARUYAMA d9dfa7b2b6 Merged r10245 from trunk to 2.0-stable (#11752)
scm: git: add functional test of diff with revision and path.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10272 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-09-01 07:25:45 +00:00
Toshi MARUYAMA e573b0455b Merged r10255 from trunk to 2.0-stable
add missing fixture to test/unit/lib/redmine/safe_attributes_test.rb.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10271 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-09-01 07:25:28 +00:00
Toshi MARUYAMA df6da812e7 Merged r10249 from trunk to 2.0-stable
set language en to test_label_for at test/unit/query_test.rb.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10270 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-09-01 07:25:11 +00:00
Toshi MARUYAMA 8810a4a343 Merged r9949 from trunk to 2.0-stable
Tests should not change settings.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10269 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-09-01 07:24:56 +00:00
Toshi MARUYAMA cf6382b92f Merged r10256 from trunk to 2.0-stable
add missing fixtures to test/unit/lib/redmine/hook_test.rb.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10268 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-09-01 07:24:38 +00:00
Toshi MARUYAMA 90c44e490e Merged r10253, r10257, r10263 and r10264 from trunk to 2.0-stable
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10267 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-09-01 07:24:21 +00:00
Toshi MARUYAMA 004a98df86 Merged r10219 from trunk to 2.0-stable (#11665)
add functional test to create non default document category.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10229 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-08-22 08:56:52 +00:00
Toshi MARUYAMA 33bf6d60d8 Merged r10216 from trunk
add missing fixtures to test/functional/documents_controller_test.rb

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10217 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-08-21 04:52:01 +00:00
Toshi MARUYAMA 004ec7a251 Merged r10213 from trunk
add missing fixtures to test/unit/document_test.rb

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10214 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-08-21 02:23:25 +00:00
Toshi MARUYAMA 656a656697 Merged r10169 from trunk to 2.0-stable (#11600)
fix plural form of the abbreviation for hours in Brazilian Portuguese.

Contributed by Mauricio Piacentini.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10171 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-08-08 01:33:43 +00:00
Toshi MARUYAMA 37c7de41ce Merged r10167 from trunk to 2.0-stable
Gemfile: mocha version up 0.12.3.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10170 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-08-08 01:33:28 +00:00
Jean-Philippe Lang b2e095cb87 Merged r10155 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10156 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-08-02 18:23:49 +00:00
Toshi MARUYAMA 10706c5a11 Merged r10011 from trunk to 2.0-stable
Removed assertion that is susceptible to fail if test runs slowly.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10140 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-07-31 11:12:57 +00:00
Toshi MARUYAMA 568cce5b22 Merged r10137 from trunk to 2.0-stable (#10320, #10818)
Gemfile: prevent "rake db:migrate RAILS_ENV=test" causes exception on Ruby 1.9.3.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10138 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-07-31 08:17:19 +00:00
Toshi MARUYAMA 48e4facc3c Merged r10083 from trunk to 2.0-stable (#11511)
fix confirmation page has broken HTML when a project folding sub project is deleted.

Contributed by Haruka Yoshihara.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10084 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-07-27 00:40:57 +00:00
Toshi MARUYAMA d42a675668 Merged r10055 from trunk to 2.0-stable (#11448)
Russian translation for 1.4-stable and 2.0-stable updated by Александр Закревский.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@10056 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-07-20 10:05:54 +00:00
Jean-Philippe Lang 7dde34460c Merged r9984 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9999 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-07-15 15:56:23 +00:00
Jean-Philippe Lang 873a5cda4f Merged r9982 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9998 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-07-15 15:55:15 +00:00
Jean-Philippe Lang d006e357c0 Merged r9924 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9959 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-07-08 12:37:47 +00:00
Jean-Philippe Lang 004bc127b2 Merged r9925 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9958 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-07-08 12:36:31 +00:00
Jean-Philippe Lang 70d2f30e9f Merged r9909 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9957 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-07-08 12:35:11 +00:00
Jean-Philippe Lang 6488210ec1 Merged r9895 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9956 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-07-08 12:34:09 +00:00
Jean-Philippe Lang 3cc0730f54 Merged r9908 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9954 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-07-08 12:30:57 +00:00
Jean-Philippe Lang 4491d483f4 Merged r9896 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9953 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-07-08 12:29:27 +00:00
Jean-Philippe Lang a6252e6c6f Merged r9894 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9952 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-07-08 12:27:56 +00:00
Jean-Philippe Lang ba074d776b Merged r9875 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9950 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-07-08 12:24:49 +00:00
Toshi MARUYAMA bf9aea9a15 Merged r9911 from trunk to 2.0-stable (#11328)
Fix Japanese mistranslation for 'label_language_based'.

Contributed by Go MAEDA.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9913 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-07-05 12:36:41 +00:00
Toshi MARUYAMA 7fe9dac8c5 Merge r9871 from trunk
fix test_global_index of functional activities controller test fails around UTC 00:00.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9873 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-19 02:11:16 +00:00
Toshi MARUYAMA 711328d172 Merge r9870 from trunk
scm: git: fix unable to run unit lib test if git binary is not available on Windows.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9872 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-19 02:10:55 +00:00
Jean-Philippe Lang 342b3302cf Merged r9864 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9865 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-18 18:45:14 +00:00
Jean-Philippe Lang 32e3d6e1b1 Merged r9861 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9862 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-18 18:34:01 +00:00
Jean-Philippe Lang 8d2d46bd8e Merged r9858 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9859 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-18 18:17:49 +00:00
Toshi MARUYAMA 7f03576b8d Merged r9853 from trunk (#10688)
fix PDF export tables problems.

Contributed by Jun NAITOH.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9854 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-17 13:10:48 +00:00
Toshi MARUYAMA e757600b39 Merge r9750 from trunk
scm: git: skip Latin-1 path tests on Git for Windows above 1.7.10

Git for Windows (msysGit) changed internal API from ANSI to Unicode in 1.7.10.
http://code.google.com/p/msysgit/issues/detail?id=80

So, Latin-1 path tests fail on Japanese Windows.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9851 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-17 10:52:18 +00:00
Jean-Philippe Lang 68560c13fe Merged r9830 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9848 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-17 09:02:24 +00:00
Jean-Philippe Lang 309f7b75fd Merged r9837 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9846 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-17 08:59:42 +00:00
Jean-Philippe Lang dbb93692ff Merged r9836 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9845 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-17 08:58:20 +00:00
Jean-Philippe Lang 5f6289d6be Merged r9831 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9843 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-17 08:56:11 +00:00
Jean-Philippe Lang 081ee54bee Merged r9822 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9840 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-17 08:52:40 +00:00
Jean-Philippe Lang 1d0fb85179 Merged r9796 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9839 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-17 08:51:04 +00:00
Etienne Massip 887e7f8647 Merged r9832 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9834 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-14 21:09:56 +00:00
Toshi MARUYAMA df05edff3d Merged r9814 from trunk
fix test_user_index of activities controller test fails at Japanese morning and afternoon.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9818 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-11 06:56:11 +00:00
Jean-Philippe Lang 67057ea3e9 Merged r9798 to r9801 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9802 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-10 13:39:42 +00:00
Jean-Philippe Lang 381e7156c2 Merged r9782, r9784, r9794 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9795 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-09 14:19:13 +00:00
Jean-Philippe Lang f9ee57f2c1 Merged r9781 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9793 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-09 13:58:40 +00:00
Jean-Philippe Lang fc13aef5bb Merged r9785 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9792 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-09 13:56:56 +00:00
Jean-Philippe Lang 4973350243 Merged r9783 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9789 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-09 13:45:55 +00:00
Jean-Philippe Lang fcbb8acdb7 Merged r9786 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9788 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-09 13:44:32 +00:00
Toshi MARUYAMA d79258f17f Merged r9777 from trunk (#11113)
fix German "field_multiple" translation glitch by Andreas Deininger.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9778 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-08 07:49:16 +00:00
Jean-Philippe Lang c4736ed42b Merged r9770 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9771 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-05 17:19:37 +00:00
Jean-Philippe Lang 47fb2eb998 Merged r9768 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9769 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-05 17:11:06 +00:00
Jean-Philippe Lang e9813791cb Merged r9759 to r9764.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9766 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-03 16:32:21 +00:00
Jean-Philippe Lang 5f23ebc31c Merged r9755 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9756 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-03 08:50:26 +00:00
Jean-Philippe Lang b88c95b0fb Merged r9740 and r9741 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9753 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-03 08:10:00 +00:00
Jean-Philippe Lang 93d8f99884 Merged r9742 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9751 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-06-03 08:07:07 +00:00
Toshi MARUYAMA 07edb10518 Merged r9734 from trunk (#11032)
fix project list is not shown on Email notifications.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9739 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-05-28 10:31:19 +00:00
Jean-Philippe Lang 0512a30368 Updates for 2.0.1 release.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9732 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-05-28 07:24:38 +00:00
Jean-Philippe Lang bc945d78a6 Merged r9719, r9726, r9727 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9729 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-05-27 19:39:26 +00:00
Jean-Philippe Lang 8cd0626075 Merged r9701 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9728 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-05-27 19:25:30 +00:00
Jean-Philippe Lang 035bd65a5a Merged r9710 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9725 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-05-26 09:50:51 +00:00
Jean-Philippe Lang 955d2b134d Merged r9711 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9724 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-05-26 09:50:01 +00:00
Jean-Philippe Lang 743b55a3f9 Merged r9718 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9723 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-05-26 09:49:19 +00:00
Jean-Philippe Lang 881595f7f0 Merged r9712 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9722 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-05-26 09:48:37 +00:00
Jean-Philippe Lang 7f51bab0fc Merged r9709 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9721 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-05-26 09:47:48 +00:00
Jean-Philippe Lang 84d5092508 Merged r9699 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9720 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-05-26 09:40:31 +00:00
Jean-Philippe Lang 352d177f7e Merged r9703 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9706 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-05-21 19:00:26 +00:00
Jean-Philippe Lang 821ea2a757 Merged r9702 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9705 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-05-21 18:59:31 +00:00
Jean-Philippe Lang 7cd7b1bd8b Merged r9700 from trunk.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9704 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-05-21 18:58:29 +00:00
Jean-Philippe Lang cf139e25a7 Merged r9696 from trunk. Updates for 2.0.0 release.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9697 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-05-14 22:19:13 +00:00
Jean-Philippe Lang 8b09f5d27d Set version to stable.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9695 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-05-14 17:02:27 +00:00
Jean-Philippe Lang d138df5241 Added 2.0-stable branch.
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/branches/2.0-stable@9694 e93f8b46-1217-0410-a6f0-8f06a7374b81
2012-05-14 16:48:29 +00:00
160 changed files with 1237 additions and 376 deletions
+6 -3
View File
@@ -1,11 +1,11 @@
source 'http://rubygems.org' source 'http://rubygems.org'
gem 'rails', '3.2.3' gem 'rails', '3.2.6'
gem 'prototype-rails', '3.2.1' gem 'prototype-rails', '3.2.1'
gem "i18n", "~> 0.6.0" gem "i18n", "~> 0.6.0"
gem "coderay", "~> 1.0.6" gem "coderay", "~> 1.0.6"
gem "fastercsv", "~> 1.5.0", :platforms => [:mri_18, :mingw_18, :jruby] gem "fastercsv", "~> 1.5.0", :platforms => [:mri_18, :mingw_18, :jruby]
gem "builder" gem "builder", "3.0.0"
# Optional gem for LDAP authentication # Optional gem for LDAP authentication
group :ldap do group :ldap do
@@ -69,11 +69,14 @@ end
group :development do group :development do
gem "rdoc", ">= 2.4.2" gem "rdoc", ">= 2.4.2"
gem "yard"
end end
group :test do group :test do
gem "shoulda", "~> 2.11" gem "shoulda", "~> 2.11"
gem "mocha" # Shoulda does not work nice on Ruby 1.9.3 and seems to need test-unit explicitely.
gem "test-unit", :platforms => [:mri_19]
gem "mocha", "0.12.3"
end end
local_gemfile = File.join(File.dirname(__FILE__), "Gemfile.local") local_gemfile = File.join(File.dirname(__FILE__), "Gemfile.local")
+1 -1
View File
@@ -43,7 +43,7 @@ class ActivitiesController < ApplicationController
if events.empty? || stale?(:etag => [@activity.scope, @date_to, @date_from, @with_subprojects, @author, events.first, User.current, current_language]) if events.empty? || stale?(:etag => [@activity.scope, @date_to, @date_from, @with_subprojects, @author, events.first, User.current, current_language])
respond_to do |format| respond_to do |format|
format.html { format.html {
@events_by_day = events.group_by(&:event_date) @events_by_day = events.group_by {|event| User.current.time_to_date(event.event_datetime)}
render :layout => false if request.xhr? render :layout => false if request.xhr?
} }
format.atom { format.atom {
+2 -2
View File
@@ -445,9 +445,9 @@ class ApplicationController < ActionController::Base
# Returns the API key present in the request # Returns the API key present in the request
def api_key_from_request def api_key_from_request
if params[:key].present? if params[:key].present?
params[:key] params[:key].to_s
elsif request.headers["X-Redmine-API-Key"].present? elsif request.headers["X-Redmine-API-Key"].present?
request.headers["X-Redmine-API-Key"] request.headers["X-Redmine-API-Key"].to_s
end end
end end
+2 -2
View File
@@ -43,10 +43,10 @@ class BoardsController < ApplicationController
@topic_count = @board.topics.count @topic_count = @board.topics.count
@topic_pages = Paginator.new self, @topic_count, per_page_option, params['page'] @topic_pages = Paginator.new self, @topic_count, per_page_option, params['page']
@topics = @board.topics.find :all, :order => ["#{Message.table_name}.sticky DESC", sort_clause].compact.join(', '), @topics = @board.topics.reorder("#{Message.table_name}.sticky DESC").order(sort_clause).all(
:include => [:author, {:last_reply => :author}], :include => [:author, {:last_reply => :author}],
:limit => @topic_pages.items_per_page, :limit => @topic_pages.items_per_page,
:offset => @topic_pages.current.offset :offset => @topic_pages.current.offset)
@message = Message.new(:board => @board) @message = Message.new(:board => @board)
render :action => 'show', :layout => !request.xhr? render :action => 'show', :layout => !request.xhr?
} }
+18 -10
View File
@@ -18,12 +18,13 @@
class TimelogController < ApplicationController class TimelogController < ApplicationController
menu_item :issues menu_item :issues
before_filter :find_project, :only => [:create] before_filter :find_project_for_new_time_entry, :only => [:create]
before_filter :find_time_entry, :only => [:show, :edit, :update] before_filter :find_time_entry, :only => [:show, :edit, :update]
before_filter :find_time_entries, :only => [:bulk_edit, :bulk_update, :destroy] before_filter :find_time_entries, :only => [:bulk_edit, :bulk_update, :destroy]
before_filter :authorize, :except => [:new, :index, :report] before_filter :authorize, :except => [:new, :index, :report]
before_filter :find_optional_project, :only => [:new, :index, :report] before_filter :find_optional_project, :only => [:index, :report]
before_filter :find_optional_project_for_new_time_entry, :only => [:new]
before_filter :authorize_global, :only => [:new, :index, :report] before_filter :authorize_global, :only => [:new, :index, :report]
accept_rss_auth :index accept_rss_auth :index
@@ -38,7 +39,7 @@ class TimelogController < ApplicationController
def index def index
sort_init 'spent_on', 'desc' sort_init 'spent_on', 'desc'
sort_update 'spent_on' => 'spent_on', sort_update 'spent_on' => ['spent_on', "#{TimeEntry.table_name}.created_on"],
'user' => 'user_id', 'user' => 'user_id',
'activity' => 'activity_id', 'activity' => 'activity_id',
'project' => "#{Project.table_name}.name", 'project' => "#{Project.table_name}.name",
@@ -133,9 +134,13 @@ class TimelogController < ApplicationController
flash[:notice] = l(:notice_successful_create) flash[:notice] = l(:notice_successful_create)
if params[:continue] if params[:continue]
if params[:project_id] if params[:project_id]
redirect_to :action => 'new', :project_id => @time_entry.project, :issue_id => @time_entry.issue, :back_url => params[:back_url] redirect_to :action => 'new', :project_id => @time_entry.project, :issue_id => @time_entry.issue,
:time_entry => {:issue_id => @time_entry.issue_id, :activity_id => @time_entry.activity_id},
:back_url => params[:back_url]
else else
redirect_to :action => 'new', :back_url => params[:back_url] redirect_to :action => 'new',
:time_entry => {:project_id => @time_entry.project_id, :issue_id => @time_entry.issue_id, :activity_id => @time_entry.activity_id},
:back_url => params[:back_url]
end end
else else
redirect_back_or_default :action => 'index', :project_id => @time_entry.project redirect_back_or_default :action => 'index', :project_id => @time_entry.project
@@ -258,7 +263,7 @@ private
end end
end end
def find_project def find_optional_project_for_new_time_entry
if (project_id = (params[:project_id] || params[:time_entry] && params[:time_entry][:project_id])).present? if (project_id = (params[:project_id] || params[:time_entry] && params[:time_entry][:project_id])).present?
@project = Project.find(project_id) @project = Project.find(project_id)
end end
@@ -266,14 +271,17 @@ private
@issue = Issue.find(issue_id) @issue = Issue.find(issue_id)
@project ||= @issue.project @project ||= @issue.project
end end
if @project.nil?
render_404
return false
end
rescue ActiveRecord::RecordNotFound rescue ActiveRecord::RecordNotFound
render_404 render_404
end end
def find_project_for_new_time_entry
find_optional_project_for_new_time_entry
if @project.nil?
render_404
end
end
def find_optional_project def find_optional_project
if !params[:issue_id].blank? if !params[:issue_id].blank?
@issue = Issue.find(params[:issue_id]) @issue = Issue.find(params[:issue_id])
+6 -4
View File
@@ -178,7 +178,7 @@ module ApplicationHelper
end end
def format_activity_day(date) def format_activity_day(date)
date == Date.today ? l(:label_today).titleize : format_date(date) date == User.current.today ? l(:label_today).titleize : format_date(date)
end end
def format_activity_description(text) def format_activity_description(text)
@@ -253,7 +253,7 @@ module ApplicationHelper
def project_tree_options_for_select(projects, options = {}) def project_tree_options_for_select(projects, options = {})
s = '' s = ''
project_tree(projects) do |project, level| project_tree(projects) do |project, level|
name_prefix = (level > 0 ? ('&nbsp;' * 2 * level + '&#187; ').html_safe : '') name_prefix = (level > 0 ? ('&nbsp;' * 2 * level + '&#187; ') : '').html_safe
tag_options = {:value => project.id} tag_options = {:value => project.id}
if project == options[:selected] || (options[:selected].respond_to?(:include?) && options[:selected].include?(project)) if project == options[:selected] || (options[:selected].respond_to?(:include?) && options[:selected].include?(project))
tag_options[:selected] = 'selected' tag_options[:selected] = 'selected'
@@ -352,7 +352,7 @@ module ApplicationHelper
def time_tag(time) def time_tag(time)
text = distance_of_time_in_words(Time.now, time) text = distance_of_time_in_words(Time.now, time)
if @project if @project
link_to(text, {:controller => 'activities', :action => 'index', :id => @project, :from => time.to_date}, :title => format_time(time)) link_to(text, {:controller => 'activities', :action => 'index', :id => @project, :from => User.current.time_to_date(time)}, :title => format_time(time))
else else
content_tag('acronym', text, :title => format_time(time)) content_tag('acronym', text, :title => format_time(time))
end end
@@ -812,7 +812,7 @@ module ApplicationHelper
end end
end end
HEADING_RE = /(<h(1|2|3|4)( [^>]+)?>(.+?)<\/h(1|2|3|4)>)/i unless const_defined?(:HEADING_RE) HEADING_RE = /(<h(\d)( [^>]+)?>(.+?)<\/h(\d)>)/i unless const_defined?(:HEADING_RE)
def parse_sections(text, project, obj, attr, only_path, options) def parse_sections(text, project, obj, attr, only_path, options)
return unless options[:edit_section_links] return unless options[:edit_section_links]
@@ -883,6 +883,8 @@ module ApplicationHelper
# Renders the TOC with given headings # Renders the TOC with given headings
def replace_toc(text, headings) def replace_toc(text, headings)
text.gsub!(TOC_RE) do text.gsub!(TOC_RE) do
# Keep only the 4 first levels
headings = headings.select{|level, anchor, item| level <= 4}
if headings.empty? if headings.empty?
'' ''
else else
+3 -3
View File
@@ -46,17 +46,17 @@ module RepositoriesHelper
end end
def render_changeset_changes def render_changeset_changes
changes = @changeset.changes.find(:all, :limit => 1000, :order => 'path').collect do |change| changes = @changeset.filechanges.find(:all, :limit => 1000, :order => 'path').collect do |change|
case change.action case change.action
when 'A' when 'A'
# Detects moved/copied files # Detects moved/copied files
if !change.from_path.blank? if !change.from_path.blank?
change.action = change.action =
@changeset.changes.detect {|c| c.action == 'D' && c.path == change.from_path} ? 'R' : 'C' @changeset.filechanges.detect {|c| c.action == 'D' && c.path == change.from_path} ? 'R' : 'C'
end end
change change
when 'D' when 'D'
@changeset.changes.detect {|c| c.from_path == change.path} ? nil : change @changeset.filechanges.detect {|c| c.from_path == change.path} ? nil : change
else else
change change
end end
+8 -4
View File
@@ -45,23 +45,27 @@ module WatchersHelper
# Returns a comma separated list of users watching the given object # Returns a comma separated list of users watching the given object
def watchers_list(object) def watchers_list(object)
remove_allowed = User.current.allowed_to?("delete_#{object.class.name.underscore}_watchers".to_sym, object.project) remove_allowed = User.current.allowed_to?("delete_#{object.class.name.underscore}_watchers".to_sym, object.project)
content = ''.html_safe
lis = object.watcher_users.collect do |user| lis = object.watcher_users.collect do |user|
s = avatar(user, :size => "16").to_s + link_to_user(user, :class => 'user').to_s s = ''.html_safe
s << avatar(user, :size => "16").to_s
s << link_to_user(user, :class => 'user')
if remove_allowed if remove_allowed
url = {:controller => 'watchers', url = {:controller => 'watchers',
:action => 'destroy', :action => 'destroy',
:object_type => object.class.to_s.underscore, :object_type => object.class.to_s.underscore,
:object_id => object.id, :object_id => object.id,
:user_id => user} :user_id => user}
s += ' ' + link_to_remote(image_tag('delete.png'), s << ' '
s << link_to_remote(image_tag('delete.png'),
{:url => url}, {:url => url},
:href => url_for(url), :href => url_for(url),
:style => "vertical-align: middle", :style => "vertical-align: middle",
:class => "delete") :class => "delete")
end end
content_tag :li, s.html_safe content << content_tag('li', s)
end end
(lis.empty? ? "" : "<ul>#{ lis.join("\n") }</ul>").html_safe content.present? ? content_tag('ul', content) : content
end end
def watchers_checkboxes(object, users, checked=nil) def watchers_checkboxes(object, users, checked=nil)
+1
View File
@@ -24,6 +24,7 @@ class Attachment < ActiveRecord::Base
validates_presence_of :filename, :author validates_presence_of :filename, :author
validates_length_of :filename, :maximum => 255 validates_length_of :filename, :maximum => 255
validates_length_of :disk_filename, :maximum => 255 validates_length_of :disk_filename, :maximum => 255
validates_length_of :description, :maximum => 255
validate :validate_max_file_size validate :validate_max_file_size
acts_as_event :title => :filename, acts_as_event :title => :filename,
+1 -1
View File
@@ -20,7 +20,7 @@ require 'iconv'
class Changeset < ActiveRecord::Base class Changeset < ActiveRecord::Base
belongs_to :repository belongs_to :repository
belongs_to :user belongs_to :user
has_many :changes, :dependent => :delete_all has_many :filechanges, :class_name => 'Change', :dependent => :delete_all
has_and_belongs_to_many :issues has_and_belongs_to_many :issues
has_and_belongs_to_many :parents, has_and_belongs_to_many :parents,
:class_name => "Changeset", :class_name => "Changeset",
+30 -3
View File
@@ -75,7 +75,7 @@ class Issue < ActiveRecord::Base
:conditions => ["#{Project.table_name}.status=#{Project::STATUS_ACTIVE}"] :conditions => ["#{Project.table_name}.status=#{Project::STATUS_ACTIVE}"]
before_create :default_assign before_create :default_assign
before_save :close_duplicates, :update_done_ratio_from_issue_status before_save :close_duplicates, :update_done_ratio_from_issue_status, :force_updated_on_change
after_save {|issue| issue.send :after_project_change if !issue.id_changed? && issue.project_id_changed?} after_save {|issue| issue.send :after_project_change if !issue.id_changed? && issue.project_id_changed?}
after_save :reschedule_following_issues, :update_nested_set_attributes, :update_parent_attributes, :create_journal after_save :reschedule_following_issues, :update_nested_set_attributes, :update_parent_attributes, :create_journal
after_destroy :update_parent_attributes after_destroy :update_parent_attributes
@@ -124,6 +124,28 @@ class Issue < ActiveRecord::Base
end end
end end
# AR#Persistence#destroy would raise and RecordNotFound exception
# if the issue was already deleted or updated (non matching lock_version).
# This is a problem when bulk deleting issues or deleting a project
# (because an issue may already be deleted if its parent was deleted
# first).
# The issue is reloaded by the nested_set before being deleted so
# the lock_version condition should not be an issue but we handle it.
def destroy
super
rescue ActiveRecord::RecordNotFound
# Stale or already deleted
begin
reload
rescue ActiveRecord::RecordNotFound
# The issue was actually already deleted
@destroyed = true
return freeze
end
# The issue was stale, retry to destroy
super
end
# Overrides Redmine::Acts::Customizable::InstanceMethods#available_custom_fields # Overrides Redmine::Acts::Customizable::InstanceMethods#available_custom_fields
def available_custom_fields def available_custom_fields
(project && tracker) ? (project.all_issue_custom_fields & tracker.custom_fields.all) : [] (project && tracker) ? (project.all_issue_custom_fields & tracker.custom_fields.all) : []
@@ -432,8 +454,6 @@ class Issue < ActiveRecord::Base
@custom_values_before_change = {} @custom_values_before_change = {}
self.custom_field_values.each {|c| @custom_values_before_change.store c.custom_field_id, c.value } self.custom_field_values.each {|c| @custom_values_before_change.store c.custom_field_id, c.value }
end end
# Make sure updated_on is updated when adding a note.
updated_on_will_change!
@current_journal @current_journal
end end
@@ -994,6 +1014,13 @@ class Issue < ActiveRecord::Base
end end
end end
# Make sure updated_on is updated when adding a note
def force_updated_on_change
if @current_journal
self.updated_on = current_time_from_proper_timezone
end
end
# Saves the changes in a Journal # Saves the changes in a Journal
# Called after_save # Called after_save
def create_journal def create_journal
+28 -8
View File
@@ -50,8 +50,8 @@ class MailHandler < ActionMailer::Base
cattr_accessor :ignored_emails_headers cattr_accessor :ignored_emails_headers
@@ignored_emails_headers = { @@ignored_emails_headers = {
'X-Auto-Response-Suppress' => 'OOF', 'X-Auto-Response-Suppress' => 'oof',
'Auto-Submitted' => 'auto-replied' 'Auto-Submitted' => /^auto-/
} }
# Processes incoming emails # Processes incoming emails
@@ -69,11 +69,14 @@ class MailHandler < ActionMailer::Base
# Ignore auto generated emails # Ignore auto generated emails
self.class.ignored_emails_headers.each do |key, ignored_value| self.class.ignored_emails_headers.each do |key, ignored_value|
value = email.header[key] value = email.header[key]
if value && value.to_s.downcase == ignored_value.downcase if value
if logger && logger.info value = value.to_s.downcase
logger.info "MailHandler: ignoring email with #{key}:#{value} header" if (ignored_value.is_a?(Regexp) && value.match(ignored_value)) || value == ignored_value
if logger && logger.info
logger.info "MailHandler: ignoring email with #{key}:#{value} header"
end
return false
end end
return false
end end
end end
@user = User.find_by_mail(sender_email) if sender_email.present? @user = User.find_by_mail(sender_email) if sender_email.present?
@@ -163,7 +166,7 @@ class MailHandler < ActionMailer::Base
issue = Issue.new(:author => user, :project => project) issue = Issue.new(:author => user, :project => project)
issue.safe_attributes = issue_attributes_from_keywords(issue) issue.safe_attributes = issue_attributes_from_keywords(issue)
issue.safe_attributes = {'custom_field_values' => custom_field_values_from_keywords(issue)} issue.safe_attributes = {'custom_field_values' => custom_field_values_from_keywords(issue)}
issue.subject = email.subject.to_s.chomp[0,255] issue.subject = cleaned_up_subject
if issue.subject.blank? if issue.subject.blank?
issue.subject = '(no subject)' issue.subject = '(no subject)'
end end
@@ -223,7 +226,7 @@ class MailHandler < ActionMailer::Base
end end
if !message.locked? if !message.locked?
reply = Message.new(:subject => email.subject.gsub(%r{^.*msg\d+\]}, '').strip, reply = Message.new(:subject => cleaned_up_subject.gsub(%r{^.*msg\d+\]}, '').strip,
:content => cleaned_up_text_body) :content => cleaned_up_text_body)
reply.author = user reply.author = user
reply.board = message.board reply.board = message.board
@@ -364,6 +367,23 @@ class MailHandler < ActionMailer::Base
cleanup_body(plain_text_body) cleanup_body(plain_text_body)
end end
def cleaned_up_subject
subject = email.subject.to_s
unless subject.respond_to?(:encoding)
# try to reencode to utf8 manually with ruby1.8
begin
if h = email.header[:subject]
if m = h.value.match(/^=\?([^\?]+)\?/)
subject = Redmine::CodesetUtil.to_utf8(subject, m[1])
end
end
rescue
# nop
end
end
subject.strip[0,255]
end
def self.full_sanitizer def self.full_sanitizer
@full_sanitizer ||= HTML::FullSanitizer.new @full_sanitizer ||= HTML::FullSanitizer.new
end end
+3 -1
View File
@@ -361,7 +361,9 @@ class Mailer < ActionMailer::Base
def self.with_synched_deliveries(&block) def self.with_synched_deliveries(&block)
saved_method = ActionMailer::Base.delivery_method saved_method = ActionMailer::Base.delivery_method
if m = saved_method.to_s.match(%r{^async_(.+)$}) if m = saved_method.to_s.match(%r{^async_(.+)$})
ActionMailer::Base.delivery_method = m[1].to_sym synched_method = m[1]
ActionMailer::Base.delivery_method = synched_method.to_sym
ActionMailer::Base.send "#{synched_method}_settings=", ActionMailer::Base.send("async_#{synched_method}_settings")
end end
yield yield
ensure ensure
+1 -1
View File
@@ -130,7 +130,7 @@ class Project < ActiveRecord::Base
end end
def identifier_frozen? def identifier_frozen?
errors[:identifier].nil? && !(new_record? || identifier.blank?) errors[:identifier].blank? && !(new_record? || identifier.blank?)
end end
# returns latest created projects # returns latest created projects
+12 -6
View File
@@ -174,9 +174,9 @@ class Query < ActiveRecord::Base
if values_for(field) if values_for(field)
case type_for(field) case type_for(field)
when :integer when :integer
add_filter_error(field, :invalid) if values_for(field).detect {|v| v.present? && !v.match(/^\d+$/) } add_filter_error(field, :invalid) if values_for(field).detect {|v| v.present? && !v.match(/^[+-]?\d+$/) }
when :float when :float
add_filter_error(field, :invalid) if values_for(field).detect {|v| v.present? && !v.match(/^\d+(\.\d*)?$/) } add_filter_error(field, :invalid) if values_for(field).detect {|v| v.present? && !v.match(/^[+-]?\d+(\.\d*)?$/) }
when :date, :date_past when :date, :date_past
case operator_for(field) case operator_for(field)
when "=", ">=", "<=", "><" when "=", ">=", "<=", "><"
@@ -848,12 +848,18 @@ class Query < ActiveRecord::Base
s = [] s = []
if from if from
from_yesterday = from - 1 from_yesterday = from - 1
from_yesterday_utc = Time.gm(from_yesterday.year, from_yesterday.month, from_yesterday.day) from_yesterday_time = Time.local(from_yesterday.year, from_yesterday.month, from_yesterday.day)
s << ("#{table}.#{field} > '%s'" % [connection.quoted_date(from_yesterday_utc.end_of_day)]) if self.class.default_timezone == :utc
from_yesterday_time = from_yesterday_time.utc
end
s << ("#{table}.#{field} > '%s'" % [connection.quoted_date(from_yesterday_time.end_of_day)])
end end
if to if to
to_utc = Time.gm(to.year, to.month, to.day) to_time = Time.local(to.year, to.month, to.day)
s << ("#{table}.#{field} <= '%s'" % [connection.quoted_date(to_utc.end_of_day)]) if self.class.default_timezone == :utc
to_time = to_time.utc
end
s << ("#{table}.#{field} <= '%s'" % [connection.quoted_date(to_time.end_of_day)])
end end
s.join(' AND ') s.join(' AND ')
end end
+4 -4
View File
@@ -22,7 +22,7 @@ class Repository < ActiveRecord::Base
belongs_to :project belongs_to :project
has_many :changesets, :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC" has_many :changesets, :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC"
has_many :changes, :through => :changesets has_many :filechanges, :class_name => 'Change', :through => :changesets
serialize :extra_info serialize :extra_info
@@ -37,8 +37,8 @@ class Repository < ActiveRecord::Base
validates_presence_of :identifier, :unless => Proc.new { |r| r.is_default? || r.set_as_default? } validates_presence_of :identifier, :unless => Proc.new { |r| r.is_default? || r.set_as_default? }
validates_uniqueness_of :identifier, :scope => :project_id, :allow_blank => true validates_uniqueness_of :identifier, :scope => :project_id, :allow_blank => true
validates_exclusion_of :identifier, :in => %w(show entry raw changes annotate diff show stats graph) validates_exclusion_of :identifier, :in => %w(show entry raw changes annotate diff show stats graph)
# donwcase letters, digits, dashes but not digits only # donwcase letters, digits, dashes, underscores but not digits only
validates_format_of :identifier, :with => /^(?!\d+$)[a-z0-9\-]*$/, :allow_blank => true validates_format_of :identifier, :with => /^(?!\d+$)[a-z0-9\-_]*$/, :allow_blank => true
# Checks if the SCM is enabled when creating a repository # Checks if the SCM is enabled when creating a repository
validate :repo_create_validation, :on => :create validate :repo_create_validation, :on => :create
@@ -228,7 +228,7 @@ class Repository < ActiveRecord::Base
:order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC", :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC",
:limit => limit) :limit => limit)
else else
changes.find( filechanges.find(
:all, :all,
:include => {:changeset => :user}, :include => {:changeset => :user},
:conditions => ["path = ?", path.with_leading_slash], :conditions => ["path = ?", path.with_leading_slash],
+4 -4
View File
@@ -54,7 +54,7 @@ class Repository::Cvs < Repository
if entries if entries
entries.each() do |entry| entries.each() do |entry|
if ( ! entry.lastrev.nil? ) && ( ! entry.lastrev.revision.nil? ) if ( ! entry.lastrev.nil? ) && ( ! entry.lastrev.revision.nil? )
change=changes.find_by_revision_and_path( change = filechanges.find_by_revision_and_path(
entry.lastrev.revision, entry.lastrev.revision,
scm.with_leading_slash(entry.path) ) scm.with_leading_slash(entry.path) )
if change if change
@@ -94,7 +94,7 @@ class Repository::Cvs < Repository
if rev_to.to_i > 0 if rev_to.to_i > 0
changeset_to = changesets.find_by_revision(rev_to) changeset_to = changesets.find_by_revision(rev_to)
end end
changeset_from.changes.each() do |change_from| changeset_from.filechanges.each() do |change_from|
revision_from = nil revision_from = nil
revision_to = nil revision_to = nil
if path.nil? || (change_from.path.starts_with? scm.with_leading_slash(path)) if path.nil? || (change_from.path.starts_with? scm.with_leading_slash(path))
@@ -102,7 +102,7 @@ class Repository::Cvs < Repository
end end
if revision_from if revision_from
if changeset_to if changeset_to
changeset_to.changes.each() do |change_to| changeset_to.filechanges.each() do |change_to|
revision_to = change_to.revision if change_to.path == change_from.path revision_to = change_to.revision if change_to.path == change_from.path
end end
end end
@@ -133,7 +133,7 @@ class Repository::Cvs < Repository
# only add the change to the database, if it doen't exists. the cvs log # only add the change to the database, if it doen't exists. the cvs log
# is not exclusive at all. # is not exclusive at all.
tmp_time = revision.time.clone tmp_time = revision.time.clone
unless changes.find_by_path_and_revision( unless filechanges.find_by_path_and_revision(
scm.with_leading_slash(revision.paths[0][:path]), scm.with_leading_slash(revision.paths[0][:path]),
revision.paths[0][:revision] revision.paths[0][:revision]
) )
+1 -1
View File
@@ -79,7 +79,7 @@ class Repository::Darcs < Repository
return nil if patch_from.nil? return nil if patch_from.nil?
patch_to = changesets.find_by_revision(rev_to) if rev_to patch_to = changesets.find_by_revision(rev_to) if rev_to
if path.blank? if path.blank?
path = patch_from.changes.collect{|change| change.path}.join(' ') path = patch_from.filechanges.collect{|change| change.path}.join(' ')
end end
patch_from ? scm.diff(path, patch_from.scmid, patch_to ? patch_to.scmid : nil) : nil patch_from ? scm.diff(path, patch_from.scmid, patch_to ? patch_to.scmid : nil) : nil
end end
+1 -1
View File
@@ -66,7 +66,7 @@ class TimeEntry < ActiveRecord::Base
end end
} }
safe_attributes 'hours', 'comments', 'issue_id', 'activity_id', 'spent_on', 'custom_field_values' safe_attributes 'hours', 'comments', 'issue_id', 'activity_id', 'spent_on', 'custom_field_values', 'custom_fields'
def initialize(attributes=nil, *args) def initialize(attributes=nil, *args)
super super
+16 -4
View File
@@ -130,8 +130,11 @@ class User < Principal
# Returns the user that matches provided login and password, or nil # Returns the user that matches provided login and password, or nil
def self.try_to_login(login, password) def self.try_to_login(login, password)
login = login.to_s
password = password.to_s
# Make sure no one can sign in with an empty password # Make sure no one can sign in with an empty password
return nil if password.to_s.empty? return nil if password.empty?
user = find_by_login(login) user = find_by_login(login)
if user if user
# user is already in local database # user is already in local database
@@ -164,7 +167,7 @@ class User < Principal
# Returns the user who matches the given autologin +key+ or nil # Returns the user who matches the given autologin +key+ or nil
def self.try_to_autologin(key) def self.try_to_autologin(key)
tokens = Token.find_all_by_action_and_value('autologin', key) tokens = Token.find_all_by_action_and_value('autologin', key.to_s)
# Make sure there's only 1 token that matches the key # Make sure there's only 1 token that matches the key
if tokens.size == 1 if tokens.size == 1
token = tokens.first token = tokens.first
@@ -338,12 +341,12 @@ class User < Principal
end end
def self.find_by_rss_key(key) def self.find_by_rss_key(key)
token = Token.find_by_value(key) token = Token.find_by_action_and_value('feeds', key.to_s)
token && token.user.active? ? token.user : nil token && token.user.active? ? token.user : nil
end end
def self.find_by_api_key(key) def self.find_by_api_key(key)
token = Token.find_by_action_and_value('api', key) token = Token.find_by_action_and_value('api', key.to_s)
token && token.user.active? ? token.user : nil token && token.user.active? ? token.user : nil
end end
@@ -370,6 +373,15 @@ class User < Principal
end end
end end
# Returns the day of +time+ according to user's time zone
def time_to_date(time)
if time_zone.nil?
time.to_date
else
time.in_time_zone(time_zone).to_date
end
end
def logged? def logged?
true true
end end
+1 -1
View File
@@ -143,7 +143,7 @@ class WikiPage < ActiveRecord::Base
if time = read_attribute(:updated_on) if time = read_attribute(:updated_on)
# content updated_on was eager loaded with the page # content updated_on was eager loaded with the page
begin begin
@updated_on = Time.zone ? Time.zone.parse(time.to_s) : Time.parse(time.to_s) @updated_on = (self.class.default_timezone == :utc ? Time.parse(time.to_s).utc : Time.parse(time.to_s).localtime)
rescue rescue
end end
else else
+1 -1
View File
@@ -1,4 +1,4 @@
<h2><%= @author.nil? ? l(:label_activity) : l(:label_user_activity, link_to_user(@author)) %></h2> <h2><%= @author.nil? ? l(:label_activity) : l(:label_user_activity, link_to_user(@author)).html_safe %></h2>
<p class="subtitle"><%= l(:label_date_from_to, :start => format_date(@date_to - @days), :end => format_date(@date_to-1)) %></p> <p class="subtitle"><%= l(:label_date_from_to, :start => format_date(@date_to - @days), :end => format_date(@date_to-1)) %></p>
<div id="activity"> <div id="activity">
+1 -1
View File
@@ -10,7 +10,7 @@
<span> <span>
<%= file_field_tag 'attachments[1][file]', :size => 30, :id => nil, :class => 'file', <%= file_field_tag 'attachments[1][file]', :size => 30, :id => nil, :class => 'file',
:onchange => "checkFileSize(this, #{Setting.attachment_max_size.to_i.kilobytes}, '#{escape_javascript(l(:error_attachment_too_big, :max_size => number_to_human_size(Setting.attachment_max_size.to_i.kilobytes)))}');" -%> :onchange => "checkFileSize(this, #{Setting.attachment_max_size.to_i.kilobytes}, '#{escape_javascript(l(:error_attachment_too_big, :max_size => number_to_human_size(Setting.attachment_max_size.to_i.kilobytes)))}');" -%>
<%= text_field_tag 'attachments[1][description]', '', :id => nil, :class => 'description', :placeholder => l(:label_optional_description) %> <%= text_field_tag 'attachments[1][description]', '', :id => nil, :class => 'description', :maxlength => 255, :placeholder => l(:label_optional_description) %>
<%= link_to_function(image_tag('delete.png'), 'removeFileField(this)', :title => (l(:button_delete))) %> <%= link_to_function(image_tag('delete.png'), 'removeFileField(this)', :title => (l(:button_delete))) %>
</span> </span>
</span> </span>
+1 -1
View File
@@ -21,6 +21,6 @@
<% if @notes.present? %> <% if @notes.present? %>
<label><%= radio_button_tag 'conflict_resolution', 'add_notes' %> <%= l(:text_issue_conflict_resolution_add_notes) %></label><br /> <label><%= radio_button_tag 'conflict_resolution', 'add_notes' %> <%= l(:text_issue_conflict_resolution_add_notes) %></label><br />
<% end %> <% end %>
<label><%= radio_button_tag 'conflict_resolution', 'cancel' %> <%= l(:text_issue_conflict_resolution_cancel, :link => link_to_issue(@issue, :subject => false)) %></label> <label><%= radio_button_tag 'conflict_resolution', 'cancel' %> <%= l(:text_issue_conflict_resolution_cancel, :link => link_to_issue(@issue, :subject => false)).html_safe %></label>
</p> </p>
<p><%= submit_tag l(:button_submit) %></p> <p><%= submit_tag l(:button_submit) %></p>
+2 -2
View File
@@ -7,14 +7,14 @@
<div class="next-prev-links contextual"> <div class="next-prev-links contextual">
<%= link_to_if @prev_issue_id, <%= link_to_if @prev_issue_id,
"\xc2\xab #{l(:label_previous)}", "\xc2\xab #{l(:label_previous)}",
issue_path(@prev_issue_id), (@prev_issue_id ? issue_path(@prev_issue_id) : nil),
:title => "##{@prev_issue_id}" %> | :title => "##{@prev_issue_id}" %> |
<% if @issue_position && @issue_count %> <% if @issue_position && @issue_count %>
<span class="position"><%= l(:label_item_position, :position => @issue_position, :count => @issue_count) %></span> | <span class="position"><%= l(:label_item_position, :position => @issue_position, :count => @issue_count) %></span> |
<% end %> <% end %>
<%= link_to_if @next_issue_id, <%= link_to_if @next_issue_id,
"#{l(:label_next)} \xc2\xbb", "#{l(:label_next)} \xc2\xbb",
issue_path(@next_issue_id), (@next_issue_id ? issue_path(@next_issue_id) : nil),
:title => "##{@next_issue_id}" %> :title => "##{@next_issue_id}" %>
</div> </div>
<% end %> <% end %>
+1 -1
View File
@@ -1,3 +1,3 @@
<p><%= l(:mail_body_wiki_content_added, :id => link_to(h(@wiki_content.page.pretty_title), @wiki_content_url), <p><%= l(:mail_body_wiki_content_added, :id => link_to(h(@wiki_content.page.pretty_title), @wiki_content_url),
:author => h(@wiki_content.author)) %><br /> :author => h(@wiki_content.author)).html_safe %><br />
<em><%=h @wiki_content.comments %></em></p> <em><%=h @wiki_content.comments %></em></p>
@@ -1,5 +1,5 @@
<p><%= l(:mail_body_wiki_content_updated, :id => link_to(h(@wiki_content.page.pretty_title), @wiki_content_url), <p><%= l(:mail_body_wiki_content_updated, :id => link_to(h(@wiki_content.page.pretty_title), @wiki_content_url),
:author => h(@wiki_content.author)) %><br /> :author => h(@wiki_content.author)).html_safe %><br />
<em><%=h @wiki_content.comments %></em></p> <em><%=h @wiki_content.comments %></em></p>
<p><%= l(:label_view_diff) %>:<br /> <p><%= l(:label_view_diff) %>:<br />
+1 -1
View File
@@ -31,7 +31,7 @@ entries_by_day = entries.group_by(&:spent_on)
<% entries_by_day[day].each do |entry| -%> <% entries_by_day[day].each do |entry| -%>
<tr class="time-entry" style="border-bottom: 1px solid #f5f5f5;"> <tr class="time-entry" style="border-bottom: 1px solid #f5f5f5;">
<td class="activity"><%=h entry.activity %></td> <td class="activity"><%=h entry.activity %></td>
<td class="subject"><%=h entry.project %> <%= ' - ' + link_to_issue(entry.issue, :truncate => 50) if entry.issue %></td> <td class="subject"><%=h entry.project %> <%= h(' - ') + link_to_issue(entry.issue, :truncate => 50) if entry.issue %></td>
<td class="comments"><%=h entry.comments %></td> <td class="comments"><%=h entry.comments %></td>
<td class="hours"><%= html_hours("%.2f" % entry.hours) %></td> <td class="hours"><%= html_hours("%.2f" % entry.hours) %></td>
<td align="center"> <td align="center">
+2 -1
View File
@@ -4,7 +4,8 @@
<%=l(:text_project_destroy_confirmation)%> <%=l(:text_project_destroy_confirmation)%>
<% if @project_to_destroy.descendants.any? %> <% if @project_to_destroy.descendants.any? %>
<br /><%= l(:text_subprojects_destroy_warning, content_tag('strong', h(@project_to_destroy.descendants.collect{|p| p.to_s}.join(', ')))) %> <br /><%= l(:text_subprojects_destroy_warning,
content_tag('strong', h(@project_to_destroy.descendants.collect{|p| p.to_s}.join(', ')))).html_safe %>
<% end %> <% end %>
</p> </p>
<p> <p>
@@ -38,4 +38,4 @@
<% end %> <% end %>
</div> </div>
<p><%= link_to l(:label_version_new), new_project_version_path(@project), :class => 'icon icon-add' if User.current.allowed_to?(:manage_versions, @project) %></p> <p><%= link_to l(:label_version_new), new_project_version_path(@project, :back_url => ''), :class => 'icon icon-add' if User.current.allowed_to?(:manage_versions, @project) %></p>
+1 -1
View File
@@ -1,6 +1,6 @@
<%= labelled_remote_form_for @wiki, <%= labelled_remote_form_for @wiki,
:as => :wiki, :as => :wiki,
:url => { :controller => 'wikis', :action => 'edit', :id => @project } do |f| %> :url => { :controller => 'wikis', :action => 'edit', :id => @project }, :method => 'post' do |f| %>
<%= error_messages_for 'wiki' %> <%= error_messages_for 'wiki' %>
+1 -1
View File
@@ -44,7 +44,7 @@
<% end %> <% end %>
</fieldset> </fieldset>
<% content_tag 'fieldset', :id => 'columns', :style => (query.has_default_columns? ? 'display:none;' : nil) do %> <%= content_tag 'fieldset', :id => 'columns', :style => (query.has_default_columns? ? 'display:none;' : nil) do %>
<legend><%= l(:field_column_names) %></legend> <legend><%= l(:field_column_names) %></legend>
<%= render :partial => 'queries/columns', :locals => {:query => query}%> <%= render :partial => 'queries/columns', :locals => {:query => query}%>
<% end %> <% end %>
+1 -1
View File
@@ -1,5 +1,5 @@
<h2><%= l(:label_repository) %></h2> <h2><%= l(:label_repository) %></h2>
<%= labelled_form_for :repository, @repository, :url => repository_path(@path), :html => {:method => :put} do |f| %> <%= labelled_form_for :repository, @repository, :url => repository_path(@repository), :html => {:method => :put} do |f| %>
<%= render :partial => 'form', :locals => {:f => f} %> <%= render :partial => 'form', :locals => {:f => f} %>
<% end %> <% end %>
+1 -1
View File
@@ -83,7 +83,7 @@
:id => @project, :id => @project,
:repository_id => @repository.identifier_param, :repository_id => @repository.identifier_param,
:path => "", :path => "",
:rev => @changeset.identifier) if @changeset.changes.any? %></p> :rev => @changeset.identifier) if @changeset.filechanges.any? %></p>
<div class="changeset-changes"> <div class="changeset-changes">
<%= render_changeset_changes %> <%= render_changeset_changes %>
+1
View File
@@ -1,6 +1,7 @@
<h2><%= l(:label_spent_time) %></h2> <h2><%= l(:label_spent_time) %></h2>
<%= labelled_form_for @time_entry, :url => time_entries_path do |f| %> <%= labelled_form_for @time_entry, :url => time_entries_path do |f| %>
<%= hidden_field_tag 'project_id', params[:project_id] if params[:project_id] %>
<%= render :partial => 'form', :locals => {:f => f} %> <%= render :partial => 'form', :locals => {:f => f} %>
<%= submit_tag l(:button_create) %> <%= submit_tag l(:button_create) %>
<%= submit_tag l(:button_create_and_continue), :name => 'continue' %> <%= submit_tag l(:button_create_and_continue), :name => 'continue' %>
+1 -1
View File
@@ -3,7 +3,7 @@
<%= select_tag 'user[mail_notification]', options_for_select(user_mail_notification_options(@user), @user.mail_notification), <%= select_tag 'user[mail_notification]', options_for_select(user_mail_notification_options(@user), @user.mail_notification),
:onchange => 'if (this.value == "selected") {Element.show("notified-projects")} else {Element.hide("notified-projects")}' %> :onchange => 'if (this.value == "selected") {Element.show("notified-projects")} else {Element.hide("notified-projects")}' %>
</p> </p>
<% content_tag 'div', :id => 'notified-projects', :style => (@user.mail_notification == 'selected' ? '' : 'display:none;') do %> <%= content_tag 'div', :id => 'notified-projects', :style => (@user.mail_notification == 'selected' ? '' : 'display:none;') do %>
<p><% @user.projects.each do |project| %> <p><% @user.projects.each do |project| %>
<label><%= check_box_tag 'notified_project_ids[]', project.id, @user.notified_projects_ids.include?(project.id) %> <%=h project.name %></label><br /> <label><%= check_box_tag 'notified_project_ids[]', project.id, @user.notified_projects_ids.include?(project.id) %> <%=h project.name %></label><br />
<% end %></p> <% end %></p>
+1
View File
@@ -26,6 +26,7 @@ module RedmineApp
config.active_record.observers = :message_observer, :issue_observer, :journal_observer, :news_observer, :document_observer, :wiki_content_observer, :comment_observer config.active_record.observers = :message_observer, :issue_observer, :journal_observer, :news_observer, :document_observer, :wiki_content_observer, :comment_observer
config.active_record.store_full_sti_class = true config.active_record.store_full_sti_class = true
config.active_record.default_timezone = :local
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
+1 -1
View File
@@ -43,7 +43,7 @@ module ActionView
end end
end end
ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| "#{html_tag}" } ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| html_tag || ''.html_safe }
require 'mail' require 'mail'
+2 -2
View File
@@ -76,14 +76,14 @@ ar:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
byte: byte:
one: "Byte" one: "Byte"
other: "Bytes" other: "Bytes"
kb: "kB" kb: "KB"
mb: "MB" mb: "MB"
gb: "GB" gb: "GB"
tb: "TB" tb: "TB"
+1 -1
View File
@@ -78,7 +78,7 @@ bg:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+1 -1
View File
@@ -89,7 +89,7 @@ bs:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+1 -1
View File
@@ -80,7 +80,7 @@ ca:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+2 -2
View File
@@ -81,14 +81,14 @@ cs:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
byte: byte:
one: "Bajt" one: "Bajt"
other: "Bajtů" other: "Bajtů"
kb: "kB" kb: "KB"
mb: "MB" mb: "MB"
gb: "GB" gb: "GB"
tb: "TB" tb: "TB"
+1 -1
View File
@@ -91,7 +91,7 @@ da:
format: format:
# separator: # separator:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+2 -2
View File
@@ -93,7 +93,7 @@ de:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
@@ -1036,7 +1036,7 @@ de:
label_copy_attachments: Anhänge Kopieren label_copy_attachments: Anhänge Kopieren
label_item_position: "%{position}/%{count}" label_item_position: "%{position}/%{count}"
label_completed_versions: Abgeschlossene Versionen label_completed_versions: Abgeschlossene Versionen
field_multiple: Mehrer Werte field_multiple: Mehrere Werte
setting_commit_cross_project_ref: Erlauben auf Tickets aller anderen Projekte zu referenzieren setting_commit_cross_project_ref: Erlauben auf Tickets aller anderen Projekte zu referenzieren
text_issue_conflict_resolution_add_notes: Meine Änderungen übernehmen und alle anderen Änderungen verwerfen text_issue_conflict_resolution_add_notes: Meine Änderungen übernehmen und alle anderen Änderungen verwerfen
text_issue_conflict_resolution_overwrite: Meine Änderungen trotzdem übernehmen (vorherige Notizen bleiben erhalten aber manche können überschrieben werden) text_issue_conflict_resolution_overwrite: Meine Änderungen trotzdem übernehmen (vorherige Notizen bleiben erhalten aber manche können überschrieben werden)
+1 -1
View File
@@ -77,7 +77,7 @@ el:
precision: 3 precision: 3
human: human:
format: format:
precision: 1 precision: 3
delimiter: "" delimiter: ""
storage_units: storage_units:
format: "%n %u" format: "%n %u"
+2 -2
View File
@@ -81,14 +81,14 @@ en-GB:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
byte: byte:
one: "Byte" one: "Byte"
other: "Bytes" other: "Bytes"
kb: "kB" kb: "KB"
mb: "MB" mb: "MB"
gb: "GB" gb: "GB"
tb: "TB" tb: "TB"
+2 -2
View File
@@ -77,14 +77,14 @@ en:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
byte: byte:
one: "Byte" one: "Byte"
other: "Bytes" other: "Bytes"
kb: "kB" kb: "KB"
mb: "MB" mb: "MB"
gb: "GB" gb: "GB"
tb: "TB" tb: "TB"
+1 -1
View File
@@ -48,7 +48,7 @@ es:
# These three are to override number.format and are optional # These three are to override number.format and are optional
# separator: # separator:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+1 -1
View File
@@ -94,7 +94,7 @@ et:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+1 -1
View File
@@ -79,7 +79,7 @@ eu:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+1 -1
View File
@@ -77,7 +77,7 @@ fa:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+1 -1
View File
@@ -64,7 +64,7 @@ fi:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+1 -1
View File
@@ -91,7 +91,7 @@ fr:
format: '%n %u' format: '%n %u'
human: human:
format: format:
precision: 2 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+1 -1
View File
@@ -32,7 +32,7 @@ gl:
format: format:
# separator: # separator:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+1 -1
View File
@@ -72,7 +72,7 @@ hr:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+1 -1
View File
@@ -97,7 +97,7 @@
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+1 -1
View File
@@ -78,7 +78,7 @@ id:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+2 -2
View File
@@ -96,7 +96,7 @@ ja:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
@@ -758,7 +758,7 @@ ja:
label_week: label_week:
label_date_from: "日付指定: " label_date_from: "日付指定: "
label_date_to: から label_date_to: から
label_language_based: 既定の言語の設定に従う label_language_based: ユーザの言語の設定に従う
label_sort_by: "並び替え %{value}" label_sort_by: "並び替え %{value}"
label_send_test_email: テストメールを送信 label_send_test_email: テストメールを送信
label_feeds_access_key: RSSアクセスキー label_feeds_access_key: RSSアクセスキー
+1 -1
View File
@@ -119,7 +119,7 @@ ko:
# These three are to override number.format and are optional # These three are to override number.format and are optional
# separator: # separator:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+1 -1
View File
@@ -109,7 +109,7 @@ lt:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
# Storage units output formatting. # Storage units output formatting.
# %u is the storage unit, %n is the number (default: 2 MB) # %u is the storage unit, %n is the number (default: 2 MB)
+1 -1
View File
@@ -72,7 +72,7 @@ lv:
human: human:
format: format:
delimiter: " " delimiter: " "
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+1 -1
View File
@@ -77,7 +77,7 @@ mk:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+1 -1
View File
@@ -75,7 +75,7 @@ mn:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+1 -1
View File
@@ -74,7 +74,7 @@ nl:
precision: 3 precision: 3
human: human:
format: format:
precision: 1 precision: 3
delimiter: "" delimiter: ""
storage_units: storage_units:
format: "%n %u" format: "%n %u"
+1 -1
View File
@@ -63,7 +63,7 @@
other: "nesten %{count} år" other: "nesten %{count} år"
number: number:
format: format:
precision: 2 precision: 3
separator: "." separator: "."
delimiter: "," delimiter: ","
currency: currency:
+1 -1
View File
@@ -21,7 +21,7 @@ pl:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+5 -5
View File
@@ -18,10 +18,10 @@ pt-BR:
time: time:
formats: formats:
default: "%A, %d de %B de %Y, %H:%M hs" default: "%A, %d de %B de %Y, %H:%M h"
time: "%H:%M hs" time: "%H:%M h"
short: "%d/%m, %H:%M hs" short: "%d/%m, %H:%M h"
long: "%A, %d de %B de %Y, %H:%M hs" long: "%A, %d de %B de %Y, %H:%M h"
only_second: "%S" only_second: "%S"
datetime: datetime:
formats: formats:
@@ -97,7 +97,7 @@ pt-BR:
delimiter: '.' delimiter: '.'
human: human:
format: format:
precision: 1 precision: 3
delimiter: '.' delimiter: '.'
storage_units: storage_units:
format: "%n %u" format: "%n %u"
+1 -1
View File
@@ -89,7 +89,7 @@ pt:
delimiter: '' delimiter: ''
human: human:
format: format:
precision: 1 precision: 3
delimiter: '' delimiter: ''
storage_units: storage_units:
format: "%n %u" format: "%n %u"
+1 -1
View File
@@ -73,7 +73,7 @@ ro:
human: human:
format: format:
precision: 1 precision: 3
delimiter: "" delimiter: ""
storage_units: storage_units:
format: "%n %u" format: "%n %u"
+35 -35
View File
@@ -68,7 +68,7 @@ ru:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 2 precision: 3
# Rails 2.2 # Rails 2.2
# storage_units: [байт, КБ, МБ, ГБ, ТБ] # storage_units: [байт, КБ, МБ, ГБ, ТБ]
@@ -1089,11 +1089,11 @@ ru:
notice_issue_successful_create: Задача %{id} создана. notice_issue_successful_create: Задача %{id} создана.
label_between: между label_between: между
setting_issue_group_assignment: Разрешить назначение задач группам пользователей setting_issue_group_assignment: Разрешить назначение задач группам пользователей
label_diff: diff label_diff: Разница(diff)
text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo) text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
description_query_sort_criteria_direction: Sort direction description_query_sort_criteria_direction: Порядок сортировки
description_project_scope: Search scope description_project_scope: Search scope
description_filter: Filter description_filter: Фильтр
description_user_mail_notification: Mail notification settings description_user_mail_notification: Mail notification settings
description_date_from: Enter start date description_date_from: Enter start date
description_message_content: Message content description_message_content: Message content
@@ -1101,23 +1101,23 @@ ru:
description_date_range_interval: Choose range by selecting start and end date description_date_range_interval: Choose range by selecting start and end date
description_issue_category_reassign: Choose issue category description_issue_category_reassign: Choose issue category
description_search: Searchfield description_search: Searchfield
description_notes: Notes description_notes: Примечания
description_date_range_list: Choose range from list description_date_range_list: Выберите диапазон из списка
description_choose_project: Projects description_choose_project: Проекты
description_date_to: Enter end date description_date_to: Введите дату выполнения
description_query_sort_criteria_attribute: Sort attribute description_query_sort_criteria_attribute: Критерий сортировки
description_wiki_subpages_reassign: Choose new parent page description_wiki_subpages_reassign: Выбрать новую родительскую страницу
description_selected_columns: Selected Columns description_selected_columns: Выбранные столбцы
label_parent_revision: Parent label_parent_revision: Родительский
label_child_revision: Child label_child_revision: Дочерний
error_scm_annotate_big_text_file: The entry cannot be annotated, as it exceeds the maximum text file size. error_scm_annotate_big_text_file: Комментарий невозможен из-за превышения максимального размера текстового файла.
setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues setting_default_issue_start_date_to_creation_date: Использовать текущую дату в качестве даты начала для новых задач
button_edit_section: Edit this section button_edit_section: Редактировать эту секцию
setting_repositories_encodings: Attachments and repositories encodings setting_repositories_encodings: Кодировка вложений и хранилищ
description_all_columns: All Columns description_all_columns: Все столбцы
button_export: Export button_export: Экспорт
label_export_options: "%{export_format} export options" label_export_options: "%{export_format} параметры экспорта"
error_attachment_too_big: This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size}) error_attachment_too_big: Этот файл нельзя загрузить из-за превышения максимального размера файла (%{max_size})
notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}." notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
label_x_issues: label_x_issues:
zero: 0 Задач zero: 0 Задач
@@ -1125,21 +1125,21 @@ ru:
few: "%{count} Задач" few: "%{count} Задач"
many: "%{count} Задач" many: "%{count} Задач"
other: "%{count} Задач" other: "%{count} Задач"
label_repository_new: New repository label_repository_new: Новое хранилище
field_repository_is_default: Main repository field_repository_is_default: Хранилище по умолчанию
label_copy_attachments: Copy attachments label_copy_attachments: Копировать вложения
label_item_position: "%{position}/%{count}" label_item_position: "%{position}/%{count}"
label_completed_versions: Completed versions label_completed_versions: Завершенные версии
text_project_identifier_info: Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed. text_project_identifier_info: Допускаются только строчные латинские буквы (a-z), цифры, тире и подчеркивания.<br />После сохранения идентификатор изменить нельзя.
field_multiple: Multiple values field_multiple: Множественные значения
setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed setting_commit_cross_project_ref: Разрешить ссылаться и исправлять задачи во всех остальных проектах
text_issue_conflict_resolution_add_notes: Add my notes and discard my other changes text_issue_conflict_resolution_add_notes: Добавить мои примечания и отказаться от моих изменений
text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten) text_issue_conflict_resolution_overwrite: Применить мои изменения (все предыдущие замечания будут сохранены, но некоторые изменения могут быть перезаписаны)
notice_issue_update_conflict: The issue has been updated by an other user while you were editing it. notice_issue_update_conflict: Кто-то изменил задачу, пока вы ее редактировали.
text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link} text_issue_conflict_resolution_cancel: Отменить мои изменения и показать задачу заново %{link}
permission_manage_related_issues: Manage related issues permission_manage_related_issues: Управление связанными задачами
field_ldap_filter: LDAP filter field_ldap_filter: Фильтр LDAP
label_search_for_watchers: Search for watchers to add label_search_for_watchers: Найти наблюдателей
notice_account_deleted: "Ваша учетная запись полностью удалена" notice_account_deleted: "Ваша учетная запись полностью удалена"
setting_unsubscribe: "Разрешить пользователям удалять свои учетные записи" setting_unsubscribe: "Разрешить пользователям удалять свои учетные записи"
button_delete_my_account: "Удалить мою учетную запись" button_delete_my_account: "Удалить мою учетную запись"
+1 -1
View File
@@ -75,7 +75,7 @@ sk:
human: human:
format: format:
precision: 1 precision: 3
delimiter: "" delimiter: ""
storage_units: storage_units:
format: "%n %u" format: "%n %u"
+1 -1
View File
@@ -75,7 +75,7 @@ sl:
precision: 3 precision: 3
human: human:
format: format:
precision: 1 precision: 3
delimiter: "" delimiter: ""
storage_units: storage_units:
format: "%n %u" format: "%n %u"
+2 -2
View File
@@ -77,14 +77,14 @@ sq:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
byte: byte:
one: "Byte" one: "Byte"
other: "Bytes" other: "Bytes"
kb: "kB" kb: "KB"
mb: "MB" mb: "MB"
gb: "GB" gb: "GB"
tb: "TB" tb: "TB"
+1 -1
View File
@@ -77,7 +77,7 @@ sr-YU:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+1 -1
View File
@@ -77,7 +77,7 @@ sr:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+2 -2
View File
@@ -47,14 +47,14 @@ sv:
# These three are to override number.format and are optional # These three are to override number.format and are optional
# separator: # separator:
delimiter: "" delimiter: ""
# precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
byte: byte:
one: "Byte" one: "Byte"
other: "Bytes" other: "Bytes"
kb: "kB" kb: "KB"
mb: "MB" mb: "MB"
gb: "GB" gb: "GB"
tb: "TB" tb: "TB"
+1 -1
View File
@@ -74,7 +74,7 @@ th:
precision: 3 precision: 3
human: human:
format: format:
precision: 1 precision: 3
delimiter: "" delimiter: ""
storage_units: storage_units:
format: "%n %u" format: "%n %u"
+1 -1
View File
@@ -99,7 +99,7 @@ tr:
format: format:
delimiter: '.' delimiter: '.'
separator: ',' separator: ','
precision: 2 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+1 -1
View File
@@ -74,7 +74,7 @@ uk:
precision: 3 precision: 3
human: human:
format: format:
precision: 1 precision: 3
delimiter: "" delimiter: ""
storage_units: storage_units:
format: "%n %u" format: "%n %u"
+1 -1
View File
@@ -48,7 +48,7 @@ vi:
# These three are to override number.format and are optional # These three are to override number.format and are optional
# separator: # separator:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
+1 -1
View File
@@ -87,7 +87,7 @@
# 下列三個選項設定, 若有設定值將會取代 number.format 成為預設值 # 下列三個選項設定, 若有設定值將會取代 number.format 成為預設值
# separator: # separator:
delimiter: "" delimiter: ""
precision: 1 precision: 3
# 儲存單位輸出格式. # 儲存單位輸出格式.
# %u 是儲存單位, %n 是數值 (預設值: 2 MB) # %u 是儲存單位, %n 是數值 (預設值: 2 MB)
storage_units: storage_units:
+2 -2
View File
@@ -79,14 +79,14 @@ zh:
human: human:
format: format:
delimiter: "" delimiter: ""
precision: 1 precision: 3
storage_units: storage_units:
format: "%n %u" format: "%n %u"
units: units:
byte: byte:
one: "Byte" one: "Byte"
other: "Bytes" other: "Bytes"
kb: "kB" kb: "KB"
mb: "MB" mb: "MB"
gb: "GB" gb: "GB"
tb: "TB" tb: "TB"
+2
View File
@@ -224,6 +224,7 @@ RedmineApp::Application.routes.draw do
get 'projects/:id/repository/:repository_id/revisions', :to => 'repositories#revisions' get 'projects/:id/repository/:repository_id/revisions', :to => 'repositories#revisions'
get 'projects/:id/repository/:repository_id/revisions/:rev/:action(/*path(.:ext))', get 'projects/:id/repository/:repository_id/revisions/:rev/:action(/*path(.:ext))',
:controller => 'repositories', :controller => 'repositories',
:format => false,
:constraints => { :constraints => {
:action => /(browse|show|entry|raw|annotate|diff)/, :action => /(browse|show|entry|raw|annotate|diff)/,
:rev => /[a-z0-9\.\-_]+/ :rev => /[a-z0-9\.\-_]+/
@@ -242,6 +243,7 @@ RedmineApp::Application.routes.draw do
delete 'projects/:id/repository/revisions/:rev/issues/:issue_id', :to => 'repositories#remove_related_issue' delete 'projects/:id/repository/revisions/:rev/issues/:issue_id', :to => 'repositories#remove_related_issue'
get 'projects/:id/repository/revisions/:rev/:action(/*path(.:ext))', get 'projects/:id/repository/revisions/:rev/:action(/*path(.:ext))',
:controller => 'repositories', :controller => 'repositories',
:format => false,
:constraints => { :constraints => {
:action => /(browse|show|entry|raw|annotate|diff)/, :action => /(browse|show|entry|raw|annotate|diff)/,
:rev => /[a-z0-9\.\-_]+/ :rev => /[a-z0-9\.\-_]+/
+70
View File
@@ -4,6 +4,76 @@ Redmine - project management software
Copyright (C) 2006-2012 Jean-Philippe Lang Copyright (C) 2006-2012 Jean-Philippe Lang
http://www.redmine.org/ http://www.redmine.org/
== 2012-09-16 v2.0.4
* Defect #10818: Running rake in test environment causes exception
* Defect #11209: Wiki diff may generate broken HTML
* Defect #11217: Project names in drop-down are escaped twice
* Defect #11262: Link is escaped in wiki added/updated notification email
* Defect #11307: Can't filter for negative numeric custom fields
* Defect #11325: Unified diff link broken on specific file/revision diff view
* Defect #11341: Escaped link in conflict resolution form
* Defect #11365: Attachment description length is not validated
* Defect #11511: Confirmation page has broken HTML when a project folding sub project is deleted
* Defect #11533: rake redmine:plugins:test doesn't run tests in subdirectories
* Defect #11541: Version sharing is missing in the REST API
* Defect #11550: Issue reminder doesn't work when using asynchronous delivery
* Defect #11776: Can't override mailer views inside redmine plugin.
* Defect #11789: Edit section links broken with h5/h6 headings
* Feature #11338: Exclude emails with auto-submitted => auto-generated
* Patch #11299: redmine:plugins:migrate should update db/schema.rb
* Patch #11328: Fix Japanese mistranslation for 'label_language_based'
* Patch #11448: Russian translation for 1.4-stable and 2.0-stable
* Patch #11600: Fix plural form of the abbreviation for hours in Brazilian Portuguese
== 2012-06-18 v2.0.3
* Defect #10688: PDF export from Wiki - Problems with tables
* Defect #11061: Cannot choose commit versions to view differences in Git/Mercurial repository view
* Defect #11065: E-Mail submitted tickets: German umlauts in 'Subject' get malformed (ruby 1.8)
* Defect #11098: Default priorities have the same position and can't be reordered
* Defect #11105: <% content_for :header_tags do %> doesn't work inside hook
* Defect #11112: REST API - custom fields in POST/PUT ignored for time_entries
* Defect #11118: "Maximum file size" displayed on upload forms is incorrect
* Defect #11124: Link to user is escaped in activity title
* Defect #11133: Wiki-page section edit link can point to incorrect section
* Defect #11160: SQL Error on time report if a custom field has multiple values for an entry
* Defect #11170: Topics sort order is broken in Redmine 2.x
* Defect #11178: Spent time sorted by date-descending order lists same-date entries in physical order (not-reverse)
* Defect #11185: Redmine fails to delete a project with parent/child task
* Feature #11162: Upgrade to Rails 3.2.6
* Patch #11113: Small glitch in German localization
== 2012-06-05 v2.0.2
* Defect #11032: Project list is not shown when "For any event on the selected projects only..." is selected on user edit panel
* Defect #11038: "Create and continue" should preserve project, issue and activity when logging time
* Defect #11046: Redmine.pm does not support "bind as user" ldap authentication
* Defect #11051: reposman.rb fails in 1.4.2 because of missing require for rubygems
* Defect #11085: Wiki start page can't be changed
* Feature #11084: Update Rails to 3.2.5
== 2012-05-28 v2.0.1
* Defect #10923: After creating a new Version Redmine jumps back to "Information"
* Defect #10932: Links to delete watchers are escaped when gravatars are enabled
* Defect #10964: Updated column doesn't get updated on issues
* Defect #10965: rake yard does not work for generating documentation.
* Defect #10972: Columns selection not displayed on the custom query form
* Defect #10991: My page > Spent time 'project' column is html-encoded
* Defect #10996: Time zones lost when upgrading from Redmine 1.4 to 2.0
* Defect #11013: Fetching Email from IMAP/POP3 - uninitialized constant RAILS_DEFAULT_LOGGER error
* Defect #11024: redmine_plugin_model generator does not create the migration
* Defect #11027: Saving new query without name causes escaping of input field
* Defect #11028: Project identifier can be updated
== 2012-05-15 v2.0.0
* Feature #4796: Rails 3 support
* Feature #7720: Limit the pagination-limit when max-results is fewer than max-pagination-limit
* Feature #9034: Add an id to the flash messages
* Patch #10782: Better translation for Estonian language
== 2012-05-13 v1.4.2 == 2012-05-13 v1.4.2
* Defect #10744: rake task redmine:email:test broken * Defect #10744: rake task redmine:email:test broken
+6 -3
View File
@@ -13,7 +13,7 @@ http://www.redmine.org/
* A database: * A database:
* MySQL (tested with MySQL 5.1) * MySQL (tested with MySQL 5.1)
* PostgreSQL (tested with PostgreSQL 8.4) * PostgreSQL (tested with PostgreSQL 9.1)
* SQLite3 (tested with SQLite 3.6) * SQLite3 (tested with SQLite 3.6)
Optional: Optional:
@@ -38,7 +38,10 @@ Optional:
3. Create an empty utf8 encoded database: "redmine" for example 3. Create an empty utf8 encoded database: "redmine" for example
4. Configure the database parameters in config/database.yml 4. Configure the database parameters in config/database.yml
for the "production" environment (default database is MySQL) for the "production" environment (default database is MySQL and ruby1.8)
If you're running Redmine with MySQL and ruby1.9, replace the adapter name
with `mysql2`
5. Generate a session store secret 5. Generate a session store secret
@@ -65,7 +68,7 @@ Optional:
8. Test the installation by running the WEBrick web server 8. Test the installation by running the WEBrick web server
Under the main application directory run: Under the main application directory run:
ruby script/server -e production ruby script/rails server -e production
Once WEBrick has started, point your browser to http://localhost:3000/ Once WEBrick has started, point your browser to http://localhost:3000/
You should now see the application welcome page. You should now see the application welcome page.
+9 -2
View File
@@ -366,12 +366,19 @@ sub is_member {
); );
$sthldap->execute($auth_source_id); $sthldap->execute($auth_source_id);
while (my @rowldap = $sthldap->fetchrow_array) { while (my @rowldap = $sthldap->fetchrow_array) {
my $bind_as = $rowldap[3] ? $rowldap[3] : "";
my $bind_pw = $rowldap[4] ? $rowldap[4] : "";
if ($bind_as =~ m/\$login/) {
# replace $login with $redmine_user and use $redmine_pass
$bind_as =~ s/\$login/$redmine_user/g;
$bind_pw = $redmine_pass
}
my $ldap = Authen::Simple::LDAP->new( my $ldap = Authen::Simple::LDAP->new(
host => ($rowldap[2] eq "1" || $rowldap[2] eq "t") ? "ldaps://$rowldap[0]:$rowldap[1]" : $rowldap[0], host => ($rowldap[2] eq "1" || $rowldap[2] eq "t") ? "ldaps://$rowldap[0]:$rowldap[1]" : $rowldap[0],
port => $rowldap[1], port => $rowldap[1],
basedn => $rowldap[5], basedn => $rowldap[5],
binddn => $rowldap[3] ? $rowldap[3] : "", binddn => $bind_as,
bindpw => $rowldap[4] ? $rowldap[4] : "", bindpw => $bind_pw,
filter => "(".$rowldap[6]."=%s)" filter => "(".$rowldap[6]."=%s)"
); );
my $method = $r->method; my $method = $r->method;
+1
View File
@@ -3,6 +3,7 @@
require 'optparse' require 'optparse'
require 'find' require 'find'
require 'etc' require 'etc'
require 'rubygems'
Version = "1.4" Version = "1.4"
SUPPORTED_SCM = %w( Subversion Darcs Mercurial Bazaar Git Filesystem ) SUPPORTED_SCM = %w( Subversion Darcs Mercurial Bazaar Git Filesystem )
+17 -1
View File
@@ -2,7 +2,23 @@ Description:
The plugin generator creates stubs for a new Redmine plugin. The plugin generator creates stubs for a new Redmine plugin.
Example: Example:
./script/generate redmine_plugin meetings ./script/rails generate redmine_plugin meetings
create plugins/meetings/app
create plugins/meetings/app/controllers
create plugins/meetings/app/helpers
create plugins/meetings/app/models
create plugins/meetings/app/views
create plugins/meetings/db/migrate
create plugins/meetings/lib/tasks
create plugins/meetings/assets/images
create plugins/meetings/assets/javascripts
create plugins/meetings/assets/stylesheets
create plugins/meetings/config/locales
create plugins/meetings/test
create plugins/meetings/test/fixtures
create plugins/meetings/test/unit
create plugins/meetings/test/functional
create plugins/meetings/test/integration
create plugins/meetings/README.rdoc create plugins/meetings/README.rdoc
create plugins/meetings/init.rb create plugins/meetings/init.rb
create plugins/meetings/config/routes.rb create plugins/meetings/config/routes.rb
@@ -2,4 +2,4 @@ Description:
Generates a plugin controller. Generates a plugin controller.
Example: Example:
./script/generate redmine_plugin_controller meetings pools index show vote ./script/rails generate redmine_plugin_controller meetings pools index show vote
+1 -1
View File
@@ -2,4 +2,4 @@ Description:
Generates a plugin model. Generates a plugin model.
Examples: Examples:
./script/generate redmine_plugin_model meetings pool ./script/rails generate redmine_plugin_model meetings pool
@@ -1,6 +1,12 @@
class RedminePluginModelGenerator < Rails::Generators::NamedBase class RedminePluginModelGenerator < Rails::Generators::NamedBase
source_root File.expand_path("../templates", __FILE__) source_root File.expand_path("../templates", __FILE__)
argument :model, :type => :string argument :model, :type => :string
argument :attributes, :type => :array, :default => [], :banner => "field[:type][:index] field[:type][:index]"
class_option :migration, :type => :boolean
class_option :timestamps, :type => :boolean
class_option :parent, :type => :string, :desc => "The parent class for the generated model"
class_option :indexes, :type => :boolean, :default => true, :desc => "Add indexes for references and belongs_to columns"
attr_reader :plugin_path, :plugin_name, :plugin_pretty_name attr_reader :plugin_path, :plugin_name, :plugin_pretty_name
@@ -10,10 +16,26 @@ class RedminePluginModelGenerator < Rails::Generators::NamedBase
@plugin_pretty_name = plugin_name.titleize @plugin_pretty_name = plugin_name.titleize
@plugin_path = "plugins/#{plugin_name}" @plugin_path = "plugins/#{plugin_name}"
@model_class = model.camelize @model_class = model.camelize
@table_name = @model_class.tableize
@migration_filename = "create_#{@table_name}"
@migration_class_name = @migration_filename.camelize
end end
def copy_templates def copy_templates
template 'model.rb.erb', "#{plugin_path}/app/models/#{model}.rb" template 'model.rb.erb', "#{plugin_path}/app/models/#{model.underscore}.rb"
template 'unit_test.rb.erb', "#{plugin_path}/test/unit/#{model}_test.rb" template 'unit_test.rb.erb', "#{plugin_path}/test/unit/#{model.underscore}_test.rb"
migration_filename = "%03i_#{@migration_filename}.rb" % (migration_number + 1)
template "migration.rb", "#{plugin_path}/db/migrate/#{migration_filename}"
end
def attributes_with_index
attributes.select { |a| a.has_index? || (a.reference? && options[:indexes]) }
end
def migration_number
current = Dir.glob("#{plugin_path}/db/migrate/*.rb").map do |file|
File.basename(file).split("_").first.to_i
end.max.to_i
end end
end end
@@ -0,0 +1,15 @@
class <%= @migration_class_name %> < ActiveRecord::Migration
def change
create_table :<%= @table_name %> do |t|
<% attributes.each do |attribute| -%>
t.<%= attribute.type %> :<%= attribute.name %><%= attribute.inject_options %>
<% end -%>
<% if options[:timestamps] %>
t.timestamps
<% end -%>
end
<% attributes_with_index.each do |attribute| -%>
add_index :<%= table_name %>, :<%= attribute.index_name %><%= attribute.inject_index_options %>
<% end -%>
end
end
@@ -131,6 +131,15 @@ module ActiveRecord
when 'lowest' when 'lowest'
move_to_bottom move_to_bottom
end end
reset_positions_in_list
end
def reset_positions_in_list
acts_as_list_class.where(scope_condition).reorder("#{position_column} ASC, id ASC").each_with_index do |item, i|
unless item.send(position_column) == (i + 1)
acts_as_list_class.update_all({position_column => (i + 1)}, {:id => item.id})
end
end
end end
# Removes the item from the list. # Removes the item from the list.
@@ -209,7 +218,7 @@ module ActiveRecord
def bottom_item(except = nil) def bottom_item(except = nil)
conditions = scope_condition conditions = scope_condition
conditions = "#{conditions} AND #{self.class.primary_key} != #{except.id}" if except conditions = "#{conditions} AND #{self.class.primary_key} != #{except.id}" if except
acts_as_list_class.find(:first, :conditions => conditions, :order => "#{position_column} DESC") acts_as_list_class.where(conditions).reorder("#{position_column} DESC").first
end end
# Forces item to assume the bottom position in the list. # Forces item to assume the bottom position in the list.
+28 -21
View File
@@ -283,6 +283,7 @@ class TCPDF
@state ||= 0 @state ||= 0
@tableborder ||= 0 @tableborder ||= 0
@tdbegin ||= false @tdbegin ||= false
@tdtext ||= ''
@tdwidth ||= 0 @tdwidth ||= 0
@tdheight ||= 0 @tdheight ||= 0
@tdalign ||= "L" @tdalign ||= "L"
@@ -3510,28 +3511,12 @@ class TCPDF
else else
#Text #Text
if (@href) if (@tdbegin)
element.gsub!(/[\t\r\n\f]/, "");
@tdtext << element.gsub(/&nbsp;/, " ");
elsif (@href)
element.gsub!(/[\t\r\n\f]/, ""); element.gsub!(/[\t\r\n\f]/, "");
addHtmlLink(@href, element, fill); addHtmlLink(@href, element, fill);
elsif (@tdbegin)
element.gsub!(/[\t\r\n\f]/, "");
element.gsub!(/&nbsp;/, " ");
base_page = @page;
base_x = @x;
base_y = @y;
MultiCell(@tdwidth, @tdheight, unhtmlentities(element.strip), @tableborder, @tdalign, @tdfill, 1);
tr_end = @t_cells[@table_id][@tr_id][@td_id]['j1'] + 1;
if @max_td_page[tr_end].nil? or (@max_td_page[tr_end] < @page)
@max_td_page[tr_end] = @page
@max_td_y[tr_end] = @y
elsif (@max_td_page[tr_end] == @page)
@max_td_y[tr_end] = @y if @max_td_y[tr_end].nil? or (@max_td_y[tr_end] < @y)
end
@page = base_page;
@x = base_x + @tdwidth;
@y = base_y;
elsif (@pre_state == true and element.length > 0) elsif (@pre_state == true and element.length > 0)
Write(@lasth, unhtmlentities(element), '', fill); Write(@lasth, unhtmlentities(element), '', fill);
elsif (element.strip.length > 0) elsif (element.strip.length > 0)
@@ -3825,6 +3810,7 @@ class TCPDF
@x += 5; @x += 5;
when 'table' when 'table'
Ln();
if @default_table_columns < @max_table_columns[@table_id] if @default_table_columns < @max_table_columns[@table_id]
@table_columns = @max_table_columns[@table_id]; @table_columns = @max_table_columns[@table_id];
else else
@@ -3921,6 +3907,11 @@ class TCPDF
when 'img' when 'img'
if (!attrs['src'].nil?) if (!attrs['src'].nil?)
# Don't generates image inside table tag
if (@tdbegin)
@tdtext << attrs['src'];
return
end
# Only generates image include a pdf if RMagick is avalaible # Only generates image include a pdf if RMagick is avalaible
unless Object.const_defined?(:Magick) unless Object.const_defined?(:Magick)
Write(@lasth, attrs['src'], '', fill); Write(@lasth, attrs['src'], '', fill);
@@ -4079,6 +4070,23 @@ class TCPDF
Ln(); Ln();
when 'td','th' when 'td','th'
base_page = @page;
base_x = @x;
base_y = @y;
MultiCell(@tdwidth, @tdheight, unhtmlentities(@tdtext.strip), @tableborder, @tdalign, @tdfill, 1);
tr_end = @t_cells[@table_id][@tr_id][@td_id]['j1'] + 1;
if @max_td_page[tr_end].nil? or (@max_td_page[tr_end] < @page)
@max_td_page[tr_end] = @page
@max_td_y[tr_end] = @y
elsif (@max_td_page[tr_end] == @page)
@max_td_y[tr_end] = @y if @max_td_y[tr_end].nil? or (@max_td_y[tr_end] < @y)
end
@page = base_page;
@x = base_x + @tdwidth;
@y = base_y;
@tdtext = '';
@tdbegin = false; @tdbegin = false;
@tdwidth = 0; @tdwidth = 0;
@tdheight = 0; @tdheight = 0;
@@ -4126,7 +4134,6 @@ class TCPDF
@l_margin -= 5; @l_margin -= 5;
@r_margin -= 5; @r_margin -= 5;
@tableborder=0; @tableborder=0;
Ln();
@table_id += 1; @table_id += 1;
when 'strong' when 'strong'
+5 -4
View File
@@ -50,16 +50,17 @@ module Redmine
words_add += 1 words_add += 1
else else
del_at = pos unless del_at del_at = pos unless del_at
deleted << ' ' + h(change[2]) deleted << ' ' unless deleted.empty?
deleted << h(change[2])
words_del += 1 words_del += 1
end end
end end
if add_at if add_at
words[add_at] = '<span class="diff_in">' + words[add_at] words[add_at] = '<span class="diff_in">'.html_safe + words[add_at]
words[add_to] = words[add_to] + '</span>' words[add_to] = words[add_to] + '</span>'.html_safe
end end
if del_at if del_at
words.insert del_at - del_off + dels + words_add, '<span class="diff_out">' + deleted + '</span>' words.insert del_at - del_off + dels + words_add, '<span class="diff_out">'.html_safe + deleted + '</span>'.html_safe
dels += 1 dels += 1
del_off += words_del del_off += words_del
words_del = 0 words_del = 0
+3 -3
View File
@@ -138,21 +138,21 @@ module Redmine
# Add list and boolean custom fields as available criteria # Add list and boolean custom fields as available criteria
custom_fields = (@project.nil? ? IssueCustomField.for_all : @project.all_issue_custom_fields) custom_fields = (@project.nil? ? IssueCustomField.for_all : @project.all_issue_custom_fields)
custom_fields.select {|cf| %w(list bool).include? cf.field_format }.each do |cf| custom_fields.select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
@available_criteria["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'Issue' AND c.customized_id = #{Issue.table_name}.id)", @available_criteria["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'Issue' AND c.customized_id = #{Issue.table_name}.id ORDER BY c.value LIMIT 1)",
:format => cf.field_format, :format => cf.field_format,
:label => cf.name} :label => cf.name}
end if @project end if @project
# Add list and boolean time entry custom fields # Add list and boolean time entry custom fields
TimeEntryCustomField.find(:all).select {|cf| %w(list bool).include? cf.field_format }.each do |cf| TimeEntryCustomField.find(:all).select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
@available_criteria["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'TimeEntry' AND c.customized_id = #{TimeEntry.table_name}.id)", @available_criteria["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'TimeEntry' AND c.customized_id = #{TimeEntry.table_name}.id ORDER BY c.value LIMIT 1)",
:format => cf.field_format, :format => cf.field_format,
:label => cf.name} :label => cf.name}
end end
# Add list and boolean time entry activity custom fields # Add list and boolean time entry activity custom fields
TimeEntryActivityCustomField.find(:all).select {|cf| %w(list bool).include? cf.field_format }.each do |cf| TimeEntryActivityCustomField.find(:all).select {|cf| %w(list bool).include? cf.field_format }.each do |cf|
@available_criteria["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'Enumeration' AND c.customized_id = #{TimeEntry.table_name}.activity_id)", @available_criteria["cf_#{cf.id}"] = {:sql => "(SELECT c.value FROM #{CustomValue.table_name} c WHERE c.custom_field_id = #{cf.id} AND c.customized_type = 'Enumeration' AND c.customized_id = #{TimeEntry.table_name}.activity_id ORDER BY c.value LIMIT 1)",
:format => cf.field_format, :format => cf.field_format,
:label => cf.name} :label => cf.name}
end end
+10 -3
View File
@@ -107,7 +107,13 @@ module Redmine
# #
def self.render_on(hook, options={}) def self.render_on(hook, options={})
define_method hook do |context| define_method hook do |context|
context[:controller].send(:render_to_string, {:locals => context}.merge(options)) if context[:hook_caller].respond_to?(:render)
context[:hook_caller].send(:render, {:locals => context}.merge(options))
elsif context[:controller].is_a?(ActionController::Base)
context[:controller].send(:render_to_string, {:locals => context}.merge(options))
else
raise "Cannot render #{self.name} hook from #{context[:hook_caller].class.name}"
end
end end
end end
@@ -138,14 +144,15 @@ module Redmine
# * project => current project # * project => current project
# * request => Request instance # * request => Request instance
# * controller => current Controller instance # * controller => current Controller instance
# * hook_caller => object that called the hook
# #
module Helper module Helper
def call_hook(hook, context={}) def call_hook(hook, context={})
if is_a?(ActionController::Base) if is_a?(ActionController::Base)
default_context = {:controller => self, :project => @project, :request => request} default_context = {:controller => self, :project => @project, :request => request, :hook_caller => self}
Redmine::Hook.call_hook(hook, default_context.merge(context)) Redmine::Hook.call_hook(hook, default_context.merge(context))
else else
default_context = { :project => @project } default_context = { :project => @project, :hook_caller => self }
default_context[:controller] = controller if respond_to?(:controller) default_context[:controller] = controller if respond_to?(:controller)
default_context[:request] = request if respond_to?(:request) default_context[:request] = request if respond_to?(:request)
Redmine::Hook.call_hook(hook, default_context.merge(context)).join(' ').html_safe Redmine::Hook.call_hook(hook, default_context.merge(context)).join(' ').html_safe
+1 -1
View File
@@ -53,7 +53,7 @@ module Redmine
private private
def logger def logger
RAILS_DEFAULT_LOGGER ::Rails.logger
end end
end end
end end
+1
View File
@@ -82,6 +82,7 @@ module Redmine #:nodoc:
view_path = File.join(p.directory, 'app', 'views') view_path = File.join(p.directory, 'app', 'views')
if File.directory?(view_path) if File.directory?(view_path)
ActionController::Base.prepend_view_path(view_path) ActionController::Base.prepend_view_path(view_path)
ActionMailer::Base.prepend_view_path(view_path)
end end
# Adds the app/{controllers,helpers,models} directories of the plugin to the autoload path # Adds the app/{controllers,helpers,models} directories of the plugin to the autoload path

Some files were not shown because too many files have changed in this diff Show More