Location: PHPKode > scripts > Duck Roll Builder > duck-roll-builder/DuckRollBuilder.class.php
<?php

/********************************************************
 * Duck Roll Builder                                    *
 *                                                      *
 * This script will, given an artist and song, find     *
 * a YouTube result, pair it with results from 1 or 2   *
 * lyrics sites and create static HTML duckroll pages.  *
 * This is terribly annoying and recommended only for   *
 * dear friends or bitter enemies. I am not responsible *
 * for your annoying friends.                           *
 *                                                      *
 * @author Abbey Hawk Sparrow                           *
 * @version 1.0                                         *
 * @creation-date 01/09/09                              *
 * @modification-date 01/10/09                          *
 * a simple usage of this class is as follows:          *
 ********************************************************
 * require('DuckRollBuilder.class.php');
 *     
 *     $roller = new DuckRollBuilder('./Rolls');
 *     if(isset($_REQUEST['artist']) && isset($_REQUEST['song'])){
 *         if($_REQUEST['remove'] == 'true'){
 *             $roller->remove_roll($_REQUEST['artist'], $_REQUEST['song']);
 *             echo('<meta http-equiv="refresh" content="0;index.php" />');
 *             exit();
 *         }else{
 *             $roller->roll($_REQUEST['artist'], $_REQUEST['song']);
 *         }
 *     }else{
 *         $existing_rolls = $roller->rolls();
 *         $roll_list = '<ul>';
 *         foreach($existing_rolls as $artist=>$songs){
 *             $roll_list .= '<li><b>'.$artist.'</b><ol>';
 *             foreach($songs as $song=>$url){
 *                 $roll_list .= '<li><a href="'.$url.'">'.$song.'</a>[<a href="index.php?song='.$song.'&artist='.$artist.'&remove=true">X</a>]</li>';
 *             }
 *             $roll_list .= '</ol></li>';
 *         }
 *         $roll_list .= '</ul>';
 *         echo('<html><head><title>Dynamic Duck Roller</title></head><body><form><input type="text" name="artist">artist</input><input type="text" name="song">song</input><input type="submit" value="Roll" /></form>'.$roll_list.'</body></html>');
 *     }
 ****************************************************/

class DuckRollBuilder{
    protected $path;
    
    function __construct($path){
        if(file_exists($path)){
            if(!is_dir($path)) throw new Exception('destination must be a folder!');
        }else{
            mkdir($path);
        }
        $this->path = $path;
    }
    public function goto($band, $song){
        $band_folder_name = preg_replace('~ ~', '', $band);
        $song_folder_name = preg_replace('~ ~', '', $song);
        $song_folder_path = $this->path.'/'.$band_folder_name.'/'.$song_folder_name;
        $location = $song_folder_path.'/';
        //drop meta and exit here
        echo('<meta http-equiv="refresh" content="0;'.$location.'" />');
        exit();
    }
    
    public function rolls(){
        $results = array();
        $artists = scandir($this->path);
        foreach($artists as $artist){
            if(substr($artist, 0, 1) != '.'){
                $songs = scandir($this->path.'/'.$artist);
                foreach($songs as $song){
                    if(substr($song, 0, 1) != '.'){
                        $results[$artist][$song] = $this->path.'/'.$artist.'/'.$song;
                    }
                }
            }
        }
        return $results;
    }
    
    public function remove_roll($artist, $song){
        $band_folder_name = preg_replace('~ ~', '', $artist);
        $song_folder_name = preg_replace('~ ~', '', $song);
        $location = $this->path.'/'.$band_folder_name.'/'.$song_folder_name;
        if(file_exists($location.'/index.html')){
            chmod ($location.'/index.html', 0777);
            unlink($location.'/index.html');
            chmod ($location, 0777);
            rmdir($location);
            $songs = scandir($this->path.'/'.$band_folder_name);
            if(count($songs) < 3){
                chmod ($this->path.'/'.$band_folder_name, 0777);
                rmdir($this->path.'/'.$band_folder_name);
            }
        }
    }

    public function roll($band, $song){
        if(!$this->exists($band, $song)) $this->build($band, $song);
        $this->goto($band, $song);
    }

    public function exists($band, $song){
        $band_folder_name = preg_replace('~ ~', '', $band);
        $song_folder_name = preg_replace('~ ~', '', $song);
        $song_folder_path = $this->path.'/'.$band_folder_name.'/'.$song_folder_name;
        return (file_exists($song_folder_path.'/index.html'));
    }
    
    public function build($band, $song){
        //make the folders we need if they don't already exist
        $band_folder_name = preg_replace('~ ~', '', $band);
        $band_folder_path = $this->path.'/'.$band_folder_name;
        if(!file_exists($band_folder_path)) mkdir($band_folder_path);
        $song_folder_name = preg_replace('~ ~', '', $song);
        $song_folder_path = $this->path.'/'.$band_folder_name.'/'.$song_folder_name;
        if(!file_exists($song_folder_path)) mkdir($song_folder_path);
        //get the data
        $lyrics = $this->getLyrics($band, $song);
        $video = $this->getVideo($band, $song);
        $fp = fopen($song_folder_path."/index.html", "w");
        fwrite($fp, $this->buildRoll($lyrics, $video));
        fclose($fp);
    }
    
    public function getVideo($band, $song){
        $band_url_name = preg_replace('~ ~', '+', $band);
        $song_url_name = preg_replace('~ ~', '+', $song);
        $url = 'http://www.youtube.com/results?search_query='.$band_url_name.'+'.$song_url_name;
        $page = $this->fetchPage($url);
        if(preg_match('~<div class="video-short-title">.*?href="/watch\?v=(.*?)".*?</div>~s', $page, $matches)){
            $embed = '<embed src="http://www.youtube.com/v/'.$matches[1].'&hl=en&autoplay=1" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed>';
            return $embed;
        }else throw new Exception('Unable to find video!');
    }
    
    public function getLyrics($band, $song){
        $band_url_name = preg_replace('~ ~', '+', $band);
        $song_url_name = preg_replace('~ ~', '+', $song);
        try{
            //$lyrics = $this->getLeoLyrics($band_url_name, $song_url_name);
            $lyrics = $this->getAstraWebLyrics($band_url_name, $song_url_name);
        }catch(Exception $ex){
            $lyrics = $this->getAstraWebLyrics($band_url_name, $song_url_name);
        }
        return $lyrics;
    }
    
    private function getLeoLyrics($band_url_name, $song_url_name){
        $url = 'http://www.leoslyrics.com/search.php?search='.$band_url_name.'+'.$song_url_name.'sartist=1&ssongtitle=1';
        $page = $this->fetchPage($url);
        if(preg_match('~href="(/listlyrics.php.*?)"~', $page, $matches)){
            $url = 'http://www.leoslyrics.com/'.$matches[1];
            $page = $this->fetchPage($url);
            if(preg_match('~<font face="Trebuchet MS, Verdana, Arial" size=-1>(.*?)</font>~s', $page, $matches)){
                //$lyrics = trim($matches[1]);
                $lyrics = preg_replace('~<br +/*>~', '', trim($matches[1]));
                $lyrics = preg_replace('~[\n\r]~', "\\n\\\n", $lyrics);
                $lyrics = preg_replace('~&#39;~', "'", $lyrics);
                return $lyrics;
            }else throw new Exception('Unable to find lyrics!');
        }else throw new Exception('Unable to find lyrics!');
    }
    
    private function getAstraWebLyrics($band_url_name, $song_url_name){
        $url = 'http://search.lyrics.astraweb.com/?word='.$band_url_name.'+'.$song_url_name;
        $page = $this->fetchPage($url);
        if(preg_match('~1\. <b><a href="(.*?)">~', $page, $matches)){
            $url = 'http://lyrics.astraweb.com'.$matches[1];
            $page = $this->fetchPage($url);
            if(preg_match('~<font face=arial size=2>(.*?)</font>~s', $page, $matches)){
                $lyrics = preg_replace('~\n~', "\\\n", preg_replace('~<br>~', " \\n\n", trim($matches[1])));
                return $lyrics;
            }else throw new Exception('Unable to find lyrics!');
        }else throw new Exception('Unable to find lyrics!');
    }
    
    private function fetchPage($url, $post=null){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $location->url);
        curl_setopt($ch, CURLOPT_FAILONERROR, 1);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);// allow redirects
        curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); // return into a variable
        curl_setopt($ch, CURLOPT_TIMEOUT, 20); // times out after 20s
        //curl_setopt($ch, CURLOPT_USERAGENT, $agent);
        if($post == null) curl_setopt($ch, CURLOPT_URL, $url);
        else{
            curl_setopt($ch, CURLOPT_URL, $url.'?'.$post);
            curl_setopt($ch, CURLOPT_POST, 0);
        }
        $result = curl_exec($ch); // run the whole process
        curl_close($ch);
        return $result;
    }
    
    private function buildRoll($lyrics, $embed){
        return '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head>


 <meta http-equiv="content-type" content="text/html; charset=utf-8"><title>blah blah</title>
 
 <script type="text/javascript">
<!--
if (self.parent.frames.length && self.parent.frames.length != 0) self.parent.location = document.location;
neva = "'.preg_replace("~['\"]~", "", $lyrics).'";
if(window.opera){
  window.onkeydown = function(e){
    if(e.keyCode != 18 && e.keyCode != 27 && e.keyCode != 32 && e.keyCode !=  115){
      if(Math.random() > .5) for(var i = 0; i < 35; i++) document.getElementById(\'roll\').Back();
      else for(var i = 0; i < 53; i++) document.getElementById(\'roll\').Forward();
      document.getElementById(\'roll\').Play();
    }
    else if(e.keyCode == 115){
      for(x in neva.split(\'\n\')){
        alert(neva.split(\'\n\')[x]);
      }
    }
    return false;
  }
}else{
  window.onkeydown = function(e){
    if(e.keyCode !=  13 && e.keyCode != 27 && e.keyCode != 32){
      if(Math.random() > .5) for(var i = 0; i < 35; i++) document.getElementById(\'roll\').Back();
      else for(var i = 0; i < 53; i++) document.getElementById(\'roll\').Forward();
      document.getElementById(\'roll\').Play();
    }
    return false;
  }
}
/* document.onkeydown = function(){
  for(var i = 0; i < 35; i++) document.getElementById(\'roll\').Back();
  document.getElementById(\'roll\').Play();
  return false;
} */
window.resizeTo(460,470);
window.moveTo(0,0);
for (i = 1; i <= 20; i++){
setTimeout(\'window.moveTo(1599,1199);\', i+"000");
i++;
setTimeout(\'window.moveTo(0,1199);\', i+"000");
i++;
setTimeout(\'window.moveTo(1599,0);\', i+"000");
i++;
setTimeout(\'window.moveTo(0,0);\', i+"000");
}
//-->
</script></head><body onbeforeunload="for(x in neva.split(\'\n\')){ alert(neva.split(\'\n\')[x]); } return false;">
<script type="text/javascript">
<!--
if(window.attachEvent){
  document.body.onkeydown = function(){
    if(Math.random() > .5) for(var i = 0; i < 35; i++) document.getElementById(\'roll\').Back();
    else for(var i = 0; i < 53; i++) document.getElementById(\'roll\').Forward();
    document.getElementById(\'roll\').Play();
    return false;
  }
}
//-->
</script>
'.$embed.'

</body></html>';
    }
}

?>
Return current item: Duck Roll Builder