diff options
Diffstat (limited to 'cgi-bin')
| l--------- | cgi-bin/2 | 1 | ||||
| -rwxr-xr-x | cgi-bin/adminz | 207 | ||||
| -rwxr-xr-x | cgi-bin/bless | 23 | ||||
| -rwxr-xr-x | cgi-bin/category | 290 | ||||
| -rwxr-xr-x | cgi-bin/comment | 186 | ||||
| -rwxr-xr-x | cgi-bin/details | 275 | ||||
| -rwxr-xr-x | cgi-bin/import | 286 | ||||
| -rwxr-xr-x | cgi-bin/inbox | 125 | ||||
| -rwxr-xr-x | cgi-bin/index | 293 | ||||
| -rwxr-xr-x | cgi-bin/invite | 123 | ||||
| -rw-r--r-- | cgi-bin/localbucky.pm | 70 | ||||
| -rw-r--r-- | cgi-bin/localbucky.pm.tmpl | 54 | ||||
| -rwxr-xr-x | cgi-bin/login | 86 | ||||
| -rwxr-xr-x | cgi-bin/logout | 12 | ||||
| -rwxr-xr-x | cgi-bin/maintain | 289 | ||||
| -rwxr-xr-x | cgi-bin/message | 149 | ||||
| -rwxr-xr-x | cgi-bin/murder | 23 | ||||
| -rwxr-xr-x | cgi-bin/playlist | 81 | ||||
| -rwxr-xr-x | cgi-bin/post | 267 | ||||
| -rwxr-xr-x | cgi-bin/profile | 167 | ||||
| -rwxr-xr-x | cgi-bin/recipe | 148 | ||||
| -rwxr-xr-x | cgi-bin/services_f | 83 | ||||
| -rwxr-xr-x | cgi-bin/services_k | 62 | ||||
| -rwxr-xr-x | cgi-bin/services_th | 54 | ||||
| -rw-r--r-- | cgi-bin/settings | 24 | ||||
| -rwxr-xr-x | cgi-bin/tag | 290 | ||||
| -rwxr-xr-x | cgi-bin/users | 228 |
27 files changed, 3896 insertions, 0 deletions
diff --git a/cgi-bin/2 b/cgi-bin/2 new file mode 120000 index 0000000..1c9ed49 --- /dev/null +++ b/cgi-bin/2 @@ -0,0 +1 @@ +/var/www/vhosts/carbonpictures.com/bucky2/cgi-bin/
\ No newline at end of file diff --git a/cgi-bin/adminz b/cgi-bin/adminz new file mode 100755 index 0000000..4a71e38 --- /dev/null +++ b/cgi-bin/adminz @@ -0,0 +1,207 @@ +#!/usr/bin/perl +######################################### +# administration of threads, keywords, +# privacy, etc. + +use localbucky; + +our $id; +our $files; + +$dbh = DBI->connect ($dsn); + +our ($USER, $lastlog) = checkin(); +logout() unless ($USER != -1); + +if ($USER->{ulevel} != 3) + { redirect("/"); } +else + { + header( { title => "bucky administrauma", color => "red" } ); + menu(); + if (exists($input->{c})) + { + if ($input->{c} eq "s") + { + update_thread_title($id, $input->{title}); + $t->{title} = $input->{title}; + print "Changed thread $id title to: <b>$t->{title}</b><br>\n"; + } + elsif ($input->{c} eq "pass") + { + do_password_reset(); + } + elsif ($input->{c} eq "p") + { + if ($input->{private} == 1) + { + print "Thread is now <b>private</b>.<br>"; + switch_thread_privacy($id, 1); + $t->{allowed} = update_whitelist(); + $t->{private} = 1; + } + else + { + print "Thread is now <b>public</b>.<br>"; + switch_thread_privacy($id, 0); + $t->{private} = 0; + } + } + elsif ($input->{c} eq "f") + { + my @flagged = corral($input, "file"); + if ($DEBUG) + { + print "<br>\nfiles flagged: "; + foreach (@flagged) + { print; print " "; } + print "<br>\n"; + } + if ($input->{verb} eq "flag") + { + print "Flagged file $flagged[0]<br>"; + update_flagged($id, $flagged[0]); + $t->{flagged} = $flagged[0]; + admin_form($id, $t, $files, $k); + } + elsif ($input->{verb} eq "move") + { + print "When this works it will be like this:!<br>\n"; + print "Where do you want to move these files here<br>\n"; + print "Moving files...<br>\n"; + # system("mv", $data_path/$oldpid/$filenamea ..., "$data_path/$newpid/"); + print "Moving ids...<br>\n"; + print "Recalculating thread sizes...<br>\n"; + } + elsif ($input->{verb} eq "rm") + { + if (!$input->{ok}) + { + print qq!<center><p><div class="bluebox" style="width: 320px; padding: 10px;"><big><b>Are you sure you want to delete these files?</b></big><hr noshade color="$BUCKY_COLOR_HR"><p>\n!; + print qq!<form action="$BUCKY/maintain" method="post" enctype="multipart/form-data">!; + print qq{<input type=hidden name="c" value="f">\n}; + print qq{<input type=hidden name="id" value="$id">\n}; + print qq{<input type=hidden name="debug" value="1">\n} if ($DEBUG); + print qq{<input type=hidden name="verb" value="rm">\n}; + print qq{<input type=hidden name="ok" value="1">\n}; + + my $i = 0; + my $fid = shift(@flagged); + foreach my $fh (sort_by_id(@$files)) + { + next if ($fid != $$fh{id}); + $i++; + print qq{<input type=hidden name="file$i" value="$fid">\n}; + print $$fh{filename}."<br>\n"; + $fid = shift(@flagged); + } + + print qq{<br><input type="submit" value="YES YES DELETE THE FILES" class="clicky"></form></div></center>}; + } + else + { + my $i = 0; + my $fid = shift(@flagged); + foreach my $fh (sort_by_id(@$files)) + { + next if ($fid != $$fh{id}); + $i++; + delete_file_record($fid); + system("rm", "-f", qq!$data_path/$id/$$fh{filename}!); + print qq!deleted $$fh{filename}<br>\n!; + $fid = shift(@flagged); + } + + print "Recalculating thread size...<br>\n"; + update_thread_size($id); + $files = get_files($id); + } + } + } + adminster_form(); + } + else + { + adminster_form(); + } + footer(); + } + +sub sort_by_username { sort { lc($a->{username}) cmp lc($b->{username}) } @_; } +sub sort_by_id { sort { $a->{id} <=> $b->{id} } @_; } + +sub adminster_form + { + print qq{<table width="100%" cellpadding=0 cellspacing=0 border=0><tr><td align=left valign=top>\n\n}; + +# my $reqs = get_user_requests(); +# if ($reqs != -1) +# { +# my $s = (@$reqs != 1) ? "s" : ""; +# alert_box("$BUCKY/approve", @$reqs." account request$s pending!"); +# } + + print <<end; +<div class="message" style="float: right;"> +<b>password reset form</b> +<hr color="$BUCKY_COLOR_HR"> +end + password_reset_form(); + print "</div>"; + +# "flush" zips button +# recalculcate thread sizes +# links to approval etc (alert!) + print qq{</td></tr></table>\n\n}; + } + +sub password_reset_form + { + my $users = get_all_users(); + + print qq!<form action="$BUCKY/adminz" method="post" enctype="multipart/form-data">!; + print qq{<input type=hidden name="c" value="pass">\n}; + print qq{<input type=hidden name="debug" value="1">\n} if ($DEBUG); + print qq!<table cellpadding=2 cellspacing=0 border=0>!; + print qq!<tr><td align="right">user:</td><td align="left">!; + print qq!<select name="user">!; + foreach $c (sort_by_username(@$users)) + { + print qq!<option value="$c->{username}"!; + print qq!>$c->{username}</option>!; + } + print qq!</select>\n!; + print <<pws; +</td></tr> +<tr><td align="right"> +password?<br> +</td><td align="left"> +<input type="password" name="pw1" value="" size=13 maxlength=20><br> +</td></tr> +<tr><td align="right" valign="top"> +<small>again!</small> +</td><td align="left"> +<input type="password" name="pw2" value="" size=13 maxlength=20><br> +<input type="submit" value="RESET PASSWORD" class="clicky"> +</td></tr> +</table> +pws + print qq!</form>\n!; + } + +sub do_password_reset + { + if (exists($input->{pw1}) && exists($input->{pw2}) && $input->{pw1} && $input->{pw2}) + { + if ($input->{pw1} eq $input->{pw2}) + { + update_password($input->{user}, crypt($input->{pw1},lc($input->{user}))); + print qq(password changed for $input->{user}<br>\n); + } + else + { + print "passwords don't match!<br>\n"; + } + } + } + diff --git a/cgi-bin/bless b/cgi-bin/bless new file mode 100755 index 0000000..0773fe7 --- /dev/null +++ b/cgi-bin/bless @@ -0,0 +1,23 @@ +#!/usr/bin/perl +######################################### +# bless +######################################### + +use localbucky; + +$dbh = DBI->connect ($dsn); + +our ($USER, $lastlog) = checkin(); +logout() unless ($USER != -1); + +our $blessy = $input->{username}; +if (get_uid($blessy) == -1) + { error("no such user $blessy"); } +elsif ($blessy eq $USER->{username}) + { error("you fucking egomaniac"); } +commit_blessing($blessy); +new_message("$blessy.inbox", {sender => "$USER->{username}", recipient => "$blessy", unread => 1, subject => "You look radiant.", body => "You feel a slight prickling along your nape."}); +redirect("$BUCKY/index"); + +$dbh->disconnect (); + diff --git a/cgi-bin/category b/cgi-bin/category new file mode 100755 index 0000000..94ee934 --- /dev/null +++ b/cgi-bin/category @@ -0,0 +1,290 @@ +#!/usr/bin/perl +######################################### +# index +# - do all index stuff, also deal with keyword admin +######################################### + +use localbucky; + +$dbh = DBI->connect ($dsn); + +our ($USER, $lastlog) = checkin(); + +my $k; +my $tag; + +# check name of the calling script: index, tag, keyword +$input->{script} ||= $input->{script_from_uri} if defined($input->{script_from_uri}); + +# load the tag or keyword into the input params, if they don't exit already +if ( $input->{script} eq $BUCKY_LEXICON_TAG ) + { + $input->{tag} ||= $input->{object_from_uri} if defined($input->{object_from_uri}); + } +elsif ( $input->{script} eq $BUCKY_LEXICON_KEYWORD ) + { + $input->{keyword} ||= $input->{object_from_uri} if defined($input->{object_from_uri}); + } + +# Get keyword +if (exists($input->{keyword}) && $input->{keyword} ne "new" && $input->{keyword} ne "unsorted") + { + $k = get_keyword($input->{keyword}); + } + + +# Create New Keyword? FORM +if (exists($input->{keyword}) && $input->{keyword} eq "new") + { + my $t; + header("add new category"); + if (exists($input->{thread})) + { + $t = get_thread($input->{thread}); + } + menu(); + print "<br><br>"; + my %faek = + ( + keyword => $input->{keyword}, + thread => $input->{thread} + ); + keyword_form($input->{keyword}, \%faek, $t); + footer(); + } + +# Edit settings for keyword +elsif ($input->{c} eq "edit" && (check_op($k) || $USER->{ulevel} == 3)) + { + header( + { + title => "settings for category '$input->{keyword}'", + sticky => $input->{keyword} + } ); + # 20070903 - marc - new menu args calling style + my $menu_args; + $menu_args->{keywords} = $k if $k; + menu( $menu_args ); +# menu($k); + print "<br><br>"; + + keyword_form($k->{keyword}, $k); + + print qq!<center><table border=0 cellpadding=0 cellspacing=0 class="threadmain" width="580">!; + my $threads = get_threads_by_keyword($k->{keyword}); + thread_box({ threads => $threads, kw => $k }); + + print qq!</table>!; + footer(); + } + +# Create new keyword? Process form results +elsif ($input->{c} eq "create") + { + if (!defined($input->{keyword})) + { error("no keyword specified!"); } + if (get_keyword($input->{keyword}) != -1) + { error("keyword already exists!"); } + my %nk = + ( + keyword => $input->{keyword}, + threads => " $input->{thread} ", + owner => $USER->{username}, + public => $input->{public}, + agglutinate => $input->{agglutinate}, + color => $input->{color}, + ops => (make_whitelist()) + ); + if ($DEBUG) + { + header("Creating keyword $input->{keyword}"); + menu(); + foreach my $ky (keys %nk) + { print "$ky => $nk{$ky}<br>\n"; } + } + add_keyword(\%nk); + update_thread_keyword($input->{thread}, $input->{keyword}); + redirect("$BUCKY/$BUCKY_LEXICON_KEYWORD/$input->{keyword}"); + } + +# Edit settings for keyword? Process form results +elsif ($input->{c} eq "update") + { + if (!defined($input->{keyword})) + { error("no keyword specified!"); } + my %nk = + ( + threads => " $input->{thread} ", + public => (exists($input->{public}) ? 1 : 0), + agglutinate => (exists($input->{agglutinate})) ? $input->{agglutinate} : 0, + color => $input->{color} + ); + if (!exists($input->{public})) + { + $nk{ops} = make_whitelist(); + } + if ($DEBUG) + { + header("Updating keyword $input->{keyword}"); + menu(); + foreach my $ky (keys %nk) + { print "$ky => $nk{$ky}<br>\n"; } + } + update_keyword($input->{keyword}, \%nk); + redirect("$BUCKY/$BUCKY_LEXICON_KEYWORD/$input->{keyword}"); + } + +# Assign keyword processing form action +elsif ($input->{c} eq "assign") + { + keyword_assign_mechanism($input->{keyword}, $input->{thread}, $k); + redirect("$BUCKY/maintain/$input->{thread}"); + # redirect("$BUCKY/index?keyword=$input->{keyword}"); + } + +# Detach keyword action +elsif ($input->{c} eq "detach") + { + my $t; + + if (!defined($input->{thread})) + { error("no post specified!"); } + $t = get_thread($input->{thread}); + $k = get_keyword($t->{keyword}); + + my %nk = ( threads => delete_key($k->{threads}, $input->{thread}) ); + + if ($DEBUG) + { + header("Detaching post from $t->{keyword}"); + menu(); + foreach my $ky (keys %nk) + { print "$ky => $nk{$ky}<br>\n"; } + print "keyword ==> $t->{keyword}<br>\n"; + print "detaching <b>$t->{title}</b> from <b>$t->{keyword}</b><br>\n"; + } + update_keyword($t->{keyword}, \%nk); + update_thread_keyword($t->{id}, "NULL"); + redirect("$BUCKY/maintain/$t->{id}"); + } + +# Display main index page +else + { + my $tag = exists($input->{tag}) ? $input->{tag} : undef; + my $keyword = exists($input->{keyword}) ? $input->{keyword} : "all"; + my $limit = exists($input->{limit}) ? int($input->{limit}) : 40; + my $date = exists($input->{start}) ? int($input->{start}) : "now"; + + header({ title => get_random_line("titles"), sticky => $input->{keyword} }); + my $keywords = get_keywords(); + my $tags = get_tags(); + + my $menu_args; + $menu_args->{keywords} = $keywords->{$keyword} if $keywords->{$keyword}; + menu( $menu_args ); + + print qq(<table width="100%" cellpadding=0 cellspacing=0 border=0>); + print qq(<tr>); +############################# +# KEYWORD LIST + print qq(<td align=center valign=top width="100">\n); + print qq(<div class="bluebox"><span style="line-height: 1.5em;"><nobr>); + my $p = ''; my $l = ''; + my $with_letter = 0; + my $s = ''; +my $pre = ''; + my $start = ''; + foreach my $k (sort { lc($a) cmp lc($b) } keys %$keywords) + { + my $style; + $l = substr($k,0,1); + $start ||= $l; + if ($p && lc($l) ne lc($p)) + { + if ($with_letter > 3) + { + print qq(<big><big><b>$start - $pre</b></big></big><br> ); + print $s; + print qq(</nobr></span></div>); + print qq(<div class="bluebox"><span style="line-height: 1.5em;"><nobr>); + $s = ''; + $with_letter = 1; + $p=''; + $start = $l; + } + } + $with_letter += 1; + $p||=$l; + $pre=$l; + $s .= qq(<a style="$css" href="$BUCKY/category/$k">$k</a><br>); + } +if ($s) + { + print qq(<big><big><b>$start - $pre</b></big></big><br> ); + print $s; + print qq(</div>); + print qq(<div class="bluebox"><small><span style="line-height: 1.5em;"><nobr>); + } + print qq(</div>); + print qq(<div class="bluebox"><small><span style="line-height: 1.5em;"><nobr>); + print qq(.: <a href="$BUCKY/category/unsorted"><i>unsorted</i></a> :.<br>); + print qq(</nobr></span></small></div></td>\n); + + print qq(<td width="300" align=right valign=top>\n); + + alerts(); + if ($USER == -1) + { + bPod_box(); + } + else + { + welcome_box(); # if (check_key($USER->{boxes}, "welcome")); + search_box(); + bPod_box() if (check_key($USER->{boxes}, "bPod")); + radio_box() if (check_key($USER->{boxes}, "radio")); + upload_form($keyword) if (check_key($USER->{boxes}, "postform")); + hoot_box() if (check_key($USER->{boxes}, "hootbox")); + } + print qq(</td>\n); + print qq(<td align=left valign=top>\n); + + if (check_key($USER->{boxes}, "photostream") || ($USER == -1) ) + { + if ( $keyword ne "all" ) + { photostream({ keyword => $keyword, vertical => 0, count => 4 }); } + elsif ( $tag ) + { photostream({ tag => $tag, vertical => 0, count => 4 }); } + else + { photostream({ user => 1, vertical => 0, count => 4 }); } + } + + print qq(<center><table border=0 cellpadding=0 cellspacing=0 class="threadmain" width="580">); + + if ($keyword ne "all") + { + my $threads = throttle_threads({ keyword => $keyword, newest => $date }); + thread_box({ threads => $threads, kw => $keywords->{$keyword} }); + } + elsif ($tag) + { + my $threads = throttle_threads({ tag => $tag, newest => $date }); + thread_box({ threads => $threads, tag => $tags->{$tag}, sort_by => "name" }); + } + else + { + alpha_index($keywords, $limit, $date); + } + + print qq(</table>); + print qq(</td></tr>); + + print qq(</table>\n\n); + + footer(); + } + +$dbh->disconnect (); + +print "Index: " . &report_time() . "\n" if $timer; diff --git a/cgi-bin/comment b/cgi-bin/comment new file mode 100755 index 0000000..01a763b --- /dev/null +++ b/cgi-bin/comment @@ -0,0 +1,186 @@ +#!/usr/bin/perl +######################################### +# comment +# redundant w/ post: add a comment/files to a thread +######################################### + +use localbucky; + +my $pid; + +$dbh = DBI->connect ($dsn); + +our ($USER, $lastlog) = checkin(); +logout() unless ($USER != -1); + +$input->{id} ||= $input->{object_from_uri} if defined($input->{object_from_uri}); +$input->{id} =~ s/\D*//g; +if ($input->{c} eq "edit") + { + my $header_args; + my $comment = get_comment($input->{id}); + error("No such comment!") if ($comment == -1); + my $thread = get_thread($comment->{thread}); + my $keyword = get_keyword($thread->{keyword}); + error("Cannot edit comment!") unless ($USER->{username} eq $BUCKY_ADMINISTRATOR || $USER->{username} eq $comment->{username} || (check_key($thread->{display}, "editable") && check_privacy($thread, $keyword))); + + $header_args->{title} = qq(editing comment . . .); + $header_args->{subtitle} = qq(<span class="lite"><a href="$BUCKY/).details_link($thread).qq(/$comment->{thread}">back to post</a> · $thread->{title}</span>), + $header_args->{color} = "ivory"; + + header ($header_args); + menu(); + print <<duh; +<table width=100% border=0 cellpadding=0 cellspacing=5> +<tr><td align=center valign=top width=100%><div style="width: 399px;"> +duh + curt_post_form($comment); + print qq!</td></tr></table>\n!; + footer(); + } +elsif ($input->{c} eq "delete") + { + my $header_args; + my $comment = get_comment($input->{id}); + error("No such comment!") if ($comment == -1); + my $thread = get_thread($comment->{thread}); + my $keyword = get_keyword($thread->{keyword}); + error("Cannot delete comment!") unless ($USER->{username} eq $BUCKY_ADMINISTRATOR || $USER->{username} eq $comment->{username} || (check_key($thread->{display}, "editable") && check_privacy($thread, $keyword))); + + if ($input->{ok} eq "yes") + { + delete_comment($comment->{id}); + redirect("$BUCKY/".details_link($thread)."/$comment->{thread}".get_revision($thread)); + } + else + { + $header_args->{title} = qq(delete comment?); + $header_args->{subtitle} = qq(<span class="lite"><a href="$BUCKY/).details_link($thread).qq(/$comment->{thread}">back to post</a> ($thread->{title})</span>); + $header_args->{color} = "ivory"; + + header ($header_args); + menu(); + print qq!<center><p><div class="bluebox" style="width: 320px; padding: 10px;"><big><b>Are you sure you want to !; + print qq!delete this comment?</b></big><hr noshade color="$BUCKY_COLOR_HR"><p>\n!; + my $subcomment = substr($comment->{comment}, 0, 64); + $subcomment =~ s/</</g; + $subcomment =~ s/>/>/g; + $subcomment =~ s/"/"/g; + print "<p>".$subcomment."</p>"; + print qq!<form action="$BUCKY/comment" method="post" enctype="multipart/form-data">!; + print qq(<input type=hidden name="c" value="delete">\n); + print qq(<input type=hidden name="id" value="$comment->{id}">\n); + print qq(<input type=hidden name="debug" value="1">\n) if ($DEBUG); + print qq(<input type=hidden name="ok" value="yes">\n); + + print qq(<br><input type="submit" value="DELETE" class="clicky"></form></div></center>); + print qq(</td></tr></table>\n); + footer(); + } + } +elsif ($input->{c} eq "reply") + { + my $header_args; + my $comment = -1; + my $thread = -1; + my $keyword = -1; + if (exists($input->{id})) + { + $comment = get_comment($input->{id}); + error("No such comment!") if ($comment == -1); + $thread = get_thread($comment->{thread}); + } + elsif (exists($input->{thread})) + { + $thread = get_thread($input->{thread}); + } + my $keyword = get_keyword($thread->{keyword}); + error("Cannot see comment!") unless (check_privacy($thread) || check_op($keyword)); + + $header_args->{title} = qq(reply to comment . . .); + $header_args->{subtitle} = qq(<span class="lite"><a href="$BUCKY/).details_link($thread).qq(/$comment->{thread}">back to post</a> · $thread->{title}</span>); + $header_args->{color} = "ivory"; + + header ($header_args); + menu(); + print <<duh; +<table width=100% border=0 cellpadding=0 cellspacing=5> +<tr><td align=center valign=top width=100%><div style="width: 399px;"> +duh + curt_reply_form($comment, $thread, $keyword); + print qq!</td></tr></table>\n!; + footer(); + } +elsif ($input->{c} eq "update") + { + my $comment = get_comment($input->{id}); + error("No such comment!") if ($comment == -1); + my $thread = get_thread($comment->{thread}); + my $keyword = get_keyword($thread->{keyword}); + error("Cannot edit comment!") unless ($USER->{username} eq $BUCKY_ADMINISTRATOR || $USER->{username} eq $comment->{username} || (check_key($thread->{display}, "editable") && check_privacy($thread, $keyword))); + update_comment($input->{id}, $input->{comment}) if ($input->{comment}); + touch_thread($thread); + + if ($comment->{thread} == 1) + { + redirect("$BUCKY/index"); + } + else + { + redirect("$BUCKY/".details_link($thread)."/$comment->{thread}".get_revision($thread)); + } + } +elsif ($input->{id} == 1) + { + add_comment($input->{id}, -1, $USER->{username}, $input->{comment}) if ($input->{comment}); + redirect("$BUCKY/index"); + } +else + { + my $pid; + my $t; + my $keyword; + if ($DEBUG) + { + header ("adding message to $input->{id}"); + print "adding message to $input->{id}:<p><tt>"; + } + + $t = get_thread($input->{id}); + if ($t == -1) + { + flush_files(); + redirect("$BUCKY/".details_link($t)."/$comment->{thread}".get_revision($t)); + } + $keyword = get_keyword($thread->{keyword}); +# error("No such thread!") unless ($t != -1 && check_privacy($t, $keyword)); + + if (exists($input->{parent_id})) + { + my $headc = get_comment($input->{parent_id}); + error("No such comment!") if ($headc == -1); + if ($headc->{parent_id} != -1) + { $pid = $headc->{parent_id}; } + else + { $pid = $headc->{id}; } + } + else + { + $pid = -1; + } + + add_comment($t->{id}, $pid, $USER->{username}, $input->{comment}) if ($input->{comment}); + situate_files($t->{id}, $USER->{username}); + touch_thread($t); + redirect("$BUCKY/".details_link($t)."/$t->{id}".get_revision($t)); + switch_file_privacy($t->{id}, $t->{private}); + } + +if ($DEBUG) + { + footer (); + } + +$dbh->disconnect (); + +print "Comment: " . &report_time() . "\n" if $timer; diff --git a/cgi-bin/details b/cgi-bin/details new file mode 100755 index 0000000..35b34c7 --- /dev/null +++ b/cgi-bin/details @@ -0,0 +1,275 @@ +#!/usr/bin/perl +######################################## +# details +######################################### + +use localbucky; + +$dbh = DBI->connect ($dsn); + +our ($USER, $lastlog) = checkin(); +our $loggedin = ($USER != -1); + +our ($t, $kw, $files, $comments) = details_init(); +details_run($t, $kw, $files, $comments); + +sub details_init + { + $input->{id} ||= $input->{object_from_uri} if defined($input->{object_from_uri}); + my $id = exists($input->{id}) ? $input->{id} : error("No such thread!"); + + my $t = get_thread($id); + error("No such post.") if ($t == -1); + my $kw = get_keyword($t->{keyword}); + + my $files = get_files($t->{id}); + my $comments = get_comments ($t->{id}); + + if ( ! check_privacy($t, $kw) ) # || check_participation($files, $comments) ) + #unless ( check_privacy($t, $kw) || check_participation($files, $comments) ) + { error("No such post!"); } + + # Reset NULL viewed + if ( ! $t->{viewed} ) + { $t->{viewed} = 0; } + + # Increment viewed for this thread + $t->{viewed}++; + # Update thread viewed count + update_thread_viewed( $t->{id}, $t->{viewed} ); + + return ($t, $kw, $files, $comments); + } + +sub details_run + { + my ($t, $kw, $files, $comments) = @_; + my $header_args = + { + title => $t->{title}, + sticky => $t->{keyword}, + color => get_color($t, $kw, $comments) +# participation => check_participation($files, $comments) + }; + + my $age = get_age($t->{lastmodified}); + $age .= " ago" unless $age eq "now"; + + $header_args->{subtitle} = + qq!posted by <a href="$BUCKY/profile/$t->{username}">$t->{username}</a> on ! . + verbosedate($t->{createdate}) . " · active " . $age . + qq! · $t->{viewed} view! . courtesy_s($t->{viewed}); + + if ($t->{username} eq $USER->{username} || check_op($kw) || $header_args->{participation} == 2 || $USER->{ulevel} == 3) + { + $header_args->{subtitle} .= qq! · !; + $header_args->{subtitle} .= qq!<a href="$BUCKY/maintain/$t->{id}">options</a>!; + } +# else +# { +# $header_args->{subtitle} .= +# qq! · <a href="$BUCKY/index">go to <b>index</b></a>!; +# } + + $header_args->{subtitle} .= qq! · !; + $header_args->{subtitle} .= qq!<span class="lite"><a href="scp://$BUCKY_FTP_USER\@$BUCKY_FTP_HOST/var/bucky/$t->{id}">download\!</a></span>!; + + my @participants = get_participants($t, $files, $comments); + + $header_args->{sidetitle} = details_participation(@participants) + if (@participants > 0); + $header_args->{sidesubtitle} = "<small><i>see also:</i> ".details_tags_box($t, $kw)."</small>" + if (@{$t->{tags}}); + + header($header_args); + + # 20070903 - marc - new menu args calling style + my $menu_args; + $menu_args->{keywords} = $kw if $kw; + $menu_args->{ftp} = 1 if ($t->{files}+$t->{comments} + 1); + menu( $menu_args ); + + details_view($t, $kw, $comments, $files); + footer(); + } + + +############################## + +sub details_view + { + my ($t, $kw, $comments, $files) = @_; + my ($many_jpgs, $flagged) = find_jpeg_v2($files, $t->{flagged}); + if ($many_jpgs > 6) + { + print qq(<center><table border=0 cellpadding=0 cellspacing=0 width="100%">); + } + else + { + print qq(<center><table border=0 cellpadding=0 cellspacing=0>); + } + + print qq(<tr><td align=right valign=top width=440>); + print qq(<table class="commentbox" cellpadding=0 cellspacing=0 border=0 width=440>); + + if ($flagged != -1 && $many_jpgs > 1) + { + print qq(<td align=center valign=middle colspan=2>); + print_flagged_jpeg($flagged); + print qq(</td></tr>); + } + + sideshow_comments({ thread => $t, keyword => $kw, comments => $comments }); + print qq(<tr><td align=center valign=top colspan=2>); + reply_form($t->{id}, $t); + print qq(</td></tr>); + print qq(</table>); + + if ($flagged != -1 && $many_jpgs == 1) + { + print qq(<td align=left valign=top colspan=2 style="padding: 10px;">); + print_flagged_jpeg($flagged); + } + elsif ($many_jpgs > 1 || @$files > $many_jpgs) + { + print qq(<td align=left valign=top style="padding-left: 5px;">); + } + else + { + print qq(<td align=left valign=top style="padding-left: 5px;">); + } + if ($many_jpgs > 1) + { + if ($many_jpgs < 6) # && @$files == $many_jpgs) + { image_column($files, $flagged, $many_jpgs); } + else + { image_gallery($files, $flagged, $many_jpgs); } + } + if (@$files > $many_jpgs) + { + if (find_mp3($files)) + { + my $z_playlist = "/cgi-bin/bucky/playlist/$t->{id}"; + my $z_autoplay = "false"; + if (check_key($USER->{boxes}, "autoplay")) + { $z_autoplay = "true"; } + print <<__PLAYLIST__; + <div id='mp3player'>LOADING MP3 PLAYER ...</div> + +<script type="text/javascript" src="/js/swfobject1.js"></script> +<script type="text/javascript"> + var s2 = new SWFObject("/mediaplayer.swf", "playlist", "392", "200", "7"); + s2.addVariable("file","$z_playlist"); + s2.addVariable("shuffle","false"); + s2.addVariable("backcolor","0xEEEEEE"); + s2.addVariable("frontcolor","0x111111"); + s2.addVariable("lightcolor","0x444444"); + s2.addVariable("displayheight","0"); + s2.addVariable("width","392"); + s2.addVariable("height","200"); + s2.addVariable("volume","50"); + s2.addVariable("autostart","$z_autoplay"); + s2.write("mp3player"); +</script> +__PLAYLIST__ + } + if (check_key($t->{display}, "nfl")) # no file list + { ; } + elsif (check_key($t->{display}, "ffl")) # full file list + { + file_list($files, 0, 1, 0); + } + else # "terse" file list + { + file_list($files, 0, 1, $many_jpgs); + } + } + if ($ZIP_BUTTON_ENABLED && @$files > 4) + { + zip_this_button($t); + } + + details_keywords_box($t, $kw); + print "</td>"; + + print qq(</tr></table></center>); + } + +sub find_mp3 + { + my ($q) = @_; + foreach my $f (@$q) + { return 1 if $f->{filename} =~ /mp3$/i; } + return 0; + } + +sub details_tags_box + { + my ($t, $kw) = @_; +# my $tags = $t->{tags}; + return tags_stringify_links ( $t ); +# return join(", ", @$tags); + } + +sub details_participation + { + my (@participants) = @_; + my $pcount = 0; + my $out; + + foreach my $p (@participants) + { + $pcount++; + next if ($pcount > 6); + my $image = get_profile_image($p, $AVATAR_MED_PREFIX); + if ($image != -1) + { + $out .= qq( ); + $out .= qq(<a href="$BUCKY/profile/$p">); + $out .= qq(<img src="$image" width="$AVATAR_MED_WIDTH" height="$AVATAR_MED_WIDTH" border=1">); + $out .= qq(</a>); + } + } + if ($pcount > 6) + { + $out .= "<small> + ".($pcount - 4); + $out .= " $BUCKY_DUDER_NOUN"; + $out .= courtesy_s($pcount - 4); + $out .= "</small>"; + } + return $out; + } + +# get list of unique users posting in thread +sub get_participants + { + my ($t, $files, $comments) = @_; + my %participant; + $participant{$t->{username}} = 1000; + + foreach my $f (@$files) + { $participant{$f->{username}}++; } + foreach my $c (keys %$comments) + { $participant{$comments->{$c}->{username}}++; } + + return (sort { $participant{$b} <=> $participant{$a} } (keys(%participant))); + } + +sub details_keywords_box + { + my ($t, $kw) = @_; + if (defined($t->{keyword}) && !check_key($t->{display}, "kws")) + { + my $t = get_threads_by_keyword($t->{keyword}); + if ($t != -1) + { + print qq(<table border=0 cellpadding=0 cellspacing=0 class="threadmain" width="$width">); + thread_box({ threads => $t, kw => $kw }); + print qq(</table>); + } + } + } + +############################## + +print "Details: " . &report_time() . "\n" if $timer; diff --git a/cgi-bin/import b/cgi-bin/import new file mode 100755 index 0000000..fc7add5 --- /dev/null +++ b/cgi-bin/import @@ -0,0 +1,286 @@ +#!/usr/bin/perl +######################################### +# import +# escorts ftp'd files into the database +######################################### + +use localbucky; + +my $pid; + +$dbh = DBI->connect ($dsn); + +our ($USER, $lastlog) = checkin(); +logout() unless ($USER != -1); + +if ($input->{c} eq "n") + { + my $valid = 0; + my $thread_id = 0; + if ($DEBUG) + { + header("importing files..."); + foreach $k (sort keys %$input) { print "$k => ".$input->{$k}."<br>"; } + } + foreach my $k (keys %$input) + { + if ($k =~ /^import/) + { $valid = 1; last; } + } + if ($valid) + { + if ($input->{id} && $input->{id} ne "new") + { + $thread = get_thread($input->{id}); + $keyword = get_keyword($thread->{keyword}); + if ($thread != -1 && check_privacy($thread, $keyword)) + { + $thread_id = $thread->{id}; + touch_thread($thread); + } + else + { + error("cannot import into specified thread"); + } + } + else + { + if ($input->{title} eq undef || $input->{title} =~ /^\s+$/) + { + error ("No thread title!"); + } + else + { + $thread_id = add_thread($input->{title}, $USER->{username}, 0); + } + } + print "thread_id => $thread_id<br>" if ($DEBUG); + add_comment($thread_id,-1,$USER->{username},$input->{comment}) if ($input->{comment} ne undef); + situate_imports($thread_id, $USER->{username}); + if (exists($input->{keyword})) + { + my $k = get_keyword($input->{keyword}); + if ($k->{public} || check_op($k)) + { + keyword_assign_mechanism($input->{keyword}, $thread_id, $k); + } + } + } + else + { error("No imports specified!"); } + if ($DEBUG) + { + print qq{this way to your new thread: <a href="$BUCKY/details/$thread_id">link!</a>}; + footer(); + } + redirect("$BUCKY/details/$thread_id"); + } + +else + { + my ($title, $size, $inc); + + my $thread = -1; + my $keyword = -1; + if ($input->{id}) + { + # id title username createdate lastmodified size private allowed flagged + $thread = get_thread($input->{id}); + $keyword = get_keyword($thread->{keyword}); + } + if ($input->{keyword}) + { + $keyword = get_keyword($input->{keyword}); + } + elsif ($thread->{keyword}) + { + $keyword = get_keyword($thread->{keyword}); + } + + header("ftp import"); + menu(); + if ($USER->{'username'} eq "asdfasdfadsfadsf") + { + print <<__SORRY__; +<center> +<br> +<div style="text-align: left; width: 300px; padding: 10px;" class="bluebox"> +<center><b><big>SORRY!</big></b> +<hr noshade color="$BUCKY_COLOR_HR"> +You have maxed out your upload quota!<p> +Delete some things you've uploaded, then try again. +</center></div><br></center> +__SORRY__ + exit; + } + print <<impHEAD; +<center> +<br> +<div style="float: right; text-align: left; width: 200px; padding: 10px; font-size: 11px; background-color: #f8f8f8;" class="bluebox"><center> + +<big><b>UPLOAD FILES TO BUCKY WITH CONVENIENCE USING SFTP</b></big> +<hr noshade color="$BUCKY_COLOR_HR"> + +You must generate a cryptographic key to use this service. Don't worry it's easy!<br/> +<br/> +<hr noshade color="#ddd"> +<br/> + +ON A MAC / UNIX<br/> +<br/> +recc'd sftp client: <a href="http://cyberduck.ch/" target="_blank">Cyberd*ck</a><br/> +<b>to generate the key</b>, from Terminal run:<br/> +<big><tt><b>ssh-keygen -t rsa</b></b></tt></big><br/> +<a href="/cgi-bin/bucky/message/jules">send me the public key</a> +<br/> +(private key is handled automatically) +<br/> +<br/> +<hr noshade color="#ddd"> +<br/> + +ON WINDOWS ...<br/> +<br/> +recc'd sftp client: <a href="http://winscp.net/" target="_blank">WINSCP (PC)</a><br/> +<b>generate the key</b> with the program <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html" target="_blank">puttygen</a> +<br/> +<a href="/cgi-bin/bucky/message/jules">send me the public key</a> +<br/> +(the private key goes in the program when you set up the session.) + +<br/> +<br/> +<hr noshade color="#ddd"> +<br/> + +log in here: +<br/> +<br/> +<tt><big> +$BUCKY_FTP_HOST<br> +username: $BUCKY_FTP_USER</big></tt> + +<br/> +<br/> +<hr noshade color="#ddd"> +<br/> + +Once you're in, upload your files and they should show up below. <b>Check off</b> only the files that are yours, +or click the toggle button to select them all. +impHEAD + + if ($thread == -1) + { + print qq(To attach FTP'd files to a pre-existing thread, go to the thread and click <b>ftp here</b>.); + } + print qq!</center></div>\n\n!; + + print qq!<form name="checkz" action="$BUCKY/import" method="post" enctype="multipart/form-data">\n!; + print qq!<div width=500>\n!; + ($title, $inc, $size) = list_imports(); + + print <<widget; +<script type="text/javascript"> +<!-- +function toggle() + { + var e = document.checkz.elements.length; + for (var i = 0; i < e; i++) + { + var y = "document.checkz[i].type"; + type = eval(y); + + var n = "document.checkz[i]"; + box = eval(n); + + if (type == "checkbox") + { + if (box.checked == false) + { box.checked = true; } + else + { box.checked = false; } + } + } + } +--> +</script> +<table cellpadding=0 cellspacing=0 width="580"> +<tr> +<td align="left" valign="top"><input type=button value="toggle checked" onClick="JavaScript:toggle()"></td> +<td align="center" valign="middle"> +widget + + if ($inc) + { + print "<center><small><i><b>INCOMPLETE</b> FILES ARE SHOWN IN ITALICS -- PLEASE WAIT FOR YOUR UPLOAD TO FINISH</i></small></center><p>\n\n"; + } + + if ($DEBUG) { print qq!<input type="hidden" name="debug" value="$DEBUG">\n!; } + print qq!<input type="hidden" name="c" value="n">\n!; + + print qq!<center>!; + print qq!<table cellpadding=2 cellspacing=0>!; + if ($thread != -1 && check_privacy($thread, $keyword)) + { + print qq!<tr><td align="right" valign="baseline">!; + print qq! !; + print qq!<td><td align="left" valign="baseline">!; + print qq!These files will be added to:<p><big><b>$thread->{title}</b></big><br>\n!; + print qq!posted by $thread->{username} on !.verbosedate($thread->{createdate}).qq!<p>\n\n!; + print qq!<input type="hidden" name="id" value="$thread->{id}">\n!; + print qq!</td></tr>!; + } + else + { + print qq!<input type="hidden" name="id" value="new">\n\n!; + print qq!<tr><td align="right" valign="baseline">!; + print qq!title: !; + print qq!<td><td align="left" valign="baseline">!; + print qq!<input type="text" name="title" value="$title" size=40 maxlength=48><br>\n!; + print qq!</td></tr>!; + print qq!<tr><td align="right" valign="baseline">!; + print "keyword: "; + print qq!<td><td align="left" valign="baseline">!; + if (exists($input->{keyword})) + { + my $k = get_keyword($input->{keyword}); + if ($k->{public} || check_op($k)) + { + keyword_pulldown($k->{keyword}); + $checked = $k->{public} ? "" : " checked"; + } + else + { keyword_pulldown("NONE"); } + } + else + { keyword_pulldown("NONE"); } + print qq!</td></tr>!; + } + print qq!<tr><td>!; + print " "; + print qq!</td></tr>!; + + print qq!<tr><td align="right" valign="top">!; + print qq!comment: !; + print qq!<td><td align="left" valign="top">!; + print <<impFOOT; +<p> +<textarea name="comment" cols="40" rows="10"></textarea> +<p> +<input type="submit" value="IMPORT" class="clicky"> +</td> +</tr> +</table> +</td> +</tr> +</table> +</center> +</form> +</div> + +impFOOT + footer(); + } + +$dbh->disconnect (); + diff --git a/cgi-bin/inbox b/cgi-bin/inbox new file mode 100755 index 0000000..9760a54 --- /dev/null +++ b/cgi-bin/inbox @@ -0,0 +1,125 @@ +#!/usr/bin/perl +######################################### +# inbox +# deal with inboxing, message display +######################################### + +use localbucky; + +$dbh = DBI->connect ($dsn); + +our ($USER, $lastlog) = checkin(); +logout() unless ($USER != -1); + +if ( defined($input->{object_from_uri}) ) + { + if ( $input->{object_from_uri} =~ /^[0-9]+$/ ) + { + $input->{id} ||= $input->{object_from_uri}; + } + else + { + $input->{box} ||= $input->{object_from_uri}; + } + + } +#$input->{id} ||= $input->{object_from_uri} if defined($input->{object_from_uri}) && ($input->{object_from_uri} =~ /^[0-9]+$/); +#$input->{box} ||= $input->{object_from_uri} if defined($input->{object_from_uri}) && ( +if (exists($input->{id})) + { + # display message + + my $message = get_message($input->{id}); + my $bn = $b->{mbox}; + $bn =~ s/^$USER->{username}\.//; + if ($message == -1) + { error("No such message!"); } + if ($USER->{username} ne $message->{recipient} && $USER->{username} ne $message->{sender}) + { error("You are not the recipient of this message."); } + unflag_message($input->{id}); + my $header_args= {}; + $header_args->{'title'} = $message->{'subject'}; + if ($message->{'body'} =~ /body bgcolor="?([#0-9a-fA-F]+)/) + { + $header_args->{'color'} = $1; + } + + header($header_args); + menu(); + print "<br><br>"; + display_message($message); + footer(); + } + +elsif ($input->{c} eq "f") + { + # folder_management_form(); + } + +else + { + my $box = exists($input->{box}) ? $input->{box} : "inbox"; + my $limit = exists($input->{limit}) ? int($input->{limit}) : 50; + my $date = exists($input->{start}) ? int($input->{start}) : "now"; + + header("your $box"); + menu(); + + my $messages = get_messages("$USER->{username}.$box", $limit, $date); + my $boxes = get_boxes($USER->{username}); + + print qq!<center>!; + + print <<userbox; +<div class="bluebox" style="float: right;"> +<b>message center</b> +<hr noshade color="$BUCKY_COLOR_HR"> +<center> +<table border=0 cellspacing=2 width=100> +<tr><td align=left><small><b>Folders</b></small></td><td align=center><small>msgs</small></td></tr> +userbox + + foreach my $b (@$boxes) + { + my $count = $b->{mcount} || 0; + my $bn = $b->{mbox}; + $bn =~ s/^$USER->{username}\.//; + print qq!<tr><td align=left><small><a href="$BUCKY/inbox/$bn"><b>$bn</b></a></small></td>! . + qq!<td align=center>!.hushnull($count, undef, 1).qq!</td></tr>!; + } + + print <<userbox; +</table> +</center> +<hr noshade color="$BUCKY_COLOR_HR"> +<small> +<a href="$BUCKY/message"><b>Compose New Mail</b></a> +</small> +<hr noshade color="$BUCKY_COLOR_HR"> +<small> +need to find someone?<br> +<a href="$BUCKY/users"><u>check the userlist</u></a> +</small> +</div> +userbox + + print qq!<table width="100%" cellpadding=0 cellspacing=0 border=0><tr><td align=left valign=top>!; + + message_list($messages, $box); + + if (@$messages == $limit) + { + print qq!<div align="right"><big><br>!; + $oldest = $messages->[-1]->{date}; + print qq(<a href="$BUCKY/inbox/$box&limit=$limit&start=$oldest">next <b>$limit</b> messages >></a>); + print qq!</big></div>\n!; + } + + print qq!</td></tr></table>!; + + footer(); + } + +$dbh->disconnect (); + +print "Inbox: " . &report_time() . "\n" if $timer; diff --git a/cgi-bin/index b/cgi-bin/index new file mode 100755 index 0000000..8ddacb4 --- /dev/null +++ b/cgi-bin/index @@ -0,0 +1,293 @@ +#!/usr/bin/perl +######################################### +# index +# - do all index stuff, also deal with keyword admin +######################################### + +use localbucky; + +$dbh = DBI->connect ($dsn); + +our ($USER, $lastlog) = checkin(); + +my $k; +my $tag; + +# check name of the calling script: index, tag, keyword +$input->{script} ||= $input->{script_from_uri} if defined($input->{script_from_uri}); + +# load the tag or keyword into the input params, if they don't exit already +if ( $input->{script} eq $BUCKY_LEXICON_TAG ) + { + $input->{tag} ||= $input->{object_from_uri} if defined($input->{object_from_uri}); + } +elsif ( $input->{script} eq $BUCKY_LEXICON_KEYWORD ) + { + $input->{keyword} ||= $input->{object_from_uri} if defined($input->{object_from_uri}); + } + +# Get keyword +if (exists($input->{keyword}) && $input->{keyword} ne "new" && $input->{keyword} ne "unsorted") + { + $k = get_keyword($input->{keyword}); + } + + +# Create New Keyword? FORM +if (exists($input->{keyword}) && $input->{keyword} eq "new") + { + my $t; + header("add new category"); + if (exists($input->{thread})) + { + $t = get_thread($input->{thread}); + } + menu(); + print "<br><br>"; + my %faek = + ( + keyword => $input->{keyword}, + thread => $input->{thread} + ); + keyword_form($input->{keyword}, \%faek, $t); + footer(); + } + +# Edit settings for keyword +elsif ($input->{c} eq "edit" && (check_op($k) || $USER->{ulevel} == 3)) + { + header( + { + title => "settings for category '$input->{keyword}'", + sticky => $input->{keyword} + } ); + # 20070903 - marc - new menu args calling style + my $menu_args; + $menu_args->{keywords} = $k if $k; + menu( $menu_args ); +# menu($k); + print "<br><br>"; + + keyword_form($k->{keyword}, $k); + + print qq!<center><table border=0 cellpadding=0 cellspacing=0 class="threadmain" width="580">!; + my $threads = get_threads_by_keyword($k->{keyword}); + thread_box({ threads => $threads, kw => $k }); + + print qq!</table>!; + footer(); + } + +# Create new keyword? Process form results +elsif ($input->{c} eq "create") + { + if (!defined($input->{keyword})) + { error("no keyword specified!"); } + if (get_keyword($input->{keyword}) != -1) + { error("keyword already exists!"); } + my %nk = + ( + keyword => $input->{keyword}, + threads => " $input->{thread} ", + owner => $USER->{username}, + public => $input->{public}, + agglutinate => $input->{agglutinate}, + color => $input->{color}, + ops => (make_whitelist()) + ); + if ($DEBUG) + { + header("Creating keyword $input->{keyword}"); + menu(); + foreach my $ky (keys %nk) + { print "$ky => $nk{$ky}<br>\n"; } + } + add_keyword(\%nk); + update_thread_keyword($input->{thread}, $input->{keyword}); + redirect("$BUCKY/$BUCKY_LEXICON_KEYWORD/$input->{keyword}"); + } + +# Edit settings for keyword? Process form results +elsif ($input->{c} eq "update") + { + if (!defined($input->{keyword})) + { error("no keyword specified!"); } + my %nk = + ( + threads => " $input->{thread} ", + public => (exists($input->{public}) ? 1 : 0), + agglutinate => (exists($input->{agglutinate})) ? $input->{agglutinate} : 0, + color => $input->{color} + ); + if (!exists($input->{public})) + { + $nk{ops} = make_whitelist(); + } + if ($DEBUG) + { + header("Updating keyword $input->{keyword}"); + menu(); + foreach my $ky (keys %nk) + { print "$ky => $nk{$ky}<br>\n"; } + } + update_keyword($input->{keyword}, \%nk); + redirect("$BUCKY/$BUCKY_LEXICON_KEYWORD/$input->{keyword}"); + } + +# Assign keyword processing form action +elsif ($input->{c} eq "assign") + { + keyword_assign_mechanism($input->{keyword}, $input->{thread}, $k); + redirect("$BUCKY/maintain/$input->{thread}"); + # redirect("$BUCKY/index?keyword=$input->{keyword}"); + } + +# Detach keyword action +elsif ($input->{c} eq "detach") + { + my $t; + + if (!defined($input->{thread})) + { error("no post specified!"); } + $t = get_thread($input->{thread}); + $k = get_keyword($t->{keyword}); + + my %nk = ( threads => delete_key($k->{threads}, $input->{thread}) ); + + if ($DEBUG) + { + header("Detaching post from $t->{keyword}"); + menu(); + foreach my $ky (keys %nk) + { print "$ky => $nk{$ky}<br>\n"; } + print "keyword ==> $t->{keyword}<br>\n"; + print "detaching <b>$t->{title}</b> from <b>$t->{keyword}</b><br>\n"; + } + update_keyword($t->{keyword}, \%nk); + update_thread_keyword($t->{id}, "NULL"); + redirect("$BUCKY/maintain/$t->{id}"); + } + +# Display main index page +else + { + my $tag = exists($input->{tag}) ? $input->{tag} : undef; + my $keyword = exists($input->{keyword}) ? $input->{keyword} : "all"; + my $limit = exists($input->{limit}) ? int($input->{limit}) : $BUCKY_INDEX_LIMIT; + my $date = exists($input->{start}) ? int($input->{start}) : "now"; + + header({ title => get_random_line("titles"), sticky => $input->{keyword}, color => get_color_from_time() }); + my $keywords = get_keywords(); + my $tags = get_tags(); + + my $menu_args; + $menu_args->{keywords} = $keywords->{$keyword} if $keywords->{$keyword}; + menu( $menu_args ); + + print qq(<table width="100%" cellpadding=0 cellspacing=0 border=0>); + print qq(<tr>); + +############################# +# KEYWORD LIST + print qq(<td align=center valign=top style="width: 100px">\n); + print qq(<div class="bluebox" width="100"><span style="line-height: 1.5em;"><nobr>); + my $p = ''; my $l = ''; + my $with_letter = 0; + my $s = ''; +my $pre = ''; + my $start = ''; + foreach my $k (sort { lc($a) cmp lc($b) } keys %$keywords) + { + my $style; + $l = substr($k,0,1); + $start ||= $l; + if ($p && lc($l) ne lc($p)) + { + if ($with_letter > 3) + { + print qq(<big><big><b>$start - $pre</b></big></big><br> ); + print $s; + print qq(</nobr></span></div>); + print qq(<div class="bluebox" width="100"><span style="line-height: 1.5em;"><nobr>); + $s = ''; + $with_letter = 1; + $p=''; + $start = $l; + } + } + $with_letter += 1; + $p||=$l; + $pre=$l; + $s .= qq(<a style="$css" href="$BUCKY/category/$k">$k</a><br>); + } +if ($s) + { + print qq(<big><big><b>$start - $pre</b></big></big><br> ); + print $s; + print qq(</div>); + print qq(<div class="bluebox" width="100"><small><span style="line-height: 1.5em;"><nobr>); + } + print qq(</div>); + print qq(<div class="bluebox"><small><span style="line-height: 1.5em;"><nobr>); + print qq(.: <a href="$BUCKY/category/unsorted"><i>unsorted</i></a> :.<br>); + print qq(</nobr></span></small></div></td>\n); + +############################# +# PRINT MAIN PANE + print qq(<td align=left valign=top>\n); + +# index_photostream($keyword,$tag); + +# print qq(<table border=0 cellpadding=0 cellspacing=0 class="threadmain" width="580">); +# print qq(<table border=0 cellpadding=0 cellspacing=0 class="threadmain">); + print qq(<table border=0 cellpadding=0 cellspacing=0 class="threadmain" width="100%">); + + if ($keyword ne "all") + { + my $threads = throttle_threads({ keyword => $keyword, newest => $date }); + thread_box({ threads => $threads, kw => $keywords->{$keyword} }); + } + elsif ($tag) + { + my $threads = throttle_threads({ tag => $tag, newest => $date }); + thread_box({ threads => $threads, tag => $tags->{$tag} }); + } + else + { + alpha_index($keywords, $limit, $date); + } + + print qq(</table>); + print qq(</td>\n); + +############################# +# PRINT SIDEBAR + print qq(<td width="300" align=left valign=top>\n); + alerts(); + if ($USER == -1) + { + bPod_box(); + } + else + { + welcome_box(); # if (check_key($USER->{boxes}, "welcome")); + search_box(); +# radio_box() ; # if (check_key($USER->{boxes}, "radio")); +# bPod_box() if (check_key($USER->{boxes}, "bPod")); + hoot_box() if (check_key($USER->{boxes}, "hootbox")); +# svn_box();# if $USER->{'ulevel'} == 3; +# upload_form($keyword) if (check_key($USER->{boxes}, "postform")); + } + print qq(</td>); + +############################### + + print qq(</tr>); + print qq(</table>\n\n); + + footer(); + } + +$dbh->disconnect (); + +print "Index: " . &report_time() . "\n" if $timer; diff --git a/cgi-bin/invite b/cgi-bin/invite new file mode 100755 index 0000000..cf29b1b --- /dev/null +++ b/cgi-bin/invite @@ -0,0 +1,123 @@ +#!/usr/bin/perl +######################################### +# invite +######################################### +# id hash state attest created expired username password realname email grass keywords + +use localbucky; + +use invite; +use Digest::MD5 qw (md5_hex); + +$dbh = DBI->connect ($dsn); + +our ($USER, $lastlog) = checkin(); +our $loggedin = ($USER != -1); + +our ($command, $hash, $id) = invite_init(); +invite_run($command, $hash, $id); + +sub invite_init + { + my $command = exists($input->{c}) ? scrub($input->{c}) : -1; + my $hash = -1; + if (defined($input->{object_from_uri})) + { $hash = scrub($input->{object_from_uri}); } + elsif (exists($input->{hash})) + { $hash = scrub($input->{hash}); } + elsif (exists($input->{invite})) + { $hash = scrub($input->{invite}); } + elsif (exists($input->{i})) + { $hash = scrub($input->{i}); } + my $id = exists($input->{id}) ? scrub($input->{id}) : -1; + return ($command, $hash, $id); + } + +sub invite_run + { + my ($command, $hash, $id) = @_; + + if ($loggedin) + { invite_process_user($command, $hash, $id); } + else + { invite_process_outsider($command, $hash); } + } + +sub invite_process_outsider + { + my ($command, $hash) = @_; + + # validate invite + if ($command eq "validate") + { + validate_invite($hash); + } + # add request + elsif ($command eq "request") + { + request_invite(); + } + # redeem invite + elsif ($hash != -1) + { + my $invite = get_invite_from_hash($hash); + unless (invite_is_active($invite)) + { error("Bad invite key!"); } + registration_form($invite); + } + # registration form + else + { + registration_form(); + } + } + +sub invite_process_user + { + my ($command, $hash, $id) = @_; + my $result = -1; + my $invite = -1; + if ($hash != -1) + { $invite = get_invite_from_hash($hash); } + elsif ($id) + { $invite = get_invite_from_id($id); } + + # new invite + if ($command eq "new") + { + $hash = generate_invite(); + $result = ($hash != -1) ? 1 : 0; + } + # approve/delete/extend invites + elsif ($command eq "approve" && $USER->{ulevel} == 3) + { $result = validate_approve($invite); } + elsif ($command eq "reject" && $USER->{ulevel} == 3) + { $result = set_invite_state($invite, $BUCKY_INVITE_REJECTED); } + elsif ($command eq "cancel" && $invite->{attest} eq $USER->{username}) + { $result = set_invite_state($invite, $BUCKY_INVITE_EXPIRED); } + elsif ($command eq "renew" && $invite->{attest} eq $USER->{username}) + { $result = set_invite_expired($invite, ($invite->{expired} + 86400*7)); } + + header("invite manager"); + menu(); + + print qq(<table width="100%" cellpadding=0 cellspacing=0 border=0>); + print qq(<tr><td align=center valign=top>\n); + + display_personal_invites($user_invites); + print "<p>"; + display_approve_list() if ($USER->{ulevel} == 3); + + print qq(</td>\n<td width="200" align=right valign=top>\n); + + invite_result_box($command, $hash, $result) if ($command != -1); + invite_create_box(); + + print qq(</td></tr></table>\n\n); + + footer(); + } + +$dbh->disconnect (); + + diff --git a/cgi-bin/localbucky.pm b/cgi-bin/localbucky.pm new file mode 100644 index 0000000..32d6e33 --- /dev/null +++ b/cgi-bin/localbucky.pm @@ -0,0 +1,70 @@ +#!/usr/bin/perl + +# Change this to point to Bucky library directory, where packages are installed +use lib "/var/www/vhosts/carbonpictures.com/bucky/lib"; + +# Change this to point to the directory of random texts +our $BUCKY_FORTUNES = "/var/www/vhosts/carbonpictures.com/bucky/fortune"; + +# Change this to point to the URL preamble for Bucky's script directory, where cgi-bin scripts are installed +BEGIN + { + our $BUCKY = "/cgi-bin/bucky"; + our $BUCKY_DB = "bucky"; + our $BUCKY_DB_CNF = "/var/www/vhosts/carbonpictures.com/.bucky.cnf"; + } + +#our $BUCKY = ""; + +our $BUCKY_NAME = 'bucky'; +our $BUCKY_SHORT_NAME = 'bucky'; +our $BUCKY_COOKIE_DOMAIN = 'carbonpictures.com'; +our $BUCKY_HOST = 'www.carbonpictures.com'; # url domain + +our $BUCKY_ADMINISTRATOR = 'jules'; +our $BUCKY_DEFAULT_BOXES = " welcome bPod radio postform hootbox photostream "; +our $BUCKY_DEFAULT_KEYWORD = 'NONE'; # default should be 'NONE' +our $BUCKY_TIMEZONE_OFFSET = 5; # correct your server's offset from GMT +our $BUCKY_DUDER_NOUN = 'duder'; # singular noun accepting courtesy 's' + +our $BUCKY_LOGIN_WELCOME = "welcome to bucky"; # welcome on login screen + +# bucky non-css colors +our $BUCKY_COLOR_HR = "#201010"; + +# /index +# presumed max number of threads to show +our $BUCKY_INDEX_LIMIT = 50; +# how many days to display under "the latest" +our $BUCKY_INDEX_LATEST = 1.78; + +our $LASTLOG_ONLY_FIRST_DAY = 0; + +our $INDEX_GALLERY_IMAGE_COUNT = 4; + +# bPod: URLs, colors +our $BPOD_URL_SERVICES_KEYWORDS = $BUCKY_HOST . "$BUCKY/services_k"; +our $BPOD_URL_SERVICES_THREADS = $BUCKY_HOST . "$BUCKY/services_th?k="; +our $BPOD_URL_SERVICES_FILES = $BUCKY_HOST . "$BUCKY/services_f?pid="; +our $BPOD_URL_PREAMBLE_FILES = $BUCKY_HOST . "/bucky/data/"; +our $BPOD_URL_DETAILS = $BUCKY_HOST . "$BUCKY/details/"; +our $BPOD_COLOR_UI_GRADIENT_1 = "0xE6F0F0"; +our $BPOD_COLOR_UI_GRADIENT_2 = "0xD8E0EC"; +our $BPOD_COLOR_UI_STROKE = "0x201010"; + +# thread url format: /details (== 0) or individually by /keyword (== 1) +our $BUCKY_KEYWORD_IN_DETAILS_URL = 0; + +our $ZIP_BUTTON_ENABLED = 1; + +# (shoutcast) radio status +our $RADIO_STATUS_ENABLED = 1; +our $RADIO_STATUS_URL = "http://radiofreehanoi.com/status"; +our $RADIO_INFO_URL = "http://radiofreehanoi.com/info"; + + +# Load bucky packages +use Bucky1; + +1; + diff --git a/cgi-bin/localbucky.pm.tmpl b/cgi-bin/localbucky.pm.tmpl new file mode 100644 index 0000000..143c192 --- /dev/null +++ b/cgi-bin/localbucky.pm.tmpl @@ -0,0 +1,54 @@ +#!/usr/bin/perl + +use Time::Stopwatch; + +# Comment out this timer to suppress page loadtime messages +tie our $timer, 'Time::Stopwatch'; + +our $BUCKY_NAME = 'king of sf'; +our $BUCKY_SHORT_NAME = 'kingofsf'; +our $BUCKY_COOKIE_DOMAIN = 'kingofsf.com'; + +our $BUCKY_ADMINISTRATOR = 'marc'; +our $BUCKY_DEFAULT_BOXES = " welcome bPod radio postform hootbox photostream "; +our $BUCKY_DEFAULT_KEYWORD = 'NONE'; # default should be 'NONE' +our $BUCKY_TIMEZONE_OFFSET = 8; # correct your server's offset from GMT + +# Change this to point to Bucky library directory, where packages are installed +use lib "/bucky/lib"; + +# Change this to point to the URL preamble for Bucky's script directory, where cgi-bin scripts are installed +our $BUCKY = "/cgi-bin/bucky"; + +# Change this to be a welcome messasge for your login screen +our $BUCKY_LOGIN_WELCOME = "welcome to kitchen hacklab, pricks"; + +# Change this to your bucky host! +our $BUCKY_HOST = "www.carbonpictures.com"; + +# bucky non-css colors +our $BUCKY_COLOR_HR = "#201010"; + +# bPod: URLs, colors +our $BPOD_URL_SERVICES_KEYWORDS = $BUCKY_HOST . "$BUCKY/services_k"; +our $BPOD_URL_SERVICES_THREADS = $BUCKY_HOST . "$BUCKY/services_th?k="; +our $BPOD_URL_SERVICES_FILES = $BUCKY_HOST . "$BUCKY/services_f?pid="; +our $BPOD_URL_PREAMBLE_FILES = $BUCKY_HOST . "/bucky/data/"; +our $BPOD_URL_DETAILS = $BUCKY_HOST . "$BUCKY/details?id="; +our $BPOD_COLOR_UI_GRADIENT_1 = "0xF8F8D7"; +our $BPOD_COLOR_UI_GRADIENT_2 = "0xF0F0E6"; +our $BPOD_COLOR_UI_STROKE = "0x201010"; + +# thread url format: /details (== 0) or individually by /keyword/ (== 1) +our $BUCKY_KEYWORD_IN_DETAILS_URL = 0; + +# Load bucky packages +use Bucky; + +# Report nicely formatted time +sub report_time + { + return sprintf("%2.2f", $timer * 1000) . "ms"; + } +1; + diff --git a/cgi-bin/login b/cgi-bin/login new file mode 100755 index 0000000..0335549 --- /dev/null +++ b/cgi-bin/login @@ -0,0 +1,86 @@ +#!/usr/bin/perl +######################################### +# login +# no input: print form +# input: set cookie, send along to index +######################################### + +if (-e "/var/www/vhosts/carbonpictures.com/bucky/lock") + { + print "Content-type: text/html\nPragma: no-cache\n\n"; + print "<center><big><b><br>" . $BUCKY_CONFIG->{BUCKY_NAME} . " is down for maintenance!<p>please check back in a bit.</b></big></center>"; + exit(0); + } + +if (! exists $ENV{'HTTPS'} || $ENV{'HTTPS'} ne "on") + { + print "Location: https://www.carbonpictures.com/cgi-bin/bucky/index\n\n"; + exit; + } +use localbucky; + +$dbh = DBI->connect ($dsn); + +# Check to see if user has supplied a username for login +if (exists($input->{username})) + { + if ($DEBUG) + { header("login"); } + + # Look up user, based on username and password + my ($USER) = auth( $input->{username}, crypt($input->{password}, lc($input->{username}) ) ); + + # No such user, or password failed, so redirect to logout + if ($USER == -1) + { print "password failed<br>\n" if $DEBUG; logout(); } + + # User successfully logged in! Update the last login time + update_lastsession( $USER->{username} ); + $USER->{lastsession} = $USER->{lastseen}; + + if ($DEBUG) + { + print "<div class=\"message\">\n"; + print "uid: $USER->{id}\n<p>username: $USER->{username}\n<p>\n"; + print "</div>\n"; + footer(); + } + + nice_redirect(); + } + +# Else, if there's an i=1 query string, redirect to adduser program +elsif (exists($input->{i}) && $input->{i} == 1) + { redirect("$BUCKY/adduser?i=1"); } + +# Else, no username, so just display the login page +else + { + header("login"); + print qq{<hr color="$BUCKY_COLOR_HR" style="padding: 0px; margin: 2px;"><br><br><br><center><div class=message>}; + + # Display any login errors + if ($input->{error} == 1) + { print "bad username/password!<br>"; } + elsif ($input->{error} == 2) + { print "illegal traversal!<br>"; } + + print "<b>$BUCKY_LOGIN_WELCOME</b>"; + print qq{</b><br>\n<hr color="$BUCKY_COLOR_HR">\n\n}; + + login_form(); + + print qq(<p>\n<small>\n); +# print qq(<a href="$BUCKY/index"><b>tour</b> the hacklab</a>); +# print qq(<p>want an account?<br><a href="$BUCKY/invite">request one</a><br>); + print qq(</small></div></center>\n\n); + + footer(); + } + +$dbh->disconnect (); +print "Login: " . &report_time() . "\n" if $timer; + + +######################################### + diff --git a/cgi-bin/logout b/cgi-bin/logout new file mode 100755 index 0000000..ac3888a --- /dev/null +++ b/cgi-bin/logout @@ -0,0 +1,12 @@ +#!/usr/bin/perl + +######################################### +# logout +# i love logging out +######################################### + +use localbucky; + +logout(); +print "Logout: " . &report_time() . "\n" if $timer; + diff --git a/cgi-bin/maintain b/cgi-bin/maintain new file mode 100755 index 0000000..007e1e3 --- /dev/null +++ b/cgi-bin/maintain @@ -0,0 +1,289 @@ +#!/usr/bin/perl +######################################### +# maintain +# - thread administration +######################################### + +use localbucky; + +our $id; +our $files; + +$dbh = DBI->connect ($dsn); + +our ($USER, $lastlog) = checkin(); +logout() unless ($USER != -1); + +$input->{id} ||= $input->{object_from_uri} if defined($input->{object_from_uri}); +if (exists($input->{id}) && $input->{id} > 0) + { $id = $input->{id}; } +elsif (exists($input->{keyword}) ) + { $keyword = $input->{keyword}; } +else + { error("No post specified."); } + +my $t = get_thread($id); +my $k = get_keyword($t->{keyword}); + +if ($t == -1) + { error("No such post."); } + +$files = get_files($t->{id}); +$comments = get_comments($t->{id}); + +#my ($participation) = check_participation($files, $comments); +my ($participation) = 0; + +if (exists($input->{c}) && $input->{c} eq "zip") + { + if ($t->{zipped} == 0) + { + my $cleantitle = generate_zip_filename($t); + update_thread_zipped($t->{id}, -1); + $t->{zipped} = -1; + system(qq!$NOHUP_PATH $ZIP_PATH -jr "$data_path/$t->{id}/$cleantitle" $data_path/$t->{id}/* >$temp_path/.zip.out -x "$cleantitle" 2>&1 &!); + redirect("$BUCKY/".details_link($t)."/$t->{id}"); + } + elsif ($t->{zipped} == 1) + { + my $cleantitle = generate_zip_filename($t); + update_thread_zipped($t->{id}, -1); + $t->{zipped} = -1; + system(qq!$NOHUP_PATH $ZIP_PATH -jr "$data_path/$t->{id}/$cleantitle" $data_path/$t->{id}/* >$temp_path/.zip.out -x "$cleantitle" 2>&1 &!); + redirect("$BUCKY/".details_link($t)."/$t->{id}"); + } + } +elsif ($t->{username} eq $USER->{username} || check_op($k) || $participation == 2 || (check_key($t->{display}, "opset") && check_privacy($t, $k)) || $USER->{ulevel} == 3) + { + header( { + title => "settings for \"$t->{title}\"", + subtitle => qq!posted by <a href="$BUCKY/profile/$t->{username}">$t->{username}</a> on ! . + (verbosedate($t->{createdate})) . + qq! · <span class="lite"><a href="$BUCKY/!.details_link($t).qq!/$t->{id}">view post</a></span>!, + color => get_color($t, $k) + } ); + menu(); + if (exists($input->{c})) + { + if ($input->{c} eq "display") + { + if ($t->{title} ne $input->{title}) + { + update_thread_title($t->{id}, $input->{title}); + $t->{title} = $input->{title}; + print "Changed title to: <b>$t->{title}</b><br>\n"; + } + + if (($t->{color} ne $input->{color}) && is_color($input->{color})) + { + update_thread_color($t->{id}, $input->{color}); + $t->{color} = $input->{color}; + print "Set color to: <b>$t->{color}</b><br>\n"; + print qq(<link rel="stylesheet" href="/css/bogart/$t->{color}.css">); + } + + my (@display) = qw[hoot ren "no-upload" shorturl editable opset "no-zip-button" hidekws]; + my $newdisplay = ' '; + foreach my $key (@display) + { + if (exists($input->{$key}) && $input->{$key} == 1) + { $newdisplay = add_key($newdisplay, $key); } + } + if ($input->{filelist} == 2) + { $newdisplay = add_key($newdisplay, "ffl"); } + if ($input->{filelist} == 0) + { $newdisplay = add_key($newdisplay, "nfl"); } + + if ($t->{display} ne $newdisplay) + { + update_thread_display($t->{id}, $newdisplay); + $t->{display} = $newdisplay; + print "New display settings: <b>$t->{display}</b><br>\n"; + } + + # touch_thread($t); + admin_form($t->{id}, $t, $files, $k); + } + elsif ($input->{c} eq "p") + { + if ($input->{private} == 2) + { + print "Thread is now <b>" . $BUCKY_CONFIG->{PRIVACY_OWNER} . "</b>.<br>"; + switch_thread_privacy($t->{id}, 2); + $t->{allowed} = update_whitelist(); + $t->{private} = 2; + } + elsif ($input->{private} == 1) + { + print "Thread is now viewable by <b>" . $BUCKY_CONFIG->{PRIVACY_BBS} || "other users" . "</b>.<br>"; + switch_thread_privacy($t->{id}, 1); + $t->{allowed} = update_whitelist(); + $t->{private} = 1; + } + else + { + print "Thread is now viewable by <b>" . $BUCKY_CONFIG->{PRIVACY_WORLD} . "</b>.<br>"; + switch_thread_privacy($t->{id}, 0); + $t->{private} = 0; + } + admin_form($t->{id}, $t, $files, $k); + } + # change tags + elsif ($input->{c} eq "t") + { + my $new_tags = 0; + if ($input->{tags} ne $input->{tags_saved}) + { + print "Changed Tag to " . $input->{tags} . "<br>" if ($DEBUG); + # First: add new tags + my $tags = get_tags_from_string( $input->{tags} ); + foreach my $tag (@$tags) + { + print "Assigning tag $tag<br>\n" if ($DEBUG); + print tag_assign_mechanism( $tag, $t ) || ""; + $new_tags++; + } + + # Second: remove deleted tags + my $old_tags = get_tags_from_string( $input->{tags_saved} ); + foreach my $old_tag (@$old_tags) + { + # If the new tags list does not contain this old tag, remove it + if ( ! grep ( /^$old_tag$/, @$tags ) ) + { + print tag_remove_mechanism( $old_tag, $t ) || ""; + $new_tags++; + } + } + } + # touch_thread($t); + $t = get_thread( $t->{id} ) if $new_tags; + admin_form($t->{id}, $t, $files, $k); + } + elsif ($input->{c} eq "f") + { + my @flagged = corral($input, "file"); + if ($DEBUG) + { + print "<br>\nfiles flagged: "; + foreach (@flagged) + { print; print " "; } + print "<br>\n"; + } + if ($input->{verb} eq "flag") + { + print "Flagged file $flagged[0]<br>"; + update_flagged($t->{id}, $flagged[0]); + $t->{flagged} = $flagged[0]; + touch_thread($t); + admin_form($t->{id}, $t, $files, $k); + } + elsif ($input->{verb} eq "move") + { + print "When this works it will be like this:!<br>\n"; + print "Where do you want to move these files here<br>\n"; + print "Moving files...<br>\n"; + # system("mv", $data_path/$oldpid/$filenamea ..., "$data_path/$newpid/"); + print "Moving ids...<br>\n"; + print "Recalculating post sizes...<br>\n"; + } + elsif ($input->{verb} eq "rm") + { + if (!$input->{ok}) + { + print qq(<center><p><div class="bluebox" style="width: 320px; padding: 10px;"><big><b>Are you sure you want to delete these files?</b></big><hr noshade color="$BUCKY_COLOR_HR"><p>\n); + print qq(<form action="$BUCKY/maintain" method="post" enctype="multipart/form-data">); + print qq(<input type=hidden name="c" value="f">\n); + print qq(<input type=hidden name="id" value="$t->{id}">\n); + print qq(<input type=hidden name="debug" value="1">\n) if ($DEBUG); + print qq(<input type=hidden name="verb" value="rm">\n); + print qq(<input type=hidden name="ok" value="1">\n); + + my $i = 0; + my $fid = shift(@flagged); + foreach my $fh (sort_by_id(@$files)) + { + next if ($fid != $fh->{id}); + $i++; + + print qq{<input type=hidden name="file$fid" value="$fid">\n}; + print $fh->{id}.": " if ($DEBUG); + print $fh->{filename}."<br>\n"; + + $fid = shift(@flagged); + } + + print qq{<br><input type="submit" value="YES YES DELETE THE FILES" class="clicky"></form></div></center>}; + } + else + { + my $i = 0; + my $fid = shift(@flagged); + foreach my $fh (sort_by_id(@$files)) + { + next if ($fid != $fh->{id}); + $i++; + + next if -d qq!$data_path/$t->{id}/$$fh{filename}!; + delete_file_record($fid); + system($RM_PATH, "-f", qq!$data_path/$t->{id}/$$fh{filename}!); + system($RM_PATH, "-f", qq!$data_path/$t->{id}/.thumb/s.$$fh{filename}!); + system($RM_PATH, "-f", qq!$data_path/$t->{id}/.thumb/t.$$fh{filename}!); + system($RM_PATH, "-f", qq!$data_path/$t->{id}/.thumb/b.$$fh{filename}!); + print qq!deleted $$fh{filename}<br>\n!; + + $fid = shift(@flagged); + } + + print "Recalculating post size...<br>\n"; + update_thread_size($t->{id}); + $files = get_files($t->{id}); + touch_thread($t); + admin_form($t->{id}, $t, $files, $k); + } + } + } + elsif ($input->{c} eq "clobber") + { + if ($input->{okay}) + { + delete_thread($t->{id}); + print qq!<br><br><center><table width=400 border=0 cellpadding=0 cellspacing=0><tr><td class="bluebox" style="padding: 20px;"><big><b>POST DELETED\!</b></big></td></tr></table></center>\n!; + } + else + { + my $fs = $t->{files} != 1 ? "s" : ""; + my $cs = $t->{comments} != 1 ? "s" : ""; + my $par = get_participation($t->{id}); + my $ps = $par != 1 ? "s" : ""; + print qq(<br><br><center><table width=350 border=0 cellpadding=0 cellspacing=0><tr><td class="bluebox" style="padding: 10px;">); + print qq(<big>Are you <b>sure</b> you want to delete:<br>$t->{title}</big><br><br>); + print qq(Doing so will delete <b>$t->{files} file$fs</b> and <b>$t->{comments} comment$cs</b>,<br>); + print qq(<b>destroying</b> the hard work of $par duder$ps\!<br>); + print qq(<br>); + print qq(<form action="$BUCKY/maintain" method="post" enctype="multipart/form-data">\n); + print qq(<input type=hidden name="debug" value="1">\n) if ($DEBUG); + print qq(<input type=hidden name="id" value="$t->{id}">\n); + print qq(<input type=hidden name="c" value="clobber">\n); + print qq(<input type=hidden name="okay" value="1">\n); + print qq(<center><table cellpadding=0 cellspacing=10 border=0><tr><td><input type="submit" value="OKAY" class="clicky"></form></td><td><input type="button" value="ABORT" class="clicky" onclick=")."javascript: history.go(-1)".qq("></td></tr></table></center>); + + print qq!</td></tr></table></center>!; + } + } + } + else + { + admin_form($t->{id}, $t, $files, $k); + } + footer(); + } +else + { + error("Unable to access $id!"); + } + +sub sort_by_username { sort { lc($a->{username}) cmp lc($b->{username}) } @_; } +sub sort_by_id { sort { $a->{id} <=> $b->{id} } @_; } + +print "Maintain: " . &report_time() . "\n" if $timer; diff --git a/cgi-bin/message b/cgi-bin/message new file mode 100755 index 0000000..08c0968 --- /dev/null +++ b/cgi-bin/message @@ -0,0 +1,149 @@ +#!/usr/bin/perl +######################################### +# message +# - deal with message reading/sending +######################################### + +use localbucky; + +$dbh = DBI->connect ($dsn); + +our ($USER, $lastlog) = checkin(); +logout() unless ($USER != -1); + +$input->{username} ||= $input->{object_from_uri} if defined($input->{object_from_uri}); +if ($$input{c} eq "s") + { + my $subject; + my $recip = lc($$input{recipient}); + my $box; + my $out; + + # send message: take input, check on it, add to db + if (!exists($$input{recipient}) || !exists($$input{body})) + { error("Missing one or more fields!"); } + if ($recip eq "system") + { $recip = "marc"; } + if (get_uid($recip) == -1) + { error("No such user $recip!"); } + if (length($input->{subject}) == 0) + { + # no subject so obviously we have to supply something retarded + @subjects = ("sup duder", "WHAUT UP DWIZLINKA", "HAPPY BIG CHAVYO WILVERFAO?", "NO DUM bB SUXCER Ylo TWIENF", "fararyY*F**YFARRRRADAYY+++", "i doINT BELIEVE YOYU!&U#*&!", "fuckN TEHAS D", "YO WHAT UP DOGGIE", "SENdiN BUcKY MeZSaGeZ", "SALWE"); + $subject = $subjects[(int rand @subjects)] + } + else + { $subject = $$input{subject}; } + + my %newmsg = (sender => $USER->{username}, recipient => $recip, unread => 1, subject => $subject, body => $$input{body}); + + if (exists($input->{later})) + { + header("saving draft"); + menu(); + $box = "drafts"; + $newmsg{unread} = 0; + if (exists($input->{oldid})) + { + update_message($input->{oldid}, \%newmsg); + } + else + { + new_message("$USER->{username}.$box", \%newmsg); + } + + $out = "SAVED AS DRAFT"; + } + else + { + header("sending message"); + menu(); + new_message("$recip.inbox", \%newmsg); + + $box = "outbox"; + $newmsg{unread} = 0; + new_message("$USER->{username}.$box", \%newmsg); + $out = "MESSAGE SENT"; + + if (exists($$input{oldid})) + { + delete_message($$input{oldid}); + recount_mailbox("$USER->{username}.drafts"); + } + } + + print qq!<p><center><div class=message><big><br><b>$out</b><br><br><a href="$BUCKY/inbox/$box">return to $box</a><br><br></big></div></center>!; + footer(); + } + +elsif ($$input{c} eq "r") # reply to message + { + $message = get_message($$input{id}); + if ($message == -1) + { error("No such message."); } + elsif ($$message{recipient} ne $USER->{username} && $$message{sender} ne $USER->{username}) + { error("You do not own this message."); } + if ($$message{mbox} =~ /drafts/) + { + header("edit message"); + menu(); + message_form($$message{recipient}, $message); + } + else + { + header("reply to message"); + menu(); + message_form($$message{sender}, $message); + } + footer(); + } + +elsif ($$input{c} eq "d") # delete message + { + if ($DEBUG) + { + header("deleting message"); + menu(); + print "Deleting message $$input{id}"; + } + my $box = process_delete($$input{id}); + if ($DEBUG) + { footer(); } + else + { + $box =~ s/^$USER->{username}.//; + redirect("$BUCKY/inbox/$box"); + } + } + +else # new message: display form + { + my $recipient; + if (exists($$input{username})) + { $recipient = $$input{username}; } + else + { $recipient = ""; } + header("new message"); + menu(); + message_form($recipient, -1); + footer(); + } + +$dbh->disconnect (); + +sub process_delete + { + my ($mid) = (@_); + my $message; + if (!defined($mid)) + { error("No id specified!"); } + $message = get_message($mid); + if ($message == -1) + { error("No such message."); } + elsif ($$message{recipient} ne $USER->{username}) + { error("You do not own this message."); } + delete_message($mid); + recount_mailbox($$message{mbox}); + return $$message{mbox}; + } +print "Message: " . &report_time() . "\n" if $timer; diff --git a/cgi-bin/murder b/cgi-bin/murder new file mode 100755 index 0000000..356cf5d --- /dev/null +++ b/cgi-bin/murder @@ -0,0 +1,23 @@ +#!/usr/bin/perl +######################################### +# not bless +######################################### + +use localbucky; + +$dbh = DBI->connect ($dsn); + +our ($USER, $lastlog) = checkin(); +logout() unless ($USER != -1); + +my $blessy = $input->{username}; +if (get_uid($blessy) == -1) + { error("no such user"); } +elsif ($blessy eq $USER->{username}) + { error("THE GUN JAMS"); } +commit_murder($blessy); +add_comment(1,-1,"system","BUT WHAT WILL WE DO WITH THE BODY"); +redirect("$BUCKY/index"); + +$dbh->disconnect (); + diff --git a/cgi-bin/playlist b/cgi-bin/playlist new file mode 100755 index 0000000..9b87d6a --- /dev/null +++ b/cgi-bin/playlist @@ -0,0 +1,81 @@ +#!/usr/bin/perl + +use localbucky; +use URI::Escape; + +$dbh = DBI->connect ($dsn); + +our ($USER, $lastlog) = checkin(); +our $loggedin = ($USER != -1); + +our ($t, $kw, $files) = playlist_init(); +playlist_run($t, $kw, $files); + +sub playlist_run + { + my ($t, $kw, $files) = @_; + my $sorty = sub { sort {lc($a->{filename}) cmp lc($b->{filename})} @_ }; + + my $z_title = $t->{title}; + my $z_link = qq($BUCKY/).details_link().qq(/$t->{id}); + $z_link .= get_revision($t) if ($USER != -1); + + my $rss = <<__RSS__; +<rss version="2.0" xmlns:media="http://"> +<channel> +<title>$z_title</title> +<link>$z_link</link> +__RSS__ + + foreach my $file ($sorty->(@$files)) + { + next if (($file->{username} ne $USER->{username}) && $file->{private} && !$whitelist && $USER->{ulevel} != 3); + next unless ($file->{filename} =~ /mp3$/i); + my $z_file = $file->{filename}; + my $z_filepath = uri_escape($file->{filename}); + my $z_content = "https://$BUCKY_HOST$live_path/$file->{thread}/$z_filepath"; + $rss .= <<__RSS__; +<item> +<title>$z_file</title> +<link>$z_content</link> +<description></description> +<media:content url="$z_content" type="audio/mpeg" /> +</item> +__RSS__ + } + + $rss .= "</channel>\n</rss>\n"; + + print "Content-type: text/xml\n\n"; + $rss =~ s/&/&/g; + print $rss; + } + +sub playlist_init + { + $input->{id} ||= $input->{object_from_uri} if defined($input->{object_from_uri}); + my $id = exists($input->{id}) ? $input->{id} : error("No such thread!"); + + my $t = get_thread($id); + error("No such post.") if ($t == -1); + my $kw = get_keyword($t->{keyword}); + + my $files = get_files($t->{id}); +# my $comments = get_comments ($t->{id}); + + if ( ! check_privacy($t, $kw) ) # || check_participation($files, $comments) ) + #unless ( check_privacy($t, $kw) || check_participation($files, $comments) ) + { error("No such post!"); } + + # Reset NULL viewed + if ( ! $t->{viewed} ) + { $t->{viewed} = 0; } + + # Increment viewed for this thread +# $t->{viewed}++; + # Update thread viewed count +# update_thread_viewed( $t->{id}, $t->{viewed} ); + + return ($t, $kw, $files); # $comments); + } + diff --git a/cgi-bin/post b/cgi-bin/post new file mode 100755 index 0000000..fd2de78 --- /dev/null +++ b/cgi-bin/post @@ -0,0 +1,267 @@ +#!/usr/bin/perl +######################################### +# post +# - create a new thread/post from an initial file +# - form: append multiple files +######################################### + +use localbucky; + +my $pid; + +$dbh = DBI->connect ($dsn); + +our ($USER, $lastlog) = checkin(); +logout() unless ($USER != -1); + +if ($input->{c} eq 'new') + { new_post_action(); } +elsif ($input->{c} eq 'reply') + { reply_post_action(); } +else + { long_post_form(); } + +################################# + +sub long_post_form + { + my $t = -1; + my $k = -1; + if ( exists($input->{thread}) ) + { + my $header_args; + + $t = get_thread( $input->{thread} ); + $k = get_keyword( $t->{keyword} ); + + error("No such post!") unless ($t != -1); + error("No such keyword!") unless ($k == -1 || ($k->{public} || check_op($k))); + + $header_args->{title} = qq(reply to $t->{title}); + $header_args->{subtitle} = qq(<span class="lite"><a href="$BUCKY/).details_link($t).qq($t->{id}">return to post</a></span>); + + header ($header_args); + } + elsif ( exists($input->{keyword}) ) + { + my $header_args; + + $k = get_keyword( $input->{keyword} ); + + if ($k != -1 && (($k->{public} || check_op($k)))) + { + $header_args->{title} = qq(new $k->{keyword}); + $header_args->{subtitle} = qq(<span class="lite"><a href=").keyword_link($k).qq(">return to $BUCKY_LEXICON_KEYWORD</a></span>); + header ($header_args); + } + else + { + header("Creating a new post..."); + } + } + else + { + header("Creating a new post..."); + } + + menu(); + print "<p>\n\n"; + my $checked = ''; + + print qq(<form action="$BUCKY/post" method="post" enctype="multipart/form-data">\n); + print qq!<input type="hidden" name="debug" value="$DEBUG">\n\n! if ($DEBUG); + + print <<FORMmid; +<center> +<table cellpadding=0 cellspacing=0 border=0> +<tr><td class="bluebox" style="padding: 20px 40px 20px 40px;"> +FORMmid + + if ($t != -1) + { + print qq!<input type="hidden" name="c" value="reply">!; + print qq!<input type="hidden" name="thread" value="$t->{id}">!; + print qq!<table border=0 width=100%><tr><td style="text-align: right; vertical-align: center;">replying to:</td><td align="center"><b><big><a href="$BUCKY/!.details_link($t).qq!/$t->{id}">$t->{title}</a></big></b><br>posted !.verbosedate($t->{createdate}).qq! by <a href="$BUCKY/profile/$t->{username}">$t->{username}</a></td></tr></table>!; + } + else + { + print qq!<table cellpadding=2 border=0>!; + print qq!<tr><td align="right" valign="baseline">!; + print qq!title: !; + print qq!</td><td align="left" valign="baseline">!; + print qq!<input name="title" value="" size=48 maxlength=48><br>\n!; + print qq!</tr>!; + print qq!<tr><td align="right" valign="baseline">!; + print "category: "; + print qq!</td><td align="left" valign="baseline">!; + if ($k->{public} || check_op($k)) + { + keyword_pulldown($k->{keyword}); + $checked = $k->{public} ? "" : " checked"; + } + else + { keyword_pulldown(); } + print qq!</tr>!; + print qq!<tr><td align="right" valign="baseline">!; + print qq!tags: !; + print qq!</td><td align="left" valign="baseline">!; + print qq!<input name="tags" value="" size=30 maxlength=48><br>\n!; + print qq!</tr>!; + print qq!<tr><td align="right" valign="middle">!; + print qq!publicity:!; + print qq!</td><td align="left" valign="middle">!; + # don't need this + # print qq!<input type=checkbox name="private" value="1"$checked>! + privacy_select("private", $checked); + print qq!</td></tr>!; + print qq!<tr><td></td><td align="left" valign="top">!; + print qq!<small>(can be changed at any time via post settings)</small>\n!; + print qq!</td></tr>!; + print qq!<tr><td align="right" valign="baseline">!; + print qq!</table>!; + print qq!<input type="hidden" name="c" value="new">!; + } + + print qq!<hr color="$BUCKY_COLOR_HR" size=1>!; + print qq!<p><textarea name="comment" cols="52" rows="16"></textarea><p>\n!; + + if (! check_key($t->{display}, "no-upload")) + { + print <<FORMEND; +<input type="file" name="file1" size="12" maxlength="192" style="font-size: 10px; font-family: Trebuchet MS, Helvetica, Arial, sans-serif;" /> <input type="file" name="file2" size="12" maxlength="192" style="font-size: 10px; font-family: Trebuchet MS, Helvetica, Arial, sans-serif;" /> <input type="file" name="file3" size="12" maxlength="192" style="font-size: 10px; font-family: Trebuchet MS, Helvetica, Arial, sans-serif;" /><br> +<input type="file" name="file4" size="12" maxlength="192" style="font-size: 10px; font-family: Trebuchet MS, Helvetica, Arial, sans-serif;" /> <input type="file" name="file5" size="12" maxlength="192" style="font-size: 10px; font-family: Trebuchet MS, Helvetica, Arial, sans-serif;" /> <input type="file" name="file6" size="12" maxlength="192" style="font-size: 10px; font-family: Trebuchet MS, Helvetica, Arial, sans-serif;" /><br> +<input type="file" name="file7" size="12" maxlength="192" style="font-size: 10px; font-family: Trebuchet MS, Helvetica, Arial, sans-serif;" /> <input type="file" name="file8" size="12" maxlength="192" style="font-size: 10px; font-family: Trebuchet MS, Helvetica, Arial, sans-serif;" /> <input type="file" name="file9" size="12" maxlength="192" style="font-size: 10px; font-family: Trebuchet MS, Helvetica, Arial, sans-serif;" /><p> +FORMEND + } + print qq(<table cellpadding=0 cellspacing=0 border=0 width=100%><tr><td width=90% align="center"><small>); +# if ($t != -1) +# { print qq(remember! you can always use <a href="$BUCKY/import?id=$t->{id}"><u><b>ftp</b></u></a> to upload files . . .); } +# else +# { print qq(remember! you can always use <a href="$BUCKY/import"><u><b>ftp</b></u></a> to upload files . . .); } + print " "; + print <<FORMEND; +</small></td> +<td align="left"><input type="submit" value="POST" class="clicky"></td></tr></table> +</form> +</td></tr></table> +</center> +FORMEND + footer(); + } + +sub new_post_action + { + my $files; + my $title = ''; + my $private = 0; + my $k; + + $k = get_keyword($input->{keyword}) if (exists($input->{keyword}) && ($input->{keyword} ne "NONE")); + + if ($input->{title}) + { + $title = $input->{title}; + $title =~ s/^\s+//; + $title =~ s/\s+/ /g; + $title =~ s/_/ /g; + } + else + { + for (my $i = 1; $i < 10; $i++) + { + if ($input->{"file".$i} ne "temp_") + { + $title = $input->{"file".$i}; + $i = 11; + } + } + if ($title) + { + $title =~ s/^temp_//i; + $title =~ s/\.....?$//; + $title =~ s/^\s+//; + $title =~ s/\s+/ /g; + $title =~ s/_/ /g; + } + elsif ($$input{"comment"}) + { + $title = "dER buCKYiSt ***cHaTTEN**** AUF ZZem *AwL**"; + } + else + { + error ("No title specified!"); + } + } + + if ($DEBUG) + { + header("new post"); + print "attempting to make a new post: $title<p>"; + } + + $private = $input->{private} if ($input->{private}); + + $thread_id = add_thread($title, $USER->{username}, $private); + print "id: $thread_id<p>" if ($DEBUG); + add_comment($thread_id,-1,$USER->{username},$$input{comment}); + situate_files($thread_id, $USER->{username}); + switch_thread_privacy($thread_id, $private); + if ($k->{public} || check_op($k)) + { + keyword_assign_mechanism($k->{keyword}, $thread_id, $k); + } + + # Check for any supplied tags + if (exists($input->{tags}) && (length(trim($input->{tags}) ) > 0) ) + { + # Unpack tags from the form text field (remove delimiters, retrieve already existing tags, + # create new tags + my $tags = get_tags_from_string( $input->{tags} ); + + # Loop through each tag + foreach my $tag (@$tags) + { + # should we even get this?? +# next unless ($tag->{public} || check_op($tag)); + + # Associate this tag with this thread + tag_assign_mechanism( $tag, $thread_id ); + } + } + + if ($DEBUG) + { + print qq{this way to your new post: <a href="$BUCKY/details/$thread_id">link!</a>}; + footer(); + } + + if ($k != -1) + { + redirect("$BUCKY/".details_link($k)."/$thread_id"); + } + else + { + redirect("$BUCKY/$BUCKY_LEXICON_DETAILS/$thread_id"); + } + } + +sub reply_post_action + { + if ($DEBUG) + { + header("posting to $input->{thread}"); + } + my $thread = (exists($input->{thread})) ? get_thread($input->{thread}) : error("No such thread!"); + my $keyword = ($thread->{keyword}) ? get_keyword($thread->{keyword}) : -1; + error("Cannot see comment!") unless (check_privacy($thread) || check_op($keyword)); + + print "id: $thread->{id}<p>" if ($DEBUG); + add_comment($thread->{id}, -1, $USER->{username}, $input->{comment}) if ($input->{comment} ne undef); + situate_files($thread->{id}, $USER->{username}); + switch_thread_privacy($thread->{id}, $thread->{private}); + redirect("$BUCKY/".details_link($thread)."/$thread->{id}"); + } + +$dbh->disconnect (); + +print "Post: " . &report_time() . "\n" if $timer; diff --git a/cgi-bin/profile b/cgi-bin/profile new file mode 100755 index 0000000..93dc089 --- /dev/null +++ b/cgi-bin/profile @@ -0,0 +1,167 @@ +#!/usr/bin/perl +######################################### +# profile +# maintain a user's profile +# or print a form +######################################### + +use localbucky; + +my $pid; + +$dbh = DBI->connect ($dsn); + +our ($USER, $lastlog) = checkin(); +our $loggedin = ($USER != -1); + +sub main + { + $input->{username} ||= $input->{object_from_uri} if defined($input->{object_from_uri}); + my ($keywords) = get_keywords(); + + if (exists($input->{c}) && $input->{c} eq "sticky" && defined($input->{keyword})) + { + logout() unless ($loggedin); + my $keyword = $input->{keyword}; + print "Switching keyword $keyword for $USER->{username} ..." if ($DEBUG); + my $stkcy = check_key($keyword, $USER->{stickies}); + my $newk; + if (exists($input->{chexor})) + { $newk = add_key($USER->{stickies}, $keyword); } + else + { $newk = delete_key($USER->{stickies}, $keyword); } + update_user_sticky($USER->{username}, $newk); + redirect("$BUCKY/index"); + } + elsif (exists($input->{username})) + { + if ($USER->{username} eq $input->{username}) + { + header( { + title => "profile for $input->{username}", + subtitle => qq!<a href="$BUCKY/profile?c=form">edit your profile</a>! + } ); + } + elsif ($input->{username} eq "system") + { + $input->{username} = "marc"; + header("profile for $input->{username}"); + } + elsif (get_uid($input->{username}) == -1) + { nice_redirect(); } + else + { header("profile for $input->{username}"); } + menu(); + show_profile($input->{username}); + } + elsif ($input->{c} eq 'form') + { + logout() unless ($loggedin); + header( { + title => "editing $USER->{username}'s profile", + subtitle => qq!<a href="$BUCKY/profile">view your profile</a>! + } ); + + menu(); + profile_form($USER->{username}); + } + elsif ($input->{c} eq 'update') + { + logout() unless ($loggedin); + my $messages = ''; + if (exists($input->{rmpic}) && $input->{rmpic} == 1) + { + system("rm", "-f", "$data_path/profile/$USER->{username}.jpg"); + system("rm", "-f", "$data_path/profile/.thumb/$AVATAR_PROFILE_PREFIX$USER->{username}.jpg"); + system("rm", "-f", "$data_path/profile/.thumb/$AVATAR_BIG_PREFIX$USER->{username}.jpg"); + system("rm", "-f", "$data_path/profile/.thumb/$AVATAR_MED_PREFIX$USER->{username}.jpg"); + $messages .= "old profile image deleted<br>\n"; + } + if (exists($input->{pw1}) && exists($input->{pw2}) && $input->{pw1} && $input->{pw2}) + { + if ($input->{pw1} eq $input->{pw2}) + { + update_password($USER->{username}, crypt($input->{pw1},lc($USER->{username}))); + $messages .= qq(password changed -- please <a href="/bucky/">log back in</a><br>\n); + } + else + { + $messages .= "passwords don't match!<br>\n"; + } + } + if (exists($input->{stickies})) + { + my $s; + $input->{stickies} =~ s/[^A-Za-z0-9 ]//; + foreach my $k (split / /, $input->{stickies}) + { + next unless ($keywords->{$k}); + $s = add_key($s, lc($k)); + } + $input->{stickies} = $s; + } + if (exists($input->{sink})) + { + my $s; + $input->{sink} =~ s/[^A-Za-z0-9 ]//g; + foreach my $k (split / /, $input->{sink}) + { + next unless ($keywords->{$k}); + $s = add_key($s, lc($k)); + } + $input->{sink} = $s; + } + + my (@boxes) = qw[welcome bPod radio postform hootbox photostream autoplay showhidden nologout]; + my $newboxes = ' '; + foreach my $key (@boxes) + { + if (exists($input->{$key}) && $input->{$key} == 1) + { $newboxes = add_key($newboxes, $key); } + } + if ($USER->{boxes} ne $newboxes) + { + update_user_boxes($USER->{username}, $newboxes); + $USER->{boxes} = $newboxes; + $messages .= "New box settings: <b>$USER->{boxes}</b><br>\n" if ($DEBUG); + } + + if ($loggedin && update_profile($USER->{username}, $input)) + { + $USER->{timezone} = $input->{timezone}; + $dateoffset = -1; + $messages .= "profile updated<br>" + } + if ($loggedin && update_profile_image($USER->{username})) + { + $messages .= "profile image updated<br>"; + } + + header( { + title => "updating profile...", + subtitle => qq!<a href="$BUCKY/profile?c=form">edit your profile</a>! + } ); + menu(); + print qq(<div style="padding: 30px;"><div class="bluebox">$messages); + print qq(</div></div><hr color="$BUCKY_COLOR_HR" style="padding: 0px; margin: 2px;">); + show_profile($USER->{username}); + } + else + { + logout() unless ($loggedin); + header( { + title => "profile for $USER->{username}", + subtitle => qq!<a href="$BUCKY/profile?c=form">edit your profile</a>! + } ); + menu(); + show_profile($USER->{username}); + } + + footer(); + } + +main(); + +$dbh->disconnect (); + +print "Profile: " . &report_time() . "\n" if $timer; diff --git a/cgi-bin/recipe b/cgi-bin/recipe new file mode 100755 index 0000000..4f134c0 --- /dev/null +++ b/cgi-bin/recipe @@ -0,0 +1,148 @@ +#!/usr/bin/perl + +use localbucky; +use JSON; + +$dbh = DBI->connect ($dsn); + +# our ($USER, $lastlog) = checkin(); +# our $loggedin = ($USER != -1); + +recipe_run(); + +my $VALID_RECIPE_FIELDS = {}; +foreach my $field (qw[ title tags time cost skill servings calories equipment source ]); + { $VALID_RECIPE_FIELDS->{$field} = 1; } + +sub recipe_run + { + our ($t, $kw, $files, $comments) = recipe_init(); + + my $recipe; + my $title = $t->{'title'}; + + FIND_RECIPE: + { + foreach my $comment (@$comments) + { + $recipe = parse_comment_into_recipe($comment, $title); + if (is_valid_recipe_object($recipe) + { + last FIND_RECIPE; + } + } + print "Content-type: text/plain\n\n"; + print "No recipe found!" + exit; + } + + my ($many_jpgs, $flagged) = find_jpeg_v2($files, $t->{flagged}); + if ($flagged != -1) + { + my $uri = "$live_path/"; + $uri .= $flagged->{thread}; + $uri .= "/.thumb/s."; + $uri .= lc($flagged->{filename}) + $recipe->{'img'} = "https://www.carbonpictures.com$uri"; + } + + my $json = new JSON; + print "Content-type: application/json\n\n"; + print $json->pretty->encode($recipe); + } + +sub recipe_init + { + $input->{id} ||= $input->{object_from_uri} if defined($input->{object_from_uri}); + my $id = exists($input->{id}) ? $input->{id} : error("No such thread!"); + + my $t = get_thread($id); + error("No such post.") if ($t == -1); + my $kw = get_keyword($t->{keyword}); + + my $files = get_files($t->{id}); + my $comments = get_comments ($t->{id}); + + if ( ! check_privacy($t, $kw) ) # || check_participation($files, $comments) ) + #unless ( check_privacy($t, $kw) || check_participation($files, $comments) ) + { error("No such post!"); } + + return ($t, $kw, $files, $comments); + } + +sub is_valid_recipe_object + { + my ($recipe) = @_; + if ( exists($recipe->{'ingredients'}) && exists($recipe->{'directions'}) ) + { return 1; } + else + { return 0; } + } +sub parse_comment_into_recipe + { + my ($comment, $title) = @_; + my $recipe = {}; + $recipe->{'chef'} = { name => $comment->{'username'} }; + my @lines = split "\n", $comment->{'comment'}; + my $last_line_was_ingredient = 0; + my $last_line_was_direction = 0; + foreach my $line (@lines) + { + chomp $line; + # key/value instruction + if (! length($line) ) + { + $last_line_was_ingredient = 0; + $last_line_was_direction = 0; + next; + } + elsif ($line =~ /: /) + { + my ($key, $value) = split ": ", $line; + if (exists( $VALID_RECIPE_FIELDS->{$key} ) + { $recipe->{$key} = $value; } + } + # direction + elsif ($line =~ /^(\d+\.|\-+|\*+)\s?/ || $last_line_was_direction) + { + my $bullet = $1; + $line =~ s/^$bullet//; + $last_line_was_direction = 1; + $recipe->{'directions'} ||= []; + push @{ $recipe->{'directions'} }, { display => $line }; + } + # ingredient + elsif ($line =~ /^\d/ || $last_line_was_ingredient) + { + $recipe->{'ingredients'} ||= []; + push @{ $recipe->{'ingredients'} }, { display => $line }; + $last_line_was_ingredient = 1; + } + else + { + if (! exists($recipe->{'name'}) && $line !~ /[^A-Z0-9 -]/) + { + $recipe->{'name'} = capitalize($line); + } + elsif (!exists( $recipe->{'ingredients'} )) + { + $recipe->{'notes'} ||= {}; + $recipe->{'notes'}->{'intro'} .= $line; + } + else + { + $recipe->{'directions'} ||= []; + push @{ $recipe->{'directions'} }, { display => $line }; + } + } + } + $recipe->{'name'} ||= $title; + return $recipe; + } +sub capitalize + { + my ($self, $match) = @_; + $match =~ s/([\w']+)/\u\L$1/g; + return $match; + } + diff --git a/cgi-bin/services_f b/cgi-bin/services_f new file mode 100755 index 0000000..ba51e4d --- /dev/null +++ b/cgi-bin/services_f @@ -0,0 +1,83 @@ +#!/usr/bin/perl +######################################### +# services_f +# feeds bPod the file list for a valid thread +######################################### + +use localbucky; + +$dbh = DBI->connect ($dsn); + +our $KWAREZ = $BUCKY_CONFIG->{BPOD_SERVICES_WAREZ_DIR}; + +our ($USER, $lastlog) = checkin(); + +our $logged_in = ($USER != -1); + +# this start/end shit is all broken anyway +#my $start = $input->{s}; +#my $end = $input->{e}; +my $pid = $input->{pid}; + +print "Content-type: text/html\r\n\r\n"; + +my $thread = get_thread( $pid ); +my $keyword = get_keyword( $thread->{keyword} ); +exit unless check_privacy( $thread, $keyword ); + +my $files = get_files( $pid ); + +my $numItems = @$files; + +my $returnString = " &numItems=" . ($numItems ); + +@$files = sort{ lc($a->{filename}) cmp lc($b->{filename}) } @$files; + +my $fileCount = 0; +foreach my $file_row (@$files) + { + $returnString .= "&filetype$fileCount=" . fileEXT($file_row->{filename}); + $returnString .= "&filename$fileCount=" . lc($file_row->{filename}); + $returnString .= "&username$fileCount=" . $file_row->{username}; + $returnString .= "&date$fileCount=" . $file_row->{date}; + $returnString .= "&url$fileCount=" . $KWAREZ . $file_row->{thread} ."/". spaceReplace($file_row->{filename}); + $returnString .= "&size$fileCount=" . sizeinK($file_row->{size}); + $fileCount++; + } +print $returnString ; + +exit; + +sub fileEXT + { + my $filename = shift; + $filename =~ s/.+\.//; + return uc($filename); + } +sub spaceReplace + { + my $filename = shift; + $filename =~ s/\ /\%20/g; + return $filename; + } +sub sizeinK + { + my $bytes = shift; + my $size = $bytes / 1024; + if ( $size < 1024 ) + { + $size = sprintf "%2.2f", $size; + $size .= "k"; + } + elsif ( $size / 1024 < 1024 ) + { + $size = sprintf "%2.2f", $size / 1024; + $size .= "mb"; + } + elsif ( $size / 1024 / 1024 < 1024 ) + { + $size = sprintf "%2.2f", $size / 1024 / 1024; + $size .= " GB"; + } + return $size; + } diff --git a/cgi-bin/services_k b/cgi-bin/services_k new file mode 100755 index 0000000..3ce9940 --- /dev/null +++ b/cgi-bin/services_k @@ -0,0 +1,62 @@ +#!/usr/bin/perl +######################################### +# services_k +# feeds bPod the keyword list for logged in user +######################################### + +use localbucky; + +$dbh = DBI->connect ($dsn); + +our ($USER, $lastlog) = checkin(); + +our $logged_in = ($USER != -1); + +our $TAGS = [ 'Docks', 'Dings', 'Mexico', 'France', 'Breakfast', 'Baked', 'Sandwich' ]; + +# this start/end shit is all broken anyway +#my $start = $input->{s}; +#my $end = $input->{e}; + +my $keywords_hashref = get_keywords(); +my $keywords_arrayref = []; + +print "Content-type: text/html\r\n\r\n"; +foreach my $keyword (keys(%$keywords_hashref)) + { + my $k = $keywords_hashref->{$keyword}; + push ( @$keywords_arrayref, $keyword ) if (check_keyword($k)); + } + +my $numItems = @$keywords_arrayref; + +my $returnString = " &numItems=" . ($numItems ); +#$returnString = "duhhh"; + +@$keywords_arrayref = sort{ lc($a) cmp lc($b) } @$keywords_arrayref; + +my $keywordCount = 0; +foreach my $keyword (@$keywords_arrayref) + { + $returnString .= "&keyword$keywordCount=$keyword"; + my $color = $keywords_hashref->{$keyword}->{color} || "plain"; + $returnString .= "&color$keywordCount=$color"; + $keywordCount++; + } + +#@$tags_arrayref = sort{ $a cmp $b } @$TAGS; +my $tags_arrayref = get_tag_names(); +@$tags_arrayref = sort{ lc($a) cmp lc($b) } @$tags_arrayref; +my $numTags = @$tags_arrayref; + +$returnString .= "&numTags=" . $numTags; + +my $tagCount = 0; +foreach my $tag (@$tags_arrayref) + { + $returnString .= "&tag$tagCount=$tag"; + $tagCount++; + } + +print $returnString ; +exit(0); diff --git a/cgi-bin/services_th b/cgi-bin/services_th new file mode 100755 index 0000000..6e2bb67 --- /dev/null +++ b/cgi-bin/services_th @@ -0,0 +1,54 @@ +#!/usr/bin/perl +######################################### +# services_th +# feeds bPod the keyword list for logged in user +######################################### + +use localbucky; + +$dbh = DBI->connect ($dsn); + +our ($USER, $lastlog) = checkin(); + +our $logged_in = ($USER != -1); + +print "Content-type: text/html\r\n\r\n"; + +my $threads; + +my $kws = {}; +my $keyword = $input->{k}; +if ($keyword =~ /^tag_/) + { + $keyword =~ s/^tag_//; + $threads = get_threads_by_tag( $keyword ); + $kws = get_keywords(); + } +else + { + $kws->{$keyword} = get_keyword($keyword); + $threads = get_threads_by_keyword( $keyword ); + } + +my $threads_allowed = []; +foreach my $thread (@$threads) + { + push ( @$threads_allowed, $thread ) if (check_privacy( $thread, $kws->{$thread->{keyword}} ) > 0); + } + +my $numItems = @$threads_allowed; + +my $returnString = " &numItems=" . ($numItems ); + +@$threads_allowed = sort{ lc($b->{title}) cmp lc($a->{title}) } @$threads_allowed; + +my $threadCount = $numItems - 1; +foreach my $thread (@$threads_allowed) + { + $returnString .= "&title$threadCount=" . $thread->{title}; + $returnString .= "&user$threadCount=" . $thread->{username}; + $returnString .= "&id$threadCount=" . $thread->{id}; + $threadCount--; + } +print $returnString ; +exit; diff --git a/cgi-bin/settings b/cgi-bin/settings new file mode 100644 index 0000000..e2b3b1f --- /dev/null +++ b/cgi-bin/settings @@ -0,0 +1,24 @@ +#!/usr/bin/perl + +use localbucky; + +$dbh = DBI->connect ($dsn); + +our ($USER, $lastlog) = checkin(); +our $loggedin = ($USER != -1); + +#nice_redirect() if ($USER->{ulevel} != 3); + +header("bucky spritz tester", qq(<a href="$BUCKY/adminzz">roll back adminzz</a>) ); +menu(); +my $id = exists($input->{id}) ? $input->{id} : 165; +my $thread = get_thread($id); +my $keyword = get_keyword($thread->{keyword}); +my $files = get_files($id); +print qq(<center><table border=0 cellpadding=0 cellspacing=0><tr><td>); +find_jpeg($files, $thread->{flagged}); +sideshow_comments($thread, $keyword); +reply_form($thread->{id}, $thread); +print qq(</td></tr></table></center>); +footer(); + diff --git a/cgi-bin/tag b/cgi-bin/tag new file mode 100755 index 0000000..6af4520 --- /dev/null +++ b/cgi-bin/tag @@ -0,0 +1,290 @@ +#!/usr/bin/perl +######################################### +# index +# - do all index stuff, also deal with keyword admin +######################################### + +use localbucky; + +$dbh = DBI->connect ($dsn); + +our ($USER, $lastlog) = checkin(); + +my $k; +my $tag; + +# check name of the calling script: index, tag, keyword +$input->{script} ||= $input->{script_from_uri} if defined($input->{script_from_uri}); + +# load the tag or keyword into the input params, if they don't exit already +if ( $input->{script} eq $BUCKY_LEXICON_TAG ) + { + $input->{tag} ||= $input->{object_from_uri} if defined($input->{object_from_uri}); + } +elsif ( $input->{script} eq $BUCKY_LEXICON_KEYWORD ) + { + $input->{keyword} ||= $input->{object_from_uri} if defined($input->{object_from_uri}); + } + +# Get keyword +if (exists($input->{keyword}) && $input->{keyword} ne "new" && $input->{keyword} ne "unsorted") + { + $k = get_keyword($input->{keyword}); + } + + +# Create New Keyword? FORM +if (exists($input->{keyword}) && $input->{keyword} eq "new") + { + my $t; + header("add new category"); + if (exists($input->{thread})) + { + $t = get_thread($input->{thread}); + } + menu(); + print "<br><br>"; + my %faek = + ( + keyword => $input->{keyword}, + thread => $input->{thread} + ); + keyword_form($input->{keyword}, \%faek, $t); + footer(); + } + +# Edit settings for keyword +elsif ($input->{c} eq "edit" && (check_op($k) || $USER->{ulevel} == 3)) + { + header( + { + title => "settings for category '$input->{keyword}'", + sticky => $input->{keyword} + } ); + # 20070903 - marc - new menu args calling style + my $menu_args; + $menu_args->{keywords} = $k if $k; + menu( $menu_args ); +# menu($k); + print "<br><br>"; + + keyword_form($k->{keyword}, $k); + + print qq!<center><table border=0 cellpadding=0 cellspacing=0 class="threadmain" width="580">!; + my $threads = get_threads_by_keyword($k->{keyword}); + thread_box({ threads => $threads, kw => $k }); + + print qq!</table>!; + footer(); + } + +# Create new keyword? Process form results +elsif ($input->{c} eq "create") + { + if (!defined($input->{keyword})) + { error("no keyword specified!"); } + if (get_keyword($input->{keyword}) != -1) + { error("keyword already exists!"); } + my %nk = + ( + keyword => $input->{keyword}, + threads => " $input->{thread} ", + owner => $USER->{username}, + public => $input->{public}, + agglutinate => $input->{agglutinate}, + color => $input->{color}, + ops => (make_whitelist()) + ); + if ($DEBUG) + { + header("Creating keyword $input->{keyword}"); + menu(); + foreach my $ky (keys %nk) + { print "$ky => $nk{$ky}<br>\n"; } + } + add_keyword(\%nk); + update_thread_keyword($input->{thread}, $input->{keyword}); + redirect("$BUCKY/$BUCKY_LEXICON_KEYWORD/$input->{keyword}"); + } + +# Edit settings for keyword? Process form results +elsif ($input->{c} eq "update") + { + if (!defined($input->{keyword})) + { error("no keyword specified!"); } + my %nk = + ( + threads => " $input->{thread} ", + public => (exists($input->{public}) ? 1 : 0), + agglutinate => (exists($input->{agglutinate})) ? $input->{agglutinate} : 0, + color => $input->{color} + ); + if (!exists($input->{public})) + { + $nk{ops} = make_whitelist(); + } + if ($DEBUG) + { + header("Updating keyword $input->{keyword}"); + menu(); + foreach my $ky (keys %nk) + { print "$ky => $nk{$ky}<br>\n"; } + } + update_keyword($input->{keyword}, \%nk); + redirect("$BUCKY/$BUCKY_LEXICON_KEYWORD/$input->{keyword}"); + } + +# Assign keyword processing form action +elsif ($input->{c} eq "assign") + { + keyword_assign_mechanism($input->{keyword}, $input->{thread}, $k); + redirect("$BUCKY/maintain/$input->{thread}"); + # redirect("$BUCKY/index?keyword=$input->{keyword}"); + } + +# Detach keyword action +elsif ($input->{c} eq "detach") + { + my $t; + + if (!defined($input->{thread})) + { error("no post specified!"); } + $t = get_thread($input->{thread}); + $k = get_keyword($t->{keyword}); + + my %nk = ( threads => delete_key($k->{threads}, $input->{thread}) ); + + if ($DEBUG) + { + header("Detaching post from $t->{keyword}"); + menu(); + foreach my $ky (keys %nk) + { print "$ky => $nk{$ky}<br>\n"; } + print "keyword ==> $t->{keyword}<br>\n"; + print "detaching <b>$t->{title}</b> from <b>$t->{keyword}</b><br>\n"; + } + update_keyword($t->{keyword}, \%nk); + update_thread_keyword($t->{id}, "NULL"); + redirect("$BUCKY/maintain/$t->{id}"); + } + +# Display main index page +else + { + my $tag = exists($input->{tag}) ? $input->{tag} : undef; + my $keyword = exists($input->{keyword}) ? $input->{keyword} : "all"; + my $limit = exists($input->{limit}) ? int($input->{limit}) : 40; + my $date = exists($input->{start}) ? int($input->{start}) : "now"; + + header({ title => get_random_line("titles"), sticky => $input->{keyword} }); + my $keywords = get_keywords(); + my $tags = get_tags(); + + my $menu_args; + $menu_args->{keywords} = $keywords->{$keyword} if $keywords->{$keyword}; + menu( $menu_args ); + + print qq(<table width="100%" cellpadding=0 cellspacing=0 border=0>); + print qq(<tr>); +############################# +# KEYWORD LIST + print qq(<td align=center valign=top width="100">\n); + print qq(<div class="bluebox"><span style="line-height: 1.5em;"><nobr>); + my $p = ''; my $l = ''; + my $with_letter = 0; + my $s = ''; +my $pre = ''; + my $start = ''; + foreach my $k (sort { lc($a) cmp lc($b) } keys %$keywords) + { + my $style; + $l = substr($k,0,1); + $start ||= $l; + if ($p && lc($l) ne lc($p)) + { + if ($with_letter > 3) + { + print qq(<big><big><b>$start - $pre</b></big></big><br> ); + print $s; + print qq(</nobr></span></div>); + print qq(<div class="bluebox"><span style="line-height: 1.5em;"><nobr>); + $s = ''; + $with_letter = 1; + $p=''; + $start = $l; + } + } + $with_letter += 1; + $p||=$l; + $pre=$l; + $s .= qq(<a style="$css" href="$BUCKY/category/$k">$k</a><br>); + } +if ($s) + { + print qq(<big><big><b>$start - $pre</b></big></big><br> ); + print $s; + print qq(</div>); + print qq(<div class="bluebox"><small><span style="line-height: 1.5em;"><nobr>); + } + print qq(</div>); + print qq(<div class="bluebox"><small><span style="line-height: 1.5em;"><nobr>); + print qq(.: <a href="$BUCKY/category/unsorted"><i>unsorted</i></a> :.<br>); + print qq(</nobr></span></small></div></td>\n); + + print qq(<td width="300" align=right valign=top>\n); + + alerts(); + if ($USER == -1) + { + bPod_box(); + print qq(</td></tr>); + } + else + { + welcome_box() if (check_key($USER->{boxes}, "welcome")); + bPod_box() if (check_key($USER->{boxes}, "bPod")); + radio_box() if (check_key($USER->{boxes}, "radio")); + upload_form($keyword) if (check_key($USER->{boxes}, "postform")); + hoot_box() if (check_key($USER->{boxes}, "hootbox")); + } + + print qq(</td><td align=left valign=top>\n); + + if (check_key($USER->{boxes}, "photostream") || ($USER == -1) ) + { + if ( $keyword ne "all" ) + { photostream({ keyword => $keyword, vertical => 0, count => 4 }); } + elsif ( $tag ) + { photostream({ tag => $tag, vertical => 0, count => 4 }); } + else + { photostream({ user => 1, vertical => 0, count => 4 }); } + } + + print qq(<center><table border=0 cellpadding=0 cellspacing=0 class="threadmain" width="580">); + + if ($keyword ne "all") + { + my $threads = throttle_threads({ keyword => $keyword, newest => $date }); + thread_box({ threads => $threads, kw => $keywords->{$keyword} }); + } + elsif ($tag) + { + my $threads = throttle_threads({ tag => $tag, newest => $date }); + thread_box({ threads => $threads, tag => $tags->{$tag} }); + } + else + { + alpha_index($keywords, $limit, $date); + } + + print qq(</table>); + print qq(</td>\n); + print qq(</tr>); + print qq(</table>\n\n); + + footer(); + } + +$dbh->disconnect (); + +print "Index: " . &report_time() . "\n" if $timer; diff --git a/cgi-bin/users b/cgi-bin/users new file mode 100755 index 0000000..b82a823 --- /dev/null +++ b/cgi-bin/users @@ -0,0 +1,228 @@ +#!/usr/bin/perl +######################################### +# display userlist +######################################### + +use localbucky; +use invite; + +$dbh = DBI->connect ($dsn); + +($USER, $lastlog) = checkin(); +logout() if ($USER == -1); + + my $users = get_all_users(); + my $keywords = get_keywords(); + + header( $BUCKY_CONFIG->{USERLIST_TITLE} ); + menu(); + + our $command = -1; + + print qq(<table width="100%" cellpadding=0 cellspacing=0 border=0>); + print qq(<tr><td align=center valign=top>\n); + + display_user_list($users); + + print qq(</td>\n<td width="200" align=right valign=top>\n); + + invite_result_box($command, $hash, $result) if ($command != -1); + invite_create_box() if ($USER->{'ulevel'} > 1); + grass_box($users); + + print qq(</td></tr></table>\n\n); + + footer(); + +sub grass_box + { + my ($users) = @_; + print qq(<div class="message">); + print qq(<b>newest users</b>\n); + my $i = 0; + print "<table border=0 cellpadding=0 cellspacing=3>"; + foreach my $duder (sort_by_firstseen(@$users)) + { + next if ($duder->{ulevel} < 1); + next if ($duder->{firstseen} == 0); + my $z_date = verbosedate($duder->{firstseen}); + my $z_user = $duder->{username}; + my $z_grass = $duder->{grass}; + print qq(<tr><td colspan=2><hr noshade color="$BUCKY_COLOR_HR">\n</td></tr>); + print qq(<tr>); + print qq(<td align="left"><b><a href="$BUCKY/profile/$z_user">$z_user</a></b></td>); + print qq(<td align="right"><small>$z_date</small></td>); + print qq(</tr>); + if (length($z_grass)) + { + print qq(<tr>); + print qq(<td align="left" colspan=2>); + print "$z_grass"; + print qq(</td>); + print qq(</tr>); + } + last if (++$i == 20); + } + print qq(</table>\n); + print qq(</div>\n); + } + +sub display_user_list + { + my ($users) = @_; + print qq[<table border=0 cellpadding=2 cellspacing=0>]; + print qq[<tr>\n]; + print qq(<td> </td>\n); +print <<userrows; +<td class="head"> </td> +<td class="head" style="padding-left: 4px; padding-right: 8px;"><b>username</b></td> +<td class="head" style="padding-left: 4px; padding-right: 8px;"><b>realname</b></td> +<td class="head" style="padding-left: 4px; padding-right: 2px; text-align: right;"><b>idle</b></td> +<td class="head" style="padding-left: 4px; padding-right: 8px;" colspan=3><b> </b></td> +userrows + # print qq(<td class="head" style="padding-left: 4px; padding-right: 8px;"> </td>\n) if ($USER->{ulevel} == 3); + print "</tr>\n"; + + my $r = 0; + my $i = 0; + my $today = 0; + my $neg = 0; + my $show_all = (exists($input->{showall})) ? 1 : 0; + + foreach my $duder (sort_by_username(@$users)) + { + next if ($duder->{ulevel} < 1); + my $vanished = + ( + $duder->{ccount} < 1 + && $duder->{fcount} < 1 + && (time - $duder->{lastseen}) > 14*24*3600 + ); + if ($vanished && !$show_all) + { + $neg++; + next; + } + print qq[<tr class="row$r">]; + print_blank_cell(qq(<small><a href="$BUCKY/profile/$$duder{username}">profile</a> · <a href="$BUCKY/message/$$duder{username}">send message</a> ·</small>), "right", "blank"); + + my $image = get_profile_image($duder->{username}, $AVATAR_MED_PREFIX); + if ($image != -1) + { + my $av .= + qq(<a href="$BUCKY/profile/$duder->{username}">). + qq(<img src="$image" width="$AVATAR_MED_WIDTH" border=1">). + qq(</a>); + print_user_cell($av); + } + else + { + print_user_cell(qq(<img src="/blank.gif" width="$AVATAR_MED_WIDTH" height="$AVATAR_MED_WIDTH">)); + } + + if ($duder->{ulevel} > 1 && $USER->{ulevel} == 3 && $show_all) + { + print_user_cell("· ".$duder->{username}); + } + elsif ($vanished) + { + print_user_cell("<small>".$duder->{username}."</small>"); + } + else + { + $duder->{username} =~ s/\n/<br>/g; + print_user_cell($duder->{username}); + } + + $duder->{realname} =~ s/\s/ /g; + if ($vanished) + { print_user_cell("<small>".$duder->{realname}."</small>"); } + else + { print_user_cell($duder->{realname}); } + + my $col = carbondate($duder->{lastseen}, 0); + $today++ if ($col eq "new"); + if ($vanished) + { + print_user_cell(qq!<span class="$col"><small>!.(get_age($duder->{lastseen})).qq! ago</small></span>!, "right"); + } + else + { + print_user_cell(qq!<small><span class="$col">!.(get_age($duder->{lastseen})).qq!</span></small>!, "right"); + } + + if ($USER->{ulevel} == 3) + { + if ($duder->{ccount} == 0) + { print_user_cell(" "); } + else + { print_user_cell(" <small>".hushnull($duder->{ccount}, "c", 1)."</small>", "right"); } + + if ($duder->{fcount} == 0) + { print_user_cell(" "); } + else + { print_user_cell(" <small>".hushnull($duder->{fcount}, "f", 1)."</small> ", "right"); } + } + + my $cell = ''; + foreach my $sticky (split_keys($duder->{stickies})) + { + my $key = $keywords->{$sticky}; + if ($key->{owner} eq $USER->{username} || check_op($key) || $USER->{ulevel} == 3) + { + $cell .= qq(<a href="$BUCKY/$BUCKY_LEXICON_KEYWORD/$sticky">$sticky</a>, ); + } + } + $cell =~ s/, $//; + print_user_cell($cell); + + print qq[</tr>]; + $r = $r ? 0 : 1; + $i++; + } + + print qq(<tr><td colspan=9 align=right><small>) . + qq(total: <b>$i</b> users \(<b>$today</b> seen today); + print qq(, $neg <a href="$BUCKY/users?showall=1">vanished</a>) if (!$show_all && $USER->{ulevel} > 2); + print qq(\)</small> </td></tr>\n); + print <<approvefoot; +</table></center> +approvefoot + } + +sub print_user_cell + { + my ($v, $align) = @_; + my ($lpx, $rpx) = ("4px", "2px"); + ($lpx, $rpx) = ("2px", "4px") if ($align eq "right"); + $align = "left" unless ($align); + print qq[<td nobreak style="padding: 3px; vertical-align: middle; text-align: $align;">$v</td>]; + } + +sub print_blank_cell + { + my ($v) = @_; + print qq[<td nobreak style="padding: 3px; background-color: #e6f0e6; vertical-align: middle; text-align: $align;">$v</td>]; + } + +sub print_sinks + { + $cell = ' '; + foreach my $sticky (split_keys($duder->{sink})) + { + my $key = $keywords->{$sticky}; + if ($key->{owner} eq $USER->{username} || check_op($key) || $USER->{ulevel} == 3) + { + $cell .= qq(<a href="$BUCKY/$BUCKY_LEXICON_KEYWORD/$sticky">$sticky</a>, ); + } + } + $cell =~ s/, $//; + print_user_cell($cell); + } + +sub sort_by_username { sort { uc($a->{username}) cmp uc($b->{username}) } @_; } +sub sort_by_firstseen { sort { uc($b->{firstseen}) <=> uc($a->{firstseen}) } @_; } + +$dbh->disconnect (); +print "Users: " . &report_time() . "\n" if $timer; + |
