From 986a32223177a759b0ef071822d227011ee1b3c7 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 7 Mar 2009 09:43:50 -0800 Subject: Limit duplicate notices in a particular time period (default 60s) We disallow posting a notice with duplicate content more than once a minute. Conflicts: config.php.sample --- classes/Notice.php | 47 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 7 deletions(-) (limited to 'classes/Notice.php') diff --git a/classes/Notice.php b/classes/Notice.php index 907239b08..eac90ce95 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -121,6 +121,8 @@ class Notice extends Memcached_DataObject $profile = Profile::staticGet($profile_id); + $final = common_shorten_links($content); + if (!$profile) { common_log(LOG_ERR, 'Problem saving notice. Unknown user.'); return _('Problem saving notice. Unknown user.'); @@ -131,7 +133,12 @@ class Notice extends Memcached_DataObject return _('Too many notices too fast; take a breather and post again in a few minutes.'); } - $banned = common_config('profile', 'banned'); + if (common_config('site', 'dupelimit') > 0 && !Notice::checkDupes($profile_id, $final)) { + common_log(LOG_WARNING, 'Dupe posting by profile #' . $profile_id . '; throttled.'); + return _('Too many duplicate messages too quickly; take a breather and post again in a few minutes.'); + } + + $banned = common_config('profile', 'banned'); if ( in_array($profile_id, $banned) || in_array($profile->nickname, $banned)) { common_log(LOG_WARNING, "Attempted post from banned user: $profile->nickname (user id = $profile_id)."); @@ -155,12 +162,12 @@ class Notice extends Memcached_DataObject $notice->query('BEGIN'); - $notice->reply_to = $reply_to; - $notice->created = common_sql_now(); - $notice->content = common_shorten_links($content); - $notice->rendered = common_render_content($notice->content, $notice); - $notice->source = $source; - $notice->uri = $uri; + $notice->reply_to = $reply_to; + $notice->created = common_sql_now(); + $notice->content = $final; + $notice->rendered = common_render_content($final, $notice); + $notice->source = $source; + $notice->uri = $uri; if (Event::handle('StartNoticeSave', array(&$notice))) { @@ -204,6 +211,32 @@ class Notice extends Memcached_DataObject return $notice; } + static function checkDupes($profile_id, $content) { + $profile = Profile::staticGet($profile_id); + if (!$profile) { + return false; + } + $notice = $profile->getNotices(0, NOTICE_CACHE_WINDOW); + if ($notice) { + $last = 0; + while ($notice->fetch()) { + if (time() - strtotime($notice->created) >= common_config('site', 'dupelimit')) { + return true; + } else if ($notice->content == $content) { + return false; + } + } + } + # If we get here, oldest item in cache window is not + # old enough for dupe limit; do direct check against DB + $notice = new Notice(); + $notice->profile_id = $profile_id; + $notice->content = $content; + $notice->whereAdd('now() - created < ' . common_config('notice', 'dupelimit')); + $cnt = $notice->count(); + return ($cnt > 0); + } + static function checkEditThrottle($profile_id) { $profile = Profile::staticGet($profile_id); if (!$profile) { -- cgit v1.2.3-54-g00ecf From bea3fca1899dddda8d1c52c16a761dd23c9ce8b8 Mon Sep 17 00:00:00 2001 From: Adrian Lang Date: Sat, 7 Mar 2009 23:04:30 +0100 Subject: Fix bug in dupe checking on notice post when there is no notice in cache. --- classes/Notice.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'classes/Notice.php') diff --git a/classes/Notice.php b/classes/Notice.php index eac90ce95..ac4db944f 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -234,7 +234,7 @@ class Notice extends Memcached_DataObject $notice->content = $content; $notice->whereAdd('now() - created < ' . common_config('notice', 'dupelimit')); $cnt = $notice->count(); - return ($cnt > 0); + return ($cnt == 0); } static function checkEditThrottle($profile_id) { -- cgit v1.2.3-54-g00ecf From b9194e792369506cd2514dcad3e26ce483e6b72d Mon Sep 17 00:00:00 2001 From: CiaranG Date: Wed, 11 Mar 2009 09:12:39 +0000 Subject: Correction to recently added dupe-checking feature - was using wrong config value --- classes/Notice.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'classes/Notice.php') diff --git a/classes/Notice.php b/classes/Notice.php index ac4db944f..1e3b330f2 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -232,7 +232,7 @@ class Notice extends Memcached_DataObject $notice = new Notice(); $notice->profile_id = $profile_id; $notice->content = $content; - $notice->whereAdd('now() - created < ' . common_config('notice', 'dupelimit')); + $notice->whereAdd('now() - created < ' . common_config('site', 'dupelimit')); $cnt = $notice->count(); return ($cnt == 0); } -- cgit v1.2.3-54-g00ecf From c08e4d904ec80144379c5728e2274e3513e6c819 Mon Sep 17 00:00:00 2001 From: CiaranG Date: Wed, 11 Mar 2009 23:41:30 +0000 Subject: PostgreSQL - a few more query compatibility issues (submitted by oxygene) --- actions/peopletag.php | 2 +- actions/sup.php | 4 +++- classes/Notice.php | 6 +++++- 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'classes/Notice.php') diff --git a/actions/peopletag.php b/actions/peopletag.php index 6b1e34f1a..5add75485 100644 --- a/actions/peopletag.php +++ b/actions/peopletag.php @@ -119,7 +119,7 @@ class PeopletagAction extends Action 'FROM profile JOIN profile_tag ' . 'ON profile.id = profile_tag.tagger ' . 'WHERE profile_tag.tagger = profile_tag.tagged ' . - 'AND tag = "%s" ' . + "AND tag = '%s' " . 'ORDER BY profile_tag.modified DESC%s'; $profile->query(sprintf($qry, $this->tag, $lim)); diff --git a/actions/sup.php b/actions/sup.php index f4b1cda23..8ef9207fa 100644 --- a/actions/sup.php +++ b/actions/sup.php @@ -65,7 +65,9 @@ class SupAction extends Action $notice->query('SELECT profile_id, max(id) AS max_id ' . 'FROM notice ' . - 'WHERE created > (now() - ' . $seconds . ') ' . + ((common_config('db','type') == 'pgsql') ? + 'WHERE extract(epoch from created) > (extract(epoch from now()) - ' . $seconds . ') ' : + 'WHERE created > (now() - ' . $seconds . ') ' ) . 'GROUP BY profile_id'); $updates = array(); diff --git a/classes/Notice.php b/classes/Notice.php index 1e3b330f2..3087e39a7 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -232,7 +232,11 @@ class Notice extends Memcached_DataObject $notice = new Notice(); $notice->profile_id = $profile_id; $notice->content = $content; - $notice->whereAdd('now() - created < ' . common_config('site', 'dupelimit')); + if (common_config('db','type') == 'pgsql') + $notice->whereAdd('extract(epoch from now() - created) < ' . common_config('site', 'dupelimit')); + else + $notice->whereAdd('now() - created < ' . common_config('site', 'dupelimit')); + $cnt = $notice->count(); return ($cnt == 0); } -- cgit v1.2.3-54-g00ecf