Commit 045a4ac47f169d7e8f6204275daa5d303122ac60
1 parent
6aa80262
Exists in
staging
and in
42 other branches
First version of the Spaminator™
(not tested yet)
Showing
2 changed files
with
159 additions
and
0 deletions
Show diff stats
| @@ -0,0 +1,106 @@ | @@ -0,0 +1,106 @@ | ||
| 1 | +require 'benchmark' | ||
| 2 | + | ||
| 3 | +class AntiSpamPlugin::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 | + end | ||
| 20 | + | ||
| 21 | + def run | ||
| 22 | + start_time = Time.now | ||
| 23 | + | ||
| 24 | + process_all_comments | ||
| 25 | + process_all_people | ||
| 26 | + process_people_without_network | ||
| 27 | + | ||
| 28 | + finish(start_time) | ||
| 29 | + end | ||
| 30 | + | ||
| 31 | + protected | ||
| 32 | + | ||
| 33 | + def finish(start_time) | ||
| 34 | + @environment.settings[:spaminator_last_run] = start_time | ||
| 35 | + @environment.save! | ||
| 36 | + end | ||
| 37 | + | ||
| 38 | + def conditions(table) | ||
| 39 | + last_run = @environment.settings[:spaminator_last_run] | ||
| 40 | + if last_run | ||
| 41 | + ["profiles.environment_id = ? AND #{table}.created_at > ?", @environment.id, last_run] | ||
| 42 | + else | ||
| 43 | + [ "profiles.environment_id = ?", @environment.id] | ||
| 44 | + end | ||
| 45 | + end | ||
| 46 | + | ||
| 47 | + def process_all_comments | ||
| 48 | + puts 'Processing comments ...' | ||
| 49 | + i = 0 | ||
| 50 | + Comment.joins("JOIN articles ON (comments.source_id = articles.id AND comments.source_type = 'Article') JOIN profiles ON (profiles.id = articles.profile_id)").where(conditions(:comments)).find_each do |comment| | ||
| 51 | + puts "Comment #{i += 1}" | ||
| 52 | + process_comment(comment) | ||
| 53 | + end | ||
| 54 | + end | ||
| 55 | + | ||
| 56 | + def process_all_people | ||
| 57 | + puts 'Processing people ...' | ||
| 58 | + i = 0 | ||
| 59 | + Person.where(conditions(:profiles)).find_each do |person| | ||
| 60 | + puts "Person #{i += 1}" | ||
| 61 | + process_person(person) | ||
| 62 | + end | ||
| 63 | + end | ||
| 64 | + | ||
| 65 | + def process_comment(comment) | ||
| 66 | + comment.check_for_spam | ||
| 67 | + | ||
| 68 | + # TODO several comments with the same content: | ||
| 69 | + # → disable author | ||
| 70 | + # → mark all of them as spam | ||
| 71 | + end | ||
| 72 | + | ||
| 73 | + def process_person(person) | ||
| 74 | + # person is author of more than 2 comments marked as spam | ||
| 75 | + # → burn | ||
| 76 | + # | ||
| 77 | + number_of_spam_comments = Comment.spam.where(author_id => person.id).count | ||
| 78 | + if number_of_spam_comments > 2 | ||
| 79 | + mark_as_spammer(person) | ||
| 80 | + end | ||
| 81 | + end | ||
| 82 | + | ||
| 83 | + def process_people_without_network | ||
| 84 | + # people who signed up more than one month ago, have no friends and <= 1 | ||
| 85 | + # communities | ||
| 86 | + # | ||
| 87 | + # → burn | ||
| 88 | + # → mark their comments as spam | ||
| 89 | + # | ||
| 90 | + Person.where(:environment_id => @environment.id).where(['created_at < ?', Time.now - 1.month]).find_each do |person| | ||
| 91 | + number_of_friends = person.friends.count | ||
| 92 | + number_of_communities = person.communities.count | ||
| 93 | + if number_of_friends == 0 && number_of_communities <= 1 | ||
| 94 | + mark_as_spammer(person) | ||
| 95 | + Comment.where(:author_id => person.id).find_each do |comment| | ||
| 96 | + comment.spam! | ||
| 97 | + end | ||
| 98 | + end | ||
| 99 | + end | ||
| 100 | + end | ||
| 101 | + | ||
| 102 | + def mark_as_spammer(person) | ||
| 103 | + person.disable | ||
| 104 | + end | ||
| 105 | + | ||
| 106 | +end |
plugins/anti_spam/test/unit/anti_spam_plugin/spaminator_test.rb
0 → 100644
| @@ -0,0 +1,53 @@ | @@ -0,0 +1,53 @@ | ||
| 1 | +require 'test_helper' | ||
| 2 | + | ||
| 3 | +class AntiSpamPluginSpaminatorTest < ActiveSupport::TestCase | ||
| 4 | + | ||
| 5 | + def setup | ||
| 6 | + @environment = Environment.new | ||
| 7 | + @environment.id = 99 | ||
| 8 | + @spaminator = AntiSpamPlugin::Spaminator.new(@environment) | ||
| 9 | + @spaminator.stubs(:puts) | ||
| 10 | + @now = Time.now | ||
| 11 | + Time.stubs(:now).returns(@now) | ||
| 12 | + end | ||
| 13 | + | ||
| 14 | + should 'search everything in the first run' do | ||
| 15 | + assert_equal(['profiles.environment_id = ?',99], @spaminator.send(:conditions, nil)) | ||
| 16 | + end | ||
| 17 | + | ||
| 18 | + should 'search using recorded last date' do | ||
| 19 | + @environment.settings[:spaminator_last_run] = @now | ||
| 20 | + assert_equal(['profiles.environment_id = ? AND table.created_at > ?', 99, @now], @spaminator.send(:conditions, 'table')) | ||
| 21 | + end | ||
| 22 | + | ||
| 23 | + should 'record time of last run in environment' do | ||
| 24 | + @spaminator.expects(:process_all_comments) | ||
| 25 | + @spaminator.expects(:process_all_people) | ||
| 26 | + @environment.stubs(:save!) | ||
| 27 | + @spaminator.run | ||
| 28 | + assert_equal @now, @environment.settings[:spaminator_last_run] | ||
| 29 | + end | ||
| 30 | + | ||
| 31 | + should 'find all comments' do | ||
| 32 | + @spaminator.stubs(:process_comment) | ||
| 33 | + @spaminator.send :process_all_comments | ||
| 34 | + end | ||
| 35 | + | ||
| 36 | + should 'find all people' do | ||
| 37 | + @spaminator.stubs(:process_person) | ||
| 38 | + @spaminator.send :process_all_people | ||
| 39 | + end | ||
| 40 | + | ||
| 41 | + should 'find all comments newer than a date' do | ||
| 42 | + @environment.settings[:spaminator_last_run] = Time.now - 1.month | ||
| 43 | + @spaminator.stubs(:process_comment) | ||
| 44 | + @spaminator.send :process_all_comments | ||
| 45 | + end | ||
| 46 | + | ||
| 47 | + should 'find all people newer than a date' do | ||
| 48 | + @environment.settings[:spaminator_last_run] = Time.now - 1.month | ||
| 49 | + @spaminator.stubs(:process_person) | ||
| 50 | + @spaminator.send :process_all_people | ||
| 51 | + end | ||
| 52 | + | ||
| 53 | +end |