init
This commit is contained in:
623
ljcom/cgi-bin/bml/scheme/dystopia.look
Executable file
623
ljcom/cgi-bin/bml/scheme/dystopia.look
Executable file
@@ -0,0 +1,623 @@
|
||||
# LiveJournal.com-specific library
|
||||
#
|
||||
# This file is NOT licensed under the GPL. As with everything in the
|
||||
# "ljcom" CVS repository, this file is the property of Danga
|
||||
# Interactive and is made available to the public only as a reference
|
||||
# as to the best way to modify/extend the base LiveJournal server code
|
||||
# (which is licensed under the GPL).
|
||||
#
|
||||
# Feel free to read and learn from things in "ljcom", but don't use
|
||||
# our schemes because we don't want your site looking like
|
||||
# LiveJournal.com (our logo and site scheme are our identity and we
|
||||
# don't want to confuse users)
|
||||
#
|
||||
# Instead, use/modify one of the schemes in the "livejournal" repository.
|
||||
# (Ideally you'd make your own entirely)
|
||||
#
|
||||
|
||||
_parent=>global.look
|
||||
|
||||
help=>{Ds}<a href="%%data%%"><img src="<?imgprefix?>/help.gif" alt="(<?_ml Help _ml?>)" title="(<?_ml Help _ml?>)" width='14' height='14' hspace='2' align='absmiddle' border='0'></a>
|
||||
|
||||
h1=>{D}<p><span class="heading">%%data%%</span>
|
||||
h1/follow_choices=>{D}<span class="heading">%%data%%</span>
|
||||
|
||||
h2=>{D}<p><span class="heading2">%%data%%</span>
|
||||
|
||||
# Banner Header: search results banner, content desriptor, etc...
|
||||
bh=>{D}<p align="center"><font face="Arial,Helvetica" color="#cc0000" size="-1"><b>%%data%%</b></font>
|
||||
|
||||
grin=>{S}<grin>
|
||||
hr=>{S}<p align="center"><font color=#660066>*</font></p>
|
||||
|
||||
newline=>{S}<br />
|
||||
p=>{DRp}<br />%%data%%
|
||||
p/follow_p=>{DRps}<br /><img src="<?imgprefix?>/dot.gif" width="1" vspace="6" height="1"><br />%%data%%
|
||||
|
||||
emcolor=>{S}#a7c7e8
|
||||
emcolorlite=>{S}#d9e9f9
|
||||
altcolor1=>{S}#d9e9f9
|
||||
altcolor2=>{S}#a7c7e8
|
||||
|
||||
de=>{DRp}<span style="color:#909090;">%%data%%</span>
|
||||
|
||||
standout<=
|
||||
{DRps}<center><font size="1"><br /></font>
|
||||
<table cellspacing="0" cellpadding="0" border="0" bgcolor="<?emcolor?>">
|
||||
<tr align="left">
|
||||
<td width="7" align="left" valign="top">
|
||||
<img width="7" height="7" src="<?imgprefix?>/dys/corn_nw.gif" alt="/"></td>
|
||||
<td height="7">
|
||||
<img height="7" src="<?imgprefix?>/dot.gif" alt=""></td>
|
||||
<td width="7" valign="top" align="right">
|
||||
<img height="7" src="<?imgprefix?>/dys/corn_ne.gif" alt="\"></td>
|
||||
</tr><tr align="left">
|
||||
<td width="7">
|
||||
<img width="7" height="1" src="<?imgprefix?>/dot.gif" alt=""></td>
|
||||
<td valign="top">
|
||||
%%data%%
|
||||
|
||||
</td>
|
||||
<td width="7">
|
||||
<img width="7" height="1" src="<?imgprefix?>/dot.gif" alt=""></td>
|
||||
</tr><tr>
|
||||
<td width="7" align=left valign=top>
|
||||
<img width="7" height="7" src="<?imgprefix?>/dys/corn_sw.gif" alt="\"></td>
|
||||
<td height="7">
|
||||
<img height="7" src="<?imgprefix?>/dot.gif" alt=""></td>
|
||||
<td width="7" valign=top align=right>
|
||||
<img height="7" src="<?imgprefix?>/dys/corn_se.gif" alt="/"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</center>
|
||||
<=standout
|
||||
|
||||
warningbar<=
|
||||
{DRps}<div class="warningbar" style="background-image: URL('<?imgprefix?>/message-warning.gif');">
|
||||
%%data%%
|
||||
</div>
|
||||
<=warningbar
|
||||
|
||||
errorbar<=
|
||||
{DRps}<div class="errorbar" style="background-image: URL('<?imgprefix?>/message-error.gif');">
|
||||
%%data%%
|
||||
</div>
|
||||
<=errorbar
|
||||
|
||||
soerror=><div style='background-color:#d0eef9; color:red; font-weight:bold; text-align:center'>%%data%%</div>
|
||||
emailex=><div style='width: 50%; font-family: courier; background-color: #efefef; border: dotted #cdcdcd 2px; padding: 5px;'>%%data%%</div>
|
||||
|
||||
######################### choices stuff
|
||||
|
||||
choice=>{PRps}<dt><img src="<?imgprefix?>/dys/b_purp.gif" align="absmiddle" width="8" height="8"> <a href="%%data2%%"><font face="Arial,Helvetica"><b>%%data1%%</b></font></a><dd><font size="2">%%data3%%</font>
|
||||
|
||||
choices<=
|
||||
{FRp}<p><div class="choice"><table width="100%" cellpadding="2" cellspacing="5">
|
||||
<tr>
|
||||
<td valign="top" width="50%">
|
||||
<dl>
|
||||
%%items%%
|
||||
</dl>
|
||||
</td>
|
||||
<td valign="top" width="50%">
|
||||
<dl>
|
||||
%%itemsb%%
|
||||
</dl>
|
||||
</td>
|
||||
</tr>
|
||||
</table></div>
|
||||
<=choices
|
||||
|
||||
ENTRYFORMCSS<=
|
||||
{Ss}
|
||||
<style type="text/css">
|
||||
#EntryForm #MetaInfo {
|
||||
width: 100%;
|
||||
}
|
||||
#EntryForm th {
|
||||
font-size: .85em;
|
||||
}
|
||||
#EntryForm #SubmitBar {
|
||||
background-color: #dfdfdf;
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
border: 1px outset #000;
|
||||
margin-left: auto; margin-right: auto;
|
||||
}
|
||||
#MetaInfo tr {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
#metainfo th {
|
||||
text-align: left;
|
||||
}
|
||||
#mood_preview {
|
||||
display: none;
|
||||
}
|
||||
#datetime_box input, #datetime_box select {
|
||||
margin-right: 2px;
|
||||
}
|
||||
#EntryForm legend {
|
||||
font-weight: bold;
|
||||
}
|
||||
#EntryForm #Options {
|
||||
margin-left: 0; margin-right: 0; padding: 0;
|
||||
background-color: #dfdfdf;
|
||||
border: 1px outset #000;
|
||||
}
|
||||
#EntryForm #Options th {
|
||||
text-align: left;
|
||||
}
|
||||
#EntryForm #infobox {
|
||||
text-align: center;
|
||||
}
|
||||
#EntryForm #infobox table {
|
||||
background-color: #dfdfdf;
|
||||
border: 2px solid <?emcolor?>;
|
||||
}
|
||||
#EntryForm textarea {
|
||||
border: 1px inset #000;
|
||||
padding: 2px;
|
||||
}
|
||||
#EntryForm #Security option {
|
||||
padding-left: 18px;
|
||||
}
|
||||
#EntryForm #security_public {
|
||||
background-image: url("<?imgprefix?>/userinfo.gif");
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
#EntryForm #security_private {
|
||||
background-image: url("<?imgprefix?>/icon_private.gif");
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
#EntryForm #security_friends, #EntryForm #security_custom {
|
||||
background-image: url("<?imgprefix?>/icon_protected.gif");
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
#EntryForm #UserpicPreviewImage {
|
||||
border: 1px solid #000;
|
||||
}
|
||||
#EntryForm {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
<=ENTRYFORMCSS
|
||||
|
||||
##################################################################################
|
||||
################################### MAIN PAGE ####################################
|
||||
##################################################################################
|
||||
|
||||
PAGE<=
|
||||
{Fps}<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html>
|
||||
<?_code
|
||||
{
|
||||
my $remote = LJ::get_remote(); # will be requested later and returned from cache
|
||||
return LJ::LJcom::expresslane_html_comment($remote, $_[0]->{r});
|
||||
}
|
||||
_code?>
|
||||
<head>
|
||||
<link rel="SHORTCUT ICON" href="<?siteroot?>/favicon.ico">
|
||||
<link rel="home" title="Home" href="/" />
|
||||
<link rel="contents" title="Site Map" href="/site/" />
|
||||
<link rel="help" title="Technical Support" href="/support/" />
|
||||
<title><?_code {
|
||||
my $elhash = $_[2];
|
||||
return $elhash->{'WINDOWTITLE'} || $elhash->{'TITLE'};
|
||||
} _code?></title>
|
||||
<?_code LJ::res_includes() _code?>
|
||||
<?metactype?>
|
||||
<style type="text/css">
|
||||
<!--
|
||||
p, td { font-size: 12px; font-family: Verdana, Arial, Helvetica, sans-serif; }
|
||||
li { font-size: 12px; font-family: Verdana, Arial, Helvetica, sans-serif; }
|
||||
body { font-size: 12px; font-family: Verdana, Arial, Helvetica, sans-serif; margin: 0px; }
|
||||
.navtext { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px; color: #FF9900; font-weight: bold}
|
||||
.navlinks { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px; color: #FFFFFF; text-decoration: underline}
|
||||
a:link { font-family: Verdana, Arial, Helvetica, sans-serif; color: #000066; }
|
||||
a:visited { font-family: Verdana, Arial, Helvetica, sans-serif; color: #000066; }
|
||||
a:active { font-family: Verdana, Arial, Helvetica, sans-serif; color: #006699; }
|
||||
.wtext { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px; font-weight: bold; color: #FFFFFF}
|
||||
.login { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px}
|
||||
.wtextunbld { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px; color: #FFFFFF }
|
||||
.copy { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px; color: #000000}
|
||||
.heading { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; color: #660066; font-weight: bold}
|
||||
.heading2 { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; color: #660066; font-style: italic }
|
||||
.talk-comment { margin-top: 1em; }
|
||||
.lesstop { margin-top: 2px; }
|
||||
.formitem { color: #343434; font-size: 1em; }
|
||||
.formnumber { font-weight: bold; margin-top: 1.8em; font-size: .9em; }
|
||||
.formitemName { font-weight: bold; font-size: .9em; margin-top: 1.8em; }
|
||||
.formitemDesc { margin-top: .4em; margin-bottom: .4em; color: #505050; }
|
||||
.formitemNote { color: #da6320; font-size: .9em; margin-top: .4em; margin-bottom: .4em; }
|
||||
.formitemFlag { color: #CE0000; font-size: .9em; margin-top: .4em; margin-bottom: .4em; }
|
||||
.borderedtable { border: solid 1px black; }
|
||||
.borderedtable th { background-color: #dddddd; border-bottom: solid 1px black; padding-left: 10px; padding-right: 10px; white-space: nowrap; font-size: 0.8em; }
|
||||
|
||||
#Comments q { padding-left: 2.5em; font-style: italic; }
|
||||
|
||||
.errorbar {
|
||||
color: #000;
|
||||
font: 12px Verdana, Arial, Sans-Serif;
|
||||
background-color: #FFEEEE;
|
||||
background-repeat: repeat-x;
|
||||
border: 1px solid #FF9999;
|
||||
padding: 8px;
|
||||
margin-top: auto; margin-bottom: auto;
|
||||
margin-left: auto; margin-right: auto;
|
||||
width: auto;
|
||||
text-align: left;
|
||||
}
|
||||
.warningbar {
|
||||
color: #000;
|
||||
font: 12px Verdana, Arial, Sans-Serif;
|
||||
background-color: #FFFFDD;
|
||||
background-repeat: repeat-x;
|
||||
border: 1px solid #FFCC33;
|
||||
padding: 8px;
|
||||
margin-top: auto; margin-bottom: auto;
|
||||
margin-left: auto; margin-right: auto;
|
||||
width: auto;
|
||||
text-align: left;
|
||||
}
|
||||
-->
|
||||
</style>
|
||||
|
||||
<script language="JavaScript">
|
||||
window.onerror = null; // damn javascript.
|
||||
</script>
|
||||
<?_code return (! LJ::get_remote() &&
|
||||
! $LJ::IS_SSL &&
|
||||
! $LJ::REQ_HEAD_HAS{'chalresp_js'}++) ?
|
||||
$LJ::COMMON_CODE{'chalresp_js'} : "";
|
||||
_code?>
|
||||
<?_code
|
||||
use strict;
|
||||
my $crumb_up;
|
||||
if(LJ::get_active_crumb() ne '')
|
||||
{
|
||||
my $parentcrumb = LJ::get_parent_crumb();
|
||||
$crumb_up = "<link rel='up' title='$parentcrumb->[0]' href='$parentcrumb->[1]' />";
|
||||
}
|
||||
return $crumb_up;
|
||||
_code?>
|
||||
%%head%%
|
||||
</head>
|
||||
<body bgcolor="#FFFFFF" background="<?imgprefix?>/dys/bg.gif" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0" text="#000000" link="#660066" vlink="#000066" alink="#CC6600" %%bodyopts%%>
|
||||
<basefont face="Verdana,Arial,Helvetica">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr align="left" valign="top">
|
||||
<td colspan='2'>
|
||||
<table width='100%' border="0" cellspacing="0" cellpadding="0" background="<?imgprefix?>/dys/bg_top.gif">
|
||||
<tr>
|
||||
<td><a href="<?siteroot?>/"><img src="<?imgprefix?>/dys/logo1.gif" width="122" height="51" border="0"></a></td>
|
||||
<td width="163" align="left" valign="top"><a href="<?siteroot?>/"><img src="<?imgprefix?>/dys/logo2.gif" width="170" height="51" border="0"></a></td>
|
||||
<td background="<?imgprefix?>/dys/bg_top.gif" align="left" valign="top" width="244"> </td>
|
||||
<td background="<?imgprefix?>/dys/bg_top.gif" align="left" valign="top" width="100%"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- logo, then search & logged in links bar stack on top of each other -->
|
||||
|
||||
<tr align="left" valign="top">
|
||||
<td width="<?_ml dystopia.nav.width _ml?>" height="49"
|
||||
><?_code
|
||||
unless ($BML::COOKIE{'langpref'}) {
|
||||
return '<img src="<?imgprefix?>/dys/logo3-lang.gif" width="122" height="52" border="0" ismap="ismap" usemap="#setlang"><map name="setlang"><area href="/manage/siteopts.bml" shape="rect" coords="50,25,122,50"></map>';
|
||||
} else {
|
||||
return '<img src="<?imgprefix?>/dys/logo3.gif" width="122" height="52" border="0">';
|
||||
}
|
||||
_code?></td>
|
||||
<td height="49">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<colgroup span="3">
|
||||
<col width="19%" />
|
||||
<col width="34%" />
|
||||
<col width="47%" />
|
||||
</colgroup>
|
||||
|
||||
<!-- search bar -->
|
||||
<tr valign="top">
|
||||
<td height="24" width="19%" align="left"> </td>
|
||||
<form action="/multisearch.bml">
|
||||
<td height="24" align="right" valign="middle" colspan="2" nowrap="nowrap">
|
||||
<font face="verdana, arial, sans-serif" color=#333333 size=-2>
|
||||
<span class="wtextunbld"><label for='searchlj'><?_ml dystopia.searchlj _ml?></label> </span>
|
||||
<?_code
|
||||
#BML:cache
|
||||
my $ret;
|
||||
my ($cur, $val) = ("user", "");
|
||||
my ($uri, $args) = (BML::get_uri(), BML::get_query_string());
|
||||
if ($uri eq '/interests.bml' && $args =~ /int=(.+?)(&|$)/) {
|
||||
$cur = "int";
|
||||
$val = LJ::durl($1);
|
||||
}
|
||||
if ($FORM{'s_loc'}) {
|
||||
$cur = "region";
|
||||
}
|
||||
|
||||
my $hval = LJ::ehtml($val);
|
||||
$ret .= "<input id='searchlj' type='text' name='q' size='15' class='login' value='$hval'> ";
|
||||
$ret .= '<select style="FONT-SIZE: 10px; FONT-FAMILY: verdana, arial, helvetica" name=type>';
|
||||
foreach my $it (
|
||||
["user", BML::ml("Username")],
|
||||
["email", BML::ml("Email")],
|
||||
["region", BML::ml("dystopia.search.region")],
|
||||
["int", BML::ml("dystopia.search.int")],
|
||||
["aolim", BML::ml("dystopia.search.aolim")],
|
||||
["icq", BML::ml("dystopia.search.icq")],
|
||||
["yahoo", BML::ml("dystopia.search.yahoo")],
|
||||
["msn", BML::ml("dystopia.search.msn")],
|
||||
["jabber", BML::ml("dystopia.search.jabber")],
|
||||
) {
|
||||
next if ($it->[0] eq "region" && $LJ::DISABLED{'directory'});
|
||||
my $sel = $cur eq $it->[0] ? " SELECTED" : "";
|
||||
$ret .= "<option value=$it->[0]$sel>$it->[1]";
|
||||
}
|
||||
return BML::noparse($ret);
|
||||
_code?>
|
||||
</select>
|
||||
<img src="<?imgprefix?>/dot.gif" width="1" height="5">
|
||||
<input type=submit value="<?_ml btn.search _ml?>" class="login">
|
||||
</font>
|
||||
</td></form>
|
||||
</tr>
|
||||
<!-- /search livejournal bar -->
|
||||
|
||||
|
||||
<!-- logged in bar -->
|
||||
<tr>
|
||||
<td height="27" class="wtext" width="53%" colspan="2" nowrap="nowrap" valign="middle">
|
||||
<?_code
|
||||
#BML:cache
|
||||
if (LJ::get_remote()) {
|
||||
return BML::noparse(BML::ml("dystopia.hello_loggedin", { 'username' => LJ::get_remote()->{'user'} }));
|
||||
} else {
|
||||
return BML::noparse(BML::ml("dystopia.hello_anonymous"))
|
||||
}
|
||||
_code?></td>
|
||||
<td height="27" width="47%" nowrap="nowrap" align="right" valign="middle">
|
||||
<a href="/"><span class="navlinks"><?_ml dystopia.nav.home _ml?></span></a> <span class="navtext">|</span>
|
||||
<a href="/site/"><span class="navlinks"><?_ml dystopia.nav.sitemap _ml?></span></a> <span class="navtext">|</span>
|
||||
<a href="/news.bml"><span class="navlinks"><?_ml dystopia.nav.news _ml?></span></a> <span class="navtext">|</span>
|
||||
<a href="/manage/siteopts.bml"><span class="navlinks"><?_ml dystopia.nav.siteopts _ml?></span></a> <span class="navtext">|</span>
|
||||
<a href="/support/"><span class="navlinks"><?_ml Help _ml?></span></a>
|
||||
<?_code
|
||||
#BML:cache
|
||||
my $r = LJ::get_remote();
|
||||
if ($r) {
|
||||
return BML::noparse(' <span class="navtext">|</span> <a href="/logout.bml?user=' . "$r->{'user'}&sessid=$r->{'_session'}->{'sessid'}" . '"><span class="navlinks">' . BML::ml("dystopia.nav.logout") . '</span></a>');
|
||||
}
|
||||
return;
|
||||
_code?>
|
||||
<img src="<?imgprefix?>/dys/5x5.gif" width="10" height="5"></td>
|
||||
</tr>
|
||||
<!-- /logged in bar -->
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- /logo, search, logged in bar -->
|
||||
|
||||
<!-- left sidebar and body -->
|
||||
|
||||
<tr align="left" valign="top">
|
||||
<td bgcolor="#336699" width="<?_ml dystopia.nav.width _ml?>" height="813">
|
||||
<table width="<?_ml dystopia.nav.width _ml?>" border="0" cellspacing="0" cellpadding="10">
|
||||
<?_code
|
||||
#BML:cache
|
||||
my @nav;
|
||||
my $remote = LJ::get_remote();
|
||||
if ($remote) {
|
||||
push @nav, { 'name' => BML::ml('dystopia.navhead.journal'),
|
||||
'links' => [ { 'url' => '/update.bml',
|
||||
'text' => BML::ml('dystopia.nav.updatejournal'), },
|
||||
{ 'url' => "/users/$remote->{'user'}/",
|
||||
'text' => BML::ml('dystopia.nav.journalrecent'), },
|
||||
{ 'url' => "/users/$remote->{'user'}/calendar",
|
||||
'text' => BML::ml('dystopia.nav.journalcalendar'), },
|
||||
{ 'url' => "/users/$remote->{'user'}/friends",
|
||||
'text' => BML::ml('dystopia.nav.journalfriends'),
|
||||
'extra' => '/friends/filter.bml', },
|
||||
{ 'url' => "/userinfo.bml?user=$remote->{'user'}",
|
||||
'text' => BML::ml('dystopia.nav.journalinfo'),
|
||||
'extra' => "/userinfo.bml?user=$remote->{'user'}&mode=full",
|
||||
},
|
||||
{ 'url' => "/tools/memories.bml?user=$remote->{'user'}",
|
||||
'text' => BML::ml('dystopia.nav.memories'), },
|
||||
{ 'url' => "/editjournal.bml",
|
||||
'text' => BML::ml('dystopia.nav.editentries'), },
|
||||
],
|
||||
};
|
||||
push @nav, { 'name' => BML::ml('dystopia.navhead.settings'),
|
||||
'links' => [ { 'url' => '/manage/',
|
||||
'text' => BML::ml('dystopia.nav.manage') },
|
||||
{ 'url' => '/editinfo.bml',
|
||||
'text' => BML::ml('dystopia.nav.personalinfo') },
|
||||
{ 'url' => "/friends/edit.bml",
|
||||
'text' => BML::ml('dystopia.nav.editfriends'), },
|
||||
{ 'url' => "/editpics.bml",
|
||||
'text' => BML::ml('dystopia.nav.editpics'), },
|
||||
{ 'url' => "/changepassword.bml",
|
||||
'text' => BML::ml('dystopia.nav.editpassword'), },
|
||||
{ 'url' => "/modify.bml",
|
||||
'text' => BML::ml('dystopia.nav.modifyjournal'), },
|
||||
{ 'url' => "/styles/edit.bml",
|
||||
'text' => BML::ml('dystopia.nav.editstyle'), },
|
||||
],
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
push @nav, { 'name' => BML::ml('dystopia.navhead.welcome'),
|
||||
'links' => [
|
||||
{ 'url' => '/login.bml',
|
||||
'text' => BML::ml('dystopia.nav.login'), },
|
||||
{ 'url' => '/create.bml',
|
||||
'text' => BML::ml('dystopia.nav.createjournal'), },
|
||||
{ 'url' => "/update.bml",
|
||||
'text' => BML::ml('dystopia.nav.updatejournal'), },
|
||||
],
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
push @nav, { 'name' => BML::ml('dystopia.navhead.findusers'),
|
||||
'links' => [
|
||||
{ 'url' => '/random.bml',
|
||||
'text' => BML::ml('dystopia.nav.findrandom'), },
|
||||
$LJ::DISABLED{'directory'} ? () :
|
||||
(
|
||||
{ 'url' => '/directory.bml',
|
||||
'text' => BML::ml('dystopia.nav.findregion'), }
|
||||
),
|
||||
{ 'url' => '/community/',
|
||||
'text' => BML::ml('dystopia.nav.findcomm'), },
|
||||
{ 'url' => '/interests.bml',
|
||||
'text' => BML::ml('dystopia.nav.findint'), },
|
||||
$LJ::DISABLED{'directory'} ? () :
|
||||
(
|
||||
{ 'url' => '/directorysearch.bml',
|
||||
'text' => BML::ml('dystopia.nav.finddir'), }
|
||||
),
|
||||
],
|
||||
};
|
||||
|
||||
push @nav, { 'name' => 'LiveJournal',
|
||||
'links' => [
|
||||
{ 'url' => '/download/',
|
||||
'text' => BML::ml('dystopia.nav.download'), },
|
||||
{ 'url' => '/paidaccounts/',
|
||||
'text' => BML::ml('dystopia.nav.paidaccts'), },
|
||||
{ 'url' => '/pay/',
|
||||
'text' => BML::ml('dystopia.nav.paymentarea'), },
|
||||
],
|
||||
};
|
||||
|
||||
push @nav, { 'name' => BML::ml('dystopia.navhead.help'),
|
||||
'links' => [ { 'url' => '/support/faq.bml',
|
||||
'text' => BML::ml('dystopia.nav.faq'), },
|
||||
{ 'url' => '/support/',
|
||||
'text' => BML::ml('dystopia.nav.support'), },
|
||||
{ 'url' => '/lostinfo.bml',
|
||||
'text' => BML::ml('dystopia.nav.lostinfo'), },
|
||||
{ 'url' => '/developer/',
|
||||
'text' => BML::ml('dystopia.nav.developer'), },
|
||||
{ 'url' => '/press/staff.bml',
|
||||
'text' => BML::ml('dystopia.nav.contact'), },
|
||||
],
|
||||
};
|
||||
|
||||
push @nav, { 'name' => BML::ml('dystopia.navhead.legal'),
|
||||
'links' => [ { 'url' => '/legal/tos.bml',
|
||||
'text' => BML::ml('dystopia.nav.legaltos'), },
|
||||
{ 'url' => '/legal/privacy.bml',
|
||||
'text' => BML::ml('dystopia.nav.legalprivacy'), },
|
||||
{ 'url' => '/legal/dmca.bml',
|
||||
'text' => BML::ml('dystopia.nav.legaldmca'), },
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
my $ret = $LJ::DYS_LEFT_TOP;
|
||||
foreach my $sec (@nav) {
|
||||
$ret .= "<tr align=left valign=top><td><p><span class=navtext>$sec->{'name'}</span><br />";
|
||||
foreach my $l (@{$sec->{'links'}}) {
|
||||
$ret .= "<a href=\"$l->{'url'}\"><span class=navlinks>$l->{'text'}</span></a>";
|
||||
if ($l->{'extra'}) {
|
||||
$ret .= " <a href=\"$l->{'extra'}\"><span class=navlinks>...</span></a>";
|
||||
}
|
||||
$ret .= "<br />";
|
||||
}
|
||||
$ret .= "</td></tr>";
|
||||
}
|
||||
return BML::noparse($ret);
|
||||
|
||||
_code?>
|
||||
<tr align="left" valign="top">
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr align="left" valign="top">
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr align="left" valign="top">
|
||||
<td> </td>
|
||||
</tr>
|
||||
</table>
|
||||
<p> </p>
|
||||
<p> </p>
|
||||
</td>
|
||||
<td height="813" bgcolor="#FFFFFF">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
|
||||
<!-- login bar -->
|
||||
<?_code
|
||||
#BML:cache
|
||||
#WITHPORTAL: unless ($remote || BML::get_uri() eq "/") {
|
||||
my $remote = LJ::get_remote();
|
||||
unless ($remote || BML::get_uri eq '/login.bml') {
|
||||
my $button;
|
||||
my $logincaption = BML::ml('dystopia.btn.login');
|
||||
if ($logincaption eq 'LOGIN') {
|
||||
if (! $LJ::IS_SSL) {
|
||||
$button = "<input type=image onclick='return sendForm()' src='$LJ::IMGPREFIX/dys/login_but.gif' width='48' height='15' border='0'>";
|
||||
} else {
|
||||
$button = "<input type=image src='$LJ::IMGPREFIX/dys/login_but.gif' width='48' height='15' border='0'>";
|
||||
}
|
||||
} else {
|
||||
if (! $LJ::IS_SSL) {
|
||||
$button = "<input type='submit' onclick='return sendForm()' value='$ML{'dystopia.btn.login'}' style='margin-top: 0px; margin-bottom: 1px; font-weight: bold; height: 19px; border: 1px solid #ffffff; background: #336699 none; color: #ffffff; padding-left: 0px; padding-right: 0px'></td>";
|
||||
} else {
|
||||
$button = "<input type='submit' value='$ML{'dystopia.btn.login'}' style='margin-top: 0px; margin-bottom: 1px; font-weight: bold; height: 19px; border: 1px solid #ffffff; background: #336699 none; color: #ffffff; padding-left: 0px; padding-right: 0px'></td>";
|
||||
}
|
||||
}
|
||||
|
||||
my $chal = LJ::challenge_generate(300);
|
||||
return <<"END_LOGIN_BAR";
|
||||
<form action="/login.bml" method="post" id='login'>
|
||||
<input type="hidden" name="mode" value="login" />
|
||||
<input type='hidden' name='chal' id='login_chal' value='$chal' />
|
||||
<input type='hidden' name='response' id='login_response' value='' />
|
||||
<tr>
|
||||
<td align="right" valign="top" bgcolor="#FFFFFF">
|
||||
<table border='0' cellspacing='0' cellpadding='0' width='200' align='right'>
|
||||
<tr>
|
||||
<td align="left" valign="bottom" bgcolor="#660066"><img src="<?imgprefix?>/dys/lg_crnrgif.gif" width="14" height="23"></td>
|
||||
<td align="right" valign="middle" bgcolor="#660066" class="wtextunbld" nowrap="nowrap"> $ML{'Username'}: </td>
|
||||
<td align="center" valign="top" bgcolor="#660066" class="wtext" nowrap="nowrap"><input type="text" name="user" size="15" maxlength="15" class="login" style="<?loginboxstyle?>"></td>
|
||||
<td align="right" valign="middle" bgcolor="#660066" class="wtextunbld" nowrap="nowrap"> $ML{'Password'}: </td>
|
||||
<td align="center" valign="top" bgcolor="#660066" class="wtext" nowrap="nowrap"><input type="password" name="password" size="10" id='xc_password' class="login"></td>
|
||||
<td align="center" valign="middle" bgcolor="#660066" nowrap="nowrap"> $button</tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
</form>
|
||||
END_LOGIN_BAR
|
||||
}
|
||||
return;
|
||||
|
||||
_code?>
|
||||
<!-- /login bar -->
|
||||
|
||||
<tr align="left" valign="top" bgcolor="#ffffff">
|
||||
<td height="585" colspan="7">
|
||||
|
||||
<!-- body area -->
|
||||
<table border="0" cellspacing="0" cellpadding="10" width="100%"><tr><td>
|
||||
|
||||
<?breadcrumbs?>
|
||||
|
||||
%%pretitle%%
|
||||
|
||||
<font size="+2" face="Verdana, Arial, Helvetica" color=#000066>%%title%%</font><p>
|
||||
|
||||
%%body%%
|
||||
|
||||
</td></tr></table>
|
||||
<!-- /body area -->
|
||||
</td></tr></table>
|
||||
</td></tr></table>
|
||||
</body></html>
|
||||
<=PAGE
|
||||
|
||||
213
ljcom/cgi-bin/bml/scheme/ssl.look
Normal file
213
ljcom/cgi-bin/bml/scheme/ssl.look
Normal file
@@ -0,0 +1,213 @@
|
||||
# SSL scheme
|
||||
|
||||
# LiveJournal.com-specific library
|
||||
#
|
||||
# This file is NOT licensed under the GPL. As with everything in the
|
||||
# "ljcom" CVS repository, this file is the property of Danga
|
||||
# Interactive and is made available to the public only as a reference
|
||||
# as to the best way to modify/extend the base LiveJournal server code
|
||||
# (which is licensed under the GPL).
|
||||
#
|
||||
# Feel free to read and learn from things in "ljcom", but don't use our styles
|
||||
# because we don't want your site looking like LiveJournal.com (our logo
|
||||
# and site scheme are our identity and we don't want to confuse users)
|
||||
#
|
||||
|
||||
######################### little stuff
|
||||
|
||||
_parent=>global.look
|
||||
|
||||
imgprefix=>{S}/img
|
||||
statprefix=>{S}/stc
|
||||
|
||||
help=>{Ds}<a href="%%data%%"><img src="/img/help.gif" alt="(<?_ml Help _ml?>)" title="(<?_ml Help _ml?>)" width='14' height='14' hspace='2' align='absmiddle' border='0'></a>
|
||||
|
||||
h1=>{D}<p><span class="heading">%%data%%</span>
|
||||
h1/follow_choices=>{D}<span class="heading">%%data%%</span>
|
||||
|
||||
h2=>{D}<p><span class="heading2">%%data%%</span>
|
||||
|
||||
# Banner Header: search results banner, content desriptor, etc...
|
||||
bh=>{D}<p align="center"><font face="Arial,Helvetica" color="#cc0000" size="-1"><b>%%data%%</b></font>
|
||||
|
||||
grin=>{S}<grin>
|
||||
hr=>{S}<p align="center"><font color=#660066>*</font></p>
|
||||
|
||||
newline=>{S}<br />
|
||||
p=>{DRp}<br />%%data%%
|
||||
p/follow_p=>{DRps}<br /><img src="/img/dot.gif" width="1" vspace="6" height="1"><br />%%data%%
|
||||
|
||||
emcolor=>{S}#a7c7e8
|
||||
emcolorlite=>{S}#d9e9f9
|
||||
|
||||
de=>{DRp}<span style="color:#909090;">%%data%%</span>
|
||||
|
||||
standout<=
|
||||
{DRps}<center><font size="1"><br /></font>
|
||||
<table cellspacing="0" cellpadding="0" border="0" bgcolor="<?emcolor?>">
|
||||
<tr align="left">
|
||||
<td width="7" align="left" valign="top">
|
||||
<img width="7" height="7" src="/img/dys/corn_nw.gif" alt="/"></td>
|
||||
<td height="7">
|
||||
<img height="7" src="/img/dot.gif" alt=""></td>
|
||||
<td width="7" valign="top" align="right">
|
||||
<img height="7" src="/img/dys/corn_ne.gif" alt="\"></td>
|
||||
</tr><tr align="left">
|
||||
<td width="7">
|
||||
<img width="7" height="1" src="/img/dot.gif" alt=""></td>
|
||||
<td valign="top">
|
||||
%%data%%
|
||||
|
||||
</td>
|
||||
<td width="7">
|
||||
<img width="7" height="1" src="/img/dot.gif" alt=""></td>
|
||||
</tr><tr>
|
||||
<td width="7" align=left valign=top>
|
||||
<img width="7" height="7" src="/img/dys/corn_sw.gif" alt="\"></td>
|
||||
<td height="7">
|
||||
<img height="7" src="/img/dot.gif" alt=""></td>
|
||||
<td width="7" valign=top align=right>
|
||||
<img height="7" src="/img/dys/corn_se.gif" alt="/"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</center>
|
||||
<=standout
|
||||
|
||||
######################### choices stuff
|
||||
|
||||
choice=>{PRps}<dt><img src="/img/dys/b_purp.gif" align="absmiddle" width="8" height="8"> <a href="%%data2%%"><font face="Arial,Helvetica"><b>%%data1%%</b></font></a><dd><font size="2">%%data3%%</font>
|
||||
|
||||
choices<=
|
||||
{FRp}<p><div class="choice"><table width="100%" cellpadding="2" cellspacing="5">
|
||||
<tr>
|
||||
<td valign="top" width="50%">
|
||||
<dl>
|
||||
%%items%%
|
||||
</dl>
|
||||
</td>
|
||||
<td valign="top" width="50%">
|
||||
<dl>
|
||||
%%itemsb%%
|
||||
</dl>
|
||||
</td>
|
||||
</tr>
|
||||
</table></div>
|
||||
<=choices
|
||||
|
||||
##################################################################################
|
||||
################################### MAIN PAGE ####################################
|
||||
##################################################################################
|
||||
|
||||
PAGE<=
|
||||
{Fps}<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<link rel="SHORTCUT ICON" href="<?siteroot?>/favicon.ico">
|
||||
<title>%%title%%</title>
|
||||
<?metactype?>
|
||||
<style type="text/css">
|
||||
<!--
|
||||
p, td { font-size: 12px; font-family: Verdana, Arial, Helvetica, sans-serif; }
|
||||
li { font-size: 12px; font-family: Verdana, Arial, Helvetica, sans-serif; }
|
||||
body { font-size: 12px; font-family: Verdana, Arial, Helvetica, sans-serif; margin: 0px; }
|
||||
.navtext { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px; color: #FF9900; font-weight: bold}
|
||||
.navlinks { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px; color: #FFFFFF; text-decoration: underline}
|
||||
a:link { font-family: Verdana, Arial, Helvetica, sans-serif; color: #000066; }
|
||||
a:visited { font-family: Verdana, Arial, Helvetica, sans-serif; color: #000066; }
|
||||
a:active { font-family: Verdana, Arial, Helvetica, sans-serif; color: #006699; }
|
||||
.wtext { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px; font-weight: bold; color: #FFFFFF}
|
||||
.login { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px}
|
||||
.wtextunbld { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px; color: #FFFFFF }
|
||||
.copy { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px; color: #000000}
|
||||
.heading { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; color: #660066; font-weight: bold}
|
||||
.heading2 { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; color: #660066; font-style: italic }
|
||||
-->
|
||||
</style>
|
||||
|
||||
<script language="JavaScript">
|
||||
window.onerror = null; // damn javascript.
|
||||
</script>
|
||||
%%head%%
|
||||
|
||||
</head>
|
||||
<?_code
|
||||
$BML::Dys::remote = LJ::get_remote();
|
||||
return;
|
||||
_code?>
|
||||
<body bgcolor="#FFFFFF" background="/img/dys/bg.gif" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0" text="#000000" link="#660066" vlink="#000066" alink="#CC6600" %%bodyopts%%>
|
||||
<basefont face="Verdana,Arial,Helvetica">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr align="left" valign="top">
|
||||
<td colspan='2'>
|
||||
<table width='100%' border="0" cellspacing="0" cellpadding="0" background="/img/dys/bg_top.gif">
|
||||
<tr>
|
||||
<td><a href="<?siteroot?>/"><img src="/img/dys/logo1.gif" width="122" height="51" border="0"></a></td>
|
||||
<td width="163" align="left" valign="top"><a href="<?siteroot?>/"><img src="/img/dys/logo2.gif" width="170" height="51" border="0"></a></td>
|
||||
<td background="/img/dys/bg_top.gif" align="left" valign="top" width="244"> </td>
|
||||
<td background="/img/dys/bg_top.gif" align="left" valign="top" width="100%"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- logo, then search & logged in links bar stack on top of each other -->
|
||||
|
||||
<tr align="left" valign="top">
|
||||
<td width="<?_ml dystopia.nav.width _ml?>" height="49"><img
|
||||
src="/img/dys/logo3.gif" width="122" height="52" border="0"></td>
|
||||
|
||||
<td height="49">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
|
||||
<!-- search bar -->
|
||||
<tr valign="top">
|
||||
<td height="24" width="19%" align="left"> </td>
|
||||
<td height="24" align="right" valign="middle" nowrap>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- /search livejournal bar -->
|
||||
|
||||
|
||||
<!-- logged in bar -->
|
||||
<tr>
|
||||
<td height="27" class="wtext" width="53%" colspan="2" align='right' nowrap="nowrap" valign="middle">
|
||||
LiveJournal Secure Site <img src='/img/dys/lock.gif' width='14' height='15' hspace='2'>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<!-- /logged in bar -->
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- /logo, search, logged in bar -->
|
||||
|
||||
<!-- left sidebar and body -->
|
||||
|
||||
<tr align="left" valign="top">
|
||||
<td height="813" colspan='2' bgcolor="#FFFFFF">
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
|
||||
|
||||
<tr align="left" valign="top" bgcolor="#ffffff">
|
||||
<td height="585" colspan="7">
|
||||
|
||||
<!-- body area -->
|
||||
<table border="0" cellspacing="0" cellpadding="10" width="100%"><tr><td>
|
||||
|
||||
%%pretitle%%
|
||||
|
||||
<div style='margin-left: 40px'>
|
||||
<font size="+2" face="Verdana, Arial, Helvetica" color=#000066>%%title%%</font><p>
|
||||
|
||||
%%body%%
|
||||
</div>
|
||||
|
||||
</td></tr></table>
|
||||
<!-- /body area -->
|
||||
</td></tr></table>
|
||||
</td></tr></table>
|
||||
</body></html>
|
||||
<=PAGE
|
||||
|
||||
838
ljcom/cgi-bin/console-local.pl
Normal file
838
ljcom/cgi-bin/console-local.pl
Normal file
@@ -0,0 +1,838 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
|
||||
package LJ::Con;
|
||||
|
||||
my $success = sub {
|
||||
my ($out, $msg) = @_;
|
||||
push @$out, [ "", $msg ];
|
||||
return 1;
|
||||
};
|
||||
my $fail = sub {
|
||||
my ($out, $msg) = @_;
|
||||
push @$out, [ "error", $msg ];
|
||||
return 0;
|
||||
};
|
||||
my $usage = sub {
|
||||
my ($out, $cmdname) = @_;
|
||||
return $fail->($out, "usage: $cmdname $cmd{$cmdname}{argsummary}");
|
||||
};
|
||||
|
||||
$cmd{'contrib'} = {
|
||||
'handler' => \&contrib_edit,
|
||||
'des' => "Adds/Acks Contributions.",
|
||||
'argsummary' => '<command> [<username>/<ackid>] [<contribtype>] [<msg>] [<url>]',
|
||||
'args' => [
|
||||
'command' => "Either 'ack' to ack a contrib, 'add' to add a contrib.",
|
||||
'username' => "The username for the contribution to add.",
|
||||
'ackid' => "Id of the contribution to ack.",
|
||||
'contribtype' => "'code' for Coding, 'doc' for documentation, 'creative' for artwork, 'biz' for buisness, 'other' for other",
|
||||
'msg' => "description of what they did",
|
||||
'url' => "[optional] url with more information",
|
||||
],
|
||||
};
|
||||
|
||||
$cmd{'payment_credit'} = {
|
||||
'handler' => \&payment_credit,
|
||||
'privs' => [qw(moneyenter)],
|
||||
'des' => "Give payment credit to an existing user from either an account code or a payid. Marks the associated code as then used by that username.",
|
||||
'argsummary' => '<thing> <id> to <username>',
|
||||
'args' => [
|
||||
'thing' => "Either 'code' or 'payment'.",
|
||||
'id' => "If code, the code; if payment, the payid.",
|
||||
'username' => "The username to give the time to.",
|
||||
],
|
||||
};
|
||||
|
||||
$cmd{'unpay'} = {
|
||||
'handler' => \&unpay,
|
||||
'privs' => [qw(moneyenter)],
|
||||
'des' => "Takes away paid time from a user for a bogus/accidental payment, while also changing the payment record to 0 months and 0 dollars, and making a note in the statushistory table why the payment was removed, and what the payment's old values were.",
|
||||
'argsummary' => '<user> <payid> <reason>',
|
||||
'args' => [
|
||||
'user' => 'Username of person to remove time from. Or, use "!" (without the quotes) for no user, when you just want to zero out a payment and/or its associated account code.',
|
||||
'payid' => 'Payment ID# to delete',
|
||||
'reason' => 'The reason the payment is being deleted. Not sent to user, only put in user\'s statushistory.',
|
||||
],
|
||||
};
|
||||
|
||||
$cmd{'inventory'} = {
|
||||
'handler' => \&inventory,
|
||||
'privs' => [qw(moneyenter shipping)],
|
||||
'des' => "View or modify inventory.",
|
||||
'argsummary' => '<command> [<item> <value>]',
|
||||
'args' => [
|
||||
'command' => 'Either "show" to show current inventory, "add" to add <value> units of <item>, or "remove" to remove <value> units of <item>, or "price" to change the price of <item> to <value>.',
|
||||
'item' => 'Inventory code.',
|
||||
'value' => 'Number to change inventory by, or new cost.',
|
||||
],
|
||||
};
|
||||
|
||||
sub unpay
|
||||
{
|
||||
my ($dbh, $remote, $args, $out) = @_;
|
||||
|
||||
my $user = LJ::canonical_username($args->[1]);
|
||||
if ($args->[1] eq "!") { $user = "!"; }
|
||||
|
||||
my $payid = $args->[2];
|
||||
my $reason = $args->[3];
|
||||
|
||||
my $err = sub {
|
||||
my $err = shift;
|
||||
my $lock = shift;
|
||||
push @$out, [ "error", $err ];
|
||||
if ($lock) {
|
||||
my $qlock = $dbh->quote($lock);
|
||||
$dbh->do("SELECT RELEASE_LOCK($qlock)");
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
return $err->("$remote->{'user'}, you are not authorized to use this command.")
|
||||
unless (LJ::check_priv($dbh, $remote, "moneyenter"));
|
||||
|
||||
return $err->("No reason given")
|
||||
unless $reason;
|
||||
|
||||
return $err->("Invalid or missing username argument")
|
||||
unless $user;
|
||||
|
||||
return $err->("Invalid payid format (not a number")
|
||||
unless ($payid =~ /^\d+$/);
|
||||
|
||||
my $p = $dbh->selectrow_hashref("SELECT * FROM payments WHERE payid=$payid");
|
||||
my $u;
|
||||
if ($user eq "!") {
|
||||
$u = {
|
||||
'userid' => 0,
|
||||
};
|
||||
} else {
|
||||
$u = LJ::load_user($user, "force");
|
||||
}
|
||||
|
||||
return $err->("The unpay command doesn't work with the new payment system")
|
||||
if $p->{'forwhat'} eq "cart";
|
||||
|
||||
return $err->("Payment not found")
|
||||
unless $p;
|
||||
|
||||
return $err->("User not found")
|
||||
unless $u;
|
||||
|
||||
return $err->("That payment doesn't belong to that user")
|
||||
unless ($p->{'userid'} == $u->{'userid'});
|
||||
|
||||
return $err->("That payment has no months or money associated with it.")
|
||||
unless ($p->{'amount'} ne "0.00" || $p->{'months'});
|
||||
|
||||
my $lockname = "unpay-$user-$payid";
|
||||
my $status;
|
||||
|
||||
# start pseudo-transaction
|
||||
$status = $dbh->selectrow_array("SELECT GET_LOCK('$lockname',10)");
|
||||
return $err->("Failed to get lock on necessary tables to do unpay, try again.")
|
||||
unless $status;
|
||||
|
||||
my $months = $p->{'months'}+0;
|
||||
|
||||
my $logtext = ("Removing payid \#$payid ($p->{'months'} months & $p->{'amount'} ".
|
||||
"dollars). Reason: " . $reason);
|
||||
|
||||
# add to status history
|
||||
if ($u->{'userid'}) {
|
||||
$status = LJ::statushistory_add($dbh, $u->{'userid'}, $remote->{'userid'},
|
||||
"unpay", $logtext);
|
||||
} else {
|
||||
$dbh->do("UPDATE payments SET notes=concat(notes, ?) WHERE payid=$payid", undef,
|
||||
"\nUNPAY: $logtext");
|
||||
}
|
||||
|
||||
$err->("Couldn't append statushistory table, aborting", $lockname)
|
||||
unless $status;
|
||||
|
||||
|
||||
# update payment record
|
||||
$dbh->do("UPDATE payments SET months=0, amount=0, used='Y' WHERE payid=$payid");
|
||||
$err->("Couldn't update payment record, aborting", $lockname)
|
||||
if $dbh->err;
|
||||
|
||||
# subtract time from user
|
||||
$dbh->do("UPDATE paiduser SET paiduntil=DATE_SUB(paiduntil, INTERVAL $months MONTH) WHERE userid=$p->{'userid'}");
|
||||
$err->("Couldn't subtract time from user, aborting", $lockname)
|
||||
if $dbh->err;
|
||||
|
||||
# end transaction
|
||||
$dbh->do("SELECT RELEASE_LOCK('$lockname')");
|
||||
|
||||
push @$out, [ "", "Done." ];
|
||||
}
|
||||
|
||||
sub payment_credit
|
||||
{
|
||||
my ($dbh, $remote, $args, $out) = @_;
|
||||
|
||||
my $thing = $args->[1];
|
||||
my $id = $args->[2];
|
||||
my $to = $args->[3];
|
||||
my $username = $args->[4];
|
||||
|
||||
unless ($remote->{'priv'}->{'moneyenter'}) {
|
||||
push @$out, [ "error", "$remote->{'user'}, you are not authorized to use this command." ];
|
||||
return 0;
|
||||
}
|
||||
|
||||
unless ($thing eq "code" || $thing eq "payment") {
|
||||
push @$out, [ "error", "Invalid first argument." ];
|
||||
return 0;
|
||||
}
|
||||
|
||||
unless ($to eq "to") {
|
||||
push @$out, [ "error", "Third argument isn't 'to'" ];
|
||||
return 0;
|
||||
}
|
||||
|
||||
my $u = LJ::load_user($username, "force");
|
||||
unless ($u) {
|
||||
push @$out, [ "error", "User doesn't exist." ];
|
||||
return 0;
|
||||
}
|
||||
|
||||
my $payid;
|
||||
my $acid;
|
||||
|
||||
if ($thing eq "code")
|
||||
{
|
||||
my $code = $id;
|
||||
($acid, undef) = LJ::acct_code_decode($code);
|
||||
my $err;
|
||||
unless (LJ::acct_code_check($dbh, $code, \$err)) {
|
||||
push @$out, [ "error", "Bad code: $err." ];
|
||||
return 0;
|
||||
}
|
||||
my $sth = $dbh->prepare("SELECT payid FROM acctpay WHERE acid=$acid");
|
||||
$sth->execute;
|
||||
($payid) = $sth->fetchrow_array;
|
||||
|
||||
unless ($payid) {
|
||||
push @$out, [ "error", "This code doesn't have an associated payment." ];
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ($thing eq "payment") {
|
||||
$payid = $id+0;
|
||||
|
||||
my $sth = $dbh->prepare("SELECT acid FROM acctpay WHERE payid=$payid");
|
||||
$sth->execute;
|
||||
($acid) = $sth->fetchrow_array;
|
||||
|
||||
unless ($acid) {
|
||||
push @$out, [ "error", "This payment doesn't have an associated code." ];
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
my $sth = $dbh->prepare("SELECT * FROM payments WHERE payid=$payid");
|
||||
$sth->execute;
|
||||
my $p = $sth->fetchrow_hashref;
|
||||
unless ($p) {
|
||||
push @$out, [ "error", "Payment not found." ];
|
||||
return 0;
|
||||
}
|
||||
unless ($p->{'userid'} == 0) {
|
||||
push @$out, [ "error", "Payment already assigned... not open." ];
|
||||
return 0;
|
||||
}
|
||||
|
||||
# guess everything's good.
|
||||
$dbh->do("UPDATE payments SET userid=$u->{'userid'} WHERE payid=$payid");
|
||||
$dbh->do("UPDATE acctcode SET rcptid=$u->{'userid'} WHERE acid=$acid");
|
||||
|
||||
push @$out, [ "", "Done." ];
|
||||
}
|
||||
|
||||
sub contrib_edit
|
||||
{
|
||||
my ($dbh, $remote, $args, $out) = @_;
|
||||
my $err = sub { push @$out, [ "error", $_[0] ]; 0; };
|
||||
|
||||
return $err->("This command has 2 or more arguments") unless @$args >= 2;
|
||||
return $err->("Must be logged in.") unless $remote;
|
||||
|
||||
my $cmd = $args->[1];
|
||||
if ($cmd eq "add")
|
||||
{
|
||||
return $err->("Not enough arguments for add.")
|
||||
unless @$args == 5 or @$args == 6;
|
||||
my $user = $args->[2];
|
||||
my $cat = $args->[3];
|
||||
my $des = $args->[4];
|
||||
my $url = $args->[5];
|
||||
|
||||
my $u = LJ::load_user($user, "force");
|
||||
return $err->("Invalid user $user") unless $u;
|
||||
my $userid = $u->{'userid'};
|
||||
return $err->("type can only be: 'code','doc','creative','biz','other'") unless
|
||||
($cat eq "code" or $cat eq "doc" or $cat eq "creative" or
|
||||
$cat eq "biz" or $cat eq "other");
|
||||
|
||||
$dbh->do("INSERT INTO contributed (userid, cat, des, url, dateadd) ".
|
||||
"VALUES (?,?,?,?,NOW())", undef, $userid, $cat, $des, $url);
|
||||
return $err->("error adding contribution") if $dbh->err;
|
||||
|
||||
} elsif ($cmd eq "ack") {
|
||||
|
||||
return $err->("Not enough arguments for ack.") unless @$args == 3;
|
||||
return $err->("You have to be an acknowledged contributor before you can acknowledge other people.")
|
||||
unless LJ::Contrib::is_acked($remote->{'userid'});
|
||||
|
||||
my $coid = $args->[2]+0;
|
||||
|
||||
LJ::Contrib::ack($coid, $remote->{'userid'});
|
||||
|
||||
} else {
|
||||
return $err->("Unknown Command Type");
|
||||
}
|
||||
|
||||
push @$out, [ '', "Success." ];
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub inventory
|
||||
{
|
||||
my ($dbh, $remote, $args, $out) = @_;
|
||||
|
||||
my $cmd = $args->[1];
|
||||
my $item = $args->[2];
|
||||
my $val = $args->[3];
|
||||
|
||||
unless ($remote->{'priv'}->{'moneyenter'} || $remote->{'priv'}->{'shipping'}) {
|
||||
push @$out, [ "error", "$remote->{'user'}, you are not authorized to use this command." ];
|
||||
return 0;
|
||||
}
|
||||
|
||||
unless ($cmd =~ /show|add|remove|price/) {
|
||||
push @$out, [ "error", "Invalid inventory command." ];
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($cmd eq "show") {
|
||||
my $sth = $dbh->prepare("SELECT item, subitem, qty, avail, price FROM inventory ".
|
||||
"ORDER BY item, subitem");
|
||||
$sth->execute;
|
||||
push @$out, [ '', "qty avl price item" ];
|
||||
push @$out, [ '', "==== ==== ====== =============================" ];
|
||||
while ($_ = $sth->fetchrow_hashref) {
|
||||
push @$out, [ '', sprintf("%4d %4d \$%5.02f %s-%s",
|
||||
$_->{'qty'}, $_->{'avail'}, $_->{'price'},
|
||||
$_->{'item'}, $_->{'subitem'}) ];
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
my $subitem;
|
||||
unless ($item =~ /^(\w+?)-(.+)$/) {
|
||||
push @$out, [ "error", "Invalid item format." ];
|
||||
return 0;
|
||||
}
|
||||
($item, $subitem) = ($1, $2);
|
||||
|
||||
if ($cmd eq "add" || $cmd eq "remove") {
|
||||
my $dir = $cmd eq "add" ? "+" : "-";
|
||||
my $ro = $dbh->do("UPDATE inventory SET qty=qty $dir ?, avail=avail $dir ? ".
|
||||
"WHERE item=? AND subitem=?",
|
||||
undef, $val, $val, $item, $subitem);
|
||||
if ($ro > 0) {
|
||||
push @$out, [ "", "$item-$subitem changed." ];
|
||||
return 1;
|
||||
}
|
||||
push @$out, [ "error", "No change made." ];
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($cmd eq "price") {
|
||||
my $price = $val;
|
||||
$price =~ s/\$//;
|
||||
unless ($price =~ /^(\d+)(\.\d\d)?$/ && $1) {
|
||||
push @$out, [ "error", "Invalid price." ];
|
||||
return 0
|
||||
}
|
||||
my $ro = $dbh->do("UPDATE inventory SET price=? ".
|
||||
"WHERE item=? AND subitem=?",
|
||||
undef, $price, $item, $subitem);
|
||||
if ($ro > 0) {
|
||||
push @$out, [ "", "$item-$subitem price changed." ];
|
||||
return 1;
|
||||
}
|
||||
push @$out, [ "error", "No change made." ];
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
$cmd{'allow_pay'} =
|
||||
{
|
||||
des => "Permit or deny a user's ability to pay.",
|
||||
privs => [qw(moneyenter)],
|
||||
argsummary => '<action> <usernames>',
|
||||
args => [
|
||||
action => "'permit', or 'deny'",
|
||||
username => "Username to allow to pay (with permit) or block payments (with deny)",
|
||||
],
|
||||
handler => sub {
|
||||
my ($dbh, $remote, $args, $out) = @_;
|
||||
|
||||
return $fail->($out, "Not logged in.") unless $remote;
|
||||
return $fail->($out, "You don't have privileges needed to run this command.")
|
||||
unless $remote->{'priv'}->{'moneyenter'};
|
||||
|
||||
# check syntax and parse out some information
|
||||
my $myname = shift @$args;
|
||||
my $action = shift @$args or return $usage->($out, $myname);
|
||||
my $user = shift @$args or return $usage->($out, $myname);
|
||||
|
||||
my $act = $action eq 'permit' ? 'Y' : 'N';
|
||||
|
||||
return $usage->($out, $myname) unless $args;
|
||||
return $usage->($out, $myname) unless $action =~ /^(permit|deny)$/;
|
||||
return $usage->($out, $myname) unless $user;
|
||||
|
||||
# make changes and revoke
|
||||
my $userid = LJ::get_userid($dbh, $user);
|
||||
return $fail->($out, "Skipping invalid username: '$_'") unless $userid;
|
||||
|
||||
LJ::set_userprop($userid, 'allow_pay', $act)
|
||||
or return $fail->($out, "Error setting 'allow_pay' userprop. Database Unavailable?");
|
||||
|
||||
# log to statushistory
|
||||
LJ::statushistory_add($userid, $remote->{userid}, "allow_pay", ucfirst($action) . "ing payments");
|
||||
|
||||
$success->($out, ucfirst($action) . "ing payment for user $user");
|
||||
return 1;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
$cmd{'got_assignment'} =
|
||||
{
|
||||
des => "Mark a user as sending in the assignment agreement paperwork for the bazaar.",
|
||||
privs => [qw(moneyenter)],
|
||||
argsummary => '<user>',
|
||||
args => [
|
||||
user => "Username who sent in the assignment agreement.",
|
||||
],
|
||||
handler => sub {
|
||||
my ($dbh, $remote, $args, $out) = @_;
|
||||
|
||||
return $fail->($out, "Not logged in.") unless $remote;
|
||||
return $fail->($out, "You don't have privileges needed to run this command.")
|
||||
unless $remote->{'priv'}->{'moneyenter'};
|
||||
|
||||
# check syntax and parse out some information
|
||||
my $myname = shift @$args;
|
||||
my $user = shift @$args or return $usage->($out, $myname);
|
||||
|
||||
my $u = LJ::load_user($user, "force");
|
||||
return $fail->($out, "User not found") unless $u;
|
||||
|
||||
LJ::set_userprop($u, "legal_assignagree", 1)
|
||||
or return $fail->($out, "Error setting userprop. Database unavailable?");
|
||||
|
||||
$success->($out, "Assignment agreement flag set for $u->{'user'}");
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
$cmd{'bazaar_pay'} =
|
||||
{
|
||||
des => "Subtract money from a user's bazaar balance.",
|
||||
privs => [qw(moneyenter)],
|
||||
argsummary => '<user> <amt>',
|
||||
args => [
|
||||
user => "Username to subtract balance from.",
|
||||
amt => "Amount to subtract.",
|
||||
],
|
||||
handler => sub {
|
||||
my ($dbh, $remote, $args, $out) = @_;
|
||||
|
||||
return $fail->($out, "Not logged in.") unless $remote;
|
||||
return $fail->($out, "You don't have privileges needed to run this command.")
|
||||
unless $remote->{'priv'}->{'moneyenter'};
|
||||
|
||||
# check syntax and parse out some information
|
||||
my $myname = shift @$args;
|
||||
my $user = shift @$args;
|
||||
my $amt = shift @$args;
|
||||
unless ($user ne "" && $amt =~ /^\d+(\.\d\d)?$/) {
|
||||
return $usage->($out, $myname);
|
||||
}
|
||||
|
||||
my $u = LJ::load_user($user, "force");
|
||||
return $fail->($out, "User not found") unless $u;
|
||||
|
||||
LJ::load_user_props($u, "legal_assignagree");
|
||||
unless ($u->{'legal_assignagree'}) {
|
||||
return $fail->($out, "Error: no assignment agreement from $u->{'user'}. Use the 'got_assignment' command if you have it.");
|
||||
}
|
||||
|
||||
if (LJ::Pay::bazaar_remove_balance($u, $amt)) {
|
||||
LJ::statushistory_add($u->{'userid'}, $remote->{'userid'}, "bzrbaldecr", "Removing \$$amt");
|
||||
return $success->($out, "Success.");
|
||||
}
|
||||
|
||||
return $fail->($out, "Error: balance wasn't large enough?");
|
||||
}
|
||||
};
|
||||
|
||||
$cmd{'bazaar_status'} =
|
||||
{
|
||||
des => "Show who's owed how much for the bazaar.",
|
||||
privs => [qw(moneyenter)],
|
||||
argsummary => '',
|
||||
args => [ ],
|
||||
handler => sub {
|
||||
my ($dbh, $remote, $args, $out) = @_;
|
||||
|
||||
return $fail->($out, "Not logged in.") unless $remote;
|
||||
return $fail->($out, "You don't have privileges needed to run this command.")
|
||||
unless $remote->{'priv'}->{'moneyenter'};
|
||||
|
||||
LJ::Pay::bazaar_do_expirations();
|
||||
|
||||
my $sth = $dbh->prepare("SELECT u.user, SUM(b.owed) FROM user u, bzrbalance b ".
|
||||
"WHERE u.userid=b.userid AND b.owed > 0 GROUP BY 1");
|
||||
$sth->execute;
|
||||
while (my ($user, $sum) = $sth->fetchrow_array) {
|
||||
push @$out, [ "", sprintf("%-20s = \$%7.02f", $user, $sum) ];
|
||||
}
|
||||
|
||||
return $success->($out, "[end]");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$cmd{'rename_redir'} =
|
||||
{
|
||||
des => "Change redirection option of a previously done redirect",
|
||||
privs => [qw(moneyenter)],
|
||||
argsummary => '<action> <from_username> <to_username>',
|
||||
args => [
|
||||
action => "'add' to do redirections, or 'remove' if redirections should not be done",
|
||||
from_username => "Source journal which was renamed",
|
||||
to_username => "Destination journal to which from_username was renamed"
|
||||
],
|
||||
handler => sub {
|
||||
my ($dbh, $remote, $args, $out) = @_;
|
||||
|
||||
return $fail->($out, "Not logged in.") unless $remote;
|
||||
return $fail->($out, "You don't have privileges needed to run this command.")
|
||||
unless $remote->{'priv'}->{'moneyenter'};
|
||||
|
||||
shift @$args; # remove command name
|
||||
my ($action, $from_username, $to_username) = @$args;
|
||||
|
||||
return $fail->($out, "Invalid action: '$action'")
|
||||
unless $action eq 'add' || $action eq 'remove';
|
||||
|
||||
my $from_user = LJ::load_user($from_username);
|
||||
return $fail->($out, "Invalid from_username")
|
||||
unless $from_user;
|
||||
$from_username = $from_user->{'user'};
|
||||
|
||||
my $to_user = LJ::load_user($to_username);
|
||||
return $fail->($out, "Invalid to_username")
|
||||
unless $to_user;
|
||||
$to_username = $to_user->{'user'};
|
||||
|
||||
return $fail->($out, "'$from_username' has already been marked as expunged'")
|
||||
if $from_user->{'statusvis'} eq 'X';
|
||||
|
||||
return $fail->($out, "'$from_username' was never renamed to '$to_username'")
|
||||
unless $dbh->selectrow_array("SELECT COUNT(*) FROM renames " .
|
||||
"WHERE fromuser=? AND touser=?",
|
||||
undef, $from_username, $to_username);
|
||||
|
||||
LJ::load_user_props($from_user, 'renamedto');
|
||||
|
||||
# create a redirection link
|
||||
if ($action eq 'add') {
|
||||
return $fail->($out, "'$from_username' already redirects to '$to_username'")
|
||||
if $from_user->{'renamedto'} eq $to_username && $from_user->{'statusvis'} eq 'R';
|
||||
|
||||
return $fail->($out, "'$from_username' redirects to another journal?")
|
||||
if $from_user->{'statusvis'} eq 'R' && $from_user->{'renamedto'} &&
|
||||
$from_user->{'renamedto'} ne $to_username;
|
||||
|
||||
# set renamedto prop
|
||||
LJ::set_userprop($from_user, "renamedto", $to_username)
|
||||
or return $fail->($out, "Error setting userprop. Database unavailable?");
|
||||
|
||||
# update user, undelete (checked to see if already expunged earlier)
|
||||
LJ::update_user($from_user,
|
||||
{ raw => "journaltype='R', statusvis='R', statusvisdate=NOW()" });
|
||||
|
||||
# update email aliases if applicable
|
||||
if (LJ::get_cap($from_user, "useremail")) {
|
||||
$dbh->do("INSERT INTO email_aliases VALUES (?,?)", undef,
|
||||
"$to_username\@$LJ::USER_DOMAIN", $to_user->{'email'});
|
||||
}
|
||||
|
||||
return $success->($out, "Redirection added for $from_username => $to_username rename action");
|
||||
}
|
||||
|
||||
# remove a redirection link
|
||||
if ($action eq 'remove') {
|
||||
|
||||
return $fail->($out, "'$from_username' does not redirect to '$to_username'")
|
||||
unless $from_user->{'renamedto'} eq $to_username &&
|
||||
$from_user->{'statusvis'} eq 'R';
|
||||
|
||||
# delete renamedto prop
|
||||
LJ::set_userprop($from_user, "renamedto", undef)
|
||||
or return $fail->($out, "Error setting userprop. Database unavailable?");
|
||||
|
||||
# update user, set deleted
|
||||
LJ::update_user($from_user,
|
||||
{ raw => "journaltype='R', statusvis='D', statusvisdate=NOW()" });
|
||||
|
||||
# update email aliases if applicable
|
||||
$dbh->do("DELETE FROM email_aliases WHERE rcpt=?",
|
||||
undef, "$from_username\@$LJ::USER_DOMAIN");
|
||||
|
||||
return $success->($out, "Redirection removed for $from_username => $to_username rename action");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$cmd{'rename_show'} =
|
||||
{
|
||||
des => "View information about a rename.",
|
||||
privs => [qw(moneyenter)],
|
||||
argsummary => '<value>',
|
||||
args => [
|
||||
'value' => "A hex or decimal tokenid, a full token string, or the username of a user who was renamed (source user)."
|
||||
],
|
||||
handler => sub {
|
||||
my ($dbh, $remote, $args, $out) = @_;
|
||||
|
||||
return $fail->($out, "Not logged in.") unless $remote;
|
||||
return $fail->($out, "You don't have privileges needed to run this command.")
|
||||
unless $remote->{'priv'}->{'moneyenter'};
|
||||
|
||||
shift @$args; # remove command name
|
||||
my $value = shift @$args;
|
||||
|
||||
return $fail->($out, "You must enter a value")
|
||||
unless $value;
|
||||
|
||||
my @ren;
|
||||
my $hashref_array = sub {
|
||||
return values %{
|
||||
$dbh->selectall_hashref(shift(), 'renid', undef, @_) || {}
|
||||
}
|
||||
};
|
||||
|
||||
# they probably have this form of the token
|
||||
if ($value =~ /^([0-9a-f]{6})(\w{10})$/) {
|
||||
push @ren, $hashref_array->("SELECT * FROM renames WHERE renid=? AND token=?", hex $1, $2);
|
||||
|
||||
# or maybe they have the tokenid?
|
||||
} elsif ($value =~ /^([0-9a-f]{1,6})/) {
|
||||
|
||||
# try decimal, hex tokenids (user could enter either)
|
||||
push @ren, $hashref_array->("SELECT * FROM renames WHERE renid=? OR renid=?", $1, hex $1);
|
||||
|
||||
# perhaps they have the token itself?
|
||||
} elsif ($value =~ /^(\w{10})$/) {
|
||||
|
||||
push @ren, $hashref_array->("SELECT * FROM renames WHERE token=?", $1);
|
||||
|
||||
# explicitly disallow special tokens ([movedaway], [manual], etc)
|
||||
# Note: "----------" is also a special token, but it's a valid username
|
||||
# so we allow searching for it,
|
||||
} elsif ($value =~ /^\[\w+\]$/) {
|
||||
return $fail->($out, "Cannot search for special tokens");
|
||||
}
|
||||
|
||||
# if no ren, then maybe they gave a username
|
||||
push @ren, $hashref_array->("SELECT * FROM renames WHERE fromuser=?",
|
||||
LJ::canonical_username($value))
|
||||
unless @ren;
|
||||
|
||||
return $fail->($out, "Could not find a matching rename.")
|
||||
unless @ren;
|
||||
|
||||
foreach my $ren (@ren) {
|
||||
push @$out, map { [ '', "$_: $ren->{$_}" ] } sort keys %$ren;
|
||||
push @$out, [ '', '' ];
|
||||
}
|
||||
|
||||
return $success->($out, "[end]");
|
||||
}
|
||||
};
|
||||
|
||||
$cmd{'rename_reset'} =
|
||||
{
|
||||
des => "Lets account admins modify friends properties if selected incorrectly during a rename.",
|
||||
privs => [qw(moneyenter)],
|
||||
argsummary => '<mode> <user>',
|
||||
args => [
|
||||
'mode' => "'friends' to reset friends, 'friendofs' to reset friends-ofs.",
|
||||
'user' => "The username whose friends list should be cleared."
|
||||
],
|
||||
handler => sub {
|
||||
my ($dbh, $remote, $args, $out) = @_;
|
||||
|
||||
return $fail->($out, "Not logged in.") unless $remote;
|
||||
return $fail->($out, "You don't have privileges needed to run this command.")
|
||||
unless $remote->{'priv'}->{'moneyenter'};
|
||||
|
||||
shift @$args; # remove command name
|
||||
my $mode = shift @$args;
|
||||
my $user = shift @$args;
|
||||
|
||||
return $fail->($out, "Invalid mode, valid modes are 'friends' and 'friendofs'")
|
||||
unless $mode eq 'friends' || $mode eq 'friendofs';
|
||||
|
||||
return $fail->($out, "You must enter a username")
|
||||
unless $user;
|
||||
|
||||
my $u = LJ::load_user($user);
|
||||
return $fail->($out, "Invalid username")
|
||||
unless $u;
|
||||
|
||||
if ($mode eq 'friends') {
|
||||
# TAG:FR:console:rename_reset:clear_friends
|
||||
# clear the given user's friends
|
||||
|
||||
# delete existing friends
|
||||
my $friends = LJ::get_friends($cid, undef, undef, 'force') || {};
|
||||
if (LJ::remove_friend($cid, [ keys %$friends ])) {
|
||||
return $success->($out, "Success, friends modified.");
|
||||
}
|
||||
|
||||
# some failure?
|
||||
return $fail->($out, "Error modifying friends for user: '$user'");
|
||||
}
|
||||
|
||||
if ($mode eq 'friendofs') {
|
||||
# TAG:FR:console:rename_reset:clear_friendofs
|
||||
# who lists this user as a friend?
|
||||
my $ids = $dbh->selectcol_arrayref("SELECT userid FROM friends WHERE friendid=?",
|
||||
undef, $u->{'userid'}) || [];
|
||||
|
||||
# delete friend edges with this user as the target
|
||||
if ($dbh->do("DELETE FROM friends WHERE friendid=?", undef, $u->{'userid'})) {
|
||||
|
||||
# clear memcache for all friend-ofs
|
||||
LJ::memcache_kill($_, "friends") foreach @$ids;
|
||||
|
||||
return $success->($out, "Success, friend-ofs modified.");
|
||||
}
|
||||
|
||||
# some failure?
|
||||
return $fail->($out, "Error modifying friend-ofs for user: '$user'");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$cmd{'fraud_watch'} =
|
||||
{
|
||||
des => "Set or unset the fraud_watch userprop for a given user",
|
||||
privs => [qw(moneyenter)],
|
||||
argsummary => '<action> <username>',
|
||||
args => [
|
||||
username => "Username who should have faud_watch set/unset",
|
||||
action => "Optional. Either 'add' or 'remove' to set/unset the watch respectively. Defaults to 'add'.",
|
||||
],
|
||||
handler => sub {
|
||||
my ($dbh, $remote, $args, $out) = @_;
|
||||
|
||||
return $fail->($out, "Not logged in.") unless $remote;
|
||||
return $fail->($out, "You don't have privileges needed to run this command.")
|
||||
unless $remote->{'priv'}->{'moneyenter'};
|
||||
|
||||
shift @$args; # remove command name
|
||||
my ($action, $user) = @$args;
|
||||
|
||||
return $fail->($out, "Invalid action: '$action'")
|
||||
unless $action eq 'add' || $action eq 'remove';
|
||||
|
||||
my $u = LJ::load_user($user);
|
||||
return $fail->($out, "Invalid username: $user")
|
||||
unless $u;
|
||||
|
||||
my $propval = $action eq 'add' ? 1 : 0;
|
||||
my $verb = $propval ? 'added' : 'removed';
|
||||
|
||||
LJ::load_user_props($u, 'fraud_watch');
|
||||
|
||||
return $fail->($out, "Fraud watch already $verb, nothing to do. [$u->{fraud_watch}]")
|
||||
if $u->{fraud_watch} == $propval;
|
||||
|
||||
# set userprop
|
||||
LJ::set_userprop($u, "fraud_watch", $propval)
|
||||
or return $fail->($out, "Error setting 'fraud_watch' userprop. Database unavailable?");
|
||||
|
||||
# log to statushistory
|
||||
LJ::statushistory_add($u->{userid}, $remote->{userid}, 'fraud_watch', "fraud watch $verb");
|
||||
|
||||
return $success->($out, "Fraud watch $verb for $u->{user}");
|
||||
}
|
||||
};
|
||||
|
||||
$cmd{'coupon_revoke'} =
|
||||
{
|
||||
des => "Revoke an unused coupon that was given out by the system (for a promo, etc)",
|
||||
privs => [qw(moneyenter)],
|
||||
argsummary => '<username> <coupon_token>',
|
||||
args => [
|
||||
username => "Username that owns the coupon to be revoked.",
|
||||
coupon => "Coupon token. A full coupon token string to be revoked.",
|
||||
],
|
||||
handler => sub {
|
||||
my ($dbh, $remote, $args, $out) = @_;
|
||||
|
||||
return $fail->($out, "Not logged in.") unless $remote;
|
||||
return $fail->($out, "You don't have privileges needed to run this command.")
|
||||
unless $remote->{'priv'}->{'moneyenter'};
|
||||
|
||||
shift @$args; # remove command name
|
||||
my ($user, $coupon) = @$args;
|
||||
|
||||
my $u = LJ::load_user($user);
|
||||
return $fail->($out, "Invalid username: $user")
|
||||
unless $u;
|
||||
|
||||
return $fail->($out, "Invalid coupon format")
|
||||
unless $coupon =~ /^(\d+)-(.+)$/;
|
||||
my ($cpid, $auth) = ($1, $2);
|
||||
my $cp = $dbh->selectrow_hashref
|
||||
("SELECT * FROM coupon WHERE cpid=? AND auth=?",
|
||||
undef, $cpid, $auth);
|
||||
return $fail->($out, "Invalid coupon, already revoked?") unless $cp;
|
||||
return $fail->($out, "Coupon owner does not match '$user'")
|
||||
unless $cp->{rcptid} == $u->{userid};
|
||||
return $fail->($out, "This command can only revoke coupons generated automatically " .
|
||||
"by the system.")
|
||||
unless $cp->{ppayid} == 0;
|
||||
return $fail->($out, "This coupon has already been used in a cart.")
|
||||
unless $cp->{payid} == 0;
|
||||
|
||||
$dbh->do("DELETE FROM coupon WHERE cpid=? AND auth=? AND rcptid=?",
|
||||
undef, $cpid, $auth, $u->{userid});
|
||||
return $fail->($out, "Database Error: " . $dbh->errstr) if $dbh->err;
|
||||
|
||||
# log to statushistory
|
||||
LJ::statushistory_add
|
||||
($u->{userid}, $remote->{userid}, 'coupon_revoke', "Coupon revoked: $coupon");
|
||||
|
||||
return $success->($out, "Coupon revoked: $coupon ($u->{user})");
|
||||
}
|
||||
};
|
||||
|
||||
1;
|
||||
10
ljcom/cgi-bin/cracklib/README.txt
Normal file
10
ljcom/cgi-bin/cracklib/README.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
need to install on clients:
|
||||
|
||||
apt-get install libcrypt-cracklib-perl
|
||||
|
||||
to make the dictionary indexes, need to do:
|
||||
|
||||
# apt-get install cracklib-runtime wenglish
|
||||
|
||||
$ /usr/sbin/crack_mkdict /usr/share/dict/words | /usr/sbin/crack_packer $LJHOME/cgi-bin/cracklib/dict
|
||||
|
||||
48
ljcom/cgi-bin/crumbs-local.pl
Normal file
48
ljcom/cgi-bin/crumbs-local.pl
Normal file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# Stores all local crumbs and adds to the crumbs hash
|
||||
|
||||
|
||||
%LJ::CRUMBS_LOCAL = (
|
||||
'about' => ['About LiveJournal', '/site/about.bml', 'home'],
|
||||
'abusereport' => ['Report Abuse', '/abuse/report.bml', 'support'],
|
||||
'acctfeatures' => ['Features By Account Type', '/site/accounts.bml', 'about'],
|
||||
'advsearch' => ['Advanced', '/directorysearch.bml', 'search'],
|
||||
'banners' => ['Advertising Banners', '/banners.bml', 'home'],
|
||||
'code' => ['LiveJournal Code', '/code/index.bml', 'about'],
|
||||
'contributors' => ['Contributors', '/site/contributors.bml', 'press'],
|
||||
'coppa' => ['COPPA', '/legal/coppa.bml', 'legal'],
|
||||
'dmca' => ['DMCA Information', '/legal/dmca.bml', 'legal'],
|
||||
'download' => ['Download a Client', '/download/index.bml', 'about'],
|
||||
'filemanager' => ['File Manager', '/manage/files.bml', 'manage'],
|
||||
'goat' => ['About Frank', '/site/goat.bml', 'home'],
|
||||
'guidingprinciples' => ['Our Guiding Principles', '/legal/principles.bml', 'about'],
|
||||
'itsfree' => ['It\'s Free?', '/site/free.bml', 'paidaccounts'],
|
||||
'legal' => ['Legal Information', '/legal/index.bml', 'home'],
|
||||
'ljhome' => ['Home', 'http://www.livejournal.com/', ''],
|
||||
'paidaccounts' => ['Paid Accounts', '/paidaccounts/index.bml', 'about'],
|
||||
'paidacctstatus' => ['Paid Account Status', '/paidaccounts/status.bml', 'paidaccounts'],
|
||||
'press' => ['LiveJournal Press Area', '/press/index.bml', 'about'],
|
||||
'pressarticles' => ['LiveJournal in the Press', '/press/articles.bml', 'press'],
|
||||
'privacy' => ['Privacy Policy', '/legal/privacy.bml', 'legal'],
|
||||
'search' => ['Search', '/site/search.bml', 'home'],
|
||||
'searchinterests' => ['By Interest', '/interests.bml', 'search'],
|
||||
'searchregion' => ['By Region', '/directory.bml', 'search'],
|
||||
'securechangepass' => ['Change Password', '/changepassword.bml', 'securemanage'],
|
||||
'securecreatejournal' => ['Create Journal', '/create.bml', 'ljhome'],
|
||||
'securelogin' => ['Login', '/login.bml', 'ljhome'],
|
||||
'securemanage' => ['Manage Accounts', 'http://www.livejournal.com/manage/', 'ljhome'],
|
||||
'singles' => ['LiveJournal Singles', '/singles/', 'home'],
|
||||
'singlesopts' => ['Modify Availability', '/singles/mod.bml', 'singles'],
|
||||
'singlessearch' => ['Search for Singles', '/singles/search.bml', 'singles'],
|
||||
'sitemap' => ['Site Map', '/site/index.bml', 'home'],
|
||||
'sizechart' => ['Sizing Chart', '/store/sizechart.bml', 'store'],
|
||||
'staff' => ['Senior Staff', '/press/staff.bml', 'press'],
|
||||
'stats' => ['Statistics', '/stats.bml', 'press'],
|
||||
'store' => ['LiveJournal Store', '/store/', 'home'],
|
||||
'storeitem' => ['View Item Detail', '', 'store'],
|
||||
'suggestions' => ['Suggestions Generator', '/suggestions/generator.bml', 'suggview'],
|
||||
'suggview' => ['Suggestions', '/suggestions/index.bml', 'home'],
|
||||
'tos' => ['Terms of Service', '/legal/tos.bml', 'legal'],
|
||||
);
|
||||
1;
|
||||
1604
ljcom/cgi-bin/ljcom.pl
Normal file
1604
ljcom/cgi-bin/ljcom.pl
Normal file
File diff suppressed because it is too large
Load Diff
6
ljcom/cgi-bin/ljlib-local.pl
Normal file
6
ljcom/cgi-bin/ljlib-local.pl
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
|
||||
require "$ENV{'LJHOME'}/cgi-bin/ljcom.pl";
|
||||
|
||||
1;
|
||||
41
ljcom/cgi-bin/modperl-ssl.pl
Normal file
41
ljcom/cgi-bin/modperl-ssl.pl
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
|
||||
use strict;
|
||||
use lib "$ENV{'LJHOME'}/cgi-bin";
|
||||
use Apache;
|
||||
use Apache::LiveJournal;
|
||||
|
||||
Apache->httpd_conf("DocumentRoot $LJ::HOME/ssldocs");
|
||||
Apache->httpd_conf("ServerAdmin $LJ::ADMIN_EMAIL")
|
||||
if $LJ::ADMIN_EMAIL;
|
||||
|
||||
Apache->httpd_conf(qq{
|
||||
|
||||
<IfModule mod_userdir.c>
|
||||
UserDir disabled
|
||||
</IfModule>
|
||||
|
||||
PerlInitHandler +Apache::LiveJournal
|
||||
PerlFixupHandler +Apache::CompressClientFixup
|
||||
DirectoryIndex index.html index.bml
|
||||
});
|
||||
|
||||
unless ($LJ::SERVER_TOTALLY_DOWN)
|
||||
{
|
||||
Apache->httpd_conf(qq{
|
||||
# BML support:
|
||||
PerlModule Apache::BML
|
||||
<Files ~ "\\.bml\$">
|
||||
SetHandler perl-script
|
||||
PerlHandler Apache::BML
|
||||
</Files>
|
||||
|
||||
# User-friendly error messages
|
||||
ErrorDocument 404 /404-error.html
|
||||
ErrorDocument 500 /500-error.html
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
1;
|
||||
23
ljcom/cgi-bin/modperl_subs-local.pl
Normal file
23
ljcom/cgi-bin/modperl_subs-local.pl
Normal file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
|
||||
# site-local version of modperl_subs.pl
|
||||
|
||||
package LJ::ModPerl;
|
||||
|
||||
use strict;
|
||||
|
||||
# pull in a lot of useful stuff before we fork children
|
||||
|
||||
use lib "$ENV{'LJHOME'}/cgi-bin";
|
||||
use XMLRPC::Lite; # for cmdbuf:pay_fb_xmlrpc hook
|
||||
|
||||
require "phonepost.pl";
|
||||
require "paylib.pl";
|
||||
|
||||
$LJ::OPTMOD_CRACKLIB = eval "use Crypt::Cracklib qw(); 1;";
|
||||
$Crypt::Cracklib::DICT = "$ENV{'LJHOME'}/cgi-bin/cracklib/dict";
|
||||
|
||||
$LJ::OPTMOD_GEOIP = eval "use Geo::IP::PurePerl (); 1;";
|
||||
|
||||
1;
|
||||
2946
ljcom/cgi-bin/paylib.pl
Normal file
2946
ljcom/cgi-bin/paylib.pl
Normal file
File diff suppressed because it is too large
Load Diff
321
ljcom/cgi-bin/phonepost.pl
Normal file
321
ljcom/cgi-bin/phonepost.pl
Normal file
@@ -0,0 +1,321 @@
|
||||
#!/usr/bin/perl
|
||||
# vim: set ts=4 sw=4 et :
|
||||
|
||||
# some variable names:
|
||||
# - phonepostid, bid, blobid: all refer to a blob id.
|
||||
# - dppid: display phonepost id; comparable to a ditemid, but for a phone post.
|
||||
|
||||
use strict;
|
||||
|
||||
use lib "$ENV{'LJHOME'}/cgi-bin";
|
||||
use LJ::Blob;
|
||||
|
||||
package LJ::PhonePost;
|
||||
|
||||
my $datatypes = {
|
||||
0 => { ext => 'mp3', mime => 'audio/mp3' },
|
||||
1 => { ext => 'ogg', mime => 'application/ogg' },
|
||||
2 => { ext => 'wav', mime => 'audio/wav' },
|
||||
};
|
||||
|
||||
sub may_transcribe {
|
||||
my ($u, $remote) = @_;
|
||||
return 0 if $remote && $remote->{journaltype} ne 'P';
|
||||
return 1 if $remote && $remote->{userid} == $u->{userid};
|
||||
LJ::load_user_props($u, 'pp_transallow');
|
||||
return 0 if $u->{pp_transallow} == -1;
|
||||
my $groupmask = LJ::get_groupmask($u, $remote);
|
||||
return 1 if ! $u->{pp_transallow} && $groupmask;
|
||||
return ($groupmask & (1 << $u->{pp_transallow})) ? 1 : 0;
|
||||
}
|
||||
|
||||
sub get_phonepost_entry {
|
||||
my ($u, $bid) = @_;
|
||||
my ($ppe, $memkey);
|
||||
|
||||
$memkey = [$u->{userid}, "ppe:$u->{userid}:$bid"];
|
||||
$ppe = LJ::MemCache::get($memkey);
|
||||
|
||||
return $ppe if $ppe;
|
||||
|
||||
my $dbcr = LJ::get_cluster_def_reader($u);
|
||||
$ppe = $dbcr->selectrow_hashref(qq{
|
||||
SELECT ppe.jitemid, ppe.posttime, ppe.anum,
|
||||
ppe.filetype, ub.length, ppe.lengthsecs, ppe.location
|
||||
FROM phonepostentry ppe, userblob ub
|
||||
WHERE ub.journalid=? AND ppe.userid=ub.journalid
|
||||
AND ub.domain=? AND ub.blobid=? AND ppe.blobid=ub.blobid
|
||||
}, undef, $u->{'userid'}, LJ::get_blob_domainid("phonepost"), $bid);
|
||||
LJ::MemCache::set($memkey, $ppe || 0);
|
||||
return $ppe;
|
||||
}
|
||||
|
||||
sub apache_content {
|
||||
my ($r, $u, $dppid) = @_;
|
||||
my $bid = $dppid >> 8;
|
||||
my $ppe = get_phonepost_entry($u, $bid);
|
||||
return 404 unless $ppe && $ppe->{jitemid} && $ppe->{anum} == $dppid % 256;
|
||||
|
||||
# check security of item
|
||||
my $logrow = LJ::get_log2_row($u, $ppe->{jitemid});
|
||||
return 404 unless $logrow;
|
||||
|
||||
if ($u->{statusvis} eq 'S' || $logrow->{security} ne "public") {
|
||||
# get the remote, ignoring IP, since the request is coming
|
||||
# from Akamai/Speedera/etc and the IP won't match
|
||||
my $remote = LJ::get_remote({ ignore_ip => 1 });
|
||||
|
||||
my %GET = $r->args;
|
||||
|
||||
my $viewall = 0;
|
||||
my $viewsome = 0;
|
||||
if ($remote && $GET{viewall} && LJ::check_priv($remote, "canview")) {
|
||||
LJ::statushistory_add($u->{'userid'}, $remote->{'userid'},
|
||||
"viewall", "phonepost: $u->{user}, itemid: $ppe->{jitemid}, statusvis: $u->{'statusvis'}");
|
||||
|
||||
$viewall = LJ::check_priv($remote, 'canview', '*');
|
||||
$viewsome = $viewall || LJ::check_priv($remote, 'canview', 'suspended');
|
||||
}
|
||||
|
||||
unless ($viewall || $viewsome && $logrow->{security} eq 'public') {
|
||||
return 403 unless LJ::can_view($remote, $logrow);
|
||||
}
|
||||
}
|
||||
|
||||
# future: if length is NULL, then it's an external reference and we redirect
|
||||
$r->header_out("Cache-Control", "must-revalidate, private");
|
||||
$r->header_out("Content-Length", $ppe->{length});
|
||||
$r->content_type( $datatypes->{ $ppe->{filetype} }->{mime} );
|
||||
|
||||
# handle IMS requests
|
||||
my $last_mod = LJ::time_to_http($ppe->{posttime});
|
||||
if (my $ims = $r->header_in("If-Modified-Since")) {
|
||||
return 304 if $ims eq $last_mod;
|
||||
}
|
||||
|
||||
$r->header_out("Last-Modified", $last_mod);
|
||||
if ($r->header_only) {
|
||||
$r->send_http_header();
|
||||
return 200;
|
||||
}
|
||||
|
||||
my $buffer;
|
||||
if ($ppe->{location} eq 'mogile') {
|
||||
# Mogile
|
||||
if ( !$LJ::REPROXY_DISABLE{phoneposts} &&
|
||||
$r->header_in('X-Proxy-Capabilities') &&
|
||||
$r->header_in('X-Proxy-Capabilities') =~ /\breproxy-file\b/i )
|
||||
{
|
||||
my @paths = LJ::mogclient()->get_paths( "pp:$u->{userid}:$bid", 1 );
|
||||
|
||||
# reproxy url
|
||||
if ($paths[0] =~ m/^http:/) {
|
||||
$r->header_out('X-REPROXY-URL', join(' ', @paths));
|
||||
}
|
||||
# reproxy file
|
||||
else {
|
||||
$r->header_out('X-REPROXY-FILE', $paths[0]);
|
||||
}
|
||||
$r->send_http_header();
|
||||
}
|
||||
else {
|
||||
$buffer = LJ::mogclient()->get_file_data("pp:$u->{userid}:$bid");
|
||||
$r->send_http_header();
|
||||
return 500 unless $buffer && ref $buffer;
|
||||
$r->print($$buffer);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
# BlobServer
|
||||
$r->send_http_header();
|
||||
my $ret = LJ::Blob::get_stream($u, 'phonepost',
|
||||
$datatypes->{ $ppe->{filetype} }->{ext}, $bid, sub {
|
||||
$buffer .= $_[0];
|
||||
if (length($buffer) > 50_000) {
|
||||
$r->print($buffer);
|
||||
undef $buffer;
|
||||
}
|
||||
});
|
||||
$r->print($buffer) if length($buffer);
|
||||
return 500 unless $ret;
|
||||
}
|
||||
|
||||
return 200;
|
||||
}
|
||||
|
||||
# if $u_embed and $ditemid are given, they represent an entry
|
||||
# in which a phonepost tag has been embedded.
|
||||
|
||||
sub make_link {
|
||||
my ($remote, $uuid, $phonepostid, $mode, $u_embed, $ditemid) = @_;
|
||||
$phonepostid += 0;
|
||||
|
||||
# mode can either be 'notrans', 'bare', or 'rss'
|
||||
$mode = "notrans" if $mode && $mode !~ /bare|rss/;
|
||||
|
||||
my $u = ref $uuid ? $uuid : LJ::load_userid($uuid);
|
||||
return $mode eq 'rss' ? "" : "<b>[Invalid user]</b>" unless $u;
|
||||
my $userid = $u->{'userid'};
|
||||
|
||||
my $ppe = get_phonepost_entry($u, $phonepostid);
|
||||
return $mode eq 'rss' ? "" : "<b>[Invalid audio link]</b>" unless $ppe;
|
||||
|
||||
if ($u_embed && $ditemid) {
|
||||
# have to check whether the link is embeddable in this entry
|
||||
if ($u_embed->{'userid'} == $userid &&
|
||||
$ditemid>>8 == $ppe->{'jitemid'}) {
|
||||
|
||||
# it's the original entry, we're ok
|
||||
} else {
|
||||
my $accdenied = "<b>[Access to audio link denied]</b>";
|
||||
|
||||
# log2 row in which the tag is embedded
|
||||
my $row = LJ::get_log2_row($u_embed, $ditemid >> 8);
|
||||
|
||||
# the original log2 row of this tag
|
||||
my $row_orig = LJ::get_log2_row($u, $ppe->{'jitemid'});
|
||||
return $mode eq 'rss' ? "" : $accdenied unless $row && $row_orig;
|
||||
|
||||
if ($row_orig->{'security'} eq "public" &&
|
||||
$row->{'posterid'} == $userid &&
|
||||
$u_embed->{'userid'} != $userid) {
|
||||
|
||||
# it's public and moved by the same
|
||||
# user to a different journal, we're okay
|
||||
} else {
|
||||
return $mode eq 'rss' ? "" : $accdenied;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my $link;
|
||||
my $dppid = ($phonepostid << 8) + $ppe->{anum};
|
||||
my $ext = $datatypes->{ $ppe->{filetype} }->{ext};
|
||||
my $path = LJ::run_hook("url_phonepost", $u, $dppid, $ext) ||
|
||||
LJ::journal_base($u) . "/data/phonepost/$dppid.$ext";
|
||||
|
||||
# make link and just return that if in bare mode
|
||||
$link = $ppe->{location} eq 'none' ?
|
||||
"<img src='$LJ::IMGPREFIX/phonepost2.gif' alt='' width='35' height='33' />" :
|
||||
"<a href='$path'><img src='$LJ::IMGPREFIX/phonepost2.gif' alt='' " .
|
||||
"width='35' height='33' border='0' /></a>";
|
||||
return $link if $mode eq 'bare';
|
||||
|
||||
my $K = $ppe->{length} ? int($ppe->{length} / 1024) . "K" : "";
|
||||
my $secs = $ppe->{lengthsecs};
|
||||
my $duration = $secs ? sprintf("%d:%02d", int($secs/60), $secs%60) : "";
|
||||
|
||||
# support rss 'enclosures' - podcasting.
|
||||
if ($mode eq 'rss') {
|
||||
$link = "<enclosure url=\"$path\" length=\"$ppe->{length}\" " .
|
||||
"type=\"$datatypes->{ $ppe->{filetype} }->{mime}\" />";
|
||||
return $link;
|
||||
}
|
||||
|
||||
# return full table
|
||||
my $ret = "<table cellspacing='5' cellpadding='0' border='0' class='ljphonepost'><tr>";
|
||||
$ret .= "<td valign='top'>$link</td>";
|
||||
$ret .= "<td valign='top'><strong>";
|
||||
$ret .= $ppe->{location} eq 'none' ? "PhonePost" : "<a href='$path'>PhonePost</a>";
|
||||
$ret .= "</strong><br /><em>$K</em> $duration</td>";
|
||||
|
||||
unless ($mode eq 'notrans') {
|
||||
my $trans_url = "$LJ::SITEROOT/phonepost/transcribe.bml?user=$u->{user}&ppid=$dppid";
|
||||
$ret .= "<td valign='top'><a href='$LJ::SITEROOT/phonepost/about.bml'><img src='$LJ::IMGPREFIX/help.gif' width='14' height='14' border='0' alt='(Help)' /></a></td>";
|
||||
my $trans = LJ::PhonePost::get_latest_trans($u, $phonepostid);
|
||||
if ($trans) {
|
||||
my $by;
|
||||
if ($trans->{revid} == 1) {
|
||||
$by = LJ::ljuser(LJ::get_username($trans->{posterid}));
|
||||
} else {
|
||||
# multiple users transcribing, or just multiple transcriptions of one user?
|
||||
my $memkey = [$u->{userid},"ppetu:$u->{userid}:$phonepostid"];
|
||||
my $tu = LJ::MemCache::get($memkey);
|
||||
unless (defined $tu) {
|
||||
my $dbr = LJ::get_cluster_reader($u);
|
||||
$tu = $dbr->selectrow_array("SELECT COUNT(DISTINCT(posterid)) " .
|
||||
"FROM phoneposttrans " .
|
||||
"WHERE journalid=? AND blobid=?",
|
||||
undef, $u->{'userid'}, $phonepostid + 0);
|
||||
LJ::MemCache::set($memkey, $tu);
|
||||
}
|
||||
$by = ($tu == 1) ? LJ::ljuser(LJ::get_username($trans->{posterid})) : "multiple users";
|
||||
}
|
||||
my $text = LJ::ehtml($trans->{body});
|
||||
$text =~ s/\n/<br \/>/g;
|
||||
|
||||
$ret .= "<td valign='top'><blockquote cite='$path'>“$text”</blockquote><br />".
|
||||
"<a href='$trans_url'>Transcribed</a> by: $by</td>";
|
||||
} elsif (LJ::PhonePost::may_transcribe($u, $remote)) {
|
||||
$ret .= "<td valign='top'>(<a href='$trans_url'>transcribe</a>)</td>";
|
||||
} else {
|
||||
$ret .= "<td valign='top'>(no transcription available)</td>";
|
||||
}
|
||||
}
|
||||
|
||||
$ret .= "</tr></table>";
|
||||
return $ret;
|
||||
|
||||
}
|
||||
|
||||
sub get_latest_trans {
|
||||
my ($u, $id) = @_;
|
||||
$id += 0;
|
||||
|
||||
my $memkey = [$u->{userid},"ppelt:$u->{userid}:$id"];
|
||||
my $lt = LJ::MemCache::get($memkey);
|
||||
unless (defined $lt) {
|
||||
my $dbcr = LJ::get_cluster_def_reader($u);
|
||||
return undef unless $dbcr;
|
||||
|
||||
$lt = "";
|
||||
my $latest = $dbcr->selectrow_array("SELECT MAX(revid) FROM phoneposttrans ".
|
||||
"WHERE journalid=? AND blobid=?", undef,
|
||||
$u->{userid}, $id);
|
||||
if ($latest) {
|
||||
$lt = $dbcr->selectrow_hashref("SELECT revid,posterid,posttime,subject,body ".
|
||||
"FROM phoneposttrans WHERE journalid=? ".
|
||||
"AND blobid=? AND revid=?", undef,
|
||||
$u->{userid}, $id, $latest);
|
||||
}
|
||||
LJ::MemCache::set($memkey, $lt);
|
||||
}
|
||||
return $lt;
|
||||
}
|
||||
|
||||
sub show_phoneposts {
|
||||
my ($u_embed, $ditemid, $remote, $eventref) = @_;
|
||||
|
||||
my $replace = sub {
|
||||
my $tag = shift;
|
||||
my ($user, $userid, $uobj, $phid, $blobid, $dpid);
|
||||
|
||||
# old tag <lj-phonepost user='foo' phonepostid='1' />
|
||||
# new tag <lj-phonepost journalid='1234567' dpid='10000422' />
|
||||
if ($tag =~ m!^journalid=['"](\d+)['"]\s*dpid=['"](\d+)['"]\s*/?$!) {
|
||||
($userid, $dpid)=($1,$2);
|
||||
|
||||
# prefer phonepostid and userid
|
||||
$phid = $dpid >> 8 if $dpid;
|
||||
|
||||
} elsif ($tag =~ m!^(user=['"](\S+)['"])?\s*(phonepostid=['"](\d+)['"])?\s*(userid=['"](\d+)['"])?\s*(blobid=['"](\d+)['"])?\s*/?$!) {
|
||||
($user,$phid,$userid,$blobid)=($2,$4,$6,$8);
|
||||
|
||||
# prefer phonepostid and userid
|
||||
$phid = $blobid >> 8
|
||||
unless $phid or not $blobid;
|
||||
do {
|
||||
$uobj = LJ::load_user($user);
|
||||
$userid = $uobj->{'userid'};
|
||||
} unless $userid or $user eq "";
|
||||
}
|
||||
|
||||
return "<b>[Invalid audio link]</b>" unless $phid and $userid;
|
||||
|
||||
return make_link($remote, $userid, $phid, 0, $u_embed, $ditemid);
|
||||
};
|
||||
$$eventref =~ s!<lj-phonepost\s*([^>]*)>!$replace->($1)!eg;
|
||||
}
|
||||
|
||||
1;
|
||||
125
ljcom/cgi-bin/portal-local.pl
Normal file
125
ljcom/cgi-bin/portal-local.pl
Normal file
@@ -0,0 +1,125 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
|
||||
use strict;
|
||||
|
||||
package LJ::Portal;
|
||||
use vars qw(%box);
|
||||
|
||||
$box{'newtolj'} =
|
||||
{
|
||||
'name' => '<?_ml portal.newtolj.name _ml?>',
|
||||
'small' => 1,
|
||||
'large' => 0,
|
||||
'handler' => sub {
|
||||
my ($remote, $opts, $box) = @_;
|
||||
my $b = $opts->{'body'};
|
||||
|
||||
box_start($b, $box, { 'title' => "About $LJ::SITENAME",
|
||||
'align' => "left",
|
||||
'url' => '/site/about.bml', });
|
||||
|
||||
$$b .= "New to $LJ::SITENAME?";
|
||||
my @links = ("What is $LJ::SITENAME?", "/site/about.bml",
|
||||
"Create an account!", "/create.bml");
|
||||
while (@links) {
|
||||
my $link = shift @links;
|
||||
my $url = shift @links;
|
||||
$$b .= "<li><a href=\"$url\"><b>$link</b></a>\n";
|
||||
}
|
||||
|
||||
box_end($b, $box);
|
||||
$$b .= "</form>\n";
|
||||
},
|
||||
};
|
||||
|
||||
############################################################################
|
||||
|
||||
$box{'goat'} =
|
||||
{
|
||||
'name' => '<?_ml portal.goat.name _ml?>',
|
||||
'small' => 1,
|
||||
'large' => 0,
|
||||
'opts' => [ { 'key' => 'misbehaved',
|
||||
'name' => '<?_ml portal.misbehaved.name _ml?>',
|
||||
'des' => '<?_ml portal.misbehaved.des _ml?>',
|
||||
'type' => 'check',
|
||||
'value' => 1,
|
||||
'default' => 0, },
|
||||
{ 'key' => 'goattext',
|
||||
'name' => '<?_ml portal.goattext.name _ml?>',
|
||||
'des' => '<?_ml portal.goattext.des _ml?>',
|
||||
'type' => 'text',
|
||||
'default' => "Baaaaah",
|
||||
'size' => 40,
|
||||
'maxlength' => 40, },
|
||||
],
|
||||
'handler' => sub {
|
||||
my ($remote, $opts, $box) = @_;
|
||||
my $b = $opts->{'body'};
|
||||
my $bo = $opts->{'bodyopts'};
|
||||
my $h = $opts->{'head'};
|
||||
my $pic;
|
||||
|
||||
if ($opts->{'form'}->{'frank'} eq "urinate" || $box->{'args'}->{'misbehaved'}) {
|
||||
$pic = "pee";
|
||||
} else {
|
||||
$pic = "hover";
|
||||
}
|
||||
|
||||
box_start($b, $box, { 'title' => "Frank",
|
||||
'align' => "center",
|
||||
'url' => "/site/goat.bml", });
|
||||
|
||||
my $imgname = "frankani" . $box->{'uniq'};
|
||||
my $goattext = $box->{'args'}->{'goattext'} || "Baaaah";
|
||||
|
||||
$$b .= <<"GOAT_STUFF";
|
||||
<a onmouseout="MM_swapImgRestore()" onmouseover="MM_swapImage('$imgname','','$LJ::IMGPREFIX/goat-$pic.gif',1)" href="/site/goat.bml"><img name="$imgname" src="$LJ::IMGPREFIX/goat-normal.gif" width='110' height='101' hspace='2' vspace='2' border='0' alt="Frank, the LiveJournal mascot goat."></a><br />
|
||||
<b><i>"$goattext"</i> says Frank.
|
||||
GOAT_STUFF
|
||||
|
||||
box_end($b, $box);
|
||||
|
||||
$opts->{'onload'}->{"MM_preloadImages('$LJ::IMGPREFIX/goat-$pic.gif');"} = 1;
|
||||
|
||||
unless ($opts->{'did'}->{'image_javascript'})
|
||||
{
|
||||
$opts->{'did'}->{'image_javascript'} = 1;
|
||||
|
||||
$$h .= <<'JAVASCRIPT';
|
||||
<script language="JavaScript">
|
||||
<!--
|
||||
function MM_swapImgRestore() { //v3.0
|
||||
var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;
|
||||
}
|
||||
|
||||
function MM_preloadImages() { //v3.0
|
||||
var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
|
||||
var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
|
||||
if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
|
||||
}
|
||||
|
||||
function MM_findObj(n, d) { //v3.0
|
||||
var p,i,x; if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
|
||||
d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
|
||||
if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
|
||||
for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document); return x;
|
||||
}
|
||||
|
||||
function MM_swapImage() { //v3.0
|
||||
var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
|
||||
if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
|
||||
}
|
||||
//-->
|
||||
</script>
|
||||
JAVASCRIPT
|
||||
|
||||
} # end unless
|
||||
|
||||
|
||||
}, # end handler
|
||||
|
||||
};
|
||||
|
||||
############################################################################
|
||||
12
ljcom/cgi-bin/redirect-local.dat
Normal file
12
ljcom/cgi-bin/redirect-local.dat
Normal file
@@ -0,0 +1,12 @@
|
||||
/legal/coppa.bml /legal/privacy.bml
|
||||
/site/contract.bml /legal/principles.bml
|
||||
/todo.bml /todo/?user=lj_biz
|
||||
/press.bml /press/
|
||||
/site/map.bml /site/
|
||||
/goat.bml /site/goat.bml
|
||||
/clients /download/
|
||||
/download/win32/source.bml /code/clients/win32/
|
||||
/sitemap.bml /site/
|
||||
/contributors.bml /site/contributors.bml
|
||||
/supporters.bml /paidaccounts/
|
||||
/free.bml /site/about.bml
|
||||
Reference in New Issue
Block a user