This commit is contained in:
2019-02-06 00:49:12 +03:00
commit 8dbb1bb605
4796 changed files with 506072 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,72 @@
#!/usr/bin/perl
use strict;
use Getopt::Long;
# load libraries now
use lib "$ENV{'LJHOME'}/cgi-bin";
use LJ::Blob;
use Image::Size ();
require "ljlib.pl";
my $opt_fast;
exit 1 unless
GetOptions("fast" => \$opt_fast,
);
my $clusterid = shift;
die "Usage: blobify_userpics.pl <clusterid>\n"
unless $clusterid;
my $db = LJ::get_cluster_master($clusterid);
die "Invalid/down cluster: $clusterid\n" unless $db;
print "Getting count.\n";
my $total = $db->selectrow_array("SELECT COUNT(*) FROM userpicblob2");
my $done = 0;
my $loop = 1;
while ($loop) {
$loop = 0;
LJ::start_request(); # shrink caches
print "Getting 200.\n";
my $sth = $db->prepare("SELECT userid, picid, imagedata FROM userpicblob2 LIMIT 200");
$sth->execute;
while (my ($uid, $picid, $image) = $sth->fetchrow_array) {
$loop = 1;
my $u = LJ::load_userid($uid);
die "Can't find userid: $uid" unless $u;
# sometimes expunges don't expunge all the way.
if ($u->{'statusvis'} eq "X") {
$db->do("DELETE FROM userpicblob2 WHERE userid=$uid AND picid=$picid");
next;
}
my ($sx, $sy, $fmt) = Image::Size::imgsize(\$image);
die "Unknown format" unless $fmt eq "GIF" || $fmt eq "JPG" || $fmt eq "PNG";
$fmt = lc($fmt);
my $err;
my $rv = LJ::Blob::put($u, "userpic", $fmt, $picid, $image, \$err);
die "Error putting file: $u->{'user'}/$picid\n" unless $rv;
unless ($opt_fast) {
# extra paranoid!
my $get = LJ::Blob::get($u, "userpic", $fmt, $picid);
die "Re-fetch didn't match" unless $get eq $image;
}
$db->do("DELETE FROM userpicblob2 WHERE userid=$uid AND picid=$picid");
$done++;
printf " Moved $uid/$picid.$fmt ($done/$total = %.2f%%)\n", ($done / $total * 100);
}
}
my $end_ct = $db->selectrow_array("SELECT COUNT(*) FROM userpicblob2");
if ($end_ct == 0) {
$db->do("TRUNCATE TABLE userpicblob2");
}
print "Done.\n";

View File

@@ -0,0 +1,77 @@
#!/usr/bin/perl
use strict;
my $clusterid = shift;
die "Usage: compress_cluster <clusterid>\n"
unless $clusterid;
# load libraries now
require "$ENV{'LJHOME'}/cgi-bin/ljlib.pl";
# force this option on, since that's the point of the tool
$LJ::COMPRESS_TEXT = 1;
my $db = LJ::get_cluster_master($clusterid);
die "Invalid/down cluster: $clusterid\n" unless $db;
# table, column, [ prikey1, prikey2 ]
foreach my $t (['logtext2', 'event', ['journalid', 'jitemid']],
['talktext2', 'body', ['journalid', 'jtalkid']]) {
my ($table, $col, $key) = @$t;
my ($pk1, $pk2) = @$key; # 2 sections of primary key
my $total = $db->selectrow_array("SELECT COUNT(*) FROM $table");
print "Processing table: $table [$total total rows]\n";
$db->do("HANDLER $table OPEN");
my $ct = 0;
my $modct = 0;
my $bytes_pre;
my $bytes_post;
my $stats = sub {
printf("%6.2f%% done (mod=%.2f%%, size=%.2f%%),\n",
($ct / $total) * 100,
($modct / $ct) * 100,
($bytes_post / $bytes_pre) * 100);
};
my $loop = 1;
while ($loop) {
my $sth = $db->prepare("HANDLER $table READ `PRIMARY` NEXT LIMIT 100");
$sth->execute;
$loop = 0;
while (my $row = $sth->fetchrow_hashref) {
$loop = 1;
# print status
$stats->() if (++$ct % 1000 == 0);
# try to compress the text
my $orig_len = length($row->{$col});
$bytes_pre += $orig_len;
my $new_text = LJ::text_compress($row->{$col});
my $new_len = length($new_text);
$bytes_post += $new_len;
# do nothing if the "compressed" and uncompressed sizes are the same
next if $new_text eq $row->{$col};
# update this row since it compressed
$db->do("UPDATE $table SET $col=? WHERE $pk1=? AND $pk2=? AND $col=?",
undef, $new_text, $row->{$pk1}, $row->{$pk2}, $row->{$col});
$modct++;
}
}
$stats->();
$db->do("HANDLER $table CLOSE");
print "$ct rows processed, $modct modified\n\n";
}

View File

@@ -0,0 +1,41 @@
#!/usr/bin/perl
#
use strict;
require "$ENV{'LJHOME'}/cgi-bin/ljlib.pl";
my $dbh = LJ::get_dbh("master");
my $user = shift @ARGV;
my $where = "dversion=1 LIMIT 1";
if ($user) {
$where = "user=" . $dbh->quote($user);
}
my $u = $dbh->selectrow_hashref("SELECT * FROM user WHERE $where");
unless ($u) {
die "No users with dversion==1 to convert. Done.\n" unless $user;
die "User not found.\n";
}
die "User not dversion 1\n" unless $u->{'dversion'} == 1;
my $dbch = LJ::get_cluster_master($u);
die "Can't connect to cluster master.\n" unless $dbch;
print "$u->{'user'}:\n";
my @pics = @{$dbh->selectcol_arrayref("SELECT picid FROM userpic WHERE ".
"userid=$u->{'userid'}")};
foreach my $picid (@pics) {
print " $picid...\n";
my $imagedata = $dbh->selectrow_array("SELECT imagedata FROM userpicblob ".
"WHERE picid=$picid");
$imagedata = $dbh->quote($imagedata);
$dbch->do("REPLACE INTO userpicblob2 (userid, picid, imagedata) VALUES ".
"($u->{'userid'}, $picid, $imagedata)");
}
$dbh->do("UPDATE user SET dversion=2 WHERE userid=$u->{'userid'}");
print "Done.\n";

View File

@@ -0,0 +1,320 @@
#!/usr/bin/perl
#
use strict;
$| = 1;
require "$ENV{'LJHOME'}/cgi-bin/ljlib.pl";
my $BLOCK_MOVE = 5000; # user rows to get at a time before moving
my $BLOCK_INSERT = 25; # rows to insert at a time when moving users
my $BLOCK_UPDATE = 1000; # users to update at a time if they had no data to move
# used for keeping stats notes
my %stats = (); # { 'action' => { 'pass' => { 'stat' => 'value' } } }
# rows come order by user, keep last username so we can avoid dups
my $lastuser;
# what pass are we on?
my $pass;
my $get_db_writer = sub {
return LJ::get_dbh({raw=>1}, "master");
};
my $get_db_slow = sub {
return LJ::get_dbh({raw=>1}, "slow", "master");
};
my $get_cluster_master = sub {
my $cid = shift;
return LJ::get_dbh({raw=>1}, "cluster$cid");
};
# percentage complete
my $status = sub {
my ($ct, $tot, $units, $pass, $user) = @_;
my $len = length($tot);
my $passtxt = $pass ? "[Pass: $pass] " : '';
my $usertxt = $user ? " Moving user: $user" : '';
return sprintf(" $passtxt\[%6.2f%%: %${len}d/%${len}d $units]$usertxt\n",
($ct / $tot) * 100, $ct, $tot);
};
my $header = sub {
my $size = 50;
return "\n" .
("#" x $size) . "\n" .
"# $_[0] " . (" " x ($size - length($_[0]) - 4)) . "#\n" .
("#" x $size) . "\n\n";
};
# mover function
my $move_user = sub {
my $user = shift;
# if the current user is the same as the last,
# we have a duplicate so skip it
return 0 if $user eq $lastuser;
$lastuser = $user;
my $u = LJ::load_user($user);
return 0 unless $u->{'dversion'} == 4;
# update user count for this pass
$stats{'move'}->{$pass}->{'user_ct'}++;
# print status
print $status->($stats{'move'}->{$pass}->{'ct'},
$stats{'move'}->{$pass}->{'total'}, "rows", $pass, $user);
# ignore expunged users
if ($u->{'statusvis'} eq "X") {
LJ::update_user($u, { 'dversion' => 5 })
or die "error updating dversion";
$u->{'dversion'} = 5; # update local copy in memory
return 1;
}
# get a handle for every user to revalidate our connection?
my $dbh = $get_db_writer->()
or die "Can't connect to global master";
my $dbslo = $get_db_slow->()
or die "Can't connect to global slow master";
my $dbcm = $get_cluster_master->($u->{'clusterid'})
or die "Can't connect to cluster master ($u->{'clusterid'})";
# be careful, we're moving data
foreach my $db ($dbh, $dbslo, $dbcm) {
$db->do("SET wait_timeout=28800");
$db->{'RaiseError'} = 1;
}
my @map = (['style' => 's1style',
qw(styleid userid styledes type formatdata is_public
is_embedded is_colorfree opt_cache has_ads lastupdate) ],
['overrides' => 's1overrides',
qw(userid override) ]
);
# in moving, s1stylecache gets special cased because its
# name hasn't changed, only location. so if there is only
# one cluster, then there's no point in physically moving it
if (@LJ::CLUSTERS > 1) {
push @map, ['s1stylecache' => 's1stylecache',
qw(styleid cleandate type opt_cache vars_stor vars_cleanver) ];
}
# user 'system' is a special case. if we encounter this user we'll swap $dbcm
# to secretly be a $dbh. because the 'system' user uses the clustered tables
# on the global dbs, the queries will still work, we just need to misdirect them
$dbcm = $dbh if $u->{'user'} eq 'system';
# styleids to delete since s1stylemap isn't keyed on user
my @delete_styleids = ();
# update tables
foreach my $tableinf (@map) {
# find src and dest table names
my $src_table = shift @$tableinf;
my $dest_table = shift @$tableinf;
# if this is the style table, replace into stylemap here,
# so that if this process is killed, style and stylemap
# won't get too out of sync
my $do_stylemap = $src_table eq 'style' && $dest_table eq 's1style';
# find what columns this table has
my @cols = @$tableinf;
my $cols = join(",", @cols);
my $bind_row = "(" . join(",", map { "?" } @cols) . ")";
my (@bind, @vals);
my (@map_bind, @map_vals);
# flush rows to destination table
my $flush = sub {
return unless @bind;
# insert data
my $bind = join(",", @bind);
$dbcm->do("REPLACE INTO $dest_table ($cols) VALUES $bind", undef, @vals);
# insert new styles into s1stylemap
if ($do_stylemap) {
my $map_bind = join(",", @map_bind);
$dbh->do("REPLACE INTO s1stylemap (styleid, userid) VALUES $map_bind",
undef, @map_vals);
}
# reset values
@bind = ();
@vals = ();
};
# s1stylecache is the only table keyed on styleid, not user
my $where = "user=" . $dbh->quote($u->{'user'});
if ($src_table eq "s1stylecache") {
my $ids = $dbh->selectcol_arrayref("SELECT styleid FROM style WHERE user=?",
undef, $u->{'user'});
my $ids_in = join(",", map { $dbh->quote($_) } @$ids) || "0";
$where = "styleid IN ($ids_in)";
}
# select from source table and build data for insert
my $sth = $dbh->prepare("SELECT * FROM $src_table WHERE $where");
$sth->execute();
while (my $row = $sth->fetchrow_hashref) {
# so that when we look for userid later, it'll be there
$row->{'userid'} = $u->{'userid'};
# build data for insert
push @bind, $bind_row;
push @vals, $row->{$_} foreach @cols;
# special case: insert new s1styles into s1stylemap
if ($do_stylemap) {
push @map_bind, "(?,?)";
push @map_vals, ($row->{'styleid'}, $u->{'userid'});
push @delete_styleids, $row->{'styleid'};
}
# increment the count for this pass, style or overrides
$stats{'move'}->{$pass}->{'ct'}++
unless $src_table eq 's1stylecache';
# flush if we've reached our insert limit
$flush->() if @bind > $BLOCK_INSERT;
}
$flush->();
}
# haven't died yet? everything is still going okay
# update dversion
LJ::update_user($u, { 'dversion' => 5 })
or die "error updating dversion";
$u->{'dversion'} = 5; # update local copy in memory
return 1;
};
my $dbh = $get_db_writer->();
die "Could not connect to global master" unless $dbh;
$dbh->{'RaiseError'} = 1;
my $dbslo = $get_db_slow->();
die "Could not connect to global slow master" unless $dbslo;
$dbslo->{'RaiseError'} = 1;
my $ts = $dbslo->selectrow_hashref("SHOW TABLE STATUS LIKE 'overrides'");
if ($ts->{'Type'} eq 'ISAM') {
die "This script isn't efficient with ISAM tables. Please convert to MyISAM with:\n" .
" mysql> ALTER TABLE overrides TYPE=MyISAM;\n\n" .
"Then re-run this script.\n";
}
print $header->("Moving user data");
# first pass should get everything, second pass will
# get changes made during the first
foreach my $p (1..2) {
# this is strange. perl bug?
$pass = $p;
# get totals from overrides and style so we can do a percentage bar
# there will be overlaps in this when users have both styles and
# overrides, but we'll fix those up as we go
foreach (qw(style overrides)) {
$stats{'move'}->{$pass}->{'total'} += $dbslo->selectrow_array("SELECT COUNT(*) FROM $_");
}
print "Processing $stats{'move'}->{$p}->{'total'} total rows\n";
# 2 passes, so we catch people with styles & overrides,
# styles w/o overrides, and overrides w/o styles
foreach my $table (qw(style overrides)) {
$lastuser = '';
# loop until we have no more users to convert
my $ct;
do {
# get blocks of $BLOCK_MOVE users at a time
my $sth = $dbslo->prepare("SELECT user FROM $table WHERE user>? " .
"ORDER BY user LIMIT $BLOCK_MOVE");
$sth->execute($lastuser);
$ct = 0;
while (my $user = $sth->fetchrow_array) {
$move_user->($user);
$ct++;
}
} while $ct;
}
print $stats{'move'}->{$p}->{'user_ct'}+0 . " users moved\n\n";
}
# now we're confident that all users have had their data moved if
# necessary, so we can just unconditionally change dversions.
print $header->("Updating remaining users");
$stats{'update'}->{'total'} = $dbslo->selectrow_array("SELECT COUNT(*) FROM user WHERE dversion=4");
print "Converting $stats{'update'}->{'total'} users\n";
# now update dversions for users who had no data to move
if ($stats{'update'}->{'total'}) {
my $get_users = sub {
my $sth = $dbslo->prepare("SELECT userid, user FROM user " .
"WHERE dversion=4 LIMIT $BLOCK_UPDATE");
$sth->execute();
my @rows; # [ userid, user ]
while ( my ($userid, $user) = $sth->fetchrow_array) {
push @rows, [ $userid, $user ];
}
return @rows;
};
while (my @rows = $get_users->()) {
# update database
my $bind = join(",", map { "?" } @rows);
my @vals = map { $_->[0] } @rows;
$dbh->do("UPDATE user SET dversion=5 WHERE userid IN ($bind)",
undef, @vals);
# update memcache
foreach (@rows) {
LJ::MemCache::delete([$_->[0], "userid:" . $_->[0]]);
LJ::MemCache::delete([$_->[1], "user:" . $_->[1]]);
}
$stats{'update'}->{'ct'} += @rows;
print $status->($stats{'update'}->{'ct'}, $stats{'update'}->{'total'}, "users");
}
}
my $zeropad = sub {
return sprintf("%d", $_[0]);
};
# calculate total move stats
foreach (1..2) {
$stats{'move'}->{'total_ct'} += $stats{'move'}->{$_}->{'ct'};
$stats{'move'}->{'total_user_ct'} += $stats{'move'}->{$_}->{'user_ct'};
}
print $header->("Dversion 4->5 conversion completed");
print " Rows moved: " . $zeropad->($stats{'move'}->{'total_ct'}) . "\n";
print " Users moved: " . $zeropad->($stats{'move'}->{'total_user_ct'}) . "\n";
print "Users updated: " . $zeropad->($stats{'update'}->{'ct'}) . "\n\n";

View File

@@ -0,0 +1,349 @@
#!/usr/bin/perl
#
use strict;
use Getopt::Long;
$| = 1;
use lib ("$ENV{LJHOME}/cgi-bin");
require "ljlib.pl";
use LJ::User;
use constant DEBUG => 0; # turn on for debugging (mostly db handle crap)
my $BLOCK_MOVE = 5000; # user rows to get at a time before moving
my $BLOCK_INSERT = 25; # rows to insert at a time when moving users
my $BLOCK_UPDATE = 1000; # users to update at a time if they had no data to move
# get options
my %opts;
exit 1 unless
GetOptions("lock=s" => \$opts{locktype},);
# if no locking, notify them about it
die "ERROR: Lock must be of types 'ddlockd' or 'none'\n"
if $opts{locktype} && $opts{locktype} !~ m/^(?:ddlockd|none)$/;
# used for keeping stats notes
my %stats = (); # { 'stat' => 'value' }
my %handle;
# database handle retrieval sub
my $get_db_handles = sub {
# figure out what cluster to load
my $cid = shift(@_) + 0;
my $dbh = $handle{0};
unless ($dbh) {
$dbh = $handle{0} = LJ::get_dbh({ raw => 1 }, "master");
print "Connecting to master ($dbh)...\n";
eval {
$dbh->do("SET wait_timeout=28800");
};
$dbh->{'RaiseError'} = 1;
}
my $dbcm;
$dbcm = $handle{$cid} if $cid;
if ($cid && ! $dbcm) {
$dbcm = $handle{$cid} = LJ::get_cluster_master({ raw => 1 }, $cid);
print "Connecting to cluster $cid ($dbcm)...\n";
return undef unless $dbcm;
eval {
$dbcm->do("SET wait_timeout=28800");
};
$dbcm->{'RaiseError'} = 1;
}
# return one or both, depending on what they wanted
return $cid ? ($dbh, $dbcm) : $dbh;
};
# percentage complete
my $status = sub {
my ($ct, $tot, $units, $user) = @_;
my $len = length($tot);
my $usertxt = $user ? " Moving user: $user" : '';
return sprintf(" \[%6.2f%%: %${len}d/%${len}d $units]$usertxt\n",
($ct / $tot) * 100, $ct, $tot);
};
my $header = sub {
my $size = 50;
return "\n" .
("#" x $size) . "\n" .
"# $_[0] " . (" " x ($size - length($_[0]) - 4)) . "#\n" .
("#" x $size) . "\n\n";
};
my $zeropad = sub {
return sprintf("%d", $_[0]);
};
# mover function
my $move_user = sub {
my $u = shift;
# make sure our user is of the proper dversion
return 0 unless $u->{'dversion'} == 5;
# at this point, try to get a lock for this user
my $lock;
if ($opts{locktype} eq 'ddlockd') {
$lock = LJ::locker()->trylock("d5d6-$u->{user}");
return 1 unless $lock;
}
# get a handle for every user to revalidate our connection?
my ($dbh, $dbcm) = $get_db_handles->($u->{clusterid});
return 0 unless $dbh;
if ($dbcm) {
# assign this dbcm to the user
$u->set_dbcm($dbcm)
or die "unable to set database for $u->{user}: dbcm=$dbcm\n";
}
# verify dversion hasn't changed on us (done by another job?)
my $dversion = $dbh->selectrow_array("SELECT dversion FROM user WHERE userid = $u->{userid}");
return 1 unless $dversion == 5;
# ignore expunged users
if ($u->{'statusvis'} eq "X" || $u->{'clusterid'} == 0) {
LJ::update_user($u, { dversion => 6 })
or die "error updating dversion";
$u->{dversion} = 6; # update local copy in memory
return 1;
}
return 0 unless $dbcm;
# step 1: get all friend groups and move those. safe to just grab with no limit because
# there are limits to how many friend groups you can have (30).
my $rows = $dbh->selectall_arrayref('SELECT groupnum, groupname, sortorder, is_public ' .
'FROM friendgroup WHERE userid = ?', undef, $u->{userid});
if (@$rows) {
# got some rows, create an update statement
my (@bind, @vars);
foreach my $row (@$rows) {
push @bind, "($u->{userid}, ?, ?, ?, ?)";
push @vars, $_ foreach @$row;
}
my $bind = join ',', @bind;
eval {
$u->do("INSERT INTO friendgroup2 (userid, groupnum, groupname, sortorder, is_public) " .
"VALUES $bind", undef, @vars);
};
}
# general purpose flusher for use below
my (@bind, @vars);
my $flush = sub {
return unless @bind;
my ($table, $cols) = @_;
# insert data into cluster master
my $bind = join(",", @bind);
$u->do("REPLACE INTO $table ($cols) VALUES $bind", undef, @vars);
die "error in flush $table: " . $u->errstr . "\n" if $u->err;
# reset values
@bind = ();
@vars = ();
};
# step 1.5: see if the user has any data already? clear it if so.
my $counter = $dbcm->selectrow_array("SELECT max FROM counter WHERE journalid = ? AND area = 'R'",
undef, $u->{userid});
$counter += 0;
if ($counter > 0) {
# yep, so we need to delete stuff, real data first
foreach my $table (qw(memorable2 memkeyword2 userkeywords)) {
$u->do("DELETE FROM $table WHERE userid = ?", undef, $u->{userid});
die "error in clear: " . $u->errstr . "\n" if $u->err;
}
# delete counters used (including memcache of such)
$u->do("DELETE FROM counter WHERE journalid = ? AND area IN ('R', 'K')", undef, $u->{userid});
die "error in clear: " . $u->errstr . "\n" if $u->err;
LJ::MemCache::delete([$u->{userid}, "auc:$u->{userid}:R"]);
LJ::MemCache::delete([$u->{userid}, "auc:$u->{userid}:K"]);
}
# step 2: get all of their memories and move them, creating the oldmemid -> newmemid mapping
# that we can use in later steps to migrate keywords
my %bindings; # ( oldid => newid )
my $sth = $dbh->prepare('SELECT memid, journalid, jitemid, des, security ' .
'FROM memorable WHERE userid = ?');
$sth->execute($u->{userid});
while (my $row = $sth->fetchrow_hashref()) {
# got a row, good
my $newid = LJ::alloc_user_counter($u, 'R');
die "Error: unable to allocate type 'R' counter for $u->{user}($u->{userid})\n"
unless $newid;
$bindings{$row->{memid}} = $newid;
# push data
push @bind, "($u->{userid}, ?, ?, ?, ?, ?)";
push @vars, ($newid, map { $row->{$_} } qw(journalid jitemid des security));
# flush if necessary
$flush->('memorable2', 'userid, memid, journalid, ditemid, des, security')
if @bind > $BLOCK_INSERT;
}
$flush->('memorable2', 'userid, memid, journalid, ditemid, des, security');
# step 3: get the list of keywords that these memories all use
my %kwmap;
if (%bindings) {
my $memids = join ',', map { $_+0 } keys %bindings;
my $rows = $dbh->selectall_arrayref("SELECT memid, kwid FROM memkeyword WHERE memid IN ($memids)");
push @{$kwmap{$_->[1]}}, $_->[0] foreach @$rows; # kwid -> [ memid, memid, memid ... ]
}
# step 4: get the actual keywords associated with these keyword ids
my %kwidmap;
if (%kwmap) {
my $kwids = join ',', map { $_+0 } keys %kwmap;
my $rows = $dbh->selectall_arrayref("SELECT kwid, keyword FROM keywords WHERE kwid IN ($kwids)");
%kwidmap = map { $_->[0] => $_->[1] } @$rows; # kwid -> keyword
}
# step 5: now migrate all keywords into userkeywords table
my %mappings;
while (my ($kwid, $keyword) = each %kwidmap) {
# reallocate counter
my $newkwid = LJ::alloc_user_counter($u, 'K');
die "Error: unable to allocate type 'K' counter for $u->{user}($u->{userid})\n"
unless $newkwid;
$mappings{$kwid} = $newkwid;
# push data
push @bind, "($u->{userid}, ?, ?)";
push @vars, ($newkwid, $keyword);
# flush if necessary
$flush->('userkeywords', 'userid, kwid, keyword')
if @bind > $BLOCK_INSERT;
}
$flush->('userkeywords', 'userid, kwid, keyword');
# step 6: now we have to do some mapping conversions and put new data into memkeyword2 table
while (my ($oldkwid, $oldmemids) = each %kwmap) {
foreach my $oldmemid (@$oldmemids) {
# get new data
my ($newkwid, $newmemid) = ($mappings{$oldkwid}, $bindings{$oldmemid});
# push data
push @bind, "($u->{userid}, ?, ?)";
push @vars, ($newmemid, $newkwid);
# flush?
$flush->('memkeyword2', 'userid, memid, kwid')
if @bind > $BLOCK_INSERT;
}
}
$flush->('memkeyword2', 'userid, memid, kwid');
# delete memcache keys that hold old data
LJ::MemCache::delete([$u->{userid}, "memkwid:$u->{userid}"]);
# haven't died yet? everything is still going okay, so update dversion
LJ::update_user($u, { 'dversion' => 6 })
or die "error updating dversion";
$u->{'dversion'} = 6; # update local copy in memory
return 1;
};
# get dbh handle
my $dbh = LJ::get_db_writer(); # just so we can get users...
die "Could not connect to global master" unless $dbh;
# get user count
my $total = $dbh->selectrow_array("SELECT COUNT(*) FROM user WHERE dversion = 5");
$stats{'total_users'} = $total+0;
# print out header and total we're moving
print $header->("Moving user data");
print "Processing $stats{'total_users'} total users with the old dversion\n";
# loop until we have no more users to convert
my $ct;
while (1) {
# get blocks of $BLOCK_MOVE users at a time
my $sth = $dbh->prepare("SELECT * FROM user WHERE dversion = 5 LIMIT $BLOCK_MOVE");
$sth->execute();
$ct = 0;
my %us;
my %fast; # people to move fast
while (my $u = $sth->fetchrow_hashref()) {
$us{$u->{userid}} = $u;
$ct++;
$fast{$u->{userid}} = 1;
}
# jump out if we got nothing
last unless $ct;
# now that we have %us, we can see who has data
my $ids = join ',', map { $_+0 } keys %us;
my $has_memorable = $dbh->selectcol_arrayref("SELECT DISTINCT userid FROM memorable WHERE userid IN ($ids)");
my $has_fgroups = $dbh->selectcol_arrayref("SELECT DISTINCT userid FROM friendgroup WHERE userid IN ($ids)");
my %uids = ( map { $_ => 1 } (@$has_memorable, @$has_fgroups) );
# these people actually have data to migrate; don't move them fast
delete $fast{$_} foreach keys %uids;
# now see who we can do in a fast way
my @fast_ids = map { $_+0 } keys %fast;
if (@fast_ids) {
print "Converting ", scalar(@fast_ids), " users quickly...\n";
# update stats for counting and print
$stats{'fast_moved'} += @fast_ids;
print $status->($stats{'slow_moved'}+$stats{'fast_moved'}, $stats{'total_users'}, "users");
# block update
LJ::update_user(\@fast_ids, { dversion => 6 });
}
my $slow_todo = scalar keys %uids;
print "Of $BLOCK_MOVE, $slow_todo have to be slow-converted...\n";
my @ids = randlist(keys %uids);
foreach my $id (@ids) {
# this person has memories, move them the slow way
die "Userid $id in \$has_memorable, but not in \%us...fatal error\n" unless $us{$id};
# now move the user
bless $us{$id}, 'LJ::User';
if ($move_user->($us{$id})) {
$stats{'slow_moved'}++;
print $status->($stats{'slow_moved'}+$stats{'fast_moved'}, $stats{'total_users'}, "users", $us{$id}{user});
}
}
}
# ...done?
print $header->("Dversion 5->6 conversion completed");
print " Users moved: " . $zeropad->($stats{'slow_moved'}) . "\n";
print "Users updated: " . $zeropad->($stats{'fast_moved'}) . "\n\n";
# helper function to randomize stuff
sub randlist
{
my @rlist = @_;
my $size = scalar(@rlist);
my $i;
for ($i=0; $i<$size; $i++) {
unshift @rlist, splice(@rlist, $i+int(rand()*($size-$i)), 1);
}
return @rlist;
}

View File

@@ -0,0 +1,352 @@
#!/usr/bin/perl
#
use strict;
use Getopt::Long;
$| = 1;
use lib "$ENV{'LJHOME'}/cgi-bin/";
require "ljlib.pl";
use LJ::Blob;
use LJ::User;
use constant DEBUG => 0; # turn on for debugging (mostly db handle crap)
my $BLOCK_MOVE = 5000; # user rows to get at a time before moving
my $BLOCK_INSERT = 25; # rows to insert at a time when moving users
my $BLOCK_UPDATE = 1000; # users to update at a time if they had no data to move
# get options
my %opts;
exit 1 unless
GetOptions("lock=s" => \$opts{locktype},
"user=s" => \$opts{user},
"total=i" => \$opts{total},);
# if no locking, notify them about it
die "ERROR: Lock must be of types 'ddlockd' or 'none'\n"
if $opts{locktype} && $opts{locktype} !~ m/^(?:ddlockd|none)$/;
# used for keeping stats notes
my %stats = (); # { 'stat' => 'value' }
my %handle;
# database handle retrieval sub
my $get_db_handles = sub {
# figure out what cluster to load
my $cid = shift(@_) + 0;
my $dbh = $handle{0};
unless ($dbh) {
$dbh = $handle{0} = LJ::get_dbh({ raw => 1 }, "master");
print "Connecting to master ($dbh)...\n";
eval {
$dbh->do("SET wait_timeout=28800");
};
$dbh->{'RaiseError'} = 1;
}
my $dbcm;
$dbcm = $handle{$cid} if $cid;
if ($cid && ! $dbcm) {
$dbcm = $handle{$cid} = LJ::get_cluster_master({ raw => 1 }, $cid);
print "Connecting to cluster $cid ($dbcm)...\n";
return undef unless $dbcm;
eval {
$dbcm->do("SET wait_timeout=28800");
};
$dbcm->{'RaiseError'} = 1;
}
# return one or both, depending on what they wanted
return $cid ? ($dbh, $dbcm) : $dbh;
};
# percentage complete
my $status = sub {
my ($ct, $tot, $units, $user) = @_;
my $len = length($tot);
my $usertxt = $user ? " Moving user: $user" : '';
return sprintf(" \[%6.2f%%: %${len}d/%${len}d $units]$usertxt\n",
($ct / $tot) * 100, $ct, $tot);
};
my $header = sub {
my $size = 50;
return "\n" .
("#" x $size) . "\n" .
"# $_[0] " . (" " x ($size - length($_[0]) - 4)) . "#\n" .
("#" x $size) . "\n\n";
};
my $zeropad = sub {
return sprintf("%d", $_[0]);
};
# mover function
my $move_user = sub {
my $u = shift;
# make sure our user is of the proper dversion
return 0 unless $u->{'dversion'} == 6;
# at this point, try to get a lock for this user
my $lock;
if ($opts{locktype} eq 'ddlockd') {
$lock = LJ::locker()->trylock("d6d7-$u->{user}");
return 1 unless $lock;
}
# get a handle for every user to revalidate our connection?
my ($dbh, $dbcm) = $get_db_handles->($u->{clusterid});
return 0 unless $dbh;
# assign this dbcm to the user
if ($dbcm) {
$u->set_dbcm($dbcm)
or die "unable to set database for $u->{user}: dbcm=$dbcm\n";
}
# verify dversion hasn't changed on us (done by another job?)
my $dversion = $dbh->selectrow_array("SELECT dversion FROM user WHERE userid = $u->{userid}");
return 1 unless $dversion == 6;
# ignore expunged users
if ($u->{'statusvis'} eq "X" || $u->{'clusterid'} == 0) {
LJ::update_user($u, { dversion => 7 })
or die "error updating dversion";
$u->{dversion} = 7; # update local copy in memory
return 1;
}
return 0 unless $dbcm;
# step 0.5: delete all the bogus userblob rows for this user
# This is due to the auto_increment for the blobid overflowing
# and thus all entries recieving an id of max id for a mediumint.
# This is lame.
my $domainid = LJ::get_blob_domainid('userpic');
$u->do("DELETE FROM userblob WHERE journalid=$u->{userid} AND domain=$domainid AND blobid>=16777216");
die "error in delete: " . $u->errstr . "\n" if $u->err;
# step 1: get all user pictures and move those. safe to just grab with no limit
# since users can only have a limited number of them
my $rows = $dbh->selectall_arrayref('SELECT picid, userid, contenttype, width, height, state, picdate, md5base64 ' .
'FROM userpic WHERE userid = ?', undef, $u->{userid}) || [];
if (@$rows) {
# got some rows, create an update statement
my (@bind, @vars, @blobids, @blobbind, @picinfo);
foreach my $row (@$rows) {
my $picid = $row->[0];
push @bind, "(?, ?, ?, ?, ?, ?, ?, ?)";
$row->[2] = {'image/gif' => 'G',
'image/jpeg' => 'J',
'image/png' => 'P'}->{$row->[2]};
push @vars, @$row;
# [picid, fmt]
my $fmt = {'G' => 'gif',
'J' => 'jpg',
'P' => 'png'}->{$row->[2]};
push @picinfo, [$picid, $fmt];
# picids
push @blobids, $picid;
push @blobbind, "?";
}
my $bind = join ',', @bind;
$u->do("REPLACE INTO userpic2 (picid, userid, fmt, width, height, state, picdate, md5base64) " .
"VALUES $bind", undef, @vars);
die "error in userpic2 replace: " . $u->errstr . "\n" if $u->err;
# step 1.5: insert missing rows into the userblob table
my $blobbind = join ',', @blobbind;
my $blobrows = $dbcm->selectall_hashref("SELECT blobid FROM userblob WHERE journalid=$u->{userid} AND domain=$domainid " .
"AND blobid IN ($blobbind)", 'blobid', undef, @blobids) || {};
my (@insertbind, @insertvars);
foreach my $pic (@picinfo) {
my ($picid, $fmt) = @$pic;
unless ($blobrows->{$picid}) {
push @insertbind, "(?, ?, ?, ?)";
my $blob = LJ::Blob::get($u, "userpic", $fmt, $picid);
my $length = length($blob);
push @insertvars, $u->{'userid'}, $domainid, $picid, $length;
}
}
if (@insertbind) {
my $insertbind = join ',', @insertbind;
$u->do("INSERT IGNORE INTO userblob (journalid, domain, blobid, length) " .
"VALUES $insertbind", undef, @insertvars);
die "error in userblob insert: " . $u->errstr . "\n" if $u->err;
}
}
# general purpose flusher for use below
my (@bind, @vars);
my $flush = sub {
return unless @bind;
my ($table, $cols) = @_;
# insert data into cluster master
my $bind = join(",", @bind);
$u->do("REPLACE INTO $table ($cols) VALUES $bind", undef, @vars);
die "error in flush $table: " . $u->errstr . "\n" if $u->err;
# reset values
@bind = ();
@vars = ();
};
# step 2: get the mapping of all of their keywords
my $kwrows = $dbh->selectall_arrayref('SELECT picid, kwid FROM userpicmap WHERE userid=?',
undef, $u->{'userid'});
my %kwmap;
if (@$kwrows) {
push @{$kwmap{$_->[1]}}, $_->[0] foreach @$kwrows; # kwid -> [ picid, picid, picid ... ]
}
# step 3: get the actual keywords associated with these keyword ids
my %kwidmap;
if (%kwmap) {
my $kwids = join ',', map { $_+0 } keys %kwmap;
my $rows = $dbh->selectall_arrayref("SELECT kwid, keyword FROM keywords WHERE kwid IN ($kwids)");
%kwidmap = map { $_->[0] => $_->[1] } @$rows; # kwid -> keyword
}
# step 4: now migrate all keywords into userkeywords table
my %mappings;
while (my ($kwid, $keyword) = each %kwidmap) {
# reallocate counter
my $newkwid = LJ::get_keyword_id($u, $keyword);
die "Error: unable to get keyword id for $u->{user}($u->{userid}), keyword '$keyword'\n"
unless $newkwid;
$mappings{$kwid} = $newkwid;
}
# step 5: now we have to do some mapping conversions and put new data into userpicmap2 table
while (my ($oldkwid, $picids) = each %kwmap) {
foreach my $picid (@$picids) {
# get new data
my $newkwid = $mappings{$oldkwid};
# push data
push @bind, "($u->{userid}, ?, ?)";
push @vars, ($picid, $newkwid);
# flush?
$flush->('userpicmap2', 'userid, picid, kwid')
if @bind > $BLOCK_INSERT;
}
}
$flush->('userpicmap2', 'userid, picid, kwid');
# delete memcache keys that hold old data
LJ::MemCache::delete([$u->{userid}, "upicinf:$u->{userid}"]);
# haven't died yet? everything is still going okay, so update dversion
LJ::update_user($u, { 'dversion' => 7 })
or die "error updating dversion";
$u->{'dversion'} = 7; # update local copy in memory
return 1;
};
# get dbh handle
my $dbh = LJ::get_db_writer(); # just so we can get users...
die "Could not connect to global master" unless $dbh;
# get user count
my $total = $opts{total} || $dbh->selectrow_array("SELECT COUNT(*) FROM user WHERE dversion = 6");
$stats{'total_users'} = $total+0;
# print out header and total we're moving
print $header->("Moving user data");
print "Processing $stats{'total_users'} total users with the old dversion\n";
# loop until we have no more users to convert
my $ct;
while (1) {
# get users to move
my $sth;
if ($opts{user}) {
$sth = $dbh->prepare("SELECT * FROM user WHERE user = ? AND dversion = 6");
$sth->execute($opts{user});
} else {
$sth = $dbh->prepare("SELECT * FROM user WHERE dversion = 6 LIMIT $BLOCK_MOVE");
$sth->execute();
}
# get blocks of $BLOCK_MOVE users at a time
$ct = 0;
my (%us, %fast);
while (my $u = $sth->fetchrow_hashref()) {
$us{$u->{userid}} = $u;
$fast{$u->{userid}} = 1;
$ct++;
}
# jump out if we got nothing
last unless $ct;
# now that we have %us, we can see who has data
my $ids = join ',', map { $_+0 } keys %us;
my $has_upics = $dbh->selectcol_arrayref("SELECT DISTINCT userid FROM userpic WHERE userid IN ($ids)");
my %uids = ( map { $_ => 1 } (@$has_upics) );
# remove folks that have userpics from the fast list
delete $fast{$_} foreach keys %uids;
# now see who we can do in a fast way
my @fast_ids = map { $_+0 } keys %fast;
if (@fast_ids) {
# update stats for counting and print
$stats{'fast_moved'} += @fast_ids;
print $status->($stats{'slow_moved'}+$stats{'fast_moved'}, $stats{'total_users'}, "users");
# block update
LJ::update_user(\@fast_ids, { dversion => 7 });
}
my $slow_todo = scalar keys %uids;
print "Of $BLOCK_MOVE, $slow_todo have to be slow-converted...\n";
my @ids = randlist(keys %uids);
foreach my $id (@ids) {
# this person has userpics, move them the slow way
die "Userid $id in \$has_upics, but not in \%us...fatal error\n" unless $us{$id};
# now move the user
bless $us{$id}, 'LJ::User';
if ($move_user->($us{$id})) {
$stats{'slow_moved'}++;
print $status->($stats{'slow_moved'}+$stats{'fast_moved'}, $stats{'total_users'}, "users", $us{$id}{user});
}
}
}
# ...done?
print $header->("Dversion 6->7 conversion completed");
print " Users moved: " . $zeropad->($stats{'slow_moved'}) . "\n";
print "Users updated: " . $zeropad->($stats{'fast_moved'}) . "\n\n";
# helper function to randomize stuff
sub randlist
{
my @rlist = @_;
my $size = scalar(@rlist);
my $i;
for ($i=0; $i<$size; $i++) {
unshift @rlist, splice(@rlist, $i+int(rand()*($size-$i)), 1);
}
return @rlist;
}

View File

@@ -0,0 +1,207 @@
# these get removed if found by texttool.pl
#
general /allpics.bml.edit
general /allpics.bml.nopics.text
general /community/join.bml.label.authpost
general /community/join.bml.label.closedcomm
general /community/manage.bml.actmembers
general /community/manage.bml.actsettings
general /community/manage.bml.commlist.actmoderate
general /community/members.bml.manage
general /community/search.bml.contasmember
general /community/search.bml.userlikes
general /community/settings.bml.label.admconsole
general /community/settings.bml.manage
general /create.bml.aolnotice.head
general /create.bml.aolnotice.text
general /create.bml.error.seebelow
general /create.bml.proceed.head
general /create.bml.proceed.text
general /create.bml.tos.error
general /create.bml.tos.haveread
general /create.bml.tos.p1.2
general /editinfo.bml.allowshocontact.email.if_domainaddy
general /editinfo.bml.allowshowcontact.email.reason
general /editinfo.bml.newemail.body
general /editinfo.bml.settings.about
general /editinfo.bml.showsubjicons.about
general /editinfo.bml.showsubjicons.header
general /editinfo.bml.tm.about
general /editinfo.bml.topicdir.about
general /editinfo.bml.topicdir.header
general /friends/edit.bml.btn.proceed
general /friends/edit.bml.edit.head
general /friends/edit.bml.edit.text
general /editjournal.bml.enterlogin
general /editjournal.bml.lostinfo.head
general /editjournal.bml.lostinfo.text
general /editjournal_do.bml.error.mustlogin
general /editjournal_do.bml.success.edit
general /friends/editgroups.bml.login.header
general /friends/editgroups.bml.login.text
general /interests.bml.findsim.account.notallowed
general /interests.bml.findsim.account.notloggedin
general /interests.bml.findsim.btn.find
general /interests.bml.findsim.head
general /interests.bml.findsim.simtouser
general /interests.bml.findsim.text
general /interests.bml.interests.findsim1
general /interests.bml.interests.findsim2
general /login.bml.error.forgotpass
general /login.bml.error.noaccount
general /manage/index.bml.information.setlang.about
general /manage/index.bml.information.setscheme.about
general /modify.bml.btn.proceed
general /modify.bml.journalstatus.about
general /modify.bml.journalstatus.head
general /modify.bml.journalstatus.select.activated
general /modify.bml.journalstatus.select.deleted
general /modify.bml.journalstatus.select.head
general /modify.bml.journalstatus.select.suspended
general /modify.bml.lostinfo.head
general /modify.bml.lostinfo.text
general /modify.bml.modify.head
general /modify.bml.modify.text
general /modify_do.bml.title
general /multisearch.bml.region.text
general /register.bml.new.body
general /setlang.bml.select
general /setlang.bml.switch
general /setlang.bml.title
general /setscheme.bml.current
general /setscheme.bml.default
general /setscheme.bml.noschemes
general /setscheme.bml.select
general /setscheme.bml.switch
general /setscheme.bml.title
general /support/faqbrowse.bml.title
general /talkpost.bml.label.picturetouse
general /talkpost_do.bml.opt.spellcheck
general /talkread.bml.pageofpages
general /tools/memadd.bml.body.added.body
general /update.bml.update.about
general /update.bml.login.success
general /update.bml.htmlokay
general /uploadpic.bml.success.text
general /uploadpic.bml.btn.proceed
general /uploadpic.bml.error.badurl
general /uploadpic.bml.error.databasedown
general /uploadpic.bml.error.filetoolarge
general /uploadpic.bml.error.imagetoolarge
general /uploadpic.bml.error.invalidauth
general /uploadpic.bml.error.invalidimage
general /uploadpic.bml.error.toomanypics
general /uploadpic.bml.error.unknownmode
general /uploadpic.bml.error.urlerror
general /uploadpic.bml.fromfile
general /uploadpic.bml.fromfile.key
general /uploadpic.bml.fromurl
general /uploadpic.bml.fromurl.key
general /uploadpic.bml.header
general /uploadpic.bml.imagesize.by
general /uploadpic.bml.kilobytes
general /uploadpic.bml.makedefault
general /uploadpic.bml.makedefault.key
general /uploadpic.bml.restriction.fileformat
general /uploadpic.bml.restriction.filesize
general /uploadpic.bml.restriction.imagesize
general /uploadpic.bml.success.editpics
general /uploadpic.bml.success.header
general /uploadpic.bml.success.preview
general /uploadpic.bml.success.upload
general /uploadpic.bml.text
general /uploadpic.bml.title
general /uploadpic_do.bml.error.urlerror
general uploadpic.error.toolarge
general /userinfo.bml.canpost
general /userinfo.bml.closedmembership.body
general /userinfo.bml.fbpictures
general /userinfo.bml.label.viewlabel
general /userinfo.bml.openmembership.body
general /userinfo.bml.posthere
general /userinfo.bml.rpmembership.body
general /userinfo.bml.syn.lastnew
general /register.bml.error.alreadyvalidated
general /tools/memories.bml.entry
general /tools/memories.bml.entries
general /create.bml.tos.p1
general /create.bml.email.text
general /create.bml.email.note
general /syn/index.bml.table.cost
general /syn/index.bml.quota.text
general /syn/index.bml.quota.your
general /syn/index.bml.quota.numbers
general /syn/index.bml.invalid.overquota
general /syn/index.bml.invalid.overquota.text
general /syn/index.bml.invalid.overquota.title
general /syn/index.bml.invalid.overquota.username
general /syn/index.bml.accounttype.notallowed
general /syn/index.bml.add.other.title
general /syn/index.bml.add.other.text
general /syn/index.bml.notused
general /userinfo.bml.syn.cost
general bml.needlogin.body
general /userinfo.bml.label.frsyndication
general /syn/index.bml.invalid.address
general /community/members.bml.key.name
general /community/members.bml.success.addusers
general /userinfo.bml.label.totalfriends
general /community/settings.bml.label.closedmemb
general /talkscreen.bml.title
general /community/members.bml.success.message
general /community/transfer.bml.error.banned
general /create.bml.age.check.question
general /create.bml.age.check.yes
general /create.bml.age.check2.question
general /create.bml.age.check2.yes
general /create.bml.age.head
general /community/members.bml.reinvited
general /community/membres.bml.success.invited
general /customize/index.bml.s1

4676
livejournal/bin/upgrading/en.dat Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,48 @@
#!/usr/bin/perl
# This script goes through all of the files in your include directory
# (LJHOME/htdocs/inc) and then imports ones that are specified by your
# ljconfig.pl file (%LJ::FILEEDIT_VIA_DB) into your database if the file
# on disk is newer than the one in the database.
use strict;
require "$ENV{'LJHOME'}/cgi-bin/ljlib.pl";
# create list of files to check
my $dir = "$ENV{'LJHOME'}/htdocs/inc";
print "searching for files to check against database...";
opendir DIR, $dir
or die "Unable to open $ENV{'LJHOME'}/htdocs/inc for searching.\n";
my @files = grep { $LJ::FILEEDIT_VIA_DB ||
$LJ::FILEEDIT_VIA_DB{$_} } readdir(DIR);
my $count = scalar(@files);
print $count+0 . " found.\n";
# now iterate through and check times
my $dbh = LJ::get_db_writer();
foreach my $file (@files) {
my $path = "$dir/$file";
next unless -f $path;
# now get filetime
my $ftimedisk = (stat($path))[9];
my $ftimedb = $dbh->selectrow_array("SELECT updatetime
FROM includetext WHERE incname=?", undef, $file)+0;
# check
if ($ftimedisk > $ftimedb) {
# load file
open FILE, "<$path";
my $content = join("", <FILE>);
close FILE;
# now do SQL
print "$file newer on disk...updating database...";
$dbh->do("REPLACE INTO includetext (incname, inctext, updatetime)" .
"VALUES (?,?,UNIX_TIMESTAMP())", undef, $file, $content);
print $dbh->err ? "error: " . $dbh->errstr . ".\n" : "done.\n";
} else {
print "$file newer in database, ignored.\n";
}
}
print "all done.\n";

View File

@@ -0,0 +1,53 @@
#!/usr/bin/perl
#
use strict;
require "$ENV{'LJHOME'}/cgi-bin/ljlib.pl";
my $dbh = LJ::get_dbh("master");
print "
This tool will create your LiveJournal 'system' account and
set its password. Or, if you already have a system user, it'll change
its password to whatever you specify.
";
print "Enter password for the 'system' account: ";
my $pass = <STDIN>;
chomp $pass;
print "\n";
print "Creating system account...\n";
unless (LJ::create_account({ 'user' => 'system',
'name' => 'System Account',
'password' => $pass }))
{
print "Already exists.\nModifying 'system' account...\n";
$dbh->do("UPDATE user SET password=? WHERE user='system'",
undef, $pass);
}
my $u = LJ::load_user("system");
unless ($u) {
print "ERROR: can't find newly-created system account.\n";
exit 1;
}
print "Giving 'system' account 'admin' priv on all areas...\n";
if (LJ::check_priv($u, "admin", "*")) {
print "Already has it.\n";
} else {
my $sth = $dbh->prepare("INSERT INTO priv_map (userid, prlid, arg) ".
"SELECT $u->{'userid'}, prlid, '*' ".
"FROM priv_list WHERE privcode='admin'");
$sth->execute;
if ($dbh->err || $sth->rows == 0) {
print "Couldn't grant system account admin privs\n";
exit 1;
}
}
print "Done.\n\n";

View File

@@ -0,0 +1,323 @@
#!/usr/bin/perl
use strict;
use lib "$ENV{LJHOME}/cgi-bin";
require 'ljlib.pl';
use LJ::Blob;
use LJ::User;
use Getopt::Long;
use IPC::Open3;
use Digest::MD5;
# this script is a migrater that will move phone posts from an old storage method
# into mogilefs.
# the basic theory is that we iterate over all clusters, find all phoneposts that
# aren't in mogile right now, and put them there
# determine
my ($one, $besteffort, $dryrun, $user, $verify, $verbose, $clusters, $purge);
my $rv = GetOptions("best-effort" => \$besteffort,
"one" => \$one,
"dry-run" => \$dryrun,
"user=s" => \$user,
"verify" => \$verify,
"verbose" => \$verbose,
"purge-old" => \$purge,
"clusters=s" => \$clusters,);
unless ($rv) {
die <<ERRMSG;
This script supports the following command line arguments:
--clusters=X[-Y]
Only handle clusters in this range. You can specify a single
number, or a range of two numbers with a dash.
--user=username
Only move this particular user.
--one
Only move one user. (But it moves all their phone posts.) This is
used for testing.
--verify
If specified, this option will reload the phonepost from MogileFS and
make sure it's been stored successfully.
--dry-run
If on, do not update the database. This mode will put the phonepost
in MogileFS and give you paths to examine the phone posts and make
sure everything is okay. It will not update the phonepost2 table,
though.
--best-effort
Normally, if a problem is encountered (null phonepost, md5 mismatch,
connection failure, etc) the script will die to make sure
everything goes well. With this flag, we don't die and instead
just print to standard error.
--purge-old
Sometimes we run into data that is for users that have since
moved to a different cluster. Normally we ignore it, but
with this option, we'll clean that data up as we find it.
--verbose
Be very chatty.
ERRMSG
}
# make sure ljconfig is setup right (or so we hope)
die "Please define a 'phoneposts' class in your \%LJ::MOGILEFS_CONFIG\n"
unless defined $LJ::MOGILEFS_CONFIG{classes}->{phoneposts};
die "Unable to find MogileFS object (\%LJ::MOGILEFS_CONFIG not setup?)\n"
unless $LJ::MogileFS;
# setup stderr if we're in best effort mode
if ($besteffort) {
my $oldfd = select(STDERR);
$| = 1;
select($oldfd);
}
# operation modes
if ($user) {
# move a single user
my $u = LJ::load_user($user);
die "No such user: $user\n" unless $u;
handle_userid($u->{userid}, $u->{clusterid});
} else {
# parse the clusters
my @clusters;
if ($clusters) {
if ($clusters =~ /^(\d+)(?:-(\d+))?$/) {
my ($min, $max) = map { $_ + 0 } ($1, $2 || $1);
push @clusters, $_ foreach $min..$max;
} else {
die "Error: --clusters argument not of right format.\n";
}
} else {
@clusters = @LJ::CLUSTERS;
}
# now iterate over the clusters to pick
my $ctotal = scalar(@clusters);
my $ccount = 0;
foreach my $cid (sort { $a <=> $b } @clusters) {
# status report
$ccount++;
print "\nChecking cluster $cid...\n\n";
# get a handle
my $dbcm = get_db_handle($cid);
# get all userids
print "Getting userids...\n";
my $limit = $one ? 'LIMIT 1' : '';
my $userids = $dbcm->selectcol_arrayref
("SELECT DISTINCT userid FROM phonepostentry WHERE (location='blob' OR location IS NULL) $limit");
my $total = scalar(@$userids);
# iterate over userids
my $count = 0;
print "Beginning iteration over userids...\n";
foreach my $userid (@$userids) {
# move this phonepost
my $extra = sprintf("[%6.2f%%, $ccount of $ctotal] ", (++$count/$total*100));
handle_userid($userid, $cid, $extra);
}
# don't hit up more clusters
last if $one;
}
}
print "\n";
print "Updater terminating.\n";
#############################################################################
### helper subs down here
# take a userid and move their phone posts
sub handle_userid {
my ($userid, $cid, $extra) = @_;
# load user to move and do some sanity checks
my $u = LJ::load_userid($userid);
unless ($u) {
LJ::end_request();
LJ::start_request();
$u = LJ::load_userid($userid);
}
die "ERROR: Unable to load userid $userid\n"
unless $u;
# if they're expunged, they might have data somewhere if they were
# copy-moved from A to B, then expunged on B. now we're on A and
# need to delete it ourselves (if purge-old is on)
if ($u->{clusterid} == 0 && $u->{statusvis} eq "X") {
return unless $purge;
# if we get here, the user has indicated they want data purged, get handle
my $to_purge_dbcm = get_db_handle($cid);
my $ct = $to_purge_dbcm->do("DELETE FROM phonepostentry WHERE userid = ?", undef, $u->{userid});
print "\tnotice: purged $ct old rows.\n\n"
if $verbose;
return;
}
# get a handle
my $dbcm = get_db_handle($u->{clusterid});
# print that we're doing this user
print "$extra$u->{user}($u->{userid})\n";
# if a user has been moved to another cluster, but the source data from
# phonepostentry wasn't deleted, we need to ignore the user or purge their data
if ($u->{clusterid} != $cid) {
return unless $purge;
# verify they have some rows on the new side
my $count = $dbcm->selectrow_array
("SELECT COUNT(*) FROM phonepostentry WHERE userid = ?",
undef, $u->{userid});
return unless $count;
# if we get here, the user has indicated they want data purged, get handle
my $to_purge_dbcm = get_db_handle($cid);
# delete the old data
if ($dryrun) {
print "\tnotice: need to delete phonepostentry rows.\n\n"
if $verbose;
} else {
my $ct = $to_purge_dbcm->do("DELETE FROM phonepostentry WHERE userid = ?", undef, $u->{userid});
print "\tnotice: purged $ct old rows.\n\n"
if $verbose;
}
# nothing else to do here
return;
}
# get all their photos that aren't in mogile already
my $rows = $dbcm->selectall_arrayref
("SELECT filetype, blobid FROM phonepostentry WHERE userid = ? ".
"AND (location = 'blob' OR location IS NULL)",
undef, $u->{userid});
return unless @$rows;
# if a user has been moved to another cluster, but the source data from
# phonepost2 wasn't deleted, we need to ignore the user
return unless $u->{clusterid} == $cid;
# now we have a userid and blobids, get the photos from the blob server
foreach my $row (@$rows) {
my ($filetype, $blobid) = @$row;
print "\tstarting move for blobid $blobid\n"
if $verbose;
my $format = { 0 => 'mp3', 1 => 'ogg', 2 => 'wav' }->{$filetype};
my $data = LJ::Blob::get($u, "phonepost", $format, $blobid);
# get length
my $len = length($data);
if (! $len) {
my $has_blob = $dbcm->selectrow_array("SELECT COUNT(*) FROM userblob WHERE ".
"journalid=? AND domain=? AND blobid=?",
undef, $u->{userid},
LJ::get_blob_domainid("phonepost"),
$blobid);
if (! $has_blob) {
$dbcm->do("UPDATE phonepostentry SET location='none' ".
"WHERE userid=? AND blobid=?", undef, $u->{userid}, $blobid);
print "\tnote: changed phonepost entry location to 'none'\n\n"
if $verbose;
next;
}
}
if ($besteffort && !$len) {
print STDERR "empty_phonepost userid=$u->{userid} blobid=$blobid\n";
print "\twarning: empty phonepost.\n\n"
if $verbose;
next;
}
die "Error: data from blob empty ($u->{user}, 'phonepost', $format, $blobid)\n"
unless $len;
# get filehandle to Mogile and put the file there
print "\tdata length = $len bytes, uploading to MogileFS...\n"
if $verbose;
my $fh = $LJ::MogileFS->new_file("pp:$u->{userid}:$blobid", 'phoneposts');
if ($besteffort && !$fh) {
print STDERR "new_file_failed userid=$u->{userid} blobid=$blobid\n";
print "\twarning: failed in call to new_file\n\n"
if $verbose;
next;
}
die "Unable to get filehandle to save file to MogileFS\n"
unless $fh;
# now save the file and close the handles
$fh->print($data);
my $rv = $fh->close;
if ($besteffort && !$rv) {
print STDERR "close_failed userid=$u->{userid} blobid=$blobid reason=$@\n";
print "\twarning: failed in call to cloes: $@\n\n"
if $verbose;
next;
}
die "Unable to save file to MogileFS: $@\n"
unless $rv;
# extra verification
if ($verify) {
my $data2 = $LJ::MogileFS->get_file_data("pp:$u->{userid}:$blobid");
my $eq = ($data2 && $$data2 eq $data) ? 1 : 0;
if ($besteffort && !$eq) {
print STDERR "verify_failed userid=$u->{userid} blobid=$blobid\n";
print "\twarning: verify failed; phone post not updated\n\n"
if $verbose;
next;
}
die "\tERROR: phone post NOT stored successfully, content mismatch\n"
unless $eq;
print "\tverified length = " . length($$data2) . " bytes...\n"
if $verbose;
}
# done moving this phone post
unless ($dryrun) {
print "\tupdating database for this phone post...\n"
if $verbose;
$dbcm->do("UPDATE phonepostentry SET location = 'mogile' WHERE userid = ? AND blobid = ?",
undef, $u->{userid}, $blobid);
}
# get the paths so the user can verify if they want
if ($verbose) {
my @paths = $LJ::MogileFS->get_paths("pp:$u->{userid}:$blobid", 1);
print "\tverify mogile path: $_\n" foreach @paths;
print "\tphone post update complete.\n\n";
}
}
}
# a sub to get a cluster handle and set it up for our use
sub get_db_handle {
my $cid = shift;
my $dbcm = LJ::get_cluster_master({ raw => 1 }, $cid);
unless ($dbcm) {
print STDERR "handle_unavailable clusterid=$cid\n";
die "ERROR: unable to get raw handle to cluster $cid\n";
}
eval {
$dbcm->do("SET wait_timeout = 28800");
die $dbcm->errstr if $dbcm->err;
};
die "Couldn't set wait_timeout on $cid: $@\n" if $@;
$dbcm->{'RaiseError'} = 1;
return $dbcm;
}

View File

@@ -0,0 +1,318 @@
#!/usr/bin/perl
use strict;
use lib "$ENV{LJHOME}/cgi-bin";
require 'ljlib.pl';
use LJ::Blob;
use LJ::User;
use Getopt::Long;
use IPC::Open3;
use Digest::MD5;
# this script is a migrater that will move userpics from an old storage method
# into mogilefs.
# the basic theory is that we iterate over all clusters, find all userpics that
# aren't in mogile right now, and put them there
# determine
my ($one, $besteffort, $dryrun, $user, $verify, $verbose, $clusters, $purge);
my $rv = GetOptions("best-effort" => \$besteffort,
"one" => \$one,
"dry-run" => \$dryrun,
"user=s" => \$user,
"verify" => \$verify,
"verbose" => \$verbose,
"purge-old" => \$purge,
"clusters=s" => \$clusters,);
unless ($rv) {
die <<ERRMSG;
This script supports the following command line arguments:
--clusters=X[-Y]
Only handle clusters in this range. You can specify a
single number, or a range of two numbers with a dash.
--user=username
Only move this particular user.
--one
Only move one user. (But it moves all their pictures.)
This is used for testing.
--verify
If specified, this option will reload the userpic from
MogileFS and make sure it's been stored successfully.
--dry-run
If on, do not update the database. This mode will put the
userpic in MogileFS and give you paths to examine the picture
and make sure everything is okay. It will not update the
userpic2 table, though.
--best-effort
Normally, if a problem is encountered (null userpic, md5
mismatch, connection failure, etc) the script will die to
make sure everything goes well. With this flag, we don't
die and instead just print to standard error.
--purge-old
Sometimes we run into data that is for users that have since
moved to a different cluster. Normally we ignore it, but
with this option, we'll clean that data up as we find it.
--verbose
Be very chatty.
ERRMSG
}
# make sure ljconfig is setup right (or so we hope)
die "Please define a 'userpics' class in your \%LJ::MOGILEFS_CONFIG\n"
unless defined $LJ::MOGILEFS_CONFIG{classes}->{userpics};
die "Unable to find MogileFS object (\%LJ::MOGILEFS_CONFIG not setup?)\n"
unless $LJ::MogileFS;
# setup stderr if we're in best effort mode
if ($besteffort) {
my $oldfd = select(STDERR);
$| = 1;
select($oldfd);
}
# operation modes
if ($user) {
# move a single user
my $u = LJ::load_user($user);
die "No such user: $user\n" unless $u;
handle_userid($u->{userid}, $u->{clusterid});
} else {
# parse the clusters
my @clusters;
if ($clusters) {
if ($clusters =~ /^(\d+)(?:-(\d+))?$/) {
my ($min, $max) = map { $_ + 0 } ($1, $2 || $1);
push @clusters, $_ foreach $min..$max;
} else {
die "Error: --clusters argument not of right format.\n";
}
} else {
@clusters = @LJ::CLUSTERS;
}
# now iterate over the clusters to pick
my $ctotal = scalar(@clusters);
my $ccount = 0;
foreach my $cid (sort { $a <=> $b } @clusters) {
# status report
$ccount++;
print "\nChecking cluster $cid...\n\n";
# get a handle
my $dbcm = get_db_handle($cid);
# get all userids
print "Getting userids...\n";
my $limit = $one ? 'LIMIT 1' : '';
my $userids = $dbcm->selectcol_arrayref
("SELECT DISTINCT userid FROM userpic2 WHERE location <> 'mogile' OR location IS NULL $limit");
my $total = scalar(@$userids);
# iterate over userids
my $count = 0;
print "Beginning iteration over userids...\n";
foreach my $userid (@$userids) {
# move this userpic
my $extra = sprintf("[%6.2f%%, $ccount of $ctotal] ", (++$count/$total*100));
handle_userid($userid, $cid, $extra);
}
# don't hit up more clusters
last if $one;
}
}
print "\n";
print "Updater terminating.\n";
#############################################################################
### helper subs down here
# take a userid and move their pictures. returns 0 on error, 1 on successful
# move of a user's pictures, and 2 meaning the user isn't ready for moving
# (dversion < 7, etc)
sub handle_userid {
my ($userid, $cid, $extra) = @_;
# load user to move and do some sanity checks
my $u = LJ::load_userid($userid);
unless ($u) {
LJ::end_request();
LJ::start_request();
$u = LJ::load_userid($userid);
}
die "ERROR: Unable to load userid $userid\n"
unless $u;
# if they're expunged, they might have data somewhere if they were
# copy-moved from A to B, then expunged on B. now we're on A and
# need to delete it ourselves (if purge-old is on)
if ($u->{clusterid} == 0 && $u->{statusvis} eq "X") {
return unless $purge;
# if we get here, the user has indicated they want data purged, get handle
my $to_purge_dbcm = get_db_handle($cid);
my $ct = $to_purge_dbcm->do("DELETE FROM userpic2 WHERE userid = ?", undef, $u->{userid});
print "\tnotice: purged $ct old rows.\n\n"
if $verbose;
return;
}
# get a handle
my $dbcm = get_db_handle($u->{clusterid});
# print that we're doing this user
print "$extra$u->{user}($u->{userid})\n";
# if a user has been moved to another cluster, but the source data from
# userpic2 wasn't deleted, we need to ignore the user or purge their data
if ($u->{clusterid} != $cid) {
return unless $purge;
# verify they have some rows on the new side
my $count = $dbcm->selectrow_array
("SELECT COUNT(*) FROM userpic2 WHERE userid = ?",
undef, $u->{userid});
return unless $count;
# if we get here, the user has indicated they want data purged, get handle
my $to_purge_dbcm = get_db_handle($cid);
# delete the old data
if ($dryrun) {
print "\tnotice: need to delete userpic2 rows.\n\n"
if $verbose;
} else {
my $ct = $to_purge_dbcm->do("DELETE FROM userpic2 WHERE userid = ?", undef, $u->{userid});
print "\tnotice: purged $ct old rows.\n\n"
if $verbose;
}
# nothing else to do here
return;
}
# get all their photos that aren't in mogile already
my $picids = $dbcm->selectall_arrayref
("SELECT picid, md5base64, fmt FROM userpic2 WHERE userid = ? AND (location <> 'mogile' OR location IS NULL)",
undef, $u->{userid});
return unless @$picids;
# now we have a userid and picids, get the photos from the blob server
foreach my $row (@$picids) {
my ($picid, $md5, $fmt) = @$row;
print "\tstarting move for picid $picid\n"
if $verbose;
my $format = { G => 'gif', J => 'jpg', P => 'png' }->{$fmt};
my $data = LJ::Blob::get($u, "userpic", $format, $picid);
# get length
my $len = length($data);
if ($besteffort && !$len) {
print STDERR "empty_userpic userid=$u->{userid} picid=$picid\n";
print "\twarning: empty userpic.\n\n"
if $verbose;
next;
}
die "Error: data from blob empty ($u->{user}, 'userpic', $format, $picid)\n"
unless $len;
# verify the md5 of this picture with what's in the database
my $blobmd5 = Digest::MD5::md5_base64($data);
if ($besteffort && ($md5 ne $blobmd5)) {
print STDERR "md5_mismatch userid=$u->{userid} picid=$picid dbmd5=$md5 blobmd5=$blobmd5\n";
print "\twarning: md5 mismatch; database=$md5, blobserver=$blobmd5\n\n"
if $verbose;
next;
}
die "\tError: data from blobserver md5 mismatch: database=$md5, blobserver=$blobmd5\n"
unless $md5 eq $blobmd5;
print "\tverified md5; database=$md5, blobserver=$blobmd5\n"
if $verbose;
# get filehandle to Mogile and put the file there
print "\tdata length = $len bytes, uploading to MogileFS...\n"
if $verbose;
my $fh = $LJ::MogileFS->new_file($u->mogfs_userpic_key($picid), 'userpics');
if ($besteffort && !$fh) {
print STDERR "new_file_failed userid=$u->{userid} picid=$picid\n";
print "\twarning: failed in call to new_file\n\n"
if $verbose;
next;
}
die "Unable to get filehandle to save file to MogileFS\n"
unless $fh;
# now save the file and close the handles
$fh->print($data);
my $rv = $fh->close;
if ($besteffort && !$rv) {
print STDERR "close_failed userid=$u->{userid} picid=$picid reason=$@\n";
print "\twarning: failed in call to cloes: $@\n\n"
if $verbose;
next;
}
die "Unable to save file to MogileFS: $@\n"
unless $rv;
# extra verification
if ($verify) {
my $data2 = $LJ::MogileFS->get_file_data($u->mogfs_userpic_key($picid));
my $eq = ($data2 && $$data2 eq $data) ? 1 : 0;
if ($besteffort && !$eq) {
print STDERR "verify_failed userid=$u->{userid} picid=$picid\n";
print "\twarning: verify failed; picture not updated\n\n"
if $verbose;
next;
}
die "\tERROR: picture NOT stored successfully, content mismatch\n"
unless $eq;
print "\tverified length = " . length($$data2) . " bytes...\n"
if $verbose;
}
# done moving this picture
unless ($dryrun) {
print "\tupdating database for this picture...\n"
if $verbose;
$dbcm->do("UPDATE userpic2 SET location = 'mogile' WHERE userid = ? AND picid = ?",
undef, $u->{userid}, $picid);
}
# get the paths so the user can verify if they want
if ($verbose) {
my @paths = $LJ::MogileFS->get_paths($u->mogfs_userpic_key($picid), 1);
print "\tverify mogile path: $_\n" foreach @paths;
print "\tverify site url: $LJ::SITEROOT/userpic/$picid/$u->{userid}\n";
print "\tpicture update complete.\n\n";
}
}
}
# a sub to get a cluster handle and set it up for our use
sub get_db_handle {
my $cid = shift;
my $dbcm = LJ::get_cluster_master({ raw => 1 }, $cid);
unless ($dbcm) {
print STDERR "handle_unavailable clusterid=$cid\n";
die "ERROR: unable to get raw handle to cluster $cid\n";
}
eval {
$dbcm->do("SET wait_timeout = 28800");
die $dbcm->errstr if $dbcm->err;
};
die "Couldn't set wait_timeout on $cid: $@\n" if $@;
$dbcm->{'RaiseError'} = 1;
return $dbcm;
}

View File

@@ -0,0 +1,162 @@
#!/usr/bin/perl
use strict;
use lib "$ENV{'LJHOME'}/cgi-bin";
require 'ljlib.pl';
# so output happens quickly
$| = 1;
# make sure we got a parameter
my $propname = shift;
die "ERROR: no property specified\n" unless $propname;
# verify it's a valid property
my $prop = LJ::get_prop('user', $propname);
# see if we know how to handle this parameter
if ($propname eq 'external_foaf_url' && $prop->{cldversion} == 0) {
# this one is simple; we're moving this one to the clusters 1000 users at a time
print "Beginning initial data migration...\n";
cluster_property($prop);
# update the property to be indexed
print "Updating property data in userproplist...\n";
update_property($prop, { indexed => 0, cldversion => 4 });
# strongly recommend a restart
print "\n";
print "* " x 38 . "\n";
print "WARNING: It is recommended that you restart your web nodes now to cause the\n";
print " updated property to start to take effect. Please press enter when\n";
print " this is done.\n";
print "* " x 38 . "\n";
readline STDIN;
# now let's hope they restarted and let's migrate anybody who is still stuck
print "Beginning final data migration...\n";
cluster_property($prop);
# done
print "Finished migrating external_foaf_url property.\n";
} else {
# don't know how to handle it
die "ERROR: don't know how to handle '$propname' (has it already been handled?)\n";
}
##############################################################################
### helper subs
sub cluster_property {
my $prop = shift;
# some state tracking information
my (%dbcms); # ( clusterid => dbcm )
my (%to_write); # ( clusterid => [ [ userid, value ], [ userid, value ], ... ]
# note: livejournal has only about 7500 external_foaf_urls... those should
# be moved in less time than any database handle will time out, so I've made
# the decision not to worry about handle timeouts right now. all other sites
# are probably no more than this size, so it should be fine for everybody.
# setup our flushing sub that we'll need later
my $flush = sub {
my $cid = shift;
# get the ref from to_write etc
my $aref = $to_write{$cid};
delete $to_write{$cid};
# get handle to database if needed
my $dbcm = $dbcms{$cid} || ($dbcms{$cid} = LJ::get_cluster_master($cid));
# notice that we're flushing data
print "\tflushing " . scalar(@$aref) . " items to cluster $cid...";
# now construct SQL
my $repstr = join(', ', map { "($_->[0], $prop->{upropid}, " .
$dbcm->quote($_->[1]) . ")" } @$aref);
$dbcm->do("REPLACE INTO userproplite2 (userid, upropid, value) VALUES $repstr");
die "ERROR: database: " . $dbcm->errstr . "\n" if $dbcm->err;
# done, status update
print "flushed\n";
};
# start our main loop
while (1) {
# data storage for each loop
my (%users, %values); # ( userid => user object or value )
# clear our handles
$LJ::DBIRole->flush_cache();
# get main database handle
my $dbh = LJ::get_db_writer();
# select up to 1000 userid:value tuples
print "Getting values...";
my $vals = $dbh->selectall_arrayref
('SELECT userid, value FROM userprop WHERE upropid = ? LIMIT 1000',
undef, $prop->{upropid});
die "ERROR: database: " . $dbh->errstr . "\n" if $dbh->err;
print "got " . scalar(@$vals) . " values.\n";
# short circuit if we have 0
return 1 if scalar @$vals == 0;
# get the userids to load
my @to_load;
foreach my $row (@$vals) {
my ($userid, $value) = @$row;
$values{$userid} = $value;
push @to_load, $userid;
}
# now load the users in one big grab
print "Loading users...";
LJ::load_userids_multiple([ map { $_ => \$users{$_} } @to_load ]);
print "loaded.\n";
# now push data onto the cluster lists
while (my ($userid, $value) = each %values) {
my $cid = $users{$userid}->{clusterid};
# clusterid 0 means the user is expunged or somesuch, so we
# don't weant to migrate their settings anywhere and should
# just delete it.
next unless $cid;
# now push this onto the to_write array
$to_write{$cid} ||= [];
push @{$to_write{$cid}}, [ $userid, $value ];
# now, flush this list if it's large (100 or more)
$flush->($cid) if scalar @{$to_write{$cid}} >= 100;
}
# now flush everything that's left
$flush->($_) foreach keys %to_write;
# now delete from the global for items that we've written
print "Deleting " . scalar(keys %values) . " items from global...";
my $instr = join(',', map { $_ + 0 } keys %values);
$dbh->do("DELETE FROM userprop WHERE upropid = $prop->{upropid} AND userid IN ($instr)");
die "ERROR: database: " . $dbh->errstr . "\n" if $dbh->err;
print "deleted.\n";
# last if we had less than 1000 this time
last if scalar @$vals < 1000;
}
}
sub update_property {
my ($prop, $sets) = @_;
die "ERROR: nothing to set\n" unless %$sets;
# now make the updates they want
my $dbh = LJ::get_db_writer();
my $updstr = join(', ', map { "$_ = " . $dbh->quote($sets->{$_}) } keys %$sets);
$dbh->do("UPDATE userproplist SET $updstr WHERE upropid = $prop->{upropid}");
die "ERROR: database: " . $dbh->errstr . "\n" if $dbh->err;
}

View File

@@ -0,0 +1,107 @@
MOOD 1 aggravated 2
MOOD 2 angry 0
MOOD 3 annoyed 2
MOOD 4 anxious 46
MOOD 5 bored 25
MOOD 6 confused 0
MOOD 7 crappy 25
MOOD 8 cranky 2
MOOD 9 depressed 25
MOOD 10 discontent 25
MOOD 11 energetic 0
MOOD 12 enraged 2
MOOD 14 exhausted 74
MOOD 15 happy 0
MOOD 16 high 41
MOOD 18 hungry 74
MOOD 19 infuriated 2
MOOD 20 irate 2
MOOD 21 jubilant 15
MOOD 22 lonely 25
MOOD 23 moody 2
MOOD 25 sad 0
MOOD 26 satisfied 53
MOOD 28 stressed 2
MOOD 30 thoughtful 0
MOOD 31 tired 14
MOOD 32 touched 15
MOOD 33 lazy 61
MOOD 34 drunk 74
MOOD 41 excited 15
MOOD 42 relieved 26
MOOD 43 hopeful 70
MOOD 44 amused 15
MOOD 46 scared 0
MOOD 47 frustrated 2
MOOD 49 sleepy 31
MOOD 51 groggy 31
MOOD 52 hyper 11
MOOD 53 relaxed 15
MOOD 54 restless 74
MOOD 55 disappointed 25
MOOD 56 curious 6
MOOD 61 okay 0
MOOD 68 calm 53
MOOD 70 optimistic 15
MOOD 71 pessimistic 38
MOOD 74 uncomfortable 25
MOOD 79 embarrassed 46
MOOD 80 envious 10
MOOD 81 sympathetic 25
MOOD 82 sick 74
MOOD 83 hot 74
MOOD 84 cold 74
MOOD 85 worried 25
MOOD 86 loved 15
MOOD 87 awake 0
MOOD 88 working 0
MOOD 89 productive 88
MOOD 90 accomplished 88
MOOD 91 busy 88
MOOD 93 full 26
MOOD 95 grumpy 2
MOOD 96 weird 66
MOOD 98 ecstatic 15
MOOD 101 contemplative 30
MOOD 102 nerdy 0
MOOD 103 geeky 102
MOOD 104 cynical 2
MOOD 106 crazy 66
MOOD 107 creative 88
MOOD 109 pleased 15
MOOD 112 irritated 2
MOOD 113 blank 78
MOOD 114 apathetic 78
MOOD 115 dorky 102
MOOD 116 impressed 15
MOOD 117 naughty 36
MOOD 119 dirty 74
MOOD 120 giddy 66
MOOD 121 surprised 15
MOOD 122 shocked 121
MOOD 123 rejected 25
MOOD 124 numb 25
MOOD 125 cheerful 15
MOOD 126 good 15
MOOD 127 distressed 4
MOOD 128 intimidated 46
MOOD 130 devious 0
MOOD 131 thankful 15
MOOD 132 grateful 15
MOOD 133 jealous 25
MOOD 134 nervous 46
MOODTHEME Classic Smileys : The classic little yellow (and other color) smiley faces.
2 /img/mood/classic/angry.gif 15 15
6 /img/mood/classic/confused.gif 19 17
11 /img/mood/classic/energetic.gif 17 17
15 /img/mood/classic/smile.gif 15 15
25 /img/mood/classic/sad.gif 15 15
30 /img/mood/classic/thinking.gif 22 21
31 /img/mood/classic/tired.gif 19 17
34 /img/mood/classic/drunk.gif 15 15
46 /img/mood/classic/shock.gif 15 15
61 /img/mood/classic/blah.gif 15 15
66 /img/mood/classic/wink.gif 15 15
79 /img/mood/classic/blush.gif 15 15
82 /img/mood/classic/sick.gif 15 15
130 /img/mood/classic/devious.gif 15 15

View File

@@ -0,0 +1,886 @@
#!/usr/bin/perl
#
# Moves a user between clusters.
#
use strict;
use Getopt::Long;
my $opt_del = 0;
my $opt_destdel = 0;
my $opt_useslow = 0;
my $opt_slowalloc = 0;
my $opt_verbose = 1;
my $opt_movemaster = 0;
my $opt_prelocked = 0;
my $opt_expungedel = 0;
my $opt_ignorebit = 0;
exit 1 unless GetOptions('delete' => \$opt_del,
'destdelete' => \$opt_destdel,
'useslow' => \$opt_useslow, # use slow db role for read
'slowalloc' => \$opt_slowalloc, # see note below
'verbose=i' => \$opt_verbose,
'movemaster|mm' => \$opt_movemaster,
'prelocked' => \$opt_prelocked,
'expungedel' => \$opt_expungedel,
'ignorebit' => \$opt_ignorebit,
);
my $optv = $opt_verbose;
require "$ENV{'LJHOME'}/cgi-bin/ljlib.pl";
require "$ENV{'LJHOME'}/cgi-bin/ljcmdbuffer.pl";
my $dbh = LJ::get_dbh({raw=>1}, "master");
die "No master db available.\n" unless $dbh;
$dbh->do("SET wait_timeout=28800");
my $dbr = $dbh;
if ($opt_useslow) {
$dbr = LJ::get_dbh({raw=>1}, "slow");
unless ($dbr) { die "Can't get slow db from which to read.\n"; }
}
my $user = LJ::canonical_username(shift @ARGV);
my $dclust = shift @ARGV;
# tables which are dumbly copied by sucking all into memory first.
# use smarter mover code for anything that shouldn't all go into memory.
# also, to use this you have to define the primary keys below
my @manual_move = qw(loginstall ratelog sessions userproplite2
sessions_data userbio userpicblob2 userpropblob
s1usercache modlog modblob counter
s1style s1overrides links userblob clustertrack2);
sub usage {
die "Usage:\n movecluster.pl <user> <destination cluster #>\n";
}
usage() unless defined $user;
usage() unless defined $dclust;
die "Failed to get move lock.\n"
unless ($dbh->selectrow_array("SELECT GET_LOCK('moveucluster-$user', 10)"));
my $u = $dbh->selectrow_hashref("SELECT * FROM user WHERE user=?", undef, $user);
die "Non-existent user $user.\n" unless $u;
die "Can't move back to legacy cluster 0\n" unless $dclust;
my $dbch = LJ::get_cluster_master({raw=>1}, $dclust);
die "Undefined or down cluster \#$dclust\n" unless $dbch;
$dbch->do("SET wait_timeout=28800");
my $separate_cluster = LJ::use_diff_db("master", "cluster$dclust");
$dbh->{'RaiseError'} = 1;
$dbch->{'RaiseError'} = 1;
my $sclust = $u->{'clusterid'};
if ($sclust == $dclust) {
die "User '$user' is already on cluster $dclust\n";
}
if ($sclust) {
verify_movable_tables();
}
# original cluster db handle.
my $dbo;
if ($sclust) {
$dbo = $opt_movemaster ?
LJ::get_dbh({raw=>1}, "cluster$u->{clusterid}movemaster") :
LJ::get_cluster_master({raw=>1}, $u);
die "Can't get source cluster handle.\n" unless $dbo;
$dbo->{'RaiseError'} = 1;
$dbo->do("SET wait_timeout=28800");
}
my $userid = $u->{'userid'};
# find readonly cap class, complain if not found
my $readonly_bit = undef;
foreach (keys %LJ::CAP) {
if ($LJ::CAP{$_}->{'_name'} eq "_moveinprogress" &&
$LJ::CAP{$_}->{'readonly'} == 1) {
$readonly_bit = $_;
last;
}
}
unless (defined $readonly_bit) {
die "Won't move user without %LJ::CAP capability class named '_moveinprogress' with readonly => 1\n";
}
# make sure a move isn't already in progress
if ($opt_prelocked) {
unless (($u->{'caps'}+0) & (1 << $readonly_bit)) {
die "User '$user' should have been prelocked.\n";
}
} else {
if (($u->{'caps'}+0) & (1 << $readonly_bit)) {
die "User '$user' is already in the process of being moved? (cap bit $readonly_bit set)\n"
unless $opt_ignorebit;
}
}
if ($opt_expungedel && $u->{'statusvis'} eq "D" &&
LJ::mysqldate_to_time($u->{'statusvisdate'}) < time() - 86400*31) {
print "Expunging user '$u->{'user'}'\n";
$dbh->do("INSERT INTO clustermove (userid, sclust, dclust, timestart, timedone) ".
"VALUES (?,?,?,UNIX_TIMESTAMP(),UNIX_TIMESTAMP())", undef,
$userid, $sclust, 0);
LJ::update_user($userid, { clusterid => 0,
statusvis => 'X',
raw => "caps=caps&~(1<<$readonly_bit), statusvisdate=NOW()" });
exit 0;
}
print "Moving '$u->{'user'}' from cluster $sclust to $dclust\n" if $optv >= 1;
# mark that we're starting the move
$dbh->do("INSERT INTO clustermove (userid, sclust, dclust, timestart) ".
"VALUES (?,?,?,UNIX_TIMESTAMP())", undef, $userid, $sclust, $dclust);
my $cmid = $dbh->{'mysql_insertid'};
# set readonly cap bit on user
LJ::update_user($userid, { raw => "caps=caps|(1<<$readonly_bit)" })
unless $opt_prelocked;
$dbh->do("SELECT RELEASE_LOCK('moveucluster-$user')");
unless ($opt_prelocked) {
# wait a bit for writes to stop if journal is somewhat active (last week update)
my $secidle = $dbh->selectrow_array("SELECT UNIX_TIMESTAMP()-UNIX_TIMESTAMP(timeupdate) ".
"FROM userusage WHERE userid=$userid");
if ($secidle) {
sleep(2) unless $secidle > 86400*7;
sleep(1) unless $secidle > 86400;
}
}
# make sure slow is caught up:
if ($opt_useslow)
{
my $ms = $dbh->selectrow_hashref("SHOW MASTER STATUS");
my $loop = 1;
while ($loop) {
my $ss = $dbr->selectrow_hashref("SHOW SLAVE STATUS");
$loop = 0;
unless ($ss->{'Log_File'} gt $ms->{'File'} ||
($ss->{'Log_File'} eq $ms->{'File'} && $ss->{'Pos'} >= $ms->{'Position'}))
{
$loop = 1;
print "Waiting for slave ($ss->{'Pos'} < $ms->{'Position'})\n";
sleep 1;
}
}
}
my $last = time();
my $stmsg = sub {
my $msg = shift;
my $now = time();
return if ($now < $last + 1);
$last = $now;
print $msg;
};
my %bufcols = (); # db|table -> scalar "(foo, anothercol, lastcol)" or undef or ""
my %bufrows = (); # db|table -> [ []+ ]
my %bufdbmap = (); # scalar(DBI hashref) -> DBI hashref
my $flush_buffer = sub {
my $dbandtable = shift;
my ($db, $table) = split(/\|/, $dbandtable);
$db = $bufdbmap{$db};
return unless exists $bufcols{$dbandtable};
my $sql = "REPLACE INTO $table $bufcols{$dbandtable} VALUES ";
$sql .= join(", ",
map { my $r = $_;
"(" . join(", ",
map { $db->quote($_) } @$r) . ")" }
@{$bufrows{$dbandtable}});
$db->do($sql);
delete $bufrows{$dbandtable};
delete $bufcols{$dbandtable};
};
my $flush_all = sub {
foreach (keys %bufcols) {
$flush_buffer->($_);
}
};
my $replace_into = sub {
my $db = ref $_[0] ? shift : $dbch; # optional first arg
my ($table, $cols, $max, @vals) = @_;
my $dbandtable = scalar($db) . "|$table";
$bufdbmap{$db} = $db;
if (exists $bufcols{$dbandtable} && $bufcols{$dbandtable} ne $cols) {
$flush_buffer->($dbandtable);
}
$bufcols{$dbandtable} = $cols;
push @{$bufrows{$dbandtable}}, [ @vals ];
if (scalar @{$bufrows{$dbandtable}} > $max) {
$flush_buffer->($dbandtable);
}
};
# assume never tried to move this user before. however, if reported crap
# in the oldids table, we'll revert to slow alloc_id functionality,
# where we do a round-trip to $dbh for everything and see if every id
# has been remapped already. otherwise we do it in perl and batch
# updates to the oldids table, which is the common/fast case.
my $first_move = ! $opt_slowalloc;
my %alloc_data;
my %alloc_arealast;
my $alloc_id = sub {
my ($area, $orig) = @_;
# fast version
if ($first_move) {
my $id = $alloc_data{$area}->{$orig} = ++$alloc_arealast{$area};
$replace_into->($dbh, "oldids", "(area, oldid, userid, newid)", 250,
$area, $orig, $userid, $id);
return $id;
}
# slow version
$dbh->{'RaiseError'} = 0;
$dbh->do("INSERT INTO oldids (area, oldid, userid, newid) ".
"VALUES ('$area', $orig, $userid, NULL)");
my $id;
if ($dbh->err) {
$id = $dbh->selectrow_array("SELECT newid FROM oldids WHERE area='$area' AND oldid=$orig");
} else {
$id = $dbh->{'mysql_insertid'};
}
$dbh->{'RaiseError'} = 1;
$alloc_data{$area}->{$orig} = $id;
return $id;
};
my $bufread;
if ($sclust == 0)
{
# do bio stuff
{
my $bio = $dbr->selectrow_array("SELECT bio FROM userbio WHERE userid=$userid");
my $bytes = length($bio);
$dbch->do("REPLACE INTO dudata (userid, area, areaid, bytes) VALUES ($userid, 'B', 0, $bytes)");
if ($separate_cluster) {
$bio = $dbh->quote($bio);
$dbch->do("REPLACE INTO userbio (userid, bio) VALUES ($userid, $bio)");
}
}
my @itemids = reverse @{$dbr->selectcol_arrayref("SELECT itemid FROM log ".
"WHERE ownerid=$u->{'userid'} ".
"ORDER BY ownerid, rlogtime")};
$bufread = make_buffer_reader("itemid", \@itemids);
my $todo = @itemids;
my $done = 0;
my $stime = time();
print "Total: $todo\n";
# moving time, journal item at a time, and everything recursively under it
foreach my $itemid (@itemids) {
movefrom0_logitem($itemid);
$done++;
my $percent = $done/$todo;
my $elapsed = time() - $stime;
my $totaltime = $elapsed * (1 / $percent);
my $timeremain = int($totaltime - $elapsed);
$stmsg->(sprintf "$user: copy $done/$todo (%.2f%%) +${elapsed}s -${timeremain}s\n", 100*$percent);
}
$flush_all->();
# update their memories. in particular, any memories of their own
# posts need to to be updated from the (0, globalid) to
# (journalid, jitemid) format, to make the memory filter feature
# work. (it checks the first 4 bytes only, not joining the
# globalid on the clustered log table)
print "Fixing memories.\n";
my @fix = @{$dbh->selectall_arrayref("SELECT memid, jitemid FROM memorable WHERE ".
"userid=$u->{'userid'} AND journalid=0")};
foreach my $f (@fix) {
my ($memid, $newid) = ($f->[0], $alloc_data{'L'}->{$f->[1]});
next unless $newid;
my ($newid2, $anum) = $dbch->selectrow_array("SELECT jitemid, anum FROM log2 ".
"WHERE journalid=$u->{'userid'} AND ".
"jitemid=$newid");
if ($newid2 == $newid) {
my $ditemid = $newid * 256 + $anum;
print "UPDATE $memid TO $ditemid\n";
$dbh->do("UPDATE memorable SET journalid=$u->{'userid'}, jitemid=$ditemid ".
"WHERE memid=$memid");
}
}
# fix polls
print "Fixing polls.\n";
@fix = @{$dbh->selectall_arrayref("SELECT pollid, itemid FROM poll ".
"WHERE journalid=$u->{'userid'}")};
foreach my $f (@fix) {
my ($pollid, $newid) = ($f->[0], $alloc_data{'L'}->{$f->[1]});
next unless $newid;
my ($newid2, $anum) = $dbch->selectrow_array("SELECT jitemid, anum FROM log2 ".
"WHERE journalid=$u->{'userid'} AND ".
"jitemid=$newid");
if ($newid2 == $newid) {
my $ditemid = $newid * 256 + $anum;
print "UPDATE $pollid TO $ditemid\n";
$dbh->do("UPDATE poll SET itemid=$ditemid WHERE pollid=$pollid");
}
}
# move userpics
print "Copying over userpics.\n";
my @pics = @{$dbr->selectcol_arrayref("SELECT picid FROM userpic WHERE ".
"userid=$u->{'userid'}")};
foreach my $picid (@pics) {
print " picid\#$picid...\n";
my $imagedata = $dbr->selectrow_array("SELECT imagedata FROM userpicblob ".
"WHERE picid=$picid");
$imagedata = $dbh->quote($imagedata);
$dbch->do("REPLACE INTO userpicblob2 (userid, picid, imagedata) VALUES ".
"($u->{'userid'}, $picid, $imagedata)");
}
$dbh->do("UPDATE userusage SET lastitemid=0 WHERE userid=$userid");
my $dversion = 2;
# if everything's good (nothing's died yet), then delete all from source
if ($opt_del)
{
# before we start deleting, record they've moved servers.
LJ::update_user($userid, { dversion => $dversion, clusterid => $dclust });
$done = 0;
$stime = time();
foreach my $itemid (@itemids) {
deletefrom0_logitem($itemid);
$done++;
my $percent = $done/$todo;
my $elapsed = time() - $stime;
my $totaltime = $elapsed * (1 / $percent);
my $timeremain = int($totaltime - $elapsed);
$stmsg->(sprintf "$user: delete $done/$todo (%.2f%%) +${elapsed}s -${timeremain}s\n", 100*$percent);
}
# delete bio from source, if necessary
if ($separate_cluster) {
$dbh->do("DELETE FROM userbio WHERE userid=$userid");
}
# delete source userpics
print "Deleting cluster0 userpics...\n";
foreach my $picid (@pics) {
print " picid\#$picid...\n";
$dbh->do("DELETE FROM userpicblob WHERE picid=$picid");
}
# unset read-only bit (marks the move is complete, also, and not aborted mid-delete)
LJ::update_user($userid, { raw => "caps=caps&~(1<<$readonly_bit)" });
$dbh->do("UPDATE clustermove SET sdeleted='1', timedone=UNIX_TIMESTAMP() ".
"WHERE cmid=?", undef, $cmid);
}
else
{
# unset readonly and move to new cluster in one update
LJ::update_user($userid, { dversion => $dversion, clusterid => $dclust,
raw => "caps=caps&~(1<<$readonly_bit)" });
$dbh->do("UPDATE clustermove SET sdeleted='0', timedone=UNIX_TIMESTAMP() ".
"WHERE cmid=?", undef, $cmid);
}
exit 0;
}
elsif ($sclust > 0)
{
print "Moving away from cluster $sclust\n" if $optv;
while (my $cmd = $dbo->selectrow_array("SELECT cmd FROM cmdbuffer WHERE journalid=$userid")) {
my $dbcm = LJ::get_cluster_master($sclust);
print "Flushing cmdbuffer for cmd: $cmd\n" if $optv > 1;
LJ::Cmdbuffer::flush($dbh, $dbcm, $cmd, $userid);
}
my $pri_key = {
# flush this first:
'cmdbuffer' => 'journalid',
# this is populated as we do log/talk
'dudata' => 'userid',
# manual
'loginstall' => 'userid',
'ratelog' => 'userid',
'sessions' => 'userid',
'sessions_data' => 'userid',
'userbio' => 'userid',
'userpicblob2' => 'userid',
'userproplite2' => 'userid',
's1usercache' => 'userid',
'modlog' => 'journalid',
'modblob' => 'journalid',
'counter' => 'journalid',
'userblob' => 'journalid',
'userpropblob' => 'userid',
'clustertrack2' => 'userid',
# log
'log2' => 'journalid',
'logsec2' => 'journalid',
'logprop2' => 'journalid',
'logtext2' => 'journalid',
# talk
'talk2' => 'journalid',
'talkprop2' => 'journalid',
'talktext2' => 'journalid',
# no primary key... move up by posttime
'talkleft' => 'userid',
# s1 styles
's1style' => 'userid',
's1overrides' => 'userid',
# link lists
'links' => 'journalid',
};
# ask the local mods if they have any tables to move
my @local_tables;
my $local_tables = LJ::run_hook("moveucluster_local_tables");
if ($local_tables) {
while (my ($tab, $key) = each %$local_tables) {
push @local_tables, $tab;
$pri_key->{$tab} = $key;
}
}
my @existing_data;
print "Checking for existing data on target cluster...\n" if $optv > 1;
foreach my $table (sort keys %$pri_key) {
my $pri = $pri_key->{$table};
my $is_there = $dbch->selectrow_array("SELECT $pri FROM $table WHERE $pri=$userid LIMIT 1");
next unless $is_there;
if ($opt_destdel) {
while ($dbch->do("DELETE FROM $table WHERE $pri=$userid LIMIT 500") > 0) {
print " deleted from $table\n" if $optv;
}
} else {
push @existing_data, $table;
}
}
if (@existing_data) {
die " Existing data in tables: @existing_data\n";
}
my %pendreplace; # "logprop2:(col,col)" => { 'values' => [ [a, b, c], [d, e, f] ],
# 'bytes' => 3043, 'recs' => 35 }
my $flush = sub {
my $dest = shift;
return 1 unless $pendreplace{$dest};
my ($table, $cols) = split(/:/, $dest);
my $vals;
foreach my $v (@{$pendreplace{$dest}->{'values'}}) {
$vals .= "," if $vals;
$vals .= "(" . join(',', map { $dbch->quote($_) } @$v) . ")";
}
print " flushing write to $table\n" if $optv > 1;
$dbch->do("REPLACE INTO $table $cols VALUES $vals");
die $dbh->errstr if $dbch->err;
delete $pendreplace{$dest};
return 1;
};
my $write = sub {
my $dest = shift;
my @values = @_;
my $new_bytes = 0; foreach (@values) { $new_bytes += length($_); }
push @{$pendreplace{$dest}->{'values'}}, \@values;
$pendreplace{$dest}->{'bytes'} += $new_bytes;
$pendreplace{$dest}->{'recs'}++;
if ($pendreplace{$dest}->{'bytes'} > 1024*500 ||
$pendreplace{$dest}->{'recs'} > 500) { $flush->($dest); }
};
my @styleids = ();
# manual moving (dumb copies)
foreach my $table (@manual_move, @local_tables) {
next if ($table eq "modlog" || $table eq "modblob") && $u->{journaltype} eq "P";
print " moving $table ...\n" if $optv > 1;
my @cols;
my $sth = $dbo->prepare("DESCRIBE $table");
$sth->execute;
my $styleidcolnum = -1;
my $colnum = 0;
while ($_ = $sth->fetchrow_hashref) {
push @cols, $_->{'Field'};
$styleidcolnum = $colnum if $_->{'Field'} eq 'styleid';
$colnum++;
}
my $cols = join(',', @cols);
my $dest = "$table:($cols)";
my $pri = $pri_key->{$table};
$sth = $dbo->prepare("SELECT $cols FROM $table WHERE $pri=$userid");
$sth->execute;
while (my @vals = $sth->fetchrow_array) {
$write->($dest, @vals);
if ($styleidcolnum > -1 && $table eq 's1style') {
push @styleids, $vals[$styleidcolnum];
}
}
}
# size of bio
my $bio_size = $dbch->selectrow_array("SELECT LENGTH(bio) FROM userbio WHERE userid=$userid");
$write->("dudata:(userid,area,areaid,bytes)", $userid, 'B', 0, $bio_size) if $bio_size;
# journal items
{
my $maxjitem = $dbo->selectrow_array("SELECT MAX(jitemid) FROM log2 WHERE journalid=$userid");
my $load_amt = 1000;
my ($lo, $hi) = (1, $load_amt);
my $sth;
my $cols = "security,allowmask,journalid,jitemid,posterid,eventtime,logtime,compressed,anum,replycount,year,month,day,rlogtime,revttime"; # order matters. see indexes below
while ($lo <= $maxjitem) {
print " log ($lo - $hi, of $maxjitem)\n" if $optv > 1;
# log2/logsec2
$sth = $dbo->prepare("SELECT $cols FROM log2 ".
"WHERE journalid=$userid AND jitemid BETWEEN $lo AND $hi");
$sth->execute;
while (my @vals = $sth->fetchrow_array) {
$write->("log2:($cols)", @vals);
if ($vals[0] eq "usemask") {
$write->("logsec2:(journalid,jitemid,allowmask)",
$userid, $vals[3], $vals[1]);
}
}
# logprop2
$sth = $dbo->prepare("SELECT journalid,jitemid,propid,value ".
"FROM logprop2 WHERE journalid=$userid AND jitemid BETWEEN $lo AND $hi");
$sth->execute;
while (my @vals = $sth->fetchrow_array) {
$write->("logprop2:(journalid,jitemid,propid,value)", @vals);
}
# logtext2
$sth = $dbo->prepare("SELECT journalid,jitemid,subject,event ".
"FROM logtext2 WHERE journalid=$userid AND jitemid BETWEEN $lo AND $hi");
$sth->execute;
while (my @vals = $sth->fetchrow_array) {
my $size = length($vals[2]) + length($vals[3]);
LJ::text_compress(\$vals[3]);
$write->("logtext2:(journalid,jitemid,subject,event)", @vals);
$write->("dudata:(userid,area,areaid,bytes)", $userid, 'L', $vals[1], $size);
}
$hi += $load_amt; $lo += $load_amt;
}
}
# comments
{
my $maxtalkid = $dbo->selectrow_array("SELECT MAX(jtalkid) FROM talk2 WHERE journalid=$userid");
my $load_amt = 1000;
my ($lo, $hi) = (1, $load_amt);
my $sth;
my %cols = ('talk2' => 'journalid,jtalkid,nodetype,nodeid,parenttalkid,posterid,datepost,state',
'talkprop2' => 'journalid,jtalkid,tpropid,value',
'talktext2' => 'journalid,jtalkid,subject,body');
while ($lo <= $maxtalkid) {
print " talk ($lo - $hi, of $maxtalkid)\n" if $optv > 1;
foreach my $table (keys %cols) {
$sth = $dbo->prepare("SELECT $cols{$table} FROM $table ".
"WHERE journalid=$userid AND jtalkid BETWEEN $lo AND $hi");
$sth->execute;
while (my @vals = $sth->fetchrow_array) {
LJ::text_compress(\$vals[3]) if $table eq "talktext2";
$write->("$table:($cols{$table})", @vals);
}
}
$hi += $load_amt; $lo += $load_amt;
}
}
# talkleft table.
{
# no primary key... delete all of target first.
while ($dbch->do("DELETE FROM talkleft WHERE userid=$userid LIMIT 1000") > 0) {
print " deleted from talkleft\n" if $optv > 1;
}
my $last_max = 0;
my $cols = "userid,posttime,journalid,nodetype,nodeid,jtalkid,publicitem";
while (defined $last_max) {
print " talkleft: $last_max\n" if $optv > 1;
my $sth = $dbo->prepare("SELECT $cols FROM talkleft WHERE userid=$userid ".
"AND posttime > $last_max ORDER BY posttime LIMIT 1000");
$sth->execute;
undef $last_max;
while (my @vals = $sth->fetchrow_array) {
$write->("talkleft:($cols)", @vals);
$last_max = $vals[1];
}
}
}
# flush remaining items
foreach (keys %pendreplace) { $flush->($_); }
# unset readonly and move to new cluster in one update
LJ::update_user($userid, { clusterid => $dclust, raw => "caps=caps&~(1<<$readonly_bit)" });
print "Moved.\n" if $optv;
# delete from source cluster
if ($opt_del) {
print "Deleting from source cluster...\n" if $optv;
foreach my $table (sort keys %$pri_key) {
my $pri = $pri_key->{$table};
while ($dbo->do("DELETE FROM $table WHERE $pri=$userid LIMIT 500") > 0) {
print " deleted from $table\n" if $optv;
}
}
# s1stylecache table
if (@styleids) {
my $styleids_in = join(",", map { $dbo->quote($_) } @styleids);
if ($dbo->do("DELETE FROM s1stylecache WHERE styleid IN ($styleids_in)") > 0) {
print " deleted from s1stylecache\n" if $optv;
}
}
} else {
# at minimum, we delete the clustertrack2 row so it doesn't get
# included in a future ljumover.pl query from that cluster.
$dbo->do("DELETE FROM clustertrack2 WHERE userid=$userid");
}
$dbh->do("UPDATE clustermove SET sdeleted=?, timedone=UNIX_TIMESTAMP() ".
"WHERE cmid=?", undef, $opt_del ? 1 : 0, $cmid);
exit 0;
}
sub deletefrom0_logitem
{
my $itemid = shift;
# delete all the comments
my $talkids = $dbh->selectcol_arrayref("SELECT talkid FROM talk ".
"WHERE nodetype='L' AND nodeid=$itemid");
my $talkidin = join(",", @$talkids);
if ($talkidin) {
foreach my $table (qw(talktext talkprop talk)) {
$dbh->do("DELETE FROM $table WHERE talkid IN ($talkidin)");
}
}
$dbh->do("DELETE FROM logsec WHERE ownerid=$userid AND itemid=$itemid");
foreach my $table (qw(logprop logtext log)) {
$dbh->do("DELETE FROM $table WHERE itemid=$itemid");
}
}
sub movefrom0_logitem
{
my $itemid = shift;
my $item = $bufread->(100, "SELECT * FROM log", $itemid);
my $itemtext = $bufread->(50, "SELECT itemid, subject, event FROM logtext", $itemid);
return 1 unless $item && $itemtext; # however that could happen.
# we need to allocate a new jitemid (journal-specific itemid) for this item now.
my $jitemid = $alloc_id->('L', $itemid);
unless ($jitemid) {
die "ERROR: could not allocate a new jitemid\n";
}
$dbh->{'RaiseError'} = 1;
$item->{'jitemid'} = $jitemid;
$item->{'anum'} = int(rand(256));
# copy item over:
$replace_into->("log2", "(journalid, jitemid, posterid, eventtime, logtime, ".
"compressed, security, allowmask, replycount, year, month, day, ".
"rlogtime, revttime, anum)",
50, map { $item->{$_} } qw(ownerid jitemid posterid eventtime
logtime compressed security allowmask replycount
year month day rlogtime revttime anum));
$replace_into->("logtext2", "(journalid, jitemid, subject, event)", 10,
$userid, $jitemid, map { $itemtext->{$_} } qw(subject event));
# add disk usage info! (this wasn't in cluster0 anywhere)
my $bytes = length($itemtext->{'event'}) + length($itemtext->{'subject'});
$replace_into->("dudata", "(userid, area, areaid, bytes)", 50, $userid, 'L', $jitemid, $bytes);
# add the logsec item, if necessary:
if ($item->{'security'} ne "public") {
$replace_into->("logsec2", "(journalid, jitemid, allowmask)", 50,
map { $item->{$_} } qw(ownerid jitemid allowmask));
}
# copy its logprop over:
while (my $lp = $bufread->(50, "SELECT itemid, propid, value FROM logprop", $itemid)) {
next unless $lp->{'value'};
$replace_into->("logprop2", "(journalid, jitemid, propid, value)", 50,
$userid, $jitemid, $lp->{'propid'}, $lp->{'value'});
}
# copy its talk shit over:
my %newtalkids = (0 => 0); # 0 maps back to 0 still
my $talkids = $dbr->selectcol_arrayref("SELECT talkid FROM talk ".
"WHERE nodetype='L' AND nodeid=$itemid");
my @talkids = sort { $a <=> $b } @$talkids;
my $treader = make_buffer_reader("talkid", \@talkids);
foreach my $t (@talkids) {
movefrom0_talkitem($t, $jitemid, \%newtalkids, $item, $treader);
}
}
sub movefrom0_talkitem
{
my $talkid = shift;
my $jitemid = shift;
my $newtalkids = shift;
my $logitem = shift;
my $treader = shift;
my $item = $treader->(100, "SELECT *, UNIX_TIMESTAMP(datepost) AS 'datepostunix' FROM talk", $talkid);
my $itemtext = $treader->(50, "SELECT talkid, subject, body FROM talktext", $talkid);
return 1 unless $item && $itemtext; # however that could happen.
# abort if this is a stranded entry. (shouldn't happen, anyway. even if it does, it's
# not like we're losing data: the UI (talkread.bml) won't show it anyway)
return unless defined $newtalkids->{$item->{'parenttalkid'}};
# we need to allocate a new jitemid (journal-specific itemid) for this item now.
my $jtalkid = $alloc_id->('T', $talkid);
unless ($jtalkid) {
die "ERROR: could not allocate a new jtalkid\n";
}
$newtalkids->{$talkid} = $jtalkid;
$dbh->{'RaiseError'} = 1;
# copy item over:
$replace_into->("talk2", "(journalid, jtalkid, parenttalkid, nodeid, ".
"nodetype, posterid, datepost, state)", 50,
$userid, $jtalkid, $newtalkids->{$item->{'parenttalkid'}},
$jitemid, 'L', map { $item->{$_} } qw(posterid datepost state));
$replace_into->("talktext2", "(journalid, jtalkid, subject, body)",
20, $userid, $jtalkid, map { $itemtext->{$_} } qw(subject body));
# copy its logprop over:
while (my $lp = $treader->(50, "SELECT talkid, tpropid, value FROM talkprop", $talkid)) {
next unless $lp->{'value'};
$replace_into->("talkprop2", "(journalid, jtalkid, tpropid, value)", 50,
$userid, $jtalkid, $lp->{'tpropid'}, $lp->{'value'});
}
# note that poster commented here
if ($item->{'posterid'}) {
my $pub = $logitem->{'security'} eq "public" ? 1 : 0;
my ($table, $db) = ("talkleft_xfp", $dbh);
($table, $db) = ("talkleft", $dbch) if $userid == $item->{'posterid'};
$replace_into->($db, $table, "(userid, posttime, journalid, nodetype, ".
"nodeid, jtalkid, publicitem)", 50,
$item->{'posterid'}, $item->{'datepostunix'}, $userid,
'L', $jitemid, $jtalkid, $pub);
}
}
sub make_buffer_reader
{
my $pricol = shift;
my $valsref = shift;
my %bfd; # buffer read data. halfquery -> { 'rows' => { id => [] },
# 'remain' => [], 'loaded' => { id => 1 } }
return sub
{
my ($amt, $hq, $pid) = @_;
if (not defined $bfd{$hq}->{'loaded'}->{$pid})
{
if (not exists $bfd{$hq}->{'remain'}) {
$bfd{$hq}->{'remain'} = [ @$valsref ];
}
my @todo;
for (1..$amt) {
next unless @{$bfd{$hq}->{'remain'}};
my $id = shift @{$bfd{$hq}->{'remain'}};
push @todo, $id;
$bfd{$hq}->{'loaded'}->{$id} = 1;
}
if (@todo) {
my $sql = "$hq WHERE $pricol IN (" . join(",", @todo) . ")";
my $sth = $dbr->prepare($sql);
$sth->execute;
while (my $r = $sth->fetchrow_hashref) {
push @{$bfd{$hq}->{'rows'}->{$r->{$pricol}}}, $r;
}
}
}
return shift @{$bfd{$hq}->{'rows'}->{$pid}};
};
}
# this function needs to die loudly if moveucluster.pl is unable to move
# any type of table that exists on this installation
sub verify_movable_tables {
my %table; # tablename -> unhandled flag
# first, assume everything's unhandled
foreach my $t (@LJ::USER_TABLES, @LJ::USER_TABLES_LOCAL) {
$table{$t} = 1;
}
# now, clear things we know how to move
foreach my $t (qw(cmdbuffer dudata log2 logsec2 logprop2 logtext2
talk2 talkprop2 talktext2 talkleft
), @manual_move) {
delete $table{$t};
}
# local stuff
my $local_tables = LJ::run_hook("moveucluster_local_tables");
if ($local_tables) {
while (my ($tab, $key) = each %$local_tables) {
delete $table{$tab};
}
}
# things we list as active tables but don't use yet
delete $table{"events"};
# things we don't move because it doesn't really matter
delete $table{"s1stylecache"};
delete $table{"captcha_session"};
if (%table) {
die "ERROR. Won't try to move user, because this mover script can't move all live tables for this user. List of tables without mover code available: \n -- " . join("\n -- ", sort keys %table), "\n";
}
}
1; # return true;

View File

@@ -0,0 +1,84 @@
#!/usr/bin/perl
#
# This script converts from dversion 3 to dversion 4,
# which makes most userprops clustered
#
use strict;
require "$ENV{'LJHOME'}/cgi-bin/ljlib.pl";
my $fromver = shift;
die "Usage: pop-clusterprops.pl <fromdversion>\n\t(where fromdversion is one of: 3)\n"
unless $fromver == 3;
my $dbh = LJ::get_db_writer();
my $todo = $dbh->selectrow_array("SELECT COUNT(*) FROM user WHERE dversion=$fromver");
my $done = 0;
unless ($todo) {
print "Nothing to convert.\n";
exit 0;
}
sub get_some {
my @list;
my $sth = $dbh->prepare("SELECT * FROM user WHERE dversion=$fromver LIMIT 200");
$sth->execute;
push @list, $_ while $_ = $sth->fetchrow_hashref;
@list;
}
my $tover = $fromver + 1;
print "Converting $todo users from data version $fromver to $tover...\n";
my @props;
my $sth = $dbh->prepare("SELECT upropid FROM userproplist WHERE cldversion=?");
$sth->execute($tover);
push @props, $_ while $_ = $sth->fetchrow_array;
my $in = join(',', @props);
die "No values?" unless $in;
my $start = time();
while (my @list = get_some()) {
LJ::start_request();
my %cluster; # clusterid -> [ $u* ]
foreach my $u (@list) {
push @{$cluster{$u->{'clusterid'}}}, $u;
}
foreach my $cid (keys %cluster) {
my $dbcm = LJ::get_cluster_master($cid);
next unless $dbcm;
my $uid_in = join(',', map { $_->{'userid'} } @{$cluster{$cid}});
my @vals;
foreach my $table (qw(userprop userproplite)) {
$sth = $dbh->prepare("SELECT userid, upropid, value FROM $table ".
"WHERE userid IN ($uid_in) AND upropid IN ($in)");
$sth->execute();
while (my ($uid, $pid, $v) = $sth->fetchrow_array) {
push @vals, "($uid,$pid," . $dbh->quote($v) . ")";
}
}
if (@vals) {
my $sql = "REPLACE INTO userproplite2 VALUES " . join(',', @vals);
$dbcm->do($sql);
if ($dbcm->err) {
die "Error: " . $dbcm->errstr . "\n\n(Do you need to --runsql on your clusters first?)\n";
}
$dbh->do("DELETE FROM userprop WHERE userid IN ($uid_in) AND upropid IN ($in)");
$dbh->do("DELETE FROM userproplite WHERE userid IN ($uid_in) AND upropid IN ($in)");
}
$dbh->do("UPDATE user SET dversion=$tover WHERE userid IN ($uid_in) AND dversion=$fromver");
$done += scalar @{$cluster{$cid}};
}
my $perc = $done/$todo;
my $elapsed = time() - $start;
my $total_time = $elapsed / $perc;
my $min_remain = int(($total_time - $elapsed) / 60);
printf "%d/%d complete (%.02f%%) minutes_remain=%d\n", $done, $todo, ($perc*100), $min_remain;
}

View File

@@ -0,0 +1,68 @@
#!/usr/bin/perl
#
# This script converts from dversion 2 (clustered + userpicblobs clustered)
# to dversion 3, which adds weekuserusage population.
#
use strict;
require "$ENV{'LJHOME'}/cgi-bin/ljlib.pl";
die "This script is no longer useful.\n";
my $dbh = LJ::get_db_writer();
my $todo = $dbh->selectrow_array("SELECT COUNT(*) FROM user WHERE dversion=2");
my $done = 0;
unless ($todo) {
print "Nothing to convert.\n";
exit 0;
}
sub get_some {
my @list;
my $sth = $dbh->prepare("SELECT * FROM user WHERE dversion=2 LIMIT 200");
$sth->execute;
push @list, $_ while $_ = $sth->fetchrow_hashref;
@list;
}
print "Converting $todo users from data version 2 to 3...\n";
my $start = time();
while (my @list = get_some()) {
LJ::start_request();
foreach my $u (@list) {
my $dbcm = LJ::get_cluster_master($u);
next unless $dbcm;
my %week;
my $sth = $dbcm->prepare("SELECT rlogtime FROM log2 ".
"WHERE journalid=? AND rlogtime < 2147483647");
$sth->execute($u->{'userid'});
while (my $t = $sth->fetchrow_array) {
my ($week, $uafter, $ubefore) = LJ::weekuu_parts($t);
if (! $week{$week}) {
$week{$week} = [ $uafter, $ubefore ];
} elsif ($ubefore < $week{$week}->[1]) {
$week{$week}->[1] = $ubefore;
}
}
if (%week) {
my $sql = "REPLACE INTO weekuserusage (wknum,userid,uafter,ubefore) VALUES " .
join(",", map { "($_,$u->{'userid'},$week{$_}->[0],$week{$_}->[1])" } keys %week);
my $rv = $dbh->do($sql);
die $dbh->errstr if $dbh->err;
next unless $rv; # error? try later.
}
$dbh->do("UPDATE user SET dversion=3 WHERE userid=?", undef, $u->{'userid'});
$done++;
}
my $perc = $done/$todo;
my $elapsed = time() - $start;
my $total_time = $elapsed / $perc;
my $min_remain = int(($total_time - $elapsed) / 60);
printf "%d/%d complete (%.02f%%) minutes_remain=%d\n", $done, $todo, ($perc*100), $min_remain;
}

View File

@@ -0,0 +1,85 @@
#!/usr/bin/perl
#
# Library to read/write s1styles.dat
#
sub s1styles_read
{
my $ss = {};
open (F, "$ENV{'LJHOME'}/bin/upgrading/s1styles.dat");
my $uniq;
my $entry;
my $read_entry = 0;
my $line = 0;
while (<F>)
{
$line++;
if ($read_entry && $entry)
{
if ($_ eq ".\n") {
chop $entry->{'formatdata'}; # we added a newline
$read_entry = 0;
undef $entry;
next;
}
s!^\.!!;
$entry->{'formatdata'} .= $_;
next;
}
if (m!^Style:\s*(\w+?)/(.+?)\s*$!) {
$uniq = "$1/$2";
die "Repeat style in s1styles.dat at line $line!"
if exists $ss->{$uniq};
$entry = $ss->{$uniq} = {
'type' => $1,
'styledes' => $2,
};
$read_entry = 0;
next;
}
if ($entry && $_ eq "\n") {
$read_entry = 1;
next;
}
next unless $entry;
if (/^(\w+):\s*(.+?)\s*$/) {
$entry->{$1} = $2;
next;
}
die "s1styles.dat:$line: bogus line\n" if /\S/;
}
close F;
return $ss;
}
sub s1styles_write
{
my $ss = shift;
open (F, ">$ENV{'LJHOME'}/bin/upgrading/s1styles.dat")
or die "Can't open s1styles.dat for writing.\n";
foreach my $uniq (sort keys %$ss) {
my $s = $ss->{$uniq};
print F "Style: $uniq\n";
foreach (qw(is_public is_embedded is_colorfree opt_cache lastupdate)) {
next unless exists $s->{$_};
print F "$_: $s->{$_}\n";
}
my $formatdata = $s->{'formatdata'};
$formatdata =~ s/\r//g; # die, DOS line endings!
$formatdata =~ s/\n\./\n\.\./g;
print F "\n$formatdata\n.\n\n";
}
close F;
}
1;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
################################################################
# base filename layer type parent
core1 core -
i18nc/da1 i18nc core1
i18nc/de1 i18nc core1
i18nc/en1 i18nc core1
i18nc/eo1 i18nc core1
i18nc/fi1 i18nc core1
i18nc/fr1 i18nc core1
i18nc/ja1 i18nc core1
i18nc/ru1 i18nc core1
classic/layout layout core1
classic/en i18n classic/layout
classic/themes theme+ classic/layout
cleansimple/layout layout core1
cleansimple/en i18n cleansimple/layout
cleansimple/themes theme+ cleansimple/layout
digitalmultiplex/layout layout core1
digitalmultiplex/en i18n digitalmultiplex/layout
haven/layout layout core1
haven/themes theme+ haven/layout
generator/layout layout core1
generator/en i18n generator/layout
generator/themes theme+ generator/layout
magazine/layout layout core1
magazine/en i18n magazine/layout
magazine/themes theme+ magazine/layout
notepad/layout layout core1
notepad/en i18n notepad/layout
#notepad/themes theme+ notepad/layout
punquin/layout layout core1
punquin/en i18n punquin/layout
punquin/themes theme+ punquin/layout
tabularindent/layout layout core1
tabularindent/en i18n tabularindent/layout
tabularindent/themes theme+ tabularindent/layout
sturdygesture/layout layout core1
sturdygesture/themes theme+ sturdygesture/layout
variableflow/layout layout core1
# include local file
s2layers-local.dat INCLUDE

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -0,0 +1,16 @@
# -*-s2-*-
layerinfo type = "i18n";
layerinfo name = "English";
layerinfo redist_uniq = "classic/en";
set text_meta_music = "Current Music";
set text_meta_mood = "Current Mood";
set text_permalink = "Link";
set text_post_comment = "Comment on This";
set text_post_comment_friends = "Comment on This";
set text_read_comments = "1 comment // # comments";
set text_read_comments_friends = "1 comment // # comments";

View File

@@ -0,0 +1,785 @@
# -*-s2-*-
layerinfo type = "layout";
layerinfo name = "Classic";
layerinfo redist_uniq = "classic/layout";
layerinfo previews = "classic/classic.jpg";
propgroup colors {
property Color body_bgcolor {
des = "Background color of page";
s1color = "stronger_back";
}
property Color main_bgcolor {
des = "Background color of main text area";
s1color = "page_back";
}
property Color main_fgcolor {
des = "Color of text on main text areas";
s1color = "page_text";
}
property Color headerbar_bgcolor {
des = "Background color of header bars";
s1color = "strong_back";
}
property Color headerbar_fgcolor {
des = "Color of text on header bars";
s1color = "strong_text";
}
property Color metabar_bgcolor {
des = "Background color of side bar";
s1color = "weak_back";
}
property Color metabar_fgcolor {
des = "Color of text on side bar";
s1color = "weak_text";
}
property Color page_title_color {
des = "Text color of the page's main title";
s1color = "page_text_title";
}
property Color page_subtitle_color {
des = "Text color of the page's subtitles";
s1color = "page_text_em";
}
property Color link_color {
des = "Text color of links";
s1color = "page_link";
}
property Color vlink_color {
des = "Text color of visited links";
s1color = "page_vlink";
}
property Color alink_color {
des = "Text color of active links";
s1color = "page_alink";
}
property Color comment_bar_one_bgcolor {
des = "Alternating background color for comment bars (one)";
}
property Color comment_bar_two_fgcolor {
des = "Text color on alternating comment bars (one)";
}
property Color comment_bar_two_bgcolor {
des = "Alternating background color for comment bars (two)";
}
property Color comment_bar_one_fgcolor {
des = "Text color on alternating comment bars (two)";
}
property Color comment_bar_screened_bgcolor {
des = "Background bar color for screened comments";
}
property Color comment_bar_screened_fgcolor {
des = "Text color on background bar for screened comments";
}
}
set body_bgcolor = "#6666cc";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set headerbar_bgcolor = "#c0c0ff";
set headerbar_fgcolor = "#000000";
set metabar_bgcolor = "#eeeeff";
set metabar_fgcolor = "#000000";
set page_title_color = "#8b1a1a";
set page_subtitle_color = "#c00000";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#ff00c0";
set comment_bar_one_bgcolor = "#c0c0ff";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#eeeeff";
set comment_bar_two_fgcolor = "#000000";
set comment_bar_screened_bgcolor = "#dddddd";
set comment_bar_screened_fgcolor = "#000000";
set tags_aware = true;
propgroup presentation {
property bool show_entry_userpic {
des = "Show your userpic with your journal's entries?";
}
property use font_base;
property use font_fallback;
property use page_recent_items;
property use page_friends_items;
property use view_entry_disabled;
property use use_shared_pic;
property bool show_entrynav_icons {
des = "Toggle to show the next, memory, edit, etc icons on the entry view page";
}
property string page_background_image {
des = "URL to an image to be used for the page background";
}
property use external_stylesheet;
}
set show_entry_userpic = false;
set font_base = "Arial, Helvetica";
set font_fallback = "sans-serif";
set page_recent_items = 20;
set page_friends_items = 25;
set view_entry_disabled = false;
set show_entrynav_icons = true;
set page_background_image = "";
propgroup text {
property use text_post_comment;
property use text_read_comments;
property use text_post_comment_friends;
property use text_read_comments_friends;
property use text_website_default_name;
}
function print_stylesheet ()
{
print clean_url($*page_background_image) != "" ? "body { background-image: url($*page_background_image); }" : "";
var string font;
if ($*font_base) {
$font = "\"$*font_base\"";
if ($*font_fallback != "none") {
$font = "$font, ";
}
}
if ($*font_fallback != "none") {
$font = "$font $*font_fallback";
}
if ($font != "") {
"""
body, table, td, th, .page_title, #yearheader {
font-family: $font;
}
""";
}
"""
body,.body {
background-color: $*body_bgcolor;
color: $*main_fgcolor;
padding: 5pt;
}
a, a:link {
color: $*link_color;
}
a:vlink {
color: $*vlink_color;
}
a:alink {
color: $*alink_color;
}
table.main {
background-color: $*main_bgcolor;
color: $*main_fgcolor;
}
.page_title {
color: $*page_title_color;
font-size: 18pt;
}
.view_links {
font-family: monospace;
white-space: nowrap;
}
.view_links2 {
font-family: monospace;
font-size: 9pt;
}
th.headerbar {
background-color: $*headerbar_bgcolor;
color: $*headerbar_fgcolor;
font-weight: bold;
font-size: 16pt;
text-align: left;
}
td.metabar {
text-align: right;
white-space: nowrap;
background-color: $*metabar_bgcolor;
color: $*metabar_fgcolor;
}
.subject {
color: $*page_subtitle_color;
font-weight: bold;
}
.comments {
text-align: right;
}
#yearheader {
color: $*page_subtitle_color;
font-weight: bold;
font-style: italic;
font-size: 14pt;
}
th.monthheader {
background-color: $*headerbar_bgcolor;
font-size: 12pt;
}
th.daysheader {
background-color: $*metabar_bgcolor;
font-weight: normal;
}
td.weekday_empty {
background-color: $*metabar_bgcolor;
}
.day_id {
font-weight: bold;
font-size: 10pt;
}
#archiveyearpage_nav {
font-size: 14pt;
font-weight: bold;
}
""";
}
function Page::lay_nav_blurb() { }
function Page::lay_primary_userpic() : Image {
return $.journal.default_pic;
}
function EntryPage::lay_primary_userpic() : Image {
return $.entry.userpic;
}
function Page::print_linklist() {
if (size $.linklist <= 0) {
return;
}
var bool section_open = false;
println "<span class='view_links2'>";
foreach var UserLink l ($.linklist) {
if ($l.title) {
if ($l.is_heading) {
if ($section_open) {
println "<br />";
}
println """<span style="font-weight: bold;">$l.title</span> """;
$section_open = true;
} else {
println """[<a href="$l.url">$l.title</a>]""";
}
}
}
if ($section_open) {
println "</span><br /><br />";
}
println "";
}
function Page::print ()
{
var string title = $this->title();
var string userpic;
var Image default_userpic = $this->lay_primary_userpic();
if (defined $default_userpic)
{
$userpic = "<img align='right' style='padding: 2px' src='$default_userpic.url' "+
"width='$default_userpic.width' height='$default_userpic.height' alt='' />";
}
var string website_name = $.journal.website_name ? $.journal.website_name : $*text_website_default_name;
var string website = $.journal.website_url ?
"""<td><a href="$.journal.website_url">$website_name</a></td><td class="body">&nbsp;</td>""" :
"";
var string links;
foreach var string v ($.views_order) {
$links = $links + ($.view == $v ?
"["+lang_viewname($v)+"]" :
"[<a href='$.view_url{$v}'>"+lang_viewname($v)+"</a>]");
}
"""
<html>
<head>
""";
if ($*external_stylesheet) {
println """<link rel="stylesheet" href="$.stylesheet_url" type="text/css" />""";
} else {
println """<style type="text/css">"""; print_stylesheet(); "</style>";
}
$this->print_head();
"""
<title>$title</title>
</head>
<body>
<table class="main" width='100%'><tr><td>
$userpic
<span class="page_title">$title</span>
<p class="view_links">$links</p>
""";
if (size $.linklist > 0 and $*linklist_support) {
$this->print_linklist();
}
$this->lay_nav_blurb();
$this->print_body();
"</td></tr></table>\n";
### Affliations
"<table class='main' align='right'><tr>";
print $website; "<td>"; server_sig(); "</td></tr>";
"</table>\n</body>\n</html>";
}
function print_entry (Page p, Entry e, Color bgcolor, Color fgcolor, bool hide_text)
{
var string time = $e.time->time_format();
var string userpic = "";
if (defined $e.userpic)
{
$userpic = "<img src='$e.userpic.url' alt='[User Picture]' height='$e.userpic.height' width='$e.userpic.width' />";
}
if ($e.new_day or $p.view == "entry")
{
"<tr><th colspan='2' align='left' class='headerbar'>";
print $e.time->date_format("%%month%% %%dayord%%, %%yyyy%%");
"</th></tr>\n";
} elseif ($p.view == "day") {
"<tr><th class='headerbar'>Time</td><td class='headerbar' style='width: 100%'>Event</th></tr>";
}
"<tr valign='top'>";
# Metabar
"<td style='background-color: $bgcolor;' class='metabar'>";
# Time
"<em>$time</em><br />";
# Altposter crap
if ($p.view == "friends")
{
"<strong><a style='color: $fgcolor' href='" + $e.journal->base_url() + "/'>";
print $e.journal.username;
"</a></strong><br />";
}
if ($e.journal.username != $e.poster.username)
{
"[<a href='" + $e.poster->base_url() + "/'>";
print $e.poster.username;
"</a>]<br />";
}
if ($userpic != "" and ($p.view == "friends" or $*show_entry_userpic == true))
{
print $userpic;
}
# Security icon
if ($e.security) { print $e.security_icon; }
# Permalink
"<p>[<a href='$e.permalink_url'>$*text_permalink</a>]</p>";
"</td>";
# Entry
"<td style='text-align:left'>";
if ($p.view == "entry" and $*show_entrynav_icons)
{
print "<div style='text-align: center'>";
$e->print_linkbar();
print "</div>";
}
if ($e.subject) { "\n\n<span class='subject'>$e.subject</span><br />"; }
if (not $hide_text) {
print $e.text; "\n\n";
if (size $e.metadata or size $e.tags)
{
"<p>";
foreach var string k ($e.metadata)
{
var string key = $k;
var string val = $e.metadata{$k};
if ($k == "mood") { $key = $*text_meta_mood; }
if ($k == "music") { $key = $*text_meta_music; }
if ($k == "mood" and defined $e.mood_icon)
{
var Image i = $e.mood_icon;
$val = "<img src='$i.url' width='$i.width' height='$i.height' alt='' /> $val";
}
"<strong>$key:</strong> $val<br />";
}
if ($e.tags) {
var int tcount = 0;
"<strong>Tags:</strong> ";
foreach var Tag t ($e.tags) {
"""<a rel="tag" href="$t.url">$t.name</a>""";
$tcount++;
if ($tcount != size $e.tags) { ", "; }
}
"<br />";
}
"</p>";
}
}
$e.comments->print();
"</td>";
"</tr>\n";
}
function Page::print_entry (Entry e)
{
print_entry($this, $e, $*metabar_bgcolor, $*metabar_fgcolor, false);
}
function FriendsPage::print_entry (Entry e)
{
var Friend f = $.friends{$e.journal.username};
print_entry($this, $e, $f.bgcolor, $f.fgcolor, false);
}
function RecentPage::lay_nav_blurb ()
{
var string user = "<a href='$.base_url/info'>$.journal.name</a>";
if ($.nav.skip > 0)
{
"Below are $.nav.count entries, after skipping $.nav.skip most recent ones in the \"$user\" journal:";
} else {
"Below are the $.nav.count most recent journal entries recorded in the \"$user\" journal:";
}
}
function RecentPage::print_body ()
{
var string nav = "";
if ($.nav.forward_url != "" or $.nav.backward_url != "")
{
if ($.nav.backward_url != "")
{
$nav = "<a href='$.nav.backward_url'>&lt;&lt; Previous $.nav.backward_count entries</a>";
}
if ($.nav.backward_url != "" and $.nav.forward_url != "")
{
$nav = "$nav --";
}
if ($.nav.forward_url != "")
{
$nav = "$nav <a href='$.nav.forward_url'>Next $.nav.forward_count entries &gt;&gt;</a>";
}
$nav = "<p align='center'>[$nav]</p>";
}
if ($nav != "") { print $nav; }
"<table style='margin-left: 30px'>\n";
foreach var Entry e ($.entries) { $this->print_entry($e); }
"</table>\n";
if ($nav != "") { print $nav; }
}
function FriendsPage::lay_nav_blurb ()
{
var int total = size $.entries;
if ($.nav.skip > 0)
{
"Below are $total friends entries, after skipping $.nav.skip most recent ones:";
} else {
"Below are the $total most recent friends journal entries:";
}
}
function CommentInfo::print ()
{
if (not $.enabled) { return; }
"<p class='comments'>(";
if ($.count > 0 or $.screened) {
$this->print_readlink();
"&nbsp;|&nbsp;";
}
$this->print_postlink();
")</p>";
}
function YearPage::lay_nav_blurb()
{
"<p id='yearpage_nav'>";
$this->print_year_links();
"</p>";
}
function YearPage::print_body
{
"<p id='yearheader'>$.year&hellip;</p>\n";
foreach var YearMonth m ($.months) {
$this->print_month($m);
}
}
function YearPage::print_year_links ()
{
foreach var YearYear y ($.years) {
if ($y.displayed) {
"[ $y.year ]";
} else {
"[ <a href=\"$y.url\">$y.year</a> ]";
}
}
}
function YearPage::print_month(YearMonth m)
{
if (not $m.has_entries) { return; }
# Table Wrapper
"<center><p><table border='1' cellpadding='4' width='80%'>\n";
# Month Header
"<tr align='center'><th colspan='7' class='monthheader'>\n";
print $m->month_format();
"</th></tr>\n";
# Weekdays Header
"<tr align='center'>\n";
foreach var int d (weekdays()) {
"<th class='daysheader'>"+$*lang_dayname_short[$d]+"</th>\n";
}
"</tr>\n";
# Weeks
foreach var YearWeek w ($m.weeks) {
$w->print();
}
# Footer
"<tr><td colspan='7'><div style='text-align: center'><a href='$m.url'>$*text_view_month</a></div></td></tr>\n";
# End Table
"</table></p></center>\n";
}
function YearWeek::print ()
{
"<tr>";
if ($.pre_empty) { "<td colspan='$.pre_empty' class='weekday_empty'>&nbsp;</td>"; }
foreach var YearDay d ($.days) {
"<td valign='top'><span class='day_id'>$d.day</span><div style='text-align: center'>";
if ($d.num_entries) {
"<a href='$d.url'>$d.num_entries</a>";
} else {
"&nbsp;";
}
"</div></td>\n";
}
if ($.post_empty) { "<td colspan='$.post_empty' class='weekday_empty'>&nbsp;</td>"; }
"</tr>";
}
function DayPage::print_body ()
{
"<h2 class='daypage_header'>"; print $.date->date_format("%%month%% %%dayord%%, %%yyyy%%"); "</h2>";
if (not $.has_entries)
{
"<blockquote><em>"; print ehtml($*text_noentries_day); "</em></blockquote>";
} else {
"<table style='margin-left: 30px'>";
foreach var Entry e ($.entries) { $this->print_entry($e); }
"</table>";
}
var string tprev = ehtml($*text_day_prev);
var string tnext = ehtml($*text_day_next);
"<table align='center'><tr align='middle'>\n";
"<td width='33%' align='left'><a href='$.prev_url'>$tprev</a></td>\n";
"<td align='center' width='33%'>";
"<strong>"; print $.date->date_format("%%yyyy%%/%%mm%%/%%dd%%"); "</strong><br />";
"[<a href='"; print $this.journal->base_url(); "/calendar'>$*text_view_archive</a>]</td>\n";
"<td width='33%' align='right'><a href='$.next_url'>$tnext</a></td>\n";
"</tr></table>";
}
function EntryPage::print_body () {
set_handler("unscreen_comment_#", [
[ "style_bgcolor", "cmtbar#", "$*comment_bar_one_bgcolor", ],
[ "style_color", "cmtbar#", "$*comment_bar_one_fgcolor", ],
]);
set_handler("screen_comment_#", [
[ "style_bgcolor", "cmtbar#", "$*comment_bar_screened_bgcolor", ],
[ "style_color", "cmtbar#", "$*comment_bar_screened_fgcolor", ],
]);
"<table style='margin-left: 30px'>\n";
print_entry($this, $.entry, $*metabar_bgcolor, $*metabar_fgcolor, $.viewing_thread);
if ($.entry.comments.enabled and $.comment_pages.total_subitems > 0)
{
$this->print_multiform_start();
"<tr valign='top'><th class='headerbar' colspan='2'>Comments</th></tr>";
"<tr valign='top'><td style='background-color: $*metabar_bgcolor'>&nbsp;</td><td style='width: 100%'>";
if ($.comment_pages.total_subitems > 0) {
$.comment_pages->print();
$this->print_comments($.comments);
}
"</td></tr>";
if ($this.multiform_on) {
"<tr valign='top'><th class='headerbar' colspan='2'>Mass Action</th></tr>";
"<tr valign='top'><td style='background-color: $*metabar_bgcolor'>&nbsp;</td><td style='width: 100%'>";
$this->print_multiform_actionline();
$this->print_multiform_end();
"</td></tr>";
}
}
"</table>\n";
}
function EntryPage::print_comment (Comment c) {
var Color background; var Color color;
if ($c.screened) {
$background = $*comment_bar_screened_bgcolor;
$color = $*comment_bar_screened_fgcolor;
} elseif ($c.depth % 2) {
$background = $*comment_bar_one_bgcolor;
$color = $*comment_bar_one_fgcolor;
} else {
$background = $*comment_bar_two_bgcolor;
$color = $*comment_bar_two_fgcolor;
}
var string poster = defined $c.poster ? $c.poster->as_string() : "<i>(Anonymous)</i>";
var string sub_icon;
if (defined $c.subject_icon) {
$sub_icon = $c.subject_icon->as_string();
}
"<a name='$c.anchor'></a><div id='cmtbar$c.talkid' style='background-color: $background; color: $color; margin-top: 10px; width: 100%'>";
"<table cellpadding='2' cellspacing='0' summary='0' style='width: 100%'><tr valign='top'>";
if (defined $c.userpic and $*comment_userpic_style != "off") {
var int w = $c.userpic.width;
var int h = $c.userpic.height;
# WARNING: this will later be done by the system (it'll be a
# constructional property), so don't copy this hack into your
# layout layers or you'll be messed up later.
if ($*comment_userpic_style == "small") {
$w = $w / 2;
$h = $h / 2;
}
print "<td style='width: 102px'><img src='$c.userpic.url' width='$w' height='$h' alt='[User Picture]' /></td>";
}
"<td style='width: 100%'><table style='width: 100%'><tr>";
### From, date, etc
"<td align='left' style='width: 50%'>";
print "<table>";
print "<tr><th align='right'>From:</th><td>$poster</td></tr>\n";
print "<tr><th align='right'>Date:</th><td style='white-space: nowrap'>";
print $c.time->date_format("long") + " - " + $c.time->time_format() + "</td></tr>";
if ($c.metadata{"poster_ip"}) { print "<tr><th align='right'>IP Address:</th><td>(" + $c.metadata{"poster_ip"} + ")</td></tr>"; }
"</table></td>";
### Gadgets
"<td align='right' style='width: 50%'>";
if ($this.multiform_on) {
" <label for='ljcomsel_$c.talkid'>$*text_multiform_check</label>";
$c->print_multiform_check();
}
$c->print_linkbar();
"</td></tr>";
### Subject / icon
print "<tr valign='top'><td style='width: 50%'>";
print (defined $c.subject_icon or $c.subject != "") ? "<h3>$c.subject_icon $c.subject</h3>" : "";
print "</td>";
### Permalink
print "<td style='width: 50%' align='right'><strong>(<a href='$c.permalink_url'>Link</a>)</strong></td></tr>";
print "</table></td></tr></table></div>";
print "<div style='margin-left: 5px'>$c.text</div>";
print "<div style='margin-top: 3px; font-size: smaller'>";
if ($c.frozen) {
print "(Replies frozen) ";
} else {
print "(<a href='$c.reply_url'>Reply to this</a>) ";
}
if ($c.parent_url != "") { "(<a href='$c.parent_url'>Parent</a>) "; }
if ($c.thread_url != "") { "(<a href='$c.thread_url'>Thread</a>) "; }
"</div>";
}
function ReplyPage::print_body()
{
"<table style='margin-left: 30px'>\n";
if (not $.entry.comments.enabled) {
print "<tr><th class='headerbar'>$*text_reply_nocomments_header</th></tr><tr><td>$*text_reply_nocomments</td></tr></table>";
return;
}
var string time = $.replyto.time->time_format();
var string userpic = "";
if (defined $.replyto.userpic)
{
$userpic = "<img src='$.replyto.userpic.url' />";
}
"<tr><th class='headerbar'>Time</td><th class='headerbar' style='width: 100%'>Text</th></tr>";
"<tr valign='top'>";
# Metabar
"<td style='background-color: $*metabar_bgcolor;' class='metabar'>";
# Time
"<em>$time</em><br />";
if ($userpic)
{
print $userpic + "<br />\n";
}
print defined $.replyto.poster ? $.replyto.poster->as_string() : "<i>(Anonymous)</i>";
# Permalink
"<p>[<a href='$.replyto.permalink_url'>$*text_permalink</a>]</p>";
"</td>";
# Text
"<td style='text-align:left'>";
if ($.replyto.subject != "") { "\n\n<span class='subject'>$.replyto.subject</span><br />"; }
print $.replyto.text; "\n\n";
"</td></tr>\n";
"<div align='center'><a href='$.entry.comments.read_url'>( Read Comments )</a></div>";
"<tr valign='top'><th class='headerbar' colspan='2'>Reply:</th></tr>";
"<tr valing='top'><td style='background-color: $*metabar_bgcolor'>&nbsp;</td><td>";
$.form->print();
"</td></tr></table>";
}
function print_theme_preview ()
{
"""
<table width='100%' style='background-color: $*body_bgcolor'>
<tr><td>
<table height='95%' cellpadding='5' width='100%' bgcolor='$*main_bgcolor'>
<tr><td>
<span style='font: normal bold 16pt $*font_base, $*font_fallback; color: $*page_title_color'>John Doe</span>
<ul><table>
<tr><td align="left" style="background-color: $*headerbar_bgcolor; color: $*headerbar_fgcolor" colspan="2">
<span style='font: normal bold 14pt $*font_base, $*font_fallback'>Friday, November 15th, 2002</span>
</td></tr>
<tr valign="top"><td style="text-align: right; background-color: $*metabar_bgcolor; white-space: nowrap">
<span style="font: italic normal 10pt $*font_base, $*font_fallback; color: $*metabar_fgcolor">
10:21 pm</span>
</td><td>
<p style="text-align:left">
<span style="font: italic bold 10pt $*font_base, $*font_fallback; color: $*page_subtitle_color">
Neque porro quisquam est&hellip;
</span><br />
Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit
Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit
Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit
Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit
Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit
Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit
</p><p style="text-align:right; font-size: 8pt">
(<a href="#" style="font-weight: bold; color: $*link_color">1 Comment</a> |
<a href="#" style="color: $*vlink_color">Comment on this</a>)
</p>
</td></tr>
</table></ul>
</td></tr>
</table>
</td></tr>
</table>
""";
}

View File

@@ -0,0 +1,419 @@
#NEWLAYER: classic/calmfire
layerinfo type = theme;
layerinfo name = "Calm Fire";
layerinfo redist_uniq = "classic/calmfire";
set body_bgcolor = "#9e0610";
set main_bgcolor = "#7d7d7d";
set main_fgcolor = "#ffffff";
set headerbar_bgcolor = "#ff6c1d";
set headerbar_fgcolor = "#000000";
set metabar_bgcolor = "#ff9364";
set metabar_fgcolor = "#000000";
set page_title_color = "#8b1a1a";
set page_subtitle_color = "#c00000";
set link_color = "#ff1010";
set vlink_color = "#f10707";
set alink_color = "#ff1d1d";
set comment_bar_one_bgcolor = "#ff6c1d";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#ff9364";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: classic/shrinkvio
layerinfo type = theme;
layerinfo name = "Shrinking Violet";
layerinfo redist_uniq = "classic/shrinkvio";
set body_bgcolor = "#ad22e7";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set headerbar_bgcolor = "#5d0383";
set headerbar_fgcolor = "#ffffff";
set metabar_bgcolor = "#5d0343";
set metabar_fgcolor = "#ffffff";
set page_title_color = "#d9a1f1";
set page_subtitle_color = "#d9a1f1";
set link_color = "#2e053f";
set vlink_color = "#611627";
set alink_color = "#ff00c0";
set comment_bar_one_bgcolor = "#5d0383";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#5d0343";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: classic/pistmint
layerinfo type = theme;
layerinfo name = "Pistachio Mint";
layerinfo redist_uniq = "classic/pistmint";
set body_bgcolor = "#133422";
set main_bgcolor = "#a7c4b4";
set main_fgcolor = "#000000";
set headerbar_bgcolor = "#096d36";
set headerbar_fgcolor = "#ffffff";
set metabar_bgcolor = "#096d36";
set metabar_fgcolor = "#ffffff";
set page_title_color = "#096d36";
set page_subtitle_color = "#096d36";
set link_color = "#8afabc";
set vlink_color = "#1da65a";
set alink_color = "#f9f5f5";
set comment_bar_one_bgcolor = "#096d36";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#096d36";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: classic/mexicanfood
layerinfo type = theme;
layerinfo name = "Mexican Food";
layerinfo redist_uniq = "classic/mexicanfood";
set body_bgcolor = "#ff0000";
set main_bgcolor = "#f8ff3e";
set main_fgcolor = "#f15601";
set headerbar_bgcolor = "#bdbf3e";
set headerbar_fgcolor = "#ff0000";
set metabar_bgcolor = "#ffc664";
set metabar_fgcolor = "#000000";
set page_title_color = "#ff0000";
set page_subtitle_color = "#e15a18";
set link_color = "#f49e08";
set vlink_color = "#b05403";
set alink_color = "#ff7405";
set comment_bar_one_bgcolor = "#bdbf3e";
set comment_bar_one_fgcolor = "#ff0000";
set comment_bar_two_bgcolor = "#ffc664";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: classic/ashfire
layerinfo type = theme;
layerinfo name = "Ash and Fire";
layerinfo redist_uniq = "classic/ashfire";
set body_bgcolor = "#b5b5b5";
set main_bgcolor = "#ffb6af";
set main_fgcolor = "#000000";
set headerbar_bgcolor = "#e75454";
set headerbar_fgcolor = "#ffffff";
set metabar_bgcolor = "#ff9696";
set metabar_fgcolor = "#ffffff";
set page_title_color = "#ff1106";
set page_subtitle_color = "#f06c88";
set link_color = "#f70208";
set vlink_color = "#b0161d";
set alink_color = "#d70106";
set comment_bar_one_bgcolor = "#e75454";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#ff9696";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: classic/desktop
layerinfo type = theme;
layerinfo name = "Classic Desktop";
layerinfo redist_uniq = "classic/desktop";
set body_bgcolor = "#00545c";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set headerbar_bgcolor = "#ff7b05";
set headerbar_fgcolor = "#ffeddd";
set metabar_bgcolor = "#ffffff";
set metabar_fgcolor = "#000000";
set page_title_color = "#ff7b05";
set page_subtitle_color = "#ffeddd";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#5a76ff";
set comment_bar_one_bgcolor = "#ff7b05";
set comment_bar_one_fgcolor = "#ffeddd";
set comment_bar_two_bgcolor = "#ffffff";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: classic/satinhandshake
layerinfo type = theme;
layerinfo name = "Satin Handshake";
layerinfo redist_uniq = "classic/satinhandshake";
set body_bgcolor = "#480c0c";
set main_bgcolor = "#d06464";
set main_fgcolor = "#00001d";
set headerbar_bgcolor = "#aaaaaa";
set headerbar_fgcolor = "#000000";
set metabar_bgcolor = "#dddddd";
set metabar_fgcolor = "#000000";
set page_title_color = "#9d0404";
set page_subtitle_color = "#9d0404";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#ff00c0";
set comment_bar_one_bgcolor = "#aaaaaa";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#dddddd";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: classic/deepmelodrama
layerinfo type = theme;
layerinfo name = "Deep MeloDrama";
layerinfo redist_uniq = "classic/deepmelodrama";
set body_bgcolor = "#872d89";
set main_bgcolor = "#719cff";
set main_fgcolor = "#8e48b2";
set comment_bar_one_bgcolor = "#3794b3";
set comment_bar_one_fgcolor = "#84b8e7";
set metabar_bgcolor = "#65b2c1";
set metabar_fgcolor = "#f5d3ff";
set page_title_color = "#8e48b2";
set page_subtitle_color = "#65b2c1";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#dfd3ff";
set comment_bar_one_bgcolor = "#3794b3";
set comment_bar_one_fgcolor = "#84b8e7";
set comment_bar_two_bgcolor = "#65b2c1";
set comment_bar_two_fgcolor = "#f5d3ff";
#NEWLAYER: classic/everwhite
layerinfo type = theme;
layerinfo name = "Everwhite";
layerinfo redist_uniq = "classic/everwhite";
set body_bgcolor = "#ffffff";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set comment_bar_one_bgcolor = "#ffffff";
set comment_bar_one_fgcolor = "#000000";
set metabar_bgcolor = "#ffffff";
set metabar_fgcolor = "#000000";
set page_title_color = "#000000";
set page_subtitle_color = "#ff0000";
set link_color = "#e60000";
set vlink_color = "#c10602";
set alink_color = "#ff0600";
set comment_bar_one_bgcolor = "#ffffff";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#ffffff";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: classic/everblue
layerinfo type = theme;
layerinfo name = "Everblue with Greys";
layerinfo redist_uniq = "classic/everblue";
set body_bgcolor = "#0f0c6d";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set headerbar_bgcolor = "#000000";
set headerbar_fgcolor = "#ffffff";
set metabar_bgcolor = "#aaaaaa";
set metabar_fgcolor = "#000000";
set page_title_color = "#000000";
set page_subtitle_color = "#aaaaaa";
set link_color = "#2f00f2";
set vlink_color = "#060667";
set alink_color = "#6691ff";
set comment_bar_one_bgcolor = "#000000";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#aaaaaa";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: classic/brownleather
layerinfo type = theme;
layerinfo name = "Brown Leather Coat";
layerinfo redist_uniq = "classic/brownleather";
set body_bgcolor = "#d2b48c";
set main_bgcolor = "#ffebcd";
set main_fgcolor = "#8b4513";
set headerbar_bgcolor = "#d48050";
set headerbar_fgcolor = "#ffffff";
set metabar_bgcolor = "#d48014";
set metabar_fgcolor = "#d48014";
set page_title_color = "#d48014";
set page_subtitle_color = "#ffe1a1";
set link_color = "#000050";
set vlink_color = "#867a55";
set alink_color = "#fffab3";
set comment_bar_one_bgcolor = "#d48014";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#d48050";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: classic/bruise
layerinfo type = theme;
layerinfo name = "Bruise";
layerinfo redist_uniq = "classic/bruise";
set body_bgcolor = "#000000";
set main_bgcolor = "#bcbcbc";
set main_fgcolor = "#000000";
set headerbar_bgcolor = "#1114a0";
set headerbar_fgcolor = "#ffffff";
set metabar_bgcolor = "#21c2f1";
set metabar_fgcolor = "#ffffff";
set page_title_color = "#1114a0";
set page_subtitle_color = "#21c2f1";
set link_color = "#0000cc";
set vlink_color = "#000088";
set alink_color = "#0000ff";
set comment_bar_one_bgcolor = "#1114a0";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#21c2f1";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: classic/ranchhand
layerinfo type = theme;
layerinfo name = "Ranch Hand";
layerinfo redist_uniq = "classic/ranchhand";
set body_bgcolor = "#2999c2";
set main_bgcolor = "#cfe0ff";
set main_fgcolor = "#000000";
set headerbar_bgcolor = "#54442c";
set headerbar_fgcolor = "#ffffff";
set metabar_bgcolor = "#bababa";
set metabar_fgcolor = "#000000";
set page_title_color = "#9d995d";
set page_subtitle_color = "#704400";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#6a20ff";
set comment_bar_one_bgcolor = "#54442c";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#bababa";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: classic/victim
layerinfo type = theme;
layerinfo name = "Victim";
layerinfo redist_uniq = "classic/victim";
set body_bgcolor = "#2cd0ff";
set main_bgcolor = "#505050";
set main_fgcolor = "#ffffff";
set headerbar_bgcolor = "#166bac";
set headerbar_fgcolor = "#ffffff";
set metabar_bgcolor = "#2098f3";
set metabar_fgcolor = "#ffffff";
set page_title_color = "#26b6ff";
set page_subtitle_color = "#353535";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#ff00c0";
set comment_bar_one_bgcolor = "#166bac";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#2098f3";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: classic/forest
layerinfo type = theme;
layerinfo name = "Forest";
layerinfo redist_uniq = "classic/forest";
set body_bgcolor = "#778e64";
set main_bgcolor = "#9b9ba5";
set main_fgcolor = "#000000";
set headerbar_bgcolor = "#72784c";
set headerbar_fgcolor = "#ffffff";
set metabar_bgcolor = "#72781c";
set metabar_fgcolor = "#ffffff";
set page_title_color = "#a0ac62";
set page_subtitle_color = "#73777a";
set link_color = "#3811e1";
set vlink_color = "#310cbb";
set alink_color = "#4e7bef";
set comment_bar_one_bgcolor = "#72784c";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#72781c";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: classic/drone
layerinfo type = theme;
layerinfo name = "Drone";
layerinfo redist_uniq = "classic/drone";
set body_bgcolor = "#395f82";
set main_bgcolor = "#f9fcfe";
set main_fgcolor = "#000000";
set headerbar_bgcolor = "#904094";
set headerbar_fgcolor = "#ffffff";
set metabar_bgcolor = "#f56efc";
set metabar_fgcolor = "#ffffff";
set page_title_color = "#ff93ff";
set page_subtitle_color = "#eeeeff";
set link_color = "#395f82";
set vlink_color = "#395f82";
set alink_color = "#5266ce";
set comment_bar_one_bgcolor = "#904094";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#f56efc";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: classic/lowercurtain
layerinfo type = theme;
layerinfo name = "Lower the Curtain";
layerinfo redist_uniq = "classic/lowercurtain";
set body_bgcolor = "#000000";
set main_bgcolor = "#6b6b6b";
set main_fgcolor = "#ffffff";
set headerbar_bgcolor = "#363636";
set headerbar_fgcolor = "#f0f5fb";
set metabar_bgcolor = "#c6c6c6";
set metabar_fgcolor = "#222222";
set page_title_color = "#363636";
set page_subtitle_color = "#c5c8ca";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#3314ba";
set comment_bar_one_bgcolor = "#363636";
set comment_bar_one_fgcolor = "#f0f5fb";
set comment_bar_two_bgcolor = "#c6c6c6";
set comment_bar_two_fgcolor = "#222222";
#NEWLAYER: classic/sunny
layerinfo type = theme;
layerinfo name = "Sunny Day";
layerinfo redist_uniq = "classic/sunny";
set body_bgcolor = "#55e0f9";
set main_bgcolor = "#e38202";
set main_fgcolor = "#ffffff";
set headerbar_bgcolor = "#fff500";
set headerbar_fgcolor = "#e38202";
set metabar_bgcolor = "#fff5c5";
set metabar_fgcolor = "#e38202";
set page_title_color = "#efe052";
set page_subtitle_color = "#ffba03";
set link_color = "#df0d12";
set vlink_color = "#ac1b25";
set alink_color = "#fe3b3b";
set comment_bar_one_bgcolor = "#fff500";
set comment_bar_one_fgcolor = "#e38202";
set comment_bar_two_bgcolor = "#fff5c5";
set comment_bar_two_fgcolor = "#e38202";
#NEWLAYER: classic/valentine
layerinfo type = theme;
layerinfo name = "Be Mine";
layerinfo redist_uniq = "classic/valentine";
set body_bgcolor = "#6f104a";
set main_bgcolor = "#f2bce9";
set main_fgcolor = "#000000";
set headerbar_bgcolor = "#ff37ff";
set headerbar_fgcolor = "#ffffff";
set metabar_bgcolor = "#df2096";
set metabar_fgcolor = "#ffffff";
set page_title_color = "#ae1774";
set page_subtitle_color = "#df2096";
set link_color = "#ffffff";
set vlink_color = "#a51014";
set alink_color = "#ed8188";
set comment_bar_one_bgcolor = "#ff37ff";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#df2096";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: classic/stripes
layerinfo type = theme;
layerinfo name = "Stripes";
layerinfo redist_uniq = "classic/stripes";
set body_bgcolor = "#ffffff";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set headerbar_bgcolor = "#e7212a";
set headerbar_fgcolor = "#ffffff";
set metabar_bgcolor = "#ffffff";
set metabar_fgcolor = "#000000";
set page_title_color = "#ffffff";
set page_subtitle_color = "#ffcfdc";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#ffafc1";
set comment_bar_one_bgcolor = "#e7212a";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#ffffff";
set comment_bar_two_fgcolor = "#000000";

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -0,0 +1,11 @@
# -*-s2-*-
layerinfo type = "i18n";
layerinfo name = "English";
layerinfo redist_uniq = "cleansimple/en";
set text_meta_music = "music";
set text_meta_mood = "mood";
set text_post_comment = "Comment on this";
set text_post_comment_friends = "Comment on this";

View File

@@ -0,0 +1,932 @@
# -*-s2-*-
layerinfo type = "layout";
layerinfo name = "Clean and Simple";
layerinfo redist_uniq = "cleansimple/layout";
layerinfo author_name = "Martin Atkins";
layerinfo previews = "cleansimple/cleansimple.jpg";
propgroup colors {
property Color body_bgcolor {
des = "Page border color";
note = "If you set the border size to 'None', this won't show up.";
s1color = "stronger_back";
}
property Color entry_bgcolor {
des = "Background of entries";
s1color = "page_back";
}
property Color entry_fgcolor {
des = "Text color of entries";
s1color = "page_text";
}
property Color meta_color {
des = "Color of entry headings and meta-information";
s1color = "page_text_em";
}
property Color link_color {
des = "Link color";
s1color = "page_link";
}
property Color vlink_color {
des = "Visited link color";
s1color = "page_vlink";
}
property Color alink_color {
des = "Active link color";
s1color = "page_alink";
}
property Color topbar_bgcolor {
des = "Background color of titlebar and userpic";
s1color = "strong_back";
}
property Color topbar_fgcolor {
des = "Titlebar text color";
s1color = "strong_text";
}
property Color navbar_bgcolor {
des = "Background color of sidebar";
s1color = "weak_back";
}
property Color navbar_fgcolor {
des = "Sidebar text color";
s1color = "weak_text";
}
property string opt_navbar_pos {
des = "Side Navbar Position";
values = "left|Left|right|Right";
}
property Color comment_bar_one_bgcolor {
des = "Alternating background color for comment bars (one)";
}
property Color comment_bar_two_fgcolor {
des = "Text color on alternating comment bars (one)";
}
property Color comment_bar_two_bgcolor {
des = "Alternating background color for comment bars (two)";
}
property Color comment_bar_one_fgcolor {
des = "Text color on alternating comment bars (two)";
}
property Color comment_bar_screened_bgcolor {
des = "Background bar color for screened comments";
}
property Color comment_bar_screened_fgcolor {
des = "Text color on background bar for screened comments";
}
}
set body_bgcolor = "#6666cc";
set entry_bgcolor = "#ffffff";
set entry_fgcolor = "#000000";
set meta_color = "#c00000";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#00ffff";
set topbar_bgcolor = "#c0c0ff";
set topbar_fgcolor = "#000000";
set navbar_bgcolor = "#eeeeff";
set navbar_fgcolor = "#000000";
set comment_bar_one_bgcolor = "#c0c0ff";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#eeeeff";
set comment_bar_two_fgcolor = "#000000";
set comment_bar_screened_bgcolor = "#dddddd";
set comment_bar_screened_fgcolor = "#000000";
set tags_aware = true;
propgroup fonts {
property use font_base;
property use font_fallback;
property string font_topbar_base {
des = "Preferred font for top bar";
note = "As with the main font, leave blank if you don't care.";
}
property string font_topbar_fallback {
des = "Alternative font style for top bar";
values = "sans-serif|Sans-serif|serif|Serif|cursive|Cursive|monospace|Monospaced|none|Use browser's default";
}
property string font_sidebar_base {
des = "Preferred font for side navigation bar";
note = "As with the main font, leave blank if you don't care.";
}
property string font_sidebar_fallback {
des = "Alternative font style for side navigation bar";
values = "sans-serif|Sans-serif|serif|Serif|cursive|Cursive|monospace|Monospaced|none|Use browser's default";
}
}
set font_topbar_fallback = "none";
set font_sidebar_fallback = "none";
propgroup presentation {
property string opt_daylines_style {
des = "Style of Lines Around Day Headings";
values = "solid|Solid|dashed|Dashed|dotted|Dotted|double|Double|hidden|Invisible";
}
property use page_recent_items;
property use page_friends_items;
property string opt_margin_size {
des = "Size of page border";
values = "0|None|5px|Tiny|25px|Small|50px|Medium|75px|Large|100px|Extra Large";
}
property use view_entry_disabled;
property use use_shared_pic;
property bool show_entrynav_icons {
des = "Toggle to show the next, memory, edit, etc icons on the entry view page";
}
property string page_background_image {
des = "URL to an image to be used for the page background";
}
property use linklist_support;
property use external_stylesheet;
}
set opt_navbar_pos = "left";
set opt_daylines_style = "dashed";
set opt_margin_size = "50px";
set view_entry_disabled = false;
set show_entrynav_icons = true;
set page_background_image = "";
set linklist_support = false;
propgroup text {
property use text_post_comment;
property use text_read_comments;
property use text_post_comment_friends;
property use text_read_comments_friends;
}
function css_fontspec(string base, string fallback)
"Prints a CSS font-family specification based on the base and fallback given"
{
if ($base != "" or $fallback != "none") {
"font-family: ";
if ($base != "") {
"\"$base\"";
if ($fallback != "none") {
", ";
}
}
if ($fallback != "none") {
print $fallback;
}
";";
}
}
function print_stylesheet ()
{
var string bgimg = clean_url($*page_background_image) != "" ? "url($*page_background_image)" : "none";
"""
body {
background: $*body_bgcolor $bgimg;
color: $*entry_fgcolor;
padding: $*opt_margin_size;
margin: 0;
""";
css_fontspec($*font_base,$*font_fallback);
"""
}
a:link {
color: $*link_color;
background: transparent;
}
a:visited {
color: $*vlink_color;
background: transparent;
}
a:active {
color: $*alink_color;
background: transparent;
}
img {
vertical-align: absmiddle;
}
table {
width: 100%;
}
pre {
text-align: left;
}
#topbar {
background: $*topbar_bgcolor none;
color: $*topbar_fgcolor;
""";
css_fontspec($*font_topbar_base,$*font_topbar_fallback);
"""
}
#topbar h1 {
margin-top: 5px;
margin-bottom: 0;
text-align: center;
font-size: 1.5em;
}
#topbar h2 {
margin-top: 0;
margin-bottom: 5px;
text-align: center;
font-size: 1.25em;
}
#navbar {
background: $*navbar_bgcolor none;
color: $*navbar_fgcolor;
width: 25%;
""";
css_fontspec($*font_sidebar_base,$*font_sidebar_fallback);
"""
}
#navbar ul {
list-style: none;
margin: 10px;
}
#navbar ul li {
margin: 0;
}
#navbar ul li.active {
font-weight: bold;
}
#navbar a:link, #navbar a:active, #navbar a:visited {
background: $*navbar_bgcolor none;
color: $*navbar_fgcolor;
text-decoration: none;
}
#navbar a:hover {
text-decoration: underline;
}
#userlinklist ul {
margin-top: 0;
margin-bottom: 0;
}
#mainstuff {
width: 75%;
background: $*entry_bgcolor none;
color: $*entry_fgcolor;
}
#userpic {
text-align: center;
margin: 10px;
}
#userpic img {
border: 2px solid $*topbar_bgcolor;
background: $*topbar_bgcolor none;
color: $*topbar_fgcolor;
}
#entries {
margin: 10px;
}
#range {
margin-bottom: 0.5em;
}
.day {
border-top: 1px $*opt_daylines_style $*entry_fgcolor;
clear: both;
}
.day h3 {
border-bottom: 1px $*opt_daylines_style $*entry_fgcolor;
padding: 2px;
margin: 0;
font-size: 1.1em;
text-align: center;
}
address {
text-align: center;
font-style: normal;
font-size: 0.95em;
}
/* entries */
.entrytext {
padding: 2px;
text-align: justify;
}
.entry {
clear: both;
}
.entrytext p, .entrytext ul, .entrytext ol, .entrytext table {
margin-top: 0.5em;
margin-bottom: 0.5em;
}
.entryheading {
font-weight: bold;
}
.timestamp, .subject, .altposter {
font-weight: bold;
color: $*meta_color;
background: $*entry_bgcolor;
}
.altposter a {
color: $*meta_color;
background: $*entry_bgcolor;
text-decoration: underline;
}
.altposter img {
border: 2px $*navbar_fgcolor solid;
background: $*navbar_bgcolor none;
color: $*navbar_fgcolor;
}
.talklinks {
font-size: 0.75em;
text-align: right;
margin-bottom: 2px;
clear: right;
}
.frienduserpic {
border: 2px solid $*topbar_bgcolor;
background: $*topbar_bgcolor none;
color: $*topbar_fgcolor;
}
""";
}
function Page::lay_viewspec_nav() {
# Intentionally blank
}
function RecentPage::lay_viewspec_nav() {
# FIXME: There is currently no decent way to i18nize this
if ($.nav.forward_url != "" or $.nav.backward_url != "") {
"<ul id=\"skiplinks\">";
if ($.nav.forward_url != "") {
println """<li><a href="$.nav.forward_url">Next</a></li>""";
}
if ($.nav.backward_url != "") {
println """<li><a href="$.nav.backward_url">Previous</a></li>""";
}
"</ul>";
}
}
# This DEFINITELY should be in core
function Page::lay_view_name(string view) : string
"Don't bother overriding this, because it'll be deleted as soon as core can do it" {
if ($view == "recent") {
return $*text_view_recent;
} elseif ($view == "friends") {
return $*text_view_friends;
} elseif ($view == "userinfo") {
return $*text_view_userinfo;
} elseif ($view == "archive") {
return $*text_view_archive;
} else {
return "Something";
}
}
function Page::lay_viewspec_heading() : string
"Returns some text to display under the main heading. Overridden in subclasses." {
return "";
}
function RecentPage::lay_viewspec_heading() : string {
return $*text_view_recent;
}
function FriendsPage::lay_viewspec_heading() : string {
if ($.journal.journal_type == "C") {
return $*text_view_friends_comm;
} else {
return $*text_view_friends;
}
}
function DayPage::lay_viewspec_heading() : string {
return $*text_view_archive;
}
function YearPage::lay_viewspec_heading() : string {
return $*text_view_archive;
}
function MonthPage::lay_viewspec_heading() : string {
return $*text_view_archive;
}
function Page::print_linklist() {
if (size $.linklist <= 0) {
return;
} elseif (not $*linklist_support) {
return;
}
var bool section_open = false;
println "<ul id='userlinklist'>";
foreach var UserLink l ($.linklist) {
if ($l.title) {
if ($l.is_heading) {
if ($section_open) {
println "</ul></li>";
}
println """<li><span style="font-style: italic;">$l.title</span>\n<ul>""";
$section_open = true;
} else {
println """<li><a href="$l.url">$l.title</a></li>""";
}
}
}
if ($section_open) {
println "</ul></li>";
}
println "</ul>";
}
function Page::lay_print_navbar() {
var string userpic;
var Image up_img = $.journal.default_pic;
if (defined $up_img) {
$userpic = """<div id="userpic"><img border="0" src="$up_img.url" height="$up_img.height" width="$up_img.width" alt="" /></div>""";
}
var string website_name = $.journal.website_name ? $.journal.website_name : $*text_website_default_name;
var string website;
if ($.journal.website_url != "") {
$website = """<li><a href="$.journal.website_url">$website_name</a></li>""";
}
"""<td id="navbar" valign="top">
<ul id="viewlinks">
""";
foreach var string v ($.views_order) {
if ($v == $.view) {
println """<li class="active">"""+
$this->lay_view_name($v)+
"""</li>""";
} else {
println """<li><a href="$.view_url{$v}">"""+
$this->lay_view_name($v)+
"""</a></li>""";
}
}
"""
$website
</ul>
""";
$this->lay_viewspec_nav();
"$userpic";
$this->print_linklist();
"</td>";
}
function Page::print ()
{
var string title = $this->title();
"""<html>\n<head>\n""";
if ($*external_stylesheet) {
println """<link rel="stylesheet" href="$.stylesheet_url" type="text/css" />""";
} else {
println """<style type="text/css">"""; print_stylesheet(); "</style>";
}
$this->print_head();
"""<title>$title</title>
</head>
<body>
<table border="0" cellpadding="0" cellspacing="0">
<tr><td colspan="2" id="topbar" valign="top">
""";
"<h1>$.journal.name</h1>";
"<h2>" + $this->lay_viewspec_heading() + "</h2>";
"""
</td></tr>
<tr>
""";
if ($*opt_navbar_pos == "left") {
$this->lay_print_navbar();
}
"""<td id="mainstuff" valign="top">
<div id="entries">
""";
$this->print_body();
"""
</div>
<address>"""; server_sig(); """</address>
</td>
""";
if ($*opt_navbar_pos == "right") {
$this->lay_print_navbar();
}
"""</tr>
</table>
</body>
</html>
""";
}
function print_entry (Page p, Entry e, Color bgcolor, Color fgcolor, bool hide_text)
{
var string time = $e.time->time_format();
if ($e.new_day) {
"""<div class="day"><h3>"""+$e.time->date_format("long")+"</h3>";
}
"""<div class="entry" id="entry$e.itemid"><div class="entrytext">""";
if ($p.view == "entry" and $*show_entrynav_icons)
{
print "<div style='text-align: center'>";
$e->print_linkbar();
print "</div>";
}
"""<span class="entryheading">""";
if ($p.view == "friends") {
if ($e.poster.username != $e.journal.username) {
"<span class=\"altposter\"><a href=\"";
print get_url($e.poster,"userinfo");
"\">"+$e.poster.username;
"</a></span>, posting in ";
}
"<a style=\"color: $fgcolor; background: $bgcolor; padding-left: 0.5em; padding-right: 0.5em;\"";
" href=\""+get_url($e.journal,"userinfo")+"\">$e.journal.username</a> @ ";
} else {
if ($e.poster.username != $e.journal.username) {
"<span class=\"altposter\">";
if (defined $e.userpic) {
"""<img src="$e.userpic.url" width="$e.userpic.width"
height="$e.userpic.height" alt="" align="right" />""";
}
"<a href=\""+
get_url($e.poster,"userinfo")+
"\">$e.poster.username</a></span> @ ";
}
}
"<span class=\"timestamp\">"+$e.time->time_format()+"</span>: ";
if ($e.security) {
$e.security_icon->print();
}
if ($e.subject) {
" <span class=\"subject\">$e.subject</span>";
}
println "</span>"+($e.subject != "" ? "<br />" : "");
if ($p.view == "friends" and defined $e.userpic) {
"""<img src="$e.userpic.url" width="$e.userpic.width"
style="color: $fgcolor; background: $bgcolor; border: 2px solid $bgcolor;"
height="$e.userpic.height" alt="" align="right" class="frienduserpic" />""";
}
if (not $hide_text) {
print "$e.text<br /><br />";
if (size $e.metadata) {
"""<div class="currents">""";
foreach var string k ($e.metadata) {
var string text = $k;
var string val = $e.metadata{$k};
if ($k == "mood") {
$text = $*text_meta_mood;
} elseif ($k == "music") {
$text = $*text_meta_music;
}
if ($k == "mood" and defined $e.mood_icon) {
var Image i = $e.mood_icon;
$val = "<img src='$i.url' width='$i.width' height='$i.height' align='absmiddle'> $val";
}
"""<div class="current$k"><strong>$text:</strong> $val</div>""";
}
"</div>\n";
}
if ($e.tags) {
var int tcount = 0;
"<strong>Tags:</strong> ";
foreach var Tag t ($e.tags) {
"""<a rel="tag" href="$t.url">$t.name</a>""";
$tcount++;
if ($tcount != size $e.tags) { ", "; }
}
"<br />";
}
}
$e.comments->print(); "\n";
"</div>";
if ($e.end_day) {
"</div>";
}
}
function Page::print_entry (Entry e)
{
print_entry($this, $e, null Color, null Color, false);
}
function FriendsPage::print_entry (Entry e) {
var Friend f = $.friends{$e.journal.username};
print_entry($this, $e, $f.bgcolor, $f.fgcolor, false);
}
function CommentInfo::print ()
{
if (not $.enabled) { return; }
"""<div class="talklinks" clear="all">""";
if ($.count > 0 or $.screened) {
$this->print_readlink();
" - ";
}
$this->print_postlink();
"</div>";
}
# This should really be provided in core
function RecentPage::lay_range_text() : string {
if ($.nav.skip == 0) {
return "You are viewing the most recent "+(size $.entries)+" entries";
} else {
return "You are viewing "+(size $.entries)+" entries, $.nav.skip into the past";
}
}
function RecentPage::print_body ()
{
"""<p id="range">"""+$this->lay_range_text()+"""</p>""";
foreach var Entry e ($.entries) {
$this->print_entry($e);
}
}
function YearPage::print_year_links ()
{
"""<ul id="skiplinks">""";
foreach var YearYear y ($.years) {
if ($y.displayed) {
println "<li class=\"active\">$y.year</span>";
} else {
println "<li><a href=\"$y.url\">$y.year</a></li>";
}
}
"</ul>";
}
function YearPage::print_month (YearMonth m)
{
if (not $m.has_entries) { return; }
"""<center><table border="0" cellpadding="4" cellspacing="0" style="margin-top: 10px; margin-bottom: 10px;">""";
"""<tr align="center"><td colspan="7" bgcolor="$*topbar_bgcolor"><font color="$*topbar_fgcolor">""";
"<b>"; print $m->month_format(); """</b> (<a href="$m.url">...</a>)</font></td></tr>""";
"""<tr align="center" bgcolor="$*navbar_bgcolor">""";
foreach var int d (weekdays()) {
"""<td><font color="$*navbar_fgcolor">"""; print $*lang_dayname_short[$d]; "</td>\n";
}
"</tr>";
foreach var YearWeek w ($m.weeks) {
$w->print();
}
"</table></center>";
}
function YearPage::lay_viewspec_nav() {
$this->print_year_links();
}
function YearPage::print_body() {
"<h3>$.year</h3>";
foreach var YearMonth m ($.months) {
$this->print_month($m);
}
}
function YearWeek::print () {
"<tr>";
if ($.pre_empty) { "<td colspan='$.pre_empty'>&nbsp;</td>"; }
foreach var YearDay d ($.days) {
"""<td valign="top"><b><font size="-1">$d.day</font></b>""";
if ($d.num_entries) {
"""<center><a href="$d.url">$d.num_entries</a></center>""";
} else {
"<center>&nbsp;</center>";
}
"</td>";
}
if ($.post_empty) { "<td colspan='$.post_empty'>&nbsp;</td>"; }
"</tr>";
}
function DayPage::lay_viewspec_nav() {
"""
<ul id="skiplinks">
<li><a href="$.prev_url">$*text_day_prev</a></li>
<li><a href="$.next_url">$*text_day_next</a></li>
</ul>
""";
}
function DayPage::print_body() {
"""<div class="day"><h3>""" + $.date->date_format("long") + "</h3>";
if (not $.has_entries) {
println $*text_noentries_day;
}
foreach var Entry e ($.entries) {
$this->print_entry($e);
}
println "</div>";
}
function EntryPage::print_body () {
set_handler("unscreen_comment_#", [
[ "style_bgcolor", "cmtbar#", "$*comment_bar_one_bgcolor", ],
[ "style_color", "cmtbar#", "$*comment_bar_one_fgcolor", ],
]);
set_handler("screen_comment_#", [
[ "style_bgcolor", "cmtbar#", "$*comment_bar_screened_bgcolor", ],
[ "style_color", "cmtbar#", "$*comment_bar_screened_fgcolor", ],
]);
print_entry($this, $.entry, null Color, null Color, $.viewing_thread);
if ($.entry.comments.enabled and $.comment_pages.total_subitems > 0)
{
$this->print_multiform_start();
"""<div class="day"><h3>Comments</h3></div>""";
if ($.comment_pages.total_subitems > 0) {
$.comment_pages->print();
$this->print_comments($.comments);
}
if ($this.multiform_on) {
"""<div class="day"><h3>Mass Action</h3></div>""";
$this->print_multiform_actionline();
$this->print_multiform_end();
}
}
}
# Clean style. Hate to clutter it up with this:
function EntryPage::print_comment (Comment c) {
var Color background; var Color color;
if ($c.screened) {
$background = $*comment_bar_screened_bgcolor;
$color = $*comment_bar_screened_fgcolor;
} elseif ($c.depth % 2) {
$background = $*comment_bar_one_bgcolor;
$color = $*comment_bar_one_fgcolor;
} else {
$background = $*comment_bar_two_bgcolor;
$color = $*comment_bar_two_fgcolor;
}
var string poster = defined $c.poster ? $c.poster->as_string() : "<i>(Anonymous)</i>";
var string sub_icon;
if (defined $c.subject_icon) {
$sub_icon = $c.subject_icon->as_string();
}
"<a name='$c.anchor'></a><div id='cmtbar$c.talkid' style='background-color: $background; color: $color; margin-top: 10px; width: 100%'>";
"<table cellpadding='2' cellspacing='0' summary='0' style='width: 100%'><tr valign='top'>";
if (defined $c.userpic and $*comment_userpic_style != "off") {
var int w = $c.userpic.width;
var int h = $c.userpic.height;
# WARNING: this will later be done by the system (it'll be a
# constructional property), so don't copy this hack into your
# layout layers or you'll be messed up later.
if ($*comment_userpic_style == "small") {
$w = $w / 2;
$h = $h / 2;
}
print "<td style='width: 102px'><img src='$c.userpic.url' width='$w' height='$h' alt='[User Picture]' /></td>";
}
"<td style='width: 100%'><table style='width: 100%'><tr>";
### From, date, etc
"<td align='left' style='width: 50%'>";
print "<table>";
print "<tr><th align='right'>From:</th><td>$poster</td></tr>\n";
print "<tr><th align='right'>Date:</th><td style='white-space: nowrap'>";
print $c.time->date_format("long") + " - " + $c.time->time_format() + "</td></tr>";
if ($c.metadata{"poster_ip"}) { print "<tr><th align='right'>IP Address:</th><td>(" + $c.metadata{"poster_ip"} + ")</td></tr>"; }
"</table></td>";
### Gadgets
"<td align='right' style='width: 50%'>";
if ($this.multiform_on) {
" <label for='ljcomsel_$c.talkid'>$*text_multiform_check</label>";
$c->print_multiform_check();
}
$c->print_linkbar();
"</td></tr>";
### Subject / icon
print "<tr valign='top'><td style='width: 50%'>";
print (defined $c.subject_icon or $c.subject != "") ? "<h3>$c.subject_icon $c.subject</h3>" : "";
print "</td>";
### Permalink
print "<td style='width: 50%' align='right'><strong>(<a href='$c.permalink_url'>Link</a>)</strong></td></tr>";
print "</table></td></tr></table></div>";
print "<div style='margin-left: 5px'>$c.text</div>";
print "<div style='margin-top: 3px; font-size: smaller'>";
if ($c.frozen) {
print "(Replies frozen) ";
} else {
print "(<a href='$c.reply_url'>Reply to this</a>) ";
}
if ($c.parent_url != "") { "(<a href='$c.parent_url'>Parent</a>) "; }
if ($c.thread_url != "") { "(<a href='$c.thread_url'>Thread</a>) "; }
"</div>";
}
function ReplyPage::print_body () {
var string time = $.replyto.time->time_format();
"""
<div class="entry">
<div class="entrytext">
<span class="entryheading">
""";
if (not $.entry.comments.enabled)
{
print "<span class='subject'>$*text_reply_nocomments_header</span></span><br />
$*text_reply_nocomments</div></div>";
return;
}
"<span style='padding-left: 0.5em; padding-right: 0.5em;'>";
print defined $.replyto.poster ? $.replyto.poster->as_string() : "<i>(Anonymous)</i>";
"</span> @ ";
"<span class='timestamp'>$time</span>: ";
if ($.replyto.subject) {
" <span class=\"subject\">$.replyto.subject</span>";
}
println "</span>"+($.replyto.subject ? "<br />" : "");
if (defined $.replyto.userpic) {
"""<img src="$.replyto.userpic.url" width="$.replyto.userpic.width"
style="border: 2px solid $*entry_fgcolor;"
height="$.replyto.userpic.height" alt="" align="right" class="frienduserpic" />""";
}
print $.replyto.text;
"""<div class="talklinks" clear="all"><a href='$.entry.comments.read_url'>Read Comments</a></div>""";
"</div>";
"""<div class="day"><h3>Reply</h3></div>""";
$.form->print();
}
function print_theme_preview ()
{
print """
<div style="background: $*body_bgcolor none; color: $*entry_fgcolor;
padding-left: 50px; padding-right: 50px; padding-top: 10px;
padding-bottom: 10px; margin: 0;">
<table border="0" cellpadding="0" cellspacing="0">
<tr><td colspan="2" style="background: $*topbar_bgcolor none; color: $*topbar_fgcolor" valign="top">
<h1 style="margin-top: 5px; margin-bottom: 5px; text-align: center; font-size: 1.5em;">John Doe</h1>
<h2 style="margin-top: 0; margin-bottom: 5px; text-align: center; font-size: 1.25em;">Recent Entries</h2>
</td></tr>
<tr><td style="background: $*navbar_bgcolor none; color: $*navbar_fgcolor; width: 25%;" valign="top">
<ul style="list-style: none; margin: 10px">
<li style="margin: 0; font-weight: bold;">Recent Entries</li>
<li><a style="background: $*navbar_bgcolor none; color: $*navbar_fgcolor;" href="#">Archive</a></li>
<li><a style="background: $*navbar_bgcolor none; color: $*navbar_fgcolor;" href="#">Friends</a></li>
<li><a style="background: $*navbar_bgcolor none; color: $*navbar_fgcolor;" href="#">User Info</a></li>
</ul>
</td><td style="width: 75%; background: $*entry_bgcolor none; color: $*entry_fgcolor" valign="top">
<div style="margin: 10px;">
<div style="border-top: 1px dashed $*entry_fgcolor; clear: both;">
<h3 style="border-bottom: 1px dashed $*entry_fgcolor; padding: 2px; margin: 0; font-size: 1.1em; text-align: center;">December 17th, 2002</h3>
<div style="clear: both;" id="entry2839"><div style="padding: 2px; text-align: justify">
<span style="font-weight: bold;">
<span style="font-weight: bold; color: $*meta_color; background: $*entry_bgcolor none;">06:42 pm</span>:
<span style="font-weight: bold; color: $*meta_color; background: $*entry_bgcolor none;">Neque porro quisquam&hellip;</span>
</span>
Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit
Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit
Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit
Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit
Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit
<div style="font-size: 0.75em; text-align: right; margin-bottom: 2px; clear: right;" >
<a href="#" style="color: $*link_color;">2 Comments Posted</a> | <a href="#" style="color: $*vlink_color">Leave a comment</a></div>
</div></div></div></div>
</td></tr></table>
</div>
""";
}

View File

@@ -0,0 +1,420 @@
#NEWLAYER: cleansimple/purpleblues
layerinfo type = theme;
layerinfo name = "Purples and Blues";
layerinfo redist_uniq = "cleansimple/purpleblues";
set body_bgcolor = "#660099";
set entry_bgcolor = "#9966cc";
set entry_fgcolor = "#ffff00";
set meta_color = "#003399";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#00ffff";
set topbar_bgcolor = "#c0c0ff";
set topbar_fgcolor = "#000000";
set navbar_bgcolor = "#eeeeff";
set navbar_fgcolor = "#000000";
set comment_bar_one_bgcolor = "#c0c0ff";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#eeeeff";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: cleansimple/flesh
layerinfo type = "theme";
layerinfo name = "Flesh";
layerinfo redist_uniq = "cleansimple/flesh";
set body_bgcolor = "#eeeeff";
set entry_bgcolor = "#ffffff";
set entry_fgcolor = "#000000";
set meta_color = "#ff0000";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#00ffff";
set topbar_bgcolor = "#fa83d7";
set topbar_fgcolor = "#000000";
set navbar_bgcolor = "#f677ad";
set navbar_fgcolor = "#000000";
set comment_bar_one_bgcolor = "#fa83d7";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#f677ad";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: cleansimple/shrinkvio
layerinfo type = theme;
layerinfo name = "Shrinking Violet";
layerinfo redist_uniq = "cleansimple/shrinkvio";
set body_bgcolor = "#ad22e7";
set entry_bgcolor = "#ffffff";
set entry_fgcolor = "#000000";
set meta_color = "#381a45";
set topbar_bgcolor = "#5d0383";
set topbar_fgcolor = "#ffffff";
set navbar_bgcolor = "#d9a1f1";
set navbar_fgcolor = "#000000";
set link_color = "#2e053f";
set vlink_color = "#611627";
set alink_color = "#ff00c0";
set comment_bar_one_bgcolor = "#5d0383";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#d9a1f1";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: cleansimple/pistmint
layerinfo type = theme;
layerinfo name = "Pistachio Mint";
layerinfo redist_uniq = "cleansimple/pistmint";
set body_bgcolor = "#133422";
set entry_bgcolor = "#a7c4b4";
set entry_fgcolor = "#000000";
set meta_color = "#096d36";
set topbar_bgcolor = "#096d36";
set topbar_fgcolor = "#ffffff";
set navbar_bgcolor = "#094f36";
set navbar_fgcolor = "#000000";
set link_color = "#8afabc";
set vlink_color = "#1da65a";
set alink_color = "#f9f5f5";
set comment_bar_one_bgcolor = "#096d36";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#094f36";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: cleansimple/mexicanfood
layerinfo type = theme;
layerinfo name = "Mexican Food";
layerinfo redist_uniq = "cleansimple/mexicanfood";
set body_bgcolor = "#ff0000";
set entry_bgcolor = "#f8ff3e";
set entry_fgcolor = "#f15601";
set meta_color = "#f50701";
set topbar_bgcolor = "#bdbf3e";
set topbar_fgcolor = "#ff0000";
set navbar_bgcolor = "#e15a18";
set navbar_fgcolor = "#ffffff";
set link_color = "#f49e08";
set vlink_color = "#b05403";
set alink_color = "#ff7405";
set comment_bar_one_bgcolor = "#bdbf3e";
set comment_bar_two_fgcolor = "#ff0000";
set comment_bar_two_bgcolor = "#e15a18";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: cleansimple/ashfire
layerinfo type = theme;
layerinfo name = "Ash and Fire";
layerinfo redist_uniq = "cleansimple/ashfire";
set body_bgcolor = "#b5b5b5";
set entry_bgcolor = "#ffb6af";
set entry_fgcolor = "#000000";
set meta_color = "#d90308";
set topbar_bgcolor = "#e75454";
set topbar_fgcolor = "#ffffff";
set navbar_bgcolor = "#f06c88";
set navbar_fgcolor = "#000000";
set link_color = "#f70208";
set vlink_color = "#b0161d";
set alink_color = "#d70106";
set comment_bar_one_bgcolor = "#e75454";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#f06c88";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: cleansimple/desktop
# for layout: 13 (cleansimple/layout)
layerinfo type = theme;
layerinfo name = "Classic Desktop";
layerinfo redist_uniq = "cleansimple/desktop";
set body_bgcolor = "#00545c";
set entry_bgcolor = "#ffffff";
set entry_fgcolor = "#000000";
set meta_color = "#000000";
set topbar_bgcolor = "#ff7b05";
set topbar_fgcolor = "#ffeddd";
set navbar_bgcolor = "#ffeddd";
set navbar_fgcolor = "#000000";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#5a76ff";
set comment_bar_one_bgcolor = "#ff7b05";
set comment_bar_one_fgcolor = "#ffeddd";
set comment_bar_two_bgcolor = "#ffeddd";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: cleansimple/satinhandshake
layerinfo type = theme;
layerinfo name = "Satin Handshake";
layerinfo redist_uniq = "cleansimple/satinhandshake";
set body_bgcolor = "#480c0c";
set entry_bgcolor = "#d06464";
set entry_fgcolor = "#00001d";
set meta_color = "#000000";
set topbar_bgcolor = "#aaaaaa";
set topbar_fgcolor = "#000000";
set navbar_bgcolor = "#9d0404";
set navbar_fgcolor = "#000000";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#ff00c0";
set comment_bar_one_bgcolor = "#aaaaaa";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#9d0404";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: cleansimple/deepmelodrama
layerinfo type = theme;
layerinfo name = "Deep MeloDrama";
layerinfo redist_uniq = "cleansimple/deepmelodrama";
set body_bgcolor = "#872d89";
set entry_bgcolor = "#719cff";
set entry_fgcolor = "#8e48b2";
set meta_color = "#8e48b2";
set topbar_bgcolor = "#3794b3";
set topbar_fgcolor = "#84b8e7";
set navbar_bgcolor = "#65b2c1";
set navbar_fgcolor = "#f5d3ff";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#dfd3ff";
set comment_bar_one_bgcolor = "#3794b3";
set comment_bar_one_fgcolor = "#84b8e7";
set comment_bar_two_bgcolor = "#65b2c1";
set comment_bar_two_fgcolor = "#f5d3ff";
#NEWLAYER: cleansimple/everwhite
layerinfo type = theme;
layerinfo name = "Everwhite";
layerinfo redist_uniq = "cleansimple/everwhite";
set body_bgcolor = "#ffffff";
set entry_bgcolor = "#ffffff";
set entry_fgcolor = "#000000";
set meta_color = "#000000";
set topbar_bgcolor = "#ffffff";
set topbar_fgcolor = "#000000";
set navbar_bgcolor = "#ffffff";
set navbar_fgcolor = "#000000";
set link_color = "#e60000";
set vlink_color = "#c10602";
set alink_color = "#ff0600";
set comment_bar_one_bgcolor = "#ffffff";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#ffffff";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: cleansimple/everblue
layerinfo type = theme;
layerinfo name = "Everblue with Greys";
layerinfo redist_uniq = "cleansimple/everblue";
set body_bgcolor = "#0f0c6d";
set entry_bgcolor = "#ffffff";
set entry_fgcolor = "#000000";
set meta_color = "#000000";
set topbar_bgcolor = "#000000";
set topbar_fgcolor = "#ffffff";
set navbar_bgcolor = "#aaaaaa";
set navbar_fgcolor = "#000000";
set link_color = "#2f00f2";
set vlink_color = "#060667";
set alink_color = "#6691ff";
set comment_bar_one_bgcolor = "#000000";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#aaaaaa";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: cleansimple/brownleather
layerinfo type = theme;
layerinfo name = "Brown Leather Coat";
layerinfo redist_uniq = "cleansimple/brownleather";
set body_bgcolor = "#d2b48c";
set entry_bgcolor = "#ffebcd";
set entry_fgcolor = "#8b4513";
set meta_color = "#000000";
set topbar_bgcolor = "#d48014";
set topbar_fgcolor = "#ffffff";
set navbar_bgcolor = "#ffe1a1";
set navbar_fgcolor = "#000000";
set link_color = "#000050";
set vlink_color = "#867a55";
set alink_color = "#fffab3";
set comment_bar_one_bgcolor = "#d48014";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#ffe1a1";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: cleansimple/bruise
layerinfo type = theme;
layerinfo name = "Bruise";
layerinfo redist_uniq = "cleansimple/bruise";
set body_bgcolor = "#000000";
set entry_bgcolor = "#bcbcbc";
set entry_fgcolor = "#000000";
set meta_color = "#000000";
set topbar_bgcolor = "#1114a0";
set topbar_fgcolor = "#ffffff";
set navbar_bgcolor = "#21c2f1";
set navbar_fgcolor = "#0000ff";
set link_color = "#0000cc";
set vlink_color = "#000088";
set alink_color = "#0000ff";
set comment_bar_one_bgcolor = "#1114a0";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#21c2f1";
set comment_bar_two_fgcolor = "#0000ff";
#NEWLAYER: cleansimple/ranchhand
layerinfo type = theme;
layerinfo name = "Ranch Hand";
layerinfo redist_uniq = "cleansimple/ranchhand";
set body_bgcolor = "#2999c2";
set entry_bgcolor = "#cfe0ff";
set entry_fgcolor = "#000000";
set meta_color = "#060667";
set topbar_bgcolor = "#54442c";
set topbar_fgcolor = "#ffffff";
set navbar_bgcolor = "#704400";
set navbar_fgcolor = "#bababa";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#6a20ff";
set comment_bar_one_bgcolor = "#54442c";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#704400";
set comment_bar_two_fgcolor = "#bababa";
#NEWLAYER: cleansimple/victim
layerinfo type = theme;
layerinfo name = "Victim";
layerinfo redist_uniq = "cleansimple/victim";
set body_bgcolor = "#2cd0ff";
set entry_bgcolor = "#505050";
set entry_fgcolor = "#ffffff";
set meta_color = "#000000";
set topbar_bgcolor = "#166bac";
set topbar_fgcolor = "#ffffff";
set navbar_bgcolor = "#353535";
set navbar_fgcolor = "#ffffff";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#ff00c0";
set comment_bar_one_bgcolor = "#166bac";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#353535";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: cleansimple/forest
layerinfo type = theme;
layerinfo name = "Forest";
layerinfo redist_uniq = "cleansimple/forest";
set body_bgcolor = "#778e64";
set entry_bgcolor = "#9b9ba5";
set entry_fgcolor = "#000000";
set meta_color = "#ffffff";
set topbar_bgcolor = "#72784c";
set topbar_fgcolor = "#ffffff";
set navbar_bgcolor = "#73777a";
set navbar_fgcolor = "#000000";
set link_color = "#3811e1";
set vlink_color = "#310cbb";
set alink_color = "#4e7bef";
set comment_bar_one_bgcolor = "#72784c";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#73777a";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: cleansimple/drone
layerinfo type = theme;
layerinfo name = "Drone";
layerinfo redist_uniq = "cleansimple/drone";
set body_bgcolor = "#395f82";
set entry_bgcolor = "#f9fcfe";
set entry_fgcolor = "#000000";
set meta_color = "#000000";
set topbar_bgcolor = "#904094";
set topbar_fgcolor = "#ffffff";
set navbar_bgcolor = "#eeeeff";
set navbar_fgcolor = "#000000";
set link_color = "#395f82";
set vlink_color = "#395f82";
set alink_color = "#5266ce";
set comment_bar_one_bgcolor = "#904094";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#eeeeff";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: cleansimple/lowercurtain
layerinfo type = theme;
layerinfo name = "Lower the Curtain";
layerinfo redist_uniq = "cleansimple/lowercurtain";
set body_bgcolor = "#000000";
set entry_bgcolor = "#6b6b6b";
set entry_fgcolor = "#ffffff";
set meta_color = "#ffffff";
set topbar_bgcolor = "#363636";
set topbar_fgcolor = "#f0f5fb";
set navbar_bgcolor = "#c5c8ca";
set navbar_fgcolor = "#000000";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#3314ba";
set comment_bar_one_bgcolor = "#363636";
set comment_bar_one_fgcolor = "#f0f5fb";
set comment_bar_two_bgcolor = "#c5c8ca";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: cleansimple/sunny
layerinfo type = theme;
layerinfo name = "Sunny Day";
layerinfo redist_uniq = "cleansimple/sunny";
set body_bgcolor = "#55e0f9";
set entry_bgcolor = "#e38202";
set entry_fgcolor = "#ffffff";
set meta_color = "#000000";
set topbar_bgcolor = "#ffba03";
set topbar_fgcolor = "#ffffff";
set navbar_bgcolor = "#ffba55";
set navbar_fgcolor = "#ffffff";
set link_color = "#df0d12";
set vlink_color = "#ac1b25";
set alink_color = "#fe3b3b";
set comment_bar_one_bgcolor = "#ffba03";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#ffba55";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: cleansimple/valentine
layerinfo type = theme;
layerinfo name = "Be Mine";
layerinfo redist_uniq = "cleansimple/valentine";
set body_bgcolor = "#6f104a";
set entry_bgcolor = "#f2bce9";
set entry_fgcolor = "#000000";
set meta_color = "#ff24ab";
set topbar_bgcolor = "#ff37ff";
set topbar_fgcolor = "#ffffff";
set navbar_bgcolor = "#df2096";
set navbar_fgcolor = "#000000";
set link_color = "#ffffff";
set vlink_color = "#a51014";
set alink_color = "#ed8188";
set comment_bar_one_bgcolor = "#ff37ff";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#df2096";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: cleansimple/stripes
layerinfo type = theme;
layerinfo name = "Stripes";
layerinfo redist_uniq = "cleansimple/stripes";
set body_bgcolor = "#ffffff";
set entry_bgcolor = "#ffffff";
set entry_fgcolor = "#000000";
set meta_color = "#ff0000";
set topbar_bgcolor = "#e7212a";
set topbar_fgcolor = "#ffffff";
set navbar_bgcolor = "#ffcfdc";
set navbar_fgcolor = "#000000";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#ffafc1";
set comment_bar_one_bgcolor = "#e7212a";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#ffcfdc";
set comment_bar_two_fgcolor = "#000000";

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -0,0 +1,10 @@
# -*-s2-*-
layerinfo type = "i18n";
layerinfo name = "English";
layerinfo redist_uniq = "digitalmultiplex/en";
set text_meta_music = "Music";
set text_meta_mood = "Mood";
set text_sidebar_link_separator = "&nbsp;&nbsp;&raquo;&nbsp;&nbsp;";

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,17 @@
# -*-s2-*-
layerinfo type = "i18n";
layerinfo name = "English";
layerinfo redist_uniq = "generator/en";
set text_meta_music = "music";
set text_meta_mood = "mood";
set text_permalink = "link";
set text_post_comment = "post comment";
set text_post_comment_friends = "post comment";
set text_read_comments = "1 comment // # comments";
set text_read_comments_friends = "1 comment // # comments";

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

@@ -0,0 +1,945 @@
# -*-s2-*-
layerinfo type = "layout";
layerinfo name = "Generator";
layerinfo redist_uniq = "generator/layout";
layerinfo previews = "generator/generator.jpg";
propgroup colors {
property Color entry_back {
des = "Entry background";
s1color = "page_back";
}
property Color entry_text {
des = "Entry text color";
s1color = "page_text";
}
property Color page_link {
des = "Link color";
s1color = "page_link";
}
property Color page_vlink {
des = "Visited link color";
s1color = "page_vlink";
}
property Color page_alink {
des = "Active link color";
s1color = "page_alink";
}
property Color page_back {
des = "Page background color (and around userpics)";
s1color = "strong_back";
}
property Color stronger_back {
des = "Background color for the bar above entries";
s1color = "strong_back";
}
property Color stronger_text {
des = "Text color for the bar above entries";
s1color = "stronger_text";
}
property Color weak_back {
des = "Background color for the bar below entries";
s1color = "weak_back";
}
property Color weak_text {
des = "Text color for the bar below entries";
s1color = "weak_text";
}
property Color comment_bar_one_bgcolor {
des = "Alternating background color for comment bars (one)";
}
property Color comment_bar_two_fgcolor {
des = "Text color on alternating comment bars (one)";
}
property Color comment_bar_two_bgcolor {
des = "Alternating background color for comment bars (two)";
}
property Color comment_bar_one_fgcolor {
des = "Text color on alternating comment bars (two)";
}
property Color comment_bar_screened_bgcolor {
des = "Background bar color for screened comments";
}
property Color comment_bar_screened_fgcolor {
des = "Text color on background bar for screened comments";
}
}
propgroup fonts {
property use font_base;
property use font_fallback;
}
propgroup presentation {
property use page_recent_items;
property use page_friends_items;
property int box_width {
des = "Box width (pixels)";
}
property use view_entry_disabled;
property use use_shared_pic;
property use comment_userpic_style;
property bool show_entrynav_icons {
des = "Toggle to show the next, memory, edit, etc icons on the entry view page";
}
property string page_background_image {
des = "URL to an image to be used for the page background";
}
property use external_stylesheet;
property use linklist_support;
}
propgroup text {
property use text_post_comment;
property use text_read_comments;
property use text_post_comment_friends;
property use text_read_comments_friends;
property use text_meta_music;
property use text_meta_mood;
property string text_website {
des = "The label for the 'website' field";
noui = 1;
}
}
# Set default colors
set entry_back = "#ffffff";
set entry_text = "#000000";
set page_link = "#0000ff";
set page_vlink = "#0000ff";
set page_alink = "#00ffff";
set page_back = "#2d4f89";
set stronger_back = "#000000";
set stronger_text = "#ffffff";
set weak_back = "#aaaaaa";
set weak_text = "#000000";
set comment_bar_one_bgcolor = "#aaaaaa";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#dddddd";
set comment_bar_two_fgcolor = "#000000";
set comment_bar_screened_bgcolor = "#5f6f99";
set comment_bar_screened_fgcolor = "#000000";
set box_width = 600;
set show_entrynav_icons = true;
set page_background_image = "";
set font_base = "Verdana";
set font_fallback = "sans-serif";
# Customize the view names to be short and lowercase
# (Sorry translators, you'll have to do these again - keep them short!)
set text_view_recent = "entries";
set text_view_friends = "friends";
set text_view_archive = "archive";
set text_view_userinfo = "userinfo";
set tags_aware = true;
set text_website = "website";
function print_stylesheet () {
print clean_url($*page_background_image) != "" ? "body { background-image: url($*page_background_image); }" : "";
"""body, td {
""";
if ($*font_base != "" or $*font_fallback != "none") {
"font-family: ";
if ($*font_base != "") {
"\"$*font_base\"";
if ($*font_fallback != "none") {
", ";
}
}
if ($*font_fallback != "none") {
print $*font_fallback;
}
";\n";
}
"""font-size: 10pt;
}
tt, pre {
font-family: monospace;
}
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.shadowed {
font-size: 8pt;
background: $*weak_back;
}
.meta {
font-size: 8pt;
}
.index {
font-size: 8pt;
}
.caption, .index {
color: $*stronger_text;
}
.comments {
font-size: 8pt;
}
""";
}
function Page::lay_top_userpic () {
var Image up_img = $.journal.default_pic;
if (defined $up_img) {
"""<td><table cellpadding="2" bgcolor="$*entry_back" cellspacing="0" border="0" summary="">
<tr><td bgcolor="$*stronger_back" align="center"><img border="0" src="$up_img.url" height="$up_img.height" width="$up_img.width" alt=""></td></tr>
</table></td>
""";
}
}
function FriendsPage::lay_top_userpic () { }
function Page::print_linklist() {
if (size $.linklist <= 0) {
return;
}
println """
<p>
<table width='$*box_width' cellpadding='2' cellspacing='0'
border='0'
summary=''>
<tr><td bgcolor='$*stronger_back' align='center'>
<table width='100%' cellpadding='3' cellspacing='0'
border='0'
summary=''>
<tr class='caption'>
<td class='caption' align='left'><b>Links</b></td>
</tr></table>
<table width='100%' cellpadding='3' cellspacing='0'
border='0'
summary=''>
<tr class='shadowed'>
<td align='center'>
<table cellspacing='5'
cellpadding='0'
border='0'
summary=''>
""";
var bool section_open = false;
if (not $.linklist[0].is_heading) {
println """<tr><td class="meta">[</td><td class="meta" align="right"><b>Links:</b></td><td class="meta" align="center">|</td><td class="meta">""";
$section_open = true;
}
foreach var UserLink l ($.linklist) {
if ($l.title) {
if ($l.is_heading) {
if ($section_open) {
println """</td><td class="meta">]</td></tr>""";
}
println """<tr><td class="meta">[</td><td class="meta" align="right"><b>$l.title</b></td><td class="meta" align="center">|</td><td class="meta">""";
$section_open = true;
} else {
println """<a href="$l.url">$l.title</a> """;
}
}
}
println """</td><td class="meta">]</td></tr>""";
"</table>
</td>
</tr>
</table>
</td>
</tr></table>
</p>
";
}
function Page::print ()
{
var string title = $this->title();
var string website_name = $.journal.website_name ? $.journal.website_name : $*text_website_default_name;
var string website;
if ($.journal.website_url != "") {
$website = """<tr><td class="meta">[</td>
<td class="meta" align="right"><b>$*text_website</b></td>
<td class="meta" align="center">|</td>
<td class="meta" align="left"><a href="$.journal.website_url">$website_name</a></td>
<td class="meta">]</td></tr>""";
}
var string links;
var bool firstlink = true;
foreach var string v ($.views_order) {
if ($firstlink == false) {
$links = "$links|";
}
else {
$firstlink = false;
}
$links = $links + ($.view == $v ?
"<b>"+lang_viewname($v)+"</b>" :
"<a class='index' href='$.view_url{$v}'>"+lang_viewname($v)+"</a>");
}
"""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">\n<html>\n<head>\n""";
if ($*external_stylesheet) {
println """<link rel="stylesheet" href="$.stylesheet_url" type="text/css" />""";
} else {
println """<style type="text/css">"""; print_stylesheet(); "</style>";
}
$this->print_head();
"""<title>$title</title>
</head>
<body bgcolor="$*page_back" text="$*entry_text" link="$*page_link" vlink="$*page_vlink" alink="$*page_alink">
<div align="center">
<table width="$*box_width" cellpadding="2" cellspacing="0"
border="0"
summary="">
<tr><td bgcolor="$*stronger_back" align="center">
<table width="100%" cellpadding="3" cellspacing="0"
border="0"
summary="">
<tr class="caption">
<td class="caption" align="left"><b>$title</b></td>
<td class="index" align="right">[$links]</td>
</tr></table>
<table width="100%" cellpadding="3" cellspacing="0"
border="0"
summary="">
<tr>
<td class="shadowed" align="center">
<table cellspacing="5"
cellpadding="0"
border="0"
summary="" style="margin-left: auto; margin-right: auto;">
<tr>""";
$this->lay_top_userpic();
var string sitename_lc = $*SITENAMESHORT->lower();
"""<td>
<div align="center"><b>$.journal.name</b></div><p>
<table cellspacing="0"
cellpadding="0"
border="0"
summary="">
$website
<tr>
<td class="meta">[</td>
<td class="meta" align="right"><b>"""+lang_viewname("userinfo")+"""</b></td>
<td class="meta" align="center">|</td>
<td class="meta" align="left"><a href="$.view_url{"userinfo"}">$sitename_lc userinfo</a></td>
<td class="meta">]</td>
</tr>
<tr>
<td class="meta">[</td>
<td class="meta" align="right"><b>"""+lang_viewname("archive")+"""</b></td>
<td class="meta" align="center">|</td>
<td class="meta" align="left"><a href="$.view_url{"archive"}">journal archive</a></td>
<td class="meta">]</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr></table>
</td></tr>
</table>
""";
if (size $.linklist > 0 and $*linklist_support) {
$this->print_linklist();
}
"""
<p>
""";
$this->print_body();
"""
</div>
<p>
</body>
</html>
""";
}
function print_entry (Page p, Entry e, Color bgcolor, Color fgcolor, bool hide_text)
{
var string datetime;
$datetime = $e.time->date_format("med")+"|<b>"
+ $e.time->time_format() + "</b>";
"""
<table width="$*box_width" cellpadding="2" cellspacing="0" border="0" summary="" class="entrybox">
<tr align='left'>
<td bgcolor="$*stronger_back" align="center">
<table width="100%" cellpadding="5" cellspacing="0" border="0" summary="">
<tr align='left'>
<td class="caption">""";
if ($e.security != "") {
$e.security_icon->print();
}
""" $e.subject</td>
<td align="right" class="index">[$datetime]</td>
</tr>
<tr align='left'>
<td colspan="2" bgcolor="$*entry_back">
""";
if ($p.view == "entry" and $*show_entrynav_icons)
{
print "<div style='text-align: center'>";
$e->print_linkbar();
print "</div>";
}
if ($p.view == "friends" or
$p.journal_type == "C" or
$e.poster.username != $e.journal.username)
{
var UserLite linkto;
var bool showposter;
if ($p.view == "recent" and $p.journal_type == "C") {
$linkto = $e.poster;
$showposter = false;
} else {
$linkto = $e.journal;
$showposter = true;
}
"""<table cellpadding="1" align="right" cellspacing="0" border="0" summary=""><tr align='left'><td bgcolor="$*stronger_back">""";
"""<table cellpadding="2" align="center" cellspacing="0" border="0" summary="">""";
"""<tr align='left'><td bgcolor="$bgcolor" align="center"><a class="index" href=\"""" + $linkto->base_url() + "\">";
if (defined $e.userpic) {
"""<img border="0" src="$e.userpic.url" width="$e.userpic.width" height="$e.userpic.height" alt=""><br>""";
}
"<font color=\"$fgcolor\">$linkto.username</font></a>";
if ($e.poster.username != $e.journal.username and $showposter) {
"<br>[<a class=\"index\" href=\"" +
$e.poster->base_url() + "/\"><font color=\"$fgcolor\">$e.poster.username</font></a>]";
}
"</td></tr></table></td></tr></table>";
}
var string metadata;
if ($e.metadata) {
$metadata = """<table cellspacing="0" cellpadding="0" border="0" summary="">""";
foreach var string k ($e.metadata) {
var string text = $k;
var string val = $e.metadata{$k};
if ($k == "mood") {
$text = $*text_meta_mood;
} elseif ($k == "music") {
$text = $*text_meta_music;
}
if ($k == "mood" and defined $e.mood_icon) {
var Image i = $e.mood_icon;
$val = "<img src='$i.url' width='$i.width' height='$i.height' align='absmiddle'> $val";
}
$metadata = """$metadata\n<tr><td class="meta">[</td><td class="meta" align="right"><b>$text</b></td>
<td class="meta" align="center">|</td><td class="meta">$val</td><td class="meta">]</td></tr>""";
}
$metadata = """$metadata</table>""";
}
var string tags;
if ($e.tags) {
var int tcount = 0;
$tags = """<table cellspacing="0" cellpadding="0" border="0" summary=""><tr><td class="meta" align="right">[<b>Tags</b></td>""";
$tags = """$tags<td class="meta" align="center">|</td><td class="meta">""";
foreach var Tag t ($e.tags) {
$tags = """$tags<a rel="tag" href="$t.url">$t.name</a>""";
$tcount++;
if ($tcount != size $e.tags) { $tags = """$tags, """; }
}
$tags = """$tags</td><td class="meta">]</td></tr></table>""";
}
if (not $hide_text) {
if ($tags or $metadata) {
print $tags;
print $metadata;
print "<br />";
}
print $e.text;
}
"""</td></tr>
<tr bgcolor="$*weak_back"><td align='left' class='comments'>
<a href="$e.permalink_url">$*text_permalink</a></td>""";
if ($p.view != "entry" and $p.view != "reply") {
"<td align='right' class='comments'>"; $e.comments->print(); "</td>";
} elseif ($e.comments.enabled) {
"<td align='right' class='comments'>"; $e.comments->print_postlink(); "</td>";
} else {
"<td></td>";
}
"""</tr></table></td></tr></table><p>""";
} # print_entry(Page,Entry,Color,Color,bool)
function Page::print_entry (Entry e) {
print_entry($this, $e, null Color, null Color, false);
}
function FriendsPage::print_entry (Entry e) {
var Friend f = $.friends{$e.journal.username};
print_entry($this, $e, $f.bgcolor, $f.fgcolor, false);
}
function RecentPage::print_body ()
{
foreach var Entry e ($.entries) {
$this->print_entry($e);
}
var string range = "most recent entries";
if ($.nav.skip > 0) {
$range = "$.nav.skip entries back";
}
"""
<table cellpadding="2" cellspacing="0"
border="0"
summary="">
<tr><td bgcolor="$*stronger_back">
<table cellpadding="3" cellspacing="0"
border="0"
summary="">
<tr>
<td align="center" class="index">navigation</td>
</tr>
<tr>
<td bgcolor="$*entry_back" align="center">
<table cellspacing="0"
cellpadding="0"
border="0"
summary="">
<tr>
<td class="meta">[</td>
<td class="meta" align="right"><b>viewing</b></td>
<td class="meta" align="center">|</td>
<td class="meta">$range</td>
<td class="meta">]</td>
</tr>
""";
# go forward/backward if possible
if ($.nav.forward_url != "" or $.nav.backward_url != "") {
var string sep;
var string back;
var string forward;
if ($.nav.backward_url != "") {
$back = """<a href="$.nav.backward_url">earlier</a>""";
}
if ($.nav.forward_url != "") {
$forward = """<a href="$.nav.forward_url">later</a>""";
}
if ($back != "" and $forward != "") { $sep = "/"; }
"""<tr>
<td class="meta">[</td>
<td class="meta" align="right"><b>go</b></td>
<td class="meta" align="center">|</td>
<td class="meta">$back$sep$forward</td>
<td class="meta">]</td>
</tr>""";
}
"</table></td></tr></table></table>";
}
function CommentInfo::print ()
{
if (not $.enabled) { return; }
if ($.count > 0 or $.screened) {
"<b>"; $this->print_readlink(); "</b>";
"|";
}
$this->print_postlink();
}
function YearPage::print_year_links ()
{
"""<table cellpadding="2" cellspacing="0" border="0" summary="">
<tr><td bgcolor="$*stronger_back" align="center">
<table cellpadding="5" cellspacing="0" border="0" summary="">
<tr><td class="caption">Years</td></tr><tr>
<td colspan="2" bgcolor="$*entry_back">""";
foreach var YearYear y ($.years) {
if ($y.displayed) {
"<b>$y.year</b>&nbsp;";
} else {
"<a href=\"$y.url\">$y.year</a>&nbsp;";
}
}
"""</td></tr></table></td></tr></table><p>""";
}
function YearPage::print_month (YearMonth m)
{
if (not $m.has_entries) { return; }
"""<table cellpadding="2" cellspacing="0" border="0" summary="">
<tr><td bgcolor="$*stronger_back" align="center">
<table cellpadding="5" cellspacing="0" border="0" summary="">
<tr>
<td class="caption">""";
print $m->month_format();
"""</td>
<td class="caption" align="right">[<a href="$m.url" class="index">subjects</a>]</td>
</tr>
<tr>
<td colspan="2" bgcolor="$*entry_back">
<!-- now the headings for the week -->
<table width="100%" cellpadding="5" cellspacing="0" border="0" summary="">
<tr align="center">
""";
foreach var int d (weekdays()) {
"<td>"+$*lang_dayname_short[$d]+"</td>\n";
}
"</tr>";
foreach var YearWeek w ($m.weeks) {
$w->print();
}
"""</table></td></tr></table></td></tr></table><p>""";
}
function YearWeek::print () {
"<tr valign='top'>";
if ($.pre_empty) { "<td colspan='$.pre_empty'></td>"; }
foreach var YearDay d ($.days) {
"""<td><div class="meta">$d.day</div>""";
if ($d.num_entries) {
"""<div align="center"><a href="$d.url">$d.num_entries</a></div>""";
} else {
"&nbsp;";
}
"</td>";
}
if ($.post_empty) { "<td colspan='$.post_empty'></td>"; }
"</tr>";
}
function DayPage::print_body() {
"""<table cellpadding="2" cellspacing="0" border="0" summary="">
<tr><td bgcolor="$*stronger_back" align="center">
<table cellpadding="5" cellspacing="0" border="0" summary="">
<tr><td bgcolor="$*entry_back">""";
if ($.has_entries) {
print $.date->date_format("long");
} else {
print ehtml($*text_noentries_day);
}
"""</td></tr></table></td></tr></table><p>""";
foreach var Entry e ($.entries) {
$this->print_entry($e);
}
var string tprev = ehtml($*text_day_prev);
var string tnext = ehtml($*text_day_next);
var string daylong = $.date->date_format("long");
"""<table cellpadding="2" cellspacing="0" border="0" summary="">
<tr><td bgcolor="$*stronger_back">
<table cellpadding="3" cellspacing="0" border="0" summary="">
<tr>
<td align="center" class="index">navigation</td>
</tr>
<tr>
<td bgcolor="$*entry_back" align="center">
<table cellspacing="0" cellpadding="0" border="0" summary="">
<tr>
<td class="meta">[</td>
<td class="meta" align="right"><b>viewing</b></td>
<td class="meta" align="center">|</td>
<td class="meta">$daylong</td>
<td class="meta">]</td>
</tr>
<tr>
<td class="meta">[</td>
<td class="meta" align="right"><b>go</b></td>
<td class="meta" align="center">|</td>
<td class="meta"><a href="$.prev_url">$tprev</a>|<a href="$.next_url">$tnext</a></td>
<td class="meta">]</td>
</tr>
</table>
</td>
</tr>
</table>
</table>""";
}
function MonthPage::print_body () {
"""<table width="$*box_width" cellpadding="2" cellspacing="0" border="0" summary="" class="entrybox">
<tr align='left'>
<td bgcolor="$*stronger_back" align="center">
<table width="100%" cellpadding="5" cellspacing="0" border="0" summary="">
<tr align='left'>
<td class="caption" colspan='2'>""";
print $.date->date_format($*lang_fmt_month_long);
"""</td></tr>
<tr align='left'>
<td colspan="2" bgcolor="$*entry_back">""";
#Lifted from core, looks decent:
"<form method='post' action='$.redir.url'><center>";
$.redir->print_hiddens();
if ($.prev_url != "") { "[<a href='$.prev_url'>&lt;&lt;&lt;</a>]\n"; }
if (size $.months > 1) {
"<select name='redir_key'>\n";
foreach var MonthEntryInfo mei ($.months) {
var string sel;
if ($mei.date.year == $.date.year and $mei.date.month == $.date.month) {
$sel = " selected='selected'";
}
"<option value='$mei.redir_key'$sel>" + $mei.date->date_format($*lang_fmt_month_long) + "</option>";
}
"</select>\n<input type='submit' value='View' />";
}
if ($.next_url != "") { "\n[<a href='$.next_url'>&gt;&gt;&gt;</a>]\n"; }
"</center></form>\n<dl>";
foreach var MonthDay d ($.days) {
if ($d.has_entries) {
"<dt><a href=\"$d.url\"><b>";
print lang_ordinal($d.day);
"</b></a></dt>\n<dd>";
$d->print_subjectlist();
"</dd>\n";
}
}
"</dl>\n";
"""</td></tr></table>
</td></tr></table><p>""";
}
function EntryPage::print_body () {
print_entry($this, $.entry, null Color, null Color, $.viewing_thread);
if ($.entry.comments.enabled and $.comment_pages.total_subitems > 0)
{
$this->print_multiform_start();
"""<table width="$*box_width" cellpadding="2" cellspacing="0" border="0" summary="" class="entrybox">
<tr align='left'>
<td bgcolor="$*stronger_back" align="center">
<table width="100%" cellpadding="5" cellspacing="0" border="0" summary="">
<tr align='left'>
<td class="caption" colspan='2'>Comments:</td></tr>""";
"""<tr align='left'><td colspan="2" bgcolor="$*entry_back">""";
$.comment_pages->print();
set_handler("unscreen_comment_#", [
[ "style_bgcolor", "cmtbar#", "$*comment_bar_one_bgcolor", ],
[ "style_color", "cmtbar#", "$*comment_bar_one_fgcolor", ],
]);
set_handler("screen_comment_#", [
[ "style_bgcolor", "cmtbar#", "$*comment_bar_screened_bgcolor", ],
[ "style_color", "cmtbar#", "$*comment_bar_screened_fgcolor", ],
]);
$this->print_comments($.comments);
$.comment_pages->print();
"""</td></tr></table></td></tr></table><p>""";
if ($this.multiform_on) {
"""<table width="$*box_width" cellpadding="2" cellspacing="0" border="0" summary="" class="entrybox">
<tr align='left'>
<td bgcolor="$*stronger_back" align="center">
<table width="100%" cellpadding="5" cellspacing="0" border="0" summary="">
<tr align='left'>
<td class="caption" colspan='2'>Mass Action:</td></tr>""";
"""<tr align='left'><td colspan="2" bgcolor="$*entry_back">""";
$this->print_multiform_actionline();
"""</td></tr></table></td></tr></table><p>""";
$this->print_multiform_end();
}
}
}
function EntryPage::print_comment (Comment c) {
var Color background; var Color color;
if ($c.screened) {
$background = $*comment_bar_screened_bgcolor;
$color = $*comment_bar_screened_fgcolor;
} elseif ($c.depth % 2) {
$background = $*comment_bar_one_bgcolor;
$color = $*comment_bar_one_fgcolor;
} else {
$background = $*comment_bar_two_bgcolor;
$color = $*comment_bar_two_fgcolor;
}
var string poster = defined $c.poster ? $c.poster->as_string() : "<i>(Anonymous)</i>";
var string sub_icon;
if (defined $c.subject_icon) {
$sub_icon = $c.subject_icon->as_string();
}
"<a name='$c.anchor'></a><div id='cmtbar$c.talkid' style='background-color: $background; color: $color; margin-top: 10px; width: 100%;'>";
"<table cellpadding='2' cellspacing='0' summary='0' style='width: 100%'><tr valign='top'>";
if (defined $c.userpic and $*comment_userpic_style != "off") {
var int w = $c.userpic.width;
var int h = $c.userpic.height;
# WARNING: this will later be done by the system (it'll be a
# constructional property), so don't copy this hack into your
# layout layers or you'll be messed up later.
if ($*comment_userpic_style == "small") {
$w = $w / 2;
$h = $h / 2;
}
print "<td style='width: 102px'><img src='$c.userpic.url' width='$w' height='$h' alt='[User Picture]' /></td>";
}
"<td style='width: 100%'><table style='width: 100%'><tr>";
### From, date, etc
"<td align='left' style='width: 50%'>";
print "<table>";
print "<tr><th align='right' style='white-space: nowrap'>From:</th><td style='white-space: nowrap'>$poster</td></tr>\n";
print "<tr><th align='right' style='white-space: nowrap'>Date:</th><td style='white-space: nowrap'>";
print $c.time->date_format("long") + " - " + $c.time->time_format() + "</td></tr>";
if ($c.metadata{"poster_ip"}) { print "<tr><th align='right' style='white-space: nowrap'>IP Address:</th><td>(" + $c.metadata{"poster_ip"} + ")</td></tr>"; }
"</table></td>";
### Gadgets
"<td align='right' style='width: 50%'>";
if ($this.multiform_on) {
" <label for='ljcomsel_$c.talkid'>$*text_multiform_check</label>";
$c->print_multiform_check();
}
$c->print_linkbar();
"</td></tr>";
### Subject / icon
print "<tr valign='top'><td style='width: 50%'>";
print (defined $c.subject_icon or $c.subject != "") ? "<h3>$c.subject_icon $c.subject</h3>" : "";
print "</td>";
### Permalink
print "<td style='width: 50%' align='right'><strong>(<a href='$c.permalink_url'>Link</a>)</strong></td></tr>";
print "</table></td></tr></table></div>";
print "<div style='margin-left: 5px'>$c.text</div>";
print "<div style='margin-top: 3px; font-size: smaller'>";
"<span class='commentlinks'>";
if ($c.frozen) {
"(Replies frozen) ";
} else {
"(<a href='$c.reply_url'>Reply to this</a>) ";
}
"</span>";
if ($c.parent_url != "") { "(<a href='$c.parent_url'>Parent</a>) "; }
if ($c.thread_url != "") { "(<a href='$c.thread_url'>Thread</a>) "; }
"</div>";
}
function ReplyPage::print_body () {
if (not $.entry.comments.enabled) {
"""<table width="$*box_width" cellpadding="2" cellspacing="0" border="0" summary="" class="entrybox">
<tr align='left'>
<td bgcolor="$*stronger_back" align="center">
<table width="100%" cellpadding="5" cellspacing="0" border="0" summary="">
<tr align='left'>
<td class="caption" colspan='2'>$*text_reply_nocomments_header</td></tr>
<tr align='left'>
<td colspan="2" bgcolor="$*entry_back">""";
print "<p>$*text_reply_nocomments</p>";
"""</td></tr></table></td></tr></table><p>""";
return;
}
var string datetime;
$datetime = $.replyto.time->date_format("med")+"|<b>" + $.replyto.time->time_format() + "</b>";
"""<table width="$*box_width" cellpadding="2" cellspacing="0" border="0" summary="" class="entrybox">
<tr align='left'>
<td bgcolor="$*stronger_back" align="center">
<table width="100%" cellpadding="5" cellspacing="0" border="0" summary="">
<tr align='left'>
<td class="caption">$.replyto.subject</td>
<td class="index" align="right">$datetime</td></tr>
<tr align='left'>
<td colspan="2" bgcolor="$*entry_back">
<table cellpadding="1" align="right" cellspacing="0" border="0" summary="">
<tr align='left'><td bgcolor="$*stronger_back">
<table cellpadding="2" align="center" cellspacing="0" border="0" summary="">
<tr align='left'><td align="center" style="color: $*stronger_text">""";
if (defined $.replyto.poster) {
"<a href='" + $.replyto.poster->base_url() + "/'>";
if (defined $.replyto.userpic) {
"""<img border="0" src="$.replyto.userpic.url" width="$.replyto.userpic.width" """;
"""height="$.replyto.userpic.height" alt=""><br />""";
}
"$.replyto.poster.username</a>";
} else {
print "<i>Anonymous</i>";
}
"""</td></tr></table></td></tr></table>$.replyto.text</td></tr>
<tr bgcolor="$*weak_back"><td align='left' class='comments'>
<a href="$.replyto.permalink_url">$*text_permalink</a></td>
<td align='right' class='comments'><a href='$.entry.comments.read_url'>Read Comments</a></td>
</tr></table></td></tr></table><p>""";
"""<table width="$*box_width" cellpadding="2" cellspacing="0" border="0" summary="" class="entrybox">
<tr align='left'>
<td bgcolor="$*stronger_back" align="center">
<table width="100%" cellpadding="5" cellspacing="0" border="0" summary="">
<tr align='left'>
<td class="caption" colspan='2'>Reply:</td></tr>
<tr align='left'>
<td colspan="2" bgcolor="$*entry_back">""";
$.form->print();
"""</td></tr></table></td></tr></table><p>""";
}
function print_theme_preview () {
"""<table width='100%' bgcolor='$*page_back' cellpadding=10><tr><td align='center'>
<table width='400' cellpadding='2' cellspacing='2'>
<tr align='left'><td bgcolor="$*stronger_back" align="center">
<table width="100%" cellpadding="5" cellspacing="0" border="0" summary="">
<tr align='left'><td style="color: $*stronger_text">Preview Subject</td><td align="right" style="font-size: 8pt; color: $*stronger_text">[Feb. 5th, 2002|<b>8:46 pm</b>]</td></tr>
<tr align='left'>
<td colspan="2" bgcolor="$*entry_back" style='color: $*entry_text'>
Preview text, preview text, etc, etc..... words, words and more words.
</td></tr>
<tr bgcolor="$*weak_back"><td align='left' class='style: font-size: 8pt'>
<a style='text-decoration:none;color: $*page_link' href="#">$*text_permalink</a>
</td><td align='right' style='font-size: 8pt'>
<a href='#' style='text-decoration:none;color:$*page_vlink'><b>1 comment</b></a>|<a href='#' style='text-decoration:none;color:$*page_link'>post comment</a>
</td></tr></table>
</td></tr></table>
</td></tr></table>
""";
}

View File

@@ -0,0 +1,369 @@
#NEWLAYER: generator/mintchoc
layerinfo "type" = "theme";
layerinfo "name" = "Mint Chocolate Chip";
layerinfo "redist_uniq" = "generator/mintchoc";
layerinfo "author_name" = "Andrea Hartmann";
layerinfo "author_email" = "mullenkamp@livejournal.com";
set entry_back = "#ddffee";
set entry_text = "#330000";
set page_link = "#993333";
set page_vlink = "#663333";
set page_alink = "#000000";
set page_back = "#ccffdd";
set stronger_back = "#663333";
set stronger_text = "#ccffdd";
set weak_back = "#88ffdd";
set weak_text = "#663333";
set comment_bar_one_bgcolor = "#88ffdd";
set comment_bar_one_fgcolor = "#663333";
set comment_bar_two_fgcolor = "#663333";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: generator/purple
layerinfo "type" = "theme";
layerinfo "name" = "Purple";
layerinfo "redist_uniq" = "generator/purple";
layerinfo "author_name" = "Andrea Hartmann";
layerinfo "author_email" = "mullenkamp@livejournal.com";
set entry_back = "#9933cc";
set entry_text = "#ddccff";
set page_link = "#ffffff";
set page_vlink = "#330033";
set page_alink = "#ffccff";
set page_back = "#bb55ee";
set stronger_back = "#660099";
set stronger_text = "#f5eeff";
set weak_back = "#bb88dd";
set weak_text = "#ddccff";
set comment_bar_one_bgcolor = "#660099";
set comment_bar_one_fgcolor = "#f5eeff";
set comment_bar_two_bgcolor = "#bb88dd";
set comment_bar_two_fgcolor = "#ddccff";
#NEWLAYER: generator/ocean
layerinfo "type" = "theme";
layerinfo "name" = "Deep Blue Xenogears Ocean";
layerinfo "redist_uniq" = "generator/ocean";
layerinfo "author_name" = "Andrea Hartmann";
layerinfo "author_email" = "mullenkamp@livejournal.com";
set entry_back = "#1100dd";
set entry_text = "#ccccff";
set page_link = "#ffffff";
set page_vlink = "#ddddff";
set page_alink = "#ffffff";
set page_back = "#3333ff";
set stronger_back = "#aabbff";
set stronger_text = "#0033cc";
set weak_back = "#3399ff";
set weak_text = "#0033cc";
set comment_bar_one_bgcolor = "#aabbff";
set comment_bar_one_fgcolor = "#0033cc";
set comment_bar_two_bgcolor = "#3399ff";
set comment_bar_two_fgcolor = "#0033cc";
#NEWLAYER: generator/harvest
layerinfo "type" = "theme";
layerinfo "name" = "Harvest";
layerinfo "redist_uniq" = "generator/harvest";
layerinfo "author_name" = "Andrea Hartmann";
layerinfo "author_email" = "mullenkamp@livejournal.com";
set entry_back = "#ff9900";
set entry_text = "#663333";
set page_link = "#ffeeaa";
set page_vlink = "#993300";
set page_alink = "#ffcc88";
set page_back = "#ffaa11";
set stronger_back = "#ffcc33";
set stronger_text = "#663333";
set weak_back = "#cc6600";
set weak_text = "#ffcc88";
set comment_bar_one_bgcolor = "#ffcc33";
set comment_bar_one_fgcolor = "#663333";
set comment_bar_two_bgcolor = "#cc6600";
set comment_bar_two_fgcolor = "#ffcc88";
#NEWLAYER: generator/jeweled
layerinfo "type" = "theme";
layerinfo "name" = "Jeweled";
layerinfo "redist_uniq" = "generator/jeweled";
layerinfo "author_name" = "Andrea Hartmann";
layerinfo "author_email" = "mullenkamp@livejournal.com";
set entry_back = "#aa6699";
set entry_text = "#330066";
set page_link = "#ccddee";
set page_vlink = "#cc99cc";
set page_alink = "#cceecc";
set page_back = "#881188";
set stronger_back = "#006699";
set stronger_text = "#ceecc";
set weak_back = "#008888";
set weak_text = "#002222";
set comment_bar_one_bgcolor = "#006699";
set comment_bar_one_fgcolor = "#ceecc";
set comment_bar_two_bgcolor = "#008888";
set comment_bar_two_fgcolor = "#002222";
#NEWLAYER: generator/darkgreens
layerinfo type = "theme";
layerinfo name = "Dark Greens";
layerinfo redist_uniq = "generator/darkgreens";
layerinfo author_name = "Ryan Fitzpatrick";
set entry_back = "#020202";
set entry_text = "#fbfbfb";
set page_link = "#9aff8d";
set page_vlink = "#e3ee39";
set page_alink = "#ff0220";
set page_back = "#117218";
set stronger_back = "#38e616";
set stronger_text = "#020100";
set weak_back = "#020100";
set weak_text = "#000000";
set comment_bar_one_bgcolor = "#38e616";
set comment_bar_one_fgcolor = "#020100";
set comment_bar_two_bgcolor = "#117218";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: generator/satin
layerinfo type = theme;
layerinfo name = "Satin Handshake";
layerinfo redist_uniq = "generator/satin";
set entry_back = "#d06464";
set entry_text = "#000000";
set page_link = "#ffffff";
set page_vlink = "#6f2222";
set page_alink = "#333333";
set page_back = "#480c0c";
set stronger_back = "#9d0404";
set stronger_text = "#ffffff";
set weak_back = "#d06464";
set weak_text = "#ffffff";
set comment_bar_one_bgcolor = "#9d0404";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#d06464";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: generator/sunset
layerinfo type = theme;
layerinfo name = "Sunset";
layerinfo redist_uniq = "generator/sunset";
set entry_back = "#ff7301";
set entry_text = "#fdb54f";
set page_link = "#ffe65e";
set page_vlink = "#ff9879";
set page_alink = "#ffb866";
set page_back = "#070494";
set stronger_back = "#f8a402";
set stronger_text = "#ffd510";
set weak_back = "#f51700";
set weak_text = "#f77603";
set comment_bar_one_bgcolor = "#f8a402";
set comment_bar_one_fgcolor = "#ffd510";
set comment_bar_two_bgcolor = "#f51700";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: generator/redbliss
layerinfo type = theme;
layerinfo name = "Red Bliss";
layerinfo redist_uniq = "generator/redbliss";
set entry_back = "#ffcccc";
set entry_text = "#000000";
set page_link = "#ffffff";
set page_vlink = "#ffcccc";
set page_alink = "#00ffff";
set page_back = "#ff3300";
set stronger_back = "#cc3333";
set stronger_text = "#ffffff";
set weak_back = "#cc3333";
set weak_text = "#fafafa";
set comment_bar_one_bgcolor = "#cc3333";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#ff3333";
set comment_bar_two_fgcolor = "#fafafa";
#NEWLAYER: generator/pastelneons
layerinfo type = theme;
layerinfo name = "Pastel Neons";
layerinfo redist_uniq = "generator/pastelneons";
set entry_back = "#ffffff";
set entry_text = "#1a6b6a";
set page_link = "#330f42";
set page_vlink = "#033339";
set page_alink = "#9923ca";
set page_back = "#00ffff";
set stronger_back = "#60d2cb";
set stronger_text = "#000000";
set weak_back = "#d385f3";
set weak_text = "#000000";
set comment_bar_one_bgcolor = "#60d2cb";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#d385f3";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: generator/classdesk
layerinfo type = "theme";
layerinfo name = "Classic Desktop";
layerinfo redist_uniq = "generator/classdesk";
set page_link = "#ff7b05";
set page_vlink = "#ce4900";
set page_alink = "#ff9e2b";
set page_back = "#007782";
set stronger_back = "#00545c";
set stronger_text = "#ffffff";
set weak_back = "#ffeddd";
set weak_text = "#ffffff";
set comment_bar_one_bgcolor = "#00545c";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#ffeddd";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: generator/everwhite
layerinfo type = theme;
layerinfo name = "Everwhite";
layerinfo redist_uniq = "generator/everwhite";
set entry_back = "#ffffff";
set entry_text = "#000000";
set page_link = "#ff0000";
set page_vlink = "#ff0000";
set page_alink = "#ffffff";
set page_back = "#ffffff";
set stronger_back = "#ffffff";
set stronger_text = "#ff0000";
set weak_back = "#ffffff";
set weak_text = "#ffffff";
set comment_bar_one_bgcolor = "#dddddd";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#aaaaaa";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: generator/everblue
layerinfo type = theme;
layerinfo name = "Everblue with Grey";
layerinfo redist_uniq = "generator/everblue";
set entry_back = "#ffffff";
set entry_text = "#000000";
set page_link = "#0000ff";
set page_vlink = "#060667";
set page_alink = "#ffffff";
set page_back = "#0f0c6d";
set stronger_back = "#000000";
set stronger_text = "#ffffff";
set weak_back = "#aaaaaa";
set weak_text = "#000000";
set comment_bar_one_bgcolor = "#000000";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#aaaaaa";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: generator/purplesky
layerinfo type = theme;
layerinfo name = "Purple Sky";
layerinfo redist_uniq = "generator/purplesky";
set entry_back = "#24d8df";
set entry_text = "#0424e4";
set page_link = "#a917c4";
set page_vlink = "#9911e8";
set page_alink = "#ea09ff";
set page_back = "#99e3e2";
set stronger_back = "#8802fa";
set stronger_text = "#ffffff";
set weak_back = "#89e5e9";
set weak_text = "#000000";
set comment_bar_one_bgcolor = "#8802fa";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#89e5e9";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: generator/bruise
layerinfo type = theme;
layerinfo name = "Bruise";
layerinfo redist_uniq = "generator/bruise";
set entry_back = "#bcbcbc";
set entry_text = "#000000";
set page_link = "#0000ff";
set page_vlink = "#0000ff";
set page_alink = "#0000ff";
set page_back = "#000000";
set stronger_back = "#1114a0";
set stronger_text = "#ffffff";
set weak_back = "#21c2f1";
set weak_text = "#000000";
set comment_bar_one_bgcolor = "#1114a0";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#21c2f1";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: generator/elegant
layerinfo type = theme;
layerinfo name = "Elegant";
layerinfo redist_uniq = "generator/elegant";
set entry_back = "#ffffff";
set entry_text = "#000000";
set page_link = "#e91822";
set page_vlink = "#bf1418";
set page_alink = "#f71e28";
set page_back = "#ffffff";
set stronger_back = "#777777";
set stronger_text = "#000000";
set weak_back = "#e6e6e6";
set weak_text = "#000000";
set comment_bar_one_bgcolor = "#777777";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#e6e6e6";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: generator/bananapeel
layerinfo type = theme;
layerinfo name = "Banana Peel";
layerinfo redist_uniq = "generator/bananapeel";
set entry_back = "#f2f688";
set entry_text = "#ee2914";
set page_link = "#db9129";
set page_vlink = "#c58f1b";
set page_alink = "#ffc518";
set page_back = "#ffffff";
set stronger_back = "#f0f905";
set stronger_text = "#000000";
set weak_back = "#dcdf02";
set weak_text = "#000000";
set comment_bar_one_bgcolor = "#f0f905";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#dcdf02";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: generator/melodrama
layerinfo type = theme;
layerinfo name = "Deep MeloDrama";
layerinfo redist_uniq = "generator/melodrama";
set entry_back = "#719cff";
set entry_text = "#9348a1";
set page_link = "#f5d3ff";
set page_vlink = "#e2ffe3";
set page_alink = "#e2ffe3";
set page_back = "#872d89";
set stronger_back = "#3794b3";
set stronger_text = "#a4b8ff";
set weak_back = "#65b2c1";
set weak_text = "#98bac5";
set comment_bar_one_bgcolor = "#3794b3";
set comment_bar_one_fgcolor = "#a4b8ff";
set comment_bar_two_bgcolor = "#65b2c1";
set comment_bar_two_fgcolor = "#872d89";
#NEWLAYER: generator/iceburg
layerinfo type = theme;
layerinfo name = "Iceburg";
layerinfo redist_uniq = "generator/iceburg";
set entry_back = "#ffffff";
set entry_text = "#000000";
set page_link = "#0000ff";
set page_vlink = "#0000ff";
set page_alink = "#387bf7";
set page_back = "#c6c2f5";
set stronger_back = "#7c6ccd";
set stronger_text = "#ffffff";
set weak_back = "#eef0fd";
set weak_text = "#000000";
set comment_bar_one_bgcolor = "#7c6ccd";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#eef0fd";
set comment_bar_two_fgcolor = "#000000";

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,392 @@
#NEWLAYER: haven/bluemonochromatic
layerinfo "type" = "theme";
layerinfo "name" = "Adaywien";
layerinfo "redist_uniq" = "haven/bluemonochromatic";
set color_scheme_base = "#1575C7";
set color_scheme = "monochromatic";
#NEWLAYER: haven/blueanalogous
layerinfo "type" = "theme";
layerinfo "name" = "Gwirasien";
layerinfo "redist_uniq" = "haven/blueanalogous";
set color_scheme_base = "#1575C7";
set color_scheme = "analogous";
#NEWLAYER: haven/bluecomplementary
layerinfo "type" = "theme";
layerinfo "name" = "Etaella";
layerinfo "redist_uniq" = "haven/bluecomplementary";
set color_scheme_base = "#1575C7";
set color_scheme = "complementary";
#NEWLAYER: haven/bluesplit_complementary
layerinfo "type" = "theme";
layerinfo "name" = "Sevaeviel";
layerinfo "redist_uniq" = "haven/bluesplit_complementary";
set color_scheme_base = "#1575C7";
set color_scheme = "split_complementary";
#NEWLAYER: haven/bluedouble_complementary
layerinfo "type" = "theme";
layerinfo "name" = "Glirewen";
layerinfo "redist_uniq" = "haven/bluedouble_complementary";
set color_scheme_base = "#1575C7";
set color_scheme = "double_complementary";
#NEWLAYER: haven/bluetriadic
layerinfo "type" = "theme";
layerinfo "name" = "Uloewiel";
layerinfo "redist_uniq" = "haven/bluetriadic";
set color_scheme_base = "#1575C7";
set color_scheme = "triadic";
#NEWLAYER: haven/bluetetradic
layerinfo "type" = "theme";
layerinfo "name" = "Yberawen";
layerinfo "redist_uniq" = "haven/bluetetradic";
set color_scheme_base = "#1575C7";
set color_scheme = "tetradic";
#NEWLAYER: haven/orangemonochromatic
layerinfo "type" = "theme";
layerinfo "name" = "Olerassa";
layerinfo "redist_uniq" = "haven/orangemonochromatic";
set color_scheme_base = "#F3904E";
set color_scheme = "monochromatic";
#NEWLAYER: haven/orangeanalogous
layerinfo "type" = "theme";
layerinfo "name" = "Vardothiel";
layerinfo "redist_uniq" = "haven/orangeanalogous";
set color_scheme_base = "#F3904E";
set color_scheme = "analogous";
#NEWLAYER: haven/orangecomplementary
layerinfo "type" = "theme";
layerinfo "name" = "Cadelaviel";
layerinfo "redist_uniq" = "haven/orangecomplementary";
set color_scheme_base = "#F3904E";
set color_scheme = "complementary";
#NEWLAYER: haven/orangesplit_complementary
layerinfo "type" = "theme";
layerinfo "name" = "Eriralle";
layerinfo "redist_uniq" = "haven/orangesplit_complementary";
set color_scheme_base = "#F3904E";
set color_scheme = "split_complementary";
#NEWLAYER: haven/orangedouble_complementary
layerinfo "type" = "theme";
layerinfo "name" = "Bemeth";
layerinfo "redist_uniq" = "haven/orangedouble_complementary";
set color_scheme_base = "#F3904E";
set color_scheme = "double_complementary";
#NEWLAYER: haven/orangetriadic
layerinfo "type" = "theme";
layerinfo "name" = "Welamma";
layerinfo "redist_uniq" = "haven/orangetriadic";
set color_scheme_base = "#F3904E";
set color_scheme = "triadic";
#NEWLAYER: haven/orangetetradic
layerinfo "type" = "theme";
layerinfo "name" = "Jerodia";
layerinfo "redist_uniq" = "haven/orangetetradic";
set color_scheme_base = "#F3904E";
set color_scheme = "tetradic";
#NEWLAYER: haven/greenmonochromatic
layerinfo "type" = "theme";
layerinfo "name" = "Cendarien";
layerinfo "redist_uniq" = "haven/greenmonochromatic";
set color_scheme_base = "#48C754";
set color_scheme = "monochromatic";
#NEWLAYER: haven/greenanalogous
layerinfo "type" = "theme";
layerinfo "name" = "Wicarede";
layerinfo "redist_uniq" = "haven/greenanalogous";
set color_scheme_base = "#48C754";
set color_scheme = "analogous";
#NEWLAYER: haven/greencomplementary
layerinfo "type" = "theme";
layerinfo "name" = "Laylla";
layerinfo "redist_uniq" = "haven/greencomplementary";
set color_scheme_base = "#48C754";
set color_scheme = "complementary";
#NEWLAYER: haven/greensplit_complementary
layerinfo "type" = "theme";
layerinfo "name" = "Dwiama";
layerinfo "redist_uniq" = "haven/greensplit_complementary";
set color_scheme_base = "#48C754";
set color_scheme = "split_complementary";
#NEWLAYER: haven/greendouble_complementary
layerinfo "type" = "theme";
layerinfo "name" = "Missi";
layerinfo "redist_uniq" = "haven/greendouble_complementary";
set color_scheme_base = "#48C754";
set color_scheme = "double_complementary";
#NEWLAYER: haven/greentriadic
layerinfo "type" = "theme";
layerinfo "name" = "Gwuwien";
layerinfo "redist_uniq" = "haven/greentriadic";
set color_scheme_base = "#48C754";
set color_scheme = "triadic";
#NEWLAYER: haven/greentetradic
layerinfo "type" = "theme";
layerinfo "name" = "Gerrathien";
layerinfo "redist_uniq" = "haven/greentetradic";
set color_scheme_base = "#48C754";
set color_scheme = "tetradic";
#NEWLAYER: haven/violetmonochromatic
layerinfo "type" = "theme";
layerinfo "name" = "Erudith";
layerinfo "redist_uniq" = "haven/violetmonochromatic";
set color_scheme_base = "#9D1EC7";
set color_scheme = "monochromatic";
#NEWLAYER: haven/violetanalogous
layerinfo "type" = "theme";
layerinfo "name" = "Narwen";
layerinfo "redist_uniq" = "haven/violetanalogous";
set color_scheme_base = "#9D1EC7";
set color_scheme = "analogous";
#NEWLAYER: haven/violetcomplementary
layerinfo "type" = "theme";
layerinfo "name" = "Yballan";
layerinfo "redist_uniq" = "haven/violetcomplementary";
set color_scheme_base = "#9D1EC7";
set color_scheme = "complementary";
#NEWLAYER: haven/violetsplit_complementary
layerinfo "type" = "theme";
layerinfo "name" = "Araymwen";
layerinfo "redist_uniq" = "haven/violetsplit_complementary";
set color_scheme_base = "#9D1EC7";
set color_scheme = "split_complementary";
#NEWLAYER: haven/violetdouble_complementary
layerinfo "type" = "theme";
layerinfo "name" = "Cydia";
layerinfo "redist_uniq" = "haven/violetdouble_complementary";
set color_scheme_base = "#9D1EC7";
set color_scheme = "double_complementary";
#NEWLAYER: haven/violettriadic
layerinfo "type" = "theme";
layerinfo "name" = "Eowiresa";
layerinfo "redist_uniq" = "haven/violettriadic";
set color_scheme_base = "#9D1EC7";
set color_scheme = "triadic";
#NEWLAYER: haven/violettetradic
layerinfo "type" = "theme";
layerinfo "name" = "Waedith";
layerinfo "redist_uniq" = "haven/violettetradic";
set color_scheme_base = "#9D1EC7";
set color_scheme = "tetradic";
#NEWLAYER: haven/yellowmonochromatic
layerinfo "type" = "theme";
layerinfo "name" = "Vauwen";
layerinfo "redist_uniq" = "haven/yellowmonochromatic";
set color_scheme_base = "#F3EAA0";
set color_scheme = "monochromatic";
#NEWLAYER: haven/yellowanalogous
layerinfo "type" = "theme";
layerinfo "name" = "Praressi";
layerinfo "redist_uniq" = "haven/yellowanalogous";
set color_scheme_base = "#F3EAA0";
set color_scheme = "analogous";
#NEWLAYER: haven/yellowcomplementary
layerinfo "type" = "theme";
layerinfo "name" = "Lelivia";
layerinfo "redist_uniq" = "haven/yellowcomplementary";
set color_scheme_base = "#F3EAA0";
set color_scheme = "complementary";
#NEWLAYER: haven/yellowsplit_complementary
layerinfo "type" = "theme";
layerinfo "name" = "Afalewen";
layerinfo "redist_uniq" = "haven/yellowsplit_complementary";
set color_scheme_base = "#F3EAA0";
set color_scheme = "split_complementary";
#NEWLAYER: haven/yellowdouble_complementary
layerinfo "type" = "theme";
layerinfo "name" = "Umoenna";
layerinfo "redist_uniq" = "haven/yellowdouble_complementary";
set color_scheme_base = "#F3EAA0";
set color_scheme = "double_complementary";
#NEWLAYER: haven/yellowtriadic
layerinfo "type" = "theme";
layerinfo "name" = "Trirwen";
layerinfo "redist_uniq" = "haven/yellowtriadic";
set color_scheme_base = "#F3EAA0";
set color_scheme = "triadic";
#NEWLAYER: haven/yellowtetradic
layerinfo "type" = "theme";
layerinfo "name" = "Jerilisien";
layerinfo "redist_uniq" = "haven/yellowtetradic";
set color_scheme_base = "#F3EAA0";
set color_scheme = "tetradic";
#NEWLAYER: haven/redmonochromatic
layerinfo "type" = "theme";
layerinfo "name" = "Ethowiel";
layerinfo "redist_uniq" = "haven/redmonochromatic";
set color_scheme_base = "#F35951";
set color_scheme = "monochromatic";
#NEWLAYER: haven/redanalogous
layerinfo "type" = "theme";
layerinfo "name" = "Dwyweth";
layerinfo "redist_uniq" = "haven/redanalogous";
set color_scheme_base = "#F35951";
set color_scheme = "analogous";
#NEWLAYER: haven/redcomplementary
layerinfo "type" = "theme";
layerinfo "name" = "Bylind";
layerinfo "redist_uniq" = "haven/redcomplementary";
set color_scheme_base = "#F35951";
set color_scheme = "complementary";
#NEWLAYER: haven/redsplit_complementary
layerinfo "type" = "theme";
layerinfo "name" = "Qiradia";
layerinfo "redist_uniq" = "haven/redsplit_complementary";
set color_scheme_base = "#F35951";
set color_scheme = "split_complementary";
#NEWLAYER: haven/reddouble_complementary
layerinfo "type" = "theme";
layerinfo "name" = "Kairawen";
layerinfo "redist_uniq" = "haven/reddouble_complementary";
set color_scheme_base = "#F35951";
set color_scheme = "double_complementary";
#NEWLAYER: haven/redtriadic
layerinfo "type" = "theme";
layerinfo "name" = "Piliwien";
layerinfo "redist_uniq" = "haven/redtriadic";
set color_scheme_base = "#F35951";
set color_scheme = "triadic";
#NEWLAYER: haven/redtetradic
layerinfo "type" = "theme";
layerinfo "name" = "Gwiradia";
layerinfo "redist_uniq" = "haven/redtetradic";
set color_scheme_base = "#F35951";
set color_scheme = "tetradic";
#NEWLAYER: haven/indigomonochromatic
layerinfo "type" = "theme";
layerinfo "name" = "Elirethiel";
layerinfo "redist_uniq" = "haven/indigomonochromatic";
set color_scheme_base = "#6F60C7";
set color_scheme = "monochromatic";
#NEWLAYER: haven/indigoanalogous
layerinfo "type" = "theme";
layerinfo "name" = "Oneawia";
layerinfo "redist_uniq" = "haven/indigoanalogous";
set color_scheme_base = "#6F60C7";
set color_scheme = "analogous";
#NEWLAYER: haven/indigocomplementary
layerinfo "type" = "theme";
layerinfo "name" = "Gwicia";
layerinfo "redist_uniq" = "haven/indigocomplementary";
set color_scheme_base = "#6F60C7";
set color_scheme = "complementary";
#NEWLAYER: haven/indigosplit_complementary
layerinfo "type" = "theme";
layerinfo "name" = "Grabeth";
layerinfo "redist_uniq" = "haven/indigosplit_complementary";
set color_scheme_base = "#6F60C7";
set color_scheme = "split_complementary";
#NEWLAYER: haven/indigodouble_complementary
layerinfo "type" = "theme";
layerinfo "name" = "Alalicien";
layerinfo "redist_uniq" = "haven/indigodouble_complementary";
set color_scheme_base = "#6F60C7";
set color_scheme = "double_complementary";
#NEWLAYER: haven/indigotriadic
layerinfo "type" = "theme";
layerinfo "name" = "Legeinia";
layerinfo "redist_uniq" = "haven/indigotriadic";
set color_scheme_base = "#6F60C7";
set color_scheme = "triadic";
#NEWLAYER: haven/indigotetradic
layerinfo "type" = "theme";
layerinfo "name" = "Olowen";
layerinfo "redist_uniq" = "haven/indigotetradic";
set color_scheme_base = "#6F60C7";
set color_scheme = "tetradic";

View File

@@ -0,0 +1,161 @@
#-*-s2-*- ;; -*- coding: utf-8 -*-
layerinfo "type" = "i18nc";
layerinfo "redist_uniq" = "i18nc/da1";
layerinfo "name" = "Danish";
layerinfo "langcode" = "da";
layerinfo "author_name" = "LiveJournal Danish Translation Team";
layerinfo "author_email" = "lj_dansk@livejournal.com";
layerinfo "source_viewable" = 1;
set lang_current = "da";
#[[ date and time l12n ]]
# Kort datoformat
set lang_fmt_date_short = "%%d%%/%%m%%/%%yy%%";
# Mellem dato
set lang_fmt_date_med = "%%dayord%% %%mon%%., %%yyyy%%";
# Mellem dato med forkortet ugedag
set lang_fmt_date_med_day = "%%da%%, d. %%dayord%% %%mon%%., %%yyyy%%";
# Lang dato
set lang_fmt_date_long = "%%dayord%% %%month%%, %%yyyy%%";
# Lang dato med ugedag
set lang_fmt_date_long_day = "%%day%%, d. %%dayord%% %%month%%, %%yyyy%%";
# Tidsformat
set lang_fmt_time_short = "%%HH%%:%%min%%";
# Kort månedsformat (samme som engelsk)
set lang_fmt_month_short = "%%m%%/%%yy%%";
# Mellem måned (samme som engelsk)
set lang_fmt_month_med = "%%mon%% %%yyyy%%";
# Lang måned (samme som engelsk)
set lang_fmt_month_long = "%%month%% %%yyyy%%";
# Årets måneder, lang
set lang_monthname_long = [ "", "Januar", "Februar", "Marts",
"April", "Maj", "Juni",
"Juli", "August", "September",
"Oktober", "November", "December" ];
# Årets måneder, kort
set lang_monthname_short = [ "", "Jan", "Feb", "Mar",
"Apr", "Maj", "Jun",
"Jul", "Aug", "Sep",
"Okt", "Nov", "Dec" ];
# Ugens dage, lang
set lang_dayname_long = [ "", "Søndag", "Mandag", "Tirsdag", "Onsdag",
"Torsdag", "Fredag", "Lørdag" ];
# Ugens dage, kort
set lang_dayname_short = [ "", "Søn", "Man", "Tirs", "Ons",
"Tors", "Fre", "Lør" ];
set reg_firstdayofweek = "monday";
#[[ texttranslation ]]
# Currents
set text_meta_music = "Nuværende musik";
set text_meta_mood = "Nuværende humør";
# Comments
set text_post_comment = "Skriv kommentar";
set text_read_comments = "1 kommentar // # kommentarer";
set text_post_comment_friends = "Skriv kommentar";
set text_read_comments_friends = "1 kommentar // # kommentarer";
# Skiplinks
set text_skiplinks_back="Forrige #";
set text_skiplinks_forward="Næste #";
# Views
set text_view_recent = "Seneste poster";
set text_view_friends = "Venner";
set text_view_archive = "Arkiv";
set text_view_userinfo = "Brugerinfo";
set text_view_month = "Vis emner"; # "Vis overskrifter"?
# Misc. texts
set text_nosubject = "(intet emne)";
set text_noentries_recent = "Der er ingen poster at vise.";
set text_noentries_day = "Der blev ikke skrevet nogle poster denne dag.";
set text_permalink = "Link";
set text_month_screened_comments = "m. skærmede";
set text_multiform_check = "Vælg:";
set text_multiform_des = "Massehandling på valgte kommentarer:";
set text_multiform_btn = "Udfør handling";
set text_multiform_opt_unscreen = "Afskærm";
set text_multiform_opt_screen = "Skærm";
set text_multiform_opt_delete = "Slet";
set text_multiform_conf_delete = "Slet valgte kommentarer?";
set text_day_prev = "Forrige dag";
set text_day_next = "Næste dag";
set text_comment_from = "Fra:";
set text_comment_date = "Dato:";
set text_comment_ipaddr = "IP adresse:";
set text_comment_reply = "Svar";
set text_comment_parent = "Forælder";
set text_comment_thread = "Tråd";
set text_reply_back = "Læs kommentarer";
set text_reply_nocomments_header = "Kommentarer slået fra:";
set text_reply_nocomments = "Kommentarer til denne post er blevet slået fra.";
set text_poster_anonymous = "(Anonym)";
set text_website_default_name = "Mit websted";
#[[ function translations ]]
# Samme som engelsk:
#function lang_map_plural (int n) : int {
# if ($n == 1) { return 0; } # singular
# return 1; # plural
#}
function lang_page_of_pages (int pg, int pgs) [notags] : string {
return "Side $pg af $pgs";
}
function lang_ordinal(int num) [notags] : string {
return $num+".";
}
function lang_user_wrote(UserLite u) : string
"Returns text describing that the user wrote something. i18nc layers should override this."
{
if (defined $u) {
return $u->as_string()+" skrev";
}
else {
return "En anonym bruger skrev";
}
}
function lang_at_datetime(DateTime d) : string
"Returns a string saying \"at {the data and time given}\". Used in the core implementation of EntryPage and ReplyPage. i18nc layers should override this."
{
# return "d. 1. Januar, 2004, kl. 23:01";
return "d. " + $d->date_format("long") + ", kl. " + $d->time_format();
}
### Ovenstående skal testes i brug ASAP. ###
function lang_viewname(string viewid) [notags] : string
"Get some words representing a view"
{
if ($viewid == "recent") { return $*text_view_recent; }
if ($viewid == "archive") { return $*text_view_archive; }
if ($viewid == "friends") { return $*text_view_friends; }
if ($viewid == "day") { return "Dag"; }
if ($viewid == "month") { return "Måned"; }
if ($viewid == "userinfo") { return $*text_view_userinfo; }
if ($viewid == "entry") { return "Læs kommentarer"; }
if ($viewid == "reply") { return "Skriv kommentar"; }
return "Ukendt visningstype";
}
function server_sig() {
"""Kørt af <a href="$*SITEROOT/">$*SITENAME</a>""";
}
function ReplyPage::view_title() : string {
return "Skriv kommentar";
}
function Page::print_entry_poster(Entry e) {
$e.poster->print();
if ($.view == "friends" and $e.poster.username != $e.journal.username) {
" skrev i ";
$e.journal->print();
}
}

View File

@@ -0,0 +1,147 @@
#-*-s2-*- ;; -*- coding: utf-8 -*-
layerinfo "type" = "i18nc";
layerinfo "redist_uniq" = "i18nc/de1";
layerinfo "name" = "German";
layerinfo "langcode" = "de";
layerinfo "author_name" = "Timwi";
layerinfo "author_email" = "timwi@livejournal.com";
layerinfo "source_viewable" = 1;
set lang_current = "de";
# Kurzes Datumsformat
set lang_fmt_date_short = "%%d%%.%%m%%.%%yy%%";
# Mittellanges Datumsformat
set lang_fmt_date_med = "%%dayord%% %%mon%% %%yyyy%%";
# Mittellanges Datumsformat mit Wochentag
set lang_fmt_date_med_day = "%%da%%, %%dayord%% %%mon%% %%yyyy%%";
# Langes Datumsformat
set lang_fmt_date_long = "%%dayord%% %%month%% %%yyyy%%";
# Langes Datumsformat mit Wochentag
set lang_fmt_date_long_day = "%%day%%, %%dayord%% %%month%% %%yyyy%%";
# Zeitformat
set lang_fmt_time_short = "%%HH%%:%%min%%";
# Kurzes Monatsformat
#set lang_fmt_month_short = "%%mon%% %%yy%%";
# Mittleres Monatsformat
#set lang_fmt_month_med = "%%mon%% %%yyyy%%";
# Langes Monatsformat
#set lang_fmt_month_long = "%%month%% %%yyyy%%";
# Monatsnamen
set lang_monthname_long = [ "", "Januar", "Februar", "März",
"April", "Mai", "Juni",
"Juli", "August", "September",
"Oktober", "November", "Dezember" ];
# Monatsabkürzungen
set lang_monthname_short = [ "", "Jan", "Feb", "Mär",
"Apr", "Mai", "Jun",
"Jul", "Aug", "Sep",
"Okt", "Nov", "Dez" ];
# Wochentagnamen
set lang_dayname_long = [ "", "Sonntag", "Montag", "Dienstag", "Mittwoch",
"Donnerstag", "Freitag", "Samstag" ];
# Wochentagabkürzungen
set lang_dayname_short = [ "", "So", "Mo", "Di", "Mi",
"Do", "Fr", "Sa" ];
set reg_firstdayofweek = "monday";
#[[ texttranslation ]]
# Currents
set text_meta_music = "Aktuelle Musik";
set text_meta_mood = "Aktuelle Stimmung";
# Comments
set text_post_comment = "Kommentar hinterlassen";
set text_read_comments = "1 Kommentar // # Kommentare";
set text_post_comment_friends = "Kommentar hinterlassen";
set text_read_comments_friends = "1 Kommentar // # Kommentare";
# Skiplinks
set text_skiplinks_back="Vorherige #";
set text_skiplinks_forward="Nächste #";
# Views
set text_view_recent = "Neueste Einträge";
set text_view_friends = "Freunde";
set text_view_archive = "Archiv";
set text_view_userinfo = "Benutzerprofil";
set text_view_month = "Monatsansicht"; # "Vis overskrifter"?
# Misc. texts
set text_nosubject = "(kein Betreff)";
set text_noentries_recent = "Keine Einträge.";
set text_noentries_day = "An diesem Tag wurden keine Einträge gemacht.";
set text_permalink = "Link";
set text_month_screened_comments = "zzgl. verdeckte";
set text_multiform_check = "Auswählen:";
set text_multiform_des = "Alle ausgewählten Kommentare:";
set text_multiform_btn = "Ausführen";
set text_multiform_opt_unscreen = "Aufdecken";
set text_multiform_opt_screen = "Verdecken";
set text_multiform_opt_delete = "Löschen";
set text_multiform_conf_delete = "Bist du dir sicher, dass du die ausgewählten Kommentare löschen möchtest?";
set text_day_prev = "Vorheriger Tag";
set text_day_next = "Nächster Tag";
set text_comment_from = "Von:";
set text_comment_date = "Datum:";
set text_comment_ipaddr = "IP-Adresse:";
set text_comment_reply = "Darauf antworten";
set text_comment_parent = "Kommentar davor";
set text_comment_thread = "Nachfolgende Kommentare";
set text_reply_back = "Kommentare lesen";
set text_reply_nocomments_header = "Kommentarfunktion deaktiviert:";
set text_reply_nocomments = "Für diesen Eintrag wurde die Kommentarfunktion deaktiviert.";
set text_website_default_name = "Meine Webseite";
set text_poster_anonymous = "(Anonym)";
#[[ function translations ]]
function lang_page_of_pages (int pg, int pgs) [notags] : string {
return "Seite $pg von $pgs";
}
function lang_ordinal(int num) [notags] : string {
return $num+".";
}
function lang_viewname(string viewid) [notags] : string
"Get some words representing a view"
{
if ($viewid == "recent") { return $*text_view_recent; }
if ($viewid == "archive") { return $*text_view_archive; }
if ($viewid == "friends") { return $*text_view_friends; }
if ($viewid == "day") { return "Tag"; }
if ($viewid == "month") { return "Monat"; }
if ($viewid == "userinfo") { return $*text_view_userinfo; }
if ($viewid == "entry") { return "Kommentare lesen"; }
if ($viewid == "reply") { return "Kommentar hinterlassen"; }
return "Unbekannte Ansicht";
}
function ReplyPage::view_title() : string {
return "Kommentar hinterlassen";
}
function server_sig() {
"""Gehostet von <a href="$*SITEROOT/">$*SITENAME</a>""";
}
function Page::print_entry_poster(Entry e) {
$e.poster->print();
if ($.view == "friends" and $e.poster.username != $e.journal.username) {
" schrieb in ";
$e.journal->print();
}
}
function lang_user_wrote(UserLite u) : string "Returns text describing that the user wrote something. i18nc layers should override this." {
if (defined $u) {
return $u->as_string()+" schrieb";
}
else {
return "Ein anonymer Benutzer schrieb";
}
}
function lang_at_datetime(DateTime d) : string "Returns a string saying \"at {the date and time given}\". Used in the core implementation of EntryPage and ReplyPage. i18nc layers should override this." {
return "am " + $d->date_format("long") + " um " + $d->time_format();
}

View File

@@ -0,0 +1,9 @@
#-*-s2-*-
layerinfo "type" = "i18nc";
layerinfo "redist_uniq" = "i18nc/en1";
layerinfo "name" = "English";
layerinfo "langcode" = "en";
# Note: this file doesn't actually override anything, since the core
# is in English

View File

@@ -0,0 +1,139 @@
#-*-s2-*- ;; -*- coding: utf-8 -*-
layerinfo "type" = "i18nc";
layerinfo "redist_uniq" = "i18nc/eo1";
layerinfo "name" = "Esperanto";
layerinfo "langcode" = "eo";
layerinfo "author_name" = "Timwi, Amuzulo";
layerinfo "author_email" = "timwi@livejournal.com, amuzulo@livejournal.com";
layerinfo "source_viewable" = 1;
set lang_current = "eo";
set lang_fmt_date_short = "%%yyyy%%-%%mm%%-%%dd%%";
set lang_fmt_date_med = "%%dayord%% de %%mon%% %%yyyy%%";
set lang_fmt_date_med_day = "%%da%%, la %%dayord%% de %%mon%% %%yyyy%%";
set lang_fmt_date_long = "la %%dayord%% de %%month%% %%yyyy%%";
set lang_fmt_date_long_day = "%%day%%, la %%dayord%% de %%month%% %%yyyy%%";
set lang_fmt_time_short = "%%HH%%:%%min%%";
set lang_fmt_month_short = "%%mon%% %%yy%%";
set lang_fmt_month_med = "%%mon%% %%yyyy%%";
set lang_fmt_month_long = "%%month%% %%yyyy%%";
set lang_monthname_long = [ "", "januaro", "februaro", "marto",
"aprilo", "majo", "junio",
"julio", "aŭgusto", "septembro",
"oktobro", "novembro", "decembro" ];
set lang_monthname_short = [ "", "jan", "feb", "mar",
"apr", "maj", "jun",
"jul", "aŭg", "sep",
"okt", "nov", "dec" ];
set lang_dayname_long = [ "", "dimanĉo", "lundo", "mardo", "merkredo",
"ĵaŭdo", "vendredo", "sabato" ];
set lang_dayname_short = [ "", "di", "lu", "ma", "me",
"ĵa", "ve", "sa" ];
set reg_firstdayofweek = "monday";
#[[ texttranslation ]]
# Currents
set text_meta_music = "Nuna muziko";
set text_meta_mood = "Nuna humoro";
# Comments
set text_post_comment = "Afiŝu novan komenton";
set text_read_comments = "1 komento // # komentoj";
set text_post_comment_friends = "Afiŝu novan komenton";
set text_read_comments_friends = "1 komento // # komentoj";
# Skiplinks
set text_skiplinks_back="# antaŭaj komentoj";
set text_skiplinks_forward="# sekvontaj komentoj";
# Views
set text_view_recent = "Lastatempaj enskribojn";
set text_view_friends = "Geamikoj";
set text_view_archive = "Arĥivo";
set text_view_userinfo = "Uzantinformoj";
set text_view_month = "Monataj temoj";
# Misc. texts
set text_nosubject = "(neniu temo)";
set text_noentries_recent = "Neniuj enskriboj.";
set text_noentries_day = "Ekzistas neniuj enskriboj en tiu tago.";
set text_permalink = "Ligilo";
set text_month_screened_comments = "+ kaŝitoj";
set text_multiform_check = "Elektu:";
set text_multiform_des = "Amasagado por elektitaj komentoj:";
set text_multiform_btn = "Agu";
set text_multiform_opt_unscreen = "Malkaŝu";
set text_multiform_opt_screen = "Kaŝu";
set text_multiform_opt_delete = "Forigu";
set text_multiform_conf_delete = "Ĉu vi certas ke vi viŝas forigi la elektitajn komentojn?";
set text_day_prev = "Antaŭa tago";
set text_day_next = "Sekvonta tago";
set text_comment_from = "De:";
set text_comment_date = "Dato:";
set text_comment_ipaddr = "IP-adreso:";
set text_comment_reply = "Respondu al ĉi tiu";
set text_comment_parent = "Patro";
set text_comment_thread = "Fadeno";
set text_reply_back = "Legu komentojn";
set text_reply_nocomments_header = "Komentoj malebligitaj:";
set text_reply_nocomments = "La uzanto malebligis komentojn por ĉi tiu enskribo.";
set text_website_default_name = "Mia TTT-ejo";
set text_poster_anonymous = "(sennoma)";
#[[ function translations ]]
function lang_page_of_pages (int pg, int pgs) [notags] : string {
return "Paĝo $pg da $pgs";
}
function lang_ordinal(int num) [notags] : string {
return $num + "-a";
}
function lang_viewname(string viewid) [notags] : string
"Get some words representing a view"
{
if ($viewid == "recent") { return $*text_view_recent; }
if ($viewid == "archive") { return $*text_view_archive; }
if ($viewid == "friends") { return $*text_view_friends; }
if ($viewid == "day") { return "Tago"; }
if ($viewid == "month") { return "Monato"; }
if ($viewid == "userinfo") { return $*text_view_userinfo; }
if ($viewid == "entry") { return "Legu komentojn"; }
if ($viewid == "reply") { return "Afiŝu komenton"; }
return "Nekonata vido";
}
function ReplyPage::view_title() : string {
return "Afiŝu komenton";
}
function server_sig() {
"""Funkciigita de <a href="$*SITEROOT/">$*SITENAME</a>""";
}
function Page::print_entry_poster(Entry e) {
$e.poster->print();
if ($.view == "friends" and $e.poster.username != $e.journal.username) {
" skribis en ";
$e.journal->print();
}
}
function lang_user_wrote(UserLite u) : string "Returns text describing that the user wrote something. i18nc layers should override this." {
if (defined $u) {
return $u->as_string()+" skribis";
}
else {
return "Sennoma uzanto skribis";
}
}
function lang_at_datetime(DateTime d) : string "Returns a string saying \"at {the date and time given}\". Used in the core implementation of EntryPage and ReplyPage. i18nc layers should override this." {
return "je " + $d->date_format("long") + " je " + $d->time_format();
}

View File

@@ -0,0 +1,171 @@
#-*-s2-*- ;; -*- coding: utf-8 -*-
layerinfo "type" = "i18nc";
layerinfo "redist_uniq" = "i18nc/fi1";
layerinfo "name" = "Finnish";
layerinfo "langcode" = "fi";
layerinfo "author_name" = "shiningkianna, zell_d";
layerinfo "source_viewable" = 1;
set lang_current = "fi";
# Ajat ja päiväykset
# Viikonpäivät
set lang_dayname_long = [ "", "sunnuntai", "maanantai", "tiistai", "keskiviikko", "torstai", "perjantai", "lauantai" ];
set lang_dayname_short = [ "", "su", "ma", "ti", "ke", "to", "pe", "la" ];
# Pitkä päiväys
set lang_fmt_date_long = "%%dayord%% %%month%%ta %%yyyy%%";
# Pitkä päiväys viikonpäivällä
set lang_fmt_date_long_day = "%%day%%, %%dayord%% %%month%%ta %%yyyy%%";
# Keskipitkä päiväys
set lang_fmt_date_med = "%%d%%. %%mon%%. %%yyyy%%";
# Keskipitkä päiväys viikonpäivällä
set lang_fmt_date_med_day = "%%da%%, %%dayord%% %%mon%%. %%yyyy%%";
# Lyhyt päiväys
set lang_fmt_date_short = "%%d%%.%%m%%.%%yyyy%%";
# Pitkä kuukausipäiväys
set lang_fmt_month_long = "%%month%% %%yyyy%%";
# Keskipitkä kuukausipäiväys
set lang_fmt_month_med = "%%mon%% %%yyyy%%";
# Lyhyt kuukausipäiväys
set lang_fmt_month_short = "%%m%%/%%yyyy%%";
# Aika
set lang_fmt_time_short ="%%HH%%:%%min%%";
# Kuukaudet
set lang_monthname_long = [ "", "tammikuu", "helmikuu", "maaliskuu", "huhtikuu", "toukokuu", "kesäkuu", "heinäkuu", "elokuu", "syyskuu", "lokakuu", "marraskuu", "joulukuu" ];
set lang_monthname_short = [ "", "tammik", "helmik", "maalisk", "huhtik", "toukok", "kesäk", "heinäk", "elok", "syysk", "lokak", "marrask", "jouluk" ];
# Viikko alkaa maanantaista
set reg_firstdayofweek = "monday";
# Tekstit
# Tämänhetkinen musiikki ja mieliala
set text_meta_mood = "Mieliala";
set text_meta_music = "Musiikki";
# Kommentit
set text_post_comment = "Jätä vastaus tähän";
set text_post_comment_friends = "Jätä vastaus tähän";
set text_read_comments = "1 kommentti // # kommenttia";
set text_read_comments_friends = "1 kommentti // # kommenttia";
# Linkit, joilla hypätään viestien yli
set text_skiplinks_back = "Edelliset #";
set text_skiplinks_forward = "Seuraavat #";
# Näkymät
set text_view_archive = "Arkisto";
set text_view_friends = "Kaverit";
set text_view_friends_comm = "Jäsenet";
set text_view_friends_filter = "Kaverit (mukautettu suodatin)";
set text_view_friendsfriends = "Kavereiden kaverit";
set text_view_friendsfriends_filter = "Kavereiden kaverit (mukautettu suodatin)";
set text_view_month = "Otsikot";
set text_view_recent = "Merkinnät";
set text_view_userinfo = "Käyttäjätiedot";
# Sekalaisia tekstejä
set text_comment_date = "Päiväys:";
set text_comment_from = "Lähettäjä:";
set text_comment_frozen = "Jäädytetty";
set text_comment_ipaddr = "IP-osoite:";
set text_comment_parent = "Ylempi";
set text_comment_reply = "Vastaa";
set text_comment_thread = "Viestiketju";
set text_day_next = "Seuraava päivä";
set text_day_prev = "Edellinen päivä";
set text_max_comments = "Maksimimäärä kommentteja saatu";
set text_month_screened_comments = "ja peitettyjä kommentteja";
set text_multiform_btn = "Muokkaa";
set text_multiform_check = "Valitse:";
set text_multiform_conf_delete = "Poista valitut kommentit?";
set text_multiform_des = "Muokkaa kaikkia valittuja kommentteja:";
set text_multiform_opt_delete = "Poista";
set text_multiform_opt_freeze = "Jäädytä";
set text_multiform_opt_screen = "Peitä";
set text_multiform_opt_unfreeze = "Poista jäädytys";
set text_multiform_opt_unscreen = "Poista peitto";
set text_noentries_day = "Kyseisenä päivänä ei tehty merkintöjä";
set text_noentries_recent = "Ei merkintöjä";
set text_nosubject = "(ei otsikkoa)";
set text_permalink = "Linkki";
set text_poster_anonymous = "(tuntematon)";
set text_reply_back = "Lue kommentteja";
set text_reply_nocomments = "Kommentointi on estetty tämän merkinnän kohdalla";
set text_reply_nocomments_header = "Kommentointi estetty:";
set text_website_default_name = "Kotisivut";
# Funktiot
# Antaa eri tuloksen riippuen siitä tuleeko tekstiä käsitellä yksikkönä vai monikkona
function lang_map_plural (int n) : int {
if ($n == 1) { return 0; } # singular
return 1; # plural
}
# Palauttaa tekstin "Sivu X/Y", esim. Sivu 3/5
function lang_page_of_pages (int pg, int pgs) [notags] : string {
return "Sivu $pg/$pgs";
}
# Tekee numerosta järjestysnumeron, eli laittaa numeron perään pisteen
function lang_ordinal(int num) : string {
return $num+".";
}
# Palauttaa tekstin joka kertoo millainen näkymä on kyseessä
function lang_viewname(string viewid) [notags] : string "Get some words representing a view" {
if ($viewid == "recent") { return $*text_view_recent; }
if ($viewid == "archive") { return $*text_view_archive; }
if ($viewid == "friends") { return $*text_view_friends; }
if ($viewid == "day") { return "Päivä"; }
if ($viewid == "month") { return "Kuukausi"; }
if ($viewid == "userinfo") { return $*text_view_userinfo; }
if ($viewid == "entry") { return "Lue kommentteja"; }
if ($viewid == "reply") { return "Jätä kommentti"; }
return "Tuntematon näkymä";
}
# Vastaussivun otsikko
function ReplyPage::view_title() : string {
return "Jätä kommentti";
}
# Kirjoittaa palvelimen allekirjoituksen,
# Esim. "Sivun tarjoaa LiveJournal.com"
function server_sig() {
"""Sivun tarjoaa <a href="$*SITEROOT/">$*SITENAME</a>""";
}
# Kirjoittaa kaverisivulla tekstin, joka kertoo missä yhteisössä joku kirjoitti jotakin,
# Esim. "Esimerkkilähettäjä kirjoitti yhteisössä esimerkkiyhteisö"
function Page::print_entry_poster(Entry e) {
$e.poster->print();
if ($.view == "friends" and $e.poster.username != $e.journal.username) {
" kirjoitti yhteisössä ";
$e.journal->print();
}
}
# Palauttaa tekstin joka kertoo että joku kirjoitti,
# Esim. "Esimerkkikäyttäjä kirjoitti" tai "Tuntematon käyttäjä kirjoitti"
function lang_user_wrote(UserLite u) : string "Returns text describing that the user wrote something. i18nc layers should override this." {
if (defined $u) {
return $u->as_string()+" kirjoitti";
}
else {
return "Tuntematon käyttäjä kirjoitti";
}
}
# Palauttaa tekstin joka ilmoittaa päiväyksen ja kellonajan,
# Esim. "3. lokakuuta 2004 kello 14:45"
function lang_at_datetime(DateTime d) : string "Returns a string saying \"at {the date and time given}\". Used in the core implementation of EntryPage and ReplyPage. i18nc layers should override this." {
return $d->date_format("long") + " kello " + $d->time_format();
}

View File

@@ -0,0 +1,144 @@
#-*-s2-*- ;; -*- coding: utf-8 -*-
layerinfo "type" = "i18nc";
layerinfo "redist_uniq" = "i18nc/fr1";
layerinfo "name" = "French";
layerinfo "langcode" = "fr";
layerinfo "author_name" = "Timwi, Diziet Sma, Eclips1st";
layerinfo "author_email" = "timwi@livejournal.com, dizietsma@livejournal.com, eclips1st@livejournal.com";
layerinfo "source_viewable" = 1;
set lang_current = "fr";
set lang_fmt_date_short = "%%d%% %%mon%% %%yy%%";
set lang_fmt_date_med = "%%dd%% %%mon%% %%yyyy%%";
set lang_fmt_date_med_day = "%%da%%, le %%dd%% %%mon%% %%yyyy%%";
set lang_fmt_date_long = "le %%dd%% %%month%% %%yyyy%%";
set lang_fmt_date_long_day = "%%day%%, le %%dd%% %%month%% %%yyyy%%";
set lang_fmt_time_short = "%%HH%%:%%min%%";
set lang_fmt_month_short = "%%mon%% %%yy%%";
set lang_fmt_month_med = "%%mon%% %%yyyy%%";
set lang_fmt_month_long = "%%month%% %%yyyy%%";
set lang_monthname_long = [ "", "janvier", "février", "mars",
"avril", "mai", "juin",
"juillet", "août", "septembre",
"octobre", "novembre", "décembre" ];
set lang_monthname_short = [ "", "jan", "fév", "mar",
"avr", "mai", "juin",
"juil", "aoû", "sep",
"oct", "nov", "déc" ];
set lang_dayname_long = [ "", "dimanche", "lundi", "mardi", "mercredi",
"jeudi", "vendredi", "samedi" ];
set lang_dayname_short = [ "", "dim", "lun", "mar", "mer",
"jeu", "ven", "sam" ];
set reg_firstdayofweek = "monday";
#[[ texttranslation ]]
# Currents
set text_meta_music = "Musique actuelle";
set text_meta_mood = "Humeur actuelle";
# Comments
set text_post_comment = "Envoyez un commentaire";
set text_read_comments = "1 commentaire // # commentaires";
set text_post_comment_friends = "Envoyez un commentaire";
set text_read_comments_friends = "1 commentaire // # commentaires";
# Skiplinks
set text_skiplinks_back="# entrées précédentes";
set text_skiplinks_forward="# entrées suivantes";
# Views
set text_view_recent = "Entrées récentes";
set text_view_friends = "Amis";
set text_view_archive = "Archives";
set text_view_userinfo = "Profil";
set text_view_month = "Sujets du mois";
# Misc. texts
set text_nosubject = "(pas de sujets)";
set text_noentries_recent = "Pas d'entrées.";
set text_noentries_day = "Il n'y a aucune entrée cette journée.";
set text_permalink = "Lien";
set text_month_screened_comments = "+ filtrée(s)";
set text_multiform_check = "Cocher&nbsp;:";
set text_multiform_des = "Modifier les commentaires cochés&nbsp;:";
set text_multiform_btn = "Modifier";
set text_multiform_opt_unscreen = "Rendre public";
set text_multiform_opt_screen = "Filtrer";
set text_multiform_opt_delete = "Effacer";
set text_multiform_conf_delete = "Êtes-vous sûr de vouloir supprimer les commentaires sélectionnés?";
set text_day_prev = "Journée précédente";
set text_day_next = "Journée suivante";
set text_comment_from = "De&nbsp;:";
set text_comment_date = "Date&nbsp;:";
set text_comment_ipaddr = "Adresse IP&nbsp;:";
set text_comment_reply = "Répondre";
set text_comment_parent = "Précédent";
set text_comment_thread = "Fil";
set text_reply_back = "Lire les commentaires";
set text_reply_nocomments_header = "Commentaires désactivés&nbsp;:";
set text_reply_nocomments = "L'utilisateur a désactivé les commentaires pour cette entrée.";
set text_website_default_name = "Mon site";
set text_poster_anonymous = "(anonyme)";
#[[ function translations ]]
function lang_page_of_pages (int pg, int pgs) [notags] : string {
return "Page $pg de $pgs";
}
function lang_ordinal(int num) [notags] : string {
if ($num == 1) { return $num+"er"; }
return $num+"e";
}
function lang_map_plural (int n) : int {
if ($n > 1) { return 1; } # plural
return 0; # singular
}
function lang_viewname(string viewid) [notags] : string
"Get some words representing a view"
{
if ($viewid == "recent") { return $*text_view_recent; }
if ($viewid == "archive") { return $*text_view_archive; }
if ($viewid == "friends") { return $*text_view_friends; }
if ($viewid == "day") { return "Journée"; }
if ($viewid == "month") { return "Mois"; }
if ($viewid == "userinfo") { return $*text_view_userinfo; }
if ($viewid == "entry") { return "Lire les commentaires"; }
if ($viewid == "reply") { return "Envoyer un commentaire"; }
return "Affichage inconnue";
}
function ReplyPage::view_title() : string {
return "Envoyer un commentaire";
}
function server_sig() {
"""Actionné par <a href="$*SITEROOT/">$*SITENAME</a>""";
}
function Page::print_entry_poster(Entry e) {
$e.poster->print();
if ($.view == "friends" and $e.poster.username != $e.journal.username) {
" a écrit dans ";
$e.journal->print();
}
}
function lang_user_wrote(UserLite u) : string "Returns text describing that the user wrote something. i18nc layers should override this." {
if (defined $u) {
return $u->as_string()+" a écrit";
}
else {
return "Un utilisateur anonyme a écrit";
}
}
function lang_at_datetime(DateTime d) : string "Returns a string saying \"at {the date and time given}\". Used in the core implementation of EntryPage and ReplyPage. i18nc layers should override this." {
return $d->date_format("long") + " à " + $d->time_format();
}

View File

@@ -0,0 +1,16 @@
#-*-s2-*- ;; -*- coding: utf-8 -*-
layerinfo "type" = "i18nc";
layerinfo "redist_uniq" = "i18nc/ja1";
layerinfo "name" = "Japanese";
layerinfo "langcode" = "ja";
set lang_current = "ja";
# One form (the number is inflected)
function lang_map_plural (int n) : int {
return 0;
}
set text_read_comments = "# コメント";
set text_post_comment = "コメントの送信";
set text_read_comments_friends = "# コメント";
set text_post_comment_friends = "コメントの送信";

View File

@@ -0,0 +1,21 @@
#-*-s2-*- ;; -*- coding: utf-8 -*-
layerinfo "type" = "i18nc";
layerinfo "redist_uniq" = "i18nc/ru1";
layerinfo "name" = "Russian";
layerinfo "langcode" = "ru";
set lang_current = "ru";
# Three forms, special cases for numbers ending in 1 and 2, 3, 4, except those ending in 1[1-4]
function lang_map_plural (int n) : int {
if ($n%10 == 1 and $n%100 != 11) { return 0; }
if ($n%10 >= 2 and $n%10 <= 4 and ($n%100 < 10 or $n%100>=20)) { return 1; }
return 2;
}
set text_post_comment="Оставить комментарий";
set text_read_comments="# комментарий // # комментария // # комментариев";
set text_post_comment_friends="Оставить комментарий";
set text_read_comments_friends="# комментарий // # комментария // # комментариев";

View File

@@ -0,0 +1,14 @@
# -*-s2-*-
layerinfo type = "i18n";
layerinfo name = "English";
layerinfo redist_uniq = "magazine/en";
set text_meta_music = "Music";
set text_meta_mood = "Mood";
set text_post_comment = "comment&nbsp;on&nbsp;this";
set text_read_comments = "#&nbsp;comments";
set text_post_comment_friends = "comment&nbsp;on&nbsp;this";
set text_read_comments_friends = "#&nbsp;comments";

View File

@@ -0,0 +1,699 @@
# -*-s2-*-
layerinfo type = "layout";
layerinfo name = "Magazine";
layerinfo redist_uniq = "magazine/layout";
layerinfo previews = "magazine/magazine.jpg";
propgroup colors {
property Color main_bgcolor {
des = "Main Background color";
s1color = "page_back";
}
property Color main_fgcolor {
des = "Main text color";
s1color = "page_text";
}
property Color sidebar_color {
des = "Sidebar color";
s1color = "stronger_back";
}
property Color headerbar_bgcolor {
des = "Headerbar background color";
s1color = "strong_back";
}
property Color headerbar_fgcolor {
des = "Text color on headerbar";
s1color = "strong_text";
}
property Color headerbar_bevel_color {
des = "Accent line color for headerbar";
s1color = "stronger_back";
}
property Color highlight_bgcolor {
des = "Highlighting color for accented text";
s1color = "weak_back";
}
property Color highlight_fgcolor {
des = "Highlighted text color";
s1color = "weak_text";
}
property Color border_color {
des = "Color of borders";
s1color = "weak_text";
}
property Color title_color {
des = "Text color of top title";
s1color = "page_text_title";
}
property Color meta_color {
des = "Text color of meta descriptions";
s1color = "page_text_em";
}
property Color link_color {
des = "Text color of links";
s1color = "page_link";
}
property Color vlink_color {
des = "Text color of visited links";
s1color = "page_vlink";
}
property Color alink_color {
des = "Text color of active links";
s1color = "page_alink";
}
property Color comment_bar_one_bgcolor {
des = "Alternating background color for comment bars (one)";
}
property Color comment_bar_two_fgcolor {
des = "Text color on alternating comment bars (one)";
}
property Color comment_bar_two_bgcolor {
des = "Alternating background color for comment bars (two)";
}
property Color comment_bar_one_fgcolor {
des = "Text color on alternating comment bars (two)";
}
property Color comment_bar_screened_bgcolor {
des = "Background bar color for screened comments";
}
property Color comment_bar_screened_fgcolor {
des = "Text color on background bar for screened comments";
}
}
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set sidebar_color = "#6666cc";
set headerbar_bgcolor = "#c0c0ff";
set headerbar_fgcolor = "#000000";
set headerbar_bevel_color = "#6666cc";
set highlight_bgcolor = "#eeeeff";
set highlight_fgcolor = "#000000";
set border_color = "#000000";
set title_color = "#8b1a1";
set meta_color = "#c00000";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#ff00c0";
set comment_bar_one_bgcolor = "#c0c0ff";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#eeeeff";
set comment_bar_two_fgcolor = "#000000";
set comment_bar_screened_bgcolor = "#dddddd";
set comment_bar_screened_fgcolor = "#000000";
propgroup presentation {
property bool show_entry_userpic {
des = "Show the userpic on the journal entries? [Excludes friends page]";
}
property use page_recent_items;
property use page_friends_items;
property use use_shared_pic;
property use view_entry_disabled;
property bool show_entrynav_icons {
des = "Toggle to show the next, memory, edit, etc icons on the entry view page";
}
property string page_background_image {
des = "URL to an image to be used for the page background";
}
property use external_stylesheet;
}
set show_entry_userpic = false;
set view_entry_disabled = false;
set show_entrynav_icons = true;
set page_background_image = "";
propgroup text {
property use text_post_comment;
property use text_read_comments;
property use text_post_comment_friends;
property use text_read_comments_friends;
}
set tags_aware = true;
function Page::lay_skip_navigation() {}
function Page::lay_bottom_navigation() {}
function print_stylesheet ()
{
print clean_url($*page_background_image) != "" ? "body { background-image: url($*page_background_image); }" : "";
"""HTML {
border-left: 1cm solid $*sidebar_color;
padding: 1cm;
}
BODY {
line-height: 1.3;
margin: 0;
background-color: $*main_bgcolor;
color: $*main_fgcolor;
}
P {
margin-top: 0;
text-align: justify;
}
H1 {
font: x-large Verdana, sans-serif; text-align: center;
letter-spacing: -0.09em;
color: $*title_color;
}
H2 {
background-color: $*headerbar_bgcolor;
color: $*headerbar_fgcolor;
border-bottom: thin solid $*headerbar_bevel_color;
font: normal 1.3em Georgia, serif;
}
H3 {
color: $*highlight_fgcolor;
font: medium sans-serif;
}
H3 SPAN {
background-color: $*highlight_bgcolor;
border-right: thin solid $*border_color;
border-bottom: thin solid $*border_color;
padding-right: 0.5ex;
}
H3 EM {
color: $*meta_color;
font-style: normal;
}
.H3Holder {
clear: both;
padding-left: 2ex;
border-left: thin solid $*border_color;
border-bottom: thin solid $*border_color;
margin-bottom: 1em;
}
A:link {
color: $*link_color;
}
A:visited {
color: $*vlink_color;
}
A:active {
color: $*alink_color;
}
.Navigation {
text-align: center;
font-family: sans-serif;
}
.Comment {
font-size: 0.7em;
margin-top: -1em;
text-align: right;
}
.Comment, .Current {
margin-bottom: 1em;
clear: right;
}
.Picture {
border-left: thin solid $*border_color;
border-top: thin solid $*border_color;
float: right;
margin: 0 0 0.5em 0.5em;
padding: 0.2em;
}
.Picture DIV {
text-align: center;
}
.Active {
background-color: $*highlight_bgcolor;
}
ACRONYM {
border-bottom: thin dashed $*border_color;
cursor: help;
}
.Bottom {
border-top: thin solid $*border_color;
text-align: center;
}
.Empty {
background-color: $*highlight_bgcolor;
}
.Month {
margin-top: 1em;
}
.MonthHeader {
color: $*headerbar_fgcolor;
background-color: $*headerbar_bgcolor ! important;
line-height: 1.5;
}
.Month TD {
color: $*highlight_fgcolor;
width: 14%;
border: thin outset;
}
.Month TH {
background-color: $*highlight_bgcolor;
font-family: Verdana, sans-serif;
border: thin outset;
}""";
}
function Page::print () {
var string title = $this->title();
"""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">\n<html>\n<head>\n""";
if ($*external_stylesheet) {
println """<link rel="stylesheet" href="$.stylesheet_url" type="text/css" />""";
} else {
println """<style type="text/css">"""; print_stylesheet(); "</style>";
}
$this->print_head();
"""<title>$title</title>
</head>
<body>
<h1>$title</h1>""";
var string website_name = $.journal.website_name ? $.journal.website_name : $*text_website_default_name;
var string website = ($.journal.website_url != "" ? "(<a href='$.journal.website_url'>$website_name</a>)" : "");
var string links;
foreach var string v ($.views_order) {
$links = "$links(<span style='white-space: nowrap;'>" + ($.view == $v ?
"<span class='Active'>"+lang_viewname($v)+"</span>" :
"<a href='$.view_url{$v}'>"+lang_viewname($v)+"</a>") + ")</span>\n";
}
"""<p class="Navigation">$links $website<br />""";
$this->lay_skip_navigation();
"</p>";
$this->print_body();
$this->lay_bottom_navigation();
"</body></html>";
}
function print_entry (Page p, Entry e, Color bgcolor, Color fgcolor, bool hide_text)
{
var string time = $e.time->time_format();
var string userpic = (defined $e.userpic ? "<img src='$e.userpic.url' />" : "");
if (($p.view != "entry" and $e.new_day) or $p.view == "entry")
{
"<h2>" + $e.time->date_format("med") + "</h2>";
}
"<div class='H3Holder'>";
# Altposter / friends / lastn userpic
if ($p.view == "friends" or
$p.view == "entry" or
$*show_entry_userpic == true or
$e.journal.username != $e.poster.username)
{
"<div class='Picture' style='background-color: $bgcolor;'>";
if ($p.view == "friends")
{
"<div><a href='";
print $e.journal->base_url() + "/";
"' style='color: $fgcolor;'><small>$e.journal.username</small></a></div>";
}
if ($*show_entry_userpic == true or $p.view == "friends" or $p.view == "entry")
{
if (defined $e.userpic) { "<div><img src='$e.userpic.url' /></div>"; }
}
if ($e.journal.username != $e.poster.username)
{
"<div><a href='";
print $e.poster->base_url() + "/";
"'>$e.poster.username</a></div>";
}
"</div>";
}
# Time / Subject / Security
var string subject = ($e.subject != "" ? " - <em>$e.subject</em>" : "");
"<h3><span>$time$subject</span> $e.security_icon</h3>";
if ($p.view == "entry" and $*show_entrynav_icons)
{
print "<div style='text-align: center'>";
$e->print_linkbar();
print "</div>";
}
if (not $hide_text)
{
# Entry
"<p>$e.text</p>";
# Tags
if ($e.tags) {
var int tcount = 0;
"<div class='ljtags'><strong>Tags:</strong> ";
foreach var Tag t ($e.tags) {
"""<a rel="tag" href="$t.url">$t.name</a>""";
$tcount++;
if ($tcount != size $e.tags) { ", "; }
}
"</div>";
}
# Metadata
if (size $e.metadata) {
foreach var string k ($e.metadata) {
"<div class='Currents'>";
var string key = $k;
var string val = $e.metadata{$k};
if ($k == "mood") {
$key = $*text_meta_mood;
} elseif ( $k == "music" ) {
$key = $*text_meta_music;
}
if ($k == "mood" and defined $e.mood_icon) {
var Image i = $e.mood_icon;
$val = "<img src='$i.url' width='$i.width' height='$i.height' align='absmiddle' alt='[mood icon]' /> $val";
}
"<div><strong>$key:</strong> $val</div>";
"</div>";
}
}
}
# Comments
$e.comments->print();
"</div>";
}
function CommentInfo::print()
{
if (not $.enabled) { return; }
"<div class='Comment'>(";
if ($.count > 0 or $.screened) {
$this->print_readlink(); "&nbsp;|&nbsp;";
}
$this->print_postlink();
")</div>";
}
function Page::print_entry (Entry e)
{
print_entry($this, $e, null Color, null Color, false);
}
function RecentPage::lay_skip_navigation()
{
var int total = size $.entries;
var string nav = "";
if ($.nav.backward_url != "") {
$nav = """<a href="$.nav.backward_url">Previous $total Entries</a>""";
}
if ($.nav.forward_url != "" and $.nav.backward_url != "") {
$nav = "$nav&nbsp;|&nbsp;";
}
if ($.nav.forward_url != "") {
$nav = """$nav<a href="$.nav.forward_url">Next $total Entries</a>""";
}
if ($nav != "") { print "Navigate: ($nav)"; }
}
function RecentPage::lay_bottom_navigation()
{
"<p class='Bottom'>"; $this->lay_skip_navigation(); "</p>";
}
function RecentPage::print_body
{
foreach var Entry e ($.entries) {
$this->print_entry($e);
}
}
function FriendsPage::lay_skip_navigation()
{
var int total = size $.entries;
var string nav = "";
if ($.nav.backward_url != "") {
$nav = """<a href="$.nav.backward_url">Previous $total Friends</a>""";
}
if ($.nav.forward_url != "" and $.nav.backward_url != "") {
$nav = "$nav&nbsp;|&nbsp;";
}
if ($.nav.forward_url != "") {
$nav = """$nav<a href="$.nav.forward_url">Next $total Friends</a>""";
}
if ($nav != "") { print "Navigate: ($nav)"; }
}
function FriendsPage::print_entry (Entry e)
{
var Friend f = $.friends{$e.journal.username};
print_entry($this, $e, $f.bgcolor, $f.fgcolor, false);
}
function FriendsPage::print_body
{
foreach var Entry e ($.entries) {
$this->print_entry($e);
}
}
function YearPage::lay_skip_navigation ()
{
$this->print_year_links();
}
function YearPage::lay_bottom_navigation() { }
function YearPage::print_body() {
"<h2>$.year</h2>";
foreach var YearMonth m ($.months) {
$this->print_month($m);
}
}
function YearPage::print_year_links ()
{
"Navigate: ";
foreach var YearYear y ($.years) {
if ($y.displayed) {
" (<span class='Active'>$y.year</span>) ";
} else {
" (<a href='$y.url'>$y.year</a>) ";
}
}
}
function YearPage::print_month(YearMonth m)
{
if (not $m.has_entries) { return; }
"<table class='Month'>";
"<tr><th class='MonthHeader' colspan='7'>";
"<a href='$m.url'>"; print $m->month_format(); "</a></th></tr>\n";
"<tr>";
foreach var int d (weekdays())
{
"<th>"+$*lang_dayname_short[$d]+ "</th>\n";
}
"</tr>";
foreach var YearWeek w ($m.weeks)
{
$w->print();
}
"</table>\n";
}
function YearWeek::print() {
"<tr valign='top'>";
if ($.pre_empty) { "<td class='empty' colspan='$.pre_empty'></td></td>"; }
foreach var YearDay d ($.days)
{
"<td>$d.day";
if ($d.num_entries)
{
"<div align='center'><a href='$d.url'><strong>$d.num_entries</strong></a></div>";
} else {
"<br /><br />";
}
"</td>";
}
if ($.post_empty) { "<td class='empty' colspan='$.post_empty'></td></td>"; }
"</tr>";
}
function DayPage::lay_skip_navigation()
{
"Navigate: (<a href='$.prev_url'>Previous Day</a>&nbsp;|&nbsp;<a href='$.next_url'>Next Day</a>)";
}
function DayPage::lay_bottom_navigation()
{
"""
<table style="border-top: thin solid $*headerbar_bevel_color;" width="100%">
<tr>
<td width="33%">&larr; <a href="$.prev_url">Previous day</a></td>
<td width="34%" align="center">(<a href="$.base_url/calendar">Calendar</a>)</td>
<td width="33%" align="right"><a href="$.next_url">Next day</a> &rarr;</td>
</tr>
</table>
""";
}
function DayPage::print_body ()
{
if (not $.has_entries) {
"<h2>"; print $.date->date_format("med"); "</h2>";
print "<p>(No journal entries for this day.)</p>";
} else {
foreach var Entry e ($.entries) {
$this->print_entry($e);
}
}
}
function EntryPage::print_body ()
{
set_handler("unscreen_comment_#", [
[ "style_bgcolor", "cmtbar#", "$*comment_bar_one_bgcolor", ],
[ "style_color", "cmtbar#", "$*comment_bar_one_fgcolor", ],
]);
set_handler("screen_comment_#", [
[ "style_bgcolor", "cmtbar#", "$*comment_bar_screened_bgcolor", ],
[ "style_color", "cmtbar#", "$*comment_bar_screened_fgcolor", ],
]);
print_entry($this, $.entry, null Color, null Color, $.viewing_thread);
if ($.entry.comments.enabled and $.comment_pages.total_subitems > 0)
{
$this->print_multiform_start();
print "<h2>Comments:</h2><div style='margin-left: 30px;'>";
if ($.comment_pages.total_subitems > 0) {
$.comment_pages->print();
$this->print_comments($.comments);
}
"</div>";
if ($this.multiform_on) {
"<h2>Mass Action</h2><div style='margin-left: 30px;'>";
$this->print_multiform_actionline();
$this->print_multiform_end();
"</div>";
}
}
}
function EntryPage::print_comment (Comment c) {
var Color background; var Color color;
if ($c.screened) {
$background = $*comment_bar_screened_bgcolor;
$color = $*comment_bar_screened_fgcolor;
} elseif ($c.depth % 2) {
$background = $*comment_bar_one_bgcolor;
$color = $*comment_bar_one_fgcolor;
} else {
$background = $*comment_bar_two_bgcolor;
$color = $*comment_bar_two_fgcolor;
}
var string poster = defined $c.poster ? $c.poster->as_string() : "<i>(Anonymous)</i>";
var string sub_icon;
if (defined $c.subject_icon) {
$sub_icon = $c.subject_icon->as_string();
}
"<a name='$c.anchor'></a><div id='cmtbar$c.talkid' style='background-color: $background; color: $color; margin-top: 10px; width: 100%'>";
"<table cellpadding='2' cellspacing='0' summary='0' style='width: 100%'><tr valign='top'>";
if (defined $c.userpic and $*comment_userpic_style != "off") {
var int w = $c.userpic.width;
var int h = $c.userpic.height;
# WARNING: this will later be done by the system (it'll be a
# constructional property), so don't copy this hack into your
# layout layers or you'll be messed up later.
if ($*comment_userpic_style == "small") {
$w = $w / 2;
$h = $h / 2;
}
print "<td style='width: 102px'><img src='$c.userpic.url' width='$w' height='$h' alt='[User Picture]' /></td>";
}
"<td style='width: 100%'><table style='width: 100%'><tr>";
### From, date, etc
"<td align='left' style='width: 50%'>";
print "<table>";
print "<tr><th align='right'>From:</th><td>$poster</td></tr>\n";
print "<tr><th align='right'>Date:</th><td style='white-space: nowrap'>";
print $c.time->date_format("long") + " - " + $c.time->time_format() + "</td></tr>";
if ($c.metadata{"poster_ip"}) { print "<tr><th align='right'>IP Address:</th><td>(" + $c.metadata{"poster_ip"} + ")</td></tr>"; }
"</table></td>";
### Gadgets
"<td align='right' style='width: 50%'>";
if ($this.multiform_on) {
" <label for='ljcomsel_$c.talkid'>$*text_multiform_check</label>";
$c->print_multiform_check();
}
$c->print_linkbar();
"</td></tr>";
### Subject / icon
print "<tr valign='top'><td style='width: 50%'>";
print (defined $c.subject_icon or $c.subject != "") ? "<h3>$c.subject_icon $c.subject</h3>" : "";
print "</td>";
### Permalink
print "<td style='width: 50%' align='right'><strong>(<a href='$c.permalink_url'>Link</a>)</strong></td></tr>";
print "</table></td></tr></table></div>";
print "<div style='margin-left: 5px'>$c.text</div>";
print "<div style='margin-top: 3px; font-size: smaller'>";
if ($c.frozen) {
print """(Replies frozen) """;
} else {
print """(<a href='$c.reply_url'>Reply to this</a>) """;
}
if ($c.parent_url != "") { "(<a href='$c.parent_url'>Parent</a>) "; }
if ($c.thread_url != "") { "(<a href='$c.thread_url'>Thread</a>) "; }
"</div>";
}
function ReplyPage::print_body ()
{
var string time = $.replyto.time->time_format();
if (not $.entry.comments.enabled)
{
print "<h2>$*text_reply_nocomments_header</h2><p>$*text_reply_nocomments</p>";
return;
}
"<h2>" + $.replyto.time->date_format("med") + "</h2>";
"<div class='H3Holder'>";
"<div class='Picture'>";
print defined $.replyto.poster ? $.replyto.poster->as_string() : "<i>(Anonymous)</i>";
if (defined $.replyto.userpic) { "<div><img src='$.replyto.userpic.url' /></div>"; }
"</div>";
# Time / Subject / Security
var string subject = ($.replyto.subject ? " - <em>$.replyto.subject</em>" : "");
"<h3><span>$time$subject</span></h3>";
"<p>$.replyto.text</p>";
"<div class='Comment'><a href='$.entry.comments.read_url'>Read Comments</a></div>";
"</div>";
print "<h2>Reply:</h2>";
$.form->print();
}
function print_theme_preview ()
{
"""<table width='100%' bgcolor='$*main_bgcolor' cellpadding='3' border='0'><tr valign='top'>
<td width='30' bgcolor='$*sidebar_color'>&nbsp;</td>
<td width='30'>&nbsp;</td>
<td>
<h2 style='background-color: $*headerbar_bgcolor; color: $*headerbar_fgcolor; border-bottom: thin solid $*headerbar_bevel_color; font: normal 1.3em Georgia, serif; line-height: 1.3;'>Dec. 22nd, 2002</h2>
<div style='clear: both; padding-left: 2ex; border-left: thin solid $*border_color; border-bottom: thin solid $*border_color; margin-bottom: 1em; '>
<h3 style='color: $*highlight_fgcolor; font: medium sans-serif'><span style='background-color: $*highlight_bgcolor; border-right: thin solid $*border_color; border-bottom: thin solid $*border_color; padding-right: 0.5ex;'>08:46 pm - <em style='color: $*meta_color; font-style: normal;'>subject</em></span></h3>
<p style='margin-top: 0; text-align: justify; font-family: serif; font-size: 12pt; color: $*main_fgcolor;'>Words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words words</p>
<div style='font-size: 0.7em; margin-top: -1em; text-align: right; font-size: 8pt; color: $*main_fgcolor;'>(<a style='color: $*link_color;' href='#'>1 comment</a>&nbsp;|&nbsp;<a style='color: $*link_color;' href='#'>Leave a comment</a>)</div>
</div>
</td></tr>
</table>""";
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -0,0 +1,459 @@
#NEWLAYER: magazine/wonb
layerinfo "type" = "theme";
layerinfo "name" = "White on Black";
layerinfo "redist_uniq" = "magazine/wonb";
set title_color = "#ffffff";
set main_bgcolor = "#000000";
set main_fgcolor = "#ffffff";
set sidebar_color = "#555555";
set headerbar_bgcolor = "#777777";
set headerbar_fgcolor = "#ffffff";
set headerbar_bevel_color = "#777777";
set link_color = "#eeeeee";
set alink_color = "#ffffff";
set vlink_color = "#dddddd";
set meta_color = "#ffffff";
set highlight_bgcolor = "#666666";
set highlight_fgcolor = "#dddddd";
set border_color = "#ffffff";
set comment_bar_one_bgcolor = "#777777";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#666666";
set comment_bar_two_fgcolor = "#dddddd";
#NEWLAYER: magazine/shrinkvio
layerinfo type = theme;
layerinfo name = "Shrinking Violet";
layerinfo redist_uniq = "magazine/shrinkvio";
set sidebar_color = "#ad22e7";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set border_color = "#381a45";
set headerbar_bgcolor = "#5d0383";
set headerbar_fgcolor = "#ffffff";
set title_color = "#5d0383";
set meta_color = "#ffffff";
set headerbar_bevel_color = "#d9a1f1";
set highlight_bgcolor = "#d9a1f1";
set highlight_fgcolor = "#000000";
set link_color = "#2e053f";
set vlink_color = "#611627";
set alink_color = "#ff00c0";
set comment_bar_one_bgcolor = "#5d0383";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#d9a1f1";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: magazine/pistmint
layerinfo type = theme;
layerinfo name = "Pistachio Mint";
layerinfo redist_uniq = "magazine/pistmint";
set sidebar_color = "#133422";
set main_bgcolor = "#a7c4b4";
set main_fgcolor = "#000000";
set border_color = "#096d36";
set headerbar_bgcolor = "#096d36";
set headerbar_fgcolor = "#ffffff";
set title_color = "#096d36";
set meta_color = "#ffffff";
set headerbar_bevel_color = "#096d36";
set highlight_bgcolor = "#096d36";
set highlight_fgcolor = "#000000";
set link_color = "#8afabc";
set vlink_color = "#1da65a";
set alink_color = "#f9f5f5";
set comment_bar_one_bgcolor = "#096d36";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#093d36";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: magazine/mexicanfood
layerinfo type = theme;
layerinfo name = "Mexican Food";
layerinfo redist_uniq = "magazine/mexicanfood";
set sidebar_color = "#ff0000";
set main_bgcolor = "#f8ff3e";
set main_fgcolor = "#f15601";
set border_color = "#f50701";
set headerbar_bgcolor = "#bdbf3e";
set headerbar_fgcolor = "#ff0000";
set title_color = "#ffc664";
set meta_color = "#000000";
set headerbar_bevel_color = "#f9ff9d";
set highlight_bgcolor = "#e15a18";
set highlight_fgcolor = "#ffffff";
set link_color = "#f49e08";
set vlink_color = "#b05403";
set alink_color = "#ff7405";
set comment_bar_one_bgcolor = "#bdbf3e";
set comment_bar_one_fgcolor = "#ff0000";
set comment_bar_two_bgcolor = "#e15a18";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: magazine/ashfire
layerinfo type = theme;
layerinfo name = "Ash and Fire";
layerinfo redist_uniq = "magazine/ashfire";
set sidebar_color = "#b5b5b5";
set main_bgcolor = "#ffb6af";
set main_fgcolor = "#000000";
set border_color = "#d90308";
set headerbar_bgcolor = "#e75454";
set headerbar_fgcolor = "#ffffff";
set title_color = "#ff9696";
set meta_color = "#ffffff";
set headerbar_bevel_color = "#ff1106";
set highlight_bgcolor = "#f06c88";
set highlight_fgcolor = "#000000";
set link_color = "#f70208";
set vlink_color = "#b0161d";
set alink_color = "#d70106";
set comment_bar_one_bgcolor = "#e75454";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#f06c88";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: magazine/desktop
layerinfo type = theme;
layerinfo name = "Classic Desktop";
layerinfo redist_uniq = "magazine/desktop";
set sidebar_color = "#00545c";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set border_color = "#000000";
set headerbar_bgcolor = "#ff7b05";
set headerbar_fgcolor = "#ffeddd";
set title_color = "#ffffff";
set meta_color = "#000000";
set headerbar_bevel_color = "#ff7b05";
set highlight_bgcolor = "#ffeddd";
set highlight_fgcolor = "#000000";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#5a76ff";
set comment_bar_one_bgcolor = "#ff7b05";
set comment_bar_one_fgcolor = "#ffeddd";
set comment_bar_two_bgcolor = "#ffeddd";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: magazine/satinhandshake
layerinfo type = theme;
layerinfo name = "Satin Handshake";
layerinfo redist_uniq = "magazine/satinhandshake";
set sidebar_color = "#480c0c";
set main_bgcolor = "#d06464";
set main_fgcolor = "#00001d";
set border_color = "#000000";
set headerbar_bgcolor = "#aaaaaa";
set headerbar_fgcolor = "#000000";
set title_color = "#aaaaaa";
set meta_color = "#000000";
set headerbar_bevel_color = "#9d0404";
set highlight_bgcolor = "#9d0404";
set highlight_fgcolor = "#ffffff";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#ff00c0";
set comment_bar_one_bgcolor = "#aaaaaa";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#9d0404";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: magazine/deepmelodrama
layerinfo type = theme;
layerinfo name = "Deep MeloDrama";
layerinfo redist_uniq = "magazine/deepmelodrama";
set sidebar_color = "#872d89";
set main_bgcolor = "#719cff";
set main_fgcolor = "#8e48b2";
set border_color = "#8e48b2";
set headerbar_bgcolor = "#3794b3";
set headerbar_fgcolor = "#84b8e7";
set title_color = "#65b2c1";
set meta_color = "#f5d3ff";
set headerbar_bevel_color = "#8e48b2";
set highlight_bgcolor = "#65b2c1";
set highlight_fgcolor = "#f5d3ff";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#dfd3ff";
set comment_bar_one_bgcolor = "#3794b3";
set comment_bar_one_fgcolor = "#84b8e7";
set comment_bar_two_bgcolor = "#65b2c1";
set comment_bar_two_fgcolor = "#f5d3ff";
#NEWLAYER: magazine/everwhite
layerinfo type = theme;
layerinfo name = "Everwhite";
layerinfo redist_uniq = "magazine/everwhite";
set sidebar_color = "#ffffff";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set border_color = "#000000";
set headerbar_bgcolor = "#ffffff";
set headerbar_fgcolor = "#000000";
set title_color = "#ffffff";
set meta_color = "#000000";
set headerbar_bevel_color = "#ffffff";
set highlight_bgcolor = "#ffffff";
set highlight_fgcolor = "#000000";
set link_color = "#e60000";
set vlink_color = "#c10602";
set alink_color = "#ff0600";
set comment_bar_one_bgcolor = "#dddddd";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#aaaaaa";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: magazine/everblue
layerinfo type = theme;
layerinfo name = "Everblue with Greys";
layerinfo redist_uniq = "magazine/everblue";
set sidebar_color = "#0f0c6d";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set border_color = "#000000";
set headerbar_bgcolor = "#000000";
set headerbar_fgcolor = "#ffffff";
set title_color = "#aaaaaa";
set meta_color = "#000000";
set headerbar_bevel_color = "#000000";
set highlight_bgcolor = "#aaaaaa";
set highlight_fgcolor = "#000000";
set link_color = "#2f00f2";
set vlink_color = "#060667";
set alink_color = "#6691ff";
set comment_bar_one_bgcolor = "#000000";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#aaaaaa";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: magazine/brownleather
layerinfo type = theme;
layerinfo name = "Brown Leather Coat";
layerinfo redist_uniq = "magazine/brownleather";
set sidebar_color = "#d2b48c";
set main_bgcolor = "#ffebcd";
set main_fgcolor = "#8b4513";
set border_color = "#000000";
set headerbar_bgcolor = "#d48014";
set headerbar_fgcolor = "#ffffff";
set title_color = "#d48014";
set meta_color = "#d48014";
set headerbar_bevel_color = "#d48014";
set highlight_bgcolor = "#ffe1a1";
set highlight_fgcolor = "#000000";
set link_color = "#000050";
set vlink_color = "#867a55";
set alink_color = "#fffab3";
set comment_bar_one_bgcolor = "#d48014";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#ffe1a1";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: magazine/bruise
layerinfo type = theme;
layerinfo name = "Bruise";
layerinfo redist_uniq = "magazine/bruise";
set sidebar_color = "#000000";
set main_bgcolor = "#bcbcbc";
set main_fgcolor = "#000000";
set border_color = "#000000";
set headerbar_bgcolor = "#1114a0";
set headerbar_fgcolor = "#ffffff";
set title_color = "#21c2f1";
set meta_color = "#ffffff";
set headerbar_bevel_color = "#1114a0";
set highlight_bgcolor = "#21c2f1";
set highlight_fgcolor = "#0000ff";
set link_color = "#0000cc";
set vlink_color = "#000088";
set alink_color = "#0000ff";
set comment_bar_one_bgcolor = "#1114a0";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#21c2f1";
set comment_bar_two_fgcolor = "#0000ff";
#NEWLAYER: magazine/ranchhand
layerinfo type = theme;
layerinfo name = "Ranch Hand";
layerinfo redist_uniq = "magazine/ranchhand";
set sidebar_color = "#2999c2";
set main_bgcolor = "#cfe0ff";
set main_fgcolor = "#000000";
set border_color = "#060667";
set headerbar_bgcolor = "#54442c";
set headerbar_fgcolor = "#ffffff";
set title_color = "#bababa";
set meta_color = "#000000";
set headerbar_bevel_color = "#9d995d";
set highlight_bgcolor = "#704400";
set highlight_fgcolor = "#bababa";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#6a20ff";
set comment_bar_one_bgcolor = "#54442c";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#704400";
set comment_bar_two_fgcolor = "#bababa";
#NEWLAYER: magazine/victim
layerinfo type = theme;
layerinfo name = "Victim";
layerinfo redist_uniq = "magazine/victim";
set sidebar_color = "#2cd0ff";
set main_bgcolor = "#505050";
set main_fgcolor = "#ffffff";
set border_color = "#000000";
set headerbar_bgcolor = "#166bac";
set headerbar_fgcolor = "#ffffff";
set title_color = "#2098f3";
set meta_color = "#ffffff";
set headerbar_bevel_color = "#26b6ff";
set highlight_bgcolor = "#353535";
set highlight_fgcolor = "#ffffff";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#ff00c0";
set comment_bar_one_bgcolor = "#166bac";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#353535";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: magazine/forest
layerinfo type = theme;
layerinfo name = "Forest";
layerinfo redist_uniq = "magazine/forest";
set sidebar_color = "#778e64";
set main_bgcolor = "#9b9ba5";
set main_fgcolor = "#000000";
set border_color = "#ffffff";
set headerbar_bgcolor = "#72784c";
set headerbar_fgcolor = "#ffffff";
set title_color = "#72784c";
set meta_color = "#ffffff";
set headerbar_bevel_color = "#a0ac62";
set highlight_bgcolor = "#73777a";
set highlight_fgcolor = "#000000";
set link_color = "#3811e1";
set vlink_color = "#310cbb";
set alink_color = "#4e7bef";
set comment_bar_one_bgcolor = "#72784c";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#73777a";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: magazine/drone
layerinfo type = theme;
layerinfo name = "Drone";
layerinfo redist_uniq = "magazine/drone";
set sidebar_color = "#395f82";
set main_bgcolor = "#f9fcfe";
set main_fgcolor = "#000000";
set border_color = "#000000";
set headerbar_bgcolor = "#904094";
set headerbar_fgcolor = "#ffffff";
set title_color = "#f56efc";
set meta_color = "#ffffff";
set headerbar_bevel_color = "#ff93ff";
set highlight_bgcolor = "#eeeeff";
set highlight_fgcolor = "#000000";
set link_color = "#395f82";
set vlink_color = "#395f82";
set alink_color = "#5266ce";
set comment_bar_one_bgcolor = "#904094";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#eeeeff";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: magazine/lowercurtain
layerinfo type = theme;
layerinfo name = "Lower the Curtain";
layerinfo redist_uniq = "magazine/lowercurtain";
set sidebar_color = "#000000";
set main_bgcolor = "#6b6b6b";
set main_fgcolor = "#ffffff";
set border_color = "#ffffff";
set headerbar_bgcolor = "#363636";
set headerbar_fgcolor = "#f0f5fb";
set title_color = "#c6c6c6";
set meta_color = "#222222";
set headerbar_bevel_color = "#363636";
set highlight_bgcolor = "#c5c8ca";
set highlight_fgcolor = "#000000";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#3314ba";
set comment_bar_one_bgcolor = "#363636";
set comment_bar_one_fgcolor = "#f0f5fb";
set comment_bar_two_bgcolor = "#c5c8ca";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: magazine/sunny
layerinfo type = theme;
layerinfo name = "Sunny Day";
layerinfo redist_uniq = "magazine/sunny";
set sidebar_color = "#55e0f9";
set main_bgcolor = "#e38202";
set main_fgcolor = "#ffffff";
set border_color = "#000000";
set headerbar_bgcolor = "#e38202";
set headerbar_fgcolor = "#ffffff";
set title_color = "#fff505";
set meta_color = "#ffffff";
set headerbar_bevel_color = "#efe052";
set highlight_bgcolor = "#ffba03";
set highlight_fgcolor = "#ffffff";
set link_color = "#df0d12";
set vlink_color = "#ac1b25";
set alink_color = "#fe3b3b";
set comment_bar_one_bgcolor = "#e38202";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#ffba03";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: magazine/valentine
layerinfo type = theme;
layerinfo name = "Be Mine";
layerinfo redist_uniq = "magazine/valentine";
set sidebar_color = "#6f104a";
set main_bgcolor = "#f2bce9";
set main_fgcolor = "#000000";
set border_color = "#ff24ab";
set headerbar_bgcolor = "#ff37ff";
set headerbar_fgcolor = "#ffffff";
set title_color = "#df2096";
set meta_color = "#ffffff";
set headerbar_bevel_color = "#ae1774";
set highlight_bgcolor = "#df2096";
set highlight_fgcolor = "#000000";
set link_color = "#ffffff";
set vlink_color = "#a51014";
set alink_color = "#ed8188";
set comment_bar_one_bgcolor = "#ff37ff";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#df2096";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: magazine/stripes
layerinfo type = theme;
layerinfo name = "Stripes";
layerinfo redist_uniq = "magazine/stripes";
set sidebar_color = "#ffffff";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set border_color = "#ff0000";
set headerbar_bgcolor = "#e7212a";
set headerbar_fgcolor = "#ffffff";
set title_color = "#ffffff";
set meta_color = "#000000";
set headerbar_bevel_color = "#ffffff";
set highlight_bgcolor = "#ffcfdc";
set highlight_fgcolor = "#000000";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#ffafc1";
set comment_bar_one_bgcolor = "#e7212a";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#ffcfdc";
set comment_bar_two_fgcolor = "#000000";

View File

@@ -0,0 +1,14 @@
# -*-s2-*-
layerinfo type = "i18n";
layerinfo name = "English";
layerinfo redist_uniq = "notepad/en";
set text_meta_music = "Music";
set text_meta_mood = "Mood";
set text_post_comment = "Make Notes";
set text_read_comments = "Read # Notes";
set text_post_comment_friends = "Make Notes";
set text_read_comments_friends = "Read # Notes";

View File

@@ -0,0 +1,605 @@
# -*-s2-*-
layerinfo type = "layout";
layerinfo name = "Notepad";
layerinfo redist_uniq = "notepad/layout";
layerinfo previews = "notepad/notepad.jpg";
propgroup colors {
property Color body_bgcolor {
des = "Body background color";
}
property Color text_color {
des = "Text color";
}
property Color subject_color {
des = "Text color of subjects";
}
property Color link_color {
des = "Link color";
}
property Color vlink_color {
des = "Visited link color";
}
property Color alink_color {
des = "Active link color";
}
property Color comment_bar_one_bgcolor {
des = "Alternating background color for comment bars (one)";
}
property Color comment_bar_two_fgcolor {
des = "Text color on alternating comment bars (one)";
}
property Color comment_bar_two_bgcolor {
des = "Alternating background color for comment bars (two)";
}
property Color comment_bar_one_fgcolor {
des = "Text color on alternating comment bars (two)";
}
property Color comment_bar_screened_bgcolor {
des = "Background bar color for screened comments";
}
property Color comment_bar_screened_fgcolor {
des = "Text color on background bar for screened comments";
}
}
set body_bgcolor = "#8cd5fe";
set text_color = "#000000";
set subject_color = "#ff0000";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#ff00c0";
set comment_bar_one_bgcolor = "#c0c0ff";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#eeeeff";
set comment_bar_two_fgcolor = "#000000";
set comment_bar_screened_bgcolor = "#dddddd";
set comment_bar_screened_fgcolor = "#000000";
propgroup presentation {
property bool show_entry_userpic {
des = "Show the userpic on the journal entries?";
}
property use page_recent_items;
property use page_friends_items;
property use use_shared_pic;
property use view_entry_disabled;
property string page_background_image {
des = "URL to an image to be used for the page background";
}
property bool show_entrynav_icons {
des = "Toggle to show the next, memory, edit, etc icons on the entry view page";
}
property use external_stylesheet;
}
set show_entry_userpic = false;
set view_entry_disabled = false;
set page_background_image = "";
set show_entrynav_icons = true;
propgroup text {
property use text_post_comment;
property use text_read_comments;
property use text_post_comment_friends;
property use text_read_comments_friends;
}
property string imguri {
noui = 1;
des = "URI to notepad images (no trailing slash)";
}
set imguri = "";
function prop_init()
{
if ($*imguri == "") { $*imguri = "$*SITEROOT/img/style/notepad"; }
}
function Page::lay_bottom_navigation() { }
function print_stylesheet ()
{
var string backgroundurl = clean_url($*page_background_image) != "" ? "background-image: url($*page_background_image);" : "";
"""body {
$backgroundurl
background-color: $*body_bgcolor;
}
td,body,p,div {
color: $*text_color;
text-decoration: none;
font-family: verdana,arial,helvetica;
font-size: 12px;
}
a:link {
color: $*link_color;
text-decoration: underline;
font-family: verdana,arial,helvetica;
font-size: 12px;
}
a:visited {
color: $*vlink_color;
text-decoration: underline;
font-family: verdana,arial,helvetica;
font-size:12px;
}
a:active {
color: $*alink_color;
text-decoration: underline;
font-family: verdana,arial,helvetica;
font-size: 12px;
}
a:hover {
color: $*alink_color;
text-decoration: underline;
font-family: verdana,arial,helvetica;
font-size:12px;
}""";
}
function Page::print()
{
var string title = $this->title();
"""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n<html>\n<head>\n""";
if ($*external_stylesheet) {
println """<link rel="stylesheet" href="$.stylesheet_url" type="text/css" />""";
} else {
println """<style type="text/css">"""; print_stylesheet(); "</style>";
}
$this->print_head();
"""<title>$title</title>
</head>
<body>
<table width="70%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td colspan="2">
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="30"><img src="$*imguri/spacer.gif" width="30" height="10" alt='' /></td>
<td width="120" height="18" style="background-image: url($*imguri/tab.jpg)">&nbsp;&nbsp;
<a href="$.base_url/">Journal</a>
</td>
<td width="120" height="18" style="background-image: url($*imguri/tab.jpg)">&nbsp;&nbsp;
<a href="$.base_url/friends">Friends</a>
</td>
<td width="120" height="18" style="background-image: url($*imguri/tab.jpg)">&nbsp;&nbsp;
<a href="$.base_url/calendar">Archive</a>
</td>
<td width="120" height="18" style="background-image: url($*imguri/tab.jpg)">&nbsp;&nbsp;
<a href="$.base_url/info">User Info</a>
</td>
<td width="120" height="18" style="background-image: url($*imguri/tab.jpg)">&nbsp;&nbsp;
<a href="$*SITEROOT/tools/memories.bml?user=$.journal.username">memories</a>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td width="80" height="38" style="background-image: url($*imguri/top-left.jpg)">
<img src="$*imguri/spacer.gif" width="80" height="10" alt='' />
</td>
<td height="38" style="background-image: url($*imguri/middle.jpg)">
<img src="$*imguri/spacer.gif" width="10" height="10" alt='' />
</td>
<td width="10" height="38" style="background-image: url($*imguri/top-right.jpg)">
<img src="$*imguri/spacer.gif" width="10" height="10" alt='' />
</td>
</tr>
<tr>
<td width="80" height="38" style="background-image: url($*imguri/side-left.jpg)">
&nbsp;
</td>
<td width="100%" height="38" style="background-image: url($*imguri/middle.jpg)">
<h1>$title</h1>
<p align="center"><img src="$*imguri/hr.gif" width="345" height="23" alt='' /></p>
""";
$this->print_body();
"<p style='text-align: center; font-size: 115%'>"; $this->lay_bottom_navigation(); "</p>";
"""
</td>
<td width="8" height="38" style="background-image: url($*imguri/side-right.jpg)">
&nbsp;
</td>
</tr>
<tr>
<td width="80" height="12" style="background-image: url($*imguri/bottom-left.jpg)">
<img src="$*imguri/spacer.gif" width="70" height="12" alt='' />
</td>
<td height="12" style="background-image: url($*imguri/bottom-line.jpg)">
<img src="$*imguri/spacer.gif" width="10" height="12" alt='' />
</td>
<td width="8" height="12" style="background-image: url($*imguri/bottom-right.jpg)">
<img src="$*imguri/spacer.gif" width="8" height="12" alt='' />
</td>
</tr>
</table>
</body>
</html>
""";
}
function print_entry (Page p, Entry e, Color bgcolor, Color fgcolor, bool hide_text)
{
"<table border='0'><tr>";
if ($p.view == "friends" or
$*show_entry_userpic == true or
$e.journal.username != $e.poster.username)
{
var string userpic = defined $e.userpic ? "<img src='$e.userpic.url' /><br />" : "";
"<td valign='top' width='100' align='center'>";
if ($p.view == "friends" or $*show_entry_userpic == true) { print $userpic; }
if ($p.view == "friends") { "<strong><a href='"; print $e.journal->base_url(); "/'>$e.journal.username</a></strong>"; }
if ($e.journal.username != $e.poster.username)
{
print ($p.view == "friends" ?
"<br />[ <a href='" + $e.poster->base_url() + "/'>$e.poster.username</a> ]" :
"<strong><a href='" + $e.poster->base_url() + "/'>$e.poster.username</a></strong>");
}
"</td>";
}
"""<td valign="top" width='100%'><font size="+1">"""; print $e.time->date_format("med"); " "; print $e.time->time_format();
if ($e.subject) { " <span style='color: $*subject_color'>$e.subject</span>"; }
" $e.security_icon</font>";
if (not $hide_text)
{
print "<p>$e.text</p>";
if (size $e.metadata) {
"<p>";
foreach var string k ($e.metadata) {
var string key = $k;
var string val = $e.metadata{$k};
if ($k == "mood") {
$key = $*text_meta_mood;
} elseif ($k == "music") {
$key = $*text_meta_music;
}
if ($k == "mood" and defined $e.mood_icon) {
var Image i = $e.mood_icon;
$val = "<img src='$i.url' width='$i.width' height='$i.height' align='absmiddle' alt='' /> $val";
}
"<strong>$key:</strong> $val<br />";
}
"</p>";
}
}
$e.comments->print();
if ($p.view == "entry" and $*show_entrynav_icons)
{
$e->print_linkbar();
}
"""</td></tr><tr><td colspan="2"></td></tr></table>""";
"""<p align="center"><img src="$*imguri/hr.gif" width="345" height="23" alt='' /></p>""";
}
function Page::print_entry (Entry e)
{
print_entry($this, $e, null Color, null Color, false);
}
function RecentPage::print_body ()
{
foreach var Entry e ($.entries) {
$this->print_entry($e);
}
}
function FriendsPage::print_entry (Entry e) {
var Friend f = $.friends{$e.journal.username};
print_entry($this, $e, $f.bgcolor, $f.fgcolor, false);
}
function RecentPage::lay_bottom_navigation ()
{
var string nav = "";
if ($.nav.backward_url != "") {
$nav = """<a href="$.nav.backward_url">Back a Page</a>""";
}
if ($.nav.forward_url != "" and $.nav.backward_url != "") {
$nav = "$nav - ";
}
if ($.nav.forward_url != "") {
$nav = """$nav<a href="$.nav.forward_url">Forward a Page</a>""";
}
if ($nav != "") { print $nav; }
}
function CommentInfo::print()
{
if (not $.enabled) { return; }
if ($.count > 0 or $.screened)
{
$this->print_readlink(); " - ";
}
$this->print_postlink();
}
function YearPage::lay_bottom_navigation ()
{
$this->print_year_links();
}
function YearPage::print_year_links ()
{
if (size $.years <= 0) { return; }
foreach var YearYear y ($.years)
{
if ($y.displayed) {
"$y.year&nbsp;";
} else {
"<a href='$y.url'>$y.year</a>&nbsp;";
}
}
}
function YearPage::print_body ()
{
"<h2>$.year</h2>";
foreach var YearMonth m ($.months)
{
$this->print_month($m);
}
}
function YearPage::print_month(YearMonth m)
{
if (not $m.has_entries) { return; }
"<p align='center'><table border='1' cellpadding='4' width='80%'>";
# Month Header
"<tr align=center><th colspan='7'>"; print $m->month_format(); "</th></tr>";
# Weekdays
"<tr align='center'>";
foreach var int d (weekdays())
{
"<td>" + $*lang_dayname_short[$d] + "</td>\n";
}
"</tr>";
# Weeks
foreach var YearWeek w ($m.weeks)
{
$w->print();
}
"<tr align='center'><td colspan='7'>";
"<a href='$m.url'>$*text_view_month</a>";
"</td></tr></table></p>";
}
function YearWeek::print()
{
"<tr>";
if ($.pre_empty) { "<td colspan='$.pre_empty'>&nbsp;</td>"; }
foreach var YearDay d ($.days)
{
"<td valign='top'><b><font size='-1'>$d.day</font></b><div align='center'>";
if ($d.num_entries)
{
"<a href='$d.url'>$d.num_entries</a>";
} else {
"&nbsp;";
}
"</div></td>";
}
if ($.post_empty) { "<td colspan='$.post_empty'>&nbsp;</td>"; }
}
function DayPage::lay_bottom_navigation()
{
if (not $.has_entries) { "<img src='$*imguri/hr.gif' alt='' /><br />"; }
print "<a href='$.prev_url'>Back a Day</a> - <a href='$.next_url'>Forward a Day</a>";
}
function DayPage::print_body()
{
if (not $.has_entries) {
"<p>No journal entries for this day.</p>";
} else {
foreach var Entry e ($.entries) { $this->print_entry($e); }
}
}
function EntryPage::print_body ()
{
set_handler("unscreen_comment_#", [
[ "style_bgcolor", "cmtbar#", "$*comment_bar_one_bgcolor", ],
[ "style_color", "cmtbar#", "$*comment_bar_one_fgcolor", ],
]);
set_handler("screen_comment_#", [
[ "style_bgcolor", "cmtbar#", "$*comment_bar_screened_bgcolor", ],
[ "style_color", "cmtbar#", "$*comment_bar_screened_fgcolor", ],
]);
print_entry($this, $.entry, null Color, null Color, $.viewing_thread);
if ($.entry.comments.enabled and $.comment_pages.total_subitems > 0)
{
$this->print_multiform_start();
print "<h2>Comments:</h2>";
if ($.comment_pages.total_subitems > 0) {
$.comment_pages->print();
$this->print_comments($.comments);
}
if ($this.multiform_on) {
"<h2>Mass Action:</h2>";
$this->print_multiform_actionline();
$this->print_multiform_end();
}
}
}
function EntryPage::print_comment (Comment c) {
var Color barlight = $*color_comment_bar->clone();
$barlight->lightness(($barlight->lightness() + 255) / 2);
var Color barc = $c.depth % 2 ? $*color_comment_bar : $barlight;
if ($c.screened) {
$barc = $*comment_bar_screened_bgcolor;
}
var string poster = defined $c.poster ? $c.poster->as_string() : "<i>(Anonymous)</i>";
"<a name='$c.anchor'></a><div id='cmtbar$c.talkid' style='background-color: $barc; margin-top: 10px; width: 100%'>";
"<table cellpadding='2' cellspacing='0' summary='0' style='width: 100%'><tr valign='top'>";
if (defined $c.userpic and $*comment_userpic_style != "off") {
var int w = $c.userpic.width;
var int h = $c.userpic.height;
# WARNING: this will later be done by the system (it'll be a
# constructional property), so don't copy this hack into your
# layout layers or you'll be messed up later.
if ($*comment_userpic_style == "small") {
$w = $w / 2;
$h = $h / 2;
}
print "<td style='width: 102px'><img src='$c.userpic.url' width='$w' height='$h' alt='' /></td>";
}
"<td><table style='width: 100%'><tr>";
"<td align='left' style='width: 50%'>";
print "<table>";
print "<tr><th align='right'>$*text_comment_from</th><td>$poster</td></tr>\n";
print "<tr><th align='right'>$*text_comment_date</th><td style='white-space: nowrap'>";
print $c.time->date_format("long") + " - " + $c.time->time_format() + "</td></tr>";
if ($c.metadata{"poster_ip"}) { print "<tr><th align='right'>$*text_comment_ipaddr</th><td>(" + $c.metadata{"poster_ip"} + ")</td></tr>"; }
"</table></td>";
print "<td align='right' style='width: 50%'>";
if ($this.multiform_on) {
" <label for='ljcomsel_$c.talkid'>$*text_multiform_check</label> ";
$c->print_multiform_check();
}
$c->print_linkbar();
"</td></tr>";
print "<tr valign='top'><td style='width: 50%'>";
if (defined $c.subject_icon or $c.subject != "") { "<h3>$c.subject_icon $c.subject</h3>\n"; }
print "</td>";
print "<td style='width:50%;' align='right'><strong>(<a href='$c.permalink_url'>$*text_permalink</a>)</strong></td></tr>\n";
print "</table></td></tr></table></div>";
print "<div style='margin-left: 5px'>$c.text</div>\n";
print "<div style='margin-top: 3px; font-size: smaller'>";
if ($c.frozen) {
print "($*text_comment_frozen) ";
} else {
print "(<a href='$c.reply_url'>$*text_comment_reply</a>) ";
}
if ($c.parent_url != "") { "(<a href='$c.parent_url'>$*text_comment_parent</a>) "; }
if ($c.thread_url != "") { "(<a href='$c.thread_url'>$*text_comment_thread</a>) "; }
"</div>\n";
}
function ReplyPage::print_body ()
{
if (not $.entry.comments.enabled)
{
print "<h2>$*text_reply_nocomments_header</h2><p>$*text_reply_nocomments</p>";
return;
}
"<table border='0'><tr>";
"<td valign='top' width='100' align='center'>";
print defined $.replyto.userpic ? "<img src='$.replyto.userpic.url' alt='' /><br />" : "";
print defined $.replyto.poster ? $.replyto.poster->as_string() : "<i>(Anonymous)</i>";
"</td>";
"""<td valign="top"><font size="+1">"""; print $.replyto.time->date_format("med"); " "; print $.replyto.time->time_format();
if ($.replyto.subject) { " <span style='color: $*subject_color'>$.replyto.subject</span>"; }
"</font>";
print "<p>$.replyto.text</p>";
"<a href='$.entry.comments.read_url'>Read Comments</a>";
"""</td></tr>""";
"""<tr><td colspan="2"><p align="center"><img src="$*imguri/hr.gif" width="345" height="23" alt='' /></p>""";
"</td></tr></table>\n";
print "<h2>Reply</h2>";
$.form->print();
}
function print_theme_preview ()
{
"""
<div style="color: $*text_color; background-color: $*body_bgcolor">
<table width="70%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td colspan="2">
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="30"><img src="$*imguri/spacer.gif" width="30" height="10" alt='' /></td>
<td width="120" height="18" style="background-image: url($*imguri/tab.jpg)">&nbsp;&nbsp;
<a href="#" style="color: $*link_color">Tab</a>
</td>
<td width="120" height="18" style="background-image: url($*imguri/tab.jpg)">&nbsp;&nbsp;
<a href="#" style="color: $*link_color">Tab</a>
</td>
<td width="120" height="18" style="background-image: url($*imguri/tab.jpg)">&nbsp;&nbsp;
<a href="#" style="color: $*link_color">Tab</a>
</td>
<td width="120" height="18" style="background-image: url($*imguri/tab.jpg)">&nbsp;&nbsp;
<a href="#" style="color: $*link_color">Tab</a>
</td>
<td width="120" height="18" style="background-image: url($*imguri/tab.jpg)">&nbsp;&nbsp;
<a href="#" style="color: $*link_color">Tab</a>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td width="80" height="38" style="background-image: url($*imguri/top-left.jpg)">
<img src="$*imguri/spacer.gif" width="80" height="10" />
</td>
<td height="38" style="background-image: url($*imguri/middle.jpg)">
<img src="$*imguri/spacer.gif" width="10" height="10" />
</td>
<td width="10" height="38" style="background-image: url($*imguri/top-right.jpg)">
<img src="$*imguri/spacer.gif" width="10" height="10" />
</td>
</tr>
<tr>
<td width="80" height="38" style="background-image: url($*imguri/side-left.jpg)">
&nbsp;
</td>
<td width="100%" height="38" style="background-image: url($*imguri/middle.jpg)">
<h1>John Doe</h1>
<p align="center"><img src="$*imguri/hr.gif" width="345" height="23"></p>
<p align='center'>
<table border='0'><tr><td valign="top">
<h1>Dec. 16th, 2002 06:39 pm <span style='color: $*subject_color'>Neque porro quisquam est qui dolorem ipsum quia dolor sit amet&hellip;</span></h1>
<p>
Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit
Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit
Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit
Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit
Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit
Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit
</p>
<p><a href="#" style="color: $*vlink_color; font-weight: bold">2 Comments</a> | <a href="#" style="color: $*link_color">Leave a comment</a></p></td></tr>
<tr><td colspan="2"><p align="center"><img src="$*imguri/hr.gif" width="345" height="23"></p></td></tr>
</table>
</p>
</td>
<td width="8" height="38" style="background-image: url($*imguri/side-right.jpg)">
&nbsp;
</td>
</tr>
<tr>
<td width="80" height="12" style="background-image: url($*imguri/bottom-left.jpg)">
<img src="$*imguri/spacer.gif" width="70" height="12" alt='' />
</td>
<td height="12" style="background-image: url($*imguri/bottom-line.jpg)">
<img src="$*imguri/spacer.gif" width="10" height="12" alt='' />
</td>
<td width="8" height="12" style="background-image: url($*imguri/bottom-right.jpg)">
<img src="$*imguri/spacer.gif" width="8" height="12" alt='' />
</td>
</tr>
</table>
</div>
""";
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -0,0 +1,27 @@
# Do not modify this file. To set the S2-usage policy for your own
# LiveJournal-based site, create a file beside this one called
# policy-local.dat, based on instructions you find in this document.
# That file will override anything not set here.
#
# 'allow' means all users get access. 'deny' means only users with
# the 's2styles' capability get access.
#
# Default policy for layouts without their own policy section.
layer: *
use allow # can all users use it?
props allow # can all users modify any property of it?
# If you decide to make your site's default policy for * to be 'deny',
# then you'll have to selectively allow access to parts, like so:
#layer: generator/layout
# use allow
# props deny
# prop page_bgcolor allow
# Notes:
# -- allowing/denying access to properties is only valid on
# layout and core layers.
# -- you can't disallow use of a core layer, or i18n layers.
# -- for theme layers, you can only set the 'use' property.

View File

@@ -0,0 +1,11 @@
# -*-s2-*-
layerinfo type = "i18n";
layerinfo name = "English";
layerinfo redist_uniq = "punquin/en";
set text_meta_music = "music";
set text_meta_mood = "mood";
set text_post_comment = "Comment on this";
set text_post_comment_friends = "Comment on this";

View File

@@ -0,0 +1,699 @@
# -*-s2-*-
layerinfo type = "layout";
layerinfo name = "Punquin Elegant";
layerinfo redist_uniq = "punquin/layout";
layerinfo previews = "punquin/punquin.jpg";
# Colors
propgroup colors {
property Color body_bgcolor {
des = "Page background color";
s1color = "stronger_accent";
}
property Color main_bgcolor {
des = "Background of text areas";
s1color = "page_back";
}
property Color main_fgcolor {
des = "Text color";
s1color = "page_text";
}
property Color subject_color {
des = "Color of entry subjects";
s1color = "page_text_em";
}
property Color title_color {
des = "Color of headers and titles";
s1color = "page_text_title";
}
property Color border_color {
des = "Color of borders";
s1color = "weak_back";
}
property Color link_color {
des = "Link color";
s1color = "page_link";
}
property Color vlink_color {
des = "Visited link color";
s1color = "page_vlink";
}
property Color alink_color {
des = "Active link color";
s1color = "page_alink";
}
property Color comment_bar_one_bgcolor {
des = "Alternating background color for comment bars (one)";
}
property Color comment_bar_two_fgcolor {
des = "Text color on alternating comment bars (one)";
}
property Color comment_bar_two_bgcolor {
des = "Alternating background color for comment bars (two)";
}
property Color comment_bar_one_fgcolor {
des = "Text color on alternating comment bars (two)";
}
property Color comment_bar_screened_bgcolor {
des = "Background bar color for screened comments";
}
property Color comment_bar_screened_fgcolor {
des = "Text color on background bar for screened comments";
}
}
set body_bgcolor = "#6666cc";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set subject_color = "#c00000";
set title_color = "#8b1a1a";
set border_color = "#eeeeff";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#ff00c0";
set comment_bar_one_bgcolor = "#c0c0ff";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#eeeeff";
set comment_bar_two_fgcolor = "#000000";
set comment_bar_screened_bgcolor = "#dddddd";
set comment_bar_screened_fgcolor = "#000000";
propgroup presentation {
property bool show_recent_userpic {
des = "Show the userpic on the recent entries page?";
}
property string sidebar_position {
des = "Position of the sidebar relative to the main content";
values = "left|Left|right|Right";
}
property use font_base;
property use font_fallback;
property use page_recent_items;
property use page_friends_items;
property use use_shared_pic;
property use view_entry_disabled;
property bool show_entrynav_icons {
des = "Toggle to show the next, memory, edit, etc icons on the entry view page";
}
property string page_background_image {
des = "URL to an image to be used for the page background";
}
property use linklist_support;
property use external_stylesheet;
}
set font_base = "Verdana, Arial, Helvetica";
set font_fallback = "sans-serif";
set show_recent_userpic = false;
set sidebar_position = "left";
set page_recent_items = 20;
set page_friends_items = 20;
set view_entry_disabled = false;
set show_entrynav_icons = true;
set page_background_image = "";
set linklist_support = false;
propgroup text {
property string text_gotop {
des = "Link text to 'top of the page'";
noui = 1;
}
property use text_post_comment;
property use text_read_comments;
property use text_post_comment_friends;
property use text_read_comments_friends;
property use text_website_default_name;
}
set text_gotop = "Go to Top";
set tags_aware = true;
function print_stylesheet ()
{
var string font = "$*font_base, $*font_fallback";
print clean_url($*page_background_image) != "" ? "body { background-image: url($*page_background_image); }" : "";
print """
body {
background-color: $*body_bgcolor;
color: $*main_fgcolor;
font: normal normal 10pt $font;
}
a {
text-decoration: none;
color: $*link_color;
background: transparent;
font: normal normal 10pt $font;
}
a:visited {
color: $*vlink_color;
background: transparent;
}
a:active {
color: $*alink_color;
background: transparent;
}
#title {
font: normal bold 10pt $font;
color: $*title_color;
text-align: center;
}
.date {
font: normal bold 12pt $font;
color: $*title_color;
text-align: right;
}
.comments {
font: normal normal 8pt $font;
}
hr.separator {
color: $*border_color;
}
.siteplug {
font: normal normal 8pt $font;
}
#yearheader {
text-align: right;
color: $*title_color;
font: normal bold 12pt $font;
}
th.monthheader {
color: $*title_color;
}
th.daysheader {
color: $*subject_color;
}
/* Tables. Fun. */
table#main {
border: solid 0px $*body_bgcolor;
}
table.standard {
border: solid 5px $*border_color;
background-color: $*main_bgcolor;
color: $*main_fgcolor;
font: normal normal 10pt $font;
}
table.standard>td {
background-color: $*main_bgcolor;
color: $*main_fgcolor;
}
table.standard td {
font: normal normal 10pt $font;
}
""";
}
function Page::lay_sidebar_navigation () { }
function print_sidebar(Page p) {
var string title = $p->title();
var string userpic;
var Image up_img = $p.journal.default_pic;
if (defined $up_img) {
$userpic = """<p align="center"><img border="0" src="$up_img.url" height="$up_img.height" width="$up_img.width" alt="" /></p>""";
}
var string website_name = $p.journal.website_name ? $p.journal.website_name : $*text_website_default_name;
var string website;
if ($p.journal.website_url != "") {
$website = """&gt; <a href="$p.journal.website_url">$website_name</a><br />""";
}
var string links;
foreach var string v ($p.views_order) {
$links = "$links&gt; " + ($p.view == $v ?
lang_viewname($v) :
"<a href='$p.view_url{$v}'>"+lang_viewname($v)+"</a>") + "<br />\n";
}
# Table Wrapper
"<!-- Begin Main Sidebar -->\n<td valign='top' align='$*sidebar_position'>";
"<table width='150' class='standard' cellpadding='5' cellspacing='0'>\n";
"<tr valign='top'><td align='left'>";
# Title
"<div style='text-align:center'><span style='color: $*title_color'><strong>$title</strong></span></div>\n";
# Links
"<p>$links\n$website\n";
$p->lay_sidebar_navigation();
# Userpic
"</p>"; if($userpic != "") { "<div style='text-align:center'>$userpic</div>"; }
# Link List
if (size $p.linklist > 0 and $*linklist_support) {
if (not $p.linklist[0].is_heading) {
"<b>Links</b><br />";
}
$p->print_linklist();
}
# End Table
"</td></tr></table>\n<!-- End Main Sidebar -->";
}
function print_gotop (Page p)
{
"<td valign='bottom' align='$*sidebar_position'>\n<!-- Begin Small Sidebar -->\n";
"<table width='150' class='standard' cellpadding='5' cellspacing='0'>\n";
"<tr valign='top'><td align='left'>\n";
$p->lay_sidebar_navigation();
"<br />&gt; <a href='#top'>$*text_gotop</a><br>\n</td></tr></table>\n<!-- End Small Sidebar -->";
}
function Page::print ()
{
var string title = $this->title();
var string main_position = $*sidebar_position == "left" ? "right" : "left";
# Head
println "<html><head>";
if ($*external_stylesheet) {
println """<link rel="stylesheet" href="$.stylesheet_url" type="text/css" />""";
} else {
println """<style type="text/css">"""; print_stylesheet(); "</style>";
}
$this->print_head();
"<title>$title</title>\n</head>\n";
# Body
"<body>\n<a name='top'></a><div align='center'>\n";
# Table wrapper
"<table id='main' cellpadding='5' cellspacing='0' width='90%'>\n<tr>";
if ($*sidebar_position == "left") { print_sidebar($this); }
# Main content
"<td valign='top' align='$main_position' rowspan='2'>\n<!-- Begin Main -->\n";
"<table class='standard' width='100%' height='90%' cellpadding='5' cellspacing='0'><tr valign='top'><td>\n";
$this->print_body();
"</td></tr></table>\n<!-- End Main -->\n</td>";
if ($*sidebar_position == "right") { print_sidebar($this); }
# Go to top
"</tr><tr>";
print_gotop($this);
"</tr><tr>";
# Plug the site!
"<td colspan='2' align='$main_position'>\n";
"<a href='$*SITEROOT/'>$*SITENAME</a></td>\n";
"</tr></table></div></body></html>";
}
function print_entry (Page p, Entry e, Color bgcolor, Color fgcolor, bool hide_text)
{
var string time = $e.time->time_format();
if ($e.new_day or $p.view == "entry") {
"<p class='date'>"; print $e.time->date_format("%%month%% %%dayord%%, %%yyyy%%"); "</p>";
"<hr class='separator' />";
}
if ($p.view == "entry" and $*show_entrynav_icons)
{
print "<div style='text-align: center'>";
$e->print_linkbar();
print "</div>";
}
"<table border='0' cellpadding='2' cellspacing='0'><tr>";
if ($p.view == "friends" or
$e.poster.username != $e.journal.username or
$*show_recent_userpic == true)
{
# Lots of muddled logic. Yay.
"""<td valign=top align="middle" style="background-color: $bgcolor" width="100">""";
if ($p.view == "friends") {
"""<a href='""" + $e.journal->base_url() + """/' style="color: $fgcolor; font-weight: bold">$e.journal.username</a><br />""";
}
if ($e.poster.username != $e.journal.username) {
if ($p.view == "friends") {
"""[<a href='""" + $e.poster->base_url() + """/' style="color: $fgcolor">$e.poster.username</a>]<br />""";
} else {
"""<a href='""" + $e.poster->base_url() + """/' style="color: $fgcolor; font-weight: bold">$e.poster.username</a><br />""";
}
}
if (defined $e.userpic) {
if (($*show_recent_userpic == false) and
($p.view != "friends") and
($p.journal_type != "C") ) { }
else { """<img border="0" src="$e.userpic.url" width="$e.userpic.width" height="$e.userpic.height" alt="" />""";
}
}
"</td>";
}
"<td valign='top'><strong>$time";
if ($e.subject) { " - <span style='color: $*subject_color'>$e.subject</span>"; }
if ($e.security) {
" "; $e.security_icon->print();
}
"</strong><br />";
if (not $hide_text) {
print $e.text; "<br />";
if (size $e.metadata) {
foreach var string k ($e.metadata) {
var string key = $k;
var string val = $e.metadata{$k};
if ($k == "mood") {
$key = $*text_meta_mood;
} elseif ( $k == "music" ) {
$key = $*text_meta_music;
}
if ($k == "mood" and defined $e.mood_icon) {
var Image i = $e.mood_icon;
$val = "<img src='$i.url' width='$i.width' height='$i.height' align='absmiddle' alt='[mood icon]' /> $val";
}
"<strong>$key:</strong> $val<br />";
}
}
if ($e.tags) {
var int tcount = 0;
"<div class='ljtags'><strong>Tags:</strong> ";
foreach var Tag t ($e.tags) {
"""<a rel="tag" href="$t.url">$t.name</a>""";
$tcount++;
if ($tcount != size $e.tags) { ", "; }
}
"</div>";
}
}
"</td></tr></table>";
$e.comments->print();
}
function Page::print_entry (Entry e)
{
print_entry($this, $e, null Color, null Color, false);
}
function FriendsPage::print_entry (Entry e) {
var Friend f = $.friends{$e.journal.username};
print_entry($this, $e, $f.bgcolor, $f.fgcolor, false);
}
function RecentPage::print_body {
foreach var Entry e ($.entries) {
$this->print_entry($e);
}
}
function FriendsPage::print_body {
foreach var Entry e ($.entries) {
$this->print_entry($e);
}
}
function RecentPage::lay_sidebar_navigation () {
var int total = size $.entries;
var string nav = "";
if ($.nav.backward_url != "") {
$nav = """&gt; <a href="$.nav.backward_url">previous $total entries</a>""";
}
if ($.nav.forward_url != "" and $.nav.backward_url != "") {
$nav = "$nav<br />";
}
if ($.nav.forward_url != "") {
$nav = """${nav}&gt; <a href="$.nav.forward_url">next $total entries</a>""";
}
print $nav;
}
function CommentInfo::print ()
{
if (not $.enabled) {
"<p align='right' class='comments'>&nbsp;</p>";
return;
}
"<p align='right' class='comments'>(";
if ($.count > 0 or $.screened) {
$this->print_readlink();
"&nbsp;|&nbsp;";
}
$this->print_postlink();
")</p>";
}
function YearPage::print_body {
"<p id='yearheader'>$.year</p>\n";
foreach var YearMonth m ($.months) {
$this->print_month($m);
}
}
function YearPage::print_year_links ()
{
foreach var YearYear y ($.years) {
if ($y.displayed) {
"&gt; $y.year<br />";
} else {
"&gt; <a href=\"$y.url\">$y.year</a><br />";
}
}
}
function YearPage::lay_sidebar_navigation ()
{
$this->print_year_links();
}
function YearPage::print_month(YearMonth m)
{
if (not $m.has_entries) { return; }
# Table Wrapper
"<center><p><table border='1' cellpadding='4' width='80%'>\n";
# Month Header
"<tr align='center'><th colspan='7' class='monthheader'>\n";
print $m->month_format();
"</th></tr>\n";
# Weekdays Header
"<tr align='center'>\n";
foreach var int d (weekdays()) {
"<th class='daysheader'>"+$*lang_dayname_short[$d]+"</th>\n";
}
"</tr>\n";
# Weeks
foreach var YearWeek w ($m.weeks) {
$w->print();
}
# Footer
"<tr><td colspan='7'><div style='text-align: center'><a href='$m.url'>view subjects</a></div></td></tr>\n";
# End Table
"</table></p></center>\n";
}
function YearWeek::print () {
"<tr>";
if ($.pre_empty) { "<td colspan='$.pre_empty'>&nbsp;</td>"; }
foreach var YearDay d ($.days) {
"<td valign='top'><strong>$d.day</strong><div style='text-align: center'>";
if ($d.num_entries) {
"<a href='$d.url'>$d.num_entries</a>";
} else {
"&nbsp;";
}
"</div></td>\n";
}
if ($.post_empty) { "<td colspan='$.post_empty'>&nbsp;</td>"; }
"</tr>";
}
function DayPage::print_body() {
if (not $.has_entries) {
"<table width='100%'><tr><td><p class='date'>\n";
print $.date->date_format("%%month%% %%dayord%%, %%yyyy%%");
"</p><hr class='separator' width='100%' /></td></tr>";
"<tr><td><blockquote align='center'>"; print ehtml($*text_noentries_day); "</blockquote></td></tr></table>";
} else {
foreach var Entry e ($.entries) {
$this->print_entry($e);
}
}
var string tprev = ehtml($*text_day_prev);
var string tnext = ehtml($*text_day_next);
"<hr class='separator' width='100%' />\n";
"<table width='100%'><tr align='middle'>\n";
"<td width='33%' align='left'><a href='$.prev_url'>$tprev</a></td>\n";
"<td align='center' width='33%'>[<a href='"; print $this.journal->base_url(); "/calendar'>$*text_view_archive</a>]</td>\n";
"<td width='33%' align='right'><a href='$.next_url'>$tnext</a></td>\n";
"</tr></table>";
}
function EntryPage::print_body ()
{
set_handler("unscreen_comment_#", [
[ "style_bgcolor", "cmtbar#", "$*comment_bar_one_bgcolor", ],
[ "style_color", "cmtbar#", "$*comment_bar_one_fgcolor", ],
]);
set_handler("screen_comment_#", [
[ "style_bgcolor", "cmtbar#", "$*comment_bar_screened_bgcolor", ],
[ "style_color", "cmtbar#", "$*comment_bar_screened_fgcolor", ],
]);
print_entry($this, $.entry, null Color, null Color, $.viewing_thread);
if ($.entry.comments.enabled and $.comment_pages.total_subitems > 0)
{
$this->print_multiform_start();
print "<h2 class='date'>Comments:</h2>";
"<hr class='separator' />";
if ($.comment_pages.total_subitems > 0) {
$.comment_pages->print();
$this->print_comments($.comments);
}
if ($this.multiform_on) {
print "<h2 class='date'>Mass Action:</h2>";
"<hr class='separator' />";
$this->print_multiform_actionline();
$this->print_multiform_end();
}
}
}
function EntryPage::print_comment (Comment c) {
var Color background; var Color color;
if ($c.screened) {
$background = $*comment_bar_screened_bgcolor;
$color = $*comment_bar_screened_fgcolor;
} elseif ($c.depth % 2) {
$background = $*comment_bar_one_bgcolor;
$color = $*comment_bar_one_fgcolor;
} else {
$background = $*comment_bar_two_bgcolor;
$color = $*comment_bar_two_fgcolor;
}
var string poster = defined $c.poster ? $c.poster->as_string() : "<i>(Anonymous)</i>";
var string sub_icon;
if (defined $c.subject_icon) {
$sub_icon = $c.subject_icon->as_string();
}
"<a name='$c.anchor'></a><div id='cmtbar$c.talkid' style='background-color: $background; color: $color; margin-top: 10px; width: 100%'>";
"<table cellpadding='2' cellspacing='0' summary='0' style='width: 100%'><tr valign='top'>";
if (defined $c.userpic and $*comment_userpic_style != "off") {
var int w = $c.userpic.width;
var int h = $c.userpic.height;
# WARNING: this will later be done by the system (it'll be a
# constructional property), so don't copy this hack into your
# layout layers or you'll be messed up later.
if ($*comment_userpic_style == "small") {
$w = $w / 2;
$h = $h / 2;
}
print "<td style='width: 102px'><img src='$c.userpic.url' width='$w' height='$h' alt='[User Picture]' /></td>";
}
"<td style='width: 100%'><table style='width: 100%'><tr>";
### From, date, etc
"<td align='left' style='width: 50%'>";
print "<table>";
print "<tr><th align='right' style='font-size: .9em'>From:</th><td>$poster</td></tr>\n";
print "<tr><th align='right' style='font-size: .9em'>Date:</th><td style='white-space: nowrap'>";
print $c.time->date_format("long") + " - " + $c.time->time_format() + "</td></tr>";
if ($c.metadata{"poster_ip"}) { print "<tr><th align='right' style='font-size: .9em'>IP Address:</th><td>(" + $c.metadata{"poster_ip"} + ")</td></tr>"; }
"</table></td>";
### Gadgets
"<td align='right' style='width: 50%'>";
if ($this.multiform_on) {
" <label for='ljcomsel_$c.talkid'>$*text_multiform_check</label>";
$c->print_multiform_check();
}
$c->print_linkbar();
"</td></tr>";
### Subject / icon
print "<tr valign='top'><td style='width: 50%'>";
print (defined $c.subject_icon or $c.subject != "") ? "<h3>$c.subject_icon $c.subject</h3>" : "";
print "</td>";
### Permalink
print "<td style='width: 50%' align='right'><strong>(<a href='$c.permalink_url'>Link</a>)</strong></td></tr>";
print "</table></td></tr></table></div>";
print "<div style='margin-left: 5px'>$c.text</div>";
print "<div style='margin-top: 3px; font-size: smaller'>";
if ($c.frozen) {
print "(Replies frozen)";
} else {
print "(<a href='$c.reply_url'>Reply to this</a>) ";
}
if ($c.parent_url != "") { "(<a href='$c.parent_url'>Parent</a>) "; }
if ($c.thread_url != "") { "(<a href='$c.thread_url'>Thread</a>) "; }
"</div>";
}
function ReplyPage::print_body() {
if (not $.entry.comments.enabled)
{
"<h2 class='date'>$*text_reply_nocomments_header</h2>";
"<hr class='separator' />";
"<p>$*text_reply_nocomments</p>";
return;
}
"<p class='date'>"; print $.replyto.time->date_format("%%month%% %%dayord%%, %%yyyy%%"); "</p>";
"<hr class='separator' />";
"<table border='0' cellpadding='2' cellspacing='0'><tr>";
"""<td valign=top align="middle" width="100">""";
print defined $.replyto.poster ? $.replyto.poster->as_string() : "<i>(Anonymous)</i>";
if (defined $.replyto.userpic) {
print """<img border="0" src="$.replyto.userpic.url" width="$.replyto.userpic.width" height="$.replyto.userpic.height" alt="" />""";
}
"</td>";
"<td valign='top'><strong>"; print $.replyto.time->time_format();
if ($.replyto.subject) { " - <span style='color: $*subject_color'>$.replyto.subject</span>"; }
"</strong><br />";
print $.replyto.text; "<br />";
"</td></tr></table>";
"<p align='right' class='comments'><a href='$.entry.comments.read_url'>Read Comments</a></p>";
"<h2 class='date'>Reply</h2>";
"<hr class='separator' />";
$.form->print();
}
function print_theme_preview ()
{
"""
<table width="100%" style="background-color: $*body_bgcolor; border: solid 1px #000000"><tr><td style="color:$*main_fgcolor">
<table bgcolor="$*border_color" border="0" cellpadding="5" cellspacing="0" width="60%" align="center">
<tr><td valign="center" align="center">
<table width="100%" height=90% bgcolor="$*main_bgcolor" border="0" cellpadding="5" cellspacing="0">
<tr valign="top"><td>
<p align="right"><font color="$*title_color" face="verdana,arial,helvetica" size="3">
<strong>December 18th, 2002</strong></font><hr noshade color="$*border_color" size="1" width="100%" />
</p>
<font face="verdana,arial,helvetica" size="2">
<b>01:22 am - <font color="$*subject_color">Test</font></b><font face="verdana,arial,helvetica" size="2"><br />
Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit.
Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit.</font>
<p align="right">(<a style="color: $*link_color" href="#">Read # Comments</a> | <a style="color: $*vlink_color" href="#">Leave a comment</a>)</p>
</td></tr>
</table>
</td></tr>
</table>
</td></tr></table>
""";
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,450 @@
#NEWLAYER: punquin/bw
layerinfo type = "theme";
layerinfo name = "Black on White";
layerinfo redist_uniq = "punquin/bw";
set body_bgcolor = "#333333";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set subject_color = "#c00000";
set title_color = "#336699";
set border_color = "#dddddd";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#ff00c0";
set comment_bar_one_bgcolor = "#dddddd";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#aaaaaa";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: punquin/autumn
layerinfo type = theme;
layerinfo name = "Autumn";
layerinfo redist_uniq = "punquin/autumn";
layerinfo author = "pumpsnail";
set body_bgcolor = "#660033";
set main_bgcolor = "#990022";
set main_fgcolor = "#ffffff";
set subject_color = "#ffffff";
set title_color = "#ffffff";
set border_color = "#fcc303";
set link_color = "#cc6600";
set vlink_color = "#cc99cc";
set alink_color = "#ffcc33";
set comment_bar_one_bgcolor = "#660033";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#993366";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: punquin/greyslate
layerinfo type = theme;
layerinfo name = "Grey Slate Rain";
layerinfo redist_uniq = "punquin/greyslate";
set body_bgcolor = "#67698f";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set subject_color = "#000000";
set title_color = "#336699";
set border_color = "#dddddd";
set link_color = "#8e80f8";
set vlink_color = "#c780f8";
set alink_color = "#f880dd";
set comment_bar_one_bgcolor = "#dddddd";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#aaaaaa";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: punquin/minimal
layerinfo type = theme;
layerinfo name = "Minimalist";
layerinfo redist_uniq = "punquin/minimal";
set body_bgcolor = "#ffffff";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#333333";
set subject_color = "#333333";
set title_color = "#333333";
set border_color = "#aaaaaa";
set link_color = "#8e80f8";
set vlink_color = "#c780f8";
set alink_color = "#f880dd";
set comment_bar_one_bgcolor = "#dddddd";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#aaaaaa";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: punquin/jewel
layerinfo type = theme;
layerinfo name = "Jewel Toned";
layerinfo redist_uniq = "punquin/jewel";
set body_bgcolor = "#950875";
set main_bgcolor = "#f3a8e2";
set main_fgcolor = "#000000";
set subject_color = "#c00000";
set title_color = "#336699";
set border_color = "#dddddd";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#ff00c0";
set comment_bar_one_bgcolor = "#950875";
set comment_bar_one_fgcolor = "#f3a8e2";
set comment_bar_two_bgcolor = "#b70875";
set comment_bar_two_fgcolor = "#f3a8e2";
#NEWLAYER: punquin/bold
layerinfo type = theme;
layerinfo name = "Bold";
layerinfo redist_uniq = "punquin/bold";
set body_bgcolor = "#2501da";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set subject_color = "#c00453";
set title_color = "#f50930";
set border_color = "#000000";
set link_color = "#5f5cd5";
set vlink_color = "#2a2ab2";
set alink_color = "#4a92eb";
set comment_bar_one_bgcolor = "#2501da";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#2501fc";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: punquin/shrinkvio
layerinfo type = theme;
layerinfo name = "Shrinking Violet";
layerinfo redist_uniq = "punquin/shrinkvio";
set body_bgcolor = "#ad22e7";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set border_color = "#381a45";
set title_color = "#5d0383";
set subject_color = "#d9a1f1";
set link_color = "#2e053f";
set vlink_color = "#611627";
set alink_color = "#ff00c0";
set comment_bar_one_bgcolor = "#5d0383";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#d9a1f1";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: punquin/pistmint
layerinfo type = theme;
layerinfo name = "Pistachio Mint";
layerinfo redist_uniq = "punquin/pistmint";
set body_bgcolor = "#133422";
set main_bgcolor = "#a7c4b4";
set main_fgcolor = "#000000";
set border_color = "#096d36";
set title_color = "#096d36";
set subject_color = "#096d36";
set link_color = "#8afabc";
set vlink_color = "#1da65a";
set alink_color = "#f9f5f5";
set comment_bar_one_bgcolor = "#096d36";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#093d36";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: punquin/mexicanfood
layerinfo type = theme;
layerinfo name = "Mexican Food";
layerinfo redist_uniq = "punquin/mexicanfood";
set body_bgcolor = "#ff0000";
set main_bgcolor = "#f8ff3e";
set main_fgcolor = "#f15601";
set border_color = "#f50701";
set title_color = "#bdbf3e";
set subject_color = "#f9ff9d";
set link_color = "#f49e08";
set vlink_color = "#b05403";
set alink_color = "#ff7405";
set comment_bar_one_bgcolor = "#bdbf3e";
set comment_bar_one_fgcolor = "#ff0000";
set comment_bar_two_bgcolor = "#e15a18";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: punquin/ashfire
layerinfo type = theme;
layerinfo name = "Ash and Fire";
layerinfo redist_uniq = "punquin/ashfire";
set body_bgcolor = "#b5b5b5";
set main_bgcolor = "#ffb6af";
set main_fgcolor = "#000000";
set border_color = "#d90308";
set title_color = "#e75454";
set subject_color = "#ff1106";
set link_color = "#f70208";
set vlink_color = "#b0161d";
set alink_color = "#d70106";
set comment_bar_one_bgcolor = "#e75454";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#f06c88";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: punquin/desktop
layerinfo type = theme;
layerinfo name = "Classic Desktop";
layerinfo redist_uniq = "punquin/desktop";
set body_bgcolor = "#00545c";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set border_color = "#000000";
set title_color = "#ff7b05";
set subject_color = "#ff7b05";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#5a76ff";
set comment_bar_one_bgcolor = "#ff7b05";
set comment_bar_one_fgcolor = "#ffeddd";
set comment_bar_two_bgcolor = "#ffeddd";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: punquin/satinhandshake
layerinfo type = theme;
layerinfo name = "Satin Handshake";
layerinfo redist_uniq = "punquin/satinhandshake";
set body_bgcolor = "#480c0c";
set main_bgcolor = "#d06464";
set main_fgcolor = "#00001d";
set border_color = "#000000";
set title_color = "#aaaaaa";
set subject_color = "#9d0404";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#ff00c0";
set comment_bar_one_bgcolor = "#aaaaaa";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#9d0404";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: punquin/deepmelodrama
layerinfo type = theme;
layerinfo name = "Deep MeloDrama";
layerinfo redist_uniq = "punquin/deepmelodrama";
set body_bgcolor = "#872d89";
set main_bgcolor = "#719cff";
set main_fgcolor = "#8e48b2";
set border_color = "#8e48b2";
set title_color = "#3794b3";
set subject_color = "#8e48b2";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#dfd3ff";
set comment_bar_one_bgcolor = "#3794b3";
set comment_bar_one_fgcolor = "#84b8e7";
set comment_bar_two_bgcolor = "#65b2c1";
set comment_bar_two_fgcolor = "#f5d3ff";
#NEWLAYER: punquin/everwhite
layerinfo type = theme;
layerinfo name = "Everwhite";
layerinfo redist_uniq = "punquin/everwhite";
set body_bgcolor = "#ffffff";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set border_color = "#000000";
set title_color = "#ffffff";
set subject_color = "#ff0000";
set link_color = "#e60000";
set vlink_color = "#c10602";
set alink_color = "#ff0600";
set comment_bar_one_bgcolor = "#dddddd";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#aaaaaa";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: punquin/everblue
layerinfo type = theme;
layerinfo name = "Everblue with Greys";
layerinfo redist_uniq = "punquin/everblue";
set body_bgcolor = "#0f0c6d";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set border_color = "#000000";
set title_color = "#000000";
set subject_color = "#000000";
set link_color = "#2f00f2";
set vlink_color = "#060667";
set alink_color = "#6691ff";
set comment_bar_one_bgcolor = "#000000";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#aaaaaa";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: punquin/brownleather
layerinfo type = theme;
layerinfo name = "Brown Leather Coat";
layerinfo redist_uniq = "punquin/brownleather";
set body_bgcolor = "#d2b48c";
set main_bgcolor = "#ffebcd";
set main_fgcolor = "#8b4513";
set border_color = "#000000";
set title_color = "#d48014";
set subject_color = "#d48014";
set link_color = "#000050";
set vlink_color = "#867a55";
set alink_color = "#fffab3";
set comment_bar_one_bgcolor = "#d48014";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#ffe1a1";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: punquin/bruise
layerinfo type = theme;
layerinfo name = "Bruise";
layerinfo redist_uniq = "punquin/bruise";
set body_bgcolor = "#000000";
set main_bgcolor = "#bcbcbc";
set main_fgcolor = "#000000";
set border_color = "#000000";
set title_color = "#1114a0";
set subject_color = "#1114a0";
set link_color = "#0000cc";
set vlink_color = "#000088";
set alink_color = "#0000ff";
set comment_bar_one_bgcolor = "#1114a0";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#21c2f1";
set comment_bar_two_fgcolor = "#0000ff";
#NEWLAYER: punquin/ranchhand
layerinfo type = theme;
layerinfo name = "Ranch Hand";
layerinfo redist_uniq = "punquin/ranchhand";
set body_bgcolor = "#2999c2";
set main_bgcolor = "#cfe0ff";
set main_fgcolor = "#000000";
set border_color = "#060667";
set title_color = "#54442c";
set subject_color = "#9d995d";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#6a20ff";
set comment_bar_one_bgcolor = "#54442c";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#704400";
set comment_bar_two_fgcolor = "#bababa";
#NEWLAYER: punquin/victim
layerinfo type = theme;
layerinfo name = "Victim";
layerinfo redist_uniq = "punquin/victim";
set body_bgcolor = "#2cd0ff";
set main_bgcolor = "#505050";
set main_fgcolor = "#ffffff";
set border_color = "#000000";
set title_color = "#166bac";
set subject_color = "#26b6ff";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#ff00c0";
set comment_bar_one_bgcolor = "#166bac";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#353535";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: punquin/forest
layerinfo type = theme;
layerinfo name = "Forest";
layerinfo redist_uniq = "punquin/forest";
set body_bgcolor = "#778e64";
set main_bgcolor = "#9b9ba5";
set main_fgcolor = "#000000";
set border_color = "#ffffff";
set title_color = "#72784c";
set subject_color = "#a0ac62";
set link_color = "#3811e1";
set vlink_color = "#310cbb";
set alink_color = "#4e7bef";
set comment_bar_one_bgcolor = "#72784c";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#73777a";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: punquin/drone
layerinfo type = theme;
layerinfo name = "Drone";
layerinfo redist_uniq = "punquin/drone";
set body_bgcolor = "#395f82";
set main_bgcolor = "#f9fcfe";
set main_fgcolor = "#000000";
set border_color = "#000000";
set title_color = "#904094";
set subject_color = "#ff93ff";
set link_color = "#395f82";
set vlink_color = "#395f82";
set alink_color = "#5266ce";
set comment_bar_one_bgcolor = "#904094";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#eeeeff";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: punquin/lowercurtain
layerinfo type = theme;
layerinfo name = "Lower the Curtain";
layerinfo redist_uniq = "punquin/lowercurtain";
set body_bgcolor = "#000000";
set main_bgcolor = "#6b6b6b";
set main_fgcolor = "#ffffff";
set border_color = "#ffffff";
set title_color = "#363636";
set subject_color = "#363636";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#3314ba";
set comment_bar_one_bgcolor = "#363636";
set comment_bar_one_fgcolor = "#f0f5fb";
set comment_bar_two_bgcolor = "#c5c8ca";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: punquin/sunny
layerinfo type = theme;
layerinfo name = "Sunny Day";
layerinfo redist_uniq = "punquin/sunny";
set body_bgcolor = "#55e0f9";
set main_bgcolor = "#e38202";
set main_fgcolor = "#ffffff";
set border_color = "#000000";
set title_color = "#e38202";
set subject_color = "#efe052";
set link_color = "#df0d12";
set vlink_color = "#ac1b25";
set alink_color = "#fe3b3b";
set comment_bar_one_bgcolor = "#e38202";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#ffba03";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: punquin/valentine
layerinfo type = theme;
layerinfo name = "Be Mine";
layerinfo redist_uniq = "punquin/valentine";
set body_bgcolor = "#6f104a";
set main_bgcolor = "#f2bce9";
set main_fgcolor = "#000000";
set border_color = "#ff24ab";
set title_color = "#ff37ff";
set subject_color = "#ae1774";
set link_color = "#ffffff";
set vlink_color = "#a51014";
set alink_color = "#ed8188";
set comment_bar_one_bgcolor = "#ff37ff";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#df2096";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: punquin/stripes
layerinfo type = theme;
layerinfo name = "Stripes";
layerinfo redist_uniq = "punquin/stripes";
set body_bgcolor = "#ffffff";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set border_color = "#ff0000";
set title_color = "#e7212a";
set subject_color = "#ffffff";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#ffafc1";
set comment_bar_one_bgcolor = "#e7212a";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#ffcfdc";
set comment_bar_two_fgcolor = "#000000";

View File

@@ -0,0 +1,850 @@
# -*-s2-*-
layerinfo type = "layout";
layerinfo name = "A Sturdy Gesture";
layerinfo lang = "en";
layerinfo author = "Martin Atkins";
layerinfo author_email = "mart@livejournal.com";
layerinfo redist_uniq = "sturdygesture/layout";
layerinfo previews = "sturdygesture/sturdygesture.jpg";
propgroup colors {
property Color clr_page_back { des = "Page background"; }
set clr_page_back = "#ffffff";
property Color clr_page_text { des = "Box border color"; }
set clr_page_text = "#000000";
property Color clr_box_text { des = "Box content color"; }
set clr_boxhead_text = "#ffffff";
property Color clr_box_back { des = "Box background color"; }
set clr_boxhead_back = "#000000";
property Color clr_boxhead_text { des = "Box heading text color"; }
set clr_boxhead_text = "#ffffff";
property Color clr_boxhead_back { des = "Box heading background color"; }
set clr_boxhead_back = "#000000";
property Color clr_page_link { des = "Link color"; }
set clr_page_link = "#0000ff";
property Color clr_page_vlink { des = "Visited link color"; }
set clr_page_vlink = "#0000ff";
}
propgroup fonts {
property use font_base;
property use font_fallback;
}
propgroup presentation {
property string opt_navbar_pos {
des = "Navigation Bar Location";
values = "left|Left|right|Right";
}
set opt_navbar_pos = "left";
property bool opt_friends_colors {
des = "Use friend colors on friends page";
note = "If this option is on, the titles of friends' entries will use the colors you have selected for each friend.";
}
set opt_friends_colors = true;
property bool opt_always_userpic {
des = "Always show userpics";
note = "With this off, userpics are only shown in the friends view.";
}
set opt_always_userpic = false;
## These have no UI, but S2 generates an empty settings page if they aren't in a group
property string text_page_prev {
des = "Text used to link to the previous page";
noui = 1;
}
property string text_page_next {
des = "Text used to link to the next page";
noui = 1;
}
set text_page_prev = "Previous Page";
set text_page_next = "Next Page";
property string{} text_entry_links {
des = "Captions for Entry Action links";
noui = 1;
}
set text_entry_links = {"edit_entry" => "Edit Entry",
"edit_tags" => "Edit Tags",
"mem_add" => "Add As Memory",
"tell_friend" => "Tell a Friend",
"nav_prev" => "Previous Entry",
"nav_next" => "Next Entry"};
property string{} text_comment_links {
des = "Captions for Comment Action links";
noui = 1;
}
set text_comment_links = {"delete_comment" => "Delete",
"screen_comment" => "Screen",
"unscreen_comment" => "Unscreen",
"freeze_thread" => "Freeze",
"unfreeze_thread" => "Unfreeze", };
property use use_shared_pic;
property use linklist_support;
property use external_stylesheet;
}
set tags_aware = true;
function navheading(RecentNav nav, int entries) : string
"i18n layers should override this to translate the skiplink box heading." {
return ($nav.skip == 0 ? $entries+" most recent" : "skipped back "+$nav.skip);
}
function navlinktext(RecentNav nav, bool next) : string
"i18n layers should override this to translate the skiplinks. If \$next is false, output 'Previous X', else 'Next X'." {
return ($next ? "Next "+$nav.forward_count : "Previous "+$nav.backward_count);
}
function print_stylesheet() {
"""
body {
background: $*clr_page_back;
color: $*clr_page_text;
""";
# Ugliness
if ($*font_base != "" or $*font_fallback != "none") {
"font-family: ";
if ($*font_base != "") {
"\"$*font_base\"";
if ($*font_fallback != "none") {
", ";
}
}
if ($*font_fallback != "none") {
print $*font_fallback;
}
";";
}
"""
}
a {
color: $*clr_page_link;
}
a:visited {
color: $*clr_page_vlink;
}
img {
border: 0;
}
.box {
border: 1px solid $*clr_page_text;
margin: 1em;
background: $*clr_box_back;
color: $*clr_box_text;
}
#navbar {
width: 25%;
}
#body {
width: 75%;
}
#navbar .box h1, .box h2, .box h3 {
font-size: 1em;
background: $*clr_boxhead_back;
color: $*clr_boxhead_text;
padding: 3px;
margin: 0;
}
#navbar .box h1 {
text-align: center;
}
.box h1 a, .box h2 a, .box h3 a {
color: $*clr_boxhead_text;
background: $*clr_boxhead_back;
}
#navbar .box div.userpic {
margin: 1em;
text-align: center;
}
#navbar p {
margin-left: 1em;
margin-right: 1em;
margin-bottom: 0;
}
#navbar ul, #skipbar ul {
list-style: none;
padding: 0;
margin: 0.5em;
}
#navbar ul li.active, #skipbar ul li.active {
font-weight: bold;
}
.box .entry {
margin: 1em;
}
.box .talklinks {
margin: 1em;
text-align: right;
clear: both;
}
.box .talklinks .permalink {
float: left;
}
.box .minicomment {
clear: both;
}
body.day #body h1 {
font-size: 1.1em;
font-weight: bold;
}
table.box, table.box td, table.box th {
border: 1px solid #000000;
}
.metadata {
margin-top: 1em;
}
form#postform table {
background: $*clr_box_back;
color: $*clr_box_text;
}
""";
}
function Page::lay_page_nav() {
}
function RecentPage::lay_page_nav() {
if ($.nav.backward_url == "" and $.nav.forward_url == "") {
return;
}
println "<div class=\"box\">";
println "<h2>"+navheading($.nav,size $.entries)+"</h2>\n<ul>";
if ($.nav.backward_url != "") {
println "<li><a href=\""+$.nav.backward_url+"\">"+
navlinktext($.nav,false)+"</a></li>";
}
if ($.nav.forward_url != "") {
println "<li><a href=\""+$.nav.forward_url+"\">"+
navlinktext($.nav,true)+"</a></li>";
}
println "</ul>\n";
println "</div>\n";
}
function DayPage::lay_page_nav() {
println "<div class=\"box\"><ul>";
println "<li><a href=\"$.prev_url\">"+$.prev_date->date_format("med")+"</a></li>";
println "<li><a href=\"$.next_url\">"+$.next_date->date_format("med")+"</a></li>";
println "</ul></div>";
}
function YearPage::lay_page_nav() {
println "<div class=\"box\"><ul>";
foreach var YearYear y ($.years) {
if ($y.displayed) {
println "<li class=\"active\">$y.year</li>";
} else {
println "<li><a href=\"$y.url\">$y.year</a></li>";
}
}
println "</ul></div>";
}
function MonthPage::lay_page_nav() {
println "<div class=\"box\"><ul>";
if ($.prev_url != "") {
"""<li><a href="$.prev_url">"""+$.prev_date->date_format($*lang_fmt_month_long)+"""</a></li>""";
}
if ($.next_url != "") {
"""<li><a href="$.next_url">"""+$.next_date->date_format($*lang_fmt_month_long)+"""</a></li>""";
}
"</ul>";
"<form method='post' action='$.redir.url'><center>";
$.redir->print_hiddens();
if (size $.months > 1) {
"<select name='redir_key'>\n";
foreach var MonthEntryInfo mei ($.months) {
var string sel;
if ($mei.date.year == $.date.year and $mei.date.month == $.date.month) {
$sel = " selected='selected'";
}
"<option value='$mei.redir_key'$sel>" + $mei.date->date_format($*lang_fmt_month_long) + "</option>";
}
"</select>\n<input type='submit' value='View' />";
}
"</center></form>\n</div>\n";
}
function EntryPage::lay_page_nav() {
println "<div class=\"box\">";
if (size $.comments > 0 and not $.comment_pages.all_subitems_displayed) {
"<h2>"+lang_page_of_pages($.comment_pages.current, $.comment_pages.total)+"</h2>\n";
}
print "<ul>\n";
if ($.entry.comments.enabled) {
"<li>"; $.entry.comments->print_postlink(); "</li>\n";
}
if ($.comment_pages.url_prev != "") {
"""<li><a href="$.comment_pages.url_prev">$*text_page_prev</a></li>\n""";
}
if ($.comment_pages.url_next != "") {
"""<li><a href="$.comment_pages.url_next">$*text_page_next</a></li>\n""";
}
println "<li>&nbsp;</li>";
var Link l = new Link;
$l = $.entry->get_link("nav_next");
println """<li><a href="$l.url">$*text_entry_links{"nav_next"}</a></li>""";
foreach var string ls ($.entry.link_keyseq) {
$l = $.entry->get_link($ls);
if (defined $l) {
println """<li><a href="$l.url">$*text_entry_links{$ls}</a></li>""";
}
}
$l = $.entry->get_link("nav_prev");
println """<li><a href="$l.url">$*text_entry_links{"nav_prev"}</a></li>""";
println "</ul></div>";
}
function Page::lay_show_firstnav() : bool {
return false;
}
function RecentPage::lay_show_firstnav() : bool {
return ((size $.entries) > 5);
}
function DayPage::lay_show_firstnav() : bool {
return ((size $.entries) > 5);
}
function YearPage::lay_show_firstnav() : bool {
return true;
}
function MonthPage::lay_show_firstnav() : bool {
return true;
}
function EntryPage::lay_show_firstnav() : bool {
return ((size $.comments) > 5);
}
function EntryPage::lay_show_firstnav() : bool {
return false;
}
function Page::lay_navbar() {
var string userpic;
var Image up_img = $.journal.default_pic;
if (defined $up_img) {
$userpic = """<div class="userpic">
<img src="$up_img.url"
class="userpic" alt=""
height="$up_img.height" width="$up_img.width" />
</div>
""";
}
var string website;
if ($.journal.website_url != "") {
$website = """<li><a href="$.journal.website_url">$.journal.website_name</a></li>\n""";
}
"""
<td id="navbar" width="25%">
<div class="box">
<h1>$.journal.name</h1>
<ul>
""";
foreach var string v ($.views_order) {
if ($.view == $v) {
println "<li class=\"active\">"+lang_viewname($v)+"</li>";
} else {
println "<li><a href=\""+$.view_url{$v}+"\">"+lang_viewname($v)+"</a></li>";
}
}
"""
$website</ul>
$userpic
</div>
""";
if ($this->lay_show_firstnav()) {
$this->lay_page_nav();
}
if (size $this.linklist > 0 and $*linklist_support) {
println "<div class=\"box\">";
println "<h2>Links</h2>\n";
$this->print_linklist();
println "</div>";
}
"</td>";
}
function Page::print_linklist() {
if (size $.linklist <= 0) {
return;
}
var bool section_open = false;
println "<ul>";
foreach var UserLink l ($.linklist) {
if ($l.title) {
if ($l.is_heading) {
if ($section_open) {
println "</ul></li>";
}
println """<li><span style="font-weight: bold;">$l.title</span>\n<ul>""";
$section_open = true;
} else {
println """<li><a href="$l.url">$l.title</a></li>""";
}
}
}
if ($section_open) {
println "</ul></li>";
}
println "</ul>";
}
function Page::print() {
var string title = $this->title();
"""<html>\n<head>\n""";
if ($*external_stylesheet) {
println """<link rel="stylesheet" href="$.stylesheet_url" type="text/css" />""";
} else {
println """<style type="text/css">"""; print_stylesheet(); "</style>";
}
$this->print_head();
"<title>"+$this->title()+"</title>";
"""
</head>
<body class="$.view">
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr valign="top">
""";
if ($*opt_navbar_pos == "left") {
$this->lay_navbar();
}
"<td rowspan=\"2\" id=\"body\">\n";
$this->print_body();
"</td>\n";
if ($*opt_navbar_pos == "right") {
$this->lay_navbar();
}
"</tr><tr><td valign=\"bottom\" id=\"skipbar\">";
$this->lay_page_nav();
"</td>";
"""
</tr>
</table>
</body>
</html>
""";
}
function print_entry(Page p, Entry e, Color bgcolor, Color fgcolor) {
var string datetime;
if ($p.view != "day") {
$datetime = $e.time->date_format("med_day")+", "+$e.time->time_format();
} else {
$datetime = $e.time->time_format();
}
if (not (defined $bgcolor) or not $*opt_friends_colors) {
$bgcolor = $*clr_boxhead_back;
}
if (not (defined $fgcolor) or not $*opt_friends_colors) {
$fgcolor = $*clr_boxhead_text;
}
"""<div class="box"><h2 style="color: $fgcolor; background: $bgcolor;">$datetime """;
if ($e.security != "") {
print """<img src="$e.security_icon.url" align="right" """+
"""width="$e.security_icon.width" height="$e.security_icon.height" """+
"""alt="[$e.security]" />""";
}
if ($p.view == "friends" or
$e.subject != "" or
$e.poster.username != $p.journal.username) {
print "<br />";
if ($p.view == "friends" or $e.poster.username != $p.journal.username) {
$p->print_entry_poster($e);
print ": ";
}
print $e.subject;
}
"</h2>\n<div class=\"entry\">\n";
if (defined $e.userpic and (
$*opt_always_userpic
or ($e.poster.username != $p.journal.username and $e.userpic.url != $p.journal.default_pic.url)
or $p.view == "friends"
or $p.view == "entry")) {
"""<img src="$e.userpic.url" """;
"""width="$e.userpic.width" height="$e.userpic.height" """;
"""alt="" align="right" style="margin: 5px;" />\n""";
}
"$e.text";
$e->print_metadata();
"""</div><div class="talklinks">""";
"""<div class="permalink"><a href="$e.permalink_url">$*text_permalink</a></div>&nbsp;""";
$e.comments->print();
"</div>";
"</div>";
} # print_entry(Page,Entry,Color,Color)
function Entry::print_metadata() {
var string caption;
var string val;
var Image i;
if (size $.metadata == 0 and size $.tags == 0) { return; }
println """<div class="metadata">""";
if ($this.tags) {
var int tcount = 0;
"<div class='ljtags'><strong>Tags:</strong> ";
foreach var Tag t ($this.tags) {
"""<a rel="tag" href="$t.url">$t.name</a>""";
$tcount++;
if ($tcount != size $this.tags) { ", "; }
}
"</div>";
}
if (size $.metadata != 0) {
foreach var string k ($.metadata) {
$caption = $k;
$val = $.metadata{$k};
if ($k == "music") {
$caption = $*text_meta_music;
}
elseif ($k == "mood") {
$caption = $*text_meta_mood;
if (defined $.mood_icon) {
$i = $.mood_icon;
$val = """<img src="$i.url" width="$i.width" height="$i.height" align="absmiddle"> $val""";
}
}
println """<div class="metadata-$k"><span style="font-weight: bold;">$caption:</span> $val</div>""";
}
}
println "</div>";
}
function Page::print_entry(Entry e) {
print_entry($this, $e, null Color, null Color);
}
function FriendsPage::print_entry(Entry e) {
var Friend f = $.friends{$e.journal.username};
print_entry($this, $e, $f.bgcolor, $f.fgcolor);
}
function colored_ljuser(UserLite u, Color fg, Color bg) : string {
var Image uiimg = userinfoicon($u);
var string dir = $u.journal_type == "C" ? "community" : "users";
return """<span class="ljuser" style="white-space:nowrap;"><a href="$*SITEROOT/userinfo.bml?user=$u.username" style="color: $fg; background: $bg;"><img src="$uiimg.url" alt="[i]" width="$uiimg.width" height="$uiimg.height" style="vertical-align:bottom;border:0;" /></a><a href="$*SITEROOT/$dir/$u.username/" style="color: $fg; background: $bg; font-weight: bold;">$u.username</a></span>""";
}
function FriendsPage::print_entry_poster(Entry e) {
var Friend f = $.friends{$e.journal.username};
var Color fg; var Color bg;
if ($*opt_friends_colors) {
$fg = $f.fgcolor;
$bg = $f.bgcolor;
} else {
$fg = $*clr_boxhead_text;
$bg = $*clr_boxhead_back;
}
print colored_ljuser($e.poster, $fg, $bg);
if ($e.poster.username != $e.journal.username) {
" posting in ";
print colored_ljuser($e.journal, $fg, $bg);
}
}
function RecentPage::print_body() {
foreach var Entry e ($.entries) {
$this->print_entry($e);
}
}
function CommentInfo::print() {
if ($.enabled) {
$this->print_postlink();
if ($.count > 0 or $.screened) {
" | ";
$this->print_readlink();
}
}
}
function DayPage::print_body() {
println """<h1 style="font-size: 1.5em; text-align: center;">"""+$.date->date_format("long")+"</h1>";
if (not $.has_entries) {
print "<p>$*text_noentries_day</p>";
return;
}
foreach var Entry e ($.entries) {
$this->print_entry($e);
}
}
function EntryPage::print_body() {
$this->print_entry($.entry);
if ($this.multiform_on) {
$this->print_multiform_start();
}
if ($.entry.comments.enabled) {
$this->print_comments($.comments);
}
if ($this.multiform_on) {
"<div class='box'><h2>Mass Action on Selected Comments:</h2>";
"<p class='entry'>"; $this->print_multiform_actionline(); "</p>";
"</div>";
$this->print_multiform_end();
}
}
function EntryPage::print_comments(Comment[] cs) {
if (size $cs == 0) { return; }
print "<div style=\"margin-left: 25px;\">";
foreach var Comment c ($cs) {
var int indent = ($c.depth - 1) * 25;
if ($c.full) {
$this->print_comment($c);
} else {
$this->print_comment_partial($c);
}
}
print "</div>";
}
function EntryPage::print_comment(Comment c) {
var string datetime;
$datetime = $c.time->date_format("med_day")+", "+$c.time->time_format();
"""<a name='$c.anchor'></a><div id="$c.dom_id" class="box"><h3 style="color: $*clr_boxhead_text; background: $*clr_boxhead_back;">""";
if ($c.metadata{"poster_ip"}) { print """<div style="float: right; vertical-align: top; font-size: 0.75em;">(""" +
$c.metadata{"poster_ip"} +
""")</div>"""; }
print $datetime;
if (defined $c.subject_icon) {
print """<img src="$c.subject_icon.url" align="right" """+
"""width="$c.subject_icon.width" height="$c.subject_icon.height" """+
"""alt="" />""";
}
var string poster = defined $c.poster ? $c.poster->as_string() : "<i>(Anonymous)</i>";
print "<br />"+$poster;
if ($c.subject != "") {
print ": "+$c.subject;
}
"</h3>\n<div class=\"entry\">\n";
if (defined $c.userpic and $*comment_userpic_style != "off") {
"""<img src="$c.userpic.url" """;
"""width="$c.userpic.width" height="$c.userpic.height" """;
"""alt="" align="right" style="margin: 5px;" />\n""";
}
"$c.text</div>";
"""<div class="talklinks">""";
"""<div class="permalink"><a href="$c.permalink_url">$*text_permalink</a></div>""";
if ($c.parent_url != "") { """<a href="$c.parent_url">$*text_comment_parent</a> - """; }
if ($c.thread_url != "") { """<a href="$c.thread_url">$*text_comment_thread</a> - """; }
var Link l = new Link;
foreach var string ls ($c.link_keyseq) {
$l = $c->get_link($ls);
if (defined $l) {
println """<a href="$l.url">$*text_comment_links{$ls}</a> - """;
}
}
if (not $c.frozen) {
"""<a href="$c.reply_url">$*text_comment_reply</a>""";
} else {
"""$*text_comment_frozen""";
}
# FIXME: better location?
if ($.multiform_on) {
"""<br /><label for="ljcomsel_$c.talkid">$*text_multiform_check</label> """; $c->print_multiform_check();
}
"</div>";
if ((size $c.replies) > 0 and $c.replies[0].full == false) {
"""<div style="margin-top: 5px; margin-bottom: 5px; clear: both;">\n""";
$this->print_comments($c.replies);
"</div>\n";
}
"</div>";
if ((size $c.replies) > 0 and $c.replies[0].full == true) {
$this->print_comments($c.replies);
}
}
function EntryPage::print_comment_partial(Comment c) {
var string poster = defined $c.poster ? $c.poster->as_string() : "<i>(Anonymous)</i>";
var string subj = $c.subject != "" ? $c.subject : $*text_nosubject;
print """<div class="minicomment"><a href="$c.permalink_url">$subj</a> - $poster</div>""";
$this->print_comments($c.replies);
}
function ReplyPage::print_body() {
var EntryLite c = $.replyto;
var string datetime;
$datetime = $c.time->date_format("med_day")+", "+$c.time->time_format();
"""<div class="box"><h2 style="color: $*clr_boxhead_text; background: $*clr_boxhead_back;">$datetime """;
var string poster = defined $c.poster ? $c.poster->as_string() : "<i>(Anonymous)</i>";
print "<br />"+$poster;
if ($c.subject != "") {
print ": "+$c.subject;
}
"</h2>\n<div class=\"entry\">\n";
if (defined $c.userpic and $*comment_userpic_style != "off") {
"""<img src="$c.userpic.url" """;
"""width="$c.userpic.width" height="$c.userpic.height" """;
"""alt="" align="right" style="margin: 5px;" />\n""";
}
"$c.text</div>";
if (defined $c.userpic and $*comment_userpic_style != "off") {
"""<br clear="all" />""";
}
"</div>";
"""<div class="box" style="margin-left: 25px;">\n""";
$.form->print();
"</div>\n";
}
function YearPage::print_body {
foreach var YearMonth m ($.months) {
$this->print_month($m);
}
}
function YearPage::print_month(YearMonth m) {
if (not $m.has_entries) { return; }
"""<table class="box" style="border-collapse: collapse; border: 1px solid; width: 80%; margin-left: 10%; margin-right: 10%;" border="1">\n
<tr><th colspan="7" style="background: $*clr_boxhead_back; color: $*clr_boxhead_text; text-align: center;">""";
print $m->month_format();
"""</th></tr>\n""";
foreach var int d (weekdays()) {
"<th style=\"width: 14%;\">"+$*lang_dayname_short[$d]+"</th>\n";
}
"</tr>\n";
foreach var YearWeek w ($m.weeks) {
$w->print();
}
"""<tr><td colspan="7" style="text-align: center;">
<a href="$m.url">$*text_view_month</a></td></tr>\n""";
"</table>";
}
function YearWeek::print() {
"""<tr valign="top" style="height: 2.75em;">\n""";
if ($.pre_empty > 0) {
"""<td class="emptyday" colspan="$.pre_empty">&nbsp;</td>\n""";
}
foreach var YearDay d ($.days) {
"""<td>\n""";
"""<div style="text-align: right;">$d.day</div>\n""";
if ($d.num_entries > 0) {
"""<div style="text-align: center;"><a href="$d.url">$d.num_entries</a></div>\n""";
}
"""</td>\n""";
}
if ($.post_empty > 0) {
"""<td colspan="$.post_empty">&nbsp;</td>\n""";
}
"</tr>";
}
function MonthPage::print_body {
"""<div class="box"><h2>"""+$.date->date_format($*lang_fmt_month_long)+"</h2>\n";
"<dl style=\"margin: 1em;\">";
foreach var MonthDay d ($.days) {
if ($d.has_entries) {
"<dt><a href=\"$d.url\"><b>";
print lang_ordinal($d.day);
"</b></a></dt>\n<dd>";
$d->print_subjectlist();
"</dd>\n";
}
}
"</dl>\n</div>\n";
}
### Handler for the theme previews
function print_theme_preview() {
"""
<div style="padding: 1em; background: $*clr_page_back; color: $*clr_page_text;">
<div style="border: 1px solid $*clr_page_text; margin: 1em; background: $*clr_box_back; color: $*clr_box_text;">
<h2 style="color: $*clr_boxhead_text; background: $*clr_boxhead_back; font-size: 1em; padding: 4px; margin: 0;">Cir zuta besho cavu mabu</h2>
<div style="margin: 1em;">
Cir zuta besho cavu mabu. Jad dop fugu hige wiju. Jam nek sapu shek noshea, moz lolle jil hattou daz.
Heck mippe giffou tipe pello, govo goof wachou fenu betui, mumu niffo puffu hivoo ziv! Sap gap jozo vem
sushu jiwo peru diche gese zar. Zuk kah rec sok vapui, mumu. Puw wuti mufe bak jivo, zef kazou gipwew cus.
Cev lepp gik fego rer. Tucku mickou jeck helou soopp! Vowa vov fawea pip wok. Heg fum heafsum pele.
Piz kuzu louw rome puir. Pashi jog huku pobi ckush. Zuj bit wido guih biha. Som veh nelo ruh ruju.
Coosh jecko nuh tutt tab. Zutt ckek vano fic der, hivu?
</div>
<div style="margin: 1em; text-align: right; clear: both;">
<div style="float: left;"><span style="color: #0000ff; text-decoration: underline; cursor: hand;">$*text_permalink</span></div>&nbsp;
</div>
</div>
</div>
""";
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -0,0 +1,75 @@
#NEWLAYER: sturdygesture/beansprout
layerinfo "type" = "theme";
layerinfo "name" = "Beansprout";
layerinfo "redist_uniq" = "sturdygesture/beansprout";
set clr_page_link = "#006760";
set clr_boxhead_text = "#ffffff";
set clr_box_text = "#000000";
set clr_page_text = "#ffffff";
set clr_box_back = "#ffffff";
set clr_boxhead_back = "#006760";
set clr_page_back = "#000000";
set clr_page_vlink = "#002C29";
#NEWLAYER: sturdygesture/boxless
layerinfo "type" = "theme";
layerinfo "name" = "Boxless";
layerinfo "redist_uniq" = "sturdygesture/boxless";
set clr_page_link = "#0000ff";
set clr_boxhead_text = "#ffffff";
set clr_box_text = "#000000";
set clr_page_text = "#ffffff";
set clr_box_back = "#ffffff";
set clr_boxhead_back = "#000000";
set clr_page_back = "#ffffff";
set clr_page_vlink = "#00007f";
#NEWLAYER: sturdygesture/martialblue
layerinfo "type" = "theme";
layerinfo "name" = "Martial Blue";
layerinfo "redist_uniq" = "sturdygesture/martialblue";
set clr_page_link = "#0068CF";
set clr_boxhead_text = "#000000";
set clr_box_text = "#000000";
set clr_page_text = "#000000";
set clr_box_back = "#FFFFFF";
set clr_boxhead_back = "#6FB7FF";
set clr_page_back = "#BFD8FF";
set clr_page_vlink = "#003070";
#NEWLAYER: sturdygesture/redmond
layerinfo "type" = "theme";
layerinfo "name" = "Redmond";
layerinfo "redist_uniq" = "sturdygesture/redmond";
set clr_page_link = "#0000ff";
set clr_boxhead_text = "#ffffff";
set clr_box_text = "#000000";
set clr_page_text = "#000000";
set clr_box_back = "#ffffff";
set clr_boxhead_back = "#00007F";
set clr_page_back = "#007F7F";
set clr_page_vlink = "#0000ff";
#NEWLAYER: sturdygesture/shadesofgray
layerinfo "type" = "theme";
layerinfo "name" = "Shades of Gray"; # or, indeed, "grey" :)
layerinfo "redist_uniq" = "sturdygesture/shadesofgray";
set clr_page_link = "#444444";
set clr_boxhead_text = "#ffffff";
set clr_box_text = "#000000";
set clr_page_text = "#7f7f7f";
set clr_box_back = "#cccccc";
set clr_boxhead_back = "#7f7f7f";
set clr_page_back = "#888888";
set clr_page_vlink = "#222222";

View File

@@ -0,0 +1,14 @@
# -*-s2-*-
layerinfo type = "i18n";
layerinfo name = "English";
layerinfo redist_uniq = "tabularindent/en";
set text_meta_music = "Music";
set text_meta_mood = "Mood";
set text_post_comment = "Add Your Own";
set text_read_comments = "Read # Comments";
set text_post_comment_friends = "Add Your Own";
set text_read_comments_friends = "Read # Comments";

View File

@@ -0,0 +1,741 @@
# -*-s2-*-
layerinfo type = "layout";
layerinfo name = "Tabular Indent";
layerinfo redist_uniq = "tabularindent/layout";
layerinfo previews = "tabularindent/tabularindent.jpg";
propgroup colors {
property Color body_bgcolor {
des = "Body background color";
s1color = "page_back";
}
property Color main_bgcolor {
des = "Background of main text areas";
s1color = "page_back";
}
property Color main_fgcolor {
des = "Main text color";
s1color = "page_text";
}
property Color border_color {
des = "Color of borders";
# No s1color equivalent
}
property Color headerbar_bgcolor {
des = "Background color of header bar(s)";
s1color = "stronger_back";
}
property Color headerbar_fgcolor {
des = "Header bar text color";
s1color = "stronger_text";
}
property Color captionbar_mainbox_bgcolor {
des = "Main background color of caption bar";
s1color = "page_back";
}
property Color captionbar_mainbox_fgcolor {
des = "Text color of caption bar";
s1color = "page_text";
}
property Color captionbar_userpicbox_color {
des = "User picture background color of caption bar";
s1color = "strong_back";
}
property Color accent_bgcolor {
des = "Background color of accented areas";
s1color = "weak_back";
}
property Color accent_fgcolor {
des = "Accented area text color";
s1color = "weak_text";
}
property Color link_color {
des = "Link color";
s1color = "page_link";
}
property Color vlink_color {
des = "Visited link color";
s1color = "page_vlink";
}
property Color alink_color {
des = "Active link color";
s1color = "page_alink";
}
property Color comment_bar_one_bgcolor {
des = "Alternating background color for comment bars (one)";
}
property Color comment_bar_two_fgcolor {
des = "Text color on alternating comment bars (one)";
}
property Color comment_bar_two_bgcolor {
des = "Alternating background color for comment bars (two)";
}
property Color comment_bar_one_fgcolor {
des = "Text color on alternating comment bars (two)";
}
property Color comment_bar_screened_bgcolor {
des = "Background bar color for screened comments";
}
property Color comment_bar_screened_fgcolor {
des = "Text color on background bar for screened comments";
}
}
set body_bgcolor = "#ffffff";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set border_color = "#000000";
set headerbar_bgcolor = "#6666cc";
set headerbar_fgcolor = "#ffffff";
set captionbar_mainbox_bgcolor = "#ffffff";
set captionbar_mainbox_fgcolor = "#000000";
set captionbar_userpicbox_color = "#c0c0ff";
set accent_bgcolor = "#eeeeff";
set accent_fgcolor = "#000000";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#ff00c0";
set comment_bar_one_bgcolor = "#c0c0ff";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#eeeeff";
set comment_bar_two_fgcolor = "#000000";
set comment_bar_screened_bgcolor = "#dddddd";
set comment_bar_screened_fgcolor = "#000000";
propgroup presentation {
property bool show_entry_userpic {
des = "Show the userpic on the journal entries?";
}
property use page_recent_items;
property use page_friends_items;
property use use_shared_pic;
property use view_entry_disabled;
property string page_background_image {
des = "URL to an image to be used for the page background";
}
property use external_stylesheet;
}
set show_entry_userpic = true;
set page_recent_items = 20;
set page_friends_items = 20;
set view_entry_disabled = false;
set page_background_image = "";
propgroup text {
property use text_post_comment;
property use text_read_comments;
property use text_post_comment_friends;
property use text_read_comments_friends;
}
set tags_aware = true;
function Page::lay_captionbar_navigation () { }
function captionbar (Page p) {
var string title = $p->title();
var string userpic;
var Image up_img = $p.journal.default_pic;
if (defined $up_img) {
$userpic = """<img src="$up_img.url" height="$up_img.height" width="$up_img.width" alt="[icon]" />""";
}
var string website_name = $p.journal.website_name ? $p.journal.website_name : $*text_website_default_name;
var string website;
if ($p.journal.website_url != "") {
$website = """<tr><td>View:</td><td><a href="$p.journal.website_url">Website ($website_name)</a>.</td></tr>""";
}
var string links;
foreach var string v ($p.views_order) {
$links = "$links<tr><td>View:</td><td>" + ($p.view == $v ?
lang_viewname($v) :
"<a href='$p.view_url{$v}'>"+lang_viewname($v)+"</a>") + ".</td></tr>\n";
}
var string captionbar_userpicbox_style = "background-color: $*captionbar_userpicbox_color";
"""
<table height='100' class='captionbar' cellpadding='5' cellspacing='1'><tr>
<td class="captionbar-userpicbox" align='center' valign='center' width='100' style='$captionbar_userpicbox_style'>$userpic</td>
<td><b>$title</b><br />
<table border='0'>
$links
$website
<tr>
<td colspan='2'>""";
$p->lay_captionbar_navigation();
"
</td>
</tr>
</table>
</td>
</tr></table>";
}
function print_stylesheet ()
{
var string backgroundurl = clean_url($*page_background_image) != "" ? "background-image: url($*page_background_image);" : "";
"""/* Tabular Indent Stylesheet */
body {
$backgroundurl
background-color: $*body_bgcolor;
}
.captionbar {
width: 100%;
border: 1px solid $*border_color;
}
.captionbar, .captionbar td {
background-color: $*captionbar_mainbox_bgcolor;
color: $*captionbar_mainbox_fgcolor;
}
.captionbar-userpicbox {
border-right: 1px solid $*border_color;
background-color: $*captionbar_userpicbox_color;
color: $*captionbar_mainbox_fgcolor;
}
body,td,p {
font-family: verdana, arial, helvetica, sans-serif;
font-size: 8pt;
}
a {
color: $*link_color;
font-family: verdana, arial, helvetica, sans-serif;
font-size: 8pt;
text-decoration: none;
}
a:visited {
color: $*vlink_color;
font-family: verdana, arial, helvetica, sans-serif;
font-size: 8pt;
text-decoration: none;
}
a:active {
color: $*alink_color;
font-family: verdana, arial, helvetica, sans-serif;
font-size: 8pt;
text-decoration: none;
}
a:hover {
color: $*alink_color;
font-family: verdana, arial, helvetica, sans-serif;
font-size: 8pt;
text-decoration: underline;
}
h3.page-header {
font-size: 8pt;
font-family: verdana, arial, helvetica, sans-serif;
font-weight: normal;
background-color: $*headerbar_bgcolor;
color: $*headerbar_fgcolor;
padding: 6px;
border: 1px solid $*border_color;
}
""";
}
function Page::print ()
{
var string title = $this->title();
println "<html>\n<head>\n";
if ($*external_stylesheet) {
println """<link rel="stylesheet" href="$.stylesheet_url" type="text/css" />""";
} else {
println """<style type="text/css">"""; print_stylesheet(); "</style>";
}
$this->print_head();
"""<title>$title</title>
</head>
<body>
""";
"<p>"; captionbar($this); "</p>";
"<p>"; $this->print_body(); "</p>";
"<p>"; captionbar($this); "</p>";
"""
</body>
</html>
""";
}
function print_box (string{} colors, string metapic, string{} meta, string content, string footer, string domid) {
var string bgcolor = $colors{"bgcolor"};
var string fgcolor = $colors{"fgcolor"};
if ($domid != "") { $domid = "id='$domid'"; }
var string style = "background-color: $bgcolor; color: $fgcolor";
"<div align='right'><table $domid border='0' width='95%' cellpadding='5' cellspacing='1' style='$style'>";
"<tr><td><table border='0' width='100%'><tr>";
if ($metapic) {
"<td width='100' valign='top' align='center'>$metapic</td>";
}
"<td valign='top'><table border='0'>";
foreach var string k ($meta) {
var string key = $k;
var string val = $meta{$k};
"<tr><td align='right'>$key</td><td>$val</td></tr>";
}
"</table></td></tr></table></td></tr>";
"<tr><td style='background-color: $*main_bgcolor; color: $*main_fgcolor'>";
print $content;
"</td></tr>";
if ($footer) {
"<tr><td style='white-space: nowrap'>$footer</td></tr>";
}
"</table></div><br />";
}
function print_header (string header)
{
print "<h3 class='page-header'>$header</h3>";
}
function print_genericbox_open () {
"<div align='right'><table border='0' width='95%' cellpadding='5' cellspacing='1' bgcolor='$*accent_bgcolor'>";
"<tr><td style='background-color: $*main_bgcolor; color: $*main_fgcolor'>";
}
function print_genericbox_close ()
{
"</font></td></tr></table></div><br />";
}
function print_entry (Page p, Entry e, Color bgcolor, Color fgcolor, bool hide_text)
{
var string{} colors; var string{} meta; var string content = ""; var string footer = "";
$colors{"bgcolor"} = "$*accent_bgcolor";
$colors{"fgcolor"} = "$*accent_fgcolor";
if ($p.view == "recent") {
if ($e.new_day) {
print_header($e.time->date_format("%%month%% %%dayord%%, %%yyyy%%"));
}
} else {
print_header($e.time->date_format("%%month%% %%dayord%%, %%yyyy%%"));
}
# Userpic
var string metapic = "";
if ($p.view == "friends" or
$*show_entry_userpic == true or
$e.journal.username != $e.poster.username)
{
var string userpic = defined $e.userpic ? "<img src='$e.userpic.url' style='border: 0' />" : "";
var string url = $e.journal->base_url() + "/";
$metapic = "<div style='background-color: $bgcolor'>";
$metapic = "$metapic <a href='$url'>$userpic</a>";
if ($e.journal.username != $e.poster.username) {
var string purl = $e.poster->base_url() + "/";
$metapic = "$metapic<br /><font color='$fgcolor'>[<a href='$purl'>$e.poster.username</a>]</font>";
}
if ($p.view == "friends") { $metapic = "$metapic<br /><font color='$fgcolor'><a href='$url'>$e.journal.username</a></font>"; }
$metapic = "$metapic</div>";
}
# Security Icon
if ($e.security) {
$meta{"Security:"} = "$e.security_icon $e.security";
}
# Subject
if ($e.subject) {
$meta{"Subject:"} = $e.subject;
}
# Time posted
var string time = $e.time->time_format();
$meta{"Time:"} = $time;
# Current
if (size $e.metadata) {
foreach var string k ($e.metadata) {
var string key = $k; var string val = $e.metadata{$k};
if ($k == "mood") {
$key = $*text_meta_mood;
} elseif ($k == "music") {
$key = $*text_meta_music;
}
if ($k == "mood" and defined $e.mood_icon) {
var Image i = $e.mood_icon;
$val = "<img src='$i.url' width='$i.width' height='$i.height' align='absmiddle' alt='[mood icon]' /> $val";
}
$meta{"$key:"} = $val;
}
}
# Tags
if ($e.tags) {
var int tcount = 0;
var string tag;
foreach var Tag t ($e.tags) {
$tag = $tag + """<a rel="tag" href="$t.url">$t.name</a>""";
$tcount++;
if ($tcount != size $e.tags) { $tag = $tag + ", "; }
}
$meta{"Tags:"} = $tag;
}
if (not $hide_text) { $content = $e.text; }
if ($e.comments.enabled) {
$footer = "comments:";
if (($e.comments.count > 0 or $e.comments.screened) and ($p.view != "entry")) {
$footer = "$footer <a href=\"$e.comments.read_url\">"
+ get_plural_phrase($e.comments.count, $p.view == "friends" ?
"text_read_comments_friends" : "text_read_comments")
+ "</a> or";
}
$footer = "$footer <a href=\"$e.comments.post_url\">"
+ ($p.view == "friends" ? $*text_post_comment_friends : $*text_post_comment)
+ "</a>";
}
# Misc Links
var Link link;
if ($p.view == "entry")
{
$link = $e->get_link("nav_prev"); $footer = "$footer $link";
}
$link = $e->get_link("edit_entry"); $footer = "$footer $link";
$link = $e->get_link("edit_tags"); $footer = "$footer $link";
$link = $e->get_link("tell_friend"); $footer = "$footer $link";
$link = $e->get_link("mem_add"); $footer = "$footer $link";
if ($p.view == "entry")
{
$link = $e->get_link("nav_next"); $footer = "$footer $link";
}
# Print
print_box($colors, $metapic, $meta, $content, $footer, "");
}
function Page::print_entry (Entry e)
{
print_entry($this, $e, null Color, null Color, false);
}
function FriendsPage::print_entry (Entry e) {
var Friend f = $.friends{$e.journal.username};
print_entry($this, $e, $f.bgcolor, $f.fgcolor, false);
}
function RecentPage::lay_captionbar_navigation()
{
var int total = size $.entries;
var string nav = "";
if ($.nav.backward_url != "") {
$nav = """<a href="$.nav.backward_url">back $total entries</a>""";
}
if ($.nav.forward_url != "" and $.nav.backward_url != "") {
$nav = "$nav or ";
}
if ($.nav.forward_url != "") {
$nav = """$nav<a href="$.nav.forward_url">forward $total entries</a>""";
}
print "You're looking at the latest ";
print size $.entries;
print ($.nav.skip > 0) ? " entries, after skipping $.nav.skip newer ones." :" entries.";
if ($nav != "") { print "<br />Missed some entries? Then simply jump $nav"; }
}
function RecentPage::print_body {
foreach var Entry e ($.entries) {
$this->print_entry($e);
}
}
function FriendsPage::print_body {
foreach var Entry e ($.entries) {
$this->print_entry($e);
}
}
function CommentInfo::print()
{
if (not $.enabled) { return; }
"<tr><td bgcolor='$*accent_bgcolor'><font color='$*accent_fgcolor'>";
"<nobr>comments: ";
if ($.count > 0 or $.screened) {
$this->print_readlink(); " or ";
}
$this->print_postlink();
"</nobr></font></td></tr>";
}
function YearPage::print_body {
print_header(string($.year));
print_genericbox_open();
foreach var YearMonth m ($.months) {
$this->print_month($m);
}
print_genericbox_close();
}
function YearPage::lay_captionbar_navigation()
{
$this->print_year_links();
}
function YearPage::print_year_links ()
{
foreach var YearYear y ($.years) {
if ($y.displayed) {
"$y.year&nbsp;";
} else {
"<a href=\"$y.url\">$y.year</a>&nbsp;";
}
}
}
function YearPage::print_month(YearMonth m)
{
if (not $m.has_entries) { return; }
"<center><table border='1' cellpadding='4' width='80%'>";
# Month header
"<tr align='center'><td colspan='7' bgcolor='$*headerbar_bgcolor'>";
"<font color='$*headerbar_fgcolor'><b>"; print $m->month_format(); "</b></font></td></tr>";
# Weekdays
"<tr align='center' bgcolor='$*accent_bgcolor'>";
foreach var int d (weekdays()) {
"<td><font color='$*accent_fgcolor'>"+$*lang_dayname_short[$d]+"</font></td>\n";
}
"</tr>";
foreach var YearWeek w ($m.weeks) {
$w->print();
}
"<tr align='center'><td colspan='7'><a href='$m.url'>View Subjects</a>";
"</td></tr></table></center>";
}
function YearWeek::print () {
"<tr>";
if ($.pre_empty) { "<td colspan='$.pre_empty' bgcolor='$*accent_bgcolor'>&nbsp;</td>"; }
foreach var YearDay d ($.days) {
"<td valign='top'><b>$d.day</b>";
"<div align='center'>";
if ($d.num_entries) {
"""<a href="$d.url">$d.num_entries</a>""";
} else {
"&nbsp;";
}
"</div></td>";
}
if ($.post_empty) { "<td colspan='$.post_empty' bgcolor='$*accent_bgcolor'>&nbsp;</td>"; }
"</tr>";
}
function DayPage::lay_captionbar_navigation()
{
print "Missed some entries? Then simply jump to the <a href='$.prev_url'>previous day</a> or the <a href='$.next_url'>next day</a>.";
}
function DayPage::print_body ()
{
if (not $.has_entries) {
"<table border='0' width='100%' cellpadding='5' cellspacing='1' bgcolor='$*border_color'>";
"<tr><td bgcolor='$*headerbar_bgcolor'><font color='$*headerbar_fgcolor'>";
print $.date->date_format("%%month%% %%dayord%%, %%yyyy%%");
"</font></td></tr></table><br />";
print "No journal entries for this day.";
} else {
foreach var Entry e ($.entries) {
$this->print_entry($e);
}
}
}
function MonthPage::print_body {
print_header($.date->date_format("%%month%% %%yyyy%%"));
print_genericbox_open();
"<form method='post' action='$.redir.url'><center>";
$.redir->print_hiddens();
if ($.prev_url != "") { "[<a href='$.prev_url'>&lt;&lt;&lt;</a>]\n"; }
if (size $.months > 1) {
"<select name='redir_key'>\n";
foreach var MonthEntryInfo mei ($.months) {
var string sel;
if ($mei.date.year == $.date.year and $mei.date.month == $.date.month) {
$sel = " selected='selected'";
}
"<option value='$mei.redir_key'$sel>" + $mei.date->date_format($*lang_fmt_month_long) + "</option>";
}
"</select>\n<input type='submit' value='View' />";
}
if ($.next_url != "") { "\n[<a href='$.next_url'>&gt;&gt;&gt;</a>]\n"; }
"</center></form>\n<dl>";
foreach var MonthDay d ($.days) {
if ($d.has_entries) {
"<dt><a href=\"$d.url\"><b>";
print lang_ordinal($d.day);
"</b></a></dt>\n<dd>";
$d->print_subjectlist();
"</dd>\n";
}
}
"</dl>\n";
print_genericbox_close();
}
function EntryPage::print_body () {
set_handler("unscreen_comment_#", [
[ "style_bgcolor", "cmtbar#", "$*comment_bar_one_bgcolor", ],
[ "style_color", "cmtbar#", "$*comment_bar_one_fgcolor", ],
]);
set_handler("screen_comment_#", [
[ "style_bgcolor", "cmtbar#", "$*comment_bar_screened_bgcolor", ],
[ "style_color", "cmtbar#", "$*comment_bar_screened_fgcolor", ],
]);
print_entry($this, $.entry, null Color, null Color, $.viewing_thread);
if ($.entry.comments.enabled and $.comment_pages.total_subitems > 0)
{
$this->print_multiform_start();
print_header("Comments:");
if ($.comment_pages.total_subitems > 0) {
$.comment_pages->print();
$this->print_comments($.comments);
}
if ($this.multiform_on) {
print_header("Mass Action:");
print_genericbox_open();
$this->print_multiform_actionline();
print_genericbox_close();
$this->print_multiform_end();
}
}
}
function EntryPage::print_comment_partial (Comment c) {
var string poster = defined $c.poster ? $c.poster->as_string() : "<i>(Anonymous)</i>";
var string subj = $c.subject != "" ? $c.subject : $*text_nosubject;
print_genericbox_open();
print "<a href='$c.permalink_url'>$subj</a> - $poster";
print_genericbox_close();
}
function EntryPage::print_comment (Comment c) {
var string{} colors; var string{} meta; var string content = ""; var string footer = "";
if ($c.screened) {
$colors{"bgcolor"} = "$*comment_bar_screened_bgcolor";
$colors{"fgcolor"} = "$*comment_bar_screened_fgcolor";
} elseif ($c.depth % 2) {
$colors{"bgcolor"} = "$*comment_bar_one_bgcolor";
$colors{"fgcolor"} = "$*comment_bar_one_fgcolor";
} else {
$colors{"bgcolor"} = "$*comment_bar_two_bgcolor";
$colors{"fgcolor"} = "$*comment_bar_two_fgcolor";
}
# Userpic
var string poster = defined $c.poster ? $c.poster->as_string() : "<i>(Anonymous)</i>";
var string metapic = "";
if (defined $c.userpic and $*comment_userpic_style != "off")
{
var string userpic = defined $c.userpic ? "<img src='$c.userpic.url' style='border: 0' />" : "";
$metapic = "$userpic<br />$poster";
} else {
$metapic = $poster;
}
# Subject
var string sub_icon;
if (defined $c.subject_icon) {
$sub_icon = $c.subject_icon->as_string();
}
if ($c.subject or $sub_icon) {
$meta{"Subject:"} = "$c.subject $sub_icon";
}
# Time posted
$meta{"Time:"} = $c.time->time_format();
# Link
$meta{"Link:"} = "(<a href='$c.permalink_url'>Link</a>)";
# IP Address:
if ($c.metadata{"poster_ip"}) {
$meta{"IP Address:"} = $c.metadata{"poster_ip"};
}
if ($c.frozen) {
$footer = "(Replies frozen) ";
} else {
$footer = "(<a href='$c.reply_url'>Reply to this</a>) ";
}
if ($c.parent_url != "") { $footer = "$footer (<a href='$c.parent_url'>Parent</a>) "; }
if ($c.thread_url != "") { $footer = "$footer (<a href='$c.thread_url'>Thread</a>) "; }
var Link link = new Link;
foreach var string k ($c.link_keyseq) {
$link = $c->get_link($k); $footer = "$footer $link";
}
println "<a name='$c.anchor'></a>";
print_box($colors, $metapic, $meta, $c.text, $footer, "cmtbar$c.talkid");
}
function ReplyPage::print_body () {
if (not $.entry.comments.enabled)
{
print_header($*text_reply_nocomments_header);
print "<p>$*text_reply_nocomments</p>";
return;
}
var string{} meta; var string metapic;
# Userpic
if (defined $.replyto.userpic and $*comment_userpic_style != "off")
{
$metapic = "<img src='$.replyto.userpic.url' />";
}
# Subject
if ($.replyto.subject) {
$meta{"Subject:"} = $.replyto.subject;
}
# Time posted
$meta{"Time:"} = $.replyto.time->time_format();
print_box({ "bgcolor" => "$*accent_bgcolor", "fgcolor" => "$*accent_fgcolor" },
$metapic, $meta, $.replyto.text, "", "");
print_header("Reply:");
print_genericbox_open();
$.form->print();
print_genericbox_close();
}
function print_theme_preview()
{
"<table width='100%' bgcolor='$*body_bgcolor' cellpadding=10><tr><td>";
"<table border='0' width='100%' cellpadding='5' cellspacing='1' bgcolor='$*border_color'>";
"<tr><td bgcolor='$*headerbar_bgcolor'><font color='$*headerbar_fgcolor'>October 29th, 2003";
"</font></td></tr></table><br />";
"<div align='right'><table border='0' width='95%' cellpadding='5' cellspacing='1' bgcolor='$*accent_bgcolor'>";
"<tr><td align='left' bgcolor='$*accent_bgcolor'>";
"<table border='0' width='100%'><tr>";
"<td valign='top'><table border='0'>";
"<tr><td align='right'><font color='$*accent_fgcolor'>Subject:</font>";
"</td><td><font color='$*accent_fgcolor'>Words Words Words</font></td></tr>";
"<tr><td align='right'><font color='$*accent_fgcolor'>Time:</font></td>";
"<td><font color='$*accent_fgcolor'>1:37 pm</font></td></tr>";
"</table></td></tr></table></td></tr>";
"<tr><td align='left' bgcolor='$*main_bgcolor'><font color='$*main_fgcolor'>Preview text, preview text, etc, etc..... words, words and more words.</font></td></tr>";
"""<tr><td align='left' bgcolor='$*accent_bgcolor'><font color='$*accent_fgcolor'><nobr>comments: <a href="#">20 comments</a> or <a href="#">Leave a comment</a></nobr></font></td></tr>""";
"</table></div><br />";
"</td></tr></table>";
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -0,0 +1,437 @@
#NEWLAYER: tabularindent/shrinkvio
layerinfo type = theme;
layerinfo name = "Shrinking Violet";
layerinfo redist_uniq = "tabularindent/shrinkvio";
set body_bgcolor = "#ad22e7";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set border_color = "#381a45";
set headerbar_bgcolor = "#5d0383";
set headerbar_fgcolor = "#ffffff";
set captionbar_mainbox_bgcolor = "#5d0383";
set captionbar_mainbox_fgcolor = "#ffffff";
set captionbar_userpicbox_color = "#d9a1f1";
set accent_bgcolor = "#d9a1f1";
set accent_fgcolor = "#000000";
set link_color = "#2e053f";
set vlink_color = "#611627";
set alink_color = "#ff00c0";
set comment_bar_one_bgcolor = "#5d0383";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#d9a1f1";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: tabularindent/pistmint
layerinfo type = theme;
layerinfo name = "Pistachio Mint";
layerinfo redist_uniq = "tabularindent/pistmint";
set body_bgcolor = "#133422";
set main_bgcolor = "#a7c4b4";
set main_fgcolor = "#000000";
set border_color = "#096d36";
set headerbar_bgcolor = "#096d36";
set headerbar_fgcolor = "#ffffff";
set captionbar_mainbox_bgcolor = "#096d36";
set captionbar_mainbox_fgcolor = "#ffffff";
set captionbar_userpicbox_color = "#096d36";
set accent_bgcolor = "#096d36";
set accent_fgcolor = "#000000";
set link_color = "#8afabc";
set vlink_color = "#1da65a";
set alink_color = "#f9f5f5";
set comment_bar_one_bgcolor = "#096d36";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#093f36";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: tabularindent/mexicanfood
layerinfo type = theme;
layerinfo name = "Mexican Food";
layerinfo redist_uniq = "tabularindent/mexicanfood";
set body_bgcolor = "#ff0000";
set main_bgcolor = "#f8ff3e";
set main_fgcolor = "#f15601";
set border_color = "#f50701";
set headerbar_bgcolor = "#bdbf3e";
set headerbar_fgcolor = "#ff0000";
set captionbar_mainbox_bgcolor = "#ffc664";
set captionbar_mainbox_fgcolor = "#000000";
set captionbar_userpicbox_color = "#f9ff9d";
set accent_bgcolor = "#e15a18";
set accent_fgcolor = "#ffffff";
set link_color = "#f49e08";
set vlink_color = "#b05403";
set alink_color = "#ff7405";
set comment_bar_one_bgcolor = "#bdbf3e";
set comment_bar_one_fgcolor = "#ff0000";
set comment_bar_two_bgcolor = "#e15a18";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: tabularindent/ashfire
layerinfo type = theme;
layerinfo name = "Ash and Fire";
layerinfo redist_uniq = "tabularindent/ashfire";
set body_bgcolor = "#b5b5b5";
set main_bgcolor = "#ffb6af";
set main_fgcolor = "#000000";
set border_color = "#d90308";
set headerbar_bgcolor = "#e75454";
set headerbar_fgcolor = "#ffffff";
set captionbar_mainbox_bgcolor = "#ff9696";
set captionbar_mainbox_fgcolor = "#ffffff";
set captionbar_userpicbox_color = "#ff1106";
set accent_bgcolor = "#f06c88";
set accent_fgcolor = "#000000";
set link_color = "#f70208";
set vlink_color = "#b0161d";
set alink_color = "#d70106";
set comment_bar_one_bgcolor = "#e75454";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#f06c88";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: tabularindent/desktop
# for layout: 13 (tabularindent/layout)
layerinfo type = theme;
layerinfo name = "Classic Desktop";
layerinfo redist_uniq = "tabularindent/desktop";
set body_bgcolor = "#00545c";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set border_color = "#000000";
set headerbar_bgcolor = "#ff7b05";
set headerbar_fgcolor = "#ffeddd";
set captionbar_mainbox_bgcolor = "#ffffff";
set captionbar_mainbox_fgcolor = "#000000";
set captionbar_userpicbox_color = "#ff7b05";
set accent_bgcolor = "#ffeddd";
set accent_fgcolor = "#000000";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#5a76ff";
set comment_bar_one_bgcolor = "#ff7b05";
set comment_bar_one_fgcolor = "#ffeddd";
set comment_bar_two_bgcolor = "#ffeddd";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: tabularindent/satinhandshake
layerinfo type = theme;
layerinfo name = "Satin Handshake";
layerinfo redist_uniq = "tabularindent/satinhandshake";
set body_bgcolor = "#480c0c";
set main_bgcolor = "#d06464";
set main_fgcolor = "#00001d";
set border_color = "#000000";
set headerbar_bgcolor = "#aaaaaa";
set headerbar_fgcolor = "#000000";
set captionbar_mainbox_bgcolor = "#aaaaaa";
set captionbar_mainbox_fgcolor = "#000000";
set captionbar_userpicbox_color = "#9d0404";
set accent_bgcolor = "#9d0404";
set accent_fgcolor = "#000000";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#ff00c0";
set comment_bar_one_bgcolor = "#aaaaaa";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#9d0404";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: tabularindent/deepmelodrama
layerinfo type = theme;
layerinfo name = "Deep MeloDrama";
layerinfo redist_uniq = "tabularindent/deepmelodrama";
set body_bgcolor = "#872d89";
set main_bgcolor = "#719cff";
set main_fgcolor = "#8e48b2";
set border_color = "#8e48b2";
set headerbar_bgcolor = "#3794b3";
set headerbar_fgcolor = "#84b8e7";
set captionbar_mainbox_bgcolor = "#65b2c1";
set captionbar_mainbox_fgcolor = "#f5d3ff";
set captionbar_userpicbox_color = "#8e48b2";
set accent_bgcolor = "#65b2c1";
set accent_fgcolor = "#f5d3ff";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#dfd3ff";
set comment_bar_one_bgcolor = "#3794b3";
set comment_bar_one_fgcolor = "#84b8e7";
set comment_bar_two_bgcolor = "#65b2c1";
set comment_bar_two_fgcolor = "#f5d3ff";
#NEWLAYER: tabularindent/everwhite
layerinfo type = theme;
layerinfo name = "Everwhite";
layerinfo redist_uniq = "tabularindent/everwhite";
set body_bgcolor = "#ffffff";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set border_color = "#000000";
set headerbar_bgcolor = "#ffffff";
set headerbar_fgcolor = "#000000";
set captionbar_mainbox_bgcolor = "#ffffff";
set captionbar_mainbox_fgcolor = "#000000";
set captionbar_userpicbox_color = "#ffffff";
set accent_bgcolor = "#ffffff";
set accent_fgcolor = "#000000";
set link_color = "#e60000";
set vlink_color = "#c10602";
set alink_color = "#ff0600";
set comment_bar_one_bgcolor = "#dddddd";
set comment_bar_one_fgcolor = "#000000";
set comment_bar_two_bgcolor = "#aaaaaa";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: tabularindent/everblue
layerinfo type = theme;
layerinfo name = "Everblue with Greys";
layerinfo redist_uniq = "tabularindent/everblue";
set body_bgcolor = "#0f0c6d";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set border_color = "#000000";
set headerbar_bgcolor = "#000000";
set headerbar_fgcolor = "#ffffff";
set captionbar_mainbox_bgcolor = "#aaaaaa";
set captionbar_mainbox_fgcolor = "#000000";
set captionbar_userpicbox_color = "#000000";
set accent_bgcolor = "#aaaaaa";
set accent_fgcolor = "#000000";
set link_color = "#2f00f2";
set vlink_color = "#060667";
set alink_color = "#6691ff";
set comment_bar_one_bgcolor = "#000000";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#aaaaaa";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: tabularindent/brownleather
layerinfo type = theme;
layerinfo name = "Brown Leather Coat";
layerinfo redist_uniq = "tabularindent/brownleather";
set body_bgcolor = "#d2b48c";
set main_bgcolor = "#ffebcd";
set main_fgcolor = "#8b4513";
set border_color = "#000000";
set headerbar_bgcolor = "#d48014";
set headerbar_fgcolor = "#ffffff";
set captionbar_mainbox_bgcolor = "#d48014";
set captionbar_mainbox_fgcolor = "#d48014";
set captionbar_userpicbox_color = "#d48014";
set accent_bgcolor = "#ffe1a1";
set accent_fgcolor = "#000000";
set link_color = "#000050";
set vlink_color = "#867a55";
set alink_color = "#fffab3";
set comment_bar_one_bgcolor = "#d48014";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#ffe1a1";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: tabularindent/bruise
layerinfo type = theme;
layerinfo name = "Bruise";
layerinfo redist_uniq = "tabularindent/bruise";
set body_bgcolor = "#000000";
set main_bgcolor = "#bcbcbc";
set main_fgcolor = "#000000";
set border_color = "#000000";
set headerbar_bgcolor = "#1114a0";
set headerbar_fgcolor = "#ffffff";
set captionbar_mainbox_bgcolor = "#21c2f1";
set captionbar_mainbox_fgcolor = "#ffffff";
set captionbar_userpicbox_color = "#1114a0";
set accent_bgcolor = "#21c2f1";
set accent_fgcolor = "#0000ff";
set link_color = "#0000cc";
set vlink_color = "#000088";
set alink_color = "#0000ff";
set comment_bar_one_bgcolor = "#1114a0";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#21c2f1";
set comment_bar_two_fgcolor = "#0000ff";
#NEWLAYER: tabularindent/ranchhand
layerinfo type = theme;
layerinfo name = "Ranch Hand";
layerinfo redist_uniq = "tabularindent/ranchhand";
set body_bgcolor = "#2999c2";
set main_bgcolor = "#cfe0ff";
set main_fgcolor = "#000000";
set border_color = "#060667";
set headerbar_bgcolor = "#54442c";
set headerbar_fgcolor = "#ffffff";
set captionbar_mainbox_bgcolor = "#bababa";
set captionbar_mainbox_fgcolor = "#000000";
set captionbar_userpicbox_color = "#9d995d";
set accent_bgcolor = "#704400";
set accent_fgcolor = "#bababa";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#6a20ff";
set comment_bar_one_bgcolor = "#54442c";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#704400";
set comment_bar_two_fgcolor = "#bababa";
#NEWLAYER: tabularindent/victim
layerinfo type = theme;
layerinfo name = "Victim";
layerinfo redist_uniq = "tabularindent/victim";
set body_bgcolor = "#2cd0ff";
set main_bgcolor = "#505050";
set main_fgcolor = "#ffffff";
set border_color = "#000000";
set headerbar_bgcolor = "#166bac";
set headerbar_fgcolor = "#ffffff";
set captionbar_mainbox_bgcolor = "#2098f3";
set captionbar_mainbox_fgcolor = "#ffffff";
set captionbar_userpicbox_color = "#26b6ff";
set accent_bgcolor = "#353535";
set accent_fgcolor = "#ffffff";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#ff00c0";
set comment_bar_one_bgcolor = "#166bac";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#353535";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: tabularindent/forest
layerinfo type = theme;
layerinfo name = "Forest";
layerinfo redist_uniq = "tabularindent/forest";
set body_bgcolor = "#778e64";
set main_bgcolor = "#9b9ba5";
set main_fgcolor = "#000000";
set border_color = "#ffffff";
set headerbar_bgcolor = "#72784c";
set headerbar_fgcolor = "#ffffff";
set captionbar_mainbox_bgcolor = "#72784c";
set captionbar_mainbox_fgcolor = "#ffffff";
set captionbar_userpicbox_color = "#a0ac62";
set accent_bgcolor = "#73777a";
set accent_fgcolor = "#000000";
set link_color = "#3811e1";
set vlink_color = "#310cbb";
set alink_color = "#4e7bef";
set comment_bar_one_bgcolor = "#72784c";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#73777a";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: tabularindent/drone
layerinfo type = theme;
layerinfo name = "Drone";
layerinfo redist_uniq = "tabularindent/drone";
set body_bgcolor = "#395f82";
set main_bgcolor = "#f9fcfe";
set main_fgcolor = "#000000";
set border_color = "#000000";
set headerbar_bgcolor = "#904094";
set headerbar_fgcolor = "#ffffff";
set captionbar_mainbox_bgcolor = "#f56efc";
set captionbar_mainbox_fgcolor = "#ffffff";
set captionbar_userpicbox_color = "#ff93ff";
set accent_bgcolor = "#eeeeff";
set accent_fgcolor = "#000000";
set link_color = "#395f82";
set vlink_color = "#395f82";
set alink_color = "#5266ce";
set comment_bar_one_bgcolor = "#904094";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#eeeeff";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: tabularindent/lowercurtain
layerinfo type = theme;
layerinfo name = "Lower the Curtain";
layerinfo redist_uniq = "tabularindent/lowercurtain";
set body_bgcolor = "#000000";
set main_bgcolor = "#6b6b6b";
set main_fgcolor = "#ffffff";
set border_color = "#ffffff";
set headerbar_bgcolor = "#363636";
set headerbar_fgcolor = "#f0f5fb";
set captionbar_mainbox_bgcolor = "#c6c6c6";
set captionbar_mainbox_fgcolor = "#222222";
set captionbar_userpicbox_color = "#363636";
set accent_bgcolor = "#c5c8ca";
set accent_fgcolor = "#000000";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#3314ba";
set comment_bar_one_bgcolor = "#363636";
set comment_bar_one_fgcolor = "#f0f5fb";
set comment_bar_two_bgcolor = "#c5c8ca";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: tabularindent/sunny
layerinfo type = theme;
layerinfo name = "Sunny Day";
layerinfo redist_uniq = "tabularindent/sunny";
set body_bgcolor = "#55e0f9";
set main_bgcolor = "#e38202";
set main_fgcolor = "#ffffff";
set border_color = "#000000";
set headerbar_bgcolor = "#e38202";
set headerbar_fgcolor = "#ffffff";
set captionbar_mainbox_bgcolor = "#fff505";
set captionbar_mainbox_fgcolor = "#ffffff";
set captionbar_userpicbox_color = "#efe052";
set accent_bgcolor = "#ffba03";
set accent_fgcolor = "#ffffff";
set link_color = "#df0d12";
set vlink_color = "#ac1b25";
set alink_color = "#fe3b3b";
set comment_bar_one_bgcolor = "#ffba03";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#ffba36";
set comment_bar_two_fgcolor = "#ffffff";
#NEWLAYER: tabularindent/valentine
layerinfo type = theme;
layerinfo name = "Be Mine";
layerinfo redist_uniq = "tabularindent/valentine";
set body_bgcolor = "#6f104a";
set main_bgcolor = "#f2bce9";
set main_fgcolor = "#000000";
set border_color = "#ff24ab";
set headerbar_bgcolor = "#ff37ff";
set headerbar_fgcolor = "#ffffff";
set captionbar_mainbox_bgcolor = "#df2096";
set captionbar_mainbox_fgcolor = "#ffffff";
set captionbar_userpicbox_color = "#ae1774";
set accent_bgcolor = "#df2096";
set accent_fgcolor = "#000000";
set link_color = "#ffffff";
set vlink_color = "#a51014";
set alink_color = "#ed8188";
set comment_bar_one_bgcolor = "#ff37ff";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#df2096";
set comment_bar_two_fgcolor = "#000000";
#NEWLAYER: tabularindent/stripes
layerinfo type = theme;
layerinfo name = "Stripes";
layerinfo redist_uniq = "tabularindent/stripes";
set body_bgcolor = "#ffffff";
set main_bgcolor = "#ffffff";
set main_fgcolor = "#000000";
set border_color = "#ff0000";
set headerbar_bgcolor = "#e7212a";
set headerbar_fgcolor = "#ffffff";
set captionbar_mainbox_bgcolor = "#ffffff";
set captionbar_mainbox_fgcolor = "#000000";
set captionbar_userpicbox_color = "#ffffff";
set accent_bgcolor = "#ffcfdc";
set accent_fgcolor = "#000000";
set link_color = "#000050";
set vlink_color = "#500050";
set alink_color = "#ffafc1";
set comment_bar_one_bgcolor = "#e7212a";
set comment_bar_one_fgcolor = "#ffffff";
set comment_bar_two_bgcolor = "#ffcfdc";
set comment_bar_two_fgcolor = "#000000";

View File

@@ -0,0 +1,967 @@
layerinfo "type" = "layout";
layerinfo "name" = "Variable Flow";
layerinfo "author_name" = "Martin Atkins";
layerinfo "des" = "A really simple layout that you can customize like crazy!";
layerinfo "redist_uniq" = "variableflow/layout";
layerinfo "previews" = "variableflow/preview.jpg";
# Originally known as "Cleanly Shaven"
#
# This layout is full of customization options, and is designed
# with code overrides in mind.
# It also uses meaningful markup an CSS, for those who like that
# sort of thing. If you like, you can override the stylesheet
# completely in your user layer to drastically change the
# presentation.
propgroup colors {
property Color clr_margin {
des = "Page Background Color";
}
property Color clr_line {
des = "Color of line separating the entry area from the background";
requires = "opt_page_border";
}
property Color clr_back {
des = "Background Color of Main Content Area";
requires = "opt_page_background";
}
property Color clr_text {
des = "Main Text Color";
}
property Color clr_link {
des = "Color of normal links";
}
property Color clr_vlink {
des = "Color of visited links";
}
property Color clr_alink {
des = "Color of links once clicked on";
}
property Color clr_title {
des = "Journal Title Color";
}
set clr_margin = "#337CCD";
set clr_line = "#000000";
set clr_back = "#33ABCD";
set clr_text = "#000000";
set clr_link = "#261A72";
set clr_vlink = "#190F57";
set clr_alink = "#261A72";
set clr_title = "#190F57";
}
propgroup layout {
property string margin_left {
des = "Page Left Margin Size";
values = "0|None|5px|Tiny|5%|Small|10%|Medium|25%|Large|50%|Massive";
}
property string margin_right {
des = "Page Right Margin Size";
values = "0|None|5px|Tiny|5%|Small|10%|Medium|25%|Large|50%|Massive";
}
property string margin_top {
des = "Page Top Margin Size";
values = "0|None|5px|Tiny|5%|Small|10%|Medium|25%|Large|50%|Massive";
}
property string margin_bottom {
des = "Page Bottom Margin Size";
values = "0|None|5px|Tiny|5%|Small|10%|Medium|25%|Large|50%|Massive";
}
set margin_left = "25%";
set margin_right = "25%";
set margin_top = "5px";
set margin_bottom = "5px";
property string padding_left {
des = "Page Left Inner Padding Size";
values = "0|None|5px|Tiny|5%|Small|10%|Medium|25%|Large|50%|Massive";
}
property string padding_right {
des = "Page Right Inner Padding Size";
values = "0|None|5px|Tiny|5%|Small|10%|Medium|25%|Large|50%|Massive";
}
property string padding_top {
des = "Page Top Inner Padding Size";
values = "0|None|5px|Tiny|5%|Small|10%|Medium|25%|Large|50%|Massive";
}
property string padding_bottom {
des = "Page Bottom Inner Padding Size";
values = "0|None|5px|Tiny|5%|Small|10%|Medium|25%|Large|50%|Massive";
}
set padding_left = "5px";
set padding_right = "5px";
set padding_top = "5px";
set padding_bottom = "5px";
property string align_viewlinks {
des = "Position of links to other journal views";
values = "left|Left|right|Right|center|Center";
}
property string align_title {
des = "Position of journal title";
values = "left|Left|right|Right|center|Center";
}
property string align_talklinks {
des = "Position of comment links";
values = "left|Left|right|Right|center|Center";
}
set align_viewlinks = "right";
set align_title = "left";
set align_talklinks = "right";
# Some "advanced" settings which don't appear in the UI,
# either because they have non-obvious interactions with
# other properties or they have issues in certain browsers.
property string adv_page_max_width {
des = "Maximum Width of Content Area";
note = "If you set this, you should also set margin_left and/or margin_right to 'auto'. Internet Explorer 6 does not support this property.";
noui = 1;
}
property string adv_entry_max_width {
des = "Maximum Width of Entry Text";
note = "Internet Explorer 6 does not support this property, and will present entries full-width.";
noui = 1;
}
property bool adv_enable_print_styles {
des = "Enable Print Stylesheet";
note = "If you disable this, your journal views may be unsuitable for printing.";
noui = 1;
}
property bool adv_enable_projection_styles {
des = "Enable Projection Stylesheet";
note = "With this enabled, browsers which support projection stylesheets will see a different stylesheet.";
noui = 1;
}
property bool adv_horrible_userpic_markup {
des = "Enable horrible userpic markup";
note = "With this enabled, the layout will use a table hack to present userpics. With it disabled, the userpics will just be shown raw with class userpic. You'll have to add your own stylesheet rules for them.";
# See the comment within Page::print_entry for more details
noui = 1;
}
set adv_page_max_width = "";
set adv_entry_max_width = "";
set adv_enable_print_styles = true;
set adv_enable_projection_styles = true;
set adv_horrible_userpic_markup = true;
}
propgroup presentation {
property use font_base;
property use font_fallback;
property string font_size {
des = "Size of text";
values = "0.75em|Tiny|1em|Normal|1.1em|Large";
}
set font_size = "0.75em";
property bool opt_page_border {
des = "Draw Line Around Content Box";
note = "With this disabled, the line color option has no effect";
}
property bool opt_page_background {
des = "Content Box has Background";
note = "With this disabled, the Content Box Background Color and Image options have no effect and the page background will show through instead.";
}
set opt_page_border = true;
set opt_page_background = true;
property string url_background_img_page {
des = "Page Background Image URL";
note = "Leave this blank if you do not wish to use a background image.";
palimg_transform = "tint;*clr_back"; # Doesn't do anything right now
}
set url_background_img_page = "";
property string background_properties_page {
des = "Page Background Image Display Options";
values = "scroll|Scrolling, Tiled|scroll no-repeat|Scrolling, No repeat|scroll repeat-x|Scrolling, tile horizontally|scroll repeat-y|Scrolling, tile vertically|fixed|Fixed, Tiled|fixed no-repeat|Fixed, No repeat|fixed repeat-x|Fixed, tile horizontally|fixed repeat-y|Fixed, tile vertically";
requires = "url_background_img_page";
}
set background_properties_page = "scroll";
property string background_position_page {
des = "Page Background Position";
values = "center|Centered|center left|Centered Vertically, Left|center right|Centered Vertically, Right|top center|Top, Centered Horizontally|top left|Top, Left|top right|Top, Right|bottom center|Bottom, Centered Horizontally|bottom left|Bottom, Left|bottom right|Bottom, Right";
requires = "url_background_img_page";
}
set background_position_page = "top left";
property string url_background_img_box {
des = "Content Box Background Image URL";
note = "Leave this blank if you do not wish to use a background image.";
palimg_transform = "tint;*clr_back"; # Doesn't do anything right now
requires = "opt_page_background";
}
set url_background_img_box = "";
property string background_properties_box {
des = "Content Box Background Image Display Options";
values = "scroll|Scrolling, Tiled|scroll no-repeat|Scrolling, No repeat|scroll repeat-x|Scrolling, tile horizontally|scroll repeat-y|Scrolling, tile vertically|fixed|Fixed, Tiled|fixed no-repeat|Fixed, No repeat|fixed repeat-x|Fixed, tile horizontally|fixed repeat-y|Fixed, tile vertically";
requires = "opt_page_background,url_background_img_box";
}
set background_properties_box = "scroll";
property string background_position_box {
des = "Content Box Background Position";
values = "center|Centered|center left|Centered Vertically, Left|center right|Centered Vertically, Right|top center|Top, Centered Horizontally|top left|Top, Left|top right|Top, Right|bottom center|Bottom, Centered Horizontally|bottom left|Bottom, Left|bottom right|Bottom, Right";
requires = "opt_page_background,url_background_img_box";
}
set background_position_box = "top left";
property bool opt_entry_userpics {
des = "Enable Userpics On Entries";
note = "With this disabled, no entries will show userpics, even on the friends page.";
}
set opt_entry_userpics = true;
property bool opt_own_userpics {
des = "Show Own Userpics";
note = "Enable this to show userpics on your own entries. You must also have the previous option enabled. This option has no effect on community journals.";
requires = "opt_entry_userpics";
}
set opt_own_userpics = false;
# This layout has quite a big stylesheet so let's avoid
# transferring it over and over.
set external_stylesheet = true;
# No good support for EntryPage/ReplyPage yet
set view_entry_disabled = true;
}
propgroup options {
# Some standard constructional properties
property use page_recent_items;
property use page_friends_items;
property use page_year_sortorder;
property use page_day_sortorder;
# Tell the system this layout has no linklist support
# If you add linklist support in a user layer, you should also
# set this property to true in your layer.
set linklist_support = false;
}
propgroup text {
property use text_post_comment;
property use text_read_comments;
property use text_post_comment_friends;
property use text_read_comments_friends;
}
function makefontspec() : string
"Forms a CSS 'font-family' value based on the font-related properties."
{
var string fontspec;
if ($*font_base != "") {
$fontspec="\""+$*font_base+"\"";
if ($*font_fallback != "") {
$fontspec=$fontspec+",";
}
}
$fontspec=$fontspec+$*font_fallback;
return $fontspec;
}
function Page::lay_print_viewlinks()
"If you override this, be sure to still use foreach or your style won't support any future views."
{
# Output a list of textual links in a particular order
var bool first = true;
"<ul class=\"navbar\">\n";
foreach var string vl ($.views_order) {
if ($vl == $.view) {
print "<li class=\"active\">"+lang_viewname($vl)+"</li>\n";
} else {
print "<li><a href=\""+ehtml($.view_url{$vl})+"\">"+lang_viewname($vl)+"</a></li>\n";
}
$first = false;
}
"</ul>\n";
}
function Page::lay_print_heading()
"This can be overridden to change the main page titles to something else."
{
"""<h1>"""+$.global_title+"""</h1>
<div id="viewtitle">""";
if ($.view == "recent" and $.global_subtitle != "") {
print $.global_subtitle;
} else {
print $this->view_title();
}
println """</div>""";
}
function Page::print() {
"""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">
<html>
<head>
<title>"""+$this->title()+"""</title>
""";
if ($*external_stylesheet) {
println """<link rel="stylesheet" href="$.stylesheet_url" type="text/css" />""";
}
else {
println """<style type="text/css">""";
print_stylesheet();
println """</style>""";
}
$this->print_head();
"""
</head>
<body class="$.view">
<div id="page">
"""; $this->lay_print_viewlinks(); """
<div id="title">
"""; $this->lay_print_heading(); """
</div>
"""; $this->print_body(); """
<div id="serversig" style="margin-top: 3em; text-align: center;">"""; server_sig(); """</div>
</div>
</body>
</html>""";
}
function lang_skipped_back(RecentNav nav) : string
"Return short text saying how many entries have been skipped back. i18n layers should override this."
{
return "Skipped Back $nav.skip";
}
## The properties for these links are currently broken
## in core - they were never updated to work with lang_map_plural.
# So, FIXME: When core does them right, remove the hardcoded English
function RecentPage::lay_print_skiplinks() {
if ($.nav.backward_url != "" or $.nav.forward_url != "") {
println """<ul class="viewspecnavbar">""";
if ($.nav.backward_url) {
println """<li><a href="$.nav.backward_url">Previous $.nav.backward_count</a></li>""";
}
if ($.nav.skip > 0) {
println "<li>"+lang_skipped_back($.nav)+"</li>";
}
if ($.nav.forward_url) {
println """<li><a href="$.nav.forward_url">Next $.nav.forward_count</a></li>""";
}
println "</ul>";
}
}
function RecentPage::print_body() {
$this->lay_print_skiplinks();
foreach var Entry e ($.entries) {
if ($e.new_day) {
"""<div class="day" id="day"""+$e.time->date_format("%%yyyy%%%%mm%%%%dd%%")+"\">\n";
}
# Print the entry
$this->print_entry($e);
if ($e.end_day) {
"</div>";
}
}
if (size $.entries > 0) {
$this->lay_print_skiplinks();
}
}
function DayPage::print_body() {
"""<ul class="viewspecnavbar">\n""";
"<li><a href=\"$.prev_url\">$*text_day_prev</a></li>\n";
"<li><a href=\"$.next_url\">$*text_day_next</a></li>\n</ul>";
if ($.has_entries) {
"<div class=\"day\" id=\"dayyymmmmmdddd\">\n";
foreach var Entry e ($.entries) {
$this->print_entry($e);
}
"</div>";
"<div class=\"skiplinks\">\n";
"<a href=\"$.prev_url\">$*text_day_prev</a> - ";
"<a href=\"$.next_url\">$*text_day_next</a>\n</div>";
} else {
"<p>$*text_noentries_day</p>";
}
}
## YearPage Stuff
function YearPage::print_body {
$this->print_year_links();
println """<div id="calendarmonthcontainer">""";
foreach var YearMonth m ($.months) {
$this->print_month($m);
}
println "</div>";
}
function YearPage::print_year_links() {
"""<ul class="viewspecnavbar">\n""";
foreach var YearYear y ($.years) {
if ($y.displayed) {
"""<li class="active">$y.year</li>\n""";
} else {
"""<li><a href="$y.url">$y.year</a></li>\n""";
}
}
"""</ul>\n""";
}
function YearPage::print_month(YearMonth m) {
if (not $m.has_entries) { return; }
"""<table class="calendarmonth">\n
<tr><th colspan="7" style="text-align: center;">""";
print "<h2>"+$m->month_format()+"</h2>\n";
"""</th></tr>\n""";
foreach var int d (weekdays()) {
"<th>"+$*lang_dayname_short[$d]+"</th>\n";
}
"</tr>\n";
foreach var YearWeek w ($m.weeks) {
$w->print();
}
"""<tr><td colspan="7" style="text-align: center;" class="calendarmonthlink">
<a href="$m.url">$*text_view_month</a></td></tr>\n""";
"</table>";
}
function YearWeek::print() {
"""<tr valign="top" style="height: 3em;">\n""";
if ($.pre_empty > 0) {
"""<td class="emptyday" colspan="$.pre_empty">&nbsp;</td>\n""";
}
foreach var YearDay d ($.days) {
"""<td class="calendarday">\n""";
"""<div style="text-align: right;">$d.day</div>\n""";
if ($d.num_entries > 0) {
"""<div style="text-align: center;"><a href="$d.url">$d.num_entries</a></div>\n""";
}
"""</td>\n""";
}
if ($.post_empty > 0) {
"""<td colspan="$.post_empty">&nbsp;</td>\n""";
}
"</tr>";
}
function metadata_title(string which) : string
"Until core provides a function for this, i18n layers should override this."
{
if ($which == "music") {
return "Current Music";
}
elseif ($which == "mood") {
return "Current Mood";
}
else {
return $which;
}
}
# Since there's currently no trusted print_entry_text function
# in core, I have to do this here. Later, when something similar
# is added to core, this can become a wrapper and be deprecated.
function Page::lay_print_entry_text(Entry e) [fixed]
"Don't override this. All it does is print the entry text."
{
print $e.text;
}
# Since the metadata keys have to be hardcoded (bad core design)
# let's separate this out so people can override print_entry
# and still get any new metadata added later.
function Page::lay_print_entry_metadata(Entry e)
"Overriding this is strongly discouraged, since if any new entry metadata is added in the future your overridden version will not support it."
{
if (size $e.metadata > 0) {
# This is horrible and unextensible. We have core to thank.
# C'est la vie.
"<div class=\"metadata\">\n";
if ($e.metadata{"music"} != "") {
"""<div class="currentmusic"><span class="metacaption">"""+metadata_title("music") + ":</span> " +
$e.metadata{"music"}+"</div>\n";
}
if ($e.metadata{"mood"} != "") {
"""<div class="currentmood"><span class="metacaption">"""+metadata_title("mood") + ":</span> ";
if (defined $e.mood_icon) {
print $e.mood_icon->as_string()+" ";
}
print $e.metadata{"mood"}+"</div>\n";
}
"</div>\n";
}
}
function Page::print_entry(Entry e) {
"""<div class="entry" id="entry$e.itemid">\n""";
var bool altposter = $e.poster.username != $e.journal.username;
var bool showpic = $*opt_entry_userpics and (($.view == "friends" or $altposter) or $*opt_own_userpics);
# By default, this layout uses an ugly table hack to present the userpic
# alongside the entry. This is because I've been bitten on many previous
# occasions by a bug with floats in IE causing text to vanish in certain
# cases. You can set the property adv_horrible_userpic_markup to false
# in a user layer to disable this behavior, but there are no CSS rules
# in the stock stylesheet to handle it, so you'll have to supply your
# own.
if ($showpic) {
if ($*adv_horrible_userpic_markup) {
"""<table cellpadding="0" border="0" cellspacing="0" style="margin: 0;" class="uglykludgeuserpic">
<tr valign="top">
<td style="text-align: center;" width="105">""";
}
if (defined $e.userpic) {
println """<img src="$e.userpic.url" width="$e.userpic.width" width="$e.userpic.height" alt="" class="userpic" />""";
} else {
if ($*adv_horrible_userpic_markup) {
print "&nbsp;";
}
}
if ($*adv_horrible_userpic_markup) {
"</td><td>";
}
}
"""<h2 class="entryheading">""";
if ($.view != "day") {
print $e.time->date_format()+" ";
}
print $e.time->time_format();
if ($.view == "friends") {
" - "; $this->print_entry_poster($e);
}
elseif ($altposter) {
" - " + $e.poster->as_string();
}
if ($e.security != "") {
" - " + $e.security_icon->as_string();
}
if ($e.subject != "") {
" - $e.subject";
}
"</h2>\n"; $this->lay_print_entry_text($e);
$this->lay_print_entry_metadata($e);
if ($showpic and $*adv_horrible_userpic_markup) {
"</td></tr></table>";
}
$e.comments->print();
"</div>";
}
function CommentInfo::print {
if (not $.enabled) { return; }
"""<ul class="entryextra">""";
if ($.count > 0) {
print """<li class="entryreadlink">""";
$this->print_readlink();
println "</li>";
}
print """<li class="entrypostlink">""";
$this->print_postlink();
print "</li>";
"</ul>";
}
function EntryPage::print_comment (Comment c) {
var Color barlight = $*color_comment_bar->clone();
$barlight->lightness(($barlight->lightness() + 255) / 2);
var string poster = defined $c.poster ? $c.poster->as_string() : "<i>(Anonymous)</i>";
"<div style='margin-top: 10px; padding: 2px'>";
"<table summary='0' style='width: 100%;'><tr valign='top'>";
if (defined $c.userpic and $*comment_userpic_style != "off") {
var int w = $c.userpic.width;
var int h = $c.userpic.height;
# WARNING: this will later be done by the system (it'll be a
# constructional property), so don't copy this hack into your
# layout layers or you'll be messed up later.
$w = $w / 2;
$h = $h / 2;
print "<td><img src='$c.userpic.url' width='$w' height='$h' alt='' /></td>";
}
"<td align='left'>";
if (defined $c.subject_icon or $c.subject != "") { "<h3>$c.subject_icon $c.subject</h3>\n"; }
print "<strong>$*text_comment_from</strong> $poster<br />\n";
print "<strong>$*text_comment_date</strong> ";
print $c.time->date_format("long") + " - " + $c.time->time_format();
if ($c.metadata{"poster_ip"}) { print " ($*text_comment_ipaddr " + $c.metadata{"poster_ip"} + ")"; }
print " <strong>(<a href='$c.permalink_url'>$*text_permalink</a>)</strong>\n";
var Link link;
foreach var string s (["delete_comment", "screen_comment", "unscreen_comment"]) {
}
$link = $c->get_link("delete_comment"); " $link";
$link = $c->get_link("screen_comment"); " $link";
$link = $c->get_link("unscreen_comment"); " $link";
if ($this.multiform_on) {
" <label for='ljcomsel_$c.talkid'>$*text_multiform_check</label> ";
$c->print_multiform_check();
}
print "</td></tr></table></div>";
print "<div style='margin-left: 5px'>$c.text</div>\n";
print "<div style='margin-top: 3px; font-size: smaller'>(<a href='$c.reply_url'>$*text_comment_reply</a>) ";
if ($c.parent_url != "") { "(<a href='$c.parent_url'>$*text_comment_parent</a>) "; }
if ($c.thread_url != "") { "(<a href='$c.thread_url'>$*text_comment_thread</a>) "; }
"</div>\n";
}
function css_rule_if_set(string prop, string val)
"Print a CSS rule only if val is not an empty string."
{
if ($val != "") {
println " $prop: $val;";
}
}
function custom_stylesheet()
"Override this in your user layer to add new stuff to the stylesheet"
{
# None, by default
}
function print_stylesheet_for_printing()
"If you have printing styles enabled, you can override this function to change how the page is styled for printing."
{
""" body, #page, a, a:link, a:visited, a:active, a:hover, #title, h2 {
background: #ffffff;
color: #000000;
}
body {
margin-top: 1em;
margin-bottom: 1em;
font-size: 12pt;
margin-left: auto;
margin-right: auto;
font-family: "Garamond", "Palatino", "Palatino Linotype", serif;
max-width: 15cm;
}
h1, h2, h3, h4, h5, h6, #title #viewtitle {
font-family: "Frutiger", "Frutiger Linotype", "Helvetica", sans-serif;
page-break-after: avoid;
}
.entry {
page-break-inside: avoid;
text-align: justify;
}
.calendarmonth {
page-break-inside: avoid;
}
#page {
border: 0;
margin: 0;
}
.navbar, .entryextra, .viewspecnavbar {
display: none;
}
#title {
display: block;
}
#title h1, #title #viewtitle {
display: inline;
}
#title #viewtitle {
margin-left: 2em;
font-style: italic;
}
""";
}
function print_stylesheet_for_projection()
"If you have projection styles enabled, you can override this function to change how the page is styled for projection."
{
var string background_body = $*clr_margin;
if ($*url_background_img_page != "" and not $*url_background_img_page->contains(")")) {
$background_body = $background_body + " url($*url_background_img_page)";
if (not $*background_properties_page->contains(";")) {
$background_body = $background_body + " $*background_properties_page";
}
}
else {
$background_body = $background_body + " none";
}
var string background_page = $*clr_back;
if ($*url_background_img_box != "" and not $*url_background_img_box->contains(")")) {
$background_page = $background_page + " url($*url_background_img_box)";
if (not $*background_properties_box->contains(";")) {
$background_page = $background_page + " $*background_properties_box";
}
}
else {
$background_page = $background_page + " none";
}
""" #page {
margin: 10px;
padding: 0;
border: 0;
font-size: 2em;
}
body {
background: $background_body;
color: $*clr_text;
}
.navbar, .viewspecnavbar { display: none; }
.entry, #title {
page-break-after: always;
margin: auto;
padding: 10px;
position: absolute;
top: 10px;
bottom: 10px;
left: 10px;
right: 10px;
""";
if ($*opt_page_border) {
println """ border: 1px solid $*clr_line;""";
}
if ($*opt_page_background) {
println """ background: $background_page;""";
}
" }\n";
}
function print_stylesheet() {
var string fontspec=makefontspec();
if ($fontspec != "") {
$fontspec=" font-family: $fontspec;";
}
var string eextrastyle="";
if ($*align_talklinks != "right") {
$eextrastyle=$eextrastyle+
""".entryextra:after { content: " :."; }\n""";
}
if ($*align_talklinks != "left") {
$eextrastyle=$eextrastyle+
""".entryextra:before { content: ".: "; }\n""";
}
$eextrastyle=$eextrastyle+
""".entryextra { text-align: $*align_talklinks; font-size: 0.9em; }""";
# This tries to do a bit of "sanity" checking to ensure users
# don't inadvertently break the CSS, but it's not brilliant.
var string background_body = $*clr_margin;
if ($*url_background_img_page != "" and not $*url_background_img_page->contains(")")) {
$background_body = $background_body + " url($*url_background_img_page)";
if (not $*background_properties_page->contains(";")) {
$background_body = $background_body + " $*background_properties_page";
}
if (not $*background_position_page->contains(";")) {
$background_body = $background_body + " $*background_position_page";
}
}
else {
$background_body = $background_body + " none";
}
var string background_page = $*clr_back;
if ($*url_background_img_box != "" and not $*url_background_img_box->contains(")")) {
$background_page = $background_page + " url($*url_background_img_box)";
if (not $*background_properties_box->contains(";")) {
$background_page = $background_page + " $*background_properties_box";
}
if (not $*background_position_box->contains(";")) {
$background_page = $background_page + " $*background_position_box";
}
}
else {
$background_page = $background_page + " none";
}
"""
body {
margin: 0;
padding: 0;
border: 0;
background: $background_body;
color: $*clr_text;
$fontspec font-size: $*font_size;
}
table, tr, td, th {
font-size: 1em;
}
#page {
""";
css_rule_if_set("margin-left", $*margin_left);
css_rule_if_set("margin-right", $*margin_right);
css_rule_if_set("margin-top", $*margin_top);
css_rule_if_set("margin-bottom", $*margin_bottom);
css_rule_if_set("padding-left", $*padding_left);
css_rule_if_set("padding-right", $*padding_right);
css_rule_if_set("padding-top", $*padding_top);
css_rule_if_set("padding-bottom", $*padding_bottom);
css_rule_if_set("max-width", $*adv_page_max_width);
if ($*opt_page_border) {
println """ border: 1px solid $*clr_line;""";
}
if ($*opt_page_background) {
println """ background: $background_page;""";
}
"""
}
#title h1 {
font-size: 1.4em;
font-weight: bold;
text-align: $*align_title;
margin: 0;
}
#title #viewtitle {
font-size: 1.1em;
font-weight: bold;
text-align: $*align_title;
margin: 0;
}
.navbar {
text-align: $*align_viewlinks;
list-style: none;
padding: 0;
margin: 0;
display: block;
}
.viewspecnavbar {
text-align: center;
list-style: none;
padding: 0;
margin: 0;
display: block;
margin-top: 1em;
margin-bottom: 1em;
}
.navbar li { display: inline; white-space: nowrap; }
.navbar li.active { display: inline; }
.navbar li:before { content: " :: "; }
.navbar li:first-child:before { content: ""; }
.viewspecnavbar li { display: inline; white-space: nowrap; }
.viewspecnavbar li.active { display: inline; }
.viewspecnavbar li:before { content: " :: "; }
.viewspecnavbar li:first-child:before { content: ""; }
#title {
margin-top: 3em;
margin-bottom: 0.5em;
color: $*clr_title;
background: transparent;
}
a:link { color: $*clr_link; background: transparent; }
a:visited { color: $*clr_vlink; background: transparent; }
a:active, a:hover { color: $*clr_alink; background: transparent; }
.entry {
margin-bottom: 4em;
}
.entryheading {
font-weight: bold; font-size: 1.0em;
}
.entrytext {
"""; css_rule_if_set("max-width", $*adv_entry_max_width);
""" margin-left: auto;
margin-right: auto;
}
.entry .metadata {
margin-top: 0.5em;
margin-bottom: 0;
margin-left: 0;
margin-right: 0;
}
.entryextra {
list-style: none;
padding: 0;
margin-left: 0;
margin-right: 0;
display: block;
}
.entryextra li {
display: inline;
}
.entryextra li.entryreadlink:after {
content: " :: ";
}
.entryextra li.entryreadlink {
font-weight: bold;
}
$eextrastyle
/* IE hack - center the block with text-align! */
.calendarmonthcontainer {
text-align: center;
}
.calendarmonth {
margin-top: 2em;
margin-bottom: 2em;
margin-left: auto;
margin-right: auto;
text-align: left;
}
.calendarmonth h2 {
font-size: 1em;
font-weight: bold;
margin: 0;
}
.calendarday {
width: 3em;
max-width: 3em;
height: 3em;
}
""";
if ($*adv_enable_print_styles) {
"""
@media print {
"""; print_stylesheet_for_printing(); """
}
""";
}
if ($*adv_enable_projection_styles) {
"""
@media projection {
"""; print_stylesheet_for_projection(); """
}
""";
}
custom_stylesheet();
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -0,0 +1,73 @@
#!/usr/bin/perl
use strict;
$| = 1;
require "$ENV{'LJHOME'}/cgi-bin/ljlib.pl";
my $sysid = LJ::get_userid("system");
die "Couldn't find system userid"
unless $sysid;
my $dbh = LJ::get_db_writer();
die "Could not connect to global master"
unless $dbh;
# find info on styles based on public layouts
# need to select from:
# s2styles - get style name
# s2stylelayers - get layout s2lid
# s2layers - get userid of layer
# s2info - get redist_uniq
{
print "Converting styles based on public layouts...";
my $sth = $dbh->prepare("SELECT s.styleid, i.value " .
"FROM s2styles s, s2stylelayers sl, s2layers l, s2info i " .
"WHERE s.styleid=sl.styleid AND l.s2lid=sl.s2lid AND i.s2lid=l.s2lid " .
"AND l.userid=? AND l.type='layout' AND s.name='wizard' " .
"AND i.infokey='redist_uniq'");
$sth->execute($sysid);
my $ct = 0;
while (my ($styleid, $redist_uniq) = $sth->fetchrow_array) {
my $layout = (split("/", $redist_uniq))[0];
$dbh->do("UPDATE s2styles SET name=? WHERE styleid=?",
undef, "wizard-$layout", $styleid);
$ct++;
print "." if $ct % 1000 == 0;
}
print " $ct done.\n";
}
# find info on styles based on user layouts
# need to select from:
# s2styles - get style name
# s2stylelayers - get layout s2lid
# s2layers - get userid of layer
{
print "Converting styles based on user layouts...";
my $sth = $dbh->prepare("SELECT s.styleid, l.s2lid " .
"FROM s2styles s, s2stylelayers sl, s2layers l " .
"WHERE s.styleid=sl.styleid AND l.s2lid=sl.s2lid " .
"AND l.userid<>? AND l.type='layout' AND s.name='wizard'");
$sth->execute($sysid);
my $ct = 0;
while (my ($styleid, $s2lid) = $sth->fetchrow_array) {
$dbh->do("UPDATE s2styles SET name=? WHERE styleid=?",
undef, "wizard-$s2lid", $styleid);
$ct++;
print "." if $ct % 1000 == 0;
}
print " $ct done.\n";
}

View File

@@ -0,0 +1,21 @@
#!/usr/bin/perl
#
require "$ENV{'LJHOME'}/cgi-bin/ljlib.pl";
my $dbh = LJ::get_dbh("master");
my $sth;
$sth = $dbh->prepare("SELECT spid FROM support WHERE timelasthelp IS NULL");
$sth->execute;
while (my ($spid) = $sth->fetchrow_array)
{
print "Fixing $spid...\n";
my $st2 = $dbh->prepare("SELECT MAX(timelogged) FROM supportlog WHERE spid=$spid AND type='answer'");
$st2->execute;
my ($max) = $st2->fetchrow_array;
$max = $max + 0; # turn undef -> 0
print " time = $max\n";
$dbh->do("UPDATE support SET timelasthelp=$max WHERE spid=$spid");
}

View File

@@ -0,0 +1,9 @@
# Note to people using LJ Server software:
# Do not modify this file. Create text-local.dat, and that will
# be read as well. See LiveJournal.com's text-local.dat in ljcom CVS.
# one language, english, which is the master of one domain (general)
lang:1:en:English
domain:1:general
langdomain:en:general:1

View File

@@ -0,0 +1,690 @@
#!/usr/bin/perl
#
# This program deals with inserting/extracting text/language data
# from the database.
#
use strict;
use Getopt::Long;
my $opt_help = 0;
my $opt_local_lang;
my $opt_extra;
my $opt_only;
my $opt_override;
my $opt_verbose;
exit 1 unless
GetOptions(
"help" => \$opt_help,
"local-lang=s" => \$opt_local_lang,
"extra=s" => \$opt_extra,
"override|r" => \$opt_override,
"verbose" => \$opt_verbose,
"only=s" => \$opt_only,
);
my $mode = shift @ARGV;
help() if $opt_help or not defined $mode;
sub help
{
die "Usage: texttool.pl <command>
Where 'command' is one of:
load Runs the following four commands in order:
popstruct Populate lang data from text[-local].dat into db
poptext Populate text from en.dat, etc into database.
--extra=<file> specifies an alternative input file
--override (-v) specifies existing values should be overwritten
for all languages. (for developer use only)
copyfaq If site is translating FAQ, copy FAQ data into trans area
loadcrumbs Load crumbs from ljcrumbs.pl and ljcrumbs-local.pl.
makeusable Setup internal indexes necessary after loading text
dumptext Dump lang text based on text[-local].dat information
check Check validity of text[-local].dat files
wipedb Remove all language/text data from database, including crumbs.
wipecrumbs Remove all crumbs from the database, leaving other text alone.
newitems Search files in htdocs, cgi-bin, & bin and insert
necessary text item codes in database.
remove takes two extra arguments: domain name and code, and removes
that code and its text in all languages
Optionally:
--local-lang=.. If given, works on local site files too
";
}
## make sure $LJHOME is set so we can load & run everything
unless (-d $ENV{'LJHOME'}) {
die "LJHOME environment variable is not set, or is not a directory.\n".
"You must fix this before you can run this database update script.";
}
require "$ENV{'LJHOME'}/cgi-bin/ljlib.pl";
require "$ENV{'LJHOME'}/cgi-bin/ljlang.pl";
require "$ENV{'LJHOME'}/cgi-bin/weblib.pl";
my %dom_id; # number -> {}
my %dom_code; # name -> {}
my %lang_id; # number -> {}
my %lang_code; # name -> {}
my @lang_domains;
my $set = sub {
my ($hash, $key, $val, $errmsg) = @_;
die "$errmsg$key\n" if exists $hash->{$key};
$hash->{$key} = $val;
};
foreach my $scope ("general", "local")
{
my $file = $scope eq "general" ? "text.dat" : "text-local.dat";
my $ffile = "$ENV{'LJHOME'}/bin/upgrading/$file";
unless (-e $ffile) {
next if $scope eq "local";
die "$file file not found; odd: did you delete it?\n";
}
open (F, $ffile) or die "Can't open file: $file: $!\n";
while (<F>) {
s/\s+$//; s/^\#.+//;
next unless /\S/;
my @vals = split(/:/, $_);
my $what = shift @vals;
# language declaration
if ($what eq "lang") {
my $lang = {
'scope' => $scope,
'lnid' => $vals[0],
'lncode' => $vals[1],
'lnname' => $vals[2],
'parentlnid' => 0, # default. changed later.
'parenttype' => 'diff',
};
$lang->{'parenttype'} = $vals[3] if defined $vals[3];
if (defined $vals[4]) {
unless (exists $lang_code{$vals[4]}) {
die "Can't declare language $lang->{'lncode'} with missing parent language $vals[4].\n";
}
$lang->{'parentlnid'} = $lang_code{$vals[4]}->{'lnid'};
}
$set->(\%lang_id, $lang->{'lnid'}, $lang, "Language already defined with ID: ");
$set->(\%lang_code, $lang->{'lncode'}, $lang, "Language already defined with code: ");
}
# domain declaration
if ($what eq "domain") {
my $dcode = $vals[1];
my ($type, $args) = split(m!/!, $dcode);
my $dom = {
'scope' => $scope,
'dmid' => $vals[0],
'type' => $type,
'args' => $args || "",
};
$set->(\%dom_id, $dom->{'dmid'}, $dom, "Domain already defined with ID: ");
$set->(\%dom_code, $dcode, $dom, "Domain already defined with parameters: ");
}
# langdomain declaration
if ($what eq "langdomain") {
my $ld = {
'lnid' =>
(exists $lang_code{$vals[0]} ? $lang_code{$vals[0]}->{'lnid'} :
die "Undefined language: $vals[0]\n"),
'dmid' =>
(exists $dom_code{$vals[1]} ? $dom_code{$vals[1]}->{'dmid'} :
die "Undefined domain: $vals[1]\n"),
'dmmaster' => $vals[2] ? "1" : "0",
};
push @lang_domains, $ld;
}
}
close F;
}
if ($mode eq "check") {
print "all good.\n";
exit 0;
}
## make sure we can connect
my $dbh = LJ::get_dbh("master");
my $sth;
unless ($dbh) {
die "Can't connect to the database.\n";
}
# indenter
my $idlev = 0;
my $out = sub {
my @args = @_;
while (@args) {
my $a = shift @args;
if ($a eq "+") { $idlev++; }
elsif ($a eq "-") { $idlev--; }
elsif ($a eq "x") { $a = shift @args; die " "x$idlev . $a . "\n"; }
else { print " "x$idlev, $a, "\n"; }
}
};
my @good = qw(load popstruct poptext dumptext newitems wipedb makeusable copyfaq remove
wipecrumbs loadcrumbs);
popstruct() if $mode eq "popstruct" or $mode eq "load";
poptext(@ARGV) if $mode eq "poptext" or $mode eq "load";
copyfaq() if $mode eq "copyfaq" or $mode eq "load";
loadcrumbs() if $mode eq "loadcrumbs" or $mode eq "load";
makeusable() if $mode eq "makeusable" or $mode eq "load";
dumptext(@ARGV) if $mode eq "dumptext";
newitems() if $mode eq "newitems";
wipedb() if $mode eq "wipedb";
wipecrumbs() if $mode eq "wipecrumbs";
remove(@ARGV) if $mode eq "remove" and scalar(@ARGV) == 2;
help() unless grep { $mode eq $_ } @good;
exit 0;
sub makeusable
{
$out->("Making usable...", '+');
my $rec = sub {
my ($lang, $rec) = @_;
my $l = $lang_code{$lang};
$out->("x", "Bogus language: $lang") unless $l;
my @children = grep { $_->{'parentlnid'} == $l->{'lnid'} } values %lang_code;
foreach my $cl (@children) {
$out->("$l->{'lncode'} -- $cl->{'lncode'}");
my %need;
# push downwards everything that has some valid text in some language (< 4)
$sth = $dbh->prepare("SELECT dmid, itid, txtid FROM ml_latest WHERE lnid=$l->{'lnid'} AND staleness < 4");
$sth->execute;
while (my ($dmid, $itid, $txtid) = $sth->fetchrow_array) {
$need{"$dmid:$itid"} = $txtid;
}
$sth = $dbh->prepare("SELECT dmid, itid, txtid FROM ml_latest WHERE lnid=$cl->{'lnid'}");
$sth->execute;
while (my ($dmid, $itid, $txtid) = $sth->fetchrow_array) {
delete $need{"$dmid:$itid"};
}
while (my $k = each %need) {
my ($dmid, $itid) = split(/:/, $k);
my $txtid = $need{$k};
my $stale = $cl->{'parenttype'} eq "diff" ? 3 : 0;
$dbh->do("INSERT INTO ml_latest (lnid, dmid, itid, txtid, chgtime, staleness) VALUES ".
"($cl->{'lnid'}, $dmid, $itid, $txtid, NOW(), $stale)");
die $dbh->errstr if $dbh->err;
}
$rec->($cl->{'lncode'}, $rec);
}
};
$rec->("en", $rec);
$out->("-", "done.");
}
sub copyfaq
{
my $faqd = LJ::Lang::get_dom("faq");
my $ll = LJ::Lang::get_root_lang($faqd);
unless ($ll) { return; }
my $domid = $faqd->{'dmid'};
$out->("Copying FAQ...", '+');
my %existing;
$sth = $dbh->prepare("SELECT i.itcode FROM ml_items i, ml_latest l ".
"WHERE l.lnid=$ll->{'lnid'} AND l.dmid=$domid AND l.itid=i.itid AND i.dmid=$domid");
$sth->execute;
$existing{$_} = 1 while $_ = $sth->fetchrow_array;
# faq category
$sth = $dbh->prepare("SELECT faqcat, faqcatname FROM faqcat");
$sth->execute;
while (my ($cat, $name) = $sth->fetchrow_array) {
next if exists $existing{"cat.$cat"};
my $opts = { 'childrenlatest' => 1 };
LJ::Lang::set_text($dbh, $domid, $ll->{'lncode'}, "cat.$cat", $name, $opts);
}
# faq items
$sth = $dbh->prepare("SELECT faqid, question, answer FROM faq");
$sth->execute;
while (my ($faqid, $q, $a) = $sth->fetchrow_array) {
next if
exists $existing{"$faqid.1question"} and
exists $existing{"$faqid.2answer"};
my $opts = { 'childrenlatest' => 1 };
LJ::Lang::set_text($dbh, $domid, $ll->{'lncode'}, "$faqid.1question", $q, $opts);
LJ::Lang::set_text($dbh, $domid, $ll->{'lncode'}, "$faqid.2answer", $a, $opts);
}
$out->('-', "done.");
}
sub wipedb
{
$out->("Wiping DB...", '+');
foreach (qw(domains items langdomains langs latest text)) {
$out->("deleting from $_");
$dbh->do("DELETE FROM ml_$_");
}
$out->("-", "done.");
}
sub wipecrumbs
{
$out->('Wiping DB of all crumbs...', '+');
# step 1: get all items that are crumbs. [from ml_items]
my $genid = $dom_code{'general'}->{'dmid'};
my @crumbs;
my $sth = $dbh->prepare("SELECT itcode FROM ml_items
WHERE dmid = $genid AND itcode LIKE 'crumb.\%'");
$sth->execute;
while (my ($itcode) = $sth->fetchrow_array) {
# push onto list
push @crumbs, $itcode;
}
# step 2: remove the items that have these unique dmid/itids
foreach my $code (@crumbs) {
$out->("deleting $code");
remove("general", $code);
}
# done
$out->('-', 'done.');
}
sub loadcrumbs
{
$out->('Loading all crumbs into DB...', '+');
# get domain id of 'general' and language id of 'en'
my $genid = $dom_code{'general'}->{'dmid'};
my $loclang = $LJ::LANGS[0] || 'en';
# list of crumbs
my @crumbs;
foreach (keys %LJ::CRUMBS_LOCAL) { push @crumbs, $_; }
foreach (keys %LJ::CRUMBS) { push @crumbs, $_; }
# begin iterating, order doesn't matter...
foreach my $crumbkey (@crumbs) {
$out->("inserting crumb.$crumbkey");
my $crumb = LJ::get_crumb($crumbkey);
my $local = $LJ::CRUMBS_LOCAL{$crumbkey} ? 1 : 0;
# see if it exists
my $itid = $dbh->selectrow_array("SELECT itid FROM ml_items
WHERE dmid = $genid AND itcode = 'crumb.$crumbkey'")+0;
LJ::Lang::set_text($genid, $local ? $loclang : 'en', "crumb.$crumbkey", $crumb->[0])
unless $itid;
}
# done
$out->('-', 'done.');
}
sub popstruct
{
$out->("Populating structure...", '+');
foreach my $l (values %lang_id) {
$out->("Inserting language: $l->{'lnname'}");
$dbh->do("INSERT INTO ml_langs (lnid, lncode, lnname, parenttype, parentlnid) ".
"VALUES (" . join(",", map { $dbh->quote($l->{$_}) } qw(lnid lncode lnname parenttype parentlnid)) . ")");
}
foreach my $d (values %dom_id) {
$out->("Inserting domain: $d->{'type'}\[$d->{'args'}\]");
$dbh->do("INSERT INTO ml_domains (dmid, type, args) ".
"VALUES (" . join(",", map { $dbh->quote($d->{$_}) } qw(dmid type args)) . ")");
}
$out->("Inserting language domains ...");
foreach my $ld (@lang_domains) {
$dbh->do("INSERT IGNORE INTO ml_langdomains (lnid, dmid, dmmaster) VALUES ".
"(" . join(",", map { $dbh->quote($ld->{$_}) } qw(lnid dmid dmmaster)) . ")");
}
$out->("-", "done.");
}
sub poptext
{
my @langs = @_;
push @langs, (keys %lang_code) unless @langs;
$out->("Populating text...", '+');
my %source; # lang -> file, or "[extra]" when given by --extra= argument
if ($opt_extra) {
$source{'[extra]'} = $opt_extra;
} else {
foreach my $lang (@langs) {
my $file = "$ENV{'LJHOME'}/bin/upgrading/${lang}.dat";
next if $opt_only && $lang ne $opt_only;
next unless -e $file;
$source{$lang} = $file;
}
}
my %existing_item; # langid -> code -> 1
foreach my $source (keys %source)
{
$out->("$source", '+');
my $file = $source{$source};
open (D, $file)
or $out->('x', "Can't open $source data file");
# fixed language in *.dat files, but in extra files
# it switches as it goes.
my $l;
if ($source ne "[extra]") { $l = $lang_code{$source}; }
my $bml_prefix = "";
my $addcount = 0;
my $lnum = 0;
my ($code, $text);
my %metadata;
while (my $line = <D>) {
$lnum++;
my $del;
my $action_line;
if ($line =~ /^==(LANG|BML):\s*(\S+)/) {
$out->('x', "Bogus directives in non-extra file.")
if $source ne "[extra]";
my ($what, $val) = ($1, $2);
if ($what eq "LANG") {
$l = $lang_code{$val};
$out->('x', 'Bogus ==LANG switch to: $what') unless $l;
$bml_prefix = "";
} elsif ($what eq "BML") {
$out->('x', 'Bogus ==BML switch to: $what')
unless $val =~ m!^/.+\.bml$!;
$bml_prefix = $val;
}
} elsif ($line =~ /^(\S+?)=(.*)/) {
($code, $text) = ($1, $2);
$action_line = 1;
} elsif ($line =~ /^\!\s*(\S+)/) {
$del = $code;
$action_line = 1;
} elsif ($line =~ /^(\S+?)\<\<\s*$/) {
($code, $text) = ($1, "");
while (<D>) {
$lnum++;
last if $_ eq ".\n";
s/^\.//;
$text .= $_;
}
chomp $text; # remove file new-line (we added it)
$action_line = 1;
} elsif ($line =~ /^[\#\;]/) {
# comment line
next;
} elsif ($line =~ /\S/) {
$out->('x', "$source:$lnum: Bogus format.");
}
if ($code =~ m!^\.!) {
$out->('x', "Can't use code with leading dot: $code")
unless $bml_prefix;
$code = "$bml_prefix$code";
}
if ($code =~ /\|(.+)/) {
$metadata{$1} = $text;
next;
}
next unless $action_line;
$out->('x', 'No language defined!') unless $l;
# load existing items for target language
unless (exists $existing_item{$l->{'lnid'}}) {
$existing_item{$l->{'lnid'}} = {};
my $sth = $dbh->prepare(qq{
SELECT i.itcode
FROM ml_latest l, ml_items i
WHERE i.dmid=1 AND l.dmid=1 AND i.itid=l.itid AND l.lnid=$l->{'lnid'}
});
$sth->execute;
$existing_item{$l->{'lnid'}}->{$_} = 1
while $_ = $sth->fetchrow_array;
}
# do deletes
if (defined $del) {
remove("general", $del)
if delete $existing_item{$l->{'lnid'}}->{$del};
next;
}
# if override is set (development option) then delete
if ($opt_override && $existing_item{$l->{'lnid'}}->{$code}) {
remove("general", $code);
delete $existing_item{$l->{'lnid'}}->{$code};
}
unless ($existing_item{$l->{'lnid'}}->{$code}) {
$addcount++;
my $staleness = $metadata{'staleness'}+0;
my $res = LJ::Lang::set_text($dbh, 1, $l->{'lncode'}, $code, $text,
{ 'staleness' => $staleness,
'notes' => $metadata{'notes'}, });
$out->("set: $code") if $opt_verbose;
unless ($res) {
$out->('x', "ERROR: " . LJ::Lang::last_error());
}
}
%metadata = ();
}
close D;
$out->("added: $addcount", '-');
}
$out->("-", "done.");
# dead phrase removal
$out->("Removing dead phrases...", '+');
foreach my $file ("deadphrases.dat", "deadphrases-local.dat") {
my $ffile = "$ENV{'LJHOME'}/bin/upgrading/$file";
next unless -s $ffile;
$out->("File: $file");
open (DP, $ffile) or die;
while (my $li = <DP>) {
$li =~ s/\#.*//;
next unless $li =~ /\S/;
$li =~ s/\s+$//;
my ($dom, $it) = split(/\s+/, $li);
next unless exists $dom_code{$dom};
my $dmid = $dom_code{$dom}->{'dmid'};
my @items;
if ($it =~ s/\*$/\%/) {
my $sth = $dbh->prepare("SELECT itcode FROM ml_items WHERE dmid=? AND itcode LIKE ?");
$sth->execute($dmid, $it);
push @items, $_ while $_ = $sth->fetchrow_array;
} else {
@items = ($it);
}
foreach (@items) {
remove($dom, $_, 1);
}
}
close DP;
}
$out->('-', "Done.");
}
sub dumptext
{
my @langs = @_;
unless (@langs) { @langs = keys %lang_code; }
$out->('Dumping text...', '+');
foreach my $lang (@langs)
{
$out->("$lang");
my $l = $lang_code{$lang};
open (D, ">$ENV{'LJHOME'}/bin/upgrading/${lang}.dat")
or $out->('x', "Can't open $lang.dat");
print D ";; -*- coding: utf-8 -*-\n";
my $sth = $dbh->prepare("SELECT i.itcode, t.text, l.staleness, i.notes FROM ".
"ml_items i, ml_latest l, ml_text t ".
"WHERE l.lnid=$l->{'lnid'} AND l.dmid=1 ".
"AND i.dmid=1 AND l.itid=i.itid AND ".
"t.dmid=1 AND t.txtid=l.txtid AND ".
# only export mappings that aren't inherited:
"t.lnid=$l->{'lnid'} ".
"ORDER BY i.itcode");
$sth->execute;
die $dbh->errstr if $dbh->err;
my $writeline = sub {
my ($k, $v) = @_;
if ($v =~ /\n/) {
$v =~ s/\n\./\n\.\./g;
print D "$k<<\n$v\n.\n";
} else {
print D "$k=$v\n";
}
};
while (my ($itcode, $text, $staleness, $notes) = $sth->fetchrow_array) {
$writeline->("$itcode|staleness", $staleness)
if $staleness;
$writeline->("$itcode|notes", $notes)
if $notes =~ /\S/;
$writeline->($itcode, $text);
print D "\n";
}
close D;
}
$out->('-', 'done.');
}
sub newitems
{
$out->("Searching for referenced text codes...", '+');
my $top = $ENV{'LJHOME'};
my @files;
push @files, qw(htdocs cgi-bin bin);
my %items; # $scope -> $key -> 1;
while (@files)
{
my $file = shift @files;
my $ffile = "$top/$file";
next unless -e $ffile;
if (-d $ffile) {
$out->("dir: $file");
opendir (MD, $ffile) or die "Can't open $file";
while (my $f = readdir(MD)) {
next if $f eq "." || $f eq ".." ||
$f =~ /^\.\#/ || $f =~ /(\.png|\.gif|~|\#)$/;
unshift @files, "$file/$f";
}
closedir MD;
}
if (-f $ffile) {
my $scope = "local";
$scope = "general" if -e "$top/cvs/livejournal/$file";
open (F, $ffile) or die "Can't open $file";
my $line = 0;
while (<F>) {
$line++;
while (/BML::ml\([\"\'](.+?)[\"\']/g) {
$items{$scope}->{$1} = 1;
}
while (/\(=_ML\s+(.+?)\s+_ML=\)/g) {
my $code = $1;
if ($code =~ /^\./ && $file =~ m!^htdocs/!) {
$code = "$file$code";
$code =~ s!^htdocs!!;
}
$items{$scope}->{$code} = 1;
}
}
close F;
}
}
$out->(sprintf("%d general and %d local found.",
scalar keys %{$items{'general'}},
scalar keys %{$items{'local'}}));
# [ General ]
my %e_general; # code -> 1
$out->("Checking which general items already exist in database...");
my $sth = $dbh->prepare("SELECT i.itcode FROM ml_items i, ml_latest l WHERE ".
"l.dmid=1 AND l.lnid=1 AND i.dmid=1 AND i.itid=l.itid ");
$sth->execute;
while (my $it = $sth->fetchrow_array) { $e_general{$it} = 1; }
$out->(sprintf("%d found", scalar keys %e_general));
foreach my $it (keys %{$items{'general'}}) {
next if exists $e_general{$it};
my $res = LJ::Lang::set_text($dbh, 1, "en", $it, undef, { 'staleness' => 4 });
$out->("Adding general: $it ... $res");
}
if ($opt_local_lang) {
my $ll = $lang_code{$opt_local_lang};
die "Bogus --local-lang argument\n" unless $ll;
die "Local-lang '$ll->{'lncode'}' parent isn't 'en'\n"
unless $ll->{'parentlnid'} == 1;
$out->("Checking which local items already exist in database...");
my %e_local;
$sth = $dbh->prepare("SELECT i.itcode FROM ml_items i, ml_latest l WHERE ".
"l.dmid=1 AND l.lnid=$ll->{'lnid'} AND i.dmid=1 AND i.itid=l.itid ");
$sth->execute;
while (my $it = $sth->fetchrow_array) { $e_local{$it} = 1; }
$out->(sprintf("%d found\n", scalar keys %e_local));
foreach my $it (keys %{$items{'local'}}) {
next if exists $e_general{$it};
next if exists $e_local{$it};
my $res = LJ::Lang::set_text($dbh, 1, $ll->{'lncode'}, $it, undef, { 'staleness' => 4 });
$out->("Adding local: $it ... $res");
}
}
$out->('-', 'done.');
}
sub remove {
my ($dmcode, $itcode, $no_error) = @_;
my $dmid;
if (exists $dom_code{$dmcode}) {
$dmid = $dom_code{$dmcode}->{'dmid'};
} else {
$out->("x", "Unknown domain code $dmcode.");
}
my $qcode = $dbh->quote($itcode);
my $itid = $dbh->selectrow_array("SELECT itid FROM ml_items WHERE dmid=$dmid AND itcode=$qcode");
return if $no_error && !$itid;
$out->("x", "Unknown item code $itcode.") unless $itid;
$out->("Removing item $itcode from domain $dmcode ($itid)...", "+");
# need to delete everything from: ml_items ml_latest ml_text
$dbh->do("DELETE FROM ml_items WHERE dmid=$dmid AND itid=$itid");
my $txtids = "";
my $sth = $dbh->prepare("SELECT txtid FROM ml_latest WHERE dmid=$dmid AND itid=$itid");
$sth->execute;
while (my $txtid = $sth->fetchrow_array) {
$txtids .= "," if $txtids;
$txtids .= $txtid;
}
$dbh->do("DELETE FROM ml_latest WHERE dmid=$dmid AND itid=$itid");
$dbh->do("DELETE FROM ml_text WHERE dmid=$dmid AND txtid IN ($txtids)");
$out->("-","done.");
}

View File

@@ -0,0 +1,32 @@
#!/usr/bin/perl
use strict;
my $clusterid = shift;
die "Usage: truncate_cluster.pl <clusterid>\n"
unless $clusterid;
# load libraries now
require "$ENV{'LJHOME'}/cgi-bin/ljlib.pl";
# force this option on, since that's the point of the tool
$LJ::COMPRESS_TEXT = 1;
my $master = LJ::get_db_writer();
my $ct = $master->selectrow_array("SELECT COUNT(*) FROM user WHERE clusterid=?",
undef, $clusterid);
if ($ct) {
die "There are still $ct users on cluster $clusterid\n";
}
my $db = LJ::get_cluster_master($clusterid);
die "Invalid/down cluster: $clusterid\n" unless $db;
my $sth = $db->prepare("SHOW TABLES");
$sth->execute;
while (my $table = $sth->fetchrow_array) {
next if $table eq "useridmap";
print " truncating $table\n";
$db->do("TRUNCATE TABLE $table");
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,807 @@
#!/usr/bin/perl
#
# This program will bring your LiveJournal database schema up-to-date
#
use strict;
use lib "$ENV{LJHOME}/cgi-bin";
use Getopt::Long;
use File::Path ();
use File::Basename ();
use File::Copy ();
use Image::Size ();
BEGIN { require "ljlib.pl";
require "ljviews.pl"; }
use LJ::S2;
use MogileFS;
my $opt_sql = 0;
my $opt_drop = 0;
my $opt_pop = 0;
my $opt_confirm = "";
my $opt_skip = "";
my $opt_help = 0;
my $cluster = 0; # by default, upgrade master.
my $opt_listtables;
my $opt_forcebuild = 0;
my $opt_compiletodisk = 0;
my $opt_innodb;
exit 1 unless
GetOptions("runsql" => \$opt_sql,
"drop" => \$opt_drop,
"populate" => \$opt_pop,
"confirm=s" => \$opt_confirm,
"cluster=s" => \$cluster,
"skip=s" => \$opt_skip,
"help" => \$opt_help,
"listtables" => \$opt_listtables,
"forcebuild|fb" => \$opt_forcebuild,
"ctd" => \$opt_compiletodisk,
"innodb" => \$opt_innodb,
);
if ($opt_help) {
die "Usage: update-db.pl
-r --runsql Actually do the SQL, instead of just showing it.
-p --populate Populate the database with the latest required base data.
-d --drop Drop old unused tables (default is to never)
--cluster=<n> Upgrade cluster number <n> (defaut,0 is global cluster)
--cluster=<n>,<n>,<n>
--cluster=user Update user clusters
--cluster=all Update user clusters, and global
-l --listtables Print used tables, one per line.
";
}
## make sure $LJHOME is set so we can load & run everything
unless (-d $ENV{'LJHOME'}) {
die "LJHOME environment variable is not set, or is not a directory.\n".
"You must fix this before you can run this database update script.";
}
die "Can't --populate a cluster" if $opt_pop && $cluster;
my @clusters;
foreach my $cl (split(/,/, $cluster)) {
die "Invalid cluster spec: $cl\n" unless
$cl =~ /^\s*((\d+)|all|user)\s*$/;
if ($cl eq "all") { push @clusters, 0, @LJ::CLUSTERS; }
elsif ($cl eq "user") { push @clusters, @LJ::CLUSTERS; }
else { push @clusters, $1; }
}
@clusters = (0) unless @clusters;
my %status; # clusterid -> string
my %clustered_table; # $table -> 1
my $sth;
my %table_exists; # $table -> 1
my %table_unknown; # $table -> 1
my %table_create; # $table -> $create_sql
my %table_drop; # $table -> 1
my %table_status; # $table -> { SHOW TABLE STATUS ... row }
my %post_create; # $table -> [ [ $action, $what ]* ]
my %coltype; # $table -> { $col -> $type }
my %indexname; # $table -> "INDEX"|"UNIQUE" . ":" . "col1-col2-col3" -> "PRIMARY" | index_name
my @alters;
my $dbh;
CLUSTER: foreach my $cluster (@clusters) {
print "Updating cluster: $cluster\n" unless $opt_listtables;
## make sure we can connect
$dbh = $cluster ? LJ::get_cluster_master($cluster) : LJ::get_db_writer();
unless ($dbh) {
$status{$cluster} = "ERROR: Can't connect to the database (clust\#$cluster), so I can't update it.";
next CLUSTER;
}
# reset everything
%clustered_table = %table_exists = %table_unknown =
%table_create = %table_drop = %post_create =
%coltype = %indexname = %table_status = ();
@alters = ();
## figure out what tables already exist (but not details of their structure)
$sth = $dbh->prepare("SHOW TABLES");
$sth->execute;
while (my ($table) = $sth->fetchrow_array) {
next if $table =~ /^access\d+$/;
$table_exists{$table} = 1;
}
%table_unknown = %table_exists; # for now, later we'll delete from table_unknown
## very important that local is run first! (it can define tables that
## the site-wide would drop if it didn't know about them already)
my $load_datfile = sub {
my $file = shift;
my $local = shift;
return if $local && ! -e $file;
open(F, $file) or die "Can't find database update file at $file\n";
my $data;
{
local $/ = undef;
$data = <F>;
}
close F;
eval $data;
die "Can't run $file: $@\n" if $@;
return 1;
};
$load_datfile->("$LJ::HOME/bin/upgrading/update-db-local.pl", 1);
$load_datfile->("$LJ::HOME/bin/upgrading/update-db-general.pl");
foreach my $t (sort keys %table_create) {
delete $table_drop{$t} if ($table_drop{$t});
print "$t\n" if $opt_listtables;
}
exit if $opt_listtables;
foreach my $t (keys %table_drop) {
delete $table_unknown{$t};
}
foreach my $t (keys %table_unknown)
{
print "# Warning: unknown live table: $t\n";
}
## create tables
foreach my $t (keys %table_create)
{
next if $table_exists{$t};
create_table($t);
}
## drop tables
foreach my $t (keys %table_drop)
{
next unless $table_exists{$t};
drop_table($t);
}
## do all the alters
foreach my $s (@alters)
{
$s->($dbh, $opt_sql);
}
$status{$cluster} = "OKAY";
}
print "\ncluster: status\n";
foreach my $clid (sort { $a <=> $b } keys %status) {
printf "%7d: %s\n", $clid, $status{$clid};
}
print "\n";
if ($opt_pop)
{
my $made_system;
# system user
my $su = LJ::load_user("system");
unless ($su) {
print "System user not found. Creating with random password.\n";
my $pass = LJ::make_auth_code(10);
LJ::create_account({ 'user' => 'system',
'name' => 'System Account',
'password' => $pass })
|| die "Failed to create system user.";
$su = LJ::load_user("system") || die "Failed to load the newly created system user.";
$made_system = 1;
}
# S1
print "Populating public system styles (S1):\n";
require "$ENV{'LJHOME'}/bin/upgrading/s1style-rw.pl";
my $ss = s1styles_read();
foreach my $uniq (sort keys %$ss) {
my $s = $ss->{$uniq};
my $existing = LJ::S1::check_dup_style($su, $s->{'type'}, $s->{'styledes'});
# update
if ($existing) {
if ($LJ::DONT_TOUCH_STYLES) {
next;
}
if ( LJ::S1::update_style($existing->{'styleid'},
{ map { $_, $s->{$_} } qw(formatdata is_embedded is_colorfree) }) ) {
print " $uniq: ";
print "updated \#$existing->{'styleid'}\n";
}
next;
}
# insert new
my %opts = ( "is_public" => 'Y', "opt_cache" => 'Y',
map { $_, $s->{$_} } qw(styledes type formatdata is_embedded is_colorfree lastupdate));
LJ::S1::create_style($su, \%opts)
or die "Error: unable to create style! Database potentially unavailable?";
print " $uniq: ";
print "added\n";
}
# delete s1pubstyc from memcache
LJ::MemCache::delete("s1pubstyc");
# S2
print "Populating public system styles (S2):\n";
{
my $LD = "s2layers"; # layers dir
my $sysid = $su->{'userid'};
# find existing re-distributed layers that are in the database
# and their styleids.
my $existing = LJ::S2::get_public_layers($sysid);
my %known_id;
chdir "$ENV{'LJHOME'}/bin/upgrading" or die;
my %layer; # maps redist_uniq -> { 'type', 'parent' (uniq), 'id' (s2lid) }
my $compile = sub {
my ($base, $type, $parent, $s2source) = @_;
return unless $s2source =~ /\S/;
my $id = $existing->{$base} ? $existing->{$base}->{'s2lid'} : 0;
unless ($id) {
my $parentid = 0;
$parentid = $layer{$parent}->{'id'} unless $type eq "core";
# allocate a new one.
$dbh->do("INSERT INTO s2layers (s2lid, b2lid, userid, type) ".
"VALUES (NULL, $parentid, $sysid, ?)", undef, $type);
die $dbh->errstr if $dbh->err;
$id = $dbh->{'mysql_insertid'};
if ($id) {
$dbh->do("INSERT INTO s2info (s2lid, infokey, value) VALUES (?,'redist_uniq',?)",
undef, $id, $base);
}
}
die "Can't generate ID for '$base'" unless $id;
# remember it so we don't delete it later.
$known_id{$id} = 1;
$layer{$base} = {
'type' => $type,
'parent' => $parent,
'id' => $id,
};
my $parid = $layer{$parent}->{'id'};
# see if source changed
my $md5_source = Digest::MD5::md5_hex($s2source);
my $md5_exist = $dbh->selectrow_array("SELECT MD5(s2code) FROM s2source WHERE s2lid=?", undef, $id);
# skip compilation if source is unchanged and parent wasn't rebuilt.
return if $md5_source eq $md5_exist && ! $layer{$parent}->{'built'} && ! $opt_forcebuild;
print "$base($id) is $type";
if ($parid) { print ", parent = $parent($parid)"; };
print "\n";
# we're going to go ahead and build it.
$layer{$base}->{'built'} = 1;
# compile!
my $lay = {
's2lid' => $id,
'userid' => $sysid,
'b2lid' => $parid,
'type' => $type,
};
my $error = "";
my $compiled;
my $info;
die $error unless LJ::S2::layer_compile($lay, \$error, {
's2ref' => \$s2source,
'redist_uniq' => $base,
'compiledref' => \$compiled,
'layerinfo' => \$info,
});
if ($info->{'previews'}) {
my @pvs = split(/\s*\,\s*/, $info->{'previews'});
my @vals;
foreach my $pv (@pvs) {
my $from = "$LD/$pv";
next unless -e $from;
my $dir = File::Basename::dirname($pv);
File::Path::mkpath("$LJ::HOME/htdocs/img/s2preview/$dir");
my $target = "$LJ::HOME/htdocs/img/s2preview/$pv";
File::Copy::copy($from, $target);
my ($w, $h) = Image::Size::imgsize($target);
push @vals, "$pv|$w|$h";
}
$dbh->do("REPLACE INTO s2info (s2lid, infokey, value) VALUES (?,?,?)",
undef, $id, '_previews', join(",", @vals)) if @vals;
}
if ($opt_compiletodisk) {
open (CO, ">$LD/$base.pl") or die;
print CO $compiled;
close CO;
}
# put raw S2 in database.
$dbh->do("REPLACE INTO s2source (s2lid, s2code) ".
"VALUES ($id, ?)", undef, $s2source);
die $dbh->errstr if $dbh->err;
};
my @layerfiles = ("s2layers.dat");
while (@layerfiles)
{
my $file = shift @layerfiles;
next unless -e $file;
open (SL, $file) or die;
print "SOURCE: $file\n";
while (<SL>)
{
s/\#.*//; s/^\s+//; s/\s+$//;
next unless /\S/;
my ($base, $type, $parent) = split;
if ($type eq "INCLUDE") {
push @layerfiles, $base;
next;
}
if ($type ne "core" && ! defined $layer{$parent}) {
die "'$base' references unknown parent '$parent'\n";
}
# is the referenced $base file really an aggregation of
# many smaller layers? (likely themes, which tend to be small)
my $multi = ($type =~ s/\+$//);
my $s2source;
open (L, "$LD/$base.s2") or die "Can't open file: $base.s2\n";
unless ($multi) {
while (<L>) { $s2source .= $_; }
$compile->($base, $type, $parent, $s2source);
} else {
my $curname;
while (<L>) {
if (/^\#NEWLAYER:\s*(\S+)/) {
my $newname = $1;
$compile->($curname, $type, $parent, $s2source);
$curname = $newname;
$s2source = "";
} elsif (/^\#NEWLAYER/) {
die "Badly formatted \#NEWLAYER line";
} else {
$s2source .= $_;
}
}
$compile->($curname, $type, $parent, $s2source);
}
close L;
}
close SL;
}
# now, delete any system layers that don't below (from previous imports?)
my $sth = $dbh->prepare("SELECT s2lid FROM s2layers WHERE userid=?");
$sth->execute($sysid);
while (my $id = $sth->fetchrow_array) {
next if $known_id{$id};
LJ::S2::delete_layer($id);
}
}
# check for old style external_foaf_url (indexed:1, cldversion:0)
my $prop = LJ::get_prop('user', 'external_foaf_url');
if ($prop->{indexed} == 1 && $prop->{cldversion} == 0) {
print "Updating external_foaf_url userprop.\n";
system("$ENV{'LJHOME'}/bin/upgrading/migrate-userprop.pl", 'external_foaf_url');
}
# base data
foreach my $file ("base-data.sql", "base-data-local.sql") {
my $ffile = "$ENV{'LJHOME'}/bin/upgrading/$file";
next unless -e $ffile;
print "Populating database with $file.\n";
open (BD, $ffile) or die "Can't open $file file\n";
while (my $q = <BD>)
{
chomp $q; # remove newline
next unless ($q =~ /^(REPLACE|INSERT|UPDATE)/);
chop $q; # remove semicolon
$dbh->do($q);
if ($dbh->err) {
print "$q\n";
die "# ERROR: " . $dbh->errstr . "\n";
}
}
close (BD);
}
# moods
my $moodfile = "$ENV{'LJHOME'}/bin/upgrading/moods.dat";
if (open(M, $moodfile)) {
print "Populating mood data.\n";
my %mood; # id -> [ mood, parent_id ]
my $sth = $dbh->prepare("SELECT moodid, mood, parentmood FROM moods");
$sth->execute;
while (@_ = $sth->fetchrow_array) { $mood{$_[0]} = [ $_[1], $_[2] ]; }
my %moodtheme; # name -> [ id, des ]
$sth = $dbh->prepare("SELECT moodthemeid, name, des FROM moodthemes WHERE is_public='Y'");
$sth->execute;
while (@_ = $sth->fetchrow_array) { $moodtheme{$_[1]} = [ $_[0], $_[2] ]; }
my $themeid; # current themeid (from existing db or just made)
my %data; # moodid -> "$url$width$height" (for equality test)
while (<M>) {
chomp;
if (/^MOOD\s+(\d+)\s+(.+)\s+(\d+)\s*$/) {
my ($id, $mood, $parid) = ($1, $2, $3);
if (! $mood{$id} || $mood{$id}->[0] ne $mood ||
$mood{$id}->[1] ne $parid) {
$dbh->do("REPLACE INTO moods (moodid, mood, parentmood) VALUES (?,?,?)",
undef, $id, $mood, $parid);
}
}
if (/^MOODTHEME\s+(.+?)\s*:\s*(.+)$/) {
my ($name, $des) = ($1, $2);
%data = ();
if ($moodtheme{$name}) {
$themeid = $moodtheme{$name}->[0];
if ($moodtheme{$name}->[1] ne $des) {
$dbh->do("UPDATE moodthemes SET des=? WHERE moodthemeid=?", undef,
$des, $themeid);
}
$sth = $dbh->prepare("SELECT moodid, picurl, width, height ".
"FROM moodthemedata WHERE moodthemeid=?");
$sth->execute($themeid);
while (@_ = $sth->fetchrow_array) {
$data{$_[0]} = "$_[1]$_[2]$_[3]";
}
} else {
$dbh->do("INSERT INTO moodthemes (ownerid, name, des, is_public) ".
"VALUES (?,?,?,'Y')", undef, $su->{'userid'}, $name, $des);
$themeid = $dbh->{'mysql_insertid'};
die "Couldn't generate themeid for theme $name\n" unless $themeid;
}
next;
}
if (/^(\d+)\s+(\S+)\s+(\d+)\s+(\d+)\s*$/) {
next unless $themeid;
my ($moodid, $url, $w, $h) = ($1, $2, $3, $4);
next if $data{$moodid} eq "$url$w$h";
$dbh->do("REPLACE INTO moodthemedata (moodthemeid, moodid, picurl, width, height) ".
"VALUES (?,?,?,?,?)", undef, $themeid, $moodid, $url, $w, $h);
LJ::MemCache::delete([$themeid, "moodthemedata:$themeid"]);
}
}
close M;
}
# clean out schema documentation for old/unknown tables
foreach my $tbl (qw(schemacols schematables)) {
my $sth = $dbh->prepare("SELECT DISTINCT tablename FROM $tbl");
$sth->execute;
while (my $doctbl = $sth->fetchrow_array) {
next if $table_create{$doctbl};
$dbh->do("DELETE FROM $tbl WHERE tablename=?", undef, $doctbl);
}
}
# create/update the MogileFS database if we use it
if (defined $LJ::MOGILEFS_CONFIG{hosts}) {
# create an admin MogileFS object
my $mgd = MogileFS::Admin->new(hosts => $LJ::MOGILEFS_CONFIG{hosts})
or die "Error: Unable to initalize MogileFS connection.\n";
my $exists = $mgd->get_domains();
print "Verifying MogileFS configuration...\n";
# verify domain exists?
my $domain = $LJ::MOGILEFS_CONFIG{domain};
unless (defined $exists->{$domain}) {
print "\tCreating domain $domain...\n";
$mgd->create_domain($domain)
or die "Error: Unable to create domain.\n";
$exists->{$domain} = {};
}
# now start verifying classes
foreach my $class (keys %{$LJ::MOGILEFS_CONFIG{classes} || {}}) {
if ($exists->{$domain}->{$class}) {
if ($exists->{$domain}->{$class} != $LJ::MOGILEFS_CONFIG{classes}->{$class}) {
# update the mindevcount since it's changed
print "\tUpdating class $class...\n";
$mgd->update_class($domain, $class, $LJ::MOGILEFS_CONFIG{classes}->{$class})
or die "Error: Unable to update class.\n";
}
} else {
# create it
print "\tCreating class $class...\n";
$mgd->create_class($domain, $class, $LJ::MOGILEFS_CONFIG{classes}->{$class})
or die "Error: Unable to create class.\n";
}
}
}
# convert users from dversion2 (no weekuserusage)
if (my $d2 = $dbh->selectrow_array("SELECT userid FROM user WHERE dversion=2 LIMIT 1")) {
$dbh->do("UPDATE user SET dversion=3 WHERE dversion=2");
}
# convert users from dversion3 (unclustered props)
if (my $d3 = $dbh->selectrow_array("SELECT userid FROM user WHERE dversion=3 LIMIT 1")) {
system("$ENV{'LJHOME'}/bin/upgrading/pop-clusterprops.pl", 3);
}
# convert users from dversion4 (unclustered s1styles)
if (my $d4 = $dbh->selectrow_array("SELECT userid FROM user WHERE dversion=4 LIMIT 1")) {
system("$ENV{'LJHOME'}/bin/upgrading/d4d5-global.pl");
}
# convert users from dversion5 (unclustered memories and friend groups)
if (my $d5 = $dbh->selectrow_array("SELECT userid FROM user WHERE dversion=5 LIMIT 1")) {
system("$ENV{'LJHOME'}/bin/upgrading/d5d6-mkf.pl");
}
# convert users from dversion6 (unclustered user pictures)
if (my $d6 = $dbh->selectrow_array("SELECT userid FROM user WHERE dversion=6 LIMIT 1")) {
system("$ENV{'LJHOME'}/bin/upgrading/d6d7-userpics.pl");
}
print "\nThe system user was created with a random password.\nRun \$LJHOME/bin/upgrading/make_system.pl to change its password and grant the necessary privileges."
if $made_system;
print "\nRemember to also run:\n bin/upgrading/texttool.pl load\n\n";
}
# make sure they don't have cluster0 users (support for that will be going away)
# Note: now cluster 0 means expunged (as well as statuvis 'X'), so there's
# an option to disable the warning if you're running new code and know what's up.
unless ($LJ::NOWARN{'cluster0'}) {
my $cluster0 = $dbh->selectrow_array("SELECT COUNT(*) FROM user WHERE clusterid=0");
if ($cluster0) {
print "\n", "* "x35, "\nWARNING: You have $cluster0 users on cluster 0.\n\n".
"Support for that old database schema is deprecated and will be removed soon.\n".
"You should stop updating from CVS until you've moved all your users to a cluster \n".
"(probably cluster '1', which you can run on the same database). \n".
"See bin/moveucluster.pl for instructions.\n" . "* "x35 . "\n\n";
}
}
print "# Done.\n";
sub skip_opt
{
return $opt_skip;
}
sub do_sql
{
my $sql = shift;
chomp $sql;
my $disp_sql = $sql;
$disp_sql =~ s/\bIN \(.+\)/IN (...)/g;
print "$disp_sql;\n";
if ($opt_sql) {
print "# Running...\n";
$dbh->do($sql);
if ($dbh->err) {
die "# ERROR: " . $dbh->errstr . "\n";
}
}
}
sub try_sql
{
my $sql = shift;
print "$sql;\n";
if ($opt_sql) {
print "# Non-critical SQL (upgrading only... it might fail)...\n";
$dbh->do($sql);
if ($dbh->err) {
print "# Acceptable failure: " . $dbh->errstr . "\n";
}
}
}
sub do_alter
{
my ($table, $sql) = @_;
return if $cluster && ! defined $clustered_table{$table};
do_sql($sql);
# columns will have changed, so clear cache:
clear_table_info($table);
}
sub create_table
{
my $table = shift;
return if $cluster && ! defined $clustered_table{$table};
my $create_sql = $table_create{$table};
if ($opt_innodb && $create_sql !~ /type=myisam/i) {
$create_sql .= " TYPE=INNODB";
}
do_sql($create_sql);
foreach my $pc (@{$post_create{$table}})
{
my @args = @{$pc};
my $ac = shift @args;
if ($ac eq "sql") {
print "# post-create SQL\n";
do_sql($args[0]);
}
elsif ($ac eq "sqltry") {
print "# post-create SQL (necessary if upgrading only)\n";
try_sql($args[0]);
}
elsif ($ac eq "code") {
print "# post-create code\n";
$args[0]->($dbh, $opt_sql);
}
else { print "# don't know how to do \$ac = $ac"; }
}
}
sub drop_table
{
my $table = shift;
return if $cluster && ! defined $clustered_table{$table};
if ($opt_drop) {
do_sql("DROP TABLE $table");
} else {
print "# Not dropping table $table to be paranoid (use --drop)\n";
}
}
sub mark_clustered
{
foreach (@_) {
$clustered_table{$_} = 1;
}
}
sub register_tablecreate
{
my ($table, $create) = @_;
# we now know of it
delete $table_unknown{$table};
return if $cluster && ! defined $clustered_table{$table};
$table_create{$table} = $create;
}
sub register_tabledrop
{
my ($table) = @_;
$table_drop{$table} = 1;
}
sub post_create
{
my $table = shift;
while (my ($type, $what) = splice(@_, 0, 2)) {
push @{$post_create{$table}}, [ $type, $what ];
}
}
sub register_alter
{
my $sub = shift;
push @alters, $sub;
}
sub clear_table_info
{
my $table = shift;
delete $coltype{$table};
delete $indexname{$table};
delete $table_status{$table};
}
sub load_table_info
{
my $table = shift;
clear_table_info($table);
my $sth = $dbh->prepare("DESCRIBE $table");
$sth->execute;
while (my $row = $sth->fetchrow_hashref) {
my $type = $row->{'Type'};
$type .= " $1" if $row->{'Extra'} =~ /(auto_increment)/i;
$coltype{$table}->{ $row->{'Field'} } = lc($type);
}
# current physical table properties
$table_status{$table} =
$dbh->selectrow_hashref("SHOW TABLE STATUS LIKE '$table'");
$sth = $dbh->prepare("SHOW INDEX FROM $table");
$sth->execute;
my %idx_type; # name -> "UNIQUE"|"INDEX"
my %idx_parts; # name -> []
while (my $ir = $sth->fetchrow_hashref) {
$idx_type{$ir->{'Key_name'}} = $ir->{'Non_unique'} ? "INDEX" : "UNIQUE";
push @{$idx_parts{$ir->{'Key_name'}}}, $ir->{'Column_name'};
}
foreach my $idx (keys %idx_type) {
my $val = "$idx_type{$idx}:" . join("-", @{$idx_parts{$idx}});
$indexname{$table}->{$val} = $idx;
}
}
sub index_name
{
my ($table, $idx) = @_; # idx form is: INDEX:col1-col2-col3
load_table_info($table) unless $indexname{$table};
return $indexname{$table}->{$idx} || "";
}
sub table_relevant
{
my $table = shift;
return 1 unless $cluster;
return 1 if $clustered_table{$table};
return 0;
}
sub column_type
{
my ($table, $col) = @_;
load_table_info($table) unless $coltype{$table};
my $type = $coltype{$table}->{$col};
$type ||= "";
return $type;
}
sub table_status
{
my ($table, $col) = @_;
load_table_info($table) unless $table_status{$table};
return $table_status{$table}->{$col} || "";
}
sub ensure_confirm
{
my $area = shift;
return 1 if ($opt_sql && ($opt_confirm eq "all" or
$opt_confirm eq $area));
print STDERR "To proceed with the necessary changes, rerun with -r --confirm=$area\n";
return 0;
}
sub set_dbnote
{
my ($key, $value) = @_;
return unless $opt_sql && $key && $value;
return $dbh->do("REPLACE INTO blobcache (bckey, dateupdate, value) VALUES (?,NOW(),?)",
undef, $key, $value);
}
sub check_dbnote
{
my $key = shift;
return $dbh->selectrow_array("SELECT value FROM blobcache WHERE bckey=?",
undef, $key);
}