<?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('~'~', "'", $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>';
}
}
?>