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-02-25 10:25 am

[dw-free] Allow importing of your journal from another LiveJournal-based site.

[commit: http://hg.dwscoalition.org/dw-free/rev/821e7159136b]

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

More work on the importer. Enable importing friend groups, friends, and
entries. This is still very experimental and needs a way to bubble up
errors to the user.

Patch by [staff profile] mark.

--------------------------------------------------------------------------------
diff -r 913ec83595d8 -r 821e7159136b bin/upgrading/update-db-general.pl
--- a/bin/upgrading/update-db-general.pl	Tue Feb 24 09:09:34 2009 +0000
+++ b/bin/upgrading/update-db-general.pl	Wed Feb 25 10:25:53 2009 +0000
@@ -3008,6 +3008,21 @@ CREATE TABLE import_data (
 )
 EOC
 
+# we don't store this in userprops because we need to index this
+# backwards and load it easily...
+register_tablecreate("import_usermap", <<'EOC');
+CREATE TABLE import_usermap (
+    hostname VARCHAR(255),
+    username VARCHAR(255),
+    identity_userid INT UNSIGNED,
+    feed_userid INT UNSIGNED,
+
+    PRIMARY KEY (hostname, username),
+    INDEX (identity_userid),
+    INDEX (feed_userid)
+)
+EOC
+
 # NOTE: new table declarations go ABOVE here ;)
 
 
diff -r 913ec83595d8 -r 821e7159136b cgi-bin/DW/Worker/ContentImporter.pm
--- a/cgi-bin/DW/Worker/ContentImporter.pm	Tue Feb 24 09:09:34 2009 +0000
+++ b/cgi-bin/DW/Worker/ContentImporter.pm	Wed Feb 25 10:25:53 2009 +0000
@@ -83,91 +83,6 @@ sub merge_watch {
 }
 
 
-=head2 C<< $class->post_event( $user, $hashref, $event, $item_errors ) >>
-
-$event is a hashref representation of a single entry, with the following format:
-
-  {
-    subject => 'My Entry',
-    event => 'I DID STUFF!!!!!',
-    security => 'usemask',
-    allowmask => 1,
-
-    eventtime => 'yyyy-mm-dd hh:mm:ss',
-    props => {
-        heres_a_userprop => "there's a userprop",
-        and_another_little => "userprop",
-    }
-    key => 'some_uniqe_key', # generally the permalink to the old entry, otherwise something unique (across *all* import sources possible)
-    url => 'http://permalink.tld/', # permalink to the old entry
-  }
-
-$item_errors is an arrayref of errors to be formatted nicely with a link to old and new entries.
-
-=cut
-sub post_event {
-    my ( $class, $u, $opts, $evt, $item_errors ) = @_;
-
-    return if $opts->{entry_map}->{$evt->{key}};
-
-    my ( $yr, $month, $day, $hr, $min, $sec ) = $evt->{eventtime} =~ m/([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})/;
-    my %proto = (
-        lineendings => 'unix',
-        subject => $evt->{subject},
-        event => $evt->{event},
-        security => $evt->{security},
-        allowmask => $evt->{allowmask},
-
-        year => $yr,
-        mon => $month,
-        day => $day,
-        hour => $hr,
-        min => $min,
-    );
-
-    my $props = $evt->{props};
-
-    # this is a list of props that actually exist on this site
-    # but have been shown to cause failures importing that entry.
-    my %bad_props = (
-        current_coords => 1,
-    );
-    foreach my $prop ( keys %$props ) {
-        my $p = LJ::get_prop( "log", $prop );
-
-        # skip over system and non-existant props
-        next unless $p;
-        next if ( $p->{ownership} eq 'system' );
-        next if ( $bad_props{$prop} );
-
-        $proto{"prop_$prop"} = $props->{$prop};
-    };
-
-    # Overwrite these here in case we're importing from an imported journal (hey, it could happen)
-    $proto{prop_opt_backdated} = '1';
-    $proto{prop_import_source} = $evt->{key};
-
-    my %res;
-    LJ::do_request({ 'mode' => 'postevent',
-                     'user' => $u->{'user'},
-                     'ver'  => $LJ::PROTOCOL_VER,
-                     %proto },
-                   \%res, { 'u' => $u,
-                            'noauth' => 1, });
-
-    my $errors = $opts->{errors};
-    if ( $res{success} eq 'FAIL' ) {
-        push @$errors, "Entry from $evt->{url}: $res{errmsg}";
-    } else {
-        my $itemid = $res{itemid};
-        $u->do( "UPDATE log2 SET logtime = ? where journalid = ? and jitemid = ?", undef, $evt->{realtime}, $u->userid, $itemid );
-        $opts->{entry_map}->{$evt->{key}} = $itemid;
-        foreach my $err ( @$item_errors ) {
-            push @$errors, "Entry at $res{url}: $err ( from $evt->{url} )";
-        }
-    }
-}
-
 =head2 C<< $class->post_event( $user, $hashref, $comment ) >>
 
 $event is a hashref representation of a single comment, with the following format:
@@ -228,31 +143,6 @@ sub insert_comment {
     my $jtalkid = LJ::Talk::Post::enter_imported_comment( $u, $parent, $item, $comment, $date, \$errref );
     return undef unless $jtalkid;
     return $jtalkid;
-}
-
-=head2 C<< $class->get_entry_map( $user, $hashref )
-
-Returns a hashref mapping import_source keys to jitemids
-
-=cut
-sub get_entry_map {
-    my ( $class, $u, $opts ) = @_;
-    return $opts->{entry_map} if $opts->{entry_map};
-
-    my $p = LJ::get_prop( "log", "import_source" );
-    return {} unless $p;
-
-    my $dbr = LJ::get_cluster_reader( $u );
-    my %map;
-    my $sth = $dbr->prepare( "SELECT jitemid, value FROM logprop2 WHERE journalid = ? AND propid = ?" );
-
-    $sth->execute( $u->id, $p->{id} );
-
-    while ( my ( $jitemid, $value ) = $sth->fetchrow_array ) {
-        $map{$value} = $jitemid;
-    }
-
-    return \%map;
 }
 
 =head2 C<< $class->get_comment_map( $user, $hashref )
@@ -389,4 +279,4 @@ sub ok {
 }
 
 
-1;
\ No newline at end of file
+1;
diff -r 913ec83595d8 -r 821e7159136b cgi-bin/DW/Worker/ContentImporter/LiveJournal.pm
--- a/cgi-bin/DW/Worker/ContentImporter/LiveJournal.pm	Tue Feb 24 09:09:34 2009 +0000
+++ b/cgi-bin/DW/Worker/ContentImporter/LiveJournal.pm	Wed Feb 25 10:25:53 2009 +0000
@@ -316,25 +316,56 @@ sub get_feed_account_from_url {
     return undef;
 }
 
+sub get_remapped_userids {
+    my ( $class, $data, $user ) = @_;
+
+    return @{ $MAPS{$data->{hostname}}->{$user} }
+        if exists $MAPS{$data->{hostname}}->{$user};
+
+    my $dbh = LJ::get_db_writer()
+        or return;
+    my ( $oid, $fid ) = $dbh->selectrow_array(
+        'SELECT identity_userid, feed_userid FROM import_usermap WHERE hostname = ? AND username = ?',
+        undef, $data->{hostname}, $user
+    );
+
+    unless ( defined $oid ) {
+        warn "[$$] Remapping identity userid of $data->{hostname}:$user\n";
+        $oid = $class->remap_username_friend( $data, $user );
+        warn "     IDENTITY USERID IS STILL UNDEFINED\n"
+            unless defined $oid;
+    }
+
+    unless ( defined $fid ) {
+        warn "[$$] Remapping feed userid of $data->{hostname}:$user\n";
+        $fid = $class->remap_username_feed( $data, $user );
+        warn "     FEED USERID IS STILL UNDEFINED\n"
+            unless defined $fid;
+    }
+
+    $dbh->do( 'REPLACE INTO import_usermap (hostname, username, identity_userid, feed_userid) VALUES (?, ?, ?, ?)',
+              undef, $data->{hostname}, $user, $oid, $fid );
+    $MAPS{$data->{hostname}}->{$user} = [ $oid, $fid ];
+
+    return ( $oid, $fid );
+}
+
 sub remap_username_feed {
     my ( $class, $data, $username ) = @_;
 
     # canonicalize username and try to return
     $username =~ s/-/_/g;
-    return $MAPS{feed_map}->{$username}
-        if defined $MAPS{feed_map}->{$username};
 
     # don't allow identity accounts (they're not feeds by default)
     return undef
         if $username =~ m/^ext_/;
 
     # fall back to getting it from the ATOM data
-    my $url = "http://$data->{hostname}/~$username/data/atom";
+    my $url = "http://www.$data->{hostname}/~$username/data/atom";
     my $acct = $class->get_feed_account_from_url( $data, $url, $username )
         or return undef;
 
-    # store it and return
-    return $MAPS{feed_map}->{$username} = $acct;
+    return $acct;
 }
 
 sub remap_username_friend {
@@ -343,9 +374,6 @@ sub remap_username_friend {
     # canonicalize username, in case they gave us a URL version, convert it to
     # the one we know sites use
     $username =~ s/-/_/g;
-
-    return $MAPS{friend_map}->{$username}
-        if defined $MAPS{friend_map}->{$username};
 
     if ( $username =~ m/^ext_/ ) {
         my $ua = LJ::get_useragent(
@@ -366,35 +394,33 @@ sub remap_username_friend {
         if ( $url =~ m!http://(.+)\.$LJ::DOMAIN\/$! ) {
             # this appears to be a local user!
             # Map this to the local userid in feed_map too, as this is a local user.
-            my $luid = LJ::User->new_from_url( $url )->id;
-            $MAPS{feed_map}->{$username} = $luid;
-            return $luid;
+            return LJ::User->new_from_url( $url )->id;
         }
 
         my $iu = LJ::User::load_identity_user( 'O', $url, undef )
             or return undef;
-        $MAPS{friend_map}->{$username} = $iu->userid;
+        return $iu->id;
 
     } else {
         my $url_prefix = "http://$data->{hostname}/~" . $username;
         my ( $foaf_items ) = $class->get_foaf_from( $url_prefix )
             or return undef;
 
+        # if they don't have an identity section (but foaf was successful
+        # or we would have returned undef above), then they are a community
+        # or some other account without.  return 0 to signify this.
         my $ident = $foaf_items->{identity}->{url}
-            or return undef;
-        $MAPS{ident_map}->{$username} = $ident;
+            or return 0;
 
         my $iu = LJ::User::load_identity_user( 'O', $ident, undef )
             or return undef;
-        $MAPS{friend_map}->{$username} = $iu->userid;
+        return $iu->id;
     }
-
-    return $MAPS{friend_map}->{$username};
 }
 
 sub remap_lj_user {
-    my ( $class, $server, $event ) = @_;
-    $event =~ s/(<lj.+?(user|comm|syn)=["']?(.+?)["' ]?>)/<lj site="$server" $2="$3">/gi;
+    my ( $class, $data, $event ) = @_;
+    $event =~ s/(<lj.+?(user|comm|syn)=["']?(.+?)["' ]?>)/<lj site="$data->{hostname}" $2="$3">/gi;
     return $event;
 }
 
@@ -422,6 +448,7 @@ sub xmlrpc_call_helper {
     my $res;
     eval { $res = $xmlrpc->call($method, $req); };
     if ( $res && $res->fault ) {
+        warn "XMLRPC fault: " . join( ', ', map { "$_:" . $res->fault->{$_} } keys %{$res->fault || {}} ) . "\n";
         return { fault => 1 };
     }
 
diff -r 913ec83595d8 -r 821e7159136b cgi-bin/DW/Worker/ContentImporter/LiveJournal/Bio.pm
--- a/cgi-bin/DW/Worker/ContentImporter/LiveJournal/Bio.pm	Tue Feb 24 09:09:34 2009 +0000
+++ b/cgi-bin/DW/Worker/ContentImporter/LiveJournal/Bio.pm	Wed Feb 25 10:25:53 2009 +0000
@@ -60,7 +60,7 @@ sub try_work {
 
     DW::Worker::ContentImporter::Local::Bio->merge_interests( $u, $interests );
 
-    $items->{bio} = $class->remap_lj_user( $data->{hostname}, $items->{bio} );
+    $items->{bio} = $class->remap_lj_user( $data, $items->{bio} );
     DW::Worker::ContentImporter::Local::Bio->merge_bio_items( $u, $items );
 
     return $ok->();
diff -r 913ec83595d8 -r 821e7159136b cgi-bin/DW/Worker/ContentImporter/LiveJournal/Entries.pm
--- a/cgi-bin/DW/Worker/ContentImporter/LiveJournal/Entries.pm	Tue Feb 24 09:09:34 2009 +0000
+++ b/cgi-bin/DW/Worker/ContentImporter/LiveJournal/Entries.pm	Wed Feb 25 10:25:53 2009 +0000
@@ -45,30 +45,24 @@ sub try_work {
     # setup
     my $u = LJ::load_userid( $data->{userid} )
         or return $fail->( 'Unable to load target with id %d.', $data->{userid} );
+    my $entry_map = DW::Worker::ContentImporter::Local::Entries->get_entry_map( $u );
 
-    # temporary failure, this code hasn't been ported yet
-    return $fail->( 'oops, not ready yet' );
-}
-
-1;
-__END__
-
-### WORK GOES HERE
-    $opts->{entry_map} = DW::Worker::ContentImporter->get_entry_map($u,$opts);
-    my $synccount = 0;
-    my $lastsync = 0;
-    my %sync;
-    while (1) {
-        DW::Worker::ContentImporter->ratelimit_request( $opts );
-        my $hash = call_xmlrpc( $opts, 'syncitems', {lastsync => $lastsync} );
+    # load the syncitems list; but never try to load the same lastsync time twice, just
+    # in case 
+    my ( $lastsync, %tried_syncs, %sync );
+    while ( $tried_syncs{$lastsync} < 2 ) {
+        warn "[$$] Attempting lastsync = " . ( $lastsync || 'undef' ) . "\n";
+        my $hash = $class->call_xmlrpc( $data, 'syncitems', { lastsync => $lastsync } );
 
         foreach my $item ( @{$hash->{syncitems} || []} ) {
-            next unless $item->{item} =~ /L-(\d+)/;
-            $synccount++;
+            next unless $item->{item} =~ /^L-(\d+)$/;
             $sync{$1} = [ $item->{action}, $item->{time} ];
-            $lastsync = $item->{time} if $item->{'time'} gt $lastsync;
+            $lastsync = $item->{time}
+                if !defined $lastsync || $item->{time} gt $lastsync;
+            $tried_syncs{$lastsync}++;
         }
 
+        warn "     count $hash->{count} == total $hash->{total}\n";
         last if $hash->{count} == $hash->{total};
     }
 
@@ -77,30 +71,44 @@ __END__
         return $sync{$id}->[1] if @{$sync{$id} || []};
     };
 
-    my $lastgrab = 0;
-    while (1) {
+    # now get the actual events
+    while ( scalar( keys %sync ) > 0 ) {
         my $count = 0;
-        DW::Worker::ContentImporter->ratelimit_request( $opts );
-        my $hash = call_xmlrpc( $opts, 'getevents', { selecttype => 'syncitems', lastsync => $lastgrab, ver => 1, lineendings => 'unix', });
+
+        # calculate what time to get entries for
+        my @keys = sort { $sync{$a}->[1] cmp $sync{$b}->[1] } keys %sync;
+        my $lastgrab = LJ::mysql_time( LJ::mysqldate_to_time( $sync{$keys[0]}->[1] ) - 1 );
+
+        warn "[$$] Fetching from lastsync = $lastgrab forward\n";
+        my $hash = $class->call_xmlrpc( $data, 'getevents',
+            {
+                ver         => 1,
+                lastsync    => $lastgrab,
+                selecttype  => 'syncitems',
+                lineendings => 'unix',
+            }
+        );
 
         foreach my $evt ( @{$hash->{events} || []} ) {
             $count++;
+
             $evt->{realtime} = $realtime->( $evt->{itemid} );
-            $lastgrab = $evt->{realtime} if $evt->{realtime} gt $lastgrab;
             $evt->{key} = $evt->{url};
 
             # skip this if we've already dealt with it before
-            next if $opts->{entry_map}->{$evt->{key}};
+            warn "     [$evt->{itemid}] $evt->{url} // $evt->{realtime} // map=$entry_map->{$evt->{key}}\n";
+            my $sync = delete $sync{$evt->{itemid}};
+            next if $entry_map->{$evt->{key}} || !defined $sync;
+
             # clean up event for LJ
-
             my @item_errors;
 
             # remap friend groups
             my $allowmask = $evt->{allowmask};
-            my $newmask = remap_groupmask( $opts, $allowmask );
+            my $newmask = $class->remap_groupmask( $data, $allowmask );
 
-            # Bah. Assume private. This shouldn't relaly happen, but
-            # a good sanity check.
+            # if we are unable to determine a good groupmask, then fall back to making
+            # the entry private and mark the error.
             if ( $allowmask != 1 && $newmask == 1 ) { 
                 $newmask = 0;
                 push @item_errors, "Could not determine groups.";
@@ -128,19 +136,26 @@ __END__
                 push @item_errors, "Entry contained a template tag, please manually re-add the templated content.";
             }
 
-            $evt->{event} = remap_lj_user( $opts, $event );
+            $evt->{event} = $class->remap_lj_user( $data, $event );
 
             # actually post it
-            DW::Worker::ContentImporter->post_event( $u, $opts, $evt, \@item_errors );
+            my $res = DW::Worker::ContentImporter::Local::Entries->post_event( $data, $entry_map, $u, $evt, \@item_errors );
+
+# FIXME: do something with the return code and @item_errors ... other than
+# printing them to STDERR of course ...
+            if ( $res ) {
+                warn "     imported!\n";
+            }  else {
+                warn "     failed!\n";
+            }
+            warn "       $_\n" foreach @item_errors;
         }
 
-        last unless $count && $lastgrab;
+        warn "     count = $count && lastgrab = $lastgrab\n";
     }
-
-    $opts->{no_entries} = 1;
 
     return $ok->();
 }
 
 
-1;
\ No newline at end of file
+1;
diff -r 913ec83595d8 -r 821e7159136b cgi-bin/DW/Worker/ContentImporter/LiveJournal/Friends.pm
--- a/cgi-bin/DW/Worker/ContentImporter/LiveJournal/Friends.pm	Tue Feb 24 09:09:34 2009 +0000
+++ b/cgi-bin/DW/Worker/ContentImporter/LiveJournal/Friends.pm	Wed Feb 25 10:25:53 2009 +0000
@@ -51,23 +51,31 @@ sub try_work {
 
     my ( @friends, @feeds );
     foreach my $friend (@{ $r->{friends} || [] }) {
-        my $local_userid = $class->remap_username_friend( $data, $friend->{username} );
+        my ( $local_oid, $local_fid ) = $class->get_remapped_userids( $data, $friend->{username} );
+
         push @friends, {
-            userid => $local_userid,
+            userid => $local_oid,
             groupmask => $class->remap_groupmask( $data, $friend->{groupmask} ),
-        } if $local_userid;
+        } if $local_oid;
 
-        $local_userid = $class->remap_username_feed( $data, $friend->{username} );
         push @feeds, {
             fgcolor => $friend->{fgcolor},
             bgcolor => $friend->{bgcolor},
-            userid => $local_userid,
-        } if $local_userid;
+            userid => $local_fid,
+        } if $local_fid;
     }
 
     DW::Worker::ContentImporter->merge_trust( $u, $opts, \@friends );
     DW::Worker::ContentImporter->merge_watch( $u, $opts, \@feeds );
 
+    # schedule events import
+    my $dbh = LJ::get_db_writer();
+    $dbh->do(
+        q{UPDATE import_items SET status = 'ready'
+          WHERE userid = ? AND item = 'lj_entries' AND import_data_id = ? AND status = 'init'},
+        undef, $u->id, $opts->{import_data_id}        
+    );
+
     return $ok->();
 }
 
diff -r 913ec83595d8 -r 821e7159136b cgi-bin/DW/Worker/ContentImporter/Local/Entries.pm
--- a/cgi-bin/DW/Worker/ContentImporter/Local/Entries.pm	Tue Feb 24 09:09:34 2009 +0000
+++ b/cgi-bin/DW/Worker/ContentImporter/Local/Entries.pm	Wed Feb 25 10:25:53 2009 +0000
@@ -26,7 +26,135 @@ DW::Worker::ContentImporter::Local::Entr
 
 These functions are part of the Saving API for entries.
 
+=head2 C<< $class->get_entry_map( $user, $hashref )
+
+Returns a hashref mapping import_source keys to jitemids
+
 =cut
 
+sub get_entry_map {
+    my ( $class, $u ) = @_;
 
-1;
\ No newline at end of file
+    my $p = LJ::get_prop( "log", "import_source" );
+    return {} unless $p;
+
+    my $dbr = LJ::get_cluster_reader( $u );
+    my %map;
+    my $sth = $dbr->prepare( "SELECT jitemid, value FROM logprop2 WHERE journalid = ? AND propid = ?" );
+
+    $sth->execute( $u->id, $p->{id} );
+
+    while ( my ( $jitemid, $value ) = $sth->fetchrow_array ) {
+        $map{$value} = $jitemid;
+    }
+
+    return \%map;
+}
+
+=head2 C<< $class->post_event( $hashref, $u, $event, $item_errors ) >>
+
+$event is a hashref representation of a single entry, with the following format:
+
+  {
+    # standard event values
+    subject => 'My Entry',
+    event => 'I DID STUFF!!!!!',
+    security => 'usemask',
+    allowmask => 1,
+    eventtime => 'yyyy-mm-dd hh:mm:ss',
+    props => {
+        heres_a_userprop => "there's a userprop",
+        and_another_little => "userprop",
+    }
+
+    # the key is a uniquely opaque string that identifies this entry.  this must be
+    # unique across all possible import sources.  the permalink may work best.
+    key => 'some_unique_key',
+
+    # a url to this entry's original location
+    url => 'http://permalink.tld/',
+  }
+
+$item_errors is an arrayref of errors to be formatted nicely with a link to old and new entries.
+
+Returns 1 on success, undef on error.
+
+=cut
+
+sub post_event {
+    my ( $class, $data, $map, $u, $evt, $errors ) = @_;
+
+    return if $map->{$evt->{key}};
+
+    my ( $yr, $month, $day, $hr, $min, $sec ) = ( $1, $2, $3, $4, $5, $6 )
+        if $evt->{eventtime} =~ m/(\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)/;
+
+    my %proto = (
+        lineendings => 'unix',
+        subject => $evt->{subject},
+        event => $evt->{event},
+        security => $evt->{security},
+        allowmask => $evt->{allowmask},
+
+        year => $yr,
+        mon => $month,
+        day => $day,
+        hour => $hr,
+        min => $min,
+    );
+
+    my $props = $evt->{props};
+
+    # this is a list of props that actually exist on this site
+    # but have been shown to cause failures importing that entry.
+    my %bad_props = (
+        current_coords => 1,
+        personifi_word_count => 1,
+        personifi_lang => 1,
+    );
+    foreach my $prop ( keys %$props ) {
+        next if $bad_props{$prop};
+
+        my $p = LJ::get_prop( "log", $prop )
+            or next;
+        next if $p->{ownership} eq 'system';
+
+        $proto{"prop_$prop"} = $props->{$prop};
+    };
+
+    # Overwrite these here in case we're importing from an imported journal (hey, it could happen)
+    $proto{prop_opt_backdated} = '1';
+    $proto{prop_import_source} = $evt->{key};
+
+    my %res;
+    LJ::do_request(
+        {
+            mode => 'postevent',
+            user => $u->user,
+            ver  => $LJ::PROTOCOL_VER,
+            %proto,
+        },
+        \%res,
+        {
+            u => $u,
+            noauth => 1,
+        }
+    );
+
+    if ( $res{success} eq 'FAIL' ) {
+        push @$errors, "Entry from $evt->{url}: $res{errmsg}";
+        return undef;
+
+    } else {
+        $u->do( "UPDATE log2 SET logtime = ? where journalid = ? and jitemid = ?",
+                undef, $evt->{realtime}, $u->userid, $res{itemid} );
+        $map->{$evt->{key}} = $res{itemid};
+        return 1;
+
+    }
+
+    # flow will never get here
+}
+
+
+1;
diff -r 913ec83595d8 -r 821e7159136b htdocs/misc/import.bml
--- a/htdocs/misc/import.bml	Tue Feb 24 09:09:34 2009 +0000
+++ b/htdocs/misc/import.bml	Wed Feb 25 10:25:53 2009 +0000
@@ -63,11 +63,15 @@ body<=
             ['lj_userpics', 'ready'],
             ['lj_bio', 'ready'],
             ['lj_tags', 'ready'],
+            ['lj_friendgroups', 'ready'],
+            ['lj_friends', 'init'],
+            ['lj_entries', 'init'],
         );
         # schedule userpic, bio, and tag imports
         foreach my $item (@jobs) {
             $dbh->do(
-                "INSERT INTO import_items (userid, item, status, created, import_data_id, priority) VALUES (?, ?, ?, UNIX_TIMESTAMP(), ?, UNIX_TIMESTAMP())",
+                "INSERT INTO import_items (userid, item, status, created, import_data_id, priority) " .
+                "VALUES (?, ?, ?, UNIX_TIMESTAMP(), ?, UNIX_TIMESTAMP())",
                 undef, $u->id, $item->[0], $item->[1], $id
             );
             return "Database error." if $dbh->err;
@@ -80,7 +84,8 @@ body<=
     my $dbh = LJ::get_db_writer()
         or return "No database.";
     my $imps = $dbh->selectall_arrayref(
-        'SELECT import_data_id, hostname, username, password_md5 FROM import_data WHERE userid = ? ORDER BY import_data_id DESC LIMIT 10',
+        'SELECT import_data_id, hostname, username, password_md5 FROM import_data WHERE userid = ? ' .
+        'ORDER BY import_data_id DESC LIMIT 3',
         undef, $u->id
     );
 
@@ -109,7 +114,7 @@ body<=
         foreach my $impid ( sort { $b <=> $a } keys %s ) {
             my $h = $s{$impid};
             $ret .= "<tr><td colspan='4'>&nbsp;</td></tr>";
-            $ret .= "<tr><td colspan='4' style='background-color: #cccccc;'>$refresh <strong>$h->{host}</strong> | $h->{user} | $h->{pw}</td></tr>";
+            $ret .= "<tr><td colspan='4' style='background-color: #cccccc;'>$refresh <strong>$h->{host}</strong> | $h->{user}</td></tr>";
             foreach my $item ( sort keys %{$h->{items}} ) {
                 my $i = $h->{items}->{$item};
                 $ret .= "<tr><td><em>$item</em></td>";
@@ -132,7 +137,8 @@ body<=
     $ret .= "<select name='hostname'><option value='livejournal.com'>LiveJournal.com</option></select><br />";
     $ret .= "<br />";
     $ret .= "Clicking submit below will cause import jobs to be queued to import your userpics, your ";
-    $ret .= "tags, and your bio fields.  You can check this page for status.";
+    $ret .= "tags, and your bio fields.  You can check this page for status.<br />";
+    $ret .= "<strong>This option now imports your friend groups, friends, and entries.</strong><br />";
     $ret .= "<input type='submit' value='Do it!'></form>";
     return $ret;
 }
--------------------------------------------------------------------------------

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