#!/usr/bin/perl -w use strict; # Creating an archive of http://livejournal.com/users/.../friends/ # Written by Misha Verbitsky under GPL # "WITH FRIENDS LIKE THESE - WHO NEEDS ENEMIES?" # Takes a site provided by ljsm-strip.pl # (the stripped down version of ljsm by Sasha Nikolaev) # Parses the entries, creates a static version of # .../friends/ and the archives of individual users use Date::Manip qw(ParseDate UnixDate); my $MAXENT=35; # How many entries per page my $MEM_MAXENT=20; # Same for memory indexes my $PATH = "/LJ/"; # The main directory (locally on your Unix system) my $BAR_COLOR = "#8888AA"; # Horizontal bar color my $LENTA = "f"; my $HEADER="
2001-2002: Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec | Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | |
". $mbar . $FOOTER; $HEAD = $HEADER . $mbar . "
"; foreach (@monthly) { print "Entering $_ to make lenta...\n"; lj_dir ($_); } } ########################################################################## ########################################################################## # Copies all files to friends directory sub friends_copy { system "rm -rf /LJ/$LENTA" || warn "Cannot remove /LJ/$LENTA/: $!\n"; mkdir "$LENTA" || warn "Cannot create /LJ/$LENTA/: $!\n"; my @topdir = glob "*"; my @users = (); foreach (@topdir) { next if (! (-d $_)); next if ((! (-d "$_/2001")) && (! (-d "$_/2002"))); push (@users, $_); } # print "Users:"; print @users; my $year=0; my $month=0; foreach $year (2001..2002) { mkdir "$LENTA/$year" || warn "Cannot create /LJ/$LENTA/$year: $!\n"; foreach $month (1..12) { next if (($year == 2001) and ($month == 1)); next if (($year == 2002) and ($month > 10)); mkdir "$LENTA/$year/$month" || warn "Cannot create $LENTA/$year/$month: $!\n";; my $user=""; foreach $user (@users) { # Now copying all LJ-files from $user/$year/$month # to the lenta directory my $dir = "$user/$year/$month"; my @file_list = glob("$dir/*"); # print "All files in directory $user/$year/$month\n"; # print @file_list; my @files =(); my $file = ""; # Testing the files in file_list, adding them to @files if passed foreach $file (@file_list) { # print "Testing $file...\n"; next if (! (-f $file)); next if ($file =~ /index[0-9]*\.html/); push (@files, $file); } # List of files is found # print "list of files to make ljdir: "; print "@files\n"; foreach $file (@files) { system "cp -i $file $LENTA/$year/$month" || die "Couldn't copy $file to $LENTA/$year/$month: $!\n"; } } } } } sub friends_clean # Cleans the friends directory after lj_lenta is run { my $year=0; my $month=0; print "Cleaning the lenta dir ($LENTA)...\n"; foreach $year (2001..2002) { foreach $month (1..12) { my $dir = "$LENTA/$year/$month"; my @file_list = glob("$dir/*"); my $file = ""; foreach $file (@file_list) { # print "Testing $file...\n"; if (! ($file =~ /index[0-9]*\.html/)) { unlink $file || die "Cannot unlink $file: $!\n"; } } } } } ########################################################################## ########################################################################## # Subroutine lj_user # given a directory of LJ entries produced by ljsm-strip, # sets $HEAD and $FOOT files and runs lj_dir in all user's # directories # # The header/footer should contain the following. # 1. The links to LJ-archive pages (same for all pages of LJ-archive) # a). Introduction b). Lenta c). http://lj.eonline.ru/ (Anything else? Hm...) # We should also put reklama.cgi and :LENIN: logo to the footer # (the very bottom part). # 2. User-specific links: intro, archives, # index-ljsm.html, memories, monthly archives, LJ-userinfo, # adding the user to friend-list (Anything else? Hm...) # We should set the title "user's Livejournal archives - YYYY/MM" # and set the
header on top the same. sub lj_user { my $user = $_[0]; # Let's find all user's monthly directories my @monthly = glob ("$user/[0-9][0-9][0-9][0-9]/[0-9][0-9] $user/[0-9][0-9][0-9][0-9]/[0-9]"); my %months = (); # print "Monthly...\n"; print @monthly; foreach (@monthly) { if ((/\/(\d\d\d\d\/\d\d)/ || /\/(\d\d\d\d\/\d)/) && (-d $_)) { $months{$1}=1; # print "Directory $1 found...\n"; } } # print "Months...\n"; # print map { "$_ => $months{$_}\n" } keys %months; # Now make the user's personal bar my @userbar= ( "
[ \u$user\'s Livejournal
| info
|
Add this user | Архивы \u$user |
Оглавление | ");
push (@userbar, (-d "$user/memories") ?
" memories ] " : " memories ] "); my $year=2001; my $month=0; foreach $month (2..12) { my $monthyear = ""; $monthyear = $year."/".$month; if (defined ($months{$monthyear})) { push (@userbar, " $month | ") } else{ push (@userbar, " $month | "); } } push (@userbar, " "); $year=2002; foreach $month (1..10) { my $monthyear = ""; $monthyear = $year."/".$month; if (defined ($months{$monthyear})) { push (@userbar, " $month | ") } else{ push (@userbar, " $month | "); } } push (@userbar, " |
". join("\n", @userbar). $FOOTER; $HEAD = $HEADER . join("\n", @userbar) . "
";
$HEAD =~s/Livejournal.com \(02.2001/Livejournal.com \(\u$user:<\/a> 02.2001/;
open (HDR, ">$user/.header") ||
die ("couldn't open $user/.header: $!");
print HDR $HEAD ||
die ("couldn't write to $user/.header: $!");
close (HDR) || die ("couldn't close $user/.header: $!");
open (FTR, ">$user/.footer") ||
die ("couldn't open $user/.footer: $!");
print FTR $FOOT ||
die ("couldn't write to $user/.footer: $!");
close (FTR) || die ("couldn't close $user/.footer: $!");
# The userbar is done! Now for the directories
foreach (@monthly)
{
# print "Entering $_...";
lj_dir ($_);
}
my $MAXENT_orig = $MAXENT; $MAXENT = $MEM_MAXENT;
lj_dir ("$user/memories") if (-d "$user/memories");
$MAXENT = $MAXENT_orig;
}
##########################################################################
##########################################################################
# Subroutine lj_dir
# 1. Reads all files in a given directory
# containing
# 2. parses the files, extracting mood,
# music, number of comments, picture, date
# 3. Creates index files with $MAXENT entries, sequentially.
sub lj_dir
{
my $dir=$_[0];
my @file_list = glob("$dir/*");
my @files =();
my $file = "";
# Testing the files in file_list, adding them to @files if passed
foreach $file (@file_list)
{
next if (! (-f $file));
next if ($file =~ /index[0-9]*\.html/);
open (FILE, "< $file") || die ("couldn't open $file: $!\n");
while ( ");
# print "Processing $monthline...\n";
my $table_tops = ($numindexes > 19) ?
"Записи $numentries ($monthline)
" : "Записи $numentries ($monthline)
";
unshift(@indices_bar,$table_tops);
# print "numindexes=$numindexes\n";
if ($numindexes >2)
{
push (@result, @indices_bar);
unshift (@result, @indices_bar);
}
push (@result, $FOOT);
unshift (@result, $HEAD);
# Now writing the file
my $indexname= "$dir/index" . "$index" . ".html";
open (INDEX, ">$indexname") ||
die ("couldn't open $indexname");
print INDEX "@result "
|| die ("couldn't write to $indexname");
close (INDEX) || die ("couldn't close $indexname");
}
if (-l "$dir/index.html")
{
unlink("$dir/index.html") || warn "couldn't unlink $dir/index.html";
}
# print "Symlinking $dir/index1.html to $dir/index.html...\n";
symlink("index1.html" ,"$dir/index.html") || warn "couldn't symlink index1.html to $dir/index.html";
$HEAD=$HEAD_orig;
$FOOT=$FOOT_orig;
}
##########################################################################
##########################################################################
# Routine strip takes a filename and produces
# the stripped-down version of its content
# suitabe for inclusion into index files
sub strip
{
my $file=$_[0];
my %event= parse_entry ($file);
# print " Stripping $file: the hash:\n";
# print map { "$_ => $event{$_}\n" } keys %event;
my $ev = \%event;
my $url = $ev->{'url'};
if ($ev->{'error'})
{
my $result = $ev->{'body'};
$result = "ERROR
";
return $result;
}
my $filename= $file;
$filename =~ s/.*\///;
my $result = $ev->{'name'};
my $community = $ev->{'community'};
$result .= "
$result
writes in $community " if (defined ($ev->{'community'}));
my $udate = ParseDate ($ev->{'date'}) ;
my $date = UnixDate($udate, "%H:%M, %B %E %Y");
# print "Date parsed with ParseDate: $date";
$result = " $result $date ";
$result = "
\n\n";
# Top line is done
# Now let's do the main table.
# The left cell
my $user = $ev->{"username"};
my $main_table = (-d ( "/$PATH/$user")) ?
"$user" :
"$user";
$main_table .= " $result
[ $community ]" if (defined ($ev->{'community'}));
if (defined ($ev->{'pic'}))
{
my $pic=$ev->{'pic'};
$main_table = $main_table .
"\n";
} else
{
$main_table = $main_table . "\n";
}
$main_table .= "
";
$main_table = "
$main_table \n";
# Left cell is done
# The right cell (the body of the message)
my $right_cell="
";
# Right cell is done. Now making the table
$main_table =
"
";
if (defined ($ev->{'subject'}))
{
my $subj = $ev->{'subject'};
$right_cell .= "
$subj
";
}
$right_cell .= $ev->{'body'};
# $right_cell .= "
";
if (defined ($ev->{'mood'}))
{
my $mood = $ev->{'mood'};
$right_cell .= "
Current mood: $mood
";
}
if (defined ($ev->{'music'}))
{
my $music = $ev->{'music'};
$right_cell .= "
Current music: $music
";
}
if (defined($ev->{'replies_num'}))
{
my $rnum = $ev->{'replies_num'};
$right_cell .="
($rnum replies)"
}
else
{
$right_cell .="
(Оригинал сообщения)
"
}
$right_cell .="
\n\n";
$result .= $main_table;
return $result;
}
##########################################################################
##########################################################################
# Routine parse_entry reads a filename
# and produces a hash with the fields ->{mood}, ->{music} ->{body} ->{date}
# ->{name} ->{username} ->{picture} ->{subject} ->{url} ->{pic}
# ->{replies_num} ->{error}
# The field ->{body} is just the event.
# Unless it's an error message,
# the fields ->{url} ->{body}, ->{date},
# ->{username}, ->{name} are always defined,
# the rest is optional. Also, ->{body} is equipped with extra linefeeds
# after $main_table $right_cell
, for readability.
# Parsing does not work on the entries
# from communities. Oh well.
sub parse_entry
{
my $file = $_[0];
open (FILE, "< $file") || die ("couldn't open $file: $!\n");
my @entry =