Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl -w
- # written by andrewt@cse.unsw.edu.au September 2015
- # as a starting point for COMP2041/9041 assignment 2
- # http://cgi.cse.unsw.edu.au/~cs2041/assignments/bitter/
- use CGI qw/:all/;
- use CGI::Carp qw(fatalsToBrowser warningsToBrowser);
- use Data::Dumper;
- use List::Util qw/min max/;
- use CGI::Cookie;
- use Digest::MD5 qw(md5_hex);
- use File::Copy;
- use Env;
- use File::Path;
- warningsToBrowser(1);
- # some globals used through the script
- $debug = 1;
- $dataset_size = "large";
- $attachments_dir = "dataset-$dataset_size/attachments";
- $users_dir = "dataset-$dataset_size/users";
- $bleats_dir = "dataset-$dataset_size/bleats";
- $default_picture = '../assets/images/default_pic.jpg';
- $stylesheet = '../assets/stylesheets/bitter.css';
- $max_length_of_bleat = '142';
- $max_attachments = 4;
- $escape_description = 0; #whether we escape html tags in desciption
- $bleats_per_page = 10;
- # form.innerHTML += "<input type='button' name='submit' onclick='reply_bleat("" + document.getElementById('bleat_box').value + "", " + bleat + ");'/>";
- # delete script
- $js_delete = <<"eof";
- <script type="text/javascript">
- function delete_bleat(bleat) {
- if (confirm('Are you sure you want to delete your bleat?')) {
- var dict = get_params();
- dict['delete_bleat'] = bleat;
- post("bitter.cgi", dict);
- }
- }
- function reply_bleat(bleat, reply) {
- //alert(""+bleat);
- var dict = get_params();
- dict['new_bleat'] = ""+bleat;
- if (typeof reply === 'undefined') {
- //
- } else {
- dict['in_reply_to'] = reply;
- }
- //alert(dict['new_bleat']);
- post("bitter.cgi", dict);
- }
- function show_reply_form(bleat) {
- if (document.getElementById('b' + bleat).style.display=="none") {
- document.getElementById('b' + bleat).style.display="block";
- } else {
- document.getElementById('b' + bleat).style.display="none";
- }
- }
- function see_attachments(attachment, bleat) {
- var image = document.getElementById('a' + bleat);
- if (image.innerHTML.indexOf('src="' + attachment + '"') > -1) {
- image.innerHTML = "";
- } else {
- image.innerHTML = '<img src="' + attachment + '" alt="Attachment"/>';
- }
- }
- function get_params() { //this is written by some dude in SO
- var qd = {};
- location.search.substr(1).split("&").forEach(function(item) {var s = item.split("="), k = s[0], v = s[1] && decodeURIComponent(s[1]); (k in qd) ? qd[k].push(v) : qd[k] = [v]})
- return qd;
- }
- function post(path, params, method) { //this is written by some dude on SO
- method = method || "post"; // Set method to post by default if not specified.
- // The rest of this code assumes you are not using a library.
- // It can be made less wordy if you use one.
- var form = document.createElement("form");
- form.setAttribute("method", method);
- form.setAttribute("action", path);
- for(var key in params) {
- if(params.hasOwnProperty(key)) {
- var hiddenField = document.createElement("input");
- hiddenField.setAttribute("type", "hidden");
- hiddenField.setAttribute("name", key);
- hiddenField.setAttribute("value", params[key]);
- form.appendChild(hiddenField);
- }
- }
- document.body.appendChild(form);
- form.submit();
- }
- </script>
- eof
- # i have no idea whetehr I am doing this right
- # we need to do this before anything else because we have to know who is logged in
- # check if a user is logged in
- %cookies = CGI::Cookie->fetch;
- if ($cookies{'login'}) {
- %login_details = $cookies{'login'}->value;
- if (validate_user($login_details{'username'}, $login_details{'password'})) {
- # cool cool
- $c_user = $login_details{'username'};
- } else {
- $c_user = '';
- }
- }
- # FUNCTIONS WHICH HAVE TO BE RUN BEFORE I WRITE THE HEADER
- my $username = param('username') || "";
- my $password = param('password') || "";
- my $remember = param('remember_me') || 0;
- @page = which_page_am_I_on();
- if ($page[0] eq "login") {
- if (!$c_user) {
- if ($username and $password) {
- if (validate_user($username, $password)) {
- $username = get_proper_case_for_user($username);
- my $ck = new_session($username, $password, $remember);
- # if they are suspended, unsuspend them
- if (user_suspended($username)) {
- unsuspend_user($username);
- }
- print $ck->bake . start_html .
- div("Welcome $username. Please click <a href='bitter.cgi'>here</a> to be redirected") .
- end_html;
- exit(0);
- }
- }
- }
- } elsif ($page[0] eq 'logout') {
- print &logout() . start_html . div("Successfully logged out. Please click <a href='bitter.cgi'>here</a> to be redirected");
- exit 0;
- } elsif ($page[0] eq 'suspend') {
- suspend_user($c_user);
- print &logout() . start_html . div("Successfully suspended. Please click <a href='bitter.cgi'>here</a> to be redirected");
- exit 0;
- } elsif ($page[0] eq 'delete') {
- delete_user($c_user);
- print &logout() . start_html . div("Successfully deleted. Please click <a href='bitter.cgi'>here</a> to be redirected");
- exit 0;
- }
- #
- # check if we are deleting a bleat before anything
- #
- if (param('delete_bleat')) {
- if (bleat_exists(param('delete_bleat'))) {
- my %bleat_to_delete = format_bleat(param('delete_bleat'));
- # check if we are the user
- if ($c_user and $bleat_to_delete{'username'} =~ /^$c_user$/i) {
- # DELETE
- &delete_bleat(param('delete_bleat'));
- }
- }
- }
- #
- # check if we are making a new bleat as well
- #
- if (param('new_bleat')) {
- if ($c_user) {
- my @attachments = upload('bleat_attachment');
- # write the attachments to files
- # GET THE MINIMUM (idk why I don't use min)
- my $num = $#attachments;
- if ($num > ($max_attachments - 1)) {
- $num = $max_attachments - 1;
- }
- my @all_attachments = ();
- my @uploaded = ();
- foreach my $i (0..$num) {
- next if ($attachments[$i] !~ /\.jpg$/i);
- @all_attachments = sort glob("$attachments_dir/*");
- my $last_attachment = (@all_attachments) ? $all_attachments[$#all_attachments] : '0';
- $last_attachment =~ s/\.jpg$//;
- $last_attachment =~ s/^.*attachments\///;
- my $handle = $attachments[$i];
- open my $fh, ">$attachments_dir/" . (int($last_attachment) + 1) . ".jpg" or die "Couldn't create new attachment: $!";
- binmode $fh;
- while (my $line = <$handle>) {
- print $fh $line;
- }
- close $fh;
- push @uploaded, "$attachments_dir/" . (int($last_attachment) + 1) . ".jpg";
- }
- if (param('in_reply_to')) {
- add_new_bleat($c_user, param('new_bleat'), param('in_reply_to'), @uploaded);
- } else {
- add_new_bleat($c_user, param('new_bleat'), '', @uploaded);
- }
- }
- }
- # print start of HTML ASAP to assist debugging if there is an error in the script
- print page_header();
- my @page = which_page_am_I_on();
- if ($page[0] eq 'p') { # a user profile
- if (user_exists($page[1])) {
- render_user_profile($page[1]);
- } else {
- print user_not_found($page[1]) . br; # change this to render a page later
- }
- } elsif ($page[0] eq 'b') { # a bleat
- if (bleat_exists($page[1])) {
- render_full_bleat($page[1]);
- } else {
- print bleat_not_found($page[1]) . br;
- }
- } elsif ($page[0] eq 'f') { #searching
- render_search_page($page[1]);
- } elsif ($page[0] eq 'login') {
- render_login_page();
- } elsif ($page[0] eq 'register') {
- render_register_page();
- } elsif ($page[0] eq 'settings' and $c_user) {
- render_settings_page();
- } elsif ($page[0] eq 'passwordrecovery') {
- render_password_recovery_page();
- } else {
- render_homepage();
- }
- #print browse_screen();
- print page_trailer();
- exit 0;
- #
- # transorms the user case to the actual one
- # e.g. if user logs in with 'brainyboy', would change it to BrainyBoy
- #
- sub get_proper_case_for_user {
- my ($user) = @_;
- my @blob = glob("$users_dir/*");
- my $new_user = $user;
- foreach (@blob) {
- $_ =~ s/^$users_dir\///;
- if ($_ =~ /^$user$/i) {
- $new_user = $_;
- }
- }
- return $new_user;
- }
- sub browse_screen {
- my $n = param('n') || 0;
- my @users = glob("$users_dir/*");
- $n = min(max($n, 0), $#users);
- param('n', $n + 1);
- my $user_to_show = $users[$n];
- my $details_filename = "$user_to_show/details.txt";
- open my $p, "$details_filename" or die "can not open $details_filename: $!";
- $details = join '', <$p>;
- close $p;
- return p,
- start_form, "\n",
- pre($details),"\n",
- hidden('n', $n + 1),"\n",
- submit('Next user'),"\n",
- end_form, "\n",
- p, "\n";
- }
- #
- # HTML placed at top of every screen
- #
- sub page_header {
- # if someone is logged in and we are on login page
- my @page = which_page_am_I_on();
- if ($page[0] eq 'login' or $page[0] eq 'register') {
- #print redirect('');
- }
- my $head = header;
- # i have no idea whetehr I am doing this right
- # i know i already did this before
- # check if a user is logged in
- %cookies = CGI::Cookie->fetch;
- if ($cookies{'login'}) {
- %login_details = $cookies{'login'}->value;
- if (validate_user($login_details{'username'}, $login_details{'password'})) {
- $c_user = $login_details{'username'};
- # we have to add the cookie to the header again
- $head = header({-cookie => $cookies{'login'}});
- } else {
- $c_user = '';
- }
- }
- #if we are on user profiel and they have a background, print the background
- #print img({-src => "../$bg", -alt=>"$username\'s background", -id=>'profile-bg'});
- my $start = start_html("-title"=>"Bitter", -style=>{-src=>"$stylesheet"});
- if ($page[0] eq 'p') {
- my $bg;
- if (user_exists($page[1]) and $bg = user_has_background($page[1])) {
- $start = start_html( -title=>'Bitter',
- -style=>{-src=>"$stylesheet"},
- -background=>"../$bg"
- );
- }
- }
- return $head, $start,
- div({-id=>'header-container'},
- div({-id=>'search-bar'},
- (start_form({-id=>'search-form', -action=>'bitter.cgi', -method=>'get'}),
- textfield({-id=>'search-box', -name=>'f', -placeholder=>'Search...'}),
- hidden({-value => 'users', -name=>'fu'}),
- submit({-id=>'search-button', -value=>'Search', -name=>''}),
- end_form)
- ), div({-id=>'bitter-title'}, a({-href=>'bitter.cgi'}, 'Bitter')), div({-id=>'menu-container'}, render_menu())),
- "\n" . br . br . "\n",
- $js_delete . "\n";
- }
- #
- # HTML placed at bottom of every screen
- # It includes all supplied parameter values as a HTML comment
- # if global variable $debug is set
- #
- sub page_trailer {
- my $html = "";
- $html .= join("", map("<!-- $_=".param($_)." -->\n", param())) if $debug;
- $html .= end_html;
- return $html;
- }
- ################## GENERAL FUNCTIONS ###########################
- #
- # gets the page from the params
- #
- sub which_page_am_I_on {
- # a user's profile
- my $user_profile = param('p') || 0;
- if ($user_profile) {
- my @ret = ('p', $user_profile);
- # check for listening too
- my $listen = param('listen') || 0;
- my $unlisten = param('unlisten') || 0;
- if ($listen and $c_user) {
- listen_to($listen);
- }
- if ($unlisten and $c_user) {
- unlisten_to($unlisten);
- }
- return @ret;
- }
- # a detailed view of a bleat
- my $detailed_bleat = param('b') || 0;
- if ($detailed_bleat) {
- my @ret = ('b', $detailed_bleat);
- return @ret;
- }
- # search
- my $search = param('f') || 0;
- if ($search) {
- #print "SEARCH TERM: $search";
- my @ret = ('f', $search);
- return @ret;
- }
- # random static pages
- my $page = param('page') || 0;
- if ($page) {
- if ($page eq 'login' and !$c_user) {
- my @ret = ('login', '');
- return @ret;
- } elsif ($page eq 'register' and !$c_user) {
- my @ret = ('register', '');
- return @ret;
- } elsif ($page eq 'logout' and $c_user) {
- my @ret = ('logout', '');
- return @ret;
- } elsif ($page eq 'settings') {
- my @ret = ('settings', '');
- return @ret;
- } elsif ($page eq 'suspend' and $c_user) {
- my @ret = ('suspend', '');
- return @ret;
- } elsif ($page eq 'delete' and $c_user) {
- my @ret = ('delete', '');
- return @ret;
- } elsif ($page eq 'passwordrecovery') {
- my @ret = ('passwordrecovery', '');
- return @ret;
- } else {
- print "Page: $page";
- }
- }
- my $validation = param('v') || 0;
- if ($validation) {
- # if the user hasn't yet validated
- if (-d "$users_dir/temp/$validation") {
- account_validation($validation);
- }
- # redirect to homepage
- redirect("bitter.cgi?p=$validation");
- }
- # print param();
- # the key value for homepage
- return (69, 420);
- }
- #
- # deletes a bleat
- #
- sub delete_bleat {
- my ($bl) = @_;
- if (!bleat_exists($bl)) {return;}
- # delete the file and the number from the user
- # first write the data to an array
- my %bleat_to_delete = format_bleat($bl);
- open my $bleats_list, "<$users_dir/$bleat_to_delete{'username'}/bleats.txt" or die "Couldn't open bleats file: $!";
- chomp ( my @list = <$bleats_list> );
- close $bleats_list;
- # then modify the array and write it back to the file
- my @new_list = grep {$_ !~ /^$bl$/} @list;
- open my $bleats_list2, ">$users_dir/$bleat_to_delete{'username'}/bleats.txt" or die "Couldn't open bleats file: $!";
- print $bleats_list2 join "\n", @new_list;
- print $bleats_list2 "\n";
- close $bleats_list2;
- # first remove all the replies tot heir bleats
- my @l;
- my @all_bleats = glob("$bleats_dir/*");
- my $delete = 0;
- foreach my $file (@all_bleats) {
- @l = ();
- open my $b, "<$file" or die "Couldn't open: $!";
- while (<$b>) {
- push @l, $_;
- next unless $_ =~ /^in_reply_to: (.*)/;
- my $temp = $1;
- chomp $temp;
- if ($temp =~ /^$bl$/) {
- pop @l; # undo the push if it is a reply to one of the deleted users' bleats
- $delete = 1;
- } else {
- $delete = 0;
- }
- }
- close $b;
- next if (grep {$_ =~ /^in_reply_to: /} @l); # to save some time
- if ($delete) {
- open my $c, ">$file" or die "Couldn't open to write: $!";
- print $c join("\n", @l);
- print $c "\n";
- close $c;
- $delete = 0;
- }
- }
- # now delete it from the bleats file
- if ( -f "$bleats_dir/$bl" ) {
- unlink "$bleats_dir/$bl";
- }
- }
- #
- # generatrs a reply form
- #
- sub generate_reply_form {
- my ($to, $bleatID) = @_;
- return <<"eof";
- <form action='bitter.cgi' enctype='multipart/form-data' method='post' >
- <textarea name='new_bleat' class='bleat-area' maxlength='$max_length_of_bleat' >\@$to </textarea><br />
- <input type='file' name='bleat_attachment' multiple/>
- <input type='hidden' name='in_reply_to' value='$bleatID' />
- <input type='submit' value='Reply' style='float:right;' />
- </form>
- eof
- }
- #
- # trims whitespace from a string
- #
- sub trim {
- my ($poop) = @_;
- $poop =~ s/^\s+|\s+$//g;
- return $poop;
- }
- #
- # does a user exist
- #
- sub user_exists {
- my ($username) = @_;
- $username = &trim(lc($username));
- # first if the user does not exist at all, return 0
- return 0 if !( -d "$users_dir/$username" );
- # but then check if they are suspended
- open my $suspended, "<$users_dir/suspended.txt" or die "Couldn't open suspended.txt: $!";
- while (my $line = <$suspended>) {
- $line = &trim($line);
- if (lc($line) eq lc($username)) {
- close $suspended;
- return 0;
- }
- }
- close $suspended;
- # return true if passed all the tests
- return 1;
- }
- #
- # return the message when you can't find a user
- #
- sub user_not_found {
- return "User @_ not found\n";
- }
- #
- # return the message when a page is not found
- #
- sub page_not_found {
- return "Page @_ not found\n";
- }
- #
- # given a username, return the path to that user's display picture
- # (or the default picture if they do not have one)
- #
- sub get_display_picture {
- my ($username) = @_;
- if ( -f "$users_dir/$username/profile.jpg" ) {
- return "../$users_dir/$username/profile.jpg";
- } else {
- return "$default_picture";
- }
- }
- #
- # given a string (assumed to be a bleat), return a string where @___ and #____ are
- # replaced with links
- #
- sub bleat_tags {
- my ($bleat, $bleatID) = @_;
- $bleat = escapeHTML($bleat);
- while ($bleat =~ /(\@[a-zA-Z0-9-_]+)/g) {
- my $tagged = substr $1, 1;
- next if (!user_exists($tagged));
- my $temp = a( { -href => "?p=$tagged" }, '@' . $tagged );
- $bleat =~ s/\@$tagged/$temp/;
- }
- # replace hashtags
- $bleat =~ s/#([a-zA-Z][a-zA-Z0-9-_]*)/a( { -href => "?f=%23$1&fb=bleats" }, '#' . $1 );/ge;
- return $bleat;
- }
- #
- # given a bleat ID, return a hash containing the info of the bleat
- #
- sub format_bleat {
- my ($bleatID) = @_;
- #print $bleatID . "\n";
- # open it and add all the shit to the hash
- open my $bleat, "<$bleats_dir/$bleatID" or die "Couldn't open $bleats_dir/$bleatID: $!";
- my %bleat_data;
- while (<$bleat>) {
- next if $_ =~ /^\s*$/;
- my @pair = split /: /, $_, 2; # only split it once
- chomp $pair[0];
- chomp $pair[1];
- #print "<!-- LINE: $line -->\n";
- #print "<!--" . join(", ", @pair) . "-->\n";
- $bleat_data{$pair[0]} = $pair[1];
- }
- close $bleat;
- $bleat_data{'id'} = $bleatID;
- return %bleat_data if (!user_suspended($bleat_data{'username'}));
- # if they are suspended, return some random shti
- my %default_bleat;
- $default_bleat{'username'} = $bleat_data{'username'};
- $default_bleat{'bleat'} = 'Bleat deleted.';
- $default_bleat{'time'} = 0;
- return %default_bleat;
- }
- #
- # given a username, return a hash containing the info of the user
- #
- sub format_user {
- my ($username) = @_;
- # open it and add all the shit to the hash
- open my $deets, "<$users_dir/$username/details.txt" or die "Couldn't open $users_dir/$username/details.txt:$!";
- my %user_data;
- while (<$deets>) {
- my @pair = split /: /, $_, 2; # only split it once
- chomp $pair[0];
- chomp $pair[1];
- $user_data{$pair[0]} = $pair[1];
- }
- close $deets;
- #add the description
- my $description = "";
- if (-f "$users_dir/$username/description.txt") {
- open my $desc, "<$users_dir/$username/description.txt" or die "Couldn't open Description.txt: $!";
- chomp ($description = join "", <$desc>);
- close $desc;
- }
- $user_data{'description'} = $description;
- return %user_data;
- }
- #
- # given a username, get a list of the users bleats
- #
- sub get_users_bleats {
- my ($username) = @_;
- my @empty = ();
- return @empty if !user_exists($username) or user_suspended($username);
- open my $bleats, "<$users_dir/$username/bleats.txt" or die "Couldn't open $users_dir/$username/bleats.txt: $!";
- my @list;
- while (<$bleats>) {
- push @list, trim($_);
- }
- close $bleats;
- return @list;
- }
- ############################ FUNCTIONS FOR USER PROFILES ############################
- #
- # given a username, renders a user profile
- #
- sub render_user_profile {
- my ($username) = @_;
- print div({-id=>'user-profile-container'}, table( { -class => 'profile' },
- Tr(
- td( { -class => 'user_sidebar' }, display_sidebar($username)),
- td( { -class => 'user_bleats' }, list_bleats_given_an_array(get_users_bleats($username)))
- )
- ));
- #print end_table;
- }
- #
- # does user have a background?
- #
- sub user_has_background {
- my ($user) = @_;
- if (-f "$users_dir/$user/background.jpg") {
- #print "$users_dir/$user/background.jpg";
- return "$users_dir/$user/background.jpg";
- } else {
- #print "NO BACKGROUND";
- return undef;
- }
- }
- #
- # returns a sexy line
- #
- sub sexy_line {
- return "\n<div><span class='sexy-line'></span></div>\n";
- }
- #
- # given a username, render the sidebar
- #
- sub display_sidebar {
- my ($username) = @_;
- # first grab the dp and user details
- my $picture = get_display_picture($username);
- my %details = format_user($username);
- # make sure it is not malicious
- foreach (keys %details) {
- if ($escape_description and $_ eq 'description') {
- # if we want to escape the description (im not sure what we are supposed to do so i just have a flag)
- } else {
- $details{$_} = escapeHTML($details{$_});
- if ($_ eq 'description') {
- $details{$_} =~ s/<\s*b\s*>/<b>/gi;
- $details{$_} =~ s/<\s*\/\s*b\s*>/<\/b>/gi;
- $details{$_} =~ s/<\s*i\s*>/<i>/gi;
- $details{$_} =~ s/<\s*\/\s*i\s*>/<\/i>/gi;
- #added support for bold and italics
- }
- }
- }
- my @listening = grep { !user_suspended($_) } split(/\s+/, $details{'listens'}) if defined($details{'listens'});
- my $string = "";
- # first print the dp
- $string .= img( { -src => $picture, -alt => $username, -id => 'profile-pic' }) . br;
- # then the details
- $string .= render_user_details(%details) . br;
- # then the grid
- $string .= '<b>Listening to:</b>' . br;
- $string .= render_listeners_grid(@listening) if @listening;
- $string .= br;
- if ($c_user and $username !~ /^$c_user$/i) {
- $string .= listen_button($username);
- }
- $string .= br;
- return $string;
- }
- #
- # given a hash of user details, pretty print :D
- #
- sub render_user_details {
- my (%deets) = @_;
- my $string = "";
- # name
- $string .= '<div id="full_name">' . $deets{'full_name'} . '</div>' . br if (defined($deets{'full_name'}));
- # suburb
- $string .= '<b>Lives in</b>: ';
- $string .= $deets{'home_suburb'} if (defined($deets{'home_suburb'}));
- # map
- if (defined($deets{'home_latitude'}) and defined($deets{'home_longitude'})) {
- $string .= ' ' . a( {-href=>"http://www.latlong.net/c/?lat=$deets{'home_latitude'}&long=$deets{'home_longitude'}", -target => '_blank' },
- "(map)");
- }
- $string .= br;
- #description
- if ($deets{'description'}) {
- $string .= b('Description: ') . p($deets{'description'}) . br;
- }
- return $string;
- }
- #
- # given a list of users, return html for
- # a grid with 3 width containing links to
- # each user
- #
- sub render_listeners_grid {
- my @users = @_;
- my $string = "";
- # make a 3x? table
- my $remainder = (scalar @users) % 3;
- my $rows = ($remainder) ? (((scalar @users) + (3-$remainder)) / 3) : ((scalar @users) / 3);
- # add the table
- $string .= "<table class='listener_grid'>\n";
- my $i = 0;
- while ($rows > 0) {
- $string .= '<tr>' . "\n";
- for (0..2) {
- if ($users[$i]) {
- $string .= "<td class='listening_grid_image'><a href='?p=$users[$i]'><img src='" . get_display_picture($users[$i]) ."' class='listening_grid_image' alt=$users[$i] /></a></td>\n";
- } else {
- $string .= "<td></td>\n";
- }
- $i++;
- }
- $string .= '</tr>' . "\n";
- $rows--;
- }
- $string .= '</table>' . "\n";
- return $string;
- }
- ############################ FUNCTIONS FOR DETAILED BLEAT VIEWS #####################
- #
- # given a bleat ID, print the bleats it is replying to as well in a
- # list view
- #
- sub render_full_bleat {
- my ($bleatID) = @_;
- print "<div id='bleat-view-container'>\n";
- # print the first bleat
- print print_bleat($bleatID);
- # print the replies
- my @replies = list_replies_to_bleat($bleatID);
- @replies = sort { $b <=> $a } @replies;
- if (@replies) {
- print h4('Replies') . "\n";
- }
- foreach (@replies) {
- print br . "\n";
- print sexy_line();
- print br . "\n";
- print print_bleat($_);
- }
- print "</div>\n";
- }
- #
- # given a bleat ID, return a list of IDs which reply to the bleat
- #
- sub list_replies_to_bleat {
- # pretty self explanatory code here
- my ($bleatID) = @_;
- my @all_bleats = glob("$bleats_dir/*");
- my @final = ();
- foreach (@all_bleats) {
- $_ =~ s/$bleats_dir\///;
- my %b = format_bleat($_);
- if ($b{'in_reply_to'} and trim($b{'in_reply_to'}) =~ /^$bleatID$/) {
- push @final, $b{'id'};
- }
- }
- return @final;
- }
- #
- # given a bleat hash, pretty print
- # THIS IS FOR SINGLE BLEAT VIEW
- #
- sub print_bleat {
- my ($bleatID) = @_;
- my %bleat = format_bleat($bleatID);
- # FIRST GET ALL THE DATA INTO VARIABLES
- my $username = "<span class='username-link'><a href='?p=" . $bleat{'username'} . "'>$bleat{'username'}</a></span>\n";
- my $time = "<a href='?b=" . $bleat{'id'} . "'>" . localtime($bleat{'time'}) . "</a>\n";
- my $formatted_bleat = bleat_tags($bleat{'bleat'}, $bleat{'id'}) . "\n";
- my $pic = "<img class='bleat-picture' src='" . get_display_picture($bleat{'username'}) . "' alt=$bleat{'username'} />\n";
- my ($location, $in_reply_to) = ("", "");
- if (defined($bleat{'home_longitude'}) and defined($bleat{'home_latitude'})) {
- $location = "<a href='http://www.latlong.net/c/?lat=" . $bleat{'home_latitude'} . "&long=" . $bleat{'home_longitude'} . " target='_blank'>\@</a>\n";
- }
- if (defined($bleat{'in_reply_to'})) {
- $in_reply_to = "in reply to <span class='username-link'><a href='?b=" . $bleat{'in_reply_to'} . "'>" . bleatID_to_username($bleat{'in_reply_to'}) . "</a></span>\n";
- }
- # ADD THE OPTIONS TO REPLY, DELETE, SEE ATTACHMENTS IF ANY, AND SHOW REPLIES
- my ($reply_string, $delete_string, $see_attachments) = ("", "", "");
- # reply
- $reply_string = a({-href=>"javascript:show_reply_form('" . $bleat{'id'} . "');"}, 'Reply') . "\n";
- # delete
- $delete_string = a({-href=>"javascript:delete_bleat('" . $bleat{'id'} . "');"}, 'Delete') . "\n" if $bleat{'username'} =~ /^$c_user$/i;
- # show attachments
- if ($bleat{'attachments'}) {
- $see_attachments = "Attachments: ";
- my @attachments = split /\s+/, $bleat{'attachments'};
- my $i = 1;
- foreach (@attachments) {
- $see_attachments .= a({-href=>"javascript:see_attachments('../$_', $bleat{'id'});"}, $i) . " \n";
- $i++;
- }
- }
- my $form = generate_reply_form($bleat{'username'}, $bleat{'id'});
- my $string = <<"eof";
- <div class='bleat-picture'>$pic</div>
- <div class='individual-bleat'>
- <div class='bleat-info'>
- $username $in_reply_to
- <span class='bleat-options'>
- $see_attachments $delete_string $reply_string
- </span>
- <br />
- $time $location
- </div>
- <div class='bleat-message'>$formatted_bleat</div>
- <br />
- <div id="b$bleat{'id'}">$form</div>
- <div id="a$bleat{'id'}"></div>
- <script type="text/javascript">document.getElementById("b$bleat{'id'}").style.display = "none";</script>
- </div>
- <br />
- eof
- return $string . "\n";
- }
- #
- # does a certain bleat exist
- #
- sub bleat_exists {
- my ($bleat) = @_;
- $bleat = &trim($bleat);
- return ( -f "$bleats_dir/$bleat" ) ? 1 : 0;
- }
- #
- # bleat not found
- #
- sub bleat_not_found {
- return "Bleat @_ not found\n";
- }
- #
- # given a bleat ID, convert to a username
- #
- sub bleatID_to_username {
- my ($bleat) = @_;
- my %temp = format_bleat($bleat);
- return $temp{'username'};
- }
- ############################ FUNCTIONS FOR MENU #####################################
- #
- # render the menu I guess
- #
- sub render_menu {
- # if the user hasn't logged in,
- if ($c_user) {
- my $menu = ul({-class=>'menu'},
- li(a{-href=>'bitter.cgi'}, 'Home'),
- li(a{-href=>"?p=$c_user"}, 'Profile'),
- li(a{-href=>'?page=settings'}, 'Settings'),
- li(a{-href=>'?page=logout'}, 'Logout')
- );
- } else {
- my $menu = ul({-class=>'menu'},
- li(a{-href=>'?page=login'}, 'Login'),
- li(a{-href=>'?page=register'}, 'Register')
- );
- }
- }
- ####################### FUNCTIONS FOR SEARCH ########################################
- #
- # searches everything given a keyword
- #
- sub render_search_page {
- my ($search_term) = @_;
- #sanitize the search term
- $search_term =~ s/[^a-z0-9#]//gi;
- $search_term =~ s/\s+/ /g;
- $search_term = &trim($search_term);
- $search_term = escapeHTML($search_term);
- # replace hashtags
- $search_term =~ s/%23/#/g;
- #print "Search term: $search_term";
- my $search_results_per_page = 10;
- #users
- my $users_string = "";
- #bleats
- my $bleats_string = "";
- my @results = ();
- # first search usernames
- # if we are looking at users
- if (!param('fb')) {
- open my $search, "<$users_dir/search.txt" or die "Couldn't open $users_dir/search.txt: $!";
- chomp (my @names = <$search>);
- close $search;
- push @results, grep { $_ =~ /$search_term/i } @names;
- $_ =~ s/.*:(.*)$/$1/ for @results;
- my $page = param('n') || 1;
- $page = int($page);
- # sanity check for page number
- my $total_pages = (scalar @results);
- while ($total_pages % $search_results_per_page != 0) {
- $total_pages++;
- }
- $total_pages /= $search_results_per_page;
- $page = 1 if ($page > $total_pages or $page < 1);
- @results = paginate($page, $search_results_per_page, @results);
- #$users_string .= "<div id='search-results-container'>\n";
- $users_string .= list_users(@results);
- #list page numbers
- $users_string .= "<div id='page-numbers'>\n";
- my $i = 1;
- while ($i < $total_pages) {
- $users_string .= "<a href='?f=$search_term&fu=users&n=$i'>$i</a> ";
- $i++;
- }
- $users_string .= "</div>\n";
- #$users_string .= "</div>\n";
- # now we do bleats
- } else {
- my @bleat_array = glob("$bleats_dir/*");
- my @bleat_results = ();
- foreach my $b (@bleat_array) {
- $b =~ s/$bleats_dir\///;
- my %formatted_bleat = format_bleat($b);
- next if user_suspended($formatted_bleat{'username'});
- # search the bleat
- if ($formatted_bleat{'bleat'} =~ /$search_term/i) {
- push @bleat_results, $b;
- }
- }
- # if there are results
- if (@bleat_results) {
- $bleats_string = list_bleats_given_an_array(@bleat_results);
- } else {
- $bleats_string = div({-class=>'no-results'}, "No bleats");
- }
- }
- # print the buttons for toggling users and bleats search results
- print '<div id="search-results-container">' . "\n";
- print '<div class="users-bledats">' . "\n";
- print start_form({-action=>'bitter.cgi', -method=>'get'}) .
- hidden({-value=>"$search_term", -name=>'f'}) . hidden({-value=>'users', -name=>'fu'}) .
- submit({-value=>'Users', -id=>'search-users-button', -class=>'hidden'}) . end_form .
- start_form({-action=>'bitter.cgi', -method=>'get'}) .
- hidden({-value=>"$search_term", -name=>'f'}) . hidden({-value=>'bleats', -name=>'fb'}) .
- submit({-value=>'Bleats', -id=>'search-bleats-button', -class=>'hidden'}) . end_form;
- print '</div>' . "\n";
- if ($bleats_string) {
- print '<div id="search-toggle"><label class="toggle-off" for="search-users-button">Users</label>' . ' ' .
- '<label class="toggle-on" for="search-bleats-button">Bleats</label></div>' . br;
- print '<div id="results">' . $bleats_string . '</div>' . "\n";
- } else {
- print '<div id="search-toggle"><label class="toggle-on" for="search-users-button">Users</label>' . ' ' .
- '<label class="toggle-off" for="search-bleats-button">Bleats</label></div>' . br;
- print '<div id="results">' . $users_string . '</div>' . "\n";
- }
- print '</div>' . "\n";
- }
- #
- # display a list of users given an array of usernames
- #
- sub list_users {
- my @users = @_;
- my $valid_users = 0;
- my $string = "";
- foreach (@users) {
- my $user = $_;
- next if !user_exists($user) or user_suspended($user);
- $valid_users++;
- $string .= "<div class='individual-result'>\n";
- my %user_hash = format_user($user);
- $string .= div({-class=>'results-picture'},
- img({-src=>get_display_picture($user_hash{'username'}), -alt=>$user_hash{'full_name'},
- -class=>'results-image'})) . "\n";
- $string .= div({-class=>'results-data'},
- div({-class=>'results-name'}, $user_hash{'full_name'}, a({-href=>"?p=$user_hash{'username'}"}, "(\@$user_hash{'username'})")),
- div({-class=>'results-other'},
- "<b>Lives in</b>: ", $user_hash{'home_suburb'})) . "\n";
- $string .= "</div>\n";
- $string .= br;
- $string .= span({-class=>'sexy-line'}, "");
- $string .= br. "\n";
- }
- # if there are no results
- $string .= div({-class=>'no-results'}, "No users") if ($valid_users == 0);
- return $string;
- }
- #
- # given a list of things, a page number and number of results per page,
- # return a new array
- # in this order: page number (starting from 1), number of results, then the array
- #
- sub paginate {
- my ($page, $n, @usernames) = @_;
- my $i = ($page - 1) * $n;
- my @new_array = ();
- while ($n > 0) {
- last if !($usernames[$i]);
- push @new_array, $usernames[$i];
- $i++;
- $n--;
- }
- return @new_array;
- }
- ############################# FUNCTIONS FOR COOKIES AND LOGGING IN #######################
- sub render_login_page {
- my $username = param('username') || "";
- my $password = param('password') || "";
- my $remember = param('remember_me') || 0;
- my $error_message = "";
- if ($username and $password) {
- if (validate_user($username, $password)) {
- #new_session($username, $password, $remember);
- # redirect script
- #return;
- } else {
- # cannot validate
- if (user_exists($username) or user_suspended($username)) {
- # if the username exists
- $error_message = "Incorrect password!";
- } else {
- $error_message = "User '$username' doesn't exist.";
- }
- }
- } else {
- $error_message = "One or more fields are missing." unless (!$username and !$password);
- }
- print '<div class="login-container">';
- print '<div class="login-title">Log In</div>';
- if ($error_message) {
- # if there is an error message, print the flash thingo ( i think that is what it is called )
- print '<div id="error-flash">' . $error_message . '</div>';
- }
- print br, br;
- print '<div class="login-form">';
- print start_form({-method=>'POST', -action=>'?page=login'}),
- label('Username'), br, textfield({-id=>'username-field', -name=>'username', -value=>$username}), br, br,
- label('Password'), br, password_field({-id=>'password-field', -name=>'password'}), br, br,
- submit({-class=>'login-button', -value=>'Log In'}), br, br,
- checkbox(-name=>'remember_me',-checked=>0,-value=>'ON',-label=>'Remember this account?'),
- hidden({-value=>'login', -name=>'page'}),
- end_form;
- print '</div>'; # end of reg form
- print br . p({-class=>'signup-text'}, 'Forgot your password? ' . a({-href=>'?page=passwordrecovery'}, 'Click here to recover it!'));
- print br . p({-class=>'signup-text'}, 'Don\'t have an account? ' . a({-href=>'?page=register'}, 'Sign up here!'));
- print '</div>';
- }
- sub render_register_page {
- my $error_message = "";
- my $username = "";
- my $password = "";
- my $email = "";
- my $full_name = "";
- if ($ENV{REQUEST_METHOD} eq 'POST') {
- $username = param('username') || "";
- $password = param('password') || "";
- $email = param('email') || "";
- $full_name = param('full_name') || "";
- # check if everything is valid and entered
- # if nothing is supplied, don't show any error
- if (!$username and !$password and !$email and !$full_name) {
- $error_message = "";
- } else {
- if (!$username) {
- $error_message = "Please enter a username.";
- } elsif (!$password) {
- $error_message = "Please enter a password.";
- } elsif (!$email) {
- $error_message = "Please enter a valid e-mail address.";
- } elsif (!$full_name) {
- $error_message = "Please enter a full name.";
- }
- if ($username) {
- if (user_exists($username) or user_suspended($username) or user_not_verified($username)) {
- # user already exists
- $error_message = "User '$username' already exists!";
- $username = "";
- } elsif (!valid_username($username)) {
- # invalid
- $error_message = "Username '$username' is invalid. Usernames must start with a letter and contain only letters and numbers.";
- $username = "";
- }
- }
- if ($email) {
- if (!valid_email($email)) {
- $error_message = "Email '$email' invalid.";
- $email = "";
- }
- }
- }
- #after validation checks, check if everything has been supplied
- if ($username and $password and $email and $full_name) {
- # make account
- $error_message = "Success!";
- create_user($username, $password, $email, $full_name);
- send_email($username, $email, $full_name);
- }
- }
- print '<div class="register-container">';
- print '<div class="register-title">Register</div>';
- if ($error_message) {
- # if there is an error message, print the flash thingo ( i think that is what it is called )
- if ($error_message eq "Success!") {
- print '<div id="success-flash">' . $error_message . '</div>';
- } else {
- print '<div id="error-flash">' . $error_message . '</div>';
- }
- }
- # print the register form
- print br, br;
- print '<div class="register-form">';
- print start_form({-method=>'POST', -action=>''}), label('Username'), br, textfield({-id=>'username-field', -name=>'username', -value=>$username}), br,br,
- label('Password'), br, password_field({-id=>'password-field', -name=>'password'}), br, br,
- label('Full name'), br, textfield({-id=>'name-field', -name=>'full_name', -value=>$full_name}), br, br,
- label('Email'), br, textfield({-id=>'email-field', -name=>'email', -value=>$email}), br, br,
- submit({-class=>'signup-button', -value=>'Register'}),
- # hidden thing to send hte page because its not working HELP
- hidden({-value=>'register', -name=>'page'}), end_form;
- print '</div>'; # end of reg form
- print br;
- print '</div>';
- }
- #
- # delete the cookie
- #
- sub logout {
- my $ck = CGI::Cookie->new(-name => 'login', -value => '', -expires => '-2y');
- return $ck->bake;
- }
- #
- # validates an account and redirects to the profile page
- #
- sub account_validation {
- my ($username) = @_;
- # move the user from temp to normal
- move("$users_dir/temp/$username", "$users_dir/$username");
- my %user = format_user($username);
- # add their username, full name and email to the files
- open my $name_file, '>>', "$users_dir/search.txt" or die "$!";
- print $name_file "$user{'full_name'}" . ":" . "$username" . "\n";
- close $name_file;
- open my $email_file, '>>', "$users_dir/email.txt" or die "$!";
- print $email_file "$user{'email'}\n";
- close $email_file;
- redirect('?page=login');
- }
- #
- # if we are still waiting for the verification
- #
- sub user_not_verified {
- my ($user) = @_;
- if ( -d "$users_dir/temp/$user" ) {
- return 1;
- } else {
- return 0;
- }
- }
- #
- # creates a new user file given username, password, email, and full name
- # in a temp directory (until they validate)
- #
- sub create_user {
- my ($username, $password, $email, $full_name) = @_;
- mkdir "$users_dir/temp/$username", 0755;
- # details.txt
- open my $f, ">$users_dir/temp/$username/details.txt" or die "$!";
- my $p = <<"eof";
- listens:
- email: $email
- full_name: $full_name
- password: $password
- username: $username
- home_suburb:
- home_latitude:
- home_longitude:
- eof
- print $f $p;
- close $f;
- # bleats.txt
- open my $s, ">$users_dir/temp/$username/bleats.txt" or die "$!";
- print $s "";
- close $s;
- }
- #
- # is it a valid username? Pair this with 'user_exists' function.
- #
- sub valid_username {
- my ($username) = @_;
- return 1 if ($username =~ /^[a-z][a-z0-9][a-z0-9][a-z0-9]*$/i);
- return 0;
- }
- #
- # is it a valid e-mail?
- #
- sub valid_email {
- my ($email) = @_;
- return 1 if ($email =~ /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i);
- return 0;
- }
- #
- # does an e-mail exist?
- #
- sub email_exists {
- my ($email) = @_;
- open my $f, '<' . "$users_dir" . "/email.txt" or die "Couldn't open email.txt: $!";
- chomp(my @emails = <$f>);
- close $f;
- return grep { $_ =~ /^$email$/i } @emails;
- }
- #
- # encrypts a string
- #
- sub encrypt_username {
- my ($string) = @_;
- return $string;
- }
- #
- # does username match password
- #
- sub validate_user {
- my ($username, $password) = @_;
- if (user_exists($username) or user_suspended($username)) {
- my %user = format_user($username);
- if ($password eq $user{'password'}) {
- return 1;
- }
- }
- return 0;
- }
- #
- # is user suspended?
- #
- sub user_suspended {
- my ($user) = @_;
- open my $suspended, "<$users_dir/suspended.txt" or die "Couldn't open suspended.txt: $!";
- chomp(my @suspended_list = <$suspended>);
- close $suspended;
- return grep { $_ =~ /^$user$/i } @suspended_list;
- }
- #
- # logs in a user
- #
- sub new_session {
- if (defined($cookies{'login'})) {
- # if someone is already logged in there is a problem
- die ;
- }
- my $expiry_date = "+20m";
- my ($username, $password, $remember) = @_;
- $expiry_date = "+1y" if ($remember);
- $login = CGI::Cookie->new(-name=>'login', -value=>{username=>$username,
- password=>$password},
- -expires=>$expiry_date);
- return $login;
- }
- ####################################### HOME PAGE / NEWS FEED ###########################
- sub render_homepage {
- # if someone is logged in, render their news feed. otherwise, try and persuade them to sign up
- if ($c_user) {
- render_newsfeed($c_user);
- } else {
- print '<div class="homepage-container">' . "\n";
- print '<div class="homepage-header">Welcome to Bitter.</div>' . "\n";
- print '<div class="homepage-signup-button"><a href="?page=register">Sign Up!</a></div>' . "\n";
- print '</div>';
- }
- }
- sub render_newsfeed {
- my ($user) = @_;
- my $bleat_form = <<eof;
- <script type="text/javascript">
- function showForm() {
- if (document.getElementById('new-bleat-form').style.display=="none") {
- document.getElementById('new-bleat-form').style.display="block";
- } else {
- document.getElementById('new-bleat-form').style.display="none";
- }
- }
- </script>
- eof
- # warm greeting :D
- my %user = format_user($c_user);
- my $name = $user{'full_name'};
- $name =~ s/\s.*//;
- #NEW BLEAT FORM
- print $bleat_form . "\n";
- print '<div class="newsfeed-container">' . "\n";
- print h3("Hello, $name.");
- print center(a({-href=>'javascript:showForm();', -class=>'compose-new-bleat'}, 'Compose new bleat')) . "\n";
- print '<div>' . "\n";
- print start_form({-id => 'new-bleat-form', -action=>'bitter.cgi'}) . br .
- textarea({-maxlength=>$max_length_of_bleat, -id=>'bleat-message-box', -name=>'new_bleat'}) . br . br.
- "<input type='file' name='bleat_attachment' multiple/>" .
- '<right>' . submit({-style=>'float:right;', -name=>'Bleat!'}) . '</right>' .
- end_form . "\n" . br . br;
- print '</div>' . "\n";
- render_relevant_bleats($user);
- print '</div>' . "\n";
- # don't forget to hide the form
- print '<script type="text/javascript">document.getElementById("new-bleat-form").style.display = "none";</script>';
- }
- #
- # given a user and a bleat message, add it, and a reply
- #
- sub add_new_bleat {
- my ($user, $message, $reply, @uploaded) = @_;
- # first sanitize it and remove newlines
- $message = &trim($message);
- $message =~ tr{\n}{ };
- my $t = time();
- # then add the bleat to the list of bleats in the users file
- # then create a new file with the bleat
- my $bleat = <<"eof";
- username: $user
- bleat: $message
- time: $t
- eof
- #add longitude later
- # first find the latest bleat
- my @bleats = sort glob("$bleats_dir/*");
- my $latest_bleat_number = 0;
- if (@bleats) {
- $latest_bleat_number = $bleats[$#bleats];
- # format it a bit
- $latest_bleat_number =~ s/$bleats_dir\///;
- $latest_bleat_number = int($latest_bleat_number);
- }
- #increase by one to get new bleat
- $latest_bleat_number++;
- open my $user_file, ">>$users_dir/$user/bleats.txt" or die "Couldn't open user file to add bleat: $!";
- print $user_file "$latest_bleat_number\n";
- close $user_file;
- # now make a new file
- open my $bleats_file, ">$bleats_dir/$latest_bleat_number" or die "Couldn't create a new bleat: $!";
- print $bleats_file "$bleat";
- #print $bleats_file "latitude: $latitude\n" if $latitude;
- #print $bleats_file "longitude: $longitude\n" if $longitude;
- print $bleats_file "in_reply_to: $reply\n" if $reply;
- if (@uploaded) {
- print $bleats_file "attachments: " . join " ", @uploaded;
- }
- close $bleats_file;
- #send a message if notifications are on to the replyee
- if ($reply) {
- my %reply_to = format_bleat($reply);
- if (get_notification_settings($reply_to{'username'}, 'reply')) {
- send_notification_email_reply($reply_to{'username'}, $latest_bleat_number);
- }
- }
- # send emails to people who are tagged
- while ($bleat =~ /\@([a-zA-Z0-9-_]+)/g) {
- if (get_notification_settings($1, 'mention')) {
- send_notification_email_mention($1, $bleatID);
- }
- }
- }
- #
- # given a username, return alist of people they follow
- #
- sub list_following {
- my ($user) = @_;
- my %asd = format_user($user);
- my @following = split / /, $asd{'listens'};
- return @following;
- }
- #
- # get a list of bleats of people mentioning the given usernaem
- #
- sub get_bleats_which_I_am_tagged_in {
- my ($me) = @_;
- my $regex = '@' . "$me";
- my @final = ();
- # open each bleat file
- my @files = glob("$bleats_dir/*");
- foreach my $bl (@files) {
- $bl =~ s/$bleats_dir\///;
- my %b = format_bleat($bl);
- next if !user_exists($b{'username'}) or user_suspended($b{'username'});
- #print "BL: $bl\n";
- # check if tagged or something
- if ($b{'bleat'} =~ /($regex)([^a-zA-Z0-9]|$)?/i) {
- #print "$#final\n";
- push @final, int($bl);
- }
- }
- return @final;
- }
- #
- # draw something which contains relevant bleats to the user
- #
- sub render_relevant_bleats {
- my ($me) = @_;
- my @bleat_list = ();
- # tagged
- push @bleat_list, get_bleats_which_I_am_tagged_in($me);
- # my own
- push @bleat_list, get_users_bleats($me);
- # following
- foreach (list_following($me)) {
- next if !user_exists($_) or user_suspended($_);
- push @bleat_list, get_users_bleats($_);
- }
- # remove duplicates
- @bleat_list = remove_dups(@bleat_list);
- # sort reversed
- @bleat_list = sort { $b <=> $a } @bleat_list;
- # paginate it later
- # print it out
- print list_bleats_given_an_array(@bleat_list);
- }
- #
- # remove duplicates from list
- #
- sub remove_dups {
- my @list = @_;
- my %temp_hash;
- foreach (@list) {
- $_ = trim($_);
- $temp_hash{$_} = '420 swag';
- }
- return keys %temp_hash;
- }
- #
- # given an array of bleats, list the bleats
- #
- sub list_bleats_given_an_array {
- my @bleats = @_;
- my $string = "";
- # firstly sort the bleats
- @bleats = sort { $b <=> $a } @bleats;
- # check if we are supposed to be on a specific page of results
- my $page = param('n') || 1;
- $page = int($page);
- # check for invalid page number
- my $total_pages = (scalar @bleats);
- while ($total_pages % $bleats_per_page != 0) {
- $total_pages++;
- }
- $total_pages /= $bleats_per_page;
- $page = 1 if ($page > $total_pages or $page < 1);
- # paginate
- @bleats = paginate($page, $bleats_per_page, @bleats);
- # sort again just in case lol
- @bleats = sort { $b <=> $a } @bleats;
- # add the bleats part to the string
- foreach (@bleats) {
- $string .= print_bleat($_) . "\n";
- $string .= sexy_line();
- $string .= br;
- }
- # then add the pages if needed
- if ($total_pages > 1) {
- $string .= "<div id='page-numbers'>\n";
- my $i = 1;
- while ($i <= $total_pages) {
- # this next part is just preserving the query string so this
- # code can be used on any page :D
- my $current_request = $ENV{QUERY_STRING};
- if ($current_request =~ s/(^|&|;)n=[0-9]+/$1n=$i/i) {} else {
- if ($current_request) {
- # if there are existing params
- $current_request .= "&n=$i";
- } else {
- $current_request = "n=$i";
- }
- }
- if ($page == $i) {
- $string .= "<a class='highlighted-page' href='" . "?$current_request" . "'>$i</a> ";
- } else {
- $string .= "<a class='nonhighlighted-page' href='" . "?$current_request" . "'>$i</a> ";
- }
- $i++;
- }
- $string .= "</div>\n";
- }
- return $string;
- }
- #
- # given an array of bleats, list the bleats
- #
- sub list_bledats_given_an_array {
- my @bleats = @_;
- my $string = "";
- # sort in reverse
- @bleats = sort { $b <=> $a } @bleats;
- # then paginate i guess
- my $bleats_per_page = 10;
- my $page = param('n') || 1;
- $page = int($page);
- # sanity check for page number
- my $total_pages = (scalar @bleats);
- while ($total_pages % $bleats_per_page != 0) {
- $total_pages++;
- }
- $total_pages /= $bleats_per_page;
- $page = 1 if ($page > $total_pages or $page < 1);
- @bleats = paginate($page, $bleats_per_page, @bleats);
- # sort in reverse again just in case
- @bleats = sort { $b <=> $a } @bleats;
- # sort in reverse order
- foreach $bleatID (@bleats) {
- chomp $bleatID;
- my %bleat_data = format_bleat($bleatID);
- #print "LIST_BLEATS: $bleatID\n";
- my $t = localtime($bleat_data{'time'});
- my $dp = get_display_picture($bleat_data{'username'});
- $string .= '<div>' . "\n";
- $string .= "<a href=\"?p=$bleat_data{'username'}\">" .
- img({-src => $dp, -alt => $bleat_data{'username'}, -class => 'newsfeed-dps'}) . "</a>";
- $string .= '<b>' . a({-href=>"?p=$bleat_data{'username'}"}, $bleat_data{'username'}) . " @ " . a( { -href => "?b=$bleatID" }, $t) . '</b>' . br;
- $string .= '<div class="bleat-msg">' . bleat_tags($bleat_data{'bleat'}, $bleat_data{'id'}) . '</div>';
- $string .= br;
- # now do the reply or delete
- $string .= a({href=>"javascript:show_reply_form('$bleatID');"}, 'Reply');
- $string .= " " . a({href=>"javascript:delete_bleat('$bleatID');"}, 'Delete') if $bleat_data{'username'} =~ /^$c_user$/i;
- # attahcments
- my $see_attachments = "";
- if ($bleat_data{'attachments'}) {
- $see_attachments = " Attachments: ";
- my @attachments = split /\s+/, $bleat_data{'attachments'};
- my $i = 1;
- foreach (@attachments) {
- $see_attachments .= " " . a({-href=>"javascript:see_attachments('../$_', $bleat_data{'id'});"}, $i);
- $i++;
- }
- }
- $string .= $see_attachments;
- $string .= br . '<div id="b' . $bleatID . '">' . "\n" . generate_reply_form($bleat_data{'username'}, $bleatID) . '</div>';
- $string .= br . '<div id="a' . $bleatID . '"></div>';
- # hide it first
- $string .= '<script type="text/javascript">document.getElementById("b' . $bleatID . '").style.display = "none";</script>';
- $string .= br . br . span({-class=>'sexy-line'}, "") . br;
- $string .= '</div>' . "\n";
- }
- # if there are multiple pages, add the page number thingo
- if ($total_pages > 1) {
- $string .= "<div id='page-numbers'>\n";
- $string .= "<ul>\n";
- my $i = 1;
- while ($i < $total_pages) {
- my $current_request = $ENV{QUERY_STRING};
- #print "QUERY STRING: $ENV{QUERY_STRING}";
- #chomp $current_request;
- if ($current_request =~ s/(^|&|;)n=[0-9]+/$1n=$i/i) {} else {
- if ($current_request) {
- # if there are existing params
- $current_request .= "&n=$i";
- } else {
- $current_request = "n=$i";
- }
- }
- $string .= "<li><a href='" . "?$current_request" . "'>$i</a></li>";
- $i++;
- #add a new line every 10 pages
- if ($i != 0 and $i % 10 == 0) {
- $string .= br;
- }
- }
- $string .= "</ul>\n";
- $string .= "</div>\n";
- }
- return $string;
- }
- #
- # print the listen button given the user in question
- #
- sub listen_button {
- return if !$c_user;
- my ($q) = @_;
- my $string = "";
- my %me = format_user($c_user);
- # grab list of people this guy is listening to
- my @listening = split /\s+/, $me{'listens'};
- # if the user is in the list
- if (grep {$_ =~ /^$q$/i} @listening) {
- $string .= start_form({-action => "bitter.cgi", -method=>'get'}) .
- hidden({-name=>'p', -value=>$q}) .
- hidden({-name=>'unlisten', -value=>$q}) .
- submit({-value => 'Unlisten', -name=>''}) . end_form;
- } else {
- $string .= start_form({-action => "bitter.cgi", -method=>'get'}) .
- hidden({-name=>'p', -value=>$q}) .
- hidden({-name=>'listen', -value=>$q}) .
- submit({-value => 'Listen', -name=>''}) . end_form;
- }
- return $string;
- }
- #
- # unlisten to someone
- #
- sub unlisten_to {
- return if !$c_user;
- my ($person_to_unfollow) = @_;
- open my $f, "<$users_dir/$c_user/details.txt" or die "Couldn't open user file: $!";
- chomp(my @temp_file = <$f>);
- close $f;
- # change the line
- foreach my $line (@temp_file) {
- next if $line !~ /^listens: /;
- my @following = split /\s+/, $line;
- shift @following;
- @following = grep { $_ !~ /$person_to_unfollow/i } @following;
- $line = "listens: " . join " ", @following;
- last;
- }
- open my $ff, ">$users_dir/$c_user/details.txt" or die "Couldn't open user file: $!";
- print $ff join "\n", @temp_file;
- close $ff;
- }
- #
- # listen to someone
- #
- sub listen_to {
- return if !$c_user;
- my ($person_to_follow) = @_;
- open my $f, "<$users_dir/$c_user/details.txt" or die "Couldn't open user file: $!";
- chomp(my @temp_file = <$f>);
- close $f;
- # change the line
- foreach my $line (@temp_file) {
- next if $line !~ /^listens: /;
- my @following = split /\s+/, $line;
- if (grep {$_ =~ /^$person_to_follow$/i} @following) {return;} # return if already following
- shift @following;
- push @following, $person_to_follow;
- $line = "listens: " . join " ", @following;
- last;
- }
- open my $ff, ">$users_dir/$c_user/details.txt" or die "Couldn't open user file: $!";
- print $ff join "\n", @temp_file;
- close $ff;
- # send the email
- if (get_notification_settings($person_to_follow, 'listen')) {
- send_notification_email_listen($person_to_follow, $c_user);
- }
- }
- ########################### FUNCTIONS FOR SETTINGS PAGE #################################
- sub render_settings_page {
- my %user_details = format_user($c_user);
- print "<div id='settings-container'>\n";
- print h4('Settings') . br;
- $CGI::POST_MAX = 1024 * 5000; # 5 mb limit
- # if we have params here, print a green flash thing
- my $error_message = "";
- my $success_message = "";
- my @changed_details = ();
- #NORMAL DETAILS
- my $full_name = param('full_name') || "";
- my $location = param('location') || "";
- my $email = param('email') || "";
- my $description = param('description') || "";
- my $updated = param('updated') || ""; # to see if we pressed the button so we don't update anythign when we
- # come to the page
- # BACKGROUND AND DP STUFF
- my $new_dp = upload('new_dp');
- my $new_bg = upload('new_bg');
- my $dp_update = param('dp_update') || "";
- my $delete_dp = param('delete_dp') || "";
- my $bg_update = param('bg_update') || "";
- my $delete_bg = param('delete_bg') || "";
- #NOTIFICAION STUFF
- my $mention = param('mention') ? 1:0;
- my $reply = param('reply') ? 1:0;
- my $listen = param('listen') ? 1:0;
- if ($updated) {
- if ($mention != get_notification_settings($c_user, 'mention')) {
- push @changed_details, 'notification settings';
- }
- if ($reply != get_notification_settings($c_user, 'reply')) {
- push @changed_details, 'notification settings';
- }
- if ($listen != get_notification_settings($c_user, 'listen')) {
- push @changed_details, 'notification settings';
- }
- }
- set_notification_settings($c_user, $mention, $reply, $listen) if $updated;
- #sanitize
- $full_name = &trim($full_name);
- $location = &trim($location);
- $email = &trim($email);
- $description = &trim($description);
- if ($updated and $full_name and $full_name ne $user_details{'full_name'}) {
- change_name($c_user, $full_name);
- push @changed_details, "name";
- }
- if ($updated and $email and $email ne $user_details{'email'}) {
- change_email($c_user, $email);
- push @changed_details, "email";
- }
- if ($updated and $description ne $user_details{'description'}) {
- change_desc($c_user, $description);
- push @changed_details, "description";
- }
- if ($updated and $location ne $user_details{'home_suburb'}) {
- change_location($c_user, $location);
- push @changed_details, "location";
- }
- if ($dp_update and $new_dp) {
- my $dp_name = param('new_dp');
- # make sure it is an image
- if ($dp_name =~ /^[a-z0-9_-]+\.jpe?g$/i) { # make sure it is not malicious
- open my $dp, ">$users_dir/$c_user/profile.jpg" or die "Couldn't open profile.jpg: $!";
- binmode $dp;
- while (my $line = <$new_dp>) {
- print $dp $line;
- }
- close $dp;
- push @changed_details, "profile picture";
- } else {
- $error_message = "Only .jpg files allowed.";
- }
- }
- if ($bg_update and $new_bg) {
- my $bg_name = param('new_bg');
- # make sure it is an image
- if ($bg_name =~ /^[a-z0-9_-]+\.jpe?g$/i) { # make sure it is not malicious
- open my $bg, ">$users_dir/$c_user/background.jpg" or die "Couldn't open background.jpg: $!";
- binmode $bg;
- while (my $line = <$new_bg>) {
- print $bg $line;
- }
- close $bg;
- push @changed_details, "background";
- } else {
- $error_message = "Only .jpg files allowed.";
- }
- }
- if ($delete_dp) {
- unlink "$users_dir/$c_user/profile.jpg";
- $success_message = "Successfully deleted profile picture.";
- }
- if ($delete_bg) {
- unlink "$users_dir/$c_user/background.jpg";
- $success_message = "Successfully deleted background.";
- }
- # FLASHY COOL ERROR AND SUCCESS BUBBLE STUFF
- @changed_details = remove_dups(@changed_details);
- if (@changed_details) {
- $success_message = "Successfully changed " . join(", ", @changed_details) . ".";
- }
- if ($success_message) {
- print div({-id=>'success-flash'}, $success_message) . "\n";
- }
- if ($error_message) {
- print div({-id=>'error-flash'}, $error_message) . "\n";
- }
- # form for normal details
- print '<div id="normal-details">';
- print start_form .
- '<fieldset><legend>User details</legend>' .
- '<center>' .
- label('Full name') . br . textfield({-value=>$user_details{'full_name'}, -name=>'full_name', -class=>'settings-textbox'}) . br .
- label('Location') . br . textfield({-value=>$user_details{'home_suburb'}, -name=>'location', -class=>'settings-textbox'}) . br .
- label('E-mail') . br . textfield({-value=>$user_details{'email'}, -name=>'email', -class=>'settings-textbox'}) . br .
- label('Description') . br . textarea({-value=>$user_details{'description'}, -name=>'description', -class=>'settings-textarea'}) . br .
- '</center>' .
- '</fieldset>' . br;
- #notification settings
- print '<fieldset><legend>Notifications</legend>';
- print checkbox(-name=>'mention', -checked=>get_notification_settings($c_user, 'mention'),
- -value=>'ON', -label=>'Mentioned in a bleat') . br;
- print checkbox(-name=>'reply', -checked=>get_notification_settings($c_user, 'reply'),
- -value=>'ON', -label=>'Someone posts a reply to my bleat') . br;
- print checkbox(-name=>'listen', -checked=>get_notification_settings($c_user, 'listen'),
- -value=>'ON', -label=>'I get a new listener') . br;
- print '</fieldset>' . br .
- #page params
- hidden({-name=>'page',-value=>'settings'}) .
- hidden({-name=>'updated',-value=>'69'}) .
- center(submit) .
- end_form;
- # delete/suspend account
- print '<center>';
- print '<button onclick="javascript:suspend();">Suspend account</button> ';
- print '<script type="text/javascript">function suspend() {if (confirm("Are you sure you want to suspend your account?")) {window.location="?page=suspend";}}</script>';
- print ' <button onclick="javascript:delete_account();">Delete account</button>';
- print '<script type="text/javascript">function delete_account() {if (confirm("Are you sure you want to delete your account?")) {window.location="?page=delete";}}</script>';
- print '</center>';
- print '</div>';
- # PROFILE PICTURE
- print '<div id="change-profile-pic">';
- print '<fieldset><legend>Customise your look</legend>' . "\n";
- print b('Current profile picture') . br;
- print img({-src=>get_display_picture($c_user), -alt=>$user_details{'full_name'}, -id=>'settings-dp'}) . br;
- print start_form({-enctype=>'multipart/form-data'});
- print filefield(-name=>'new_dp') . br;
- print hidden({-name=>'page', -value=>'settings'});
- print hidden({-name=>'dp_update', -value=>'420'});
- print submit('Upload');
- print end_form;
- if (get_display_picture($c_user) ne "$default_picture") {
- print start_form . hidden({-name=>'page', -value=>'settings'}) .
- hidden({-name=>'delete_dp', -value=>'123'}) . submit('Delete') . end_form;
- }
- print br . br;
- # BACKGROUND
- if (my $bg = user_has_background($c_user)) {
- print b('Current background') . br . img({-src=>"../$bg", -alt=>"Background", -id=>'settings-bg'});
- } else {
- print b('Upload a background');
- }
- print start_form({-enctype=>'multipart/form-data'});
- print filefield(-name=>'new_bg') . br;
- print hidden({-name=>'page', -value=>'settings'});
- print hidden({-name=>'bg_update', -value=>'420'});
- print submit('Upload');
- print end_form;
- if (user_has_background($c_user)) {
- print start_form . hidden({-name=>'page', -value=>'settings'}) .
- hidden({-name=>'delete_bg', -value=>'123'}) . submit('Delete') . end_form;
- }
- print '</fieldset>';
- print '</div>';
- print "</div>\n";
- }
- #
- # get notification settings from someone
- # arguments: 'mention' for mention, 'reply' for reply
- # and 'listen' for listener
- #
- sub get_notification_settings {
- my ($user, $which) = @_;
- my @settings = ();
- if ( -f "$users_dir/$user/notification.txt" ) {
- open my $n, "<$users_dir/$user/notification.txt" or die "Couldn't open notifcations.txt, user : $user: $!";
- chomp (@settings = <$n>);
- close $n;
- } else {
- # doesnt exist then make one
- open my $n, ">$users_dir/$user/notification.txt" or die "Couldn't open notifcations.txt,user: $user: $!";
- print $n "\n";
- close $n;
- @settings = ('ben');
- }
- return (grep { $_ =~ /$which/i } @settings) ? 1:0;
- }
- #
- # set notification settings for user
- # arguments: USER, MENTIONED, REPLIED TO, NEW LISTENER
- #
- sub set_notification_settings {
- my ($user, $mention, $reply, $listen) = @_;
- open my $n, ">$users_dir/$user/notification.txt" or die "Couldn't open notifcations.txt: $!";
- print $n "mention\n" if $mention;
- print $n "reply\n" if $reply;
- print $n "listen\n" if $listen;
- close $n;
- }
- #
- # changes the name of someone
- #
- sub change_name {
- my ($user, $new_name) = @_;
- my %u = format_user($user);
- #$new_name = escapeHTML($new_name);
- my @new_file = ();
- open my $deets, "<$users_dir/$user/details.txt" or die "Couldn't open details.txt: $!";
- while (my $line = <$deets>) {
- chomp $line;
- push @new_file, $line if $line !~ /^full_name: /;
- push @new_file, "full_name: $new_name" if $line =~ /^full_name: /;
- }
- close $deets;
- #create new file
- open my $july, ">$users_dir/$user/details.txt" or die "Couldn't open details.txt: $!";
- print $july join "\n", @new_file;
- close $july;
- #change search file
- open my $email_file, "<$users_dir/search.txt" or die "Couldn't open search file: $!";
- chomp (my @search = <$email_file>);
- close $email_file;
- foreach (@search) {
- chomp $_;
- if ($_ =~ /^$u{'full_name'}:$user$/i) {
- $_ = "$new_name:$user";
- }
- }
- open my $e_file, ">$users_dir/search.txt" or die "Couldn't open search file: $!";
- print $e_file join("\n", @search);
- print $e_file "\n";
- close $e_file;
- }
- #
- # changes the location of someone
- #
- sub change_location {
- my ($user, $new_name) = @_;
- #$new_name = escapeHTML($new_name);
- my @new_file = ();
- open my $deets, "<$users_dir/$user/details.txt" or die "Couldn't open details.txt: $!";
- while (my $line = <$deets>) {
- chomp $line;
- push @new_file, $line if $line !~ /^home_suburb: /;
- push @new_file, "home_suburb: $new_name" if $line =~ /^home_suburb: /;
- }
- close $deets;
- #create new file
- open my $july, ">$users_dir/$user/details.txt" or die "Couldn't open details.txt: $!";
- print $july join "\n", @new_file;
- close $july;
- }
- #
- # changes the email of someone
- #
- sub change_email {
- my ($user, $new_name) = @_;
- my %u = format_user($user);
- #$new_name = escapeHTML($new_name);
- my @new_file = ();
- open my $deets, "<$users_dir/$user/details.txt" or die "Couldn't open details.txt: $!";
- while (my $line = <$deets>) {
- chomp $line;
- push @new_file, $line if $line !~ /^email: /;
- push @new_file, "email: $new_name" if $line =~ /^email: /;
- }
- close $deets;
- #create new file
- open my $july, ">$users_dir/$user/details.txt" or die "Couldn't open details.txt: $!";
- print $july join "\n", @new_file;
- close $july;
- #change email file
- open my $email_file, "<$users_dir/email.txt" or die "Couldn't open e-mail file: $!";
- chomp (my @emails = <$email_file>);
- close $email_file;
- foreach (@emails) {
- chomp $_;
- if ($_ =~ /^$u{'email'}$/i) {
- $_ = $new_name;
- }
- }
- open my $e_file, ">$users_dir/email.txt" or die "Couldn't open email file: $!";
- print $e_file join("\n", @emails);
- print $e_file "\n";
- close $e_file;
- }
- #
- # changes the description of someone
- #
- sub change_desc {
- my ($user, $new_name) = @_;
- #$new_name = escapeHTML($new_name);
- open my $deets, ">$users_dir/$user/description.txt" or die "Couldn't open details.txt: $!";
- print $deets $new_name;
- close $deets;
- }
- #
- # deletes a user
- #
- sub delete_user {
- my ($user) = @_;
- my %u = format_user($user);
- my $user_email = $u{'email'};
- my $user_full_name = $u{'full_name'};
- #remove from email.txt and name.txt and search.txt
- open my $emails, "<$users_dir/email.txt" or die "Couldn't open email.txt: $!";
- chomp (my @lines = <$emails>);
- close $emails;
- @lines = grep {$_ !~ /^$user_email$/i} @lines;
- open my $email, ">$users_dir/email.txt" or die "Couldn't open email.txt: $!";
- print $email join("\n", @lines);
- print $email "\n";
- close $email;
- #open my $names, "<$users_dir/name.txt" or die "Couldn't open name.txt: $!";
- #chomp (my @lines2 = <$names>);
- #close $names;
- #@lines2 = grep {$_ !~ /^$user_full_name$/i} @lines2;
- #open my $names, ">$users_dir/name.txt" or die "Couldn't open name.txt: $!";
- #print $names join("\n", @lines2);
- #print $names "\n";
- #close $names;
- open my $searches, "<$users_dir/search.txt" or die "Couldn't open search.txt: $!";
- chomp (my @lines3 = <$searches>);
- close $searches;
- @lines3 = grep {$_ !~ /^$user_full_name:$user$/i} @lines3;
- open my $search, ">$users_dir/search.txt" or die "Couldn't open search.txt: $!";
- print $search join("\n", @lines3);
- print $search "\n";
- close $search;
- # now delete all their bleats
- open my $bleat_file, "<$users_dir/$user/bleats.txt" or die "Couldn;t open blet file : $!";
- chomp (my @bleats = <$bleat_file>);
- close $bleat_file;
- # first remove all the replies tot heir bleats
- my @l;
- my @all_bleats = glob("$bleats_dir/*");
- foreach my $file (@all_bleats) {
- @l = ();
- open my $b, "<$file" or die "Couldn't open: $!";
- while (<$b>) {
- push @l, $_;
- next unless $_ =~ /^in_reply_to: (.*)/;
- my $temp = $1;
- chomp $temp;
- if (grep {$_ =~ /^$temp$/} @bleats) {
- pop @l; # undo the push if it is a reply to one of the deleted users' bleats
- }
- }
- close $b;
- next if (grep {$_ =~ /^in_reply_to: /} @l); # to save some time
- open my $c, ">$file" or die "Couldn't open to write: $!";
- print $c join("\n", @l);
- print $c "\n";
- close $c;
- }
- # now delete the bleat files
- foreach my $to_delete (@bleats) {
- if (-f "$bleats_dir/$to_delete") {
- unlink "$bleats_dir/$to_delete";
- }
- }
- #finally delete the user profile folder
- rmtree "$users_dir/$user";
- }
- #
- # suspsneds a user
- #
- sub suspend_user {
- my ($user) = @_;
- # add to file
- open my $suspend, "<$users_dir/suspended.txt" or die "Couldn't open suspended: $!";
- chomp (my @lines = <$suspend>);
- close $suspend;
- push @lines, "$user\n";
- open my $sus9audpaosusidah9839025b890dniskcjnoixmcpozi90q84b9ns98d, ">$users_dir/suspended.txt" or die "$!"; # i am tired ok
- print $sus9audpaosusidah9839025b890dniskcjnoixmcpozi90q84b9ns98d join "\n", @lines;
- close $sus9audpaosusidah9839025b890dniskcjnoixmcpozi90q84b9ns98d;
- }
- #
- # unsuspends a user
- #
- sub unsuspend_user {
- my ($user) = @_;
- open my $suspend, "<$users_dir/suspended.txt" or die "Couldn't open suspended: $!";
- chomp (my @lines = <$suspend>);
- close $suspend;
- trim($_) for @lines;
- @lines = grep { $_ !~ /^$user$/i } @lines;
- open my $sus9audpaosusidah9839025b890dniskcjnoixmcpozi90q84b9ns98d, ">$users_dir/suspended.txt" or die "$!"; # i am tired ok
- print $sus9audpaosusidah9839025b890dniskcjnoixmcpozi90q84b9ns98d join "\n", @lines;
- close $sus9audpaosusidah9839025b890dniskcjnoixmcpozi90q84b9ns98d;
- }
- #
- ##################### PASSWORD RECOVERY ##############################################
- #
- sub render_password_recovery_page {
- my $update = param('update_pwd') || "";
- if ($update) {
- my $user = param('user');
- $update = trim($update);
- $user = trim($user);
- #print $user;
- change_password($user, $update);
- print '<div id="recovery-container">';
- print p('Password successfully changed. Please click <a href="?page=login">here</a> to sign in.');
- print '</div>';
- print end_html;
- exit 0;
- }
- # if they have received the e-mail, then
- # verify that the randomly generated filename
- # contains the correct username
- my $recover = param('recover') || "";
- if ($recover) {
- if (-f "$users_dir/$recover.txt") {
- # if there is a file then hoorah
- open my $u, "<$users_dir/$recover.txt" or die "$!";
- my $user_to_reset = "";
- while (<$u>) {
- $user_to_reset = $_ if $_;
- }
- close $u;
- unlink "$users_dir/$recover.txt";
- print "<div id='recovery-container'>";
- print label('Enter new password:') . br . password_field({-id=>'passone'}) . br .
- label('Enter it again:') . br . password_field({-id=>'passtwo'}) . a({-href=>"javascript:check_password('$user_to_reset');"}, 'Change');
- my $js_check = <<"eof";
- <script type="text/javascript">
- function check_password(user){
- var one = document.getElementById("passone");
- var two = document.getElementById("passtwo");
- if (one.value == two.value) {
- var dict = get_params();
- dict["update_pwd"] = one.value;
- dict["user"] = user;
- post("bitter.cgi", dict);
- } else {
- alert('Passwords do not match.');
- }
- }
- </script>
- eof
- print $js_check;
- print "</div>";
- print end_html;
- exit 0;
- }
- }
- # if they submit an e-mail, check that it exists
- # then if it does, make a file with a random name
- # and send them an e-mail
- my $email = param('email') || "";
- if ($email) {
- $email = trim($email);
- open my $emails, "<$users_dir/email.txt" or die "$!";
- chomp(my @eee = <$emails>);
- close $emails;
- if (grep {$_ =~ /^$email$/i} @eee) {
- # find whose thing it belongs to
- my @users = glob("$users_dir/*");
- foreach my $user (@users) {
- if (-d $user and -f "$user/details.txt") {
- open my $details, "<$user/details.txt" or die "Couldn't open $user/details.txt: $!";
- chomp(my @deets = <$details>);
- close $details;
- if (grep { $_ =~ /^email: $email$/i } @deets) {
- #found the email
- # we make a file using randomly generated name
- $user =~ s/$users_dir\///;
- my $random = generate_random_name();
- open my $pwd_recovery, ">$users_dir/$random.txt" or die "Couldn't create pwd recovery: $!";
- print $pwd_recovery $user."\n";
- close $pwd_recovery;
- # send email
- send_password_recovery_email($random, $email);
- print div({-id=>'recovery-container'}, p('Please check your e-mail.'));
- }
- }
- }
- } else {
- print '<div id="recovery-container">' . "\n";
- print '<p>Sorry, that e-mail does not exist. Please try again.</p>';
- print start_form . textfield({-name=>'email'}) . hidden({-name=>'page', -value=>'passwordrecovery'}) . submit . end_form;
- print '</div>' . "\n";
- }
- } else {
- print '<div id="recovery-container">' . "\n";
- print '<p>Enter your e-mail and we will send you a password recovery link.</p>';
- print start_form . textfield({-name=>'email'}) . hidden({-name=>'page', -value=>'passwordrecovery'}) . submit . end_form;
- print '</div>' . "\n";
- }
- }
- #
- # generates a cool name
- #
- sub generate_random_name {
- my @array = ('apple', 'banana', 'carrot', 'durian', 'e', 'falafel', 'grape', 'hommus', 'italian', 'jelly', 'kangaroo');
- return 'pwd' . $array[int(rand(11))];
- }
- #
- # change someones password
- #
- sub change_password {
- my ($user, $pwd) = @_;
- # get the file contents into an array
- open my $file, "<$users_dir/$user/details.txt" or die "couldn't open details: $!";
- chomp(my@lines=<$file>);
- close $file;
- # modify the array
- foreach (@lines) {
- $_ = "password: $pwd" if ($_ =~ /^password: /);
- }
- # write back to the file
- open my $file1, ">$users_dir/$user/details.txt" or die "couldn't open details: $!";
- print $file1 join "\n", @lines;
- print $file1 "\n";
- close $file1;
- }
- ############################ FUNCTIONS FOR SENDING EMAILS ####################################
- #
- # sends a notification e-mail for mention
- #
- sub send_notification_email_mention {
- my ($to, $bleatID) = @_;
- my %user = format_user($to);
- my $text = <<"eof";
- Hello, $user{'full_name'}!
- Someone has mentioned you in a bleat! Go to bitter.cgi?b=$bleatID to check it out!
- eof
- system("python", "sendmail.py", "Bitter", "$user{'email'}", "Account verification", "$text") == 0 or die "couldnt send email: $!";
- }
- #
- # sends a notification e-mail for new replies
- #
- sub send_notification_email_reply {
- my ($to, $bleatID) = @_;
- my %user = format_user($to);
- my $text = <<"eof";
- Hello, $user{'full_name'}!
- Someone has replied to your bleat!. Go to bitter.cgi?b=$bleatID to check it out!
- eof
- system("python", "sendmail.py", "Bitter", "$user{'email'}", "Account verification", "$text") == 0 or die "couldnt send email: $!";
- }
- #
- # sends a notification e-mail for new listener
- #
- sub send_notification_email_listen {
- my ($to, $listener) = @_;
- my %user = format_user($to);
- my $text = <<"eof";
- Hello, $user{'full_name'}!
- $listener just followed you! POPULAR. Check out their profile at bitter.cgi?p=$listener!
- eof
- system("python", "sendmail.py", "Bitter", "$user{'email'}", "Account verification", "$text") == 0 or die "couldnt send email: $!";
- }
- #
- # sends a validation e-mail
- #
- sub send_email {
- my ($username, $email, $full_name) = @_;
- my $text = <<"eof";
- Hello, $full_name!
- Welcome to Bitter. Please go to bitter.cgi?v=$username to complete your registration.
- eof
- system("python", "sendmail.py", "Bitter", "$email", "Account verification", "$text") == 0 or die "couldnt send email: $!";
- }
- #
- # sends a password recovery e-mail
- #
- sub send_password_recovery_email {
- my ($random, $email) = @_;
- my $text = <<"eof";
- Hello!
- Please go to bitter.cgi?page=passwordrecovery&recover=$random to complete your registration.
- eof
- system("python", "sendmail.py", "Bitter", "$email", "Password recovery", "$text") == 0 or die "couldnt send email: $!";
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement