Commit 3133eb48de1d1f587b01c80b8f47881f0a9eadfd

Authored by Rodrigo Souto
2 parents c8842511 04962ef3

Merge branch 'stable'

Conflicts:
	script/quick-start
	test/unit/application_helper_test.rb
	test/unit/environment_statistics_block_test.rb
	test/unit/environment_test.rb
app/helpers/application_helper.rb
@@ -1424,7 +1424,7 @@ module ApplicationHelper @@ -1424,7 +1424,7 @@ module ApplicationHelper
1424 end 1424 end
1425 1425
1426 def filter_html(html, source) 1426 def filter_html(html, source)
1427 - if @plugins 1427 + if @plugins && source.has_macro?
1428 html = convert_macro(html, source) 1428 html = convert_macro(html, source)
1429 #TODO This parse should be done through the macro infra, but since there 1429 #TODO This parse should be done through the macro infra, but since there
1430 # are old things that do not support it we are keeping this hot spot. 1430 # are old things that do not support it we are keeping this hot spot.
app/helpers/boxes_helper.rb
@@ -100,9 +100,7 @@ module BoxesHelper @@ -100,9 +100,7 @@ module BoxesHelper
100 options[:title] = _("This block is invisible. Your visitors will not see it.") 100 options[:title] = _("This block is invisible. Your visitors will not see it.")
101 end 101 end
102 102
103 - if @controller.send(:content_editor?)  
104 - result = filter_html(result, block)  
105 - end 103 + result = filter_html(result, block)
106 104
107 box_decorator.block_target(block.box, block) + 105 box_decorator.block_target(block.box, block) +
108 content_tag('div', 106 content_tag('div',
app/helpers/profile_helper.rb
1 module ProfileHelper 1 module ProfileHelper
2 2
3 def display_field(title, profile, field, force = false) 3 def display_field(title, profile, field, force = false)
4 - if (!force && !profile.active_fields.include?(field.to_s)) ||  
5 - (profile.active_fields.include?(field.to_s) && !profile.public_fields.include?(field.to_s) && (!user || (user != profile && !user.is_a_friend?(profile)))) 4 + unless force || profile.may_display_field_to?(field, user)
6 return '' 5 return ''
7 end 6 end
8 value = profile.send(field) 7 value = profile.send(field)
app/models/article.rb
@@ -681,6 +681,10 @@ class Article < ActiveRecord::Base @@ -681,6 +681,10 @@ class Article < ActiveRecord::Base
681 681
682 delegate :region, :region_id, :environment, :environment_id, :to => :profile, :allow_nil => true 682 delegate :region, :region_id, :environment, :environment_id, :to => :profile, :allow_nil => true
683 683
  684 + def has_macro?
  685 + true
  686 + end
  687 +
684 private 688 private
685 689
686 def sanitize_tag_list 690 def sanitize_tag_list
app/models/block.rb
@@ -138,4 +138,8 @@ class Block < ActiveRecord::Base @@ -138,4 +138,8 @@ class Block < ActiveRecord::Base
138 4.hours 138 4.hours
139 end 139 end
140 140
  141 + def has_macro?
  142 + false
  143 + end
  144 +
141 end 145 end
app/models/profile.rb
@@ -226,12 +226,14 @@ class Profile < ActiveRecord::Base @@ -226,12 +226,14 @@ class Profile < ActiveRecord::Base
226 226
227 belongs_to :region 227 belongs_to :region
228 228
  229 + LOCATION_FIELDS = %w[address district city state country_name zip_code]
  230 +
229 def location(separator = ' - ') 231 def location(separator = ' - ')
230 myregion = self.region 232 myregion = self.region
231 if myregion 233 if myregion
232 myregion.hierarchy.reverse.first(2).map(&:name).join(separator) 234 myregion.hierarchy.reverse.first(2).map(&:name).join(separator)
233 else 235 else
234 - %w[address district city state country_name zip_code ].map {|item| (self.respond_to?(item) && !self.send(item).blank?) ? self.send(item) : nil }.compact.join(separator) 236 + LOCATION_FIELDS.map {|item| (self.respond_to?(item) && !self.send(item).blank?) ? self.send(item) : nil }.compact.join(separator)
235 end 237 end
236 end 238 end
237 239
@@ -882,6 +884,21 @@ private :generate_url, :url_options @@ -882,6 +884,21 @@ private :generate_url, :url_options
882 [] 884 []
883 end 885 end
884 886
  887 + def may_display_field_to? field, user = nil
  888 + if not self.active_fields.include? field.to_s
  889 + self.send "may_display_#{field}_to?", user rescue true
  890 + else
  891 + not (!self.public_fields.include? field.to_s and (!user or (user != self and !user.is_a_friend?(self))))
  892 + end
  893 + end
  894 +
  895 + def may_display_location_to? user = nil
  896 + LOCATION_FIELDS.each do |field|
  897 + return false if !self.may_display_field_to? field, user
  898 + end
  899 + return true
  900 + end
  901 +
885 # field => privacy (e.g.: "address" => "public") 902 # field => privacy (e.g.: "address" => "public")
886 def fields_privacy 903 def fields_privacy
887 self.data[:fields_privacy] 904 self.data[:fields_privacy]
app/models/raw_html_block.rb
@@ -10,4 +10,7 @@ class RawHTMLBlock < Block @@ -10,4 +10,7 @@ class RawHTMLBlock < Block
10 (title.blank? ? '' : block_title(title)).html_safe + html.to_s.html_safe 10 (title.blank? ? '' : block_title(title)).html_safe + html.to_s.html_safe
11 end 11 end
12 12
  13 + def has_macro?
  14 + true
  15 + end
13 end 16 end
lib/feed_updater.rb
@@ -20,14 +20,20 @@ end @@ -20,14 +20,20 @@ end
20 class FeedUpdater 20 class FeedUpdater
21 21
22 class ExceptionNotification < ActionMailer::Base 22 class ExceptionNotification < ActionMailer::Base
23 - def mail error 23 + def mail container, error
24 environment = Environment.default 24 environment = Environment.default
25 25
26 recipients NOOSFERO_CONF['exception_recipients'] 26 recipients NOOSFERO_CONF['exception_recipients']
27 from environment.contact_email 27 from environment.contact_email
28 reply_to environment.contact_email 28 reply_to environment.contact_email
29 subject "[#{environment.name}] Feed-updater: #{error.message}" 29 subject "[#{environment.name}] Feed-updater: #{error.message}"
30 - body render(:text => error.backtrace.join("\n")) 30 + body render(:text => "
  31 +Container:
  32 +#{container.inspect}
  33 +
  34 +Backtrace:
  35 +#{error.backtrace.join("\n")}
  36 + ")
31 end 37 end
32 end 38 end
33 39
@@ -88,11 +94,13 @@ class FeedUpdater @@ -88,11 +94,13 @@ class FeedUpdater
88 if !running 94 if !running
89 break 95 break
90 end 96 end
91 - feed_handler.process(container) 97 + begin
  98 + feed_handler.process(container)
  99 + rescue Exception => e
  100 + FeedUpdater::ExceptionNotification.deliver_mail container, e if NOOSFERO_CONF['exception_recipients'].present?
  101 + end
92 end 102 end
93 end 103 end
94 - rescue Exception => e  
95 - FeedUpdater::ExceptionNotification.deliver_mail e if NOOSFERO_CONF['exception_recipients'].present?  
96 end 104 end
97 end 105 end
98 106
test/unit/application_helper_test.rb
@@ -591,7 +591,7 @@ class ApplicationHelperTest &lt; ActiveSupport::TestCase @@ -591,7 +591,7 @@ class ApplicationHelperTest &lt; ActiveSupport::TestCase
591 end 591 end
592 592
593 should 'include item in usermenu for environment enabled features' do 593 should 'include item in usermenu for environment enabled features' do
594 - env = Environment.new 594 + env = fast_create(Environment)
595 env.enable('xmpp_chat', false) 595 env.enable('xmpp_chat', false)
596 stubs(:environment).returns(env) 596 stubs(:environment).returns(env)
597 597
@@ -791,6 +791,29 @@ class ApplicationHelperTest &lt; ActiveSupport::TestCase @@ -791,6 +791,29 @@ class ApplicationHelperTest &lt; ActiveSupport::TestCase
791 '<br style=\'clear: left;\' /></div>', result 791 '<br style=\'clear: left;\' /></div>', result
792 end 792 end
793 793
  794 + should 'not filter html if source does not have macros' do
  795 + class Plugin1 < Noosfero::Plugin
  796 + end
  797 +
  798 + class Plugin1::Macro1 < Noosfero::Plugin::Macro
  799 + def parse(params, inner_html, source)
  800 + 'Test1'
  801 + end
  802 + end
  803 +
  804 + environment = Environment.default
  805 + environment.enable_plugin(Plugin1)
  806 + @plugins = Noosfero::Plugin::Manager.new(environment, self)
  807 + macro1_name = Plugin1::Macro1.identifier
  808 + source = mock
  809 + source.stubs(:has_macro?).returns(false)
  810 +
  811 + html = "<div class='macro nonEdit' data-macro='#{macro1_name}' data-macro-param='123'></div>"
  812 + parsed_html = filter_html(html, source)
  813 +
  814 + assert_no_match /Test1/, parsed_html
  815 + end
  816 +
794 protected 817 protected
795 include NoosferoTestHelper 818 include NoosferoTestHelper
796 819
test/unit/environment_statistics_block_test.rb
@@ -84,7 +84,7 @@ class EnvironmentStatisticsBlockTest &lt; ActiveSupport::TestCase @@ -84,7 +84,7 @@ class EnvironmentStatisticsBlockTest &lt; ActiveSupport::TestCase
84 end 84 end
85 85
86 should 'not display enterprises if disabled' do 86 should 'not display enterprises if disabled' do
87 - env = Environment.new 87 + env = fast_create(Environment)
88 env.enable('disable_asset_enterprises', false) 88 env.enable('disable_asset_enterprises', false)
89 89
90 block = EnvironmentStatisticsBlock.new 90 block = EnvironmentStatisticsBlock.new
test/unit/environment_test.rb
@@ -34,7 +34,7 @@ class EnvironmentTest &lt; ActiveSupport::TestCase @@ -34,7 +34,7 @@ class EnvironmentTest &lt; ActiveSupport::TestCase
34 end 34 end
35 35
36 def test_features 36 def test_features
37 - v = Environment.new 37 + v = fast_create(Environment)
38 v.enable('feature1', false) 38 v.enable('feature1', false)
39 assert v.enabled?('feature1') 39 assert v.enabled?('feature1')
40 v.disable('feature1', false) 40 v.disable('feature1', false)
@@ -42,14 +42,14 @@ class EnvironmentTest &lt; ActiveSupport::TestCase @@ -42,14 +42,14 @@ class EnvironmentTest &lt; ActiveSupport::TestCase
42 end 42 end
43 43
44 def test_enabled_features 44 def test_enabled_features
45 - v = Environment.new 45 + v = fast_create(Environment)
46 v.enable('feature1', false) 46 v.enable('feature1', false)
47 v.enable('feature2', false) 47 v.enable('feature2', false)
48 assert v.enabled?('feature1') && v.enabled?('feature2') && !v.enabled?('feature3') 48 assert v.enabled?('feature1') && v.enabled?('feature2') && !v.enabled?('feature3')
49 end 49 end
50 50
51 def test_enabled_features_no_features_enabled 51 def test_enabled_features_no_features_enabled
52 - v = Environment.new 52 + v = fast_create(Environment)
53 assert !v.enabled?('feature1') && !v.enabled?('feature2') && !v.enabled?('feature3') 53 assert !v.enabled?('feature1') && !v.enabled?('feature2') && !v.enabled?('feature3')
54 end 54 end
55 55
@@ -1074,7 +1074,7 @@ class EnvironmentTest &lt; ActiveSupport::TestCase @@ -1074,7 +1074,7 @@ class EnvironmentTest &lt; ActiveSupport::TestCase
1074 end 1074 end
1075 1075
1076 should 'get enabled features' do 1076 should 'get enabled features' do
1077 - env = Environment.new 1077 + env = fast_create(Environment)
1078 env.enable('feature1', false) 1078 env.enable('feature1', false)
1079 env.enable('feature2', false) 1079 env.enable('feature2', false)
1080 env.disable('feature3', false) 1080 env.disable('feature3', false)
test/unit/person_test.rb
@@ -211,7 +211,7 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -211,7 +211,7 @@ class PersonTest &lt; ActiveSupport::TestCase
211 p3 = create_user('testuser3').person 211 p3 = create_user('testuser3').person
212 p1.add_friend(p3) 212 p1.add_friend(p3)
213 213
214 - assert_equal [p2,p3], p1.friends(true) # force reload 214 + assert_equivalent [p2,p3], p1.friends(true) # force reload
215 215
216 end 216 end
217 217
@@ -1074,8 +1074,8 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1074,8 +1074,8 @@ class PersonTest &lt; ActiveSupport::TestCase
1074 person.add_friend(friend_1) 1074 person.add_friend(friend_1)
1075 person.add_friend(friend_2) 1075 person.add_friend(friend_2)
1076 person.add_friend(friend_3) 1076 person.add_friend(friend_3)
1077 - assert_equal [friend_1, friend_2, friend_3], person.friends  
1078 - assert_equal [friend_1], person.friends.online 1077 + assert_equivalent [friend_1, friend_2, friend_3], person.friends
  1078 + assert_equivalent [friend_1], person.friends.online
1079 end 1079 end
1080 1080
1081 should 'return url to a person wall' do 1081 should 'return url to a person wall' do
test/unit/profile_helper_test.rb
@@ -13,84 +13,48 @@ class ProfileHelperTest &lt; ActiveSupport::TestCase @@ -13,84 +13,48 @@ class ProfileHelperTest &lt; ActiveSupport::TestCase
13 end 13 end
14 attr_reader :profile, :helper 14 attr_reader :profile, :helper
15 15
16 - should 'not display field if field is not active and not forced' do  
17 - profile.expects(:active_fields).returns([])  
18 - assert_equal '', display_field('Title', profile, 'field')  
19 - end  
20 -  
21 - should 'display field if field is not active but is forced' do  
22 - profile.expects(:active_fields).returns([]) 16 + should 'display field if may display it' do
  17 + self.stubs(:user).returns(nil)
  18 + profile.expects(:may_display_field_to?).returns(true)
23 profile.expects(:field).returns('value') 19 profile.expects(:field).returns('value')
24 - assert_match /Title.*value/, display_field('Title', profile, 'field', true) 20 + assert_match /Title.*value/, display_field('Title', profile, 'field')
25 end 21 end
26 22
27 - should 'not display field if field is active but not public and not logged in' do  
28 - profile.stubs(:active_fields).returns(['field'])  
29 - profile.expects(:public_fields).returns([])  
30 - @controller = mock  
31 - @controller.stubs(:user).returns(nil) 23 + should 'not display field if may not display it and not forced' do
  24 + self.stubs(:user).returns(nil)
  25 + profile.expects(:may_display_field_to?).returns(false)
32 assert_equal '', display_field('Title', profile, 'field') 26 assert_equal '', display_field('Title', profile, 'field')
33 end 27 end
34 28
35 - should 'not display field if field is active but not public and user is not friend' do  
36 - profile.stubs(:active_fields).returns(['field'])  
37 - profile.expects(:public_fields).returns([])  
38 - user = mock  
39 - user.expects(:is_a_friend?).with(profile).returns(false)  
40 - @controller = mock  
41 - @controller.stubs(:user).returns(user)  
42 - assert_equal '', display_field('Title', profile, 'field')  
43 - end  
44 -  
45 - should 'display field if field is active and not public but user is profile owner' do  
46 - profile.stubs(:active_fields).returns(['field'])  
47 - profile.expects(:public_fields).returns([]) 29 + should 'display field if may not display it but is forced' do
  30 + self.stubs(:user).returns(nil)
  31 + profile.stubs(:may_display_field_to?).returns(false)
48 profile.expects(:field).returns('value') 32 profile.expects(:field).returns('value')
49 - @controller = mock  
50 - @controller.stubs(:user).returns(profile)  
51 assert_match /Title.*value/, display_field('Title', profile, 'field', true) 33 assert_match /Title.*value/, display_field('Title', profile, 'field', true)
52 end 34 end
53 35
54 - should 'display field if field is active and not public but user is a friend' do  
55 - profile.stubs(:active_fields).returns(['field'])  
56 - profile.expects(:public_fields).returns([])  
57 - profile.expects(:field).returns('value')  
58 - user = mock  
59 - user.expects(:is_a_friend?).with(profile).returns(true)  
60 - @controller = mock  
61 - @controller.stubs(:user).returns(user)  
62 - assert_match /Title.*value/, display_field('Title', profile, 'field', true) 36 + should 'display work info if at least one of the fields should be displayed' do
  37 + self.stubs(:user).returns(nil)
  38 + profile.stubs(:may_display_field_to?).with(:organization, nil).returns(true)
  39 + profile.stubs(:may_display_field_to?).with(:organization_website, nil).returns(false)
  40 + profile.expects(:organization).returns('Organization Name')
  41 + profile.expects(:organization_website).never
  42 + assert_match /Work.*Organization Name/, display_work_info(profile)
63 end 43 end
64 44
65 - should 'not display work info if field is active but not public and user is not friend' do  
66 - profile.stubs(:active_fields).returns(['organization', 'organization_website'])  
67 - profile.expects(:public_fields).returns([]).times(2)  
68 - user = mock  
69 - user.expects(:is_a_friend?).with(profile).returns(false).times(2)  
70 - @controller = mock  
71 - @controller.stubs(:user).returns(user) 45 + should 'not display work info if none of the fields should be displayed' do
  46 + self.stubs(:user).returns(nil)
  47 + profile.stubs(:may_display_field_to?).returns(false)
  48 + profile.expects(:organization).never
  49 + profile.expects(:organization_website).never
72 assert_equal '', display_work_info(profile) 50 assert_equal '', display_work_info(profile)
73 end 51 end
74 52
75 - should 'display work info if field is active and not public but user is profile owner' do  
76 - profile.stubs(:active_fields).returns(['organization', 'organization_website'])  
77 - profile.expects(:public_fields).returns([]).times(2)  
78 - profile.expects(:organization).returns('Organization Name')  
79 - profile.expects(:organization_website).returns('')  
80 - @controller = mock  
81 - @controller.stubs(:user).returns(profile)  
82 - assert_match /Work.*Organization Name/, display_work_info(profile)  
83 - end  
84 -  
85 - should 'display work info if field is active and not public but user is a friend' do  
86 - profile.stubs(:active_fields).returns(['organization', 'organization_website'])  
87 - profile.expects(:public_fields).returns([]).times(2) 53 + should 'display work info if both fields should be displayed' do
  54 + self.stubs(:user).returns(nil)
  55 + profile.stubs(:may_display_field_to?).returns(true)
88 profile.expects(:organization).returns('Organization Name') 56 profile.expects(:organization).returns('Organization Name')
89 profile.expects(:organization_website).returns('') 57 profile.expects(:organization_website).returns('')
90 - user = mock  
91 - user.expects(:is_a_friend?).with(profile).returns(true).times(2)  
92 - @controller = mock  
93 - @controller.stubs(:user).returns(user)  
94 assert_match /Work.*Organization Name/, display_work_info(profile) 58 assert_match /Work.*Organization Name/, display_work_info(profile)
95 end 59 end
96 60
test/unit/profile_list_block_test.rb
@@ -34,6 +34,7 @@ class ProfileListBlockTest &lt; ActiveSupport::TestCase @@ -34,6 +34,7 @@ class ProfileListBlockTest &lt; ActiveSupport::TestCase
34 self.expects(:profile_image_link).with(person2, :minor).once 34 self.expects(:profile_image_link).with(person2, :minor).once
35 self.expects(:profile_image_link).with(person3, :minor).once 35 self.expects(:profile_image_link).with(person3, :minor).once
36 36
  37 + self.stubs(:tag).returns('<div></div>')
37 self.expects(:content_tag).returns('<div></div>').at_least_once 38 self.expects(:content_tag).returns('<div></div>').at_least_once
38 self.expects(:block_title).returns('block title').at_least_once 39 self.expects(:block_title).returns('block title').at_least_once
39 40
test/unit/profile_test.rb
@@ -1833,4 +1833,59 @@ class ProfileTest &lt; ActiveSupport::TestCase @@ -1833,4 +1833,59 @@ class ProfileTest &lt; ActiveSupport::TestCase
1833 assert_equal f, p.fields_privacy 1833 assert_equal f, p.fields_privacy
1834 end 1834 end
1835 1835
  1836 + should 'not display field if field is active but not public and user not logged in' do
  1837 + profile = fast_create(Profile)
  1838 + profile.stubs(:active_fields).returns(['field'])
  1839 + profile.stubs(:public_fields).returns([])
  1840 + assert !profile.may_display_field_to?('field', nil)
  1841 + end
  1842 +
  1843 + should 'not display field if field is active but not public and user is not friend' do
  1844 + profile = fast_create(Profile)
  1845 + profile.stubs(:active_fields).returns(['field'])
  1846 + profile.expects(:public_fields).returns([])
  1847 + user = mock
  1848 + user.expects(:is_a_friend?).with(profile).returns(false)
  1849 + assert !profile.may_display_field_to?('field', user)
  1850 + end
  1851 +
  1852 + should 'display field if field is active and not public but user is profile owner' do
  1853 + user = profile = fast_create(Profile)
  1854 + profile.stubs(:active_fields).returns(['field'])
  1855 + profile.expects(:public_fields).returns([])
  1856 + assert profile.may_display_field_to?('field', user)
  1857 + end
  1858 +
  1859 + should 'display field if field is active and not public but user is a friend' do
  1860 + profile = fast_create(Profile)
  1861 + profile.stubs(:active_fields).returns(['field'])
  1862 + profile.expects(:public_fields).returns([])
  1863 + user = mock
  1864 + user.expects(:is_a_friend?).with(profile).returns(true)
  1865 + assert profile.may_display_field_to?('field', user)
  1866 + end
  1867 +
  1868 + should 'call may_display on field name if the field is not active' do
  1869 + user = fast_create(Person)
  1870 + profile = fast_create(Profile)
  1871 + profile.stubs(:active_fields).returns(['humble'])
  1872 + profile.expects(:may_display_humble_to?).never
  1873 + profile.expects(:may_display_bundle_to?).once
  1874 +
  1875 + profile.may_display_field_to?('humble', user)
  1876 + profile.may_display_field_to?('bundle', user)
  1877 + end
  1878 +
  1879 + # TODO Eventually we would like to specify it in a deeper granularity...
  1880 + should 'not display location if any field is private' do
  1881 + user = fast_create(Person)
  1882 + profile = fast_create(Profile)
  1883 + profile.stubs(:active_fields).returns(Profile::LOCATION_FIELDS)
  1884 + Profile::LOCATION_FIELDS.each { |field| profile.stubs(:may_display_field_to?).with(field, user).returns(true)}
  1885 + assert profile.may_display_location_to?(user)
  1886 +
  1887 + profile.stubs(:may_display_field_to?).with(Profile::LOCATION_FIELDS[0], user).returns(false)
  1888 + assert !profile.may_display_location_to?(user)
  1889 + end
  1890 +
1836 end 1891 end
vendor/plugins/action_tracker_has_comments/init.rb
1 # monkey patch to add comments on action_tracker 1 # monkey patch to add comments on action_tracker
2 2
3 -ActionTracker::Record.module_eval do 3 +Rails.configuration.to_prepare do
  4 + ActionTracker::Record.module_eval do
4 5
5 - has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :finder_sql => 'SELECT * FROM comments WHERE #{conditions_for_comments} ORDER BY created_at ASC', :counter_sql => 'SELECT * FROM comments WHERE #{conditions_for_comments}' 6 + has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :finder_sql => 'SELECT * FROM comments WHERE #{conditions_for_comments} ORDER BY created_at ASC', :counter_sql => 'SELECT * FROM comments WHERE #{conditions_for_comments}'
6 7
7 - def conditions_for_comments  
8 - type, id = (self.target_type == 'Article' ? ['Article', self.target_id] : [self.class.to_s, self.id])  
9 - "source_type = '#{type}' AND source_id = '#{id}'"  
10 - end 8 + def conditions_for_comments
  9 + type, id = (self.target_type == 'Article' ? ['Article', self.target_id] : [self.class.to_s, self.id])
  10 + "source_type = '#{type}' AND source_id = '#{id}'"
  11 + end
11 12
12 - def comments_as_thread  
13 - result = {}  
14 - root = []  
15 - self.comments.each do |c|  
16 - c.replies = []  
17 - result[c.id] ||= c  
18 - c.reply_of_id.nil? ? root << c : result[c.reply_of_id].replies << c 13 + def comments_as_thread
  14 + result = {}
  15 + root = []
  16 + self.comments.each do |c|
  17 + c.replies = []
  18 + result[c.id] ||= c
  19 + c.reply_of_id.nil? ? root << c : result[c.reply_of_id].replies << c
  20 + end
  21 + root
19 end 22 end
20 - root  
21 - end  
22 23
  24 + end
23 end 25 end
vendor/plugins/monkey_patches/rescue_delayed_job_crashes/init.rb
1 Delayed::Worker.module_eval do 1 Delayed::Worker.module_eval do
2 # based on https://groups.google.com/forum/#!topic/delayed_job/ZGMUFFppNgs 2 # based on https://groups.google.com/forum/#!topic/delayed_job/ZGMUFFppNgs
3 class Delayed::Worker::ExceptionNotification < ActionMailer::Base 3 class Delayed::Worker::ExceptionNotification < ActionMailer::Base
4 - def mail error 4 + def mail job, error
5 environment = Environment.default 5 environment = Environment.default
6 6
7 recipients NOOSFERO_CONF['exception_recipients'] 7 recipients NOOSFERO_CONF['exception_recipients']
8 from environment.contact_email 8 from environment.contact_email
9 reply_to environment.contact_email 9 reply_to environment.contact_email
10 - subject "[#{environment.name}] DelayedJob: #{error.message}"  
11 - body render(:text => error.backtrace.join("\n")) 10 + subject "[#{environment.name}] DelayedJob ##{job.id}: #{error.message}"
  11 + body render(:text => "
  12 +Job:
  13 +#{job.inspect}
  14 +
  15 +Handler:
  16 +#{job.handler}
  17 +
  18 +Backtrace:
  19 +#{error.backtrace.join("\n")}
  20 + ")
12 end 21 end
13 end 22 end
14 23
15 def handle_failed_job_with_notification(job, error) 24 def handle_failed_job_with_notification(job, error)
16 - Delayed::Worker::ExceptionNotification.deliver_mail error if NOOSFERO_CONF['exception_recipients'].present? 25 + Delayed::Worker::ExceptionNotification.deliver_mail job, error if NOOSFERO_CONF['exception_recipients'].present?
17 handle_failed_job_without_notification job, error 26 handle_failed_job_without_notification job, error
18 end 27 end
19 alias_method_chain :handle_failed_job, :notification 28 alias_method_chain :handle_failed_job, :notification