Bug fixes!
This commit is contained in:
parent
45561c4101
commit
e294816071
|
@ -6,7 +6,5 @@ web/static/api/*
|
|||
*.DS_Store
|
||||
*.apdisk
|
||||
*.zip
|
||||
<<<<<<< local
|
||||
*.mp3
|
||||
=======
|
||||
>>>>>>> other
|
||||
db.sql
|
||||
|
|
|
@ -12,4 +12,6 @@ return array(
|
|||
'db_pass' => 'PVLRadio2013!',
|
||||
'db_name' => 'centova',
|
||||
|
||||
// Time zone to use when submitting requests.
|
||||
'timezone' => 'US/Eastern',
|
||||
);
|
|
@ -3,6 +3,7 @@ namespace PVL;
|
|||
|
||||
use \Entity\Station;
|
||||
use \Entity\StationMedia;
|
||||
use \Entity\StationRequest;
|
||||
|
||||
class CentovaCast
|
||||
{
|
||||
|
@ -38,6 +39,11 @@ class CentovaCast
|
|||
{
|
||||
$db = self::getDatabase();
|
||||
$em = self::getEntityManager();
|
||||
$settings = self::getSettings();
|
||||
|
||||
// Forbid web crawlers from using this feature.
|
||||
if (\PVL\Utilities::isCrawler())
|
||||
throw new \DF\Exception('Search engine crawlers are not permitted to use this feature.');
|
||||
|
||||
// Verify that the station supports CentovaCast requests.
|
||||
$station_id = self::getStationID($station);
|
||||
|
@ -108,17 +114,28 @@ class CentovaCast
|
|||
if (count($existing_request) > 0)
|
||||
throw new \DF\Exception('You already have a pending request with this station! Please try again later.');
|
||||
|
||||
// Check for any request (on any station) within 5 minutes.
|
||||
$recent_threshold = time()-(60*5);
|
||||
|
||||
$recent_requests = $em->createQuery('SELECT sr FROM Entity\StationRequest sr WHERE sr.ip = :user_ip AND sr.timestamp >= :threshold')
|
||||
->setParameter('user_ip', $user_ip)
|
||||
->setParameter('threshold', $recent_threshold)
|
||||
->getArrayResult();
|
||||
|
||||
if (count($recent_requests) > 0)
|
||||
throw new \DF\Exception('You have submitted a request too recently! Please wait a while before submitting another one.');
|
||||
|
||||
// Enable the "Automated Song Requests" playlist.
|
||||
$updated_playlist = array(
|
||||
'status' => 'enabled',
|
||||
);
|
||||
$db->update('playlists', $updated_playlist, array('id' => $playlist_id));
|
||||
$db->update('playlists', array('status' => 'enabled'), array('id' => $playlist_id));
|
||||
|
||||
$requesttime = new \DateTime('NOW');
|
||||
$requesttime->setTimezone(new \DateTimeZone($settings['timezone']));
|
||||
|
||||
// Create a new request if all other checks pass.
|
||||
$new_request = array(
|
||||
'playlistid' => $playlist_id,
|
||||
'trackid' => $track_id,
|
||||
'requesttime' => date('Y-m-d h:i:s'),
|
||||
'requesttime' => $requesttime->format('Y-m-d h:i:s'),
|
||||
'sendername' => 'Ponyville Live!',
|
||||
'senderemail' => 'requests@ponyvillelive.com',
|
||||
'dedication' => '',
|
||||
|
@ -157,6 +174,23 @@ class CentovaCast
|
|||
$db->executeQuery('DELETE FROM playbackstats_tracks WHERE endtime <= ?', array($threshold_date));
|
||||
$db->executeQuery('DELETE FROM visitorstats_sessions WHERE endtime <= ?', array($threshold_date));
|
||||
|
||||
// Delete old requests still listed as pending.
|
||||
$requesttime = new \DateTime('NOW');
|
||||
$requesttime->modify('-3 hours');
|
||||
$requesttime->setTimezone(new \DateTimeZone($settings['timezone']));
|
||||
|
||||
$threshold_requests = $requesttime->format('Y-m-d h:i:s');
|
||||
$db->executeQuery('DELETE FROM playlist_tracks_requests WHERE requesttime <= ?', array($threshold_requests));
|
||||
|
||||
// Force playlist enabling for existing pending requests.
|
||||
$request_playlists_raw = $db->fetchAll('SELECT DISTINCT ptr.playlistid AS pid FROM playlist_tracks_requests AS ptr');
|
||||
|
||||
foreach($request_playlists_raw as $pl)
|
||||
{
|
||||
$pl_id = $pl['pid'];
|
||||
$db->update('playlists', array('status' => 'enabled'), array('id' => $pl_id));
|
||||
}
|
||||
|
||||
// Preload all station media locally.
|
||||
$stations = $em->createQuery('SELECT s FROM Entity\Station s WHERE s.requests_enabled = 1')->execute();
|
||||
|
||||
|
|
|
@ -3,30 +3,9 @@ namespace PVL\NewsAdapter;
|
|||
|
||||
class YouTube extends AdapterAbstract
|
||||
{
|
||||
public static function getAccount($url)
|
||||
{
|
||||
if (stristr($url, 'youtube.com') !== FALSE)
|
||||
{
|
||||
$url_parts = parse_url($url);
|
||||
$path = rtrim($url_parts['path'], '/');
|
||||
|
||||
$url_components = explode('/', $path);
|
||||
$url_last_element = array_pop($url_components);
|
||||
$account = trim($url_last_element);
|
||||
}
|
||||
else
|
||||
{
|
||||
$account = trim($url);
|
||||
}
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
public static function fetch($url, $params = array())
|
||||
{
|
||||
$api_key = 'AI39si5oveOXVqbMmAeF-7oZ8NeDTeqo27ghNJVTi1yTBVpf3j03Vfs2hx908oI0zCAF07tpFS4N8cAXJnH9TaYhFPKWN6_hLA';
|
||||
|
||||
$username = self::getAccount($url);
|
||||
$v3_api_key = 'AIzaSyC1vhf1rFShf9mzbUEL2LpfaD0E0BNOURk';
|
||||
|
||||
$client = new \Zend_Http_Client();
|
||||
$client->setConfig(array(
|
||||
|
@ -34,19 +13,45 @@ class YouTube extends AdapterAbstract
|
|||
'keepalive' => true,
|
||||
));
|
||||
|
||||
$client->setUri('http://gdata.youtube.com/feeds/api/videos');
|
||||
$account_info = self::getAccount($url);
|
||||
|
||||
if ($account_info['type'] == 'user')
|
||||
{
|
||||
$client->setUri('https://www.googleapis.com/youtube/v3/channels');
|
||||
$client->setParameterGet(array(
|
||||
'part' => 'id,contentDetails',
|
||||
'forUsername' => $account_info['id'],
|
||||
'maxResults' => 25,
|
||||
'key' => $v3_api_key,
|
||||
));
|
||||
|
||||
$response = $client->request('GET');
|
||||
|
||||
if ($response->isSuccessful())
|
||||
{
|
||||
$response_text = $response->getBody();
|
||||
$data = @json_decode($response_text, TRUE);
|
||||
|
||||
$playlist_id = $data['items'][0]['contentDetails']['relatedPlaylists']['uploads'];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$playlist_id = $account_info['id'];
|
||||
}
|
||||
|
||||
if (!$playlist_id)
|
||||
return null;
|
||||
|
||||
$client->setUri('https://www.googleapis.com/youtube/v3/playlistItems');
|
||||
$client->setParameterGet(array(
|
||||
'alt' => 'json',
|
||||
'author' => $username,
|
||||
'orderby' => 'published',
|
||||
'safeSearch' => 'none',
|
||||
'racy' => 'include',
|
||||
'part' => 'id,snippet,status,contentDetails',
|
||||
'playlistId' => $playlist_id,
|
||||
'maxResults' => 25,
|
||||
'key' => $v3_api_key,
|
||||
));
|
||||
|
||||
$client->setHeaders('GData-Version: 2');
|
||||
$client->setHeaders('X-GData-Key: key='.$api_key);
|
||||
$response = $client->request('GET');
|
||||
|
||||
$news_items = array();
|
||||
|
||||
if ($response->isSuccessful())
|
||||
|
@ -54,35 +59,57 @@ class YouTube extends AdapterAbstract
|
|||
$response_text = $response->getBody();
|
||||
$data = @json_decode($response_text, TRUE);
|
||||
|
||||
$feed_items = (array)$data['feed']['entry'];
|
||||
$feed_items = (array)$data['items'];
|
||||
|
||||
foreach($feed_items as $item)
|
||||
{
|
||||
$embed_src = $item['link'][0]['href'];
|
||||
|
||||
$thumbnails = (array)$item['media$group']['media$thumbnail'];
|
||||
foreach($thumbnails as $thumb)
|
||||
{
|
||||
if (stristr($thumb['url'], 'mqdefault') !== FALSE)
|
||||
$thumbnail = $thumb['url'];
|
||||
}
|
||||
if (!$thumbnail)
|
||||
$thumbnail = $thumbnails[0]['url'];
|
||||
|
||||
$body = '<a class="fancybox fancybox.iframe" href="'.$embed_src.'"><img src="'.$thumbnail.'" alt="Click to Watch Video"></a>';
|
||||
$body .= '<p>'.$item['media$group']['media$description']['$t'].'</p>';
|
||||
$embed_src = 'http://www.youtube.com/watch?v='.$item['contentDetails']['videoId'];
|
||||
|
||||
$news_items[] = array(
|
||||
'guid' => 'youtube_'.md5($item['id']['$t']),
|
||||
'timestamp' => strtotime($item['published']['$t']),
|
||||
'title' => $item['title']['$t'],
|
||||
'body' => $body,
|
||||
'guid' => 'youtube_'.md5($item['id']),
|
||||
'timestamp' => strtotime($item['snippet']['publishedAt']),
|
||||
'title' => $item['snippet']['title'],
|
||||
'body' => $item['snippet']['description'],
|
||||
'web_url' => $embed_src,
|
||||
'author' => $item['author'][0]['name']['$t'],
|
||||
'author' => $item['snippet']['channelTitle'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $news_items;
|
||||
}
|
||||
|
||||
public static function getAccount($url)
|
||||
{
|
||||
if (stristr($url, 'youtube.com') !== FALSE)
|
||||
{
|
||||
$url_parts = \PVL\Utilities::parseUrl($url);
|
||||
|
||||
if ($url_parts['path_clean'] == 'playlist')
|
||||
{
|
||||
return array(
|
||||
'type' => 'playlist',
|
||||
'id' => $url_parts['query_arr']['list'],
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$url_components = explode('/', $url_parts['path']);
|
||||
$url_last_element = array_pop($url_components);
|
||||
$account = trim($url_last_element);
|
||||
|
||||
return array(
|
||||
'type' => 'user',
|
||||
'id' => $account,
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return array(
|
||||
'type' => 'user',
|
||||
'id' => trim($url),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?
|
||||
namespace PVL;
|
||||
|
||||
class Utilities
|
||||
{
|
||||
public static function parseUrl($url)
|
||||
{
|
||||
$url_parts = @parse_url($url);
|
||||
$url_parts['path_clean'] = trim($url_parts['path'], '/');
|
||||
$url_parts['query_arr'] = self::convertUrlQuery($url_parts['query']);
|
||||
|
||||
return $url_parts;
|
||||
}
|
||||
|
||||
public static function convertUrlQuery($query)
|
||||
{
|
||||
$queryParts = explode('&', $query);
|
||||
$params = array();
|
||||
foreach ($queryParts as $param)
|
||||
{
|
||||
$item = explode('=', $param);
|
||||
$params[$item[0]] = $item[1];
|
||||
}
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* User-Agent Detection
|
||||
*/
|
||||
|
||||
public static function isCrawler()
|
||||
{
|
||||
$ua = strtolower($_SERVER['HTTP_USER_AGENT']);
|
||||
|
||||
$crawlers_agents = strtolower('Bloglines subscriber|Dumbot|Sosoimagespider|QihooBot|FAST-WebCrawler|Superdownloads Spiderman|LinkWalker|msnbot|ASPSeek|WebAlta Crawler|Lycos|FeedFetcher-Google|Yahoo|YoudaoBot|AdsBot-Google|Googlebot|Scooter|Gigabot|Charlotte|eStyle|AcioRobot|GeonaBot|msnbot-media|Baidu|CocoCrawler|Google|Charlotte t|Yahoo! Slurp China|Sogou web spider|YodaoBot|MSRBOT|AbachoBOT|Sogou head spider|AltaVista|IDBot|Sosospider|Yahoo! Slurp|Java VM|DotBot|LiteFinder|Yeti|Rambler|Scrubby|Baiduspider|accoona');
|
||||
$crawlers = explode("|", $crawlers_agents);
|
||||
|
||||
foreach($crawlers as $crawler)
|
||||
{
|
||||
if (strpos($ua, trim($crawler)) !== false)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -68,6 +68,11 @@ class StationMedia extends \DF\Doctrine\Entity
|
|||
{
|
||||
$this->requests = (int)$this->requests + 1;
|
||||
$this->newest_request = time();
|
||||
|
||||
$record = new StationRequest;
|
||||
$record->track = $this;
|
||||
$record->station = $this->station;
|
||||
$record->save();
|
||||
}
|
||||
|
||||
public function setLength($length)
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
namespace Entity;
|
||||
|
||||
use \Doctrine\Common\Collections\ArrayCollection;
|
||||
|
||||
/**
|
||||
* @Table(name="station_requests")
|
||||
* @Entity
|
||||
*/
|
||||
class StationRequest extends \DF\Doctrine\Entity
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->timestamp = time();
|
||||
$this->ip = $_SERVER['REMOTE_ADDR'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @Column(name="id", type="integer")
|
||||
* @Id
|
||||
* @GeneratedValue(strategy="IDENTITY")
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/** @Column(name="station_id", type="integer") */
|
||||
protected $station_id;
|
||||
|
||||
/** @Column(name="track_id", type="integer") */
|
||||
protected $track_id;
|
||||
|
||||
/** @Column(name="timestamp", type="integer") */
|
||||
protected $timestamp;
|
||||
|
||||
/** @Column(name="ip", type="string", length=15) */
|
||||
protected $ip;
|
||||
|
||||
/**
|
||||
* @ManyToOne(targetEntity="Station", inversedBy="media")
|
||||
* @JoinColumns({
|
||||
* @JoinColumn(name="station_id", referencedColumnName="id", onDelete="CASCADE")
|
||||
* })
|
||||
*/
|
||||
protected $station;
|
||||
|
||||
/**
|
||||
* @ManyToOne(targetEntity="StationMedia")
|
||||
* @JoinColumns({
|
||||
* @JoinColumn(name="track_id", referencedColumnName="id", onDelete="CASCADE")
|
||||
* })
|
||||
*/
|
||||
protected $track;
|
||||
}
|
|
@ -79,7 +79,7 @@ class IndexController extends \DF\Controller\Action
|
|||
if ($this->_hasParam('autoplay'))
|
||||
$autoplay = ((bool)$autoplay == true);
|
||||
else
|
||||
$autoplay = ($this->_getParam('showonlystation', false) == 'true');
|
||||
$autoplay = false;
|
||||
|
||||
$this->view->autoplay = $autoplay;
|
||||
$this->view->standalone = true;
|
||||
|
|
|
@ -16,10 +16,18 @@ class UtilController extends \DF\Controller\Action
|
|||
error_reporting(E_ALL & ~E_NOTICE);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
\PVL\CentovaCast::sync();
|
||||
$db = \PVL\CentovaCast::getDatabase();
|
||||
$settings = \PVL\CentovaCast::getSettings();
|
||||
|
||||
echo 'CC Synced';
|
||||
// Delete old requests still listed as pending.
|
||||
$requesttime = new \DateTime('NOW');
|
||||
$requesttime->modify('-3 hours');
|
||||
$requesttime->setTimezone(new \DateTimeZone($settings['timezone']));
|
||||
|
||||
$threshold_requests = $requesttime->format('Y-m-d h:i:s');
|
||||
$db->executeQuery('DELETE FROM playlist_tracks_requests WHERE requesttime <= ?', array($threshold_requests));
|
||||
|
||||
echo 'Deleted all records before '.$threshold_requests;
|
||||
exit;
|
||||
|
||||
$results = \Entity\StationMedia::search(1, 'Lost on the');
|
||||
|
|
|
@ -2,10 +2,28 @@
|
|||
$this->headTitle('Download the Archive');
|
||||
?>
|
||||
|
||||
<h2>Your Favorite Pony Songs, All In One Place.</h2>
|
||||
|
||||
<p>You can download the existing MLP Music Archive using the link below.<br>This version of the archive was created on November 27, 2012.</p>
|
||||
<h2>Latest Version</h2>
|
||||
<p>You can download the newest MLP Music Archive using the link below.</p>
|
||||
|
||||
<div class="buttons">
|
||||
<a href="https://docs.google.com/open?id=0B5LW1ZIpaxUIZkIwdUtsQnFKUVU" class="btn btn-xlarge btn-primary">Download v14 (Torrent)</a>
|
||||
</div>
|
||||
<?=$this->button(array(
|
||||
'type' => 'link',
|
||||
'class' => 'btn-large btn-primary',
|
||||
'icon' => 'icon-download',
|
||||
'text' => 'Download MLPMA Version 15, Fall 2013 (.torrent)',
|
||||
'href' => '//ponyvillelive.com/resources/mlpma_v15.torrent',
|
||||
)) ?>
|
||||
</div>
|
||||
|
||||
<h2>Older Versions</h2>
|
||||
<p>Old versions of the MLP Music Archive are available for download below.</p>
|
||||
|
||||
<ul class="nav nav-list">
|
||||
<li><a href="//ponyvillelive.com/resources/mlpma_v14.torrent"><i class="icon-download"></i> MLPMA Version 14, Fall 2012 (.torrent)</a></li>
|
||||
</ul>
|
||||
|
||||
<br>
|
||||
<h2>About .torrent Files</h2>
|
||||
<p>A .torrent file lets you download files from the BitTorrent peer-to-peer file sharing network. Since the MLPMA is so large, this is the best way to make sure everyone can download it at the fastest possible speeds, without overloading servers in the process.</p>
|
||||
|
||||
<p>In order to download .torrent files, you will need a BitTorrent downloader tool. There are many options available, but a simple lightweight option is the <a href="http://deluge-torrent.org/">Deluge</a> client.</p>
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -18,4 +18,10 @@
|
|||
# http://www.sxw.org.uk/computing/robots/check.html
|
||||
|
||||
User-agent: *
|
||||
Crawl-delay: 10
|
||||
Crawl-delay: 2
|
||||
|
||||
# Prevent GoogleBot from requesting tracks!
|
||||
Disallow: /station/request/*
|
||||
|
||||
# Allow all others.
|
||||
Allow: /
|
|
@ -144,14 +144,14 @@
|
|||
.navbar-inner,
|
||||
.nav,
|
||||
.navbar-inverse {
|
||||
background:#fff;
|
||||
background: none;
|
||||
filter:none;
|
||||
border:none;
|
||||
padding:0;
|
||||
margin:0 !important;
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.nav i.icon-sort-up {
|
||||
|
@ -160,6 +160,10 @@
|
|||
bottom:-6px;
|
||||
}
|
||||
|
||||
.navbar-inverse .navbar-inner {
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
.navbar-inner {
|
||||
padding-left: 0px !important;
|
||||
padding-right: 0px !important;
|
||||
|
|
|
@ -17,9 +17,12 @@ $(function() {
|
|||
socials: 1,
|
||||
volume: 1,
|
||||
playlist: 1,
|
||||
storePlaylist: 1,
|
||||
loopPlaylist: 0,
|
||||
autoPopup: 0,
|
||||
sortable: true
|
||||
keyboard: 0,
|
||||
sortable: 1,
|
||||
opened: 0
|
||||
});
|
||||
|
||||
$('body').initPage();
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 5.9 KiB |
Loading…
Reference in New Issue