<?PHP
#
#   FILE:  AutoScreenshot.php
#
#   Part of the Collection Workflow Integration System (CWIS)
#   Copyright 2011 Edward Almasy and Internet Scout
#   http://scout.wisc.edu
#

class AutoScreenshot extends Plugin{

    function Register()
    {
        $this->Name = "Auto Screenshot";
        $this->Version = "1.0.0";
        $this->Description = "Automatically obtain resources screenshots";
        $this->Url = "http://scout.wisc.edu/cwis/";
        $this->Email = "scout@scout.wisc.edu";
        $this->Requires = array("CWISCore" => "2.2.2");

        $this->CfgSetup["MinutesBetweenChecks"] = array(
            "Type" => "Number",
            "Label" => "Screenshot Check Interval",
            "Units" => "minutes",
            "MaxVal" => 999999,
            "Help" => "The number of minutes between automatic screenshot generation.",
            );

        $this->CfgSetup["Method"] = array(
            "Type" => "Option",
            "Label" => "Screenshot Method",
            "Help" =>
            "Select what screenshot generating program you want to use.",
            "Options" =>
            array(
                "wkhtmltoimage" => "wkhtmltoimage",
                "firefox"       => "Firefox with Xvfb"
                )
            );
    }

    function Install()
    {
        $DB = new Database();

        $DB->Query("CREATE TABLE AutoScreenshotFailures "
                   ."(ResourceId INT, Messages TEXT, FailureTime TIMESTAMP DEFAULT NOW())");
        $DB->Query("CREATE TABLE AutoScreenshotApprovalQueue (ResourceId INT, ImageId INT)");
        $DB->Query("CREATE TABLE AutoScreenshotBlacklist (ResourceId INT);");

        $this->ConfigSetting("MinutesBetweenChecks", 5);
        $this->ConfigSetting("Method", "wkhtmltoimage");
    }

    function HookEvents()
    {
        return array(
            "EVENT_COLLECTION_ADMINISTRATION_MENU" => "AddCollectionAdminMenuItems",
            "EVENT_PERIODIC" => "TakeScreenshots",
            );
    }

    function AddCollectionAdminMenuItems()
    {
        return array(
            "ApprovalQueue" => "Automatic Screenshots",
            );
    }

    function TakeScreenshots($LastRunAt)
    {
        $DB = new Database();

        $Schema = new MetadataSchema();

        $Field = $Schema->GetFieldByName("Screenshot");

        $DB->Query("SELECT ResourceId FROM Resources ".
                   "WHERE ResourceId > 0 AND ".
                   "(".$Field->DBFieldName()."=0 OR ".
                   "ISNULL(".$Field->DBFieldName()."))");

        if ($DB->NumRowsSelected() > 0 )
        {
            $Resources = array();
            while ($Row = $DB->FetchRow() )
            {
                $Resources []= $Row["ResourceId"];
            }

            $ResourcesToFilter = array();

            $DB->Query("SELECT ResourceId FROM AutoScreenshotFailures");
            while ($Row = $DB->FetchRow())
            {
                $ResourcesToFilter []= $Row["ResourceId"];
            }

            $DB->Query("SELECT ResourceId FROM AutoScreenshotApprovalQueue");
            while ($Row = $DB->FetchRow())
            {
                $ResourcesToFilter []= $Row["ResourceId"];
            }

            $DB->Query("SELECT ResourceId FROM AutoScreenshotBlacklist");
            while ($Row = $DB->FetchRow())
            {
                $ResourcesToFilter []= $Row["ResourceId"];
            }

            $FilteredResources = array_diff($Resources, $ResourcesToFilter);


            if (count($FilteredResources)>0)
            {
                $ResourceId = array_pop($FilteredResources);

                $TargetResource = new Resource($ResourceId);

                $Url = $TargetResource->Get("Url");

                $ScreenshotBinary = dirname(__FILE__)."/bin/screenshot-".
                    $this->ConfigSetting("Method").".sh";

                $TmpFileName = "tmp/".md5(mt_rand()).".jpg";

                $CmdString = $ScreenshotBinary.
                    " ".escapeshellarg($Url).
                    " ".escapeshellarg($TmpFileName)." 2>&1";

                exec($CmdString, $CmdOutput, $CmdStatus);

                if (file_exists($TmpFileName) && $CmdStatus==0 )
                {
                    $NewImage = new SPTImage(
                        $TmpFileName,
                        $Field->MaxWidth(), $Field->MaxHeight(),
                        $Field->MaxPreviewWidth(), $Field->MaxPreviewHeight(),
                        $Field->MaxThumbnailWidth(), $Field->MaxThumbnailHeight());

                    $DB->Query("INSERT INTO AutoScreenshotApprovalQueue "
                               ."(ResourceId,ImageId) VALUES "
                               ."(".intval($TargetResource->Id()).",".
                               intval($NewImage->Id()).")");

                }
                else
                {
                    ob_start();
                    print_r($CmdOutput);
                    $ErrorMessages = ob_get_contents();
                    ob_end_clean();

                    $DB->Query("INSERT INTO AutoScreenshotFailures "
                               ."(ResourceId,Messages) VALUES (".$TargetResource->Id().","
                               ."'".addslashes($ErrorMessages)."')");
                }

                if (file_exists($TmpFileName))
                {
                    unlink($TmpFileName);
                }

            }
            else
            {
                $DB->Query("DELETE FROM AutoScreenshotFailures WHERE FailureTime < NOW() - INTERVAL 1 WEEK");
            }
        }

        return $this->ConfigSetting("MinutesBetweenChecks");
    }

    function CleanDuplicatesOfManual()
    {
        $DB = new Database();

        $Schema = new MetadataSchema();

        $Field = $Schema->GetFieldByName("Screenshot");

        $DB->Query("SELECT * FROM AutoScreenshotApprovalQueue");
        $ApprovalQueue = $DB->FetchRows();

        foreach ($ApprovalQueue as $QueueEntry)
        {
            $ResourceId = $QueueEntry["ResourceId"];
            $Resource = new Resource($ResourceId);

            $ImageFiles = $Resource->Get("Screenshot");
            if (count($ImageFiles)>0)
            {
                $ThisImage = new SPTImage($QueueEntry["ImageId"]);
                $ThisImage->Delete();
                $DB->Query("DELETE FROM AutoScreenshotApprovalQueue "
                           ."WHERE ResourceId=".intval($ResourceId));
            }
        }
    }
}
?>
