Zend - The PHP Company




Miscellaneous

Add Code


The Chegulator  

Type: application
Added by: robF
Entered: 03/06/2003
Last modified: 09/12/2002
Rating: - (fewer than 3 votes)
Views: 4386
A brutal hack in PHP and shell to get and display results from Fark (www.fark.com) Photoshop competitions


//============================================================================
//
// I participate in a lot of Fark (http://www.fark.com) Photoshop
// competitions, and I was curious to find out how I'd done in them over the
// last year or so.
//
// So, on a rainy Saturday afternoon, I cobbled together the following shell
// script and PHP script.
//
// The shell script simply runs off to Fark and downloads the HTML results
// pages of every single Photoshop competition, storing them on local disk.
// Even with a fast connection, this takes absolutely ages, and uses a lot
// of disk space.
//
// when the PHP script is called it looks through all the cached
// competitions and works out the given user's position in all of them, then
// presents the results in a table.
//
// The whole thing is a complete hack. It's slow, inefficient and ugly, but
// it works, and it's not bad for two or three hours' work.
//
// I wrote this on my SPARC, and it might not work on anything other than
// Solaris.  The PHP makes an external call to /usr/bin/fgrep, and the shell
// script expects to find a well behaved Korn shell (I use ksh93, but 88 or
// pdksh ought to work. Bash might: I don't know.) cURL (curl.haxx.se) is
// needed by the shell script, but it's easy to change it to use wget, which
// I suppose is much more widespread. I prefer cURL because I think it's
// just brilliant. You also need gnu grep, because I needed lines of context
// after the regexp and I couldn't remember exactly how to do that with sed,
// and couldn't be bothered to work it out. (I know, I know.)
//
// This emulates a small part of the Fark Photoshop Monitor,
// (http://64.81.51.213/fpm) but seems to be much more accurate. If I ever
// get around to it I might write a proper version which caches results in a
// database, does nice things with the reports, and doesn't take forever to
// set up. If anyone wants me to do this, e-mail me and it might provoke me
// into action.
//
// Oh, and I call it "The Chegulator", which is derived from my utterly
// nonsensical Fark username.
//
// If you're still reading, I'm amazed. I'll be *really* amazed if anyone
// bothers setting this up and running it, so please let me know if you do.
//
// As usual, I take no responsibility if my grievous hack trashes your
// computer.
//
//============================================================================

// Here's the shell script. Call it anything you like

//============================================================================

#!/bin/ksh

#-----------------------------------------------------------------------------
# VARIABLES

BASE="/export/home/fark_cache"
        # where to store everything - needs quite a bit of space

#-----------------------------------------------------------------------------
# FUNCTIONS

get_archive_list() {

        # simply retrieves a list of indexes which we'll expand on later

        curl  -s http://www.fark.com/archives/ | egrep 
        'HREF="index.' | sed 's/^.*="//;s/">.*$//'

}

get_contest_list() {

        # pull the Photoshop contest IDs out of a URL and whack them in to a
        # file $1 is the file - seem to be relative links

        print -n "$1: "

        if [ -f ${BASE}/indexes/$1 ]
        then
                echo "cached"
        else
                curl -s http://www.fark.com/archives/$1 -o indexes/$1 && 
                echo "got" || echo "failed"
        fi

}

#-----------------------------------------------------------------------------
# CONTROL STARTS HERE

for index in $(get_archive_list)
do
        get_contest_list $index
done

print -n "last 7 days: "

curl -s http://www.fark.com/week.html -o 
"${BASE}/indexes/index.last_7_days.html" && echo "got" || echo "failed"

print -n "current: "
curl -s http://www.fark.com -o "${BASE}/indexes/index.current.html" 
&& echo "got" || echo "failed"

print "finding competitions"

for index in ${BASE}/indexes/*
do
        ggrep -A3 photoshop.gif $index | grep IDLink | sed 
        's/(.*)([0-9]{6})(.*)/2/'
done | sort -run > /tmp/pshop_list

for file in $(egrep "^[0-9]" /tmp/pshop_list)
do
        print -n "$file : "
        if [ -f ${BASE}/tfiles/tfile.$file ]
        then
                echo "already got"
        else
                curl -s 
                http://cgi.fark.com/cgi/fark/comments-voteresults.pl?$file 
                -o $BASE/tfiles/tfile.$file && echo "ok" || echo "failed"
        fi
done

exit 0

//============================================================================
//
// And the PHP is from here to the end
//
//============================================================================

function get_votes($id, $user) {

        $tmpfile = "/export/home/fark_cache/tfiles/tfile.${id}";
        $posn = 0;              // used to count where you finished

        // step through each line of the file looking for things. Not very
        // efficient but the whole thing's such a hack anyway that I don't think
        // it matters

        $c = 0;
        $arr = file($tmpfile);
        $ret_arr = array();

        for ($s = sizeof($arr), $i = 0; $i < $s; $i++) {

                // get the description of the competition

                if (strpos($arr[$i], "img.fark.com/images/2001/topics/photoshop.
gif"))
                        $desc = strip_tags($arr[$i + 1]);

                // count each user so we know your finishing position

                if (strpos($arr[$i], "users.pl?login"))
                        $posn++;

                // Look for your username

                if (strpos($arr[$i], $user)):
                        ereg("(([0-9]+) votes)", $arr[$i + 2], $regs);
                        $ret_arr[] = array("desc" => $desc, "votes" => $regs[2],
 "posn"
                        => $posn, "id" => $id);
                endif;

        }
        unset($arr);

        return $ret_arr;
}

function ordinal($number) {

    // when fed a number, adds the English ordinal suffix. Works for any
    // number, even negatives

    if ($number % 100 > 10 && $number %100 < 14):
        $suffix = "th";
    else:
        switch($number % 10) {

            case 0:
                $suffix = "th";
                break;

            case 1:
                $suffix = "st";
                break;

            case 2:
                $suffix = "nd";
                break;

            case 3:
                $suffix = "rd";
                break;

            default:
                $suffix = "th";
                break;
        }

    endif;

    return "${number}<SUP>$suffix</SUP>";

}

function show_entry($arr) {

        return "<TR><TD>$arr[desc]</TD><TD VALIGN="TOP">$arr[votes]</TD><TD
        VALIGN="TOP">" . ordinal($arr["posn"]) . "</TD></TR>";
}

// Some HTML functions yanked and put from my standard library

function dialog_submit($name, $value) {

    // code to produce a generic submit button

        return "n<INPUT TYPE="submit" NAME="$name" VALUE="$value">";

}

function dialog_string($name, $size = 30, $maxl = 30, $value = false) {

        global $data;

        $str = "n<INPUT TYPE="text" SIZE="$size" MAXLENGTH="$maxl" " .
        "NAME="" . str_replace("n", "", $name) . """;

        if ($value)
                $str .= " VALUE="" .  trim($value) . """;

        $str .= ">n";

        return $str;

}

function dialog_form($page, $method = "post") {

    // open a form

        return "n<FORM ACTION="$page" METHOD="$method">n" .
        dialog_hidden("md5", md5(time().$_SERVER['REMOTE_ADDR'].microtime()));
}

//==============================================================================
// CONTROL STARTS HERE

if (!isset($_POST["user"]) && !isset($_GET["user"])):

        include("/htdocs/catflap/functions/functions.html.php");

        echo dialog_form($_SERVER["PHP_SELF"]), "enter your Fark username : ",
        dialog_string("user", 70, 80), dialog_submit("go", "go"), "</FORM>";
        exit();

endif;

if (isset($_GET["user"]))
        $user = $_GET["user"];

if (isset($_POST["user"]))
        $user = $_POST["user"];

// use fgrep to quickly get a list of PS comps this user participated in

$user = ucwords($user);
exec("/usr/bin/fgrep -l $user /export/home/fark_cache/tfiles/tfile.*", $list);

if (sizeof($list) == 0)
        die("nothing found for $user");

foreach ($list as $thread) {

        if (ereg("([0-9]{6})", $thread, $regs))

        $c = get_votes($regs[1], $user);

        foreach($c as $entry) {

                if (isset($entry["votes"]))
                        $contests[] = $entry;
        }

}

$sortarray = array();

if (isset($_GET["key"])):

        foreach($contests as $sk) {
                $sortarray[] = $sk[$_GET["key"]];
        }

        if ($_GET["key"] == "posn"):
                array_multisort($sortarray, SORT_ASC, $contests);
        else:
                array_multisort($sortarray, SORT_DESC, $contests);
        endif;

else:
        foreach($contests as $sk) {
                $sortarray[] = $sk["id"];
        }

        array_multisort($sortarray, SORT_DESC, $contests);

endif;

?>

<TABLE CELLSPACING="3" CELLPADDING="5" BORDER="0" WIDTH="90%" ALIGN="CENTER">
<?php

        
echo "<TR><TD><A
        HREF="
$_SERVER[PHP_SELF]?user=$user&key=desc">description</A></TD><TD>
<A
        HREF="
$_SERVER[PHP_SELF]?user=$user&key=votes">votes</A></TD><TD><A
        HREF="
$_SERVER[PHP_SELF]?user=$user&key=posn">position</A></TD></TR>";

        foreach(
$contests as $contest) {
                echo 
"n<TR><TD><A
                HREF="
http://forums.fark.com/cgi/fark/comments.pl?IDLink=$conte
st[id]">$contest[desc]</A></TD><TD
                VALIGN="
TOP"><A
                        HREF="
http://cgi.fark.com/cgi/fark/comments-voteresults
.pl?$contest[id]">$contest[votes]</A></TD><TD VALIGN="TOP">",
                
ordinal($contest["posn"]), "</TD></TR>";
        }



Usage Example




Rate This Script





Search



This Category All Categories