mark: A photo of Mark kneeling on top of the Taal Volcano in the Philippines. It was a long hike. (Default)
Mark Smith ([staff profile] mark) wrote in [site community profile] changelog2009-03-07 07:33 am

[dw-free] update LJ::SpellCheck to work in Apache2

[commit: http://hg.dwscoalition.org/dw-free/rev/0a54348c7df8]

http://bugs.dwscoalition.org/show_bug.cgi?id=307

Update spellchecker to work with Apache2.

Patch by [personal profile] afuna.

Files modified:
  • cgi-bin/DW/Request/Apache2.pm
  • cgi-bin/LJ/SpellCheck.pm
  • etc/config.pl
--------------------------------------------------------------------------------
diff -r 4d05067f5b2e -r 0a54348c7df8 cgi-bin/DW/Request/Apache2.pm
--- a/cgi-bin/DW/Request/Apache2.pm	Sat Mar 07 07:29:39 2009 +0000
+++ b/cgi-bin/DW/Request/Apache2.pm	Sat Mar 07 07:32:58 2009 +0000
@@ -25,6 +25,7 @@ use Apache2::RequestRec ();
 use Apache2::RequestRec ();
 use Apache2::RequestUtil ();
 use Apache2::RequestIO ();
+use Apache2::SubProcess ();
 
 use fields (
             'r',         # The Apache2::Request object
@@ -171,4 +172,10 @@ sub OK {
     return Apache2::Const::OK;
 }
 
+# spawn a process for an external program
+sub spawn {
+    my DW::Request::Apache2 $self = shift;
+    return $self->{r}->spawn_proc_prog( @_ );
+}
+
 1;
diff -r 4d05067f5b2e -r 0a54348c7df8 cgi-bin/LJ/SpellCheck.pm
--- a/cgi-bin/LJ/SpellCheck.pm	Sat Mar 07 07:29:39 2009 +0000
+++ b/cgi-bin/LJ/SpellCheck.pm	Sat Mar 07 07:32:58 2009 +0000
@@ -17,24 +17,35 @@ package LJ::SpellCheck;
 package LJ::SpellCheck;
 
 use strict;
-use FileHandle;
-use IPC::Open2;
-use POSIX ":sys_wait_h";
+use warnings;
+
+use Config;
+use constant PERLIO_IS_ENABLED => $Config{useperlio};
 
 use vars qw($VERSION);
-$VERSION = '1.0';
+$VERSION = '2.0';
 
 # Good spellcommand values:
-#    ispell -a -h  (default)
-#    /usr/local/bin/aspell pipe -H --sug-mode=fast --ignore-case
+#    /usr/bin/ispell -a -h  
+#    /usr/bin/aspell pipe -H --sug-mode=fast --ignore-case
+#
+# Use the full path to the command, not just the command name.
+#
+# If you want to include an external dictionary containing site-specific
+# terms, you can add a "-p /path/to/dictionary" to the program arguments
 
 sub new {
     my ($class, $args) = @_;
     my $self = {};
     bless $self, ref $class || $class;
 
-    $self->{'command'} = $args->{'spellcommand'} || "ispell -a -h";
-    $self->{'color'} = $args->{'color'} || "#FF0000";
+    my $command = $args->{spellcommand} || "/usr/bin/aspell pipe -H --sug-mode=fast --ignore-case";
+    my @command_args = split /\s+/, $command;
+
+    $self->{command} = shift @command_args;
+    $self->{command_args} = \@command_args;
+
+    $self->{color} = $args->{color} || "#FF0000";
     return $self;
 }
 
@@ -45,24 +56,24 @@ sub check_html {
 sub check_html {
     my $self = shift;
     my $journal = shift;
+
+    my $r = DW::Request->get;
+    my ( $iwrite, $iread ) = $r->spawn( $self->{command}, $self->{command_args} );
     
-    my $iread = new FileHandle;
-    my $iwrite = new FileHandle;
-    my $ierr = new FileHandle;
-    my $pid;
+    my $read_data = sub {
+        my ($fh) = @_;
+        my $data;
+        $data = <$fh> if PERLIO_IS_ENABLED || IO::Select->new($fh)->can_read(10);
+        return defined $data ? $data : '';
+    };
 
-    # work-around for mod_perl
-    my $tie_stdin = tied *STDIN;
-    untie *STDIN if $tie_stdin;
+    # header from aspell/ispell
+    my $banner = $read_data->( $iread );
+    return "<?errorbar Spell checker not set up properly. banner=$banner errorbar?>" unless $banner =~ /^@\(#\)/;
 
-    $iwrite->autoflush(1);
+    # send the command to shell-escape
+    print $iwrite "!\n";
 
-    $pid = open2($iread, $iwrite, $self->{'command'}) || die "spell process failed";
-    die "Couldn't find spell checker\n" unless $pid;
-    my $banner = <$iread>;
-    die "banner=$banner\n" unless ($banner =~ /^@\(\#\)/);
-    print $iwrite "!\n";
-    
     my $output = "";
     my $footnotes = "";
     
@@ -76,7 +87,7 @@ sub check_html {
 	
 	my $idata;
 	do {
-	    $idata = <$iread>;
+	    $idata = $read_data->($iread);
 	    chomp($idata);
 	    
 	    if ($idata =~ /^& /) {
@@ -108,11 +119,7 @@ sub check_html {
 
     $iread->close;
     $iwrite->close;
- 
-    $pid = waitpid($pid, 0);
 
-    # return mod_perl to previous state, though not necessary?
-    tie *STDIN, $tie_stdin if $tie_stdin;
 
     return (($mscnt || $other_bad) ? "$output<p><b>Suggestions:</b><table cellpadding=3 border=0>$footnotes</table>" : "");
 }
@@ -147,7 +154,7 @@ The only method on the object is check_h
 
 =head1 BUGS
 
-Sometimes the opened spell process hangs and eats up tons of CPU.  Fixed now, though... I think.
+Version 1.0 had some logic to do a waitpid, I suspect to fix a problem where sometimes the opened spell process would and eats up tons of CPU. Because this calls aspell in another manner (doesn't return the PID and may not trigger the bug), the waitpid has been removed. If any issues crop up, revisit this.
 
 check_html returns HTML we like.  You may not.  :)
 
@@ -155,5 +162,5 @@ check_html returns HTML we like.  You ma
 
 Evan Martin, evan@livejournal.com
 Brad Fitzpatrick, bradfitz@livejournal.com
-
+Afuna, coder.dw@afunamatata.com
 =cut
diff -r 4d05067f5b2e -r 0a54348c7df8 etc/config.pl
--- a/etc/config.pl	Sat Mar 07 07:29:39 2009 +0000
+++ b/etc/config.pl	Sat Mar 07 07:32:58 2009 +0000
@@ -153,7 +153,7 @@
 
     # command-line to spell checker, or undefined if you don't want spell checking
     #$SPELLER = "/usr/local/bin/ispell -a";
-    #$SPELLER = "/usr/local/bin/aspell pipe --sug-mode=fast --ignore-case";
+    #$SPELLER = "/usr/bin/aspell pipe --mode=html --sug-mode=fast --ignore-case";
 
     # to save bandwidth, should we compress pages before they go out?
     # require Compress::Zlib to be installed
--------------------------------------------------------------------------------

Post a comment in response:

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org