Index: /branches/release-39/plugins/TypePadAntiSpam/lib/MT/TypePadAntiSpam.pm
===================================================================
--- /branches/release-39/plugins/TypePadAntiSpam/lib/MT/TypePadAntiSpam.pm (revision 2461)
+++ /branches/release-39/plugins/TypePadAntiSpam/lib/MT/TypePadAntiSpam.pm (revision 2461)
@@ -0,0 +1,93 @@
+# MT::TypePadAntiSpam, (C) 2008 Six Apart, Ltd.
+# Based on Akismet plugin by Tim Appnel
+# This program is distributed under the terms of the
+# GNU General Public License, version 2.
+#
+# $Id: TypePadAntiSpam.pm 81617 2008-05-23 20:11:13Z bchoate $
+
+package MT::TypePadAntiSpam;
+
+use strict;
+use base qw( MT::ErrorHandler );
+
+use Storable;
+use LWP::UserAgent;
+use Carp qw( croak );
+
+our $VERSION      = '1.0';
+our $API_VERSION  = '1.1';
+our $SERVICE_HOST = 'api.antispam.typepad.com';
+
+sub check       { shift->_typepadantispam('comment-check', 1, @_) }
+sub submit_spam { shift->_typepadantispam('submit-spam',   0, @_) }
+sub submit_ham  { shift->_typepadantispam('submit-ham',    0, @_) }
+
+sub verify {
+    my ($class, $key, $url) = @_;
+    return $class->error("API key is a required parameter.")
+      unless $key;
+    return $class->error("The URL of the site is a required parameter.")
+      unless $url;
+    my $agent = $class->_get_agent;
+    my $r =
+    $agent->post("http://$SERVICE_HOST/$API_VERSION/verify-key",
+        {key => $key, blog => $url});
+
+    # Could be more RESTful in that status code should indicate success
+    # or failure not a string in the content of the response.
+    my $res = MT::TypePadAntiSpam::Response->new;
+    $res->http_response($r);
+    $res->http_status($r->code);
+    $res->status($r->is_success && $r->content =~ /valid/i ? 1 : 0);
+    $res;
+}
+
+#--- internals
+
+my $num_dumped = 0;
+sub _typepadantispam {
+    my ($class, $meth, $is_true, $sig, $key) = @_;
+    unless ($key) {
+        my $plugin = MT::Plugin::TypePadAntiSpam->instance;
+        # print STDERR "DEBUG: processing\n" if MT->config->DebugMode;
+        return $class->error(
+            $plugin->translate("API key is a required parameter.")
+        );
+    }
+    my $agent = $class->_get_agent;
+    my $r =
+    $agent->post("http://$key.$SERVICE_HOST/$API_VERSION/$meth", [%ENV, %$sig]);
+    my $res = MT::TypePadAntiSpam::Response->new;
+    $res->http_response($r);
+    $res->http_status($r->code);
+    my $status = 0;
+    if ($r->is_success) {
+        $status = $is_true ? $r->content =~ /false/i : 1;
+    }
+    $res->status($status);    # 1 (true) means valid api key or not spam.
+    $res;
+}
+
+our $AGENT;
+sub _get_agent {
+    my $class = shift;
+    return $AGENT if $AGENT;
+    $AGENT = MT->new_ua;
+    $AGENT->agent(join '/', $class, $class->VERSION);
+    $AGENT->timeout(10);
+    $AGENT;
+}
+
+package MT::TypePadAntiSpam::Signature;
+use base qw( Class::Accessor::Fast );
+MT::TypePadAntiSpam::Signature->mk_accessors(
+    qw( blog user_ip user_agent referrer permalink comment_type
+      comment_author comment_author_email comment_author_url
+      comment_content article_date )
+);
+
+package MT::TypePadAntiSpam::Response;
+use base qw( Class::Accessor::Fast );
+MT::TypePadAntiSpam::Response->mk_accessors(qw( status http_status http_response ));
+
+1;
Index: /branches/release-39/plugins/TypePadAntiSpam/lib/TypePadAntiSpam/L10N.pm
===================================================================
--- /branches/release-39/plugins/TypePadAntiSpam/lib/TypePadAntiSpam/L10N.pm (revision 2461)
+++ /branches/release-39/plugins/TypePadAntiSpam/lib/TypePadAntiSpam/L10N.pm (revision 2461)
@@ -0,0 +1,11 @@
+# Movable Type (r) Open Source (C) 2005-2008 Six Apart, Ltd.
+# This program is distributed under the terms of the
+# GNU General Public License, version 2.
+#
+# $Id: L10N.pm 81360 2008-05-21 03:39:58Z fyoshimatsu $
+
+package TypePadAntiSpam::L10N;
+use strict;
+use base 'MT::Plugin::L10N';
+
+1;
Index: /branches/release-39/plugins/TypePadAntiSpam/lib/TypePadAntiSpam/L10N/es.pm
===================================================================
--- /branches/release-39/plugins/TypePadAntiSpam/lib/TypePadAntiSpam/L10N/es.pm (revision 2461)
+++ /branches/release-39/plugins/TypePadAntiSpam/lib/TypePadAntiSpam/L10N/es.pm (revision 2461)
@@ -0,0 +1,51 @@
+# Movable Type (r) Open Source (C) 2005-2008 Six Apart, Ltd.
+# This program is distributed under the terms of the
+# GNU General Public License, version 2.
+#
+# $Id: ja.pm 81672 2008-05-26 10:30:44Z fyoshimatsu $
+
+package TypePadAntiSpam::L10N::es;
+
+use strict;
+use base 'TypePadAntiSpam::L10N::en_us';
+use vars qw( %Lexicon );
+
+## The following is the translation table.
+
+%Lexicon = (
+
+## plugins/TypePadAntiSpam/lib/MT/TypePadAntiSpam.pm
+	'API key is a required parameter.' => 'La clave del API es un parÃ¡metro necesario.', # Translate - New
+
+## plugins/TypePadAntiSpam/tmpl/system.tmpl
+	'API Key' => 'Clave del API', # Translate - New
+	'To enable this plugin, you\'ll need a free TypePad AntiSpam API key. You can <strong>get your free API key at [_1]antispam.typepad.com[_2]</strong>. Once you have your key, return to this page and enter it in the field below.' => 'Para habilitar esta extensiÃ³n, necesita una clave gratuita del API de TypePad AntiSpam. Puede <strong>obtener su clave, gratis, en [_1]antispam.typepad.com[_2]</strong>. Tras obtenerla, regrese a esta pÃ¡gina para introducir la clave en el campo de abajo.', # Translate - New
+	'Service Host' => 'Servidor', # Translate - New
+	'The default service host for TypePad AntiSpam is api.antispam.typepad.com. You should only change this if you are using a different service that is compatible with the TypePad AntiSpam API.' => 'El servidor predefinido para TypePad AntiSpam es api.antispam.typepad.com. ModifÃ­quelo solo en el caso de utilizar otro servicio compatible con el API de TypePad AntiSpam.', # Translate - New
+
+## plugins/TypePadAntiSpam/tmpl/config.tmpl
+	'Junk Score Weight' => 'Peso de la puntuaciÃ³n', # Translate - New
+	'Least Weight' => 'Peso mÃ­nimo', # Translate - New
+	'Most Weight' => 'Peso mÃ¡ximo', # Translate - New
+	'Comments and TrackBacks receive a junk score between -10 (definitely spam) and +10 (definitely not spam). This setting allows you to control the weight of the TypePad AntiSpam rating relative to other filters you may have installed to help you filter comments and TrackBacks.' => 'Los comentarios y los TrackBacks reciben una puntuaciÃ³n de basura entre -10 (realmente spam) y +10 (no es spam). Esta opciÃ³n le permite controlar el peso de la puntuaciÃ³n de TypePad AntiSpam relativo a otros filtros que pudiera tener instalados para ayudarle a filtrar los comentarios y TrackBacks.', # Translate - New
+
+## plugins/TypePadAntiSpam/tmpl/stats_widget.tmpl
+	'widget_label_width' => 'widget_label_width', # Translate - New
+	'widget_totals_width' => 'widget_totals_width', # Translate - New
+	'TypePad AntiSpam' => 'TypePad AntiSpam', # Translate - New
+	'Spam Blocked' => 'Spam bloqueado', # Translate - New
+	'on this blog' => 'en este blog', # Translate - New
+	'on this system' => 'en este sistema', # Translate - New
+
+## plugins/TypePadAntiSpam/TypePadAntiSpam.pl
+	'TypePad AntiSpam is a free service from Six Apart that helps protect your blog from comment and TrackBack spam. The TypePad AntiSpam plugin will send every comment or TrackBack submitted to your blog to the service for evaluation, and Movable Type will filter items if TypePad AntiSpam determines it is spam. If you discover that TypePad AntiSpam incorrectly classifies an item, simply change its classification by marking it as "Spam" or "Not Spam" from the Manage Comments screen, and TypePad AntiSpam will learn from your actions. Over time the service will improve based on reports from its users, so take care when marking items as "Spam" or "Not Spam."' => 'TypePad AntiSpam es un servicio gratuito de Six Apart. Le ayuda a proteger su blog del spam en los comentarios y en el TrackBack. La extensiÃ³n de TypePad AntiSpam enviarÃ¡ al servicio todos los comentarios y TrackBacks que reciba su blog para analizarlos. Movable Type filtrarÃ¡ los elementos que TypePad AntiSpam identifique como spam. Si descubre que TypePad AntiSpam clasifica incorrectamente algÃºn elemento, solo tiene que modificar la clasificaciÃ³n marcando al elemento como "Spam" o "No es spam" en la pantalla de administraciÃ³n de comentarios. TypePad AntiSpam aprenderÃ¡ de sus decisiones. El servicio mejorarÃ¡ con el tiempo gracias a los informes remitidos por los usuarios, asÃ­ que tenga cuidado al marcar lso elementos como "Spam" o como "No es spam".', # Translate - New
+	'So far, TypePad AntiSpam has blocked [quant,_1,message,messages] for this blog, and [quant,_2,message,messages] system-wide.' => 'Hasta ahora, TypePad AntiSpam ha bloqueado [quant,_1,mensaje,mensajes] en este blog y [quant,_2,mensaje,mensajes] en todo el sistema.', # Translate - New
+	'So far, TypePad AntiSpam has blocked [quant,_1,message,messages] system-wide.' => 'Hasta ahora, TypePad AntiSpam ha bloqueado [quant,_1,mensaje,mensajes] en todo el sistema.', # Translate - New
+	'Failed to verify your TypePad AntiSpam API key: [_1]' => 'Fallo al verificar la clave API de TypePad AntiSpam: [_1]', # Translate - New
+	'The TypePad AntiSpam API key provided is invalid.' => 'La clave API de TypePad AntiSpam no es vÃ¡lida.', # Translate - New
+
+
+);
+
+1;
+
Index: /branches/release-39/plugins/TypePadAntiSpam/lib/TypePadAntiSpam/L10N/de.pm
===================================================================
--- /branches/release-39/plugins/TypePadAntiSpam/lib/TypePadAntiSpam/L10N/de.pm (revision 2461)
+++ /branches/release-39/plugins/TypePadAntiSpam/lib/TypePadAntiSpam/L10N/de.pm (revision 2461)
@@ -0,0 +1,51 @@
+# Movable Type (r) Open Source (C) 2005-2008 Six Apart, Ltd.
+# This program is distributed under the terms of the
+# GNU General Public License, version 2.
+#
+# $Id: ja.pm 81672 2008-05-26 10:30:44Z fyoshimatsu $
+
+package TypePadAntiSpam::L10N::de;
+
+use strict;
+use base 'TypePadAntiSpam::L10N::en_us';
+use vars qw( %Lexicon );
+
+## The following is the translation table.
+
+%Lexicon = (
+
+## plugins/TypePadAntiSpam/lib/MT/TypePadAntiSpam.pm
+	'API key is a required parameter.' => 'API-SchlÃŒssel erforderlich', # Translate - New # OK
+
+## plugins/TypePadAntiSpam/tmpl/system.tmpl
+	'API Key' => 'API-SchlÃŒssel', # Translate - New  # OK
+	'To enable this plugin, you\'ll need a free TypePad AntiSpam API key. You can <strong>get your free API key at [_1]antispam.typepad.com[_2]</strong>. Once you have your key, return to this page and enter it in the field below.' => 'Um dieses Plugin zu aktivieren, benÃ¶tigen Sie einen kostenlosen TypePad AntiSpam API-SchlÃŒssel. <strong>Sie erhalten Ihren kostenlosen API-SchlÃŒssel auf [_1]antispam.typepad.com[_2]</strong>. Geben Sie Ihren SchlÃŒssel in das folgende Feld ein.', # Translate - New # OK
+	'Service Host' => 'Dienstadresse', # Translate - New # OK
+	'The default service host for TypePad AntiSpam is api.antispam.typepad.com. You should only change this if you are using a different service that is compatible with the TypePad AntiSpam API.' => 'Die Standard-Dienstadresse fÃŒr TypePad AntiSpam ist api.antispam.typepad.com. Ãndern Sie diese Angabe nur dann, wenn Sie einen anderen Dienst verwenden, der mit der TypePad Antispam-API kompatibel ist.', # Translate - New # OK
+
+## plugins/TypePadAntiSpam/tmpl/config.tmpl
+	'Junk Score Weight' => 'Spamfilter-Gewichtung', # Translate - New # OK
+	'Least Weight' => 'Geringstes Gewicht', # Translate - New # OK
+	'Most Weight' => 'GrÃ¶Ãtes Gewicht', # Translate - New # OK
+	'Comments and TrackBacks receive a junk score between -10 (definitely spam) and +10 (definitely not spam). This setting allows you to control the weight of the TypePad AntiSpam rating relative to other filters you may have installed to help you filter comments and TrackBacks.' => 'Kommentare und TrackBacks erhalten eine Spam-Bewertung zwischen -10 (mit Sicherheit Spam) und +10 (mit Sicherheit kein Spam). Hier kÃ¶nnen Sie einstellen, wieviel Gewicht diese Bewertung im VerhÃ€ltnis zu anderen Spamfiltern, die Sie mÃ¶glicherweise ebenfalls installiert haben, erhalten soll.', # Translate - New # OK
+
+## plugins/TypePadAntiSpam/tmpl/stats_widget.tmpl
+	'widget_label_width' => 'widget_label_width', # Translate - New # OK
+	'widget_totals_width' => 'widget_totals_width', # Translate - New # OK
+	'TypePad AntiSpam' => 'TypePad AntiSpam', # Translate - New # OK
+	'Spam Blocked' => 'Blockierter Spam', # Translate - New # OK
+	'on this blog' => 'in diesem Blog', # Translate - New # OK
+	'on this system' => 'in diesem System', # Translate - New # OK
+
+## plugins/TypePadAntiSpam/TypePadAntiSpam.pl
+	'TypePad AntiSpam is a free service from Six Apart that helps protect your blog from comment and TrackBack spam. The TypePad AntiSpam plugin will send every comment or TrackBack submitted to your blog to the service for evaluation, and Movable Type will filter items if TypePad AntiSpam determines it is spam. If you discover that TypePad AntiSpam incorrectly classifies an item, simply change its classification by marking it as "Spam" or "Not Spam" from the Manage Comments screen, and TypePad AntiSpam will learn from your actions. Over time the service will improve based on reports from its users, so take care when marking items as "Spam" or "Not Spam."' => 'TypePad AntiSpam schÃŒtzt Ihr Blog vor Kommentar- und TrackBack-Spam. Mit dem TypePad AntiSpam-Plugin wird jeder eingehende Kommentar und jedes eingehende TrackBack vom TypePad AntiSpam-Service ÃŒberprÃŒft und, falls es sich um Spam handelt, von Movable Type automatisch herausgefiltert. Kommentare und TrackBacks kÃ¶nnen auch manuell als Spam oder gÃŒltiges Feedback markiert werden. TypePad AntiSpam ist adaptiv und lernt dabei nicht nur aus Ihren Eingaben, sondern aus denen aller Benutzer des Dienstes. TypePad AntiSpam ist ein kostenloser Dienst von Six Apart.', # Translate - New # OK
+	'So far, TypePad AntiSpam has blocked [quant,_1,message,messages] for this blog, and [quant,_2,message,messages] system-wide.' => 'Bisher [quant,_1,Spam-Nachricht,Spam-Nachrichten] in diesem Blog und [quant,_2,Spam-Nachricht,Spam-Nachrichten] systemweit von TypePad AntiSpam blockiert.', # Translate - New # OK
+	'So far, TypePad AntiSpam has blocked [quant,_1,message,messages] system-wide.' => 'Bisher [quant,_1,Spam-Nachricht,Spam-Nachrichten] von TypePad AntiSpam blockiert.', # Translate - New # OK
+	'Failed to verify your TypePad AntiSpam API key: [_1]' => 'Verifizierung des TypePad AntiSpam API-SchlÃŒssels fehlgeschlagen: [_1]', # Translate - New # OK
+	'The TypePad AntiSpam API key provided is invalid.' => 'Der angegebene TypePad AntiSpam API-SchlÃŒssel ist ungÃŒltig.', # Translate - New # OK
+
+
+);
+
+1;
+
Index: /branches/release-39/plugins/TypePadAntiSpam/lib/TypePadAntiSpam/L10N/en_us.pm
===================================================================
--- /branches/release-39/plugins/TypePadAntiSpam/lib/TypePadAntiSpam/L10N/en_us.pm (revision 2461)
+++ /branches/release-39/plugins/TypePadAntiSpam/lib/TypePadAntiSpam/L10N/en_us.pm (revision 2461)
@@ -0,0 +1,19 @@
+# Movable Type (r) Open Source (C) 2005-2008 Six Apart, Ltd.
+# This program is distributed under the terms of the
+# GNU General Public License, version 2.
+#
+# $Id: en_us.pm 81624 2008-05-23 21:35:31Z bsmith $
+
+package TypePadAntiSpam::L10N::en_us;
+
+use strict;
+
+use base 'TypePadAntiSpam::L10N';
+use vars qw( %Lexicon );
+%Lexicon = ( 
+
+## plugins/TypePadAntiSpam/tmpl/stats_widget.tmpl 
+	'widget_label_width' => '57', 
+	'widget_totals_width' => '200', 
+);
+1;
Index: /branches/release-39/plugins/TypePadAntiSpam/lib/TypePadAntiSpam/L10N/nl.pm
===================================================================
--- /branches/release-39/plugins/TypePadAntiSpam/lib/TypePadAntiSpam/L10N/nl.pm (revision 2461)
+++ /branches/release-39/plugins/TypePadAntiSpam/lib/TypePadAntiSpam/L10N/nl.pm (revision 2461)
@@ -0,0 +1,51 @@
+# Movable Type (r) Open Source (C) 2005-2008 Six Apart, Ltd.
+# This program is distributed under the terms of the
+# GNU General Public License, version 2.
+#
+# $Id: ja.pm 81672 2008-05-26 10:30:44Z fyoshimatsu $
+
+package TypePadAntiSpam::L10N::nl;
+
+use strict;
+use base 'TypePadAntiSpam::L10N::en_us';
+use vars qw( %Lexicon );
+
+## The following is the translation table.
+
+%Lexicon = (
+
+## plugins/TypePadAntiSpam/lib/MT/TypePadAntiSpam.pm
+	'API key is a required parameter.' => 'API sleutel is een vereiste parameter', # Translate - New
+
+## plugins/TypePadAntiSpam/tmpl/system.tmpl
+	'API Key' => 'API sleutel', # Translate - New
+	'To enable this plugin, you\'ll need a free TypePad AntiSpam API key. You can <strong>get your free API key at [_1]antispam.typepad.com[_2]</strong>. Once you have your key, return to this page and enter it in the field below.' => 'Om deze plugin te kunnen inschakelen heeft u een gratis TypePad AntiSpam API sleutel nodig.  U kunt uw <strong>gratis API sleutel afhalen op [_1]antispam.typepad.com[_2]</strong>.  Zodra u uw sleutel heeft, moet u terugkeren naar deze pagina en hem hieronder invullen.', # Translate - New
+	'Service Host' => 'Service host', # Translate - New
+	'The default service host for TypePad AntiSpam is api.antispam.typepad.com. You should only change this if you are using a different service that is compatible with the TypePad AntiSpam API.' => 'De standaard host voor TypePad AntiSpam is api.antispam.com.  U moet dit alleen veranderen als u een andere service gebruikt die compatibel is met de TypePad AntiSpam API.', # Translate - New
+
+## plugins/TypePadAntiSpam/tmpl/config.tmpl
+	'Junk Score Weight' => 'Spamscoregewicht', # Translate - New
+	'Least Weight' => 'Laagste gewicht', # Translate - New
+	'Most Weight' => 'Hoogste gewicht', # Translate - New
+	'Comments and TrackBacks receive a junk score between -10 (definitely spam) and +10 (definitely not spam). This setting allows you to control the weight of the TypePad AntiSpam rating relative to other filters you may have installed to help you filter comments and TrackBacks.' => 'Reacties en TrackBacks krijgen een spamscore tussen -10 (zeker spam) en +10 (zeker geen spam).  Deze instelling geeft u de mogelijkheid het gewicht van het oordeel van TypePad AntiSpam in te stellen relatief tot de andere filters die u misschien geÃ¯nstalleerd heeft om reacties en TrackBacks te filteren.', # Translate - New
+
+## plugins/TypePadAntiSpam/tmpl/stats_widget.tmpl
+	'widget_label_width' => 'widget_label_width', # Translate - New
+	'widget_totals_width' => 'widget_totals_width', # Translate - New
+	'TypePad AntiSpam' => 'TypePad AntiSpam', # Translate - New
+	'Spam Blocked' => 'Spams gestopt', # Translate - New
+	'on this blog' => 'op deze blog', # Translate - New
+	'on this system' => 'op dit systeem', # Translate - New
+
+## plugins/TypePadAntiSpam/TypePadAntiSpam.pl
+	'TypePad AntiSpam is a free service from Six Apart that helps protect your blog from comment and TrackBack spam. The TypePad AntiSpam plugin will send every comment or TrackBack submitted to your blog to the service for evaluation, and Movable Type will filter items if TypePad AntiSpam determines it is spam. If you discover that TypePad AntiSpam incorrectly classifies an item, simply change its classification by marking it as "Spam" or "Not Spam" from the Manage Comments screen, and TypePad AntiSpam will learn from your actions. Over time the service will improve based on reports from its users, so take care when marking items as "Spam" or "Not Spam."' => 'TypePad AntiSpam is een gratis service van Six Apart die helpt uw blog te beschermen tegen spam in uw reacties en TrackBacks.  De TypePad AntiSpam plugin verstuurt elke reactie of TrackBack die ontvangen wordt op uw blog door naar de service waar ze dan beoordeeld worden.  Movable Type zal items filteren als TypePad AntiSpam bepaalt dat ze spam zijn.  Als u merkt dat TypePad AntiSpam items niet correct classificeert dan kunt u de classificatie eenvoudigweg aanpassen door ze als "Spam" of "Geen Spam" te markeren vanop het scherm voor reactiebeheer.  TypePad AntiSpam zal dan leren uit uw acties.  Na verloop van tijd wordt de service dus altijd maar beter, gebaseerd op rapporten van gebruikers, dus let op voor u iets als "Spam" of "Geen Spam" markeert!', # Translate - New
+	'So far, TypePad AntiSpam has blocked [quant,_1,message,messages] for this blog, and [quant,_2,message,messages] system-wide.' => 'Tot nu toe heeft TypePad AntiSpam [quant,_1,bericht,berichten] geblokkeerd voor deze weblog, en [quant,_2,bericht,berichten] over het hele systeem.', # Translate - New
+	'So far, TypePad AntiSpam has blocked [quant,_1,message,messages] system-wide.' => 'Tot nu toe heeft TypePad AntiSpam [quant,_1,bericht,berichten] geblokkeerd over het hele systeem.', # Translate - New
+	'Failed to verify your TypePad AntiSpam API key: [_1]' => 'Verificatie van uw TypePad AntiSpam API sleutel mislukt:', # Translate - New
+	'The TypePad AntiSpam API key provided is invalid.' => 'De TypePad AntiSpam API sleutel die u opgaf was ongeldig.', # Translate - New
+
+
+);
+
+1;
+
Index: /branches/release-39/plugins/TypePadAntiSpam/lib/TypePadAntiSpam/L10N/ja.pm
===================================================================
--- /branches/release-39/plugins/TypePadAntiSpam/lib/TypePadAntiSpam/L10N/ja.pm (revision 2461)
+++ /branches/release-39/plugins/TypePadAntiSpam/lib/TypePadAntiSpam/L10N/ja.pm (revision 2461)
@@ -0,0 +1,55 @@
+# Movable Type (r) Open Source (C) 2005-2008 Six Apart, Ltd.
+# This program is distributed under the terms of the
+# GNU General Public License, version 2.
+#
+# $Id: ja.pm 81947 2008-05-28 11:02:59Z fyoshimatsu $
+
+package TypePadAntiSpam::L10N::ja;
+
+use strict;
+use base 'TypePadAntiSpam::L10N::en_us';
+use vars qw( %Lexicon );
+
+## The following is the translation table.
+
+%Lexicon = (
+
+## plugins/TypePadAntiSpam/tmpl/stats_widget.tmpl
+	'widget_label_width' => '77',
+	'widget_totals_width' => '180',
+	'TypePad AntiSpam' => 'TypePad AntiSpam',
+	'Spam Blocked' => 'ãã­ãã¯ããã¹ãã ',
+	'on this blog' => 'ãã­ã°ã¬ãã«',
+	'on this system' => 'ã·ã¹ãã å
+šäœ',
+
+## plugins/TypePadAntiSpam/tmpl/system.tmpl
+	'API Key' => 'APIã­ãŒ',
+	'To enable this plugin, you\'ll need a free TypePad AntiSpam API key. You can <strong>get your free API key at [_1]antispam.typepad.com[_2]</strong>. Once you have your key, return to this page and enter it in the field below.' => 'ãã®ãã©ã°ã€ã³ãå©çšããã«ã¯ãTypePad AntiSpam APIã­ãŒ(ç¡å)ãå¿
+èŠã§ããAPIã­ãŒã¯<strong>[_1]antispam.typepad.com[_2]</strong>ããç¡åã§ååŸã§ããŸããååŸãããããã®ããŒãžã«æ»ã£ãŠã­ãŒãå
+¥åããŠãã ãããè©³ããã¯<a href="http://antispam.typepad.jp/info/how-to-get-api-key.html" target="_blank">ãã¡ã</a>ã',
+	'Service Host' => 'ãµãŒãã¹ã®ãã¹ã',
+	'The default service host for TypePad AntiSpam is api.antispam.typepad.com. You should only change this if you are using a different service that is compatible with the TypePad AntiSpam API.' => 'TypePad AntiSpamã®æ¢å®ã®ãã¹ãã¯api.antispam.typepad.comã§ããTypePad AntiSpam APIãšäºææ§ãæã€ä»ã®ãµãŒãã¹ãå©çšããå Žåã«éã£ãŠããã®èš­å®ãå€æŽããŠãã ããã',
+
+## plugins/TypePadAntiSpam/tmpl/config.tmpl
+	'Junk Score Weight' => 'ã¹ã³ã¢ã®éã¿ã¥ã',
+	'Least Weight' => 'ç·©ã',
+	'Most Weight' => 'å³ãã',
+	'Comments and TrackBacks receive a junk score between -10 (definitely spam) and +10 (definitely not spam). This setting allows you to control the weight of the TypePad AntiSpam rating relative to other filters you may have installed to help you filter comments and TrackBacks.' => 'ã³ã¡ã³ãããã³ãã©ãã¯ããã¯ã«ã¯-10(ééããªãã¹ãã )ãã+10(ã¹ãã ã§ã¯ããããªã)ãŸã§ã®ç¯å²ã§ç¹æ°ãä»ããããŸãããã®èš­å®ãå€æŽãããšãTypePad AntiSpamã«ããå€å®ããã€ã³ã¹ããŒã«ãããŠããä»ã®ã¹ãã ãã£ã«ã¿ã®å€å®ãšã®é¢é£ã§é«ããããäœããããããããšã§ãã³ã¡ã³ããšãã©ãã¯ããã¯ã®ã¹ãã ãã£ã«ã¿ãªã³ã°ã®èš­å®ãèª¿æŽã§ããŸãã',
+
+## plugins/TypePadAntiSpam/TypePadAntiSpam.pl
+	'TypePad AntiSpam is a free service from Six Apart that helps protect your blog from comment and TrackBack spam. The TypePad AntiSpam plugin will send every comment or TrackBack submitted to your blog to the service for evaluation, and Movable Type will filter items if TypePad AntiSpam determines it is spam. If you discover that TypePad AntiSpam incorrectly classifies an item, simply change its classification by marking it as "Spam" or "Not Spam" from the Manage Comments screen, and TypePad AntiSpam will learn from your actions. Over time the service will improve based on reports from its users, so take care when marking items as "Spam" or "Not Spam."' => '<a href="http://antispam.typepad.jp/" target="_blank">TypePad AntiSpam</a>ã¯Six Apartããç¡åã§æäŸããããã³ã¡ã³ããšãã©ãã¯ããã¯ã¹ãã ããããªãã®ãã­ã°ãå®ãããã®ãµãŒãã¹ã§ããTypePad AntiSpamãã©ã°ã€ã³ã¯ãããªãã®ãã­ã°ã«å®ãŠããããã¹ãŠã®ã³ã¡ã³ããšãã©ãã¯ããã¯ããè©äŸ¡ã®ããã«ãµãŒãã¹ã«éä¿¡ããTypePad AntiSpamãã¹ãã ã§ãããšå€æ­ããå Žåã«ã¯ãMovable Typeãããããã£ã«ã¿ãªã³ã°ããŸããTypePad AntiSpamã«ããå€å®ã«èª€ãããã£ãå Žåã¯ãã³ã¡ã³ãã®äžèŠ§ç»é¢ã§ãããã¹ãã ã«ããããããã¯ã¹ãã ã§ã¯ãªããšæå®ããã°ãTypePad AntiSpamã¯ãããå­Šç¿ããŸãããã®ãããªãŠãŒã¶ãŒããã®ã¬ããŒãã«ãã£ãŠTypePad AntiSpamã«ããè©äŸ¡ã®ç²ŸåºŠãããã«é«ããŸãããã®ãããã¢ã€ãã ãã¹ãã ã«ããããã¹ãã ããè§£é€ããå Žåã«ã¯ãå°ãæ°ãã€ããŠãã ããã',
+	'So far, TypePad AntiSpam has blocked [quant,_1,message,messages] for this blog, and [quant,_2,message,messages] system-wide.' => 'ãããŸã§ã®ãšãããTypePad AntiSpamã¯ãã®ãã­ã°ã«å¯Ÿããã¹ãã ã[quant,_1,ä»¶,ä»¶]ãã­ãã¯ããŸãããã·ã¹ãã å
+šäœã§ã¯[quant,_1,ä»¶,ä»¶]ãã­ãã¯ããŸããã',
+	'So far, TypePad AntiSpam has blocked [quant,_1,message,messages] system-wide.' => 'ãããŸã§ã®ãšãããTypePad AntiSpamã¯ãã®ã·ã¹ãã å
+šäœã«å¯Ÿããã¹ãã ã[quant,_1,ä»¶,ä»¶]ãã­ãã¯ããŸããã',
+	'Failed to verify your TypePad AntiSpam API key: [_1]' => 'TypePad AntiSpam APIã­ãŒã®æ€èšŒã«å€±æããŸãã: [_1]',
+	'The TypePad AntiSpam API key provided is invalid.' => 'äžæ­£ãªTypePad AntiSpam APIã­ãŒã§ãã',
+
+## plugins/TypePadAntiSpam/lib/MT/TypePadAntiSpam.pm
+	'API key is a required parameter.' => 'APIã­ãŒãèš­å®ããŠãã ããã',
+
+);
+
+1;
+
Index: /branches/release-39/plugins/TypePadAntiSpam/php/function.mttypepadantispamcounter.php
===================================================================
--- /branches/release-39/plugins/TypePadAntiSpam/php/function.mttypepadantispamcounter.php (revision 2461)
+++ /branches/release-39/plugins/TypePadAntiSpam/php/function.mttypepadantispamcounter.php (revision 2461)
@@ -0,0 +1,15 @@
+<?php
+# Movable Type (r) Open Source (C) 2001-2008 Six Apart, Ltd.
+# This program is distributed under the terms of the
+# GNU General Public License, version 2.
+#
+# $Id$
+
+function smarty_function_mttypepadantispamcounter($args, &$ctx) {
+    $blog = $ctx->stash('blog');
+    $cfg = $ctx->mt->db->fetch_plugin_config('MT::Plugin::TypePadAntiSpam',
+        'blog:' . $blog['blog_id']);
+    $count = $cfg['blocked'];
+    $count or $count = 0;
+    return $ctx->count_format($count, $args);
+}
Index: /branches/release-39/plugins/TypePadAntiSpam/tmpl/system.tmpl
===================================================================
--- /branches/release-39/plugins/TypePadAntiSpam/tmpl/system.tmpl (revision 2461)
+++ /branches/release-39/plugins/TypePadAntiSpam/tmpl/system.tmpl (revision 2461)
@@ -0,0 +1,24 @@
+<div class="field field-left-label pkg">
+    <div class="field-inner">
+        <div class="field-header">
+            <label for="tpas_api_key"><MT_TRANS phrase="API Key"></label>
+        </div>
+        <div class="field-content">
+            <div class="textarea-wrapper"><input type="text" size="15" id="tpas_api_key" name="api_key" value="<TMPL_VAR NAME=API_KEY ESCAPE=HTML>" /></div>
+            <TMPL_UNLESS NAME=API_KEY>
+            <p class="hint"><MT_TRANS phrase="To enable this plugin, you'll need a free TypePad AntiSpam API key. You can <strong>get your free API key at [_1]antispam.typepad.com[_2]</strong>. Once you have your key, return to this page and enter it in the field below." params='<a href="http://antispam.typepad.com/" target="_blank">%%</a>'></p>
+            </TMPL_UNLESS>
+        </div>
+    </div>
+</div>
+<div class="field field-left-label pkg">
+    <div class="field-inner">
+        <div class="field-header">
+            <label for="tpas_service_host"><MT_TRANS phrase="Service Host"></label>
+        </div>
+        <div class="field-content">
+            <div class="textarea-wrapper"><input type="text" size="40" name="service_host" id="tpas_service_host" value="<TMPL_VAR NAME=SERVICE_HOST ESCAPE=HTML>" /></div>
+            <p class="hint"><MT_TRANS phrase="The default service host for TypePad AntiSpam is api.antispam.typepad.com. You should only change this if you are using a different service that is compatible with the TypePad AntiSpam API."></p>
+        </div>
+    </div>
+</div>
Index: /branches/release-39/plugins/TypePadAntiSpam/tmpl/config.tmpl
===================================================================
--- /branches/release-39/plugins/TypePadAntiSpam/tmpl/config.tmpl (revision 2461)
+++ /branches/release-39/plugins/TypePadAntiSpam/tmpl/config.tmpl (revision 2461)
@@ -0,0 +1,22 @@
+<div class="field field-left-label pkg">
+    <div class="field-inner">
+        <div class="field-header">
+            <label for="tpas_weight"><MT_TRANS phrase="Junk Score Weight"></label>
+        </div>
+        <div class="field-content">
+            <select id="tpas_weight" name="weight">
+                <option value="1" <TMPL_IF NAME=WEIGHT_1>selected="selected"</TMPL_IF>>1 - <MT_TRANS phrase="Least Weight"></option>
+                <option value="2" <TMPL_IF NAME=WEIGHT_2>selected="selected"</TMPL_IF>>2</option>
+                <option value="3" <TMPL_IF NAME=WEIGHT_3>selected="selected"</TMPL_IF>>3</option>
+                <option value="4" <TMPL_IF NAME=WEIGHT_4>selected="selected"</TMPL_IF>>4</option>
+                <option value="5" <TMPL_IF NAME=WEIGHT_5>selected="selected"</TMPL_IF>>5</option>
+                <option value="6" <TMPL_IF NAME=WEIGHT_6>selected="selected"</TMPL_IF>>6</option>
+                <option value="7" <TMPL_IF NAME=WEIGHT_7>selected="selected"</TMPL_IF>>7</option>
+                <option value="8" <TMPL_IF NAME=WEIGHT_8>selected="selected"</TMPL_IF>>8</option>
+                <option value="9" <TMPL_IF NAME=WEIGHT_9>selected="selected"</TMPL_IF>>9</option>
+                <option value="10" <TMPL_IF NAME=WEIGHT_10>selected="selected"</TMPL_IF>>10 - <MT_TRANS phrase="Most Weight"></option>
+            </select>
+            <p class="hint"><MT_TRANS phrase="Comments and TrackBacks receive a junk score between -10 (definitely spam) and +10 (definitely not spam). This setting allows you to control the weight of the TypePad AntiSpam rating relative to other filters you may have installed to help you filter comments and TrackBacks."></p>
+        </div>
+    </div>
+</div>
Index: /branches/release-39/plugins/TypePadAntiSpam/tmpl/stats_widget.tmpl
===================================================================
--- /branches/release-39/plugins/TypePadAntiSpam/tmpl/stats_widget.tmpl (revision 2461)
+++ /branches/release-39/plugins/TypePadAntiSpam/tmpl/stats_widget.tmpl (revision 2461)
@@ -0,0 +1,68 @@
+<mt:setvarblock name="html_head" append="1">
+<__trans_section component="typepadantispam">
+<style type="text/css" media="screen">
+    .typepadantispam-stats {
+        width: 300px;
+        background: #e7eff3;
+    }
+    .typepadantispam-stats .widget-content {
+        padding-top: 3px;
+    }
+    .tpas-label {
+        float: left;
+        width: <__trans phrase="widget_label_width">px;
+        text-align: right;
+        padding-top: 3px;
+    }
+    .tpas-totals {
+        float: right;
+        width: <__trans phrase="widget_totals_width">px;
+        padding: 2px 6px;
+        background: #fff;
+        border: 1px solid #d5e3ea;
+        border-width: 0 1px 1px 0;
+        overflow: auto;
+    }
+    .tpas-totals strong {
+        font-size: 24px;
+        font-weight: normal;
+        white-space: nowrap;
+    }
+    .tpas-totals em {
+        color: #999;
+        padding-left: 5px;
+        white-space: nowrap;
+    }
+    .tpas-ad {
+        clear: both;
+        width: 280px;
+        height: 30px;
+        margin-top: 10px;
+    }
+    .tpas-ad iframe {
+        border: none;
+    }
+</style>
+</__trans_section>
+</mt:setvarblock>
+<mtapp:widget class="widget typepadantispam-stats"
+    label="<__trans phrase="TypePad AntiSpam">"
+    label_link="http://antispam.typepad.com/"
+    can_close="1"
+    corners="1">
+    <div class="tpas-data pkg">
+        <div class="tpas-label"><__trans phrase="Spam Blocked"></div>
+        <div class="tpas-totals">
+<mt:if name="blog_id">
+            <strong><mt:var name="blog_blocked"></strong>
+            <em><__trans phrase="on this blog"></em>
+<mt:else>
+            <strong><mt:var name="system_blocked"></strong>
+            <em><__trans phrase="on this system"></em>
+</mt:if>
+        </div>
+    </div>
+    <mt:unless name="is_ssl">
+    <div class="tpas-ad"><iframe src="http://ads.sixapart.com/show?p=mt&amp;channel=app&amp;width=280&amp;height=30&amp;language=<mt:var name="language">" width="280" height="30" frameborder="0" marginwidth="0" marginheight="0" scrolling="0"></iframe></div>
+    </mt:unless>
+</mtapp:widget>
Index: /branches/release-39/plugins/TypePadAntiSpam/TypePadAntiSpam.pl
===================================================================
--- /branches/release-39/plugins/TypePadAntiSpam/TypePadAntiSpam.pl (revision 2461)
+++ /branches/release-39/plugins/TypePadAntiSpam/TypePadAntiSpam.pl (revision 2461)
@@ -0,0 +1,349 @@
+# TypePad AntiSpam Plugin for Movable Type
+# Copyright (C) 2008, Six Apart, Ltd.
+# Derived from Tim Appnel's MT Akismet plugin for Movable Type.
+# This program is distributed under the terms of the
+# GNU General Public License, version 2.
+#
+# $Id: TypePadAntiSpam.pl 82073 2008-05-29 02:58:04Z fyoshimatsu $
+
+package MT::Plugin::TypePadAntiSpam;
+
+use strict;
+
+use base qw( MT::Plugin );
+our $VERSION = '1.0';
+
+my $plugin;
+{
+    my $settings = [
+        ['api_key', { Scope => 'system'} ],
+        ['weight',  { Default => 1, Scope => 'blog'}],
+        ['service_host',  { Default => 'api.antispam.typepad.com', Scope => 'system'}],
+    ];
+    my $about = {
+        name                   => 'TypePad AntiSpam',
+        id                     => 'typepadantispam',
+        key                    => __PACKAGE__,
+        author_name            => 'Six Apart Ltd.',
+        author_link            => 'http://www.sixapart.com/',
+        version                => $VERSION,
+        blog_config_template   => 'config.tmpl',
+        system_config_template => 'system.tmpl',
+        settings               => MT::PluginSettings->new($settings),
+        l10n_class             => 'TypePadAntiSpam::L10N',
+        registry => {
+            callbacks => {
+                handle_spam => \&handle_junk,
+                handle_ham => \&handle_not_junk,
+                'MT::Comment::pre_save' => \&pre_save_obj,
+                'MT::TBPing::pre_save' => \&pre_save_obj,
+            },
+            junk_filters => {
+                'TypePadAntiSpam' => {
+                    label => 'TypePad AntiSpam',
+                    code => \&typepadantispam_score,
+                },
+            },
+            tags => {
+                function => {
+                    TypePadAntiSpamCounter => \&_hdlr_tpas_counter,
+                },
+            },
+            widgets => {
+                typepadantispam => {
+                    label      => 'TypePad AntiSpam',
+                    template   => 'stats_widget.tmpl',
+                    handler    => \&stats_widget, 
+                    set        => 'sidebar',
+                    singular   => 1,
+                    order      => 2.1,
+                    condition  => sub {
+                        return $plugin->api_key ? 1 : 0;
+                    },
+                },
+            },
+        },
+    };
+    $plugin = __PACKAGE__->new($about);
+}
+MT->add_plugin($plugin);
+if (MT->version_number < 4) {
+    MT->add_callback('HandleJunk',    5, $plugin, \&handle_junk);
+    MT->add_callback('HandleNotJunk', 5, $plugin, \&handle_not_junk);
+    MT->register_junk_filter({
+        name => 'TypePadAntiSpam',
+        code => \&typepadantispam_score
+    });
+    require MT::Template::Context;
+    MT::Template::Context->add_tag( TypePadAntiSpamCounter => \&_hdlr_tpas_counter );
+}
+
+#--- plugin handlers
+
+sub instance {
+    return $plugin;
+}
+
+sub description {
+    my $plugin = shift;
+    my $app = MT->instance;
+    my $blog;
+    if ($app->isa('MT::App::CMS')) {
+        $blog = $app->blog;
+    }
+    my $sys_blocked = $plugin->blocked();
+    my $desc = '<p>' . $plugin->translate('TypePad AntiSpam is a free service from Six Apart that helps protect your blog from comment and TrackBack spam. The TypePad AntiSpam plugin will send every comment or TrackBack submitted to your blog to the service for evaluation, and Movable Type will filter items if TypePad AntiSpam determines it is spam. If you discover that TypePad AntiSpam incorrectly classifies an item, simply change its classification by marking it as "Spam" or "Not Spam" from the Manage Comments screen, and TypePad AntiSpam will learn from your actions. Over time the service will improve based on reports from its users, so take care when marking items as "Spam" or "Not Spam."') . '</p>';
+
+    if ($blog) {
+        my $blog_blocked = $blog ? $plugin->blocked($blog) : 0;
+        $desc .= '<p>' . $plugin->translate('So far, TypePad AntiSpam has blocked [quant,_1,message,messages] for this blog, and [quant,_2,message,messages] system-wide.', $blog_blocked, $sys_blocked) . '</p>';
+    } else {
+        $desc .= '<p>' . $plugin->translate('So far, TypePad AntiSpam has blocked [quant,_1,message,messages] system-wide.', $sys_blocked) . '</p>';
+    }
+    return $desc;
+}
+
+sub _hdlr_tpas_counter {
+    my ($ctx, $args, $cond) = @_;
+    my $blog = $ctx->stash('blog');
+    return $ctx->count_format($plugin->blocked($blog), $args);
+}
+
+sub save_config {
+    my $plugin = shift;
+    my ($args, $scope) = @_;
+
+    my $app = MT->instance;
+
+    $scope ||= 'system';
+    if ( $scope eq 'system' ) {
+        my $existing_api_key = $plugin->api_key || '';
+        my $new_api_key = $args->{api_key} || '';
+        if ( ($new_api_key ne '') && ( $new_api_key ne $existing_api_key ) ) {
+            # user assigned a new API key
+            $plugin->require_tpas;
+            local $MT::TypePadAntiSpam::SERVICE_HOST = $args->{service_host}
+                if $args->{service_host};
+            my $url = $app->base . $app->mt_uri;
+            my $res = MT::TypePadAntiSpam->verify( $new_api_key, $url );
+            if ( $res->http_status >= 500 ) {
+                return $plugin->error($plugin->translate("Failed to verify your TypePad AntiSpam API key: [_1]", $res->http_response->message));
+            } elsif ( $res->status != 1 ) {
+                return $plugin->error($plugin->translate("The TypePad AntiSpam API key provided is invalid."));
+            }
+        }
+    }
+
+    my $result = $plugin->SUPER::save_config(@_);
+    return $result if MT->version_number < 4;
+
+    my $user = $app->user;
+    my $blog_id = $app->blog->id if $app->blog;
+
+    my $widget_store = $user->widgets();
+    if ($widget_store && %$widget_store) {
+        my $sys_db = $widget_store->{'dashboard:system'} ||= default_widgets();
+        my $blog_db = $widget_store->{'dashboard:blog:' . $blog_id} ||= default_widgets()
+            if $blog_id;
+
+        my $changed = 0;
+        if ($blog_id && (!exists $blog_db->{'typepadantispam'})) {
+            $blog_db->{'typepadantispam'} =
+                { order => 2.1,  # following mt shortcuts, if shown
+                    set => 'sidebar' };
+            $changed++;
+        }
+        if (!exists $sys_db->{'typepadantispam'}) {
+            $sys_db->{'typepadantispam'} =
+                { order => 2.1,  # following mt shortcuts, if shown
+                    set => 'sidebar' };
+            $changed++;
+        }
+        if ($changed) {
+            $user->widgets( $widget_store );
+            $user->save;
+        }
+    }
+
+    return $result;
+}
+
+sub default_widgets {
+    # FIXME: This should come from the app
+    return {
+        'blog_stats' =>
+          { param => { tab => 'entry' }, order => 1, set => 'main' },
+        'this_is_you-1' => { order => 1, set => 'sidebar' },
+        'mt_shortcuts'  => { order => 2, set => 'sidebar' },
+        'mt_news'       => { order => 3, set => 'sidebar' },
+    };
+}
+
+sub stats_widget {
+    my $app = shift;
+    my ( $tmpl, $param ) = @_;
+    my $blog = $app->blog;
+    if ($blog) {
+        $param->{'blog_blocked'} = $plugin->blocked($blog) || 0;
+    }
+    $param->{'system_blocked'} = $plugin->blocked();
+    $param->{'language'} = lc substr( MT->instance->current_language, 0, 2 );
+    $param->{'use_ssl'} = $app->is_secure;
+    $param->{'api_key'} = $plugin->api_key;
+    return;
+}
+
+sub pre_save_obj {
+    my ($cb, $obj) = @_;
+    if (!$obj->id && $obj->is_junk && ($obj->junk_log =~ m/TypePad AntiSpam says spam/)) {
+        # this was junked due in part to TypePad AntiSpam
+        if (my $blog = $obj->blog) {
+            $plugin->blocked( $blog, $plugin->blocked($blog) + 1 );
+        }
+        # now increment total block count:
+        $plugin->blocked( undef, $plugin->blocked() + 1 );
+    }
+}
+
+sub handle_junk {
+    my ($cb, $app, $thing) = @_;
+    $plugin->require_tpas;
+    my $key    = is_valid_key($thing)       or return;
+    my $sig    = package_signature($thing)  or return;
+    MT::TypePadAntiSpam->submit_spam($sig, $key);
+}
+
+sub handle_not_junk {
+    my ($cb, $app, $thing) = @_;
+    $plugin->require_tpas;
+    my $key    = is_valid_key($thing)       or return;
+    my $sig    = package_signature($thing)  or return;
+    MT::TypePadAntiSpam->submit_ham($sig, $key);
+}
+
+sub typepadantispam_score {
+    my $thing = shift;
+    $plugin->require_tpas;
+    my $key    = is_valid_key($thing)
+        or return MT::JunkFilter::ABSTAIN();
+    my $sig    = package_signature($thing, 1)
+        or return MT::JunkFilter::ABSTAIN();
+    my $res = MT::TypePadAntiSpam->check($sig, $key);
+    my $http_resp = $res->http_response;
+    if ( $http_resp && ! $http_resp->is_success ) {
+        MT->log("TypePad AntiSpam error: " . $http_resp->message);
+    } elsif ( !$http_resp ) {
+        if ( MT::TypePadAntiSpam->errstr ) {
+            MT->log("TypePad AntiSpam error: " . MT::TypePadAntiSpam->errstr );
+        }
+    }
+    return MT::JunkFilter::ABSTAIN()
+        unless $res && $res->http_response->is_success;
+    my $weight = $plugin->get_config_value('weight',
+        'blog:' . $thing->blog_id) || 1;
+    my ($score, $grade) = $res->status
+                        ? ($weight, 'ham')
+                        : (-$weight, 'spam');
+    ($score, ["TypePad AntiSpam says $grade"]);
+}
+
+#--- utility
+
+sub is_valid_key {
+    my $thing = shift;
+    my $r     = MT->request;
+    unless ($r->stash('MT::Plugin::TypePadAntiSpam::api_key')) {
+        my $key = $plugin->api_key || return;
+        $r->stash('MT::Plugin::TypePadAntiSpam::api_key', $key);
+    }
+    $r->stash('MT::Plugin::TypePadAntiSpam::api_key');
+}
+
+sub require_tpas {
+    my $plugin = shift;
+    require MT::TypePadAntiSpam;
+
+    my $host = $plugin->get_config_value('service_host');
+    if ($host) {
+        $MT::TypePadAntiSpam::SERVICE_HOST = $host;
+    }
+}
+
+sub package_signature {
+    my $thing = shift;
+    my ($include_referrer) = @_;
+    my $sig   = MT::TypePadAntiSpam::Signature->new;
+    if ($include_referrer) {
+        $sig->user_agent($ENV{HTTP_USER_AGENT});
+        $sig->referrer($ENV{HTTP_REFERER});
+    }
+    $sig->user_ip($thing->ip);
+    $sig->blog(cache('B' . $thing->blog_id));
+    if (ref $thing eq 'MT::Comment') {
+        my $entry = $thing->entry;
+        $sig->article_date(MT->version_number < 4 ? $entry->created_on : $entry->authored_on);
+        $sig->permalink($entry->permalink);
+        $sig->comment_type('comment');
+        $sig->comment_author($thing->author);
+        $sig->comment_author_email($thing->email);
+        $sig->comment_author_url($thing->url);
+        $sig->comment_content($thing->text);
+    } elsif (ref $thing eq 'MT::TBPing') {
+        my $p = $thing->parent;
+        if ($p->isa('MT::Entry')) {
+            $sig->article_date(MT->version_number < 4 ? $p->created_on : $p->authored_on);
+            $sig->permalink($p->permalink);
+        }
+        $sig->comment_type('trackback');
+        $sig->comment_author($thing->blog_name);
+        $sig->comment_author_url($thing->source_url);
+        $sig->comment_content(join "\n", $thing->title, $thing->excerpt);
+    } else {
+        return;    # don't know what this is.
+    }
+    $sig;
+}
+
+sub cache {
+    my $id    = shift;
+    my $cache = MT->request->stash('MT::Plugin::TypePadAntiSpam::permalinks');
+    unless ($cache) {
+        $cache = {};
+        MT->request->stash('MT::Plugin::TypePadAntiSpam::permalinks', $cache);
+    }
+    unless ($cache->{$id}) {
+        if ($id =~ /^B/) {
+            my $b = MT::Blog->load(substr($id, 1)) or return;
+            $cache->{$id} = $b->site_url;
+        } else {
+            require MT::Entry;
+            my $e = MT::Entry->load($id) or return;
+            $cache->{$id} = $e->permalink;
+        }
+    }
+    $cache->{$id};
+}
+
+sub api_key {
+    my $plugin = shift;
+    my $blog = shift;
+    if (@_) {
+        my $key = shift;
+        $plugin->set_config_value('api_key', $key);
+    } else {
+        return $plugin->get_config_value('api_key');
+    }
+}
+
+sub blocked {
+    my $plugin = shift;
+    my $blog = shift;
+    my $blog_id = (ref($blog) && $blog->isa('MT::Blog')) ? $blog->id : $blog;
+    my $blocked = $plugin->get_config_value('blocked', $blog_id ? 'blog:' . $blog_id : 'system');
+    return $blocked || 0 unless @_;
+    my ($count) = @_;
+    $plugin->set_config_value('blocked', $count, $blog_id ? 'blog:' . $blog_id : 'system');
+    return $count;
+}
+
+1;
Index: /branches/release-39/build/mt-dists/default.mk
===================================================================
--- /branches/release-39/build/mt-dists/default.mk (revision 2370)
+++ /branches/release-39/build/mt-dists/default.mk (revision 2461)
@@ -1,7 +1,7 @@
 PRODUCT_NAME = Movable Type Core
 
-PRODUCT_VERSION = 4.15
+PRODUCT_VERSION = 4.2
 SCHEMA_VERSION = 4.0062
-API_VERSION = 4.15
+API_VERSION = 4.2
 
 # BUILD_LANGUAGE = en_US
