Commit 3a1370f6c8d5ed8d3915e6d201ebe1ac21562d25
Committed by
Daniela Feitosa
1 parent
4cdef594
Exists in
master
and in
29 other branches
Spaminator Plugin
Sorry, couldn't organize thing in micro-commits... =/
Showing
16 changed files
with
745 additions
and
0 deletions
Show diff stats
plugins/spaminator/controllers/spaminator_plugin_admin_controller.rb
0 → 100644
... | ... | @@ -0,0 +1,61 @@ |
1 | +class SpaminatorPluginAdminController < AdminController | |
2 | + append_view_path File.join(File.dirname(__FILE__) + '/../views') | |
3 | + | |
4 | + def index | |
5 | + @settings ||= Noosfero::Plugin::Settings.new(environment, SpaminatorPlugin, params[:settings]) | |
6 | + @reports_count = SpaminatorPlugin::Report.from(environment).count | |
7 | + @reports = SpaminatorPlugin::Report.from(environment).order('created_at desc').limit(3) | |
8 | + @next_run = settings.period.to_i + ((settings.last_run || Date.today).to_date - Date.today) | |
9 | + if request.post? | |
10 | + settings.period = nil if settings.period.blank? | |
11 | + settings.save! | |
12 | + redirect_to :action => 'index' | |
13 | + end | |
14 | + end | |
15 | + | |
16 | + def deploy | |
17 | + if !settings.deployed | |
18 | + SpaminatorPlugin.schedule_scan(environment) | |
19 | + settings.deployed = true | |
20 | + settings.save! | |
21 | + end | |
22 | + redirect_to :action => 'index' | |
23 | + end | |
24 | + | |
25 | + def withhold | |
26 | + remove_scheduled_scan | |
27 | + settings.deployed = false | |
28 | + settings.save! | |
29 | + redirect_to :action => 'index' | |
30 | + end | |
31 | + | |
32 | + def scan | |
33 | + if !settings.scanning | |
34 | + settings.scanning = true | |
35 | + settings.save! | |
36 | + remove_scheduled_scan | |
37 | + Delayed::Job.enqueue(SpaminatorPlugin::ScanJob.new(environment)) | |
38 | + end | |
39 | + redirect_to :action => 'index' | |
40 | + end | |
41 | + | |
42 | + def reports | |
43 | + @reports = SpaminatorPlugin::Report.from(environment).order('created_at desc') | |
44 | + end | |
45 | + | |
46 | + private | |
47 | + | |
48 | + def settings | |
49 | + @settings ||= Noosfero::Plugin::Settings.new(environment, SpaminatorPlugin) | |
50 | + end | |
51 | + | |
52 | + def remove_scheduled_scan | |
53 | + if settings.scheduled_scan | |
54 | + Delayed::Job.find(settings.scheduled_scan).destroy | |
55 | + settings.scheduled_scan = nil | |
56 | + settings.save! | |
57 | + end | |
58 | + end | |
59 | + | |
60 | +end | |
61 | + | ... | ... |
plugins/spaminator/db/migrate/20120921223609_create_reports.rb
0 → 100644
... | ... | @@ -0,0 +1,21 @@ |
1 | +class CreateReports < ActiveRecord::Migration | |
2 | + def self.up | |
3 | + create_table :spaminator_plugin_reports do |t| | |
4 | + t.integer :spams_by_content, :default => 0 | |
5 | + t.integer :spams_by_no_network, :default => 0 | |
6 | + t.integer :spammers_by_comments, :default => 0 | |
7 | + t.integer :spammers_by_no_network, :default => 0 | |
8 | + t.integer :total_people, :default => 0 | |
9 | + t.integer :total_comments, :default => 0 | |
10 | + t.integer :processed_comments, :default => 0 | |
11 | + t.integer :processed_people, :default => 0 | |
12 | + t.references :environment | |
13 | + t.text :failed | |
14 | + t.timestamps | |
15 | + end | |
16 | + end | |
17 | + | |
18 | + def self.down | |
19 | + drop_table :spaminator_plugin_reports | |
20 | + end | |
21 | +end | ... | ... |
... | ... | @@ -0,0 +1,28 @@ |
1 | +class SpaminatorPlugin < Noosfero::Plugin | |
2 | + | |
3 | + def self.plugin_name | |
4 | + "Spaminator" | |
5 | + end | |
6 | + | |
7 | + def self.plugin_description | |
8 | + _("Search and destroy spams and spammers.") | |
9 | + end | |
10 | + | |
11 | + def self.period_default_setting | |
12 | + 30 | |
13 | + end | |
14 | + | |
15 | + def self.schedule_scan(environment) | |
16 | + settings = Noosfero::Plugin::Settings.new(environment, self) | |
17 | + if !settings.scanning | |
18 | + job = Delayed::Job.enqueue(SpaminatorPlugin::ScanJob.new(environment.id), 0, settings.period.to_i.days.from_now) | |
19 | + settings.scheduled_scan = job.id | |
20 | + settings.save! | |
21 | + end | |
22 | + end | |
23 | + | |
24 | + def stylesheet? | |
25 | + true | |
26 | + end | |
27 | + | |
28 | +end | ... | ... |
... | ... | @@ -0,0 +1,14 @@ |
1 | +class SpaminatorPlugin::Mailer < Noosfero::Plugin::MailerBase | |
2 | + | |
3 | + def inactive_person_notification(person) | |
4 | + hostname = person.hostname || person.environment.default_hostname | |
5 | + recipients person.email | |
6 | + from 'no-reply@' + hostname | |
7 | + subject _("[%s] You must reactivate your account.") % person.environment.name | |
8 | + content_type 'text/html' | |
9 | + body :person => person, | |
10 | + :environment => person.environment, | |
11 | + :url => url_for(:host => hostname, :controller => 'account', :action => 'forgot_password') | |
12 | + end | |
13 | + | |
14 | +end | ... | ... |
... | ... | @@ -0,0 +1,30 @@ |
1 | +class SpaminatorPlugin::Report < Noosfero::Plugin::ActiveRecord | |
2 | + serialize :failed, Hash | |
3 | + | |
4 | + belongs_to :environment | |
5 | + | |
6 | + validates_presence_of :environment | |
7 | + | |
8 | + named_scope :from, lambda { |environment| {:conditions => {:environment_id => environment}}} | |
9 | + | |
10 | + def after_initialize | |
11 | + self.failed ||= {:people => [], :comments => []} | |
12 | + end | |
13 | + | |
14 | + def spams | |
15 | + spams_by_no_network + spams_by_content | |
16 | + end | |
17 | + | |
18 | + def spammers | |
19 | + spammers_by_no_network + spammers_by_comments | |
20 | + end | |
21 | + | |
22 | + def formated_date | |
23 | + created_at.strftime("%Y-%m-%d") | |
24 | + end | |
25 | + | |
26 | + def details | |
27 | + # TODO Implement some decent visualization | |
28 | + inspect | |
29 | + end | |
30 | +end | ... | ... |
... | ... | @@ -0,0 +1,16 @@ |
1 | +class SpaminatorPlugin::ScanJob < Struct.new(:environment_id) | |
2 | + def perform | |
3 | + fork do | |
4 | + environment = Environment.find(environment_id) | |
5 | + settings = Noosfero::Plugin::Settings.new(environment, SpaminatorPlugin) | |
6 | + settings.scanning = true | |
7 | + settings.save! | |
8 | + | |
9 | + SpaminatorPlugin::Spaminator.run(environment) | |
10 | + | |
11 | + settings.scanning = false | |
12 | + SpaminatorPlugin.schedule_scan(environment) if settings.deployed | |
13 | + settings.save! | |
14 | + end | |
15 | + end | |
16 | +end | ... | ... |
... | ... | @@ -0,0 +1,156 @@ |
1 | +require 'spaminator_plugin/mailer' | |
2 | + | |
3 | +class SpaminatorPlugin::Spaminator | |
4 | + | |
5 | + class << self | |
6 | + def run(environment) | |
7 | + instance = new(environment) | |
8 | + instance.run | |
9 | + end | |
10 | + | |
11 | + def benchmark(environment) | |
12 | + puts Benchmark.measure { run(environment) } | |
13 | + end | |
14 | + end | |
15 | + | |
16 | + | |
17 | + def initialize(environment) | |
18 | + @environment = environment | |
19 | + @settings = Noosfero::Plugin::Settings.new(@environment, SpaminatorPlugin) | |
20 | + @report = SpaminatorPlugin::Report.new(:environment => environment, | |
21 | + :total_people => Person.count, | |
22 | + :total_comments => Comment.count) | |
23 | + end | |
24 | + | |
25 | + def run | |
26 | + start_time = Time.now | |
27 | + | |
28 | + process_all_comments | |
29 | + process_all_people | |
30 | + | |
31 | + finish(start_time) | |
32 | + end | |
33 | + | |
34 | + protected | |
35 | + | |
36 | + def finish(start_time) | |
37 | + finish_report | |
38 | + @settings.last_run = start_time | |
39 | + @settings.save! | |
40 | + end | |
41 | + | |
42 | + # TODO considering run everything always | |
43 | + def on_environment | |
44 | + [ "profiles.environment_id = ?", @environment.id] | |
45 | + end | |
46 | + | |
47 | + def comments_to_process | |
48 | + Comment.joins("JOIN articles ON (comments.source_id = articles.id AND comments.source_type = 'Article') JOIN profiles ON (profiles.id = articles.profile_id)").without_spam.where(on_environment) | |
49 | + end | |
50 | + | |
51 | + def people_to_process | |
52 | + Person.visible.non_abusers.where(on_environment) | |
53 | + end | |
54 | + | |
55 | + def process_all_comments | |
56 | + comments = comments_to_process | |
57 | + total = comments.count | |
58 | + pbar = ProgressBar.new("☢ Comments", total) | |
59 | + comments.each do |comment| | |
60 | + begin | |
61 | + process_comment(comment) | |
62 | + rescue | |
63 | + register_fail(:comments, comment) | |
64 | + end | |
65 | + pbar.inc | |
66 | + end | |
67 | + @report.processed_comments = total | |
68 | + pbar.finish | |
69 | + end | |
70 | + | |
71 | + def process_all_people | |
72 | + people = people_to_process | |
73 | + total = people.count | |
74 | + pbar = ProgressBar.new("☢ People", total) | |
75 | + people.find_each do |person| | |
76 | + process_person_by_comments(person) | |
77 | + process_person_by_no_network(person) | |
78 | + pbar.inc | |
79 | + end | |
80 | + @report.processed_people = total | |
81 | + pbar.finish | |
82 | + end | |
83 | + | |
84 | + def process_comment(comment) | |
85 | + comment = Comment.find(comment.id) | |
86 | + comment.check_for_spam | |
87 | + @report.spams_by_content += 1 if comment.spam | |
88 | + | |
89 | + # TODO several comments with the same content: | |
90 | + # → disable author | |
91 | + # → mark all of them as spam | |
92 | + | |
93 | + # TODO check comments that contains URL's | |
94 | + end | |
95 | + | |
96 | + def process_person_by_comments(person) | |
97 | + # person is author of more than 2 comments marked as spam | |
98 | + # → mark as spammer | |
99 | + # | |
100 | + begin | |
101 | + number_of_spam_comments = Comment.spam.where(:author_id => person.id).count | |
102 | + if number_of_spam_comments > 2 | |
103 | + mark_as_spammer(person) | |
104 | + @report.spammers_by_comments += 1 | |
105 | + end | |
106 | + rescue | |
107 | + register_fail(:people, person) | |
108 | + end | |
109 | + end | |
110 | + | |
111 | + def process_person_by_no_network(person) | |
112 | + # person who signed up more than one month ago, have no friends and <= 1 | |
113 | + # communities | |
114 | + # | |
115 | + # → disable the profile | |
116 | + # ? mark their comments as spam | |
117 | + # | |
118 | + if person.created_at < (Time.now - 1.month) && | |
119 | + person.friends.count == 0 && | |
120 | + person.communities.count <= 1 | |
121 | + begin | |
122 | + disable_person(person) | |
123 | + @report.spammers_by_no_network += 1 | |
124 | + rescue | |
125 | + register_fail(:people, person) | |
126 | + end | |
127 | + Comment.where(:author_id => person.id).find_each do |comment| | |
128 | + begin | |
129 | + comment.spam! | |
130 | + @report.spams_by_no_network += 1 | |
131 | + rescue | |
132 | + register_fail(:comments, comment) | |
133 | + end | |
134 | + end | |
135 | + end | |
136 | + end | |
137 | + | |
138 | + def disable_person(person) | |
139 | + person.disable | |
140 | + SpaminatorPlugin::Mailer.delay.deliver_inactive_person_notification(person) | |
141 | + end | |
142 | + | |
143 | + def mark_as_spammer(person) | |
144 | + AbuseComplaint.create!(:reported => person).finish | |
145 | + end | |
146 | + | |
147 | + def finish_report | |
148 | + puts @report.details | |
149 | + @report.save! | |
150 | + end | |
151 | + | |
152 | + def register_fail(kind, failed) | |
153 | + @report[:failed][kind.to_sym] << failed.id | |
154 | + end | |
155 | +end | |
156 | + | ... | ... |
... | ... | @@ -0,0 +1,15 @@ |
1 | +#spaminator-report-table { | |
2 | + text-align: center; | |
3 | + float: right; | |
4 | + width: 50%; | |
5 | +} | |
6 | + | |
7 | +#spaminator-config-fields { | |
8 | + float: left; | |
9 | + width: 50%; | |
10 | +} | |
11 | + | |
12 | +#spaminator-reports-see-all { | |
13 | + border-bottom: none; | |
14 | + background-color: #f0f0f0; | |
15 | +} | ... | ... |
plugins/spaminator/test/functional/spaminator_plugin_admin_controller_test.rb
0 → 100644
... | ... | @@ -0,0 +1,82 @@ |
1 | +require 'test_helper' | |
2 | +require File.dirname(__FILE__) + '/../../controllers/spaminator_plugin_admin_controller' | |
3 | + | |
4 | +# Re-raise errors caught by the controller. | |
5 | +class SpaminatorPluginAdminController; def rescue_action(e) raise e end; end | |
6 | + | |
7 | +class SpaminatorPluginAdminControllerTest < ActionController::TestCase | |
8 | + def setup | |
9 | + @controller = SpaminatorPluginAdminController.new | |
10 | + @request = ActionController::TestRequest.new | |
11 | + @response = ActionController::TestResponse.new | |
12 | + @environment = Environment.default | |
13 | + @settings = Noosfero::Plugin::Settings.new(@environment, SpaminatorPlugin) | |
14 | + login_as(create_admin_user(@environment)) | |
15 | + end | |
16 | + | |
17 | + attr_accessor :settings, :environment | |
18 | + | |
19 | + should 'deploy spaminator' do | |
20 | + SpaminatorPlugin.expects(:schedule_scan).with(environment) | |
21 | + get :deploy | |
22 | + reload_settings | |
23 | + assert settings.deployed | |
24 | + end | |
25 | + | |
26 | + should 'deploy spaminator when already deployed' do | |
27 | + settings.deployed = true | |
28 | + settings.save! | |
29 | + SpaminatorPlugin.expects(:scheduled_scan).never | |
30 | + | |
31 | + get :deploy | |
32 | + end | |
33 | + | |
34 | + should 'withhold spaminator' do | |
35 | + settings.deployed = true | |
36 | + settings.save! | |
37 | + | |
38 | + get :withhold | |
39 | + reload_settings | |
40 | + | |
41 | + assert !settings.deployed | |
42 | + end | |
43 | + | |
44 | + should 'make spaminator scan' do | |
45 | + Delayed::Job.expects(:enqueue) | |
46 | + | |
47 | + get :scan | |
48 | + reload_settings | |
49 | + | |
50 | + assert settings.scanning | |
51 | + end | |
52 | + | |
53 | + should 'not scan if already scanning' do | |
54 | + settings.scanning = true | |
55 | + settings.save! | |
56 | + Delayed::Job.expects(:enqueue).never | |
57 | + | |
58 | + get :scan | |
59 | + end | |
60 | + | |
61 | + should 'remove scheduled scan' do | |
62 | + SpaminatorPlugin.schedule_scan(environment) | |
63 | + reload_settings | |
64 | + | |
65 | + assert settings.scheduled_scan | |
66 | + assert Delayed::Job.exists?(settings.scheduled_scan) | |
67 | + | |
68 | + @controller.stubs(:settings).returns(settings) | |
69 | + @controller.send(:remove_scheduled_scan) | |
70 | + reload_settings | |
71 | + | |
72 | + assert settings.scheduled_scan.nil? | |
73 | + assert !Delayed::Job.exists?(settings.scheduled_scan) | |
74 | + end | |
75 | + | |
76 | + private | |
77 | + | |
78 | + def reload_settings | |
79 | + environment.reload | |
80 | + settings = Noosfero::Plugin::Settings.new(environment, SpaminatorPlugin) | |
81 | + end | |
82 | +end | ... | ... |
plugins/spaminator/test/unit/spaminator_plugin/report_test.rb
0 → 100644
... | ... | @@ -0,0 +1,41 @@ |
1 | +require 'test_helper' | |
2 | + | |
3 | +class SpaminatorPlugin::ReportTest < ActiveSupport::TestCase | |
4 | + | |
5 | + should 'must belong to an environment' do | |
6 | + report = SpaminatorPlugin::Report.new | |
7 | + report.valid? | |
8 | + assert report.errors.invalid?(:environment) | |
9 | + | |
10 | + report.environment = Environment.default | |
11 | + report.valid? | |
12 | + assert !report.errors.invalid?(:environment) | |
13 | + end | |
14 | + | |
15 | + should 'have scope of all reports from an environment' do | |
16 | + environment = Environment.default | |
17 | + r1 = SpaminatorPlugin::Report.create(:environment => environment) | |
18 | + r2 = SpaminatorPlugin::Report.create(:environment => environment) | |
19 | + r3 = SpaminatorPlugin::Report.create(:environment => environment) | |
20 | + r4 = SpaminatorPlugin::Report.create(:environment => fast_create(Environment)) | |
21 | + | |
22 | + reports = SpaminatorPlugin::Report.from(environment) | |
23 | + | |
24 | + assert_equal ActiveRecord::NamedScope::Scope, reports.class | |
25 | + assert_includes reports, r1 | |
26 | + assert_includes reports, r2 | |
27 | + assert_includes reports, r3 | |
28 | + assert_not_includes reports, r4 | |
29 | + end | |
30 | + | |
31 | + should 'initialize failed hash' do | |
32 | + report = SpaminatorPlugin::Report.new | |
33 | + | |
34 | + assert report.failed.kind_of?(Hash) | |
35 | + assert report.failed.has_key?(:people) | |
36 | + assert report.failed.has_key?(:comments) | |
37 | + assert_equal [], report.failed[:people] | |
38 | + assert_equal [], report.failed[:comments] | |
39 | + end | |
40 | + | |
41 | +end | ... | ... |
plugins/spaminator/test/unit/spaminator_plugin/spaminator_test.rb
0 → 100644
... | ... | @@ -0,0 +1,137 @@ |
1 | +require 'test_helper' | |
2 | + | |
3 | +class SpaminatorPlugin::SpaminatorTest < ActiveSupport::TestCase | |
4 | + | |
5 | + def setup | |
6 | + @environment = Environment.default | |
7 | + @spaminator = SpaminatorPlugin::Spaminator.new(@environment) | |
8 | + @spaminator.stubs(:puts) | |
9 | + @settings = Noosfero::Plugin::Settings.new(@environment, SpaminatorPlugin) | |
10 | + @now = Time.now | |
11 | + Time.stubs(:now).returns(@now) | |
12 | + end | |
13 | + | |
14 | + attr_accessor :spaminator, :environment, :settings, :now | |
15 | + | |
16 | +# should 'search everything in the first run' do | |
17 | +# assert_equal(['profiles.environment_id = ?',99], spaminator.send(:conditions, nil)) | |
18 | +# end | |
19 | +# | |
20 | +# should 'search using recorded last date' do | |
21 | +# settings.last_run = now | |
22 | +# assert_equal(['profiles.environment_id = ? AND table.created_at > ?', 99, now], spaminator.send(:conditions, 'table')) | |
23 | +# end | |
24 | + | |
25 | + should 'record time of last run in environment' do | |
26 | + spaminator.expects(:process_all_comments) | |
27 | + spaminator.expects(:process_all_people) | |
28 | + environment.stubs(:save!) | |
29 | + spaminator.run | |
30 | + assert_equal now, settings.last_run | |
31 | + end | |
32 | + | |
33 | + should 'process only comments from the environment and that are not spams' do | |
34 | + profile = fast_create(Profile, :environment_id => environment) | |
35 | + another_profile = fast_create(Profile, :environment_id => fast_create(Environment)) | |
36 | + source = fast_create(Article, :profile_id => profile) | |
37 | + another_source = fast_create(Article, :profile_id => another_profile) | |
38 | + c1 = fast_create(Comment, :source_id => source, :source_type => source.class.to_s) | |
39 | + c2 = fast_create(Comment, :source_id => source, :source_type => source.class.to_s) | |
40 | + c3 = fast_create(Comment, :source_id => source, :source_type => source.class.to_s, :spam => true) | |
41 | + c4 = fast_create(Comment, :source_id => another_source, :source_type => another_source.class.to_s) | |
42 | + | |
43 | + spaminator.expects(:process_comment).with(c1) | |
44 | + spaminator.expects(:process_comment).with(c2) | |
45 | + spaminator.expects(:process_comment).with(c3).never | |
46 | + spaminator.expects(:process_comment).with(c4).never | |
47 | + | |
48 | + spaminator.send :process_all_comments | |
49 | + assert_equal 2, report.processed_comments | |
50 | + end | |
51 | + | |
52 | + should 'process only people from the environment and that are not abusers' do | |
53 | + p1 = fast_create(Person) | |
54 | + p2 = fast_create(Person) | |
55 | + p3 = fast_create(Person, :environment_id => fast_create(Environment)) | |
56 | + p4 = create_user('spammer').person | |
57 | + spaminator.send(:mark_as_spammer, p4) | |
58 | + | |
59 | + spaminator.expects(:process_person_by_comments).with(p1) | |
60 | + spaminator.expects(:process_person_by_comments).with(p2) | |
61 | + spaminator.expects(:process_person_by_comments).with(p3).never | |
62 | + spaminator.expects(:process_person_by_comments).with(p4).never | |
63 | + | |
64 | + spaminator.send :process_all_people | |
65 | + assert_equal 2, report.processed_people | |
66 | + end | |
67 | + | |
68 | + should 'process comment' do | |
69 | + profile = fast_create(Profile) | |
70 | + source = fast_create(Article, :profile_id => profile) | |
71 | + comment = fast_create(Comment, :source_id => source, :source_type => source.class.to_s) | |
72 | + Comment.any_instance.stubs(:check_for_spam) | |
73 | + | |
74 | + spaminator.send(:process_comment, comment) | |
75 | + assert_equal 0, report.spams_by_content | |
76 | + | |
77 | + Comment.any_instance.stubs(:spam).returns(true) | |
78 | + spaminator.send(:process_comment, comment) | |
79 | + assert_equal 1, report.spams_by_content | |
80 | + end | |
81 | + | |
82 | + should 'process person by comments' do | |
83 | + person = create_user('spammer').person | |
84 | + fast_create(Comment, :author_id => person, :spam => true) | |
85 | + fast_create(Comment, :author_id => person, :spam => true) | |
86 | + | |
87 | + spaminator.send(:process_person_by_comments, person) | |
88 | + assert_equal 0, report.spammers_by_comments | |
89 | + assert !person.abuser? | |
90 | + | |
91 | + fast_create(Comment, :author_id => person, :spam => true) | |
92 | + spaminator.send(:process_person_by_comments, person) | |
93 | + assert person.abuser? | |
94 | + assert_equal 1, report.spammers_by_comments | |
95 | + end | |
96 | + | |
97 | + should 'process person by network' do | |
98 | + person = create_user('spammer').person | |
99 | + person.created_at = Time.now - 2.months | |
100 | + person.save! | |
101 | + c1 = fast_create(Community) | |
102 | + c2 = fast_create(Community) | |
103 | + c1.add_member(person) | |
104 | + c2.add_member(person) | |
105 | + fast_create(Comment, :author_id => person) | |
106 | + fast_create(Comment, :author_id => person) | |
107 | + | |
108 | + spaminator.send(:process_person_by_no_network, person) | |
109 | + assert !person.abuser? | |
110 | + assert_equal 0, report.spammers_by_no_network | |
111 | + assert_equal 0, report.spams_by_no_network | |
112 | + assert person.visible | |
113 | + | |
114 | + c1.remove_member(person) | |
115 | + spaminator.send(:process_person_by_no_network, person) | |
116 | + assert !person.abuser? | |
117 | + assert_equal 1, report.spammers_by_no_network | |
118 | + assert_equal 2, report.spams_by_no_network | |
119 | + assert !person.visible | |
120 | + end | |
121 | + | |
122 | + should 'mark person as spammer' do | |
123 | + person = create_user('spammer').person | |
124 | + assert_difference AbuseComplaint.finished, :count, 1 do | |
125 | + spaminator.send(:mark_as_spammer, person) | |
126 | + end | |
127 | + person.reload | |
128 | + assert !person.visible | |
129 | + end | |
130 | + | |
131 | + private | |
132 | + | |
133 | + def report | |
134 | + spaminator.instance_variable_get('@report') | |
135 | + end | |
136 | + | |
137 | +end | ... | ... |
... | ... | @@ -0,0 +1,26 @@ |
1 | +require 'test_helper' | |
2 | + | |
3 | +class SpaminatorPluginTest < ActiveSupport::TestCase | |
4 | + | |
5 | + def setup | |
6 | + @environment = Environment.default | |
7 | + @settings = Noosfero::Plugin::Settings.new(@environment, SpaminatorPlugin) | |
8 | + end | |
9 | + | |
10 | + attr_accessor :environment, :settings | |
11 | + | |
12 | + should 'schedule a scan if not already scanning' do | |
13 | + settings.scanning = true | |
14 | + settings.save! | |
15 | + assert_no_difference Delayed::Job, :count do | |
16 | + SpaminatorPlugin.schedule_scan(environment) | |
17 | + end | |
18 | + | |
19 | + settings.scanning = false | |
20 | + settings.save! | |
21 | + assert_difference Delayed::Job, :count, 1 do | |
22 | + SpaminatorPlugin.schedule_scan(environment) | |
23 | + end | |
24 | + end | |
25 | + | |
26 | +end | ... | ... |
plugins/spaminator/views/spaminator_plugin/mailer/inactive_person_notification.html.erb
0 → 100644
... | ... | @@ -0,0 +1,26 @@ |
1 | +<!DOCTYPE html> | |
2 | +<html> | |
3 | + <head> | |
4 | + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> | |
5 | + </head> | |
6 | + <body> | |
7 | + <h4><%= _('Hi %s!') % @person.name %></h4> | |
8 | + | |
9 | + <p> | |
10 | + <%= _('Due to the recent increase in the number of spams on %s, we decided to deactivate all inactive users on the network. It just happens that you are one of them! But there is no need to worry. Your account is completely preserved and if you want to reactivate it you just need to click on the following link and recover your password (since it was changed to a huge scramble of random characters ^^):') % @environment.name %> | |
11 | + </p> | |
12 | + <p> | |
13 | + <%= @url %> | |
14 | + </p> | |
15 | + <p> | |
16 | + <%= _("We are sorry that this procedure might bother you a lot, but it's necessary for the healthy of our network.") %> | |
17 | + <%= _("We hope to see you back soon!") %> | |
18 | + </p> | |
19 | + | |
20 | + <p> | |
21 | + --<br/> | |
22 | + <%=_('Best Regards,')%><br/> | |
23 | + <%= @environment.name %> | |
24 | + </p> | |
25 | + </body> | |
26 | +</html> | ... | ... |
plugins/spaminator/views/spaminator_plugin_admin/index.rhtml
0 → 100644
... | ... | @@ -0,0 +1,60 @@ |
1 | +<h1><%= _('Spaminator settings')%></h1> | |
2 | + | |
3 | +<% form_for(:settings) do |f| %> | |
4 | + | |
5 | + <div id="spaminator-config-fields"> | |
6 | + <%= labelled_form_field _('Period (days)'), f.text_field(:period, :size => 4) %> | |
7 | + | |
8 | + <p id="deploy-status"> | |
9 | + <% if @settings.deployed.nil? %> | |
10 | + <%= _("Spaminator was never deployed. While deployed, Spaminator will periodically scan your social network for spams. Do it now!") %> | |
11 | + <% elsif @settings.deployed %> | |
12 | + <%= _("Spaminator is deployed.") %> | |
13 | + <% else %> | |
14 | + <%= _("Spaminator is withhold.") %> | |
15 | + <% end %> | |
16 | + </p> | |
17 | + <p id="next-run-status"> | |
18 | + <% if @settings.scanning %> | |
19 | + <%= _("Spaminator is scanning...") %> | |
20 | + <% elsif @settings.deployed %> | |
21 | + <%= _("Next scan on %s days.") % @next_run %> | |
22 | + <% end %> | |
23 | + </p> | |
24 | + | |
25 | + <% content = @settings.scanning ? _('Scanning...') : _('Scan now!') %> | |
26 | + <% klass = @settings.scanning ? 'disabled' : '' %> | |
27 | + <%= button(:search, content, {:action => 'scan'}, :class => klass, :disabled => @settings.scanning) %> | |
28 | + <% if !@settings.scanning %> | |
29 | + <%= button(:right, _('Deploy'), :action => 'deploy') if !@settings.deployed %> | |
30 | + <%= button(:cancel, _('Withhold'), :action => 'withhold') if @settings.deployed %> | |
31 | + <% end %> | |
32 | + | |
33 | + <% button_bar do %> | |
34 | + <%= submit_button(:save, _('Save'), :cancel => {:controller => 'plugins', :action => 'index'}) %> | |
35 | + <% end %> | |
36 | + </div> | |
37 | + | |
38 | + <table id="spaminator-report-table"> | |
39 | + <tr> | |
40 | + <th><%= _('Date') %></th> | |
41 | + <th><%= _('Spams') %></th> | |
42 | + <th><%= _('Spammers')%></th> | |
43 | + </tr> | |
44 | + <% @reports.each do |report| %> | |
45 | + <tr> | |
46 | + <td><%= report.formated_date %></td> | |
47 | + <td><%= "#{report.spams} / #{report.total_comments}" %></td> | |
48 | + <td><%= "#{report.spammers} / #{report.total_people}" %></td> | |
49 | + </tr> | |
50 | + <% end %> | |
51 | + <tr id="spaminator-reports-see-all"> | |
52 | + <% content = @reports_count > 0 ? link_to(_('SEE FULL REPORTS (%s)') % @reports_count, :action => 'reports') : _('No Report') %> | |
53 | + <td colspan='3'><%= content %></td> | |
54 | + </tr> | |
55 | + </table> | |
56 | + | |
57 | + <br style='clear: both'/> | |
58 | + | |
59 | +<% end %> | |
60 | + | ... | ... |
plugins/spaminator/views/spaminator_plugin_admin/reports.html.erb
0 → 100644
... | ... | @@ -0,0 +1,30 @@ |
1 | +<h1><%= _('Spaminator reports')%></h1> | |
2 | + | |
3 | +<table id="spaminator-report-table"> | |
4 | + <tr> | |
5 | + <th><%= _('Date') %></th> | |
6 | + <th><%= _('Spams by content') %></th> | |
7 | + <th><%= _('Spams by author without network') %></th> | |
8 | + <th><%= _('Total Spams') %></th> | |
9 | + <th><%= _('Spammers by more than 2 spams')%></th> | |
10 | + <th><%= _('Spammers due to no network')%></th> | |
11 | + <th><%= _('Total Spammers')%></th> | |
12 | + </tr> | |
13 | + <% @reports.each do |report| %> | |
14 | + <tr> | |
15 | + <td><%= report.created_at.strftime("%Y-%m-%d") %></td> | |
16 | + <td><%= "#{report.spams_by_content} / #{report.processed_comments}" %></td> | |
17 | + <td><%= "#{report.spams_by_no_network} / #{report.processed_comments}" %></td> | |
18 | + <td><%= "#{report.spams} / #{report.total_comments}" %></td> | |
19 | + <td><%= "#{report.spammers_by_comments} / #{report.processed_people}" %></td> | |
20 | + <td><%= "#{report.spammers_by_no_network} / #{report.processed_people}" %></td> | |
21 | + <td><%= "#{report.spammers} / #{report.total_people}" %></td> | |
22 | + </tr> | |
23 | + <% end %> | |
24 | +</table> | |
25 | + | |
26 | +<br style='clear: both'/> | |
27 | + | |
28 | +<% button_bar do %> | |
29 | + <%= button(:back, _('Back'), :action => 'index') %> | |
30 | +<% end %> | ... | ... |