From 045a4ac47f169d7e8f6204275daa5d303122ac60 Mon Sep 17 00:00:00 2001 From: Antonio Terceiro Date: Fri, 31 Aug 2012 18:02:10 -0300 Subject: [PATCH] First version of the Spaminator™ --- plugins/anti_spam/lib/anti_spam_plugin/spaminator.rb | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ plugins/anti_spam/test/unit/anti_spam_plugin/spaminator_test.rb | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 159 insertions(+), 0 deletions(-) create mode 100644 plugins/anti_spam/lib/anti_spam_plugin/spaminator.rb create mode 100644 plugins/anti_spam/test/unit/anti_spam_plugin/spaminator_test.rb diff --git a/plugins/anti_spam/lib/anti_spam_plugin/spaminator.rb b/plugins/anti_spam/lib/anti_spam_plugin/spaminator.rb new file mode 100644 index 0000000..8e30e10 --- /dev/null +++ b/plugins/anti_spam/lib/anti_spam_plugin/spaminator.rb @@ -0,0 +1,106 @@ +require 'benchmark' + +class AntiSpamPlugin::Spaminator + + class << self + def run(environment) + instance = new(environment) + instance.run + end + + def benchmark(environment) + puts Benchmark.measure { run(environment) } + end + end + + + def initialize(environment) + @environment = environment + end + + def run + start_time = Time.now + + process_all_comments + process_all_people + process_people_without_network + + finish(start_time) + end + + protected + + def finish(start_time) + @environment.settings[:spaminator_last_run] = start_time + @environment.save! + end + + def conditions(table) + last_run = @environment.settings[:spaminator_last_run] + if last_run + ["profiles.environment_id = ? AND #{table}.created_at > ?", @environment.id, last_run] + else + [ "profiles.environment_id = ?", @environment.id] + end + end + + def process_all_comments + puts 'Processing comments ...' + i = 0 + 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| + puts "Comment #{i += 1}" + process_comment(comment) + end + end + + def process_all_people + puts 'Processing people ...' + i = 0 + Person.where(conditions(:profiles)).find_each do |person| + puts "Person #{i += 1}" + process_person(person) + end + end + + def process_comment(comment) + comment.check_for_spam + + # TODO several comments with the same content: + # → disable author + # → mark all of them as spam + end + + def process_person(person) + # person is author of more than 2 comments marked as spam + # → burn + # + number_of_spam_comments = Comment.spam.where(author_id => person.id).count + if number_of_spam_comments > 2 + mark_as_spammer(person) + end + end + + def process_people_without_network + # people who signed up more than one month ago, have no friends and <= 1 + # communities + # + # → burn + # → mark their comments as spam + # + Person.where(:environment_id => @environment.id).where(['created_at < ?', Time.now - 1.month]).find_each do |person| + number_of_friends = person.friends.count + number_of_communities = person.communities.count + if number_of_friends == 0 && number_of_communities <= 1 + mark_as_spammer(person) + Comment.where(:author_id => person.id).find_each do |comment| + comment.spam! + end + end + end + end + + def mark_as_spammer(person) + person.disable + end + +end diff --git a/plugins/anti_spam/test/unit/anti_spam_plugin/spaminator_test.rb b/plugins/anti_spam/test/unit/anti_spam_plugin/spaminator_test.rb new file mode 100644 index 0000000..0b59cc5 --- /dev/null +++ b/plugins/anti_spam/test/unit/anti_spam_plugin/spaminator_test.rb @@ -0,0 +1,53 @@ +require 'test_helper' + +class AntiSpamPluginSpaminatorTest < ActiveSupport::TestCase + + def setup + @environment = Environment.new + @environment.id = 99 + @spaminator = AntiSpamPlugin::Spaminator.new(@environment) + @spaminator.stubs(:puts) + @now = Time.now + Time.stubs(:now).returns(@now) + end + + should 'search everything in the first run' do + assert_equal(['profiles.environment_id = ?',99], @spaminator.send(:conditions, nil)) + end + + should 'search using recorded last date' do + @environment.settings[:spaminator_last_run] = @now + assert_equal(['profiles.environment_id = ? AND table.created_at > ?', 99, @now], @spaminator.send(:conditions, 'table')) + end + + should 'record time of last run in environment' do + @spaminator.expects(:process_all_comments) + @spaminator.expects(:process_all_people) + @environment.stubs(:save!) + @spaminator.run + assert_equal @now, @environment.settings[:spaminator_last_run] + end + + should 'find all comments' do + @spaminator.stubs(:process_comment) + @spaminator.send :process_all_comments + end + + should 'find all people' do + @spaminator.stubs(:process_person) + @spaminator.send :process_all_people + end + + should 'find all comments newer than a date' do + @environment.settings[:spaminator_last_run] = Time.now - 1.month + @spaminator.stubs(:process_comment) + @spaminator.send :process_all_comments + end + + should 'find all people newer than a date' do + @environment.settings[:spaminator_last_run] = Time.now - 1.month + @spaminator.stubs(:process_person) + @spaminator.send :process_all_people + end + +end -- libgit2 0.21.2