Advertisement
Guest User

Untitled

a guest
Oct 29th, 2016
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 28.18 KB | None | 0 0
  1. #!/usr/bin/perl -w
  2.  
  3. # written by andrewt@cse.unsw.edu.au September 2015
  4. # http://cgi.cse.unsw.edu.au/~cs2041/assignments/bitter/
  5. # ACKNOWLDGEMENTS: Use of Materialize CSS http://materializecss.com/
  6.  
  7.  
  8. use CGI qw/:all/;
  9. use CGI::Carp qw/fatalsToBrowser warningsToBrowser/;
  10. use CGI::Cookie;
  11. use CGI::Session;
  12.  
  13.  
  14. sub main() {
  15.     #### DEFINING GLOBAL VARIABLES
  16.     ## which determine the page to load
  17.  
  18.     $logging_out = param('logging_out');
  19.    
  20.     $debug = 1;
  21.     $dataset_size = "medium";
  22.     $users_dir = "dataset-$dataset_size/users";
  23.     $bleats_dir = "dataset-$dataset_size/bleats";
  24.  
  25.     $searched = param('search_query') || '';
  26.     $bleat_searched = param('bleat_search_query') || '';
  27.    
  28.     #tests if showing homepage or a user page
  29.     my $user_to_show;
  30.     my $page = "home";
  31.     if (defined(param('page'))) { $page = param('page'); }
  32.     if (defined(param('user'))) { $user_to_show = param('user');
  33.     } else { $user_to_show = $curr_user; }
  34.    
  35.     #Setting [un]listen_attempt variable such that page redirects
  36.     #  to the same page where the listen happened
  37.     $listen_attempt = param('listen_user') || '';
  38.     $unlisten_attempt = param('unlisten_user') || '';
  39.     $listened_from_search = param('search_listen') || '';
  40.     $unlistened_from_search = param('search_unlisten') || '';
  41.     $listened_from_user = param('userpage_listen') || '';
  42.     $unlistened_from_user = param('userpage_unlisten') || '';
  43.     if ($listened_from_search) {
  44.         $searched = param('curr_search');
  45.         $listen_attempt = $listened_from_search;
  46.     } elsif ($unlistened_from_search) {
  47.         $searched = param('curr_search');
  48.         $unlisten_attempt = $unlistened_from_search;
  49.     }
  50.     if ($listened_from_user) {
  51.         $listen_attempt = $listened_from_user;
  52.         $page = "user";
  53.         $user_to_show = $listened_from_user;
  54.     } elsif ($unlistened_from_user) {
  55.         $unlisten_attempt = $unlistened_from_user;
  56.         $page = "user";
  57.         $user_to_show = $unlistened_from_user;
  58.     }
  59.  
  60.     #Get username and password from textfields
  61.     $entered_username = param('username_field') || '';
  62.     $entered_password = param('password_field') || '';
  63.  
  64.  
  65.     #retrieving current session
  66.     $sesh = CGI::Session->load() or die CGI::Session->errstr();
  67.    
  68.     $curr_user = $sesh->param('username');
  69.     $logged_in = $sesh->param('_isLoggedIn');
  70.  
  71.    
  72.     #If curr_user is attempting to listen to another user,
  73.     # these changes are made before page loaded
  74.     if ($listen_attempt) { make_listen($curr_user, $listen_attempt); }
  75.     if ($unlisten_attempt) { make_unlisten($curr_user, $unlisten_attempt); }
  76.  
  77.     #IF USER IS ATTEMPTING TO LOG IN
  78.     if ($entered_username || $entered_password) {
  79.         if (validate_pw($entered_username, $entered_password) eq 1) { #SUCCESSFUL LOGIN
  80.             #Setting up Session ID
  81.             $session = CGI::Session->new();
  82.             $session->param('username', $entered_username);
  83.             $session->param('_isLoggedIn', 'true');
  84.             $session->expire('_isLoggedIn', '+20m');
  85.             $session->expire('+1d');
  86.             $CGISESSID = $session->id();
  87.             $cookie = CGI::Cookie->new(-name=>$session->name(), -value=>$session->id());
  88.             print redirect(-uri=>"bitter.cgi", -cookie=>$cookie, @_);
  89.             print page_header();
  90.             warningsToBrowser(1);
  91.             CGI::Session->name("BITTER_SESSION");
  92.             print nav_bar(0, $entered_username);
  93.             print user_page("$users_dir/$entered_username");
  94.         } else { #UNSUCCESSFULY LOGIN - show login page
  95.             print page_header();
  96.             warningsToBrowser(1);
  97.             CGI::Session->name("BITTER_SESSION");
  98.             print nav_bar(1);
  99.            
  100.             print login_page();
  101.  
  102.             $error_msg = validate_pw($entered_username, $entered_password);
  103.             print "<p class=\"flow-text\">$error_msg</p>";
  104.         }
  105.     } elsif ($logging_out eq 1) {
  106.         $sesh->delete();
  107.         $sesh->flush();
  108.        
  109.         print page_header();
  110.         warningsToBrowser(1);
  111.         CGI::Session->name("BITTER_SESSION");
  112.         print nav_bar(1);
  113.  
  114.         print login_page();
  115.        
  116.     } elsif ($logged_in) { #IF ALREADY LOGGED IN - decide page    
  117.         print page_header();
  118.         warningsToBrowser(1);
  119.         CGI::Session->name("BITTER_SESSION");
  120.         print nav_bar(0, $curr_user);
  121.    
  122.         #write new bleats if necessary
  123.         my $new_bleat = param('new_bleat_area') || '';
  124.         my $new_reply = param('reply_text') || '';
  125.         my $in_reply_to = param('in_reply_to') || '';
  126.         if ($new_reply) {
  127.             new_bleat($new_reply, $in_reply_to);
  128.         }
  129.         if ($new_bleat) {
  130.             new_bleat($new_bleat);
  131.         }
  132.  
  133.         #delete bleats if necessary
  134.         my $delete_bleat_id = param('delete_bleat') || '';
  135.         if ($delete_bleat_id) {
  136.             delete_bleat($delete_bleat_id);
  137.         }
  138.  
  139.         if ($bleat_searched) {
  140.             print bleat_search_results($bleat_searched);
  141.         } elsif ($searched) {
  142.             print search_results($searched);
  143.         } elsif ($page eq "home") {
  144.             print newsfeed($curr_user);
  145.         } elsif ($page eq "user") {
  146.             print user_page("$users_dir/$user_to_show");
  147.         }
  148.  
  149.    
  150.     } else { #IF NOT LOGGED IN - show login screen
  151.         print page_header();
  152.         warningsToBrowser(1);
  153.         CGI::Session->name("BITTER_SESSION");
  154.         print nav_bar(1);
  155.  
  156.         print login_page();
  157.     }
  158.  
  159.     #IMPORTING JAVASCRIPT FILES
  160.     print "<script type=\"text/javascript\" src=\"https://code.jquery.com/jquery-2.1.1.min.js\"></script>\n";
  161.     print "<script type=\"text/javascript\" src=\"materialize.min.js\"></script>";
  162.  
  163. }
  164.  
  165. #DELETES THE BLEAT OF THE INPUTTED ID
  166. sub delete_bleat {
  167.     my ($id) = @_;
  168.     unlink "$bleats_dir/$id";
  169.     my $bleat_dir = "$users_dir/$curr_user/bleats.txt";
  170.     open A, "<$bleat_dir" or die "can not open $bleat_dir: $!";
  171.     my @new_bleat_file = ();
  172.     foreach my $line (<A>) {
  173.         chomp $line;
  174.         if ($id !~ /$line/) {
  175.             push(@new_bleat_file, $line);
  176.         }
  177.     }
  178.     close A;
  179.  
  180.     open (my $fh, '>', $bleat_dir) or die "can not open file $bleat_dir: $!";
  181.     foreach my $bleat (@new_bleat_file) {
  182.         print $fh "$bleat\n";
  183.     }
  184.     close $fh;
  185. }
  186.  
  187. #GENERATES AN UNUSED BLEAT ID FOR NEW BLEATS
  188. sub generate_bleat_id {
  189.     my $largest = "";
  190.     foreach my $line(glob "$bleats_dir/*") {
  191.         $largest = $line;
  192.         $largest =~ s/^$bleats_dir\///;
  193.     }
  194.     $largest += 5;
  195.     return $largest;
  196. }
  197.  
  198. #GENERATES NEW BLEAT OF THE PASSED IN MESSAGE
  199. sub new_bleat {
  200.     my ($new_bleat, $in_reply_to) = @_;
  201.     my @new_bleat_info = ();
  202.     push (@new_bleat_info, "bleat: $new_bleat");
  203.     push (@new_bleat_info, "username: $curr_user");
  204.    
  205.     #Collect information to put in new bleat file
  206.     my $details_dir = "$users_dir/$curr_user/details.txt";
  207.     open A, "<$details_dir" or die "can not open $details_dir: $!";
  208.     my $latt = "";
  209.     my $long = "";
  210.     foreach my $line (<A>) {
  211.         if ($line =~ /^home_latitude/) {
  212.             $latt = $line;
  213.             $latt =~ s/^home_latitude: //;
  214.             chomp $latt;
  215.         }
  216.         if ($line =~ /^home_longitude/) {
  217.             $long = $line;
  218.             $long =~ s/^home_longitude: //;
  219.             chomp $long;
  220.         }
  221.     }
  222.     close A;
  223.  
  224.     if ($latt) { push (@new_bleat_info, "latitude: $latt"); }
  225.     if ($long) { push (@new_bleat_info, "longitude: $long"); }
  226.     $time = time;
  227.     push (@new_bleat_info, "time: $time");
  228.  
  229.     if ($in_reply_to) { push (@new_bleat_info, "in_reply_to: $in_reply_to") };
  230.    
  231.     my $new_bleat_id = generate_bleat_id();
  232.  
  233.     my $new_bleat_dir = "$bleats_dir/$new_bleat_id";
  234.     open (my $fh, '>', $new_bleat_dir) or die "Could not open file $new_bleat_dir $!";
  235.     $new_bleat = join("\n", @new_bleat_info);
  236.    
  237.     $new_bleat .= "\n";
  238.     print $fh $new_bleat;
  239.     close $fh;
  240.  
  241.     ##Rewrite the bleat file
  242.     my $users_bleats_dir = "$users_dir/$curr_user/bleats.txt";
  243.     open (my $fh, '>>', $users_bleats_dir) or die "Could not open file $users_bleats_dir $!";
  244.     print $fh "$new_bleat_id\n";
  245.     close $fh;
  246.    
  247. }
  248.  
  249. #PRINTS THE CURRENT USERS NEWSFEED:
  250. #shows the bleats of users they are listening to, and bleats that they are mentioned in
  251. sub newsfeed {
  252.     my ($user) = @_;
  253.     $user =~ s/$users_dir\///;
  254.    
  255.     my $return_str = <<"eof";
  256.    
  257.     <div class="row">
  258.     <div class="col s3 offset-s9">
  259.             <form method="post"><label for="search"><i class="material-icons">search</i></label>
  260.                      <input id="search" type="search" required name='bleat_search_query' placeholder="Search for bleats">
  261.             </form>
  262.         </div>
  263.     <div class="container">
  264.     <form method="post">
  265.       <div class="row">
  266.         <div class="input-field col s12">
  267.           <textarea id="new_bleat_area" name='new_bleat_area' class="materialize-textarea" maxlength="142"></textarea>
  268.           <label for="new_bleat_area">Type your bleat here</label>
  269.             <button onclick = "alert_function()" class="btn waves-effect waves-light" type="submit" name="action">Post
  270.     <i class="material-icons right">send</i>
  271.   </button>
  272.         <script>
  273.         function alert_function () {
  274.             alert("Bleat successful!");
  275.         }
  276.         </script>
  277.         </div></div></form></div></div>
  278. eof
  279.  
  280.     my %all_bleat_ids;
  281.     my @listening = listening_array($user);
  282.     push (@listening, $curr_user);
  283.     foreach $person (@listening) {
  284.         chomp $person;
  285.         $person =~ s/$users_dir\///;
  286.         my $users_bleats_dir = "$users_dir/$person/bleats.txt";
  287.         open A, "<$users_bleats_dir" or die "can not open $users_bleats_dir: $!";
  288.         foreach my $id (<A>) {
  289.             $all_bleat_ids{$id} = $person;
  290.         }
  291.         close A;
  292.     }
  293.  
  294.     my $bleats_str = "";
  295.     foreach my $bleat_id (reverse sort keys %all_bleat_ids) {
  296.         my $dir = "$bleats_dir/$bleat_id";
  297.         open A, "<$dir" or die "can not open $dir: $!";
  298.         my $bleat_text = "";
  299.         foreach my $line (<A>) {
  300.             if ($line =~ /^bleat/) {
  301.                 $bleat_text = $line;
  302.                 $bleat_text =~ s/^bleat: //;
  303.                 next;
  304.             }
  305.         }
  306.         close A;
  307.         my $action = "listen";
  308.         my $input = "listen_user";
  309.         my $tooltip = "Listen!";
  310.         my $icon = "volume_up";
  311.         if (is_listening($curr_user, $all_bleat_ids{$bleat_id}) eq 1) {
  312.             $action = "unlisten";
  313.             $input = "unlisten_user";
  314.             $tooltip = "Unlisten.";
  315.             $icon = "volume_off";
  316.         }
  317.  
  318.         my $pic = profile_pic($all_bleat_ids{$bleat_id}, "small");
  319.         $bleats_str .= <<"eof"
  320.  
  321.     <div class="container">
  322.         <div class="card-panel hoverable teal lighten-3 row">
  323.             <div class="col s6">
  324.                 <h4>$pic <i>$all_bleat_ids{$bleat_id}</i></h4>
  325.                 $bleat_text
  326.             </div>
  327.             <div class="col s6">
  328.                 <div class="right-align">
  329.                     <form>
  330.                     <input type="hidden" name="$input" value=$all_bleat_ids{$bleat_id}>
  331.                     <button type="submit" name="$action" class="btn-floating btn-large waves-effect waves-light teal tooltipped data-position="bottom" data-delay="50" data-tooltip="$tooltip"">
  332.                     <i class="material-icons">$icon</i></button>
  333.                     </form> <br>
  334.                     <form>
  335.                         <input type="hidden" name="in_reply_to" value=$bleat_id>
  336.                     <button onclick="bleat_reply()" name="reply" data-target="modal1" class="btn-floating modal-trigger btn-large waves-effect waves-light teal tooltipped data-position="bottom" data-delay="50" data-tooltip="Reply!"">
  337. <i class="material-icons">replay</i></button>
  338.  
  339.                     <input type="hidden" name="reply_text">
  340.  
  341.                     <script>
  342.                     function bleat_reply() {
  343.                         var reply = prompt("Please enter your reply.");
  344.                         if (reply != null) {
  345.                             document.getElementsByName("reply_text")[0].setAttribute("value", reply);
  346.                         }
  347.                     }
  348.                     </script>
  349.                     </form></div></div></div></div>
  350. eof
  351.     }
  352.  
  353.     return "$return_str$bleats_str";
  354. }
  355.  
  356. ## sub returns if USER 1 is listening to USER 2 (1=true, 0=false)
  357. sub is_listening {
  358.     my ($user1, $user2) = @_;
  359.     my $dir = "$users_dir/$user1/details.txt";
  360.     open A, "<$dir" or die "can not open $dir: $!";
  361.     foreach my $line (<A>) {
  362.         if ($line =~ /^listens/) {
  363.             foreach (split (/ /, $line)) {
  364.                 (my $i = $_) =~ s/^\s*//;
  365.                 chomp $i;
  366.                 if ($i =~ /$user2/) { return 1; }
  367.             }
  368.             next;
  369.         }
  370.     }
  371.     close A;
  372.     return 0;
  373. }
  374.  
  375. ## makes user1 unfollow user2
  376. sub make_unlisten {
  377.     my ($user1, $user2) = @_;
  378.     my $dir = "$users_dir/$user1/details.txt";
  379.     my @details = ();
  380.     open A, "<$dir"  or die "can not open $details_dir: $!";
  381.     foreach my $line (<A>) {
  382.         if ($line =~ /^listens/) {
  383.             $line =~ s/$user2//;
  384.             $line =~ s/  / /g;
  385.         }
  386.         push (@details, $line);
  387.     }
  388.     close A;
  389.     open (my $fh, '>', $dir) or die "Could not open file $dir: $!";
  390.     foreach my $line (@details) {
  391.         print $fh $line;
  392.     }
  393.     close $fh;
  394. }
  395.  
  396. ## makes user 1 follow user2
  397. sub make_listen {
  398.     my ($user1, $user2) = @_;
  399.     my $dir = "$users_dir/$user1/details.txt";
  400.     my @details = ();
  401.     open A, "<$dir"  or die "can not open $details_dir: $!";
  402.     foreach my $line (<A>) {
  403.         if ($line =~ /^listen/) {
  404.             chomp $line;
  405.             $line .= " $user2\n";
  406.             $line =~ s/  / /g;
  407.         }
  408.         push (@details, $line);
  409.     }
  410.     close A;
  411.     open (my $fh, '>', $dir) or die "Could not open file $dir: $!";
  412.     foreach my $line (@details) {
  413.         print $fh $line;
  414.     }
  415.     close $fh;
  416. }
  417.  
  418. sub validate_pw {
  419.     my ($username, $input_pw) = @_;
  420.     my $user_dir = "$users_dir/$username";
  421.     if ($username && $input_pw) {
  422.         if ((-e $user_dir) && (-d $user_dir)) {
  423.             $details_dir = "$user_dir/details.txt";
  424.             open F, "<$details_dir" or die "can not open $details_dir: $!";
  425.             my $correct_pw;
  426.             foreach my $line (<F>) {
  427.                 if ($line =~ /^password/) {
  428.                     $correct_pw = $line;
  429.                     $correct_pw =~ s/^password: //;
  430.                     next;
  431.                 }
  432.             }
  433.            
  434.             if ($correct_pw =~ /$input_pw/) { return 1;
  435.             } else { return "Password is incorrect."; }
  436.  
  437.             close F;
  438.         } else {
  439.             return "Username does not exist.";
  440.         }
  441.     } elsif ($username) {
  442.         return "Please enter a password.";
  443.     } elsif ($input_pw) {
  444.         return "Please enter a username.";
  445.     }
  446. }
  447.  
  448. sub login_page {
  449.     return <<eof                                                  
  450.     <form action="bitter.cgi" method="post">
  451.         <div class="container">
  452.              <div class="card-panel teal lighten-2 hoverable">
  453.                  <div class="row">
  454.                      <div class="input-field col s6">
  455.                      <input id="username" type="text" name='username_field'>
  456.                      <label for="username" style="color:black;">Username</label>
  457.                  </div>
  458.                      <div class="input-field col s6">
  459.                      <input id="password" type="password" name='password_field'>
  460.                      <label for="password" style="color:black;" >Password</label>
  461.                      </div>
  462.                  </div>
  463.              </div>
  464.      
  465.             <button class="btn waves-effect waves-light center-align" type="submit" name="action">Login
  466.                 <i class="material-icons right">send</i>
  467.             </button>
  468.         </div>
  469.     </form>
  470.    
  471. eof
  472. }
  473.  
  474. ##PRINTS SEARCH RESULTS
  475. # where $query is a search query for bleats (substrings/keywords, hashtags)
  476. sub bleat_search_results {
  477.     my ($query) = @_;
  478.     my @bleats = sort(glob("$bleats_dir/*"));
  479.     my @results = ();
  480.     my $results_str = "";
  481.     foreach my $bleat_id (@bleats) {
  482.         open A, "<$bleat_id" or die "can not open $details_dir: $!";
  483.         my $bleat = "";
  484.         my $username = "";
  485.         foreach my $line (<A>) {
  486.             if ($line =~ /^bleat/) {
  487.                 $bleat = $line;
  488.                 $bleat =~ s/^bleat: //;
  489.             }
  490.             if ($line =~ /^username/) {
  491.                 ($username = $line) =~ s/^username: //;
  492.             }
  493.         }
  494.         close A;
  495.         chomp $username;
  496.         my $pic = profile_pic($username, "small");
  497.         if ($bleat =~ /$query/i) {
  498.             my $result = <<"eof";
  499.          
  500.         $pic
  501.          <p class=\"flow-text\">
  502.              <a href=\"bitter.cgi?user=$username&page=user\">
  503.                 <h3>\@$username</h3><br>
  504.              </a>
  505.              $bleat<br>
  506.          </p>
  507. eof
  508.  
  509.         $results_str .= "<br>\n<div class=\"card-panel teal lighten-3\">$result</div>";
  510.         }
  511.     }
  512.     if ($results_str) {
  513.         $results_str = "<h3>Results for <i>\"$query\"</i></h3>\n<div class=\"container\">\n$results_str\n</div>";
  514.     } else {
  515.         $results_str = "<h3>No results for <i>\"$query\"</i></h3>";
  516.     }
  517.     return $results_str;
  518. }
  519.  
  520. ##PRINTS SEARCH RESULTS
  521. # where $query is a search query for usernames/fullnames
  522. sub search_results {
  523.     my ($query) = @_;
  524.     my @users = sort(glob("$users_dir/*"));
  525.     my $username = "";
  526.     my $full_name = "";
  527.     my @results = ();
  528.     foreach my $user (@users) {
  529.         my $details_dir = "$user/details.txt";
  530.         open D, "<$details_dir" or die "can not open $details_dir: $!";
  531.         foreach my $line (<D>) {
  532.             if ($line =~ /^username/) {
  533.                 $username = $line;
  534.                 $username =~ s/^username: //;
  535.             }
  536.             if ($line =~ /^full_name/) {
  537.                 $full_name = $line;
  538.                 $full_name =~ s/^full_name: //;
  539.             }
  540.         }
  541.  
  542.         if (($username =~ /$query/i) || ($full_name =~ /$query/i)) {
  543.             push(@results, $username);
  544.         }
  545.         close D;
  546.     }
  547.     $results_str = "";
  548.     if ($#results > 0) {
  549.         foreach my $line (@results) {
  550.             #get full name
  551.             chomp $line;
  552.             my $details_dir = "$users_dir/$line/details.txt";
  553.             open A, "<$details_dir" or die "can not open $details_dir: $!";
  554.             my $full_name = "";
  555.             foreach my $detail (<A>) {
  556.                 if ($detail =~ /^full_name/) {
  557.                     $full_name = $detail;
  558.                     $full_name =~ s/^full_name: //;
  559.                 }
  560.             }
  561.             close A;
  562.             #get profile picture
  563.             my $pic = profile_pic($line, "small");
  564.             my $action = "listen";
  565.             my $input = "search_listen";
  566.             my $tooltip = "Listen!";
  567.             my $icon = "volume_up";
  568.             if (is_listening($curr_user, $line) eq 1) {
  569.                 $action = "unlisten";
  570.                 $input = "search_unlisten";
  571.                 $tooltip = "Unlisten.";
  572.                 $icon = "volume_off";
  573.             }
  574.             my $result = <<"eof";
  575.            
  576.             <a href=\"bitter.cgi?user=$line&page=user\">
  577.                 <p class=\"flow-text\">
  578.                     $pic
  579.                     $full_name<br>
  580.                     <font color=\"blue\">\@$line</font>
  581.                  </p>
  582.              </a>
  583.              <div class="right-align">
  584.                     <form>
  585.                     <input type="hidden" name="$input" value="$line">
  586.                     <input type="hidden" name="curr_search" value="$query">
  587.                     <button type="submit" name="$action" class="btn-floating btn-large waves-effect waves-light teal tooltipped data-position="bottom" data-delay="50" data-tooltip="$tooltip"">
  588.                     <i class="material-icons">$icon</i></button>
  589.                     </form>
  590.                 </div>
  591.  
  592. eof
  593.  
  594.             $results_str .= "<br>\n<div class=\"card-panel teal lighten-3\">$result</div>";
  595.         }
  596.         $results_str = "<h3>Results for <i>\"$query\"</i></h3>\n<div class=\"container\">\n$results_str\n</div>";
  597.     } else {
  598.         $results_str = "<h3>No results for <i>\"$query\"</i></h3>";
  599.     }
  600.    
  601.     return $results_str;
  602. }
  603.  
  604. sub listening_array {
  605.     my ($user) = @_;
  606.     my $details_dir = "$users_dir/$user/details.txt";
  607.     open A, "<$details_dir" or die "can not open $details_dir: $!";
  608.     foreach my $line (<A>) {
  609.         if ($line =~ /^listens/) {
  610.             $line =~ s/^listens:\s*//;
  611.             return split(/\s+/, $line);
  612.         }
  613.     }
  614.     close A;
  615. }
  616.  
  617. sub print_listening {
  618.     my ($user_to_test) = @_;
  619.     my @users = listening_array($user_to_test);
  620.     my $listening_str = "";
  621.     foreach my $user (@users) {
  622.         my $pic = profile_pic($user, "small");
  623.         $listening_str .= "$pic<a href=\"bitter.cgi?page=user&user=$user\">\@$user</a><br>\n";
  624.     }
  625.     return "<h5>Listens to:</h5>$listening_str";
  626. }
  627.  
  628. sub print_details {
  629.     my ($user) = @_;
  630.     $user =~ s/$users_dir\///g;
  631.     my $details_filename = "$users_dir/$user/details.txt";
  632.     open E, "<$details_filename" or die "can not open $details_filename: $!";
  633.    
  634.     %details;
  635.     foreach my $line (<E>) {
  636.         if ($line !~ /^\s*(email|password)/) {
  637.             if ($line =~ /([\w _]*):(.*)/) {
  638.                 $details{$1} = $2;
  639.             }
  640.         }
  641.     }
  642.     my $username = "<h4 class=\"truncate\">$details{username}</h4>";
  643.     my $details_string = "";
  644.     my @order = ("full_name", "home_latitude", "home_longitude", "home_suburb");
  645.     foreach $key (@order) {
  646.         if (exists $details{$key}) {
  647.             ($new_key = $key) =~ s/_/ /g;
  648.             $new_key =~ s/(full |home )//;
  649.             if ($new_key =~ /^([a-z])/) {
  650.                 my $first_letter = $1;
  651.                 my $upper = uc $first_letter;
  652.                 $new_key =~ s/^$first_letter/$upper/;
  653.             }
  654.             $details_string .= "<b>$new_key:</b> $details{$key}<br>";
  655.        }
  656.     }
  657.     close E;
  658.     $user =~ s/^dataset-$dataset_size\/users\///;
  659.     my $listening_str = print_listening($user);
  660.     return "$username$details_string<br>$listening_str";
  661. }
  662.  
  663. sub profile_pic {
  664.     my ($user, $size) = @_;
  665.     $user =~ s/$users_dir\///g;
  666.     $image_dir = "$users_dir/$user/profile.jpg";
  667.     my $image = "";
  668.     if (! -e $image_dir) {
  669.         $image_dir = "default.jpg";
  670.     }
  671.     my $name = $user;
  672.     $name =~ s/$users_dir\///;
  673.     if ($size eq "small") {
  674.             $image = "<a href=bitter.cgi?page=user&user=$name><img src=\"$image_dir\" alt=\"Profile Picture\" class=\"circle responsive-img\" style=\"width:50px;height:50px;\"></a>";
  675.         } elsif ($size eq "large") {
  676.             $image = "<a href=bitter.cgi?page=user&user=$name><div class=\"center-align\"><img src=\"$image_dir\" alt=\"Profile Picture\" class=\"circle responsive-img\"></div></a>";
  677.         }
  678.     return $image;
  679. }
  680.  
  681. sub print_bleats {
  682.     my ($user) = @_;
  683.     $user =~ s/$users_dir\///g;
  684.     my $bleats_filename = "$users_dir/$user/bleats.txt";
  685.     open F, "<$bleats_filename" or die "can not open $bleats_filename: $!";
  686.    
  687.     #my $bleats = "<h3 class=\"center-align\">Bleats</h3>";
  688.     my $bleats = "";
  689.     my @array = ();
  690.     foreach my $bleat_id (<F>) {
  691.         push (@array, $bleat_id);
  692.     }
  693.     foreach my $bleat_id (reverse @array) {
  694.         my $path = "$bleats_dir/$bleat_id";
  695.         open G, "<$path" or die "cannot open $path: $!";
  696.         foreach my $line (<G>) {
  697.             if ($line =~ /^\s*bleat/i) {
  698.                 $line =~ s/^\s*bleat:\s*//i;
  699.                 chomp $line;
  700.                 my $name = $user;
  701.                 $name =~ s/$users_dir\///;
  702.                 $bleats .= "<div class=\"card-panel hoverable teal lighten-3\">\n<h4><i>$name</i></h4>$line";
  703.  
  704.                 if ($user eq $curr_user) {
  705.                     $bleats .= <<"eof";
  706.                     <form>
  707.                     <div class = "row">
  708.                     <input type="hidden" name="delete_bleat" value=$bleat_id>
  709.                     <button type="submit" name="delete" class="btn-floating btn-large waves-effect waves-light teal tooltipped data-position="bottom" data-delay="50" data-tooltip="Delete bleat"">
  710.                     <i class="material-icons">delete</i></button>
  711.                     </div>
  712.                 </form>
  713. eof
  714.                 }
  715.                 $bleats .= "</div>";  
  716.             }
  717.         }
  718.     }
  719.     close F;
  720.     return $bleats;
  721. }
  722.  
  723. ###########################################################
  724.  
  725. #
  726. # Show unformatted details for user "n".
  727. # Increment parameter n and store it as a hidden variable
  728. #
  729. sub user_page {
  730.     my ($user_to_show) = @_;    
  731.     $user_to_show =~ s/$users_dir\///g;
  732.     my $image = profile_pic($user_to_show, "large");
  733.     my $bleats = print_bleats($user_to_show);
  734.     my $details = print_details($user_to_show);
  735.    
  736.  
  737.     my $action = "listen";
  738.     my $input = "userpage_listen";
  739.     my $tooltip = "Listen!";
  740.     my $icon = "volume_up";
  741.     my $message = "Listen";
  742.     if (is_listening($curr_user, $user_to_show) eq 1) {
  743.         $action = "unlisten";
  744.         $input = "userpage_unlisten";
  745.         $tooltip = "Unlisten.";
  746.         $icon = "volume_off";
  747.         $message = "unlisten";
  748.     }
  749.  
  750.     return <<eof
  751.  
  752. <br>
  753. <div class="container">
  754. <div class="row">
  755.     <div class="col s4">
  756.         <div class="card-panel teal lighten-2">
  757.             $image<br>
  758.                 <form>
  759.                 <input type="hidden" name="$input" value=$user_to_show>
  760.                 <button type="submit" name="$action" class="waves-effect waves-light btn teal tooltipped data-position="bottom" data-delay="50" data-tooltip="$tooltip"">
  761.                 <i class="material-icons right">$icon</i>$message</button>
  762.                 </form>
  763.             <br>$details
  764.         </div>
  765.     </div>
  766.     <div class="col s8">
  767.             $bleats
  768.         <br>
  769.     </div>
  770. </div>
  771. </div>
  772. eof
  773. }
  774.  
  775. sub nav_bar {
  776. my ($logged_out, $user) = @_;
  777.  
  778. my $return_string = <<"eof";
  779. <nav class="teal lighten-2">
  780.   <div class="nav-wrapper">
  781.     <a href="#!" class="brand-logo center"><b>Bitter</b></a>
  782.     <ul class="right hide-on-med-and-down">
  783.  
  784. eof
  785.  
  786. if ($logged_out eq 0) {
  787.     $return_string .= <<"eof"
  788.  
  789.     <li><a href="bitter.cgi?user=$user&page=home"><b>Home</b></a></li>
  790.     <li><a href="bitter.cgi?user=$user&page=user"><b>My Profile: </b>$user</a></li>
  791.     <li><a href=\"bitter.cgi?logging_out=1\">Logout</a></li>
  792.        </ul>
  793.            <ul id="nav-mobile" class="left hide-on-med-and-down">
  794.                    <form method="post">
  795.                    <div class="input-field">
  796.                         <input id="search" type="search" required name='search_query' placeholder="Search for users">
  797.                        <label for="search"><i class="material-icons">search</i></label>
  798.                        <i class="material-icons">close</i>
  799.                    </div>
  800.                </form>
  801.                </ul>      
  802. eof
  803. }
  804. $return_string .= "</div>\n</nav>";
  805.  
  806. return $return_string;
  807.  
  808. }
  809.  
  810. #
  811. # HTML placed at the top of every page
  812. #
  813. sub page_header {
  814.    if ($cookie) {
  815.        print "Set-Cookie: $cookie";
  816.    }
  817.  
  818.    return <<eof
  819. Content-Type: text/html
  820.  
  821. <!DOCTYPE html>
  822. <html lang="en">
  823. <head>
  824. <title>Bitter</title>
  825. <link href="bitter.css" rel="stylesheet">
  826. <link href="materialize/css/materialize.css" rel="stylesheet">
  827. <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
  828. <script src="materialize/js/materialize.js"></script>
  829. </head>
  830. <body>
  831.  <!-- jQuery is required by Materialize to function -->
  832.  <script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
  833.  <script type="text/javascript" src="js/materialize.min.js"></script>
  834.  <script type="text/javascript">
  835.    //custom JS code
  836.  </script>
  837. eof
  838. }
  839.  
  840.  
  841. #
  842. # HTML placed at the bottom of every page
  843. # It includes all supplied parameter values as a HTML comment
  844. # if global variable $debug is set
  845. #
  846. sub page_trailer {
  847.    my $html = "";
  848.    $html .= join("", map("<!-- $_=".param($_)." -->\n", param())) if $debug;
  849.    $html .= end_html;
  850.    return $html;
  851. }
  852.  
  853. main();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement