';
$html;
}
sub _debug {
my $app = shift;
return '' unless $app->_debug_status() && $app->{user}->can_create_blog; #JAYBO
unless (@_) {
my ($package, $filename, $line) = caller();
@_ = ('No debugging info available at '.$package.', line '.$line);
}
if ((@_ > 1) || ref($_[0])){
require Data::Dumper;
return '
'.Data::Dumper::Dumper(@_).'
';
} else {
return '
'.(shift).'
';
}
}
sub _debug_status {
my $app = shift;
if (my $status = shift) {
$app->{debug_status} = $status;
}
$app->{debug_status};
}
sub _getTimestamp {
use MT::Util;
my @ts = MT::Util::offset_time_list(time);
my $ts = sprintf '%04d%02d%02d%02d%02d%02d',
$ts[5]+1900, $ts[4]+1, @ts[3,2,1,0];
$ts;
}
sub _getBlacklistMasthead {
return <
/* */
EOD
}
sub _defaultBlacklist {
my $list = <<'EOD';
(ragazze)-?\w+\.[a-z]{2,} # Catchall regexp for many spam sites
(buy)[\w\-_.]*online[\w\-_.]*\.[a-z]{2,} # Catchall regexp for many spam sites
(phentermine|viagra|vig-?rx)[\w\-_.]*\.[a-z]{2,} # Catchall regexp for many spam sites
([\w\-_.]+\.)?(l(so|os)tr)\.[a-z]{2,} # Catchall regex for lsotr.xxx and lostr.xxx with or without a subdomain
(penis)[_.\-]?enlargement([\w\-_.]+)?\.[a-z]{2,} # Catchall regexp for many spam sites
xxxxxx.lsotr.xxx
00000-online-casino.com
0adult-cartoon.com
0adult-manga.com
0cartoon-porn.com
0cartoon-sex.com
0cartoon.com
0casino-online.com
0casinoonline.com
0free-hentai.com
0freehentai.com
0hentai-anime.com
0hentai-manga.com
0hentaimanga.com
0internet-casino.com
0livesex.com
0manga-porno.com
0manga-sesso.com
0manga.com
0sesso-amatoriale.com
0sesso-orale.biz
0sesso.biz
0sesso.us
0sessoanale.com
0sessogratis.us
0sex-toons.com
0sfondi-desktop.com
0sfondi.com
0suonerie.com
0tatuaggi.com
0toons.com
0video-porno.com
0virtual-casino.com
0xxx-cartoon.com
101pills.com
123sessogratis.com
1concerttickets.com
1footballtickets.com
1st-shemale-sex.com
accompagnatrici.cc
adult-manga.org
adultfriendfindersite.com
adultlingerieuk.com
adultserviceproviders.com
all-gay-porn.us
allmagic.ru
amateur-porn-gallery.com
amateur-site.us
anal-sex-pictures.us
anime-manga.us
anmichelle-22.da.ru
annunci-coppie.net
annunci-erotici.net
annunci-erotici.org
annunci-personali.org
annunci-sesso.org
annunci-sesso.us
annuncisesso.us
aquatyca.net
autofinanzierung-zum-festzins.de
autokredit-tipp.de
autumn-jade.com
banialoba3w.150m.com
barcodes.cn
basi-musicali.com
bast3.ru
beauty-farm.net
belle-donne.biz
belle-ragazze.net
belle-ragazze.org
belleragazze.biz
belleragazze.org
bellissime-donne.com
bellissime-donne.net
bellissimedonne.com
bellissimedonne.org
benessere.us
best-diet-pills-online.com
best-prescription-diet-pills.com
big-black-butts.net
big-hooters.net
big-natural-boobs.us
bigbras-club.com
bigmoms.com
bigtitchaz.com
blackbusty.com
blackjack-homepage.com
bon-referencement.com
boobmorning.com
boobspost.com
breast-augmentation.top-big-tits.com
btd-online-casino.com
busty-models.us
bustyangelique.com
bustydustystash.com
bustykerrymarie.com
buy-adult-sex-toys.com
buy-sex-toys.net
buy-sexy-lingerie-online.com
buycheappills.net
calendari-donne.com
calendari-donne.net
calendaridonne.com
calendaridonne.net
canzoni-italiane.com
canzoni-italiane.net
canzoni-italiane.org
canzoni-karaoke.com
canzoni-mp3.com
canzoni-mp3.us
canzoni-musica.com
canzoni.cc
canzonisanremo.com
canzonistraniere.com
cartoni-animati.com
cartoni-hentai.com
cartoni-hentai.net
cartoni-hentai.org
cartoni-porno.com
cartonierotici.com
cartonigiapponesi.com
cartonihentai.net
casino-en-ligne.fr.vu
casino-in-linea.it.st
certificationking.net
cheap-adult-sex-toys.com
cheap-online-pharmacy.org
cheap-pills-online.com
cherrybrady.com
chloesworld.com
chickz.com
cialis.incredishop.com
classifiche-italiane.org
classifiche-musicali.com
classifiche-musicali.net
classifiche-musicali.org
classifichemusicali.com
computer-und-erotische-spiele-download.com
cycatki.com
danni.com
dedichepersonali.com
desiraesworld.com
devon-daniels.com
dianepoppos.com
diet-pills-shop.com
dieta-dimagrante.net
dieta-mediterranea.net
dieta-zona.com
dieta.cc
diete-dimagranti.com
diete.bz
dieting-review.com
discount-airfares-guide.com
discount-life-insurance.us
disney-hentai.org
donne-belle.net
donne-famose.biz
donne-muscolose.net
donne-muscolose.org
donne-nere.net
donne-nere.org
donne-nude.biz
donne-porche.com
donne-vogliose.com
donne.bz
donnebelle.net
donnefamose.biz
donnegrasse.org
donnemature.biz
donnemuscolose.com
donnenere.com
donnenere.net
donnenude.biz
donneporche.org
donnesexy.org
donnevogliose.net
donnevogliose.org
dr\.ag
dragonball-porno.com
dragonball-x.biz
dragonball-xxx.biz
dragonballporno.net
dragonballx.cc
dragonballxxx.biz
drugstore.st
drunk-girls-flashing.com
e-discus.com
e-order-propecia.com
e-order-xenical.com
ecblast.com
effective-penis-pills.com
elcenter-s.ru
envoyer-des-fleurs.com
eonsystems.com
erotische-geschichten-portal.com
esesso-gratis.com
evromaster.ru
evrostroyka.narod.ru
exoticmoms.com
fat-lesbians.net
figa.nu
film-porno.us
final-fantasy-hentai.org
find-lesbian-porn.com
fioricet.st
fitnessx.net
forex.inc.ru
foto-gay.us
foto-porno.us
foto-porno.ws
free-adult-check.com
free-net-sex.com
fumetti-porno.org
fumettiporno.org
gagnerargent.com
gambling-homepage.com
gamblingguidance.co.uk
gayx.us
generic-propecia.net
genimat.220v.org
genimat.cjb.net
genimut.dr.ag
get-hardcore-sex.com
getaprescription.net
giochi-hentai.com
giochi-online.us
giochix.com
godere.org
gogito.com
grannysexthumbs.com
guardami.org
hardcore-porn-links.com
hardcore-sex.bz
hardcorecash.net
hautesavoieimmobilier.com
hentai-gratis.us
hentai-hard.com
hentai-xxx.us
hentaigratis.net
hentaimanga.us
hentaix.net
hentaixxx.us
hentay.us
hgh-online.com
hobbs-farm.com
homelivecams.com
hornymoms.net
hotel-bordeaux.cjb.net
immagini-hentai.org
immobilierdessavoie.com
inescudna.com
inter-ross.ru
inviare-mms.net
invio-mms.us
ipharmacy.com # Catchall for many spam sites
itramadol.com
juliamiles.co.uk
koihoo.com
kraskidliavas.ru
kredite-portal.de
kredite-sofortzusage.de
kupibuket.ru
las-vegas-real-estate-1.com
lasvegasrealtor.com
legalblonde.com
lesbichex.com
levitraguide.com
link-dir.com
linseysworld.com
lizziemills.com
logos-logos.be
mainjob.ru
manga-free.net
manga-free.org
manga-x.biz
manga-xxx.org
mature-big-tits.net
mediaaustralia.com.au
megapornstation.com
menguma.com
menzyme.com
mmsanimati.com
mneuron.com
moltobene.ru
mortgage-rates-guide.net
mp3download.bz
mp3x.biz
musica-da-scaricare.net
musica-gratis.biz
musica-gratis.org
musica-karaoke.net
musica-mp3.biz
musicamp3.us
musicenergy.com
my-sex-toys-store.com
mybestcasinos.net
mydatingagency.com
naturalknockers.net
net-mature.com
netizen.org
nichehit.com
nicolepeters.com
oldgrannyfucking.com
onepiecex.net
online--pharmacy.us
online-prescription.st
online-prescriptions-internet-pharmacy.com
operazione-trionfo.net
partnersuche-partnervermittlung.com
peepissing.com
penisenlargementmagazine.com
penisimprovement.com
penisresearch.com
perfect-dedicated-server.com
pharmacyprices.net
picsfreesex.com
piercingx.com
pilltip.com
pj-city.com
pokemon-hentai.com
pokemon-hentai.org
pokemonhentai.net
pokemonx.biz
poker-homepage.com
pompini.nu
porn-4u.net
porn-house.us
pornogratis.bz
pornostars.cc
pornwww.com
pregnant-sex-free.us
prescription-drugs.st
prescriptions.md
propecia-store.com
prozac.st
quality-penis-pills.com
racconti-gay.org
raf-ranking.com
ragazze.bz
rampantrabbitvibrator.co.uk
ratenkredit-center.de
ratenkredit-shop.de
real-sex.us
ricettegolose.com
rx-store.com # Catchall for many spam sites
sailor-moon-hentai.org
sailor-moon-hentai.us
salute-bellezza.net
salute-bellezza.org
salute-benessere.org
salute-e-benessere.net
salute-igiene.com
salute-malattie.com
salute-malattie.net
sarennasworld.com
scarica-mp3.biz
scarica-mp3.com
scarica-musica-mp3.org
scarica-musica.com
scarica-musica.org
scaricamp3.us
scaricare-canzoni.com
scaricare-canzoni.net
scaricare-canzoni.org
scaricare-mp3.org
seitensprung-gratis.com
selena-u.ru
sesso-gratis.cc
sesso-online.net
sessoanalex.com
sessox.biz
sex-4you.org
sex-manga.us
sexe.vc
sexo9.com
sexshop-sexeshop.com
sextoysportal.com
sexwebclub.com
sfondi-desktop-gratis.com
siti-porno.us
ski-resorts-guide.com
slot-machines-slots.com
sms-sms-sms.org
soma.st
sonnerie-hifi-sms.com
sonnerie-logos.be
sonnerie-portable-composer.com
sonnerie-portable.be
sonneries-gsm-sms.com
sorglos-kredit.de
spiele-kostenlose.com
spiele-planet.com
sting.cc
suonerie-loghi-gratis.com
suonerieloghix.com
suoneriex.net
susiewildin.com
svitonline.com
sylviapanda.com
tatuaggi-gratis.com
tatuaggi-piercing.org
tatuaggi-tribali.com
tatuaggi.cc
tatuaggi.us
tatuaggitribali.com
terminator-sales.com
testi-canzoni.com
testi-canzoni.net
testi-musicali.com
testi-musicali.net
testi.cc
tette.bz
tettone.cc
theceleb.com
themadpiper.ent
tiffany-towers.com
tits-center.com
tits-cumshots.net
top-dedicated-servers.com
tramadol.st
troie.bz
trucchi-giochi.us
u-w-m.ru
ultram.st
ultrampharmacy.com
unbeatablerx.com
uni-card.ru
us-meds.com
vacation-rentals-guide.com
viaggix.com
viapaxton.com
video-porno.nu
videohentai.org
web-revenue.com
webcam-erotiche.com
webcopywizard.net
wet-4all.com
wethorny.com
www-sesso # Catchall for many spam sites
x-ring-tones.com
xlboobs.net
xsesso.biz
yaninediaz.com
yukka.inc.ru
zipcodedownload.com
zipcodesmap.com
EOD
$list;
}
# #####################################
#
#
# METHODS USED BY BOTH APP AND PLUGIN
#
#
# #####################################
sub _getBlacklist {
# This function is used by both
# the plugin and the application
# Return cached data if exists
return $_cache->{blacklist} if $_cache->{blacklist} && @{$_cache->{blacklist}};
my $list = _getBlacklistData('blacklist');
# Within the application the blacklist will
# always have a dummy first entry at index 0.
# When it is saved, it is stripped from the array.
while ($list->[0]->{string} eq '') { shift(@{$list}); }
unshift(@{$list}, {string => ''});
# Cache the data
$_cache->{blacklist} = $list;
$list;
}
sub _getConfig {
# This function is used by both
# the plugin and the application
# Return cached data if exists
return $_cache->{config} if $_cache->{config};
my $config = _getBlacklistData('config');
# Cache the data
$_cache->{config} = $config;
$config or return;
}
sub _getBlacklistData {
# This function is used by both
# the plugin and the application
my $key = shift;
my $data = _getPluginDataObject($key);
return $data->data if $data;
}
sub _getPluginDataObject {
# This function is used by both
# the plugin and the application
my $key = shift;
mywarn("In getPluginDataObject for $key");
if ($_cache->{plugindataobject}{$key}) {
mywarn("(CACHE) Returning from _getPluginDataObject $key PluginDataObject");
$_cache->{plugindataobject}{$key};
} else {
mywarn("(DB) Returning from _getPluginDataObject $key PluginDataObject");
$_cache->{plugindataobject}{$key} = MT::PluginData->load ({ plugin => 'Blacklist',
key => $key });
}
}
sub _getEntry {
my $id = shift;
mywarn("In _getEntry with entry ID $id");
if (my $e = $_cache->{entry}->{$id}) {
mywarn("(CACHE) Returning from _getEntry entry ID $id\n");
return $e ;
}
mywarn("(DB) Loading from _getEntry entry ID $id\n");
require MT::Entry;
$_cache->{entry}->{$id} = MT::Entry->load($id);
}
sub _getTrackback {
my $id = shift;
mywarn("In loadTrackback with trackback ID $id from caller");
if (my $trackback = $_cache->{trackback}->{$id}) {
mywarn("(CACHE) Returning trackback ID $id\n");
return $trackback ;
}
mywarn("(DB) Loading trackback ID $id\n");
require MT::Trackback;
$_cache->{trackback}->{$id} = MT::Trackback->load($id);
}
sub _getObjectEntry {
my ($type,$object) = @_;
if ($type eq 'comment') {
_getCommentEntry($object);
} elsif ($type eq 'ping') {
_getPingEntry($object);
} else {
die "Unknown object type in _getObjectEntry";
}
}
sub _getCommentEntry {
my $c = shift;
my $entry = _getEntry($c->entry_id);
}
sub _getPingEntry {
my $p = shift;
my $tb = _getTrackback($p->tb_id);
my $entry = _getEntry($tb->entry_id);
}
sub _getBlog {
my $id = shift;
mywarn("In loadBlog with Blog ID ".$id);
if (my $b = $_cache->{blog}->{$id}) {
mywarn("(CACHE) Returning blog ID $id");
return $b;
} else {
mywarn("(DB) Returning blog ID $id");
require MT::Blog;
$_cache->{blog}->{$id} = MT::Blog->load($id);
}
}
sub _getBlogs {
require MT::Blog;
mywarn("In loadBlogs");
if ($_cache->{blogs_loaded}) {
mywarn("(CACHE) Returning blogs");
return $_cache->{blog};
} else {
mywarn("(DB) Returning blogs");
my @blogs = MT::Blog->load();
$_cache->{blogs_loaded}++;
%{$_cache->{blog}} = map { $_->id, $_ } @blogs;
$_cache->{blog};
}
}
# #####################################
#
#
# START OF MT-BLACKLIST PLUGIN METHODS
#
#
# #####################################
#
# RE-redefinition of MT::App::Comments::post
#
# In order to include the link in the comment notification
# email, I have to use the entire 'post' method, because
# Ben has never abstracted the emails as templates. Grrrrr.
#
sub comment_post_hdlr {
use MT::Util qw( remove_html );
my $app = shift;
my $q = $app->{query};
if (my $state = $q->param('comment_state')) {
require MT::Serialize;
my $ser = MT::Serialize->new($app->{cfg}->Serializer);
$state = $ser->unserialize(pack 'H*', $state);
$state = $$state;
for my $f (keys %$state) {
$q->param($f, $state->{$f});
}
}
my $entry_id = $q->param('entry_id')
or return $app->error("No entry_id");
my $entry = _getEntry($entry_id)
or return $app->error($app->translate(
"Invalid entry ID '[_1]'.", scalar $q->param('entry_id')));
unless ($entry->allow_comments eq '1') {
return $app->handle_error($app->translate(
"Comments are not allowed on this entry."));
}
require MT::IPBanList;
my $iter = MT::IPBanList->load_iter({ blog_id => $entry->blog_id });
my $user_ip = $app->remote_ip;
while (my $ban = $iter->()) {
my $banned_ip = $ban->ip;
if ($user_ip =~ /$banned_ip/) {
return $app->handle_error($app->translate(
"You are not allowed to post comments."));
}
}
my $blog = _getBlog($entry->blog_id);
if (!$blog->allow_anon_comments &&
(!$q->param('author') || !$q->param('email'))) {
return $app->handle_error($app->translate(
"Name and email address are required."));
}
if (!$q->param('text')) {
return $app->handle_error($app->translate("Comment text is required."));
}
### INSERTED CODE STARTS HERE ###
if (my ($blRc,$blStr,$textStr,$blResponse) = _matchBlacklist($entry->blog_id,
$q->param('text'),
$q->param('url'),
$q->param('email'),
$q->param('author'))) {
$app->log('MT-Blacklist comment denial on '.$blog->name.": $blStr") if defined($blStr);
if (defined($blResponse)) {
$blResponse =~ s/__TYPE__/comment/g;
$blResponse =~ s/__BLACKLIST__/$blStr/g if defined($blStr);
$blResponse =~ s/__TEXT__/$blStr/g if defined($textStr);
}
return $app->handle_error($blResponse);
}
### INSERTED CODE ENDS HERE ###
my $comment = MT::Comment->new;
$comment->ip($app->remote_ip);
$comment->blog_id($entry->blog_id);
$comment->entry_id($q->param('entry_id'));
$comment->author(remove_html(scalar $q->param('author')));
my $email = $q->param('email') || '';
if ($email) {
require MT::Util;
if (my $fixed = MT::Util::is_valid_email($email)) {
$email = $fixed;
} else {
return $app->handle_error($app->translate(
"Invalid email address '[_1]'", $email));
}
}
$comment->email(remove_html($email));
my $url = $q->param('url') || '';
if ($url) {
require MT::Util;
if (my $fixed = MT::Util::is_valid_url($url)) {
$url = $fixed;
} else {
return $app->handle_error($app->translate(
"Invalid URL '[_1]'", $url));
}
}
$comment->url(remove_html($url));
$comment->text($q->param('text'));
$comment->save;
$app->rebuild_indexes( Blog => $blog )
or return $app->error($app->translate(
"Rebuild failed: [_1]", $app->errstr));
$app->rebuild_entry( Entry => $entry )
or return $app->error($app->translate(
"Rebuild failed: [_1]", $app->errstr));
my $link_url;
if (!$q->param('static')) {
my $url = $app->base . $app->uri;
$url .= '?entry_id=' . $q->param('entry_id');
$link_url = $url;
} else {
my $static = $q->param('static');
if ($static == 1) {
$link_url = $entry->permalink;
} else {
$link_url = $static . '#' . $comment->id;
}
}
if ($blog->email_new_comments) {
require MT::Mail;
my $author = $entry->author;
$app->set_language($author->preferred_language)
if $author && $author->preferred_language;
if ($author && $author->email) {
my %head = ( To => $author->email,
From => $comment->email || $author->email,
Subject =>
'[' . $blog->name . '] ' .
$app->translate('New Comment Posted to \'[_1]\'',
$entry->title)
);
my $charset = $app->{cfg}->PublishCharset || 'iso-8859-1';
$head{'Content-Type'} = qq(text/plain; charset="$charset");
my $body = $app->translate(
'A new comment has been posted on your blog [_1], on entry #[_2] ([_3]).',
$blog->name, $entry->id, $entry->title);
require Text::Wrap;
$Text::Wrap::cols = 72;
$body = Text::Wrap::wrap('', '', $body) . "\n$link_url\n\n" .
$app->translate('IP Address:') . ' ' . $comment->ip . "\n" .
$app->translate('Name:') . ' ' . $comment->author . "\n" .
$app->translate('Email Address:') . ' ' . $comment->email . "\n" .
$app->translate('URL:') . ' ' . $comment->url . "\n\n" .
$app->translate('Comments:') . "\n\n" . $comment->text . "\n";
### INSERTED CODE STARTS HERE ###
my $comment_view_url = $app->base.$app->path.'mt-blacklist.cgi?__mode=despam&_type=comment&id='.$comment->id;
$body .= "\n\n----------------------\nDe-spam using MT-Blacklist:\n". $comment_view_url. "\n\n";
### INSERTED CODE ENDS HERE ###
MT::Mail->send(\%head, $body);
}
}
return $app->redirect($link_url);
}
#
# Redefinition of MT::App::Trackback::ping
#
# In order to include the link in the comment notification
# email, I have to use the entire 'post' method, because
# Ben has never abstracted the emails as templates. Grrrrr.
#
sub ping_post_hdlr {
my $app = shift;
my $q = $app->{query};
my($tb_id, $pass) = $app->_get_params;
return $app->_response(Error =>
$app->translate("Need a TrackBack ID (tb_id)."))
unless $tb_id;
use MT::Util qw( first_n_words encode_xml is_valid_url );
use File::Spec;
require MT::App::Trackback;
#print STDERR "In ".__PACKAGE__." at ".__LINE__."\n";
#warn "In ".__PACKAGE__." at ".__LINE__."\n";
my($title, $excerpt, $url, $blog_name) = map scalar $q->param($_),
qw( title excerpt url blog_name);
MT::App::Trackback::no_utf8($tb_id, $title, $excerpt, $url, $blog_name);
return $app->_response(Error => $app->translate("Need a Source URL (url)."))
unless $url;
if (my $fixed = MT::Util::is_valid_url($url)) {
$url = $fixed;
} else {
return $app->_response(Error =>
$app->translate("Invalid URL '[_1]'", $url));
}
require MT::TBPing;
my $tb = _getTrackback($tb_id)
or return $app->_response(Error =>
$app->translate("Invalid TrackBack ID '[_1]'", $tb_id));
return $app->_response(Error =>
$app->translate("This TrackBack item is disabled."))
if $tb->is_disabled;
if ($tb->passphrase && (!$pass || $pass ne $tb->passphrase)) {
return $app->_response(Error =>
$app->translate("This TrackBack item is protected by a passphrase."));
}
## Check if this user has been banned from sending TrackBack pings.
require MT::IPBanList;
my $iter = MT::IPBanList->load_iter({ blog_id => $tb->blog_id });
my $user_ip = $app->remote_ip;
while (my $ban = $iter->()) {
my $banned_ip = $ban->ip;
if ($user_ip =~ /$banned_ip/) {
return $app->_response(Error =>
$app->translate("You are not allowed to send TrackBack pings."));
}
}
## Check if user has pinged recently
#my @past = MT::TBPing->load({ tb_id => $tb_id, ip => $host_ip });
#if (@past) {
# @past = sort { $b->created_on cmp $a->created_on } @past;
#}
### INSERTED CODE STARTS HERE ###
if (my ($blRc,$blStr,$textStr,$blResponse) = _matchBlacklist($tb->blog_id,$title,$excerpt,$url)) {
my $blog = _getBlog($tb->blog_id);
$app->log('MT-Blacklist trackback denial on '.$blog->name.": $blStr") if defined($blStr);
$blResponse =~ s/__TYPE__/ping/g;
$blResponse =~ s/__BLACKLIST__/$blStr/g if defined($blStr);
$blResponse =~ s/__TEXT__/$blStr/g if defined($textStr);
return $app->_response(Error => $blResponse);
}
### INSERTED CODE ENDS HERE ###
my $ping = MT::TBPing->new;
$ping->blog_id($tb->blog_id);
$ping->tb_id($tb_id);
$ping->source_url($url);
$ping->ip($app->remote_ip || '');
if ($excerpt) {
if (length($excerpt) > 255) {
$excerpt = substr($excerpt, 0, 252) . '...';
}
$title = first_n_words($excerpt, 5)
unless defined $title;
$ping->excerpt($excerpt);
}
$ping->title(defined $title && $title ne '' ? $title : $url);
$ping->blog_name($blog_name);
$ping->save;
## If this is a trackback item for a particular entry, we need to
## rebuild the indexes in case the <$MTEntryTrackbackCount$> tag
## is being used. We also want to place the RSS files inside of the
## Local Site Path.
my($blog_id, $entry, $cat);
if ($tb->entry_id) {
$entry = _getEntry($tb->entry_id);
$blog_id = $entry->blog_id;
} elsif ($tb->category_id) {
require MT::Category;
$cat = MT::Category->load($tb->category_id);
$blog_id = $cat->blog_id;
}
my $blog = _getBlog($blog_id);
$app->rebuild_indexes( Blog => $blog )
or return $app->_response(Error =>
$app->translate("Rebuild failed: [_1]", $app->errstr));
if ($app->{cfg}->GenerateTrackBackRSS) {
## Now generate RSS feed for this trackback item.
my $rss = MT::App::Trackback::_generate_rss($tb, 10);
my $base = $blog->archive_path;
my $feed = File::Spec->catfile($base, $tb->rss_file || $tb->id . '.xml');
my $fmgr = $blog->file_mgr;
$fmgr->put_data($rss, $feed)
or return $app->_response(Error =>
$app->translate("Can't create RSS feed '[_1]': ", $feed,
$fmgr->errstr));
}
if ($blog->email_new_pings) {
require MT::Mail;
my($author, $subj, $body);
if ($entry) {
$author = $entry->author;
$app->set_language($author->preferred_language)
if $author && $author->preferred_language;
$subj = $app->translate('New TrackBack Ping to Entry [_1] ([_2])',
$entry->id, $entry->title);
$body = $app->translate('A new TrackBack ping has been sent to your weblog, on the entry [_1] ([_2]).', $entry->id, $entry->title);
} elsif ($cat) {
require MT::Author;
$author = MT::Author->load($cat->created_by);
$app->set_language($author->preferred_language)
if $author && $author->preferred_language;
$subj = $app->translate('New TrackBack Ping to Category [_1] ([_2])',
$cat->id, $cat->label);
$body = $app->translate('A new TrackBack ping has been sent to your weblog, on the category [_1] ([_2]).', $cat->id, $cat->label);
}
if ($author && $author->email) {
my %head = ( To => $author->email,
From => $author->email,
Subject => '[' . $blog->name . '] ' . $subj );
my $charset = $app->{cfg}->PublishCharset || 'iso-8859-1';
$head{'Content-Type'} = qq(text/plain; charset="$charset");
require Text::Wrap;
$Text::Wrap::cols = 72;
$body = Text::Wrap::wrap('', '', $body) . "\n\n" .
$app->translate('IP Address:') . ' ' . $ping->ip . "\n" .
$app->translate('URL:') . ' ' . $ping->source_url . "\n" .
$app->translate('Title:') . ' ' . $ping->title . "\n" .
$app->translate('Weblog:') . ' ' . $ping->blog_name . "\n\n" .
$app->translate('Excerpt:') . "\n" . $ping->excerpt . "\n";
### INSERTED CODE STARTS HERE ###
my $ping_view_url = $app->base.$app->path.
'mt-blacklist.cgi?__mode=despam&_type=ping&id='.
$ping->id;
$body .= "\n\n".('-'x22).
"\nDe-spam using MT-Blacklist:\n".
$ping_view_url. "\n\n";
### INSERTED CODE ENDS HERE ###
MT::Mail->send(\%head, $body);
}
}
return $app->_response;
}
#
# _matchBlacklist method
#
# Here we match blacklisted strings against the user input.
# Plain strings and regular expressions are allowed. Nothing
# needs to be escaped as far as I know since our delimiters
# and regular expression metacharaters are mutually exclusive
# aside from the period which makes no difference.
#
sub _matchBlacklist {
my (@strings, @blacklisted_strings, $str, $deny);
my $blog_id = shift;
@strings = @_;
# Read in config
my $config;
$config = _getConfig();
unless ($ENV{REQUEST_URI} =~ m/__mode=search/) {
return unless $config && $config->{'blacklistActive'};
}
# Sanitize text
$str = _sanitizeInput(join(' ', @strings));
return unless $str =~ /\S/;
# Build combined pattern
unless ($_cache->{pattern}) {
# Read in blacklist
@blacklisted_strings = _readBlacklist();
shift(@blacklisted_strings);
$_cache->{pattern} = join('|', @blacklisted_strings);
}
# Match against pattern in one expression
return unless $str =~ m#$_cache->{pattern}#io;
my $matched_string = $&;
# We match an entry, find out which one it was
@blacklisted_strings = _readBlacklist();
shift(@blacklisted_strings);
# Match against blacklist
foreach my $blacklist_string (@blacklisted_strings) {
if ($str =~ m#$blacklist_string#i) {
return (1,$blacklist_string,$matched_string,$config->{denyResponse});
}
}
# We should never get here...
die "Oops!";
}
#
# Read blacklist
#
# This subroutine doesn't READ the blacklist so
# much as it transforms it into a simple array
# of strings/regexps
sub _readBlacklist {
return map { $_->{'string'}} @{ _getBlacklist() };
}
#
# Sanitize user input
#
# Here, we sanitize the user input to prevent spammers
# from trying to circumvent matching. I'm sure that
# this will grow over time as spammers attempt to
# prove that the are smarter than the thousands
# of highly connected people that they are pissing off.
sub _sanitizeInput {
my $str = shift;
# Remove any #'s since we will be using it as a delimiter
# This is safe since it isn't something that would
# be included in a blacklist.
$str =~ tr/#//d;
# Remove any HTML comments in the form of
$str =~ s/\x3c\!.+?\x3e//g;
#
#THANKS to Stepan Riha for the next three
# Convert decimal entities (p => p)
$str =~ s/(\d{1,3});/chr($1)/eg;
# Convert hex entities (p => p)
$str =~ s/(\d{2});/chr(hex($1))/eg;
# Convert URL encodings (%70 => p)
$str =~ s/\%(\d{2})/chr(hex($1))/eg;
return $str;
}
sub mywarn {
my $warning = shift;
push(@_warnings, $warning);
}
sub dumpwarn {
my $app = shift;
$app->_debug_status(1);
return $app->_debug(join("
\n", @_warnings));
}
1;