164 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			164 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/local/bin/perl
 | 
						|
#
 | 
						|
# The ticker (client & admin) loosely follows an MVC architecture.  The model
 | 
						|
# is over in Ticker.pm (it does all the DB work).  ticker.cgi is the view for
 | 
						|
# the client, while this is the view+controller for the admin.
 | 
						|
#
 | 
						|
use strict;
 | 
						|
use warnings;
 | 
						|
 | 
						|
use lib '/home/slowtwitch/site/slowtwitch.com/cgi-bin/articles/admin';
 | 
						|
use Links qw(:objects);
 | 
						|
use Ticker;
 | 
						|
use Error qw(:try);
 | 
						|
 | 
						|
Links::init('/var/home/slowtwitch/site/slowtwitch.com/cgi-bin/articles/admin');
 | 
						|
Links::init_admin();
 | 
						|
 | 
						|
use constant {
 | 
						|
    STATE_NORMAL => 0,
 | 
						|
    STATE_UPDATE => 1,
 | 
						|
    STATE_REDIRECT => 2,
 | 
						|
    ADMIN_URL => "https://www.slowtwitch.com/cgi-bin/articles/ticker/admin/admin.cgi"
 | 
						|
};
 | 
						|
 | 
						|
# prototypes.
 | 
						|
sub controller();
 | 
						|
sub view($);
 | 
						|
 | 
						|
# And call the controller.
 | 
						|
controller();
 | 
						|
 | 
						|
#
 | 
						|
# This is the controller.  This is where work gets done.
 | 
						|
#
 | 
						|
sub controller() {
 | 
						|
    my %viewstate = (state => STATE_NORMAL);
 | 
						|
 | 
						|
    # if we have an action parameter (that's non-empty), then do work:
 | 
						|
    if(defined $IN->param('action') && length($IN->param('action')) > 0) {
 | 
						|
        $viewstate{state} = STATE_REDIRECT;
 | 
						|
        try {
 | 
						|
            my $p = $IN->get_hash();
 | 
						|
            if($p->{action} =~ /create/) {
 | 
						|
                Ticker::create_ticker($p->{msg}, $p->{link});
 | 
						|
            } elsif($p->{action} =~ /show_update/) {
 | 
						|
                $viewstate{state} = STATE_UPDATE;
 | 
						|
                $viewstate{id} = $p->{'id'};
 | 
						|
            } elsif($p->{action} =~ /do_update/) {
 | 
						|
                Ticker::update_ticker($p->{'id'}, $p->{'msg'}, $p->{'link'});
 | 
						|
            } elsif($p->{action} =~ /delete/) {
 | 
						|
                Ticker::delete_ticker($p->{'id'});
 | 
						|
            }
 | 
						|
        } catch Ticker::TickerException with {
 | 
						|
            # oops.  something bad happened.
 | 
						|
            $viewstate{error} = "Error: " . shift;
 | 
						|
            # reset the viewstate so that we display the error message.
 | 
						|
            $viewstate{state} = STATE_NORMAL;
 | 
						|
        };
 | 
						|
    }
 | 
						|
 | 
						|
    return view(\%viewstate);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#
 | 
						|
# Build the view, which takes a single hashref describing how the view should
 | 
						|
# behave.
 | 
						|
#
 | 
						|
sub view($) {
 | 
						|
    my ($state) = @_;
 | 
						|
    my %s = %$state;
 | 
						|
 | 
						|
    # If the state is redirect, we're done.
 | 
						|
    if($s{state} == STATE_REDIRECT) {
 | 
						|
        print $IN->redirect(ADMIN_URL);
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    # Now let's actually build the view, depending on our current state:
 | 
						|
    print $IN->header();
 | 
						|
    print qq{<html><head><title>Ticker Admin</title></head><body>};
 | 
						|
 | 
						|
    # Try to load all the tickers:
 | 
						|
    try {
 | 
						|
        $s{data} = Ticker::read_tickers();
 | 
						|
 | 
						|
        # Are we also trying to update a record?  Yeah, I know - we're
 | 
						|
        # hitting the db again.  I wish that fetchall_hashref actually worked...
 | 
						|
        if(defined $s{id}) {
 | 
						|
            my $result = Ticker::read_ticker($s{id});
 | 
						|
            $s{msg} = $result->{ticker_text};
 | 
						|
            $s{link} = $result->{ticker_link};
 | 
						|
        }
 | 
						|
    } catch Ticker::TickerException with {
 | 
						|
        $s{error} .= "  Could not read tickers from database!";
 | 
						|
    };
 | 
						|
 | 
						|
    # Print an error message if we have one:
 | 
						|
    if(defined $s{error}) {
 | 
						|
        print "<p>" . $s{error} . "</p>";
 | 
						|
    }
 | 
						|
 | 
						|
    # What should the top form look like?
 | 
						|
    if($s{state} == STATE_NORMAL) {
 | 
						|
        $s{title} = 'Create a ticker:';
 | 
						|
        $s{submit} = 'Create ticker';
 | 
						|
        $s{action} = 'create';
 | 
						|
        $s{id} = "";
 | 
						|
        $s{msg} = "";
 | 
						|
        $s{link} = "";
 | 
						|
    } elsif($s{state} == STATE_UPDATE) {
 | 
						|
        $s{title} = 'Update a ticker:';
 | 
						|
        $s{submit} = 'Update ticker';
 | 
						|
        $s{action} = 'do_update';
 | 
						|
    }
 | 
						|
    
 | 
						|
    # print the form, which is configured for the type of action we're
 | 
						|
    # performing:
 | 
						|
    print qq{<h3>} . $s{title} . qq{</h3>
 | 
						|
        <form method="post" action="} . ADMIN_URL . qq{">
 | 
						|
            <input type="hidden" name="action" value="} .
 | 
						|
            $s{action} . qq{"/>
 | 
						|
            <input type="hidden" name="id" value="} . $s{id} . qq{"/>
 | 
						|
            <div><label for="message">Message:</label>
 | 
						|
            <input type="text" name="msg" value="} . $s{msg} . qq{"/>
 | 
						|
            </div><div><label for="link">Link:</label>
 | 
						|
            <input type="text" name="link" value="} . $s{link} . qq{"/>
 | 
						|
            </div><div><input type="submit" value="} . $s{submit} . qq{"/>
 | 
						|
        </div></form>
 | 
						|
    };
 | 
						|
    
 | 
						|
    # provide a way to get back to the create interface:
 | 
						|
    if($s{action} =~ /update/) {
 | 
						|
        print qq{<a href="} . ADMIN_URL . qq{">Create a ticker instead.</a>};
 | 
						|
    }
 | 
						|
 | 
						|
    # Now print the entire list of all tickers.
 | 
						|
    print qq{<h3>Current tickers:</h3>};
 | 
						|
 | 
						|
 | 
						|
    # If there are no tickers, say so:
 | 
						|
    if(@{$s{data}} == 0) {
 | 
						|
        print "There are no tickers.";
 | 
						|
    } else {
 | 
						|
        # Print a table showing the ID, delete/edit links, messages, and links:
 | 
						|
        print "<table>"; 
 | 
						|
        print "<tr><td>ID</td><td/><td/><td>Message</td><td>Link</td></tr>";
 | 
						|
        foreach my $k (@{$s{data}}) {
 | 
						|
            my $id = $k->{ticker_id};
 | 
						|
            my $msg = $k->{ticker_text};
 | 
						|
            my $link = $k->{ticker_link};
 | 
						|
            print qq{<tr><td>$id</td><td>
 | 
						|
                <a href="} . ADMIN_URL . qq{?action=delete&id=$id">Delete</a></td><td>
 | 
						|
                <a href="} . ADMIN_URL . qq{?action=show_update&id=$id">Update</a></td><td>} .
 | 
						|
                $msg . "</td><td>" .
 | 
						|
                qq{<a href="} . $link . qq{">} . 
 | 
						|
                $link . "</a></td></tr>";
 | 
						|
        }
 | 
						|
        print "</table>";
 | 
						|
    }
 | 
						|
    print qq{</body></html>};
 | 
						|
}
 | 
						|
 |