/dev/null 2>&1 // Collect data from various services and store locally for later display. //***************************************************************************// $startTime = time(); $interruptedExecution = false; register_shutdown_function('shutdown'); // make sure our file_exist returns fresh data. Likely not necessary. clearstatcache(); if(in_array($_SERVER['SERVER_NAME'],array('localhost','a.io'))) { $conf = json_decode(file_get_contents(getcwd() . '/../conf/wia.conf')); } else { $conf = json_decode(file_get_contents('/home/atomaka/conf/wia.conf')); } define('CACHE',$conf->site->path . '/data/cache.txt'); define('DATA',$conf->site->path . '/data/index.txt'); define('LOCK',$conf->site->path . '/data/whoisandrew.lock'); // All the sources we intend on pulling data from with a corresponding // cache lifetime. $dataSources = array( 'twitter' => 300, 'github' => 300, 'hulu' => 600, 'lastfm' => 60, 'sc2ranks' => 43200, 'steam' => 3600, 'wow' => 43200, ); // Make sure that the script does not begin execution if it is already. if(!file_exists(LOCK)) { touch(LOCK); } else { $interruptedExecution = true; exit(); } // In case our data files are not present if(file_exists(CACHE)) { $cacheData = json_decode(file_get_contents(CACHE),true); } else { $cacheData = array(); } if(file_exists(DATA)) { $sourceData = json_decode(file_get_contents(DATA),true); } else { $sourceData = array(); } foreach($dataSources as $dataSource=>$refreshTime) { // check last time the data was updated $lastModified = (array_key_exists($dataSource, $cacheData)) ? $cacheData[$dataSource] : 0; // and see if we need to retrieve new information if(time() - $lastModified > $refreshTime) { $cacheData[$dataSource] = time(); $data = call_user_func($dataSource); if($data != false) { echo 'updating ' . $dataSource . '
'; $sourceData[$dataSource] = $data; } else { echo 'failed ' . $dataSource . '
'; $cacheData[$dataSource] = 0; } } } file_put_contents(CACHE,json_encode($cacheData)); file_put_contents(DATA,json_encode($sourceData)); //***************************************************************************// // Data sources //***************************************************************************// function twitter() { $url = 'https://api.twitter.com/1/statuses/user_timeline.json?include_entities=true&include_rts=true&screen_name=atomaka&count=1'; $tweetInfo = json_decode(curl_request($url)); // An empty result set currently (always?) means that the last post was // retweeted. if(empty($tweetInfo)) { $data = array( 'text' => 'Last post was a retweet and cannot be listed.', 'time' => 0, ); } else { $tweet = urlify($tweetInfo[0]->text); $data = array( 'text' => $tweet, 'time' => strtotime($tweetInfo[0]->created_at), ); } if(isset($data['text']) && isset($data['time'])) { return $data; } else { return false; } } function github() { // get the last repo we worked on $url = 'https://api.github.com/users/atomaka/repos'; $repos = json_decode(curl_request($url)); // & notation for a variable to be passed by reference is actually // deprecated and will cause a warning in 5.3. However, it is // required to work in 5.2 usort(&$repos,'github_sort'); // and then get the last commit to that repo $url = sprintf('https://api.github.com/repos/atomaka/%s/commits', $repos[0]->name); $commits = json_decode(curl_request($url)); $data = array( 'commit' => $commits[0]->commit->message, 'repo' => $repos[0]->name, 'url' => $repos[0]->html_url, ); if(isset($data['commit']) && isset($data['repo']) && isset($data['url'])) { return $data; } else { return false; } } function lastfm() { $url = 'http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=atomaka&limit=1&api_key=27ea07733c17562cf1fe512586954825'; $xml = simplexml_load_file($url); $latestSong = $xml->recenttracks->track[0]; $cover = (is_array($latestSong->image)) ? 'img/lastfm/blank_album64.png' : (string)$latestSong->image[1]; $time = (isset($latestSong->attributes()->nowplaying) && (bool)$latestSong->attributes()->nowplaying) ? 0 : strtotime($latestSong->date . ' UTC'); $data = array( 'song' => (string)$latestSong->name, 'artist' => (string)$latestSong->artist, 'time' => $time, 'url' => (string)$latestSong->url, 'cover' => $cover, ); if(isset($data['song']) && isset($data['artist']) && isset($data['time']) && isset($data['url']) && isset($data['cover'])) { return $data; } else { return false; } } function sc2ranks() { $url = 'http://sc2ranks.com/api/base/teams/us/Gaffer$888.json?appKey=whoisandrew.com'; $profile = json_decode(file_get_contents($url)); // find the 1v1 team foreach($profile->teams as $team) { if($team->bracket == 1) break; } $data = array( 'league' => $team->league, 'division' => $team->division, 'rank' => $team->division_rank, 'points' => $team->points, 'wins' => $team->wins, ); if(isset($data['league']) && isset($data['division']) && isset($data['rank']) && isset($data['points']) && isset($data['wins'])) { return $data; } else { return false; } } function hulu() { $url = 'http://www.hulu.com/feed/history/atomaka'; $xml = simplexml_load_file($url); // data for last show $lastShow = $xml->channel->item[0]; $title = explode(' - ', $lastShow->title); preg_match('/description, $thumb); $data = array( 'series' => isset($title[2]) ? $title[0] : 'Not Available', 'title' => isset($title[2]) ? $title[2] : $title[0], 'time' => strtotime($lastShow->pubDate), 'url' => (string)$lastShow->link, 'thumb' => $thumb[1], ); if(isset($data['series']) && isset($data['title']) && isset($data['time']) && isset($data['url']) && isset($data['thumb'])) { return $data; } else { return false; } } function steam() { $url = 'http://steamcommunity.com/profiles/76561197993725971/?xml=1'; $xml = simplexml_load_file($url); // find the most recently played games $recentGames = array(); if(isset($xml->mostPlayedGames)) { foreach($xml->mostPlayedGames->mostPlayedGame as $game) { $recentGames[] = array( 'name' => (string)$game->gameName, 'link' => (string)$game->gameLink, 'hours' => (float)$game->hoursPlayed, ); } } $data = array( 'hours' => (float)$xml->hoursPlayed2Wk, 'recent' => $recentGames, ); if(isset($data['hours']) && isset($data['recent'])) { return $data; } else { return false; } } function wow() { $CLASSES = array( 6 => 'deathknight', 5 => 'priest', 11 => 'druid', 4 => 'rogue', 8 => 'mage', 7 => 'shaman', 1 => 'warrior', 9 => 'warlock', 3 => 'hunter', ); $characters = array( 'Gaffer' => false, 'Getburnt' => false, 'Veincane' => false, 'Toppazz' => false, 'Toopro' => false, 'Levita' => false, 'Ttg' => false, 'Notgaffer' => false, 'Loveglove' => false, ); $currentInstance = 25; // 25 = Firelands // build our mutli curl request $mh = curl_multi_init(); foreach($characters as $character=>$data) { $url = sprintf('http://us.battle.net/api/wow/character/crushridge/%s?fields=progression,talents', $character); $characters[$character] = curl_prep($url); curl_multi_add_handle($mh, $characters[$character]); } // execute the multi curl request $running = 0; do { curl_multi_exec($mh, $running); } while($running > 0); // and process the results $characterData = array(); foreach($characters as $character=>$data) { $json = json_decode( curl_multi_getcontent($characters[$character]) ); // merge heroic and normal ragnaros $bosses = $json->progression->raids[$currentInstance]->bosses; $bosses[6]->heroicKills = $bosses[7]->heroicKills; unset($bosses[7]); // find the boss with the lowest kills $leastN = 1000; $leastH = 1000; foreach($bosses as $boss) { // -1 means that the boss has never but killed on normal, but // has been on heroic so it's safe to reset to 0 for our purposes. if($boss->normalKills == -1) $boss->normalKills = 0; if(($boss->normalKills + $boss->heroicKills) < $leastN) { $leastN = $boss->normalKills + $boss->heroicKills; } if($boss->heroicKills < $leastH) $leastH = $boss->heroicKills; } //find our active talent tree foreach($json->talents as $talent) { if(isset($talent->selected)) { break; } } $characterData[$character] = array( 'name' => $character, 'level' => $json->level, 'class' => $CLASSES[$json->class], 'progression' => $leastH > 0 ? $leastH * 100 : $leastN, 'armory' => sprintf('http://us.battle.net/wow/en/character/crushridge/%s/advanced',$character), 'spec_icon' => $talent->icon, 'spec_name' => $talent->name, ); } // & notation for a variable to be passed by reference is actually // deprecated and will cause a warning in 5.3. However, it is // required to work in 5.2 usort(&$characterData,'progression_sort'); $data = $characterData; foreach($data as $character) { if(!isset($character['name'])) return false; if(!isset($character['level'])) return false; if(!isset($character['class'])) return false; if(!isset($character['progression'])) return false; if(!isset($character['armory'])) return false; if(!isset($character['spec_icon'])) return false; if(!isset($character['spec_name'])) return false; } return $data; } //***************************************************************************// // Helper functions //***************************************************************************// function curl_request($url) { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); $contents = curl_exec($curl); curl_close($curl); return $contents; } function curl_prep($url) { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($curl, CURLOPT_ENCODING, 'gzip'); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); return $curl; } function urlify($string) { $pattern ="{\\b((https?|telnet|gopher|file|wais|ftp) : [\\w/\\#~:.?+=&%@!\\-]+?) (?= [.:?\\-]* (?:[^\\w/\\#~:.?+=&%@!\\-] |$) ) }x"; return preg_replace($pattern,"$1", $string); } function github_sort($a, $b) { return strtotime($a->pushed_at) < strtotime($b->pushed_at); } function progression_sort($a, $b) { return $a['progression'] < $b['progression']; } function shutdown() { // need to make the variables we need available global $interruptedExecution, $startTime, $conf; $db = mysqli_init(); $db->real_connect($conf->db->hostname,$conf->db->username,$conf->db->password, $conf->db->database); // $interruptedExecution is true if our lock file still existed when the // script began execution. true also implies that the lock file does not // exist. if($interruptedExecution) { $query = "INSERT INTO wia_log (time,type,description) VALUES(NOW(), 'warning', 'The script attempted to run while another copy was already processing')"; $db->query($query); } else { unlink(LOCK); } $completionTime = time() - $startTime; // If the script took longer to execute than the server allows and the server // does not have an unlimited execution time if($completionTime >= ini_get('max_execution_time') && ini_get('max_execution_time') != 0) { $message = 'The script reached the maximum execution time: ' . $completionTime; $query = "INSERT INTO wia_log (time,type,description) VALUES(NOW(), 'warning','$message')"; $db->query($query); } } ?>