Name
E2 autonoder
Purpose
To make autonoding faster, easier, more portable and generally more feasible, to lessen pointless cut-and-pasting, in hopes that saved time will be spent writing bad poetry and guides to how to get laid (hint hint).
Justification
Why write this, when there already are at least 3 autonoders (jes-whatever/novalis's, JeffMagnus', rescdsk's) in existence? Well, for the latter two, they aren't published. I don't believe in security through obscurity... and as for first one, honestly, lynx isn't really the way to do it. Advantages this one has to e2auto.pl:
  1. Faster (downloads don't need get finished... although I should add /<html>/ after the second read, ah well)
  2. More portable (there isn't lynx in win32)
  3. More reliable (lynx and persistent cookies are bane all around... Eraser_ for one couldn't make it work)
  4. More functional (the previous one seemed to break under certain conditions
  5. Easier to find with search box (E2 seems to have real problems handling '.' with searches...)
  6. Doesn't overwiden the node window with too long lines and <pre>-tags ok, ok, I'll shut up now, was just a bit disappointed...
Usage
Get the source, save it, mangle to make it usable if necessary (see E2 node tracker for more instructions, I'm too tired to copy them here right now), run "./autonode.pl filename" where filename is name of file containing node data. Log in, and cry out in joy as E2 grows.
To-do
  • Configurability
  • Noding in alphabetic order instead of random perl internal hash order
  • Faster 2nd download
  • Option to allow some nodes enter ENN ('*' in front of type, for example)
... as you can see, most are trivial, expect new version shortly, I suppose...
Source, version 0.1 (initial public release, seems to work):

#!/usr/bin/perl -w

$sleep=5;

use Socket;
use CGI qw(escape);

if (!@ARGV) {
    print <<EOT
Usage: $0 <nodefile>

Syntax for nodefile:

name
type
body text
body text
...
----
name
type
body text
body text
...
----

name: name of node, as you would write it in search box.
type: person/place/idea/thing
EOT
;
    exit;
}

$|++;

print "Username: ";
$username=<STDIN>;
chomp $username;
system "stty", "-echo";
print "Password: ";
$userpass=<STDIN>;
chomp($userpass);
system "stty", "echo";
print "\n";  # Need this, since user's return won't be echoed

open(FILE,$ARGV[0]) or die "can't open nodefile!";
while (<FILE>) {
    chomp;
    $title=$_;
    $type=<FILE>;
    chomp $type;
    if ($type =~ m/(person|place|idea|thing)/) {
        $type=$1;
    } else {
        print "invalid type: $type\n";
        exit;
    }
    $text="";
    while ((defined ($a=<FILE>)) && ($a ne "----\n")) {
        $text.="$a";
    }
    chomp $text;
    $node{$title}=[$type,$text];
}
close(FILE);

print "Logging in... ";
consock(SOCK,"everything2.com",80) or die "can't connect!";
hotfh(SOCK);
print "connected. sending... ";
print SOCK
"GET /?op=login&node_id=109&lastnode_id=0&user=$username&".
"passwd=$userpass HTTP/1.0\r\n\r\n";
print "sent. reading... ";
while (<SOCK>) {
    if (/Set-Cookie: userpass=(.*?); /mi) {
        $cookie=$1;
        last;
        }
}
close(SOCK);
die "couldn't log in!" if !$cookie;
print "read.\nCookie: $cookie\n";

for $i (keys %node) {
    my $content;
    my $name=escape($i);
    my $body=escape($node{$i}[1]);
    my $node_id;
    my $type=$node{$i}[0];
    
    $content="node=$name&op=new&type=e2node";

    print "creating nodeshell for [$i] (if not already created)... ";
    consock(SOCK,"everything2.com",80) or die "can't connect";
    hotfh(SOCK) or die "can't unblock";
    
    print "connected. sending... ";

        print SOCK
"POST / HTTP/1.0\r\nCookie: userpass=$cookie\r\n".
"Content-length: ".(length $content)."\r\n\r\n$content\r\n";
        
        print "sent. reading... ";
            
    while (<SOCK>) {
        if (/<A HREF="\/index.pl\?node_id=\d+&lastnode_id=(\d+)">/i) {
            $node_id=$1;
            last;
        }
    }
    close(SOCK);
    
    print "done.\n";
    if (!$node_id) {
        print "Couldn't find node_id! Something is wrong.\n";
        exit;
    }
    print "node_id: $node_id\n";
    print "Creating writeup for [$i] ... ";
    consock(SOCK,"everything2.com",80) or die "can't connect";
    hotfh(SOCK) or die "can't unblock";
    
    $content="node=new+writeup&".
         "op=new&".
         "type=writeup&".
         "node=$node_id".
         "&writeup_notnew=1&".
         "writeup_doctext=$body&".
         "writeup_parent_e2node=$node_id&".
         "writeuptype-$type.x=0&".
         "writeuptype-$type.y=0";
    
    print "sending... ";
    print SOCK
"POST / HTTP/1.0\r\nCookie: userpass=$cookie\r\n".
"Content-length: ".(length $content)."\r\n\r\n$content\r\n";
    print "sent. reading... ";
    while (<SOCK>) { }
    print "done. It should be created! Sleeping for $sleep seconds now.\n";
    sleep($sleep);
}


sub hotfh {
        my $ofh;
        $ofh = select $_[0];
        $|++;
        select $ofh;
}

sub consock {
# SYNTAX: consock(filehandle, address, port)
        my ($remote, $port, $iaddr, $paddr, $proto, $fh, $sval);
        $fh = $_[0];
        $remote = $_[1];
        $port = $_[2];
        if (!($iaddr = inet_aton($remote))) {
                return;
        }
        $paddr = sockaddr_in($port, $iaddr);
        $proto = getprotobyname('tcp');
        socket($fh, PF_INET, SOCK_STREAM, $proto);

        $sval = connect($fh, $paddr);
        return $sval;
}

P.S. some people never learn...