mirror of
https://github.com/Yetangitu/ampache
synced 2025-10-05 19:41:55 +02:00
Add Podcast feature
This commit is contained in:
parent
58fa76fe3d
commit
baaceca250
43 changed files with 2857 additions and 111 deletions
19
browse.php
19
browse.php
|
@ -57,6 +57,8 @@ switch ($_REQUEST['action']) {
|
||||||
case 'personal_video':
|
case 'personal_video':
|
||||||
case 'label':
|
case 'label':
|
||||||
case 'pvmsg':
|
case 'pvmsg':
|
||||||
|
case 'podcast':
|
||||||
|
case 'podcast_episode':
|
||||||
$browse->set_type($_REQUEST['action']);
|
$browse->set_type($_REQUEST['action']);
|
||||||
$browse->set_simple_browse(true);
|
$browse->set_simple_browse(true);
|
||||||
break;
|
break;
|
||||||
|
@ -202,8 +204,23 @@ switch ($_REQUEST['action']) {
|
||||||
$browse->update_browse_from_session();
|
$browse->update_browse_from_session();
|
||||||
$browse->show_objects();
|
$browse->show_objects();
|
||||||
break;
|
break;
|
||||||
|
case 'podcast':
|
||||||
|
if (AmpConfig::get('catalog_disable')) {
|
||||||
|
$browse->set_filter('catalog_enabled', '1');
|
||||||
|
}
|
||||||
|
$browse->set_sort('title','ASC');
|
||||||
|
$browse->update_browse_from_session();
|
||||||
|
$browse->show_objects();
|
||||||
|
break;
|
||||||
|
case 'podcast_episode':
|
||||||
|
if (AmpConfig::get('catalog_disable')) {
|
||||||
|
$browse->set_filter('catalog_enabled', '1');
|
||||||
|
}
|
||||||
|
$browse->set_sort('pubdate','DESC');
|
||||||
|
$browse->update_browse_from_session();
|
||||||
|
$browse->show_objects();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} // end Switch $action
|
} // end Switch $action
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
; if this config file is up to date
|
; if this config file is up to date
|
||||||
; this is compared against a value hard-coded
|
; this is compared against a value hard-coded
|
||||||
; into the init script
|
; into the init script
|
||||||
config_version = 32
|
config_version = 33
|
||||||
|
|
||||||
;#########################################################
|
;#########################################################
|
||||||
; Path Vars #
|
; Path Vars #
|
||||||
|
@ -554,6 +554,12 @@ channel = "true"
|
||||||
; DEFAULT: true
|
; DEFAULT: true
|
||||||
live_stream = "true"
|
live_stream = "true"
|
||||||
|
|
||||||
|
; Podcasts
|
||||||
|
; Set this to true to enable podcasts and the
|
||||||
|
; possibility for admins to subscribe to new podcasts.
|
||||||
|
; DEFAULT: false
|
||||||
|
;podcast = "false"
|
||||||
|
|
||||||
; Web Socket address
|
; Web Socket address
|
||||||
; Declare the web socket server address
|
; Declare the web socket server address
|
||||||
; DEFAULT: determined automatically
|
; DEFAULT: determined automatically
|
||||||
|
|
|
@ -333,6 +333,14 @@ class Browse extends Query
|
||||||
$box_title = T_('Private Messages');
|
$box_title = T_('Private Messages');
|
||||||
$box_req = AmpConfig::get('prefix') . UI::find_template('show_pvmsgs.inc.php');
|
$box_req = AmpConfig::get('prefix') . UI::find_template('show_pvmsgs.inc.php');
|
||||||
break;
|
break;
|
||||||
|
case 'podcast':
|
||||||
|
$box_title = T_('Podcasts');
|
||||||
|
$box_req = AmpConfig::get('prefix') . UI::find_template('show_podcasts.inc.php');
|
||||||
|
break;
|
||||||
|
case 'podcast_episode':
|
||||||
|
$box_title = T_('Podcast Episodes');
|
||||||
|
$box_req = AmpConfig::get('prefix') . UI::find_template('show_podcast_episodes.inc.php');
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// Rien a faire
|
// Rien a faire
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -526,10 +526,16 @@ abstract class Catalog extends database_object
|
||||||
* of what you find
|
* of what you find
|
||||||
* @return int[]
|
* @return int[]
|
||||||
*/
|
*/
|
||||||
public static function get_catalogs()
|
public static function get_catalogs($filter_type='')
|
||||||
{
|
{
|
||||||
$sql = "SELECT `id` FROM `catalog` ORDER BY `name`";
|
$params = array();
|
||||||
$db_results = Dba::read($sql);
|
$sql = "SELECT `id` FROM `catalog` ";
|
||||||
|
if (!empty($filter_type)) {
|
||||||
|
$sql .= "WHERE `gather_types` = ? ";
|
||||||
|
$params[] = $filter_type;
|
||||||
|
}
|
||||||
|
$sql .= "ORDER BY `name`";
|
||||||
|
$db_results = Dba::read($sql, $params);
|
||||||
|
|
||||||
$results = array();
|
$results = array();
|
||||||
|
|
||||||
|
@ -615,7 +621,7 @@ abstract class Catalog extends database_object
|
||||||
$gather_types = $data['gather_media'];
|
$gather_types = $data['gather_media'];
|
||||||
|
|
||||||
// Should it be an array? Not now.
|
// Should it be an array? Not now.
|
||||||
if (!in_array($gather_types, array('music', 'clip', 'tvshow', 'movie', 'personal_video'))) {
|
if (!in_array($gather_types, array('music', 'clip', 'tvshow', 'movie', 'personal_video', 'podcast'))) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -722,6 +728,11 @@ abstract class Catalog extends database_object
|
||||||
$db_results = Dba::read($sql, $params);
|
$db_results = Dba::read($sql, $params);
|
||||||
$data = Dba::fetch_row($db_results);
|
$data = Dba::fetch_row($db_results);
|
||||||
$live_streams = $data[0];
|
$live_streams = $data[0];
|
||||||
|
|
||||||
|
$sql = 'SELECT COUNT(`id`) FROM `podcast`';
|
||||||
|
$db_results = Dba::read($sql, $params);
|
||||||
|
$data = Dba::fetch_row($db_results);
|
||||||
|
$podcasts = $data[0];
|
||||||
|
|
||||||
$results = array();
|
$results = array();
|
||||||
$results['songs'] = $songs;
|
$results['songs'] = $songs;
|
||||||
|
@ -730,7 +741,7 @@ abstract class Catalog extends database_object
|
||||||
$results['artists'] = $artists;
|
$results['artists'] = $artists;
|
||||||
$results['playlists'] = $playlists;
|
$results['playlists'] = $playlists;
|
||||||
$results['smartplaylists'] = $smartplaylists;
|
$results['smartplaylists'] = $smartplaylists;
|
||||||
$results['live_streams'] = $live_streams;
|
$results['podcasts'] = $podcasts;
|
||||||
$results['size'] = $size;
|
$results['size'] = $size;
|
||||||
$results['time'] = $time;
|
$results['time'] = $time;
|
||||||
|
|
||||||
|
@ -1074,6 +1085,94 @@ abstract class Catalog extends database_object
|
||||||
|
|
||||||
return $results;
|
return $results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_podcast_ids
|
||||||
|
*
|
||||||
|
* This returns an array of ids of podcasts in this catalog
|
||||||
|
* @return int[]
|
||||||
|
*/
|
||||||
|
public function get_podcast_ids()
|
||||||
|
{
|
||||||
|
$results = array();
|
||||||
|
|
||||||
|
$sql = 'SELECT `podcast`.`id` FROM `podcast` ';
|
||||||
|
$sql .= 'WHERE `podcast`.`catalog` = ?';
|
||||||
|
$db_results = Dba::read($sql, array($this->id));
|
||||||
|
while ($r = Dba::fetch_assoc($db_results)) {
|
||||||
|
$results[] = $r['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param int[]|null $catalogs
|
||||||
|
* @return \Podcast[]
|
||||||
|
*/
|
||||||
|
public static function get_podcasts($catalogs = null)
|
||||||
|
{
|
||||||
|
if (!$catalogs) {
|
||||||
|
$catalogs = self::get_catalogs();
|
||||||
|
}
|
||||||
|
|
||||||
|
$results = array();
|
||||||
|
foreach ($catalogs as $catalog_id) {
|
||||||
|
$catalog = Catalog::create_from_id($catalog_id);
|
||||||
|
$podcast_ids = $catalog->get_podcast_ids();
|
||||||
|
foreach ($podcast_ids as $podcast_id) {
|
||||||
|
$results[] = new Podcast($podcast_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_newest_podcasts_ids
|
||||||
|
*
|
||||||
|
* This returns an array of ids of latest podcast episodes in this catalog
|
||||||
|
* @return int[]
|
||||||
|
*/
|
||||||
|
public function get_newest_podcasts_ids()
|
||||||
|
{
|
||||||
|
$results = array();
|
||||||
|
|
||||||
|
$sql = 'SELECT `podcast_episode`.`id` FROM `podcast_episode` ' .
|
||||||
|
'INNER JOIN `podcast` ON `podcast`.`id` = `podcast_episode`.`podcast` ' .
|
||||||
|
'WHERE `podcast`.`catalog` = ? ' .
|
||||||
|
'ORDER BY `podcast_episode`.`pubdate` DESC';
|
||||||
|
$db_results = Dba::read($sql, array($this->id));
|
||||||
|
while ($r = Dba::fetch_assoc($db_results)) {
|
||||||
|
$results[] = $r['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param int[]|null $catalogs
|
||||||
|
* @return \Podcast_Episode[]
|
||||||
|
*/
|
||||||
|
public static function get_newest_podcasts($catalogs = null)
|
||||||
|
{
|
||||||
|
if (!$catalogs) {
|
||||||
|
$catalogs = self::get_catalogs();
|
||||||
|
}
|
||||||
|
|
||||||
|
$results = array();
|
||||||
|
foreach ($catalogs as $catalog_id) {
|
||||||
|
$catalog = Catalog::create_from_id($catalog_id);
|
||||||
|
$episode_ids = $catalog->get_newest_podcasts_ids();
|
||||||
|
foreach ($episode_ids as $episode_id) {
|
||||||
|
$results[] = new Podcast_Episode($episode_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
479
lib/class/podcast.class.php
Normal file
479
lib/class/podcast.class.php
Normal file
|
@ -0,0 +1,479 @@
|
||||||
|
<?php
|
||||||
|
/* vim:set softtabstop=4 shiftwidth=4 expandtab: */
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* LICENSE: GNU Affero General Public License, version 3 (AGPLv3)
|
||||||
|
* Copyright 2001 - 2015 Ampache.org
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Podcast extends database_object implements library_item
|
||||||
|
{
|
||||||
|
/* Variables from DB */
|
||||||
|
public $id;
|
||||||
|
public $catalog;
|
||||||
|
public $feed;
|
||||||
|
public $title;
|
||||||
|
public $website;
|
||||||
|
public $description;
|
||||||
|
public $language;
|
||||||
|
public $copyright;
|
||||||
|
public $generator;
|
||||||
|
public $lastbuilddate;
|
||||||
|
public $lastsync;
|
||||||
|
|
||||||
|
public $episodes;
|
||||||
|
public $f_title;
|
||||||
|
public $f_description;
|
||||||
|
public $f_language;
|
||||||
|
public $f_copyright;
|
||||||
|
public $f_generator;
|
||||||
|
public $f_lastbuilddate;
|
||||||
|
public $f_lastsync;
|
||||||
|
public $link;
|
||||||
|
public $f_link;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Podcast
|
||||||
|
* Takes the ID of the podcast and pulls the info from the db
|
||||||
|
*/
|
||||||
|
public function __construct($id='')
|
||||||
|
{
|
||||||
|
/* If they failed to pass in an id, just run for it */
|
||||||
|
if (!$id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the information from the db */
|
||||||
|
$info = $this->get_info($id);
|
||||||
|
|
||||||
|
foreach ($info as $key=>$value) {
|
||||||
|
$this->$key = $value;
|
||||||
|
} // foreach info
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} //constructor
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gc
|
||||||
|
*
|
||||||
|
* This cleans out unused podcasts
|
||||||
|
*/
|
||||||
|
public static function gc()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_catalogs
|
||||||
|
*
|
||||||
|
* Get all catalog ids related to this item.
|
||||||
|
* @return int[]
|
||||||
|
*/
|
||||||
|
public function get_catalogs()
|
||||||
|
{
|
||||||
|
return array($this->catalog);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_episodes
|
||||||
|
* gets all episodes for this tv show
|
||||||
|
*/
|
||||||
|
public function get_episodes($state_filter = '')
|
||||||
|
{
|
||||||
|
$params = array();
|
||||||
|
$sql = "SELECT `podcast_episode`.`id` FROM `podcast_episode` ";
|
||||||
|
if (AmpConfig::get('catalog_disable')) {
|
||||||
|
$sql .= "LEFT JOIN `podcast` ON `podcast`.`id` = `podcast_episode`.`podcast` ";
|
||||||
|
$sql .= "LEFT JOIN `catalog` ON `catalog`.`id` = `podcast`.`catalog` ";
|
||||||
|
}
|
||||||
|
$sql .= "WHERE `podcast_episode`.`podcast`='" . Dba::escape($this->id) . "' ";
|
||||||
|
if (!empty($state_filter)) {
|
||||||
|
$sql .= "AND `podcast_episode`.`state` = ? ";
|
||||||
|
$params[] = $state_filter;
|
||||||
|
}
|
||||||
|
if (AmpConfig::get('catalog_disable')) {
|
||||||
|
$sql .= "AND `catalog`.`enabled` = '1' ";
|
||||||
|
}
|
||||||
|
$sql .= "ORDER BY `podcast_episode`.`pubdate` DESC";
|
||||||
|
$db_results = Dba::read($sql, $params);
|
||||||
|
|
||||||
|
$results = array();
|
||||||
|
while ($r = Dba::fetch_assoc($db_results)) {
|
||||||
|
$results[] = $r['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
} // get_episodes
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _get_extra info
|
||||||
|
* This returns the extra information for the podcast, this means totals etc
|
||||||
|
*/
|
||||||
|
private function _get_extra_info()
|
||||||
|
{
|
||||||
|
// Try to find it in the cache and save ourselves the trouble
|
||||||
|
if (parent::is_cached('podcast_extra', $this->id) ) {
|
||||||
|
$row = parent::get_from_cache('podcast_extra', $this->id);
|
||||||
|
} else {
|
||||||
|
$sql = "SELECT COUNT(`podcast_episode`.`id`) AS `episode_count` FROM `podcast_episode` " .
|
||||||
|
"WHERE `podcast_episode`.`podcast` = ?";
|
||||||
|
$db_results = Dba::read($sql, array($this->id));
|
||||||
|
$row = Dba::fetch_assoc($db_results);
|
||||||
|
|
||||||
|
parent::add_to_cache('podcast_extra',$this->id,$row);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set Object Vars */
|
||||||
|
$this->episodes = $row['episode_count'];
|
||||||
|
|
||||||
|
return $row;
|
||||||
|
} // _get_extra_info
|
||||||
|
|
||||||
|
/**
|
||||||
|
* format
|
||||||
|
* this function takes the object and reformats some values
|
||||||
|
*/
|
||||||
|
public function format($details = true)
|
||||||
|
{
|
||||||
|
$this->f_title = scrub_out($this->title);
|
||||||
|
$this->f_description = scrub_out($this->description);
|
||||||
|
$this->f_language = scrub_out($this->language);
|
||||||
|
$this->f_copyright = scrub_out($this->copyright);
|
||||||
|
$this->f_generator = scrub_out($this->generator);
|
||||||
|
$this->f_website = scrub_out($this->website);
|
||||||
|
$this->f_lastbuilddate = date("m\/d\/Y - H:i", $this->lastbuilddate);
|
||||||
|
$this->f_lastsync = date("m\/d\/Y - H:i", $this->lastsync);
|
||||||
|
$this->link = AmpConfig::get('web_path') . '/podcast.php?action=show&podcast=' . $this->id;
|
||||||
|
$this->f_link = '<a href="' . $this->link . '" title="' . $this->f_title . '">' . $this->f_title . '</a>';
|
||||||
|
|
||||||
|
if ($details) {
|
||||||
|
$this->_get_extra_info();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_keywords()
|
||||||
|
{
|
||||||
|
$keywords = array();
|
||||||
|
$keywords['podcast'] = array('important' => true,
|
||||||
|
'label' => T_('Podcast'),
|
||||||
|
'value' => $this->f_title);
|
||||||
|
|
||||||
|
return $keywords;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_fullname()
|
||||||
|
{
|
||||||
|
return $this->f_title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_parent()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_childrens()
|
||||||
|
{
|
||||||
|
return array('podcast_episode' => $this->get_episodes());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function search_childrens($name)
|
||||||
|
{
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_medias($filter_type = null)
|
||||||
|
{
|
||||||
|
$medias = array();
|
||||||
|
if (!$filter_type || $filter_type == 'podcast_episode') {
|
||||||
|
$episodes = $this->get_episodes('completed');
|
||||||
|
foreach ($episodes as $episode_id) {
|
||||||
|
$medias[] = array(
|
||||||
|
'object_type' => 'podcast_episode',
|
||||||
|
'object_id' => $episode_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $medias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_user_owner()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_default_art_kind()
|
||||||
|
{
|
||||||
|
return 'default';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_description()
|
||||||
|
{
|
||||||
|
return $this->f_description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function display_art($thumb = 2)
|
||||||
|
{
|
||||||
|
if (Art::has_db($this->id, 'podcast')) {
|
||||||
|
Art::display('podcast', $this->id, $this->get_fullname(), $thumb, $this->link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update
|
||||||
|
* This takes a key'd array of data and updates the current podcast
|
||||||
|
*/
|
||||||
|
public function update(array $data)
|
||||||
|
{
|
||||||
|
$feed = isset($data['feed']) ? $data['feed'] : $this->feed;
|
||||||
|
$title = isset($data['title']) ? scrub_in($data['title']) : $this->title;
|
||||||
|
$website = isset($data['website']) ? scrub_in($data['website']) : $this->website;
|
||||||
|
$description = isset($data['description']) ? scrub_in($data['description']) : $this->description;
|
||||||
|
$generator = isset($data['generator']) ? scrub_in($data['generator']) : $this->generator;
|
||||||
|
$copyright = isset($data['copyright']) ? scrub_in($data['copyright']) : $this->copyright;
|
||||||
|
|
||||||
|
if (strpos($feed, "http://") !== 0 && strpos($feed, "https://") !== 0) {
|
||||||
|
debug_event('podcast', 'Podcast update canceled, bad feed url.', 1);
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = 'UPDATE `podcast` SET `feed` = ?, `title` = ?, `website` = ?, `description` = ?, `generator` = ?, `copyright` = ? WHERE `id` = ?';
|
||||||
|
Dba::write($sql, array($feed, $title, $website, $description, $generator, $copyright, $this->id));
|
||||||
|
|
||||||
|
$this->feed = $feed;
|
||||||
|
$this->title = $title;
|
||||||
|
$this->website = $website;
|
||||||
|
$this->description = $description;
|
||||||
|
$this->generator = $generator;
|
||||||
|
$this->copyright = $copyright;
|
||||||
|
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function create(array $data)
|
||||||
|
{
|
||||||
|
$feed = $data['feed'];
|
||||||
|
// Feed must be http/https
|
||||||
|
if (strpos($data['feed'], "http://") !== 0 && strpos($data['feed'], "https://") !== 0) {
|
||||||
|
AmpError::add('feed', T_('Wrong feed url'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$catalog_id = intval($data['catalog']);
|
||||||
|
if ($catalog_id <= 0) {
|
||||||
|
AmpError::add('catalog', T_('Target catalog required'));
|
||||||
|
} else {
|
||||||
|
$catalog = Catalog::create_from_id($catalog_id);
|
||||||
|
if ($catalog->gather_types !== "podcast") {
|
||||||
|
AmpError::add('catalog', T_('Wrong target catalog type'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AmpError::occurred()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$title = T_('Unknown');
|
||||||
|
$website = null;
|
||||||
|
$description = null;
|
||||||
|
$language = null;
|
||||||
|
$copyright = null;
|
||||||
|
$generator = null;
|
||||||
|
$lastbuilddate = 0;
|
||||||
|
$episodes = array();
|
||||||
|
$arturl = '';
|
||||||
|
|
||||||
|
$xmlstr = file_get_contents($feed);
|
||||||
|
if ($xmlstr === false) {
|
||||||
|
AmpError::add('feed', T_('Cannot access the feed.'));
|
||||||
|
} else {
|
||||||
|
$xml = simplexml_load_string($xmlstr);
|
||||||
|
if ($xml === false) {
|
||||||
|
AmpError::add('feed', T_('Cannot read the feed.'));
|
||||||
|
} else {
|
||||||
|
$title = html_entity_decode($xml->channel->title);
|
||||||
|
$website = $xml->channel->link;
|
||||||
|
$description = html_entity_decode($xml->channel->description);
|
||||||
|
$language = $xml->channel->language;
|
||||||
|
$copyright = html_entity_decode($xml->channel->copyright);
|
||||||
|
$generator = html_entity_decode($xml->channel->generator);
|
||||||
|
$lastbuilddatestr = $xml->channel->lastBuildDate;
|
||||||
|
if ($lastbuilddatestr) {
|
||||||
|
$lastbuilddate = strtotime($lastbuilddatestr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($xml->channel->image) {
|
||||||
|
$arturl = $xml->channel->image->url;
|
||||||
|
}
|
||||||
|
|
||||||
|
$episodes = $xml->channel->item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AmpError::occurred()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "INSERT INTO `podcast` (`feed`, `catalog`, `title`, `website`, `description`, `language`, `copyright`, `generator`, `lastbuilddate`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||||
|
$db_results = Dba::write($sql, array($feed, $catalog_id, $title, $website, $description, $language, $copyright, $generator, $lastbuilddate));
|
||||||
|
if ($db_results) {
|
||||||
|
$id = Dba::insert_id();
|
||||||
|
$podcast = new Podcast($id);
|
||||||
|
$dirpath = $podcast->get_root_path();
|
||||||
|
if (!is_dir($dirpath)) {
|
||||||
|
if (mkdir($dirpath) === false) {
|
||||||
|
debug_event('podcast', 'Cannot create directory ' . $dirpath, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!empty($arturl)) {
|
||||||
|
$art = new Art($id, 'podcast');
|
||||||
|
$art->insert_url($arturl);
|
||||||
|
}
|
||||||
|
if (count($episodes) > 0) {
|
||||||
|
$podcast->add_episodes($episodes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $db_results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function add_episodes($episodes, $afterdate=0, $gather=false)
|
||||||
|
{
|
||||||
|
foreach ($episodes as $episode) {
|
||||||
|
$this->add_episode($episode, $afterdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select episodes to download
|
||||||
|
$dlnb = AmpConfig::get('podcast_new_download');
|
||||||
|
if ($dlnb != 0) {
|
||||||
|
$sql = "SELECT `podcast_episode`.`id` FROM `podcast_episode` INNER JOIN `podcast` ON `podcast`.`id` = `podcast_episode`.`podcast` " .
|
||||||
|
"WHERE `podcast`.`id` = ? AND `podcast_episode`.`addition_time` > `podcast`.`lastsync` " .
|
||||||
|
"ORDER BY `podcast_episode`.`pubdate` DESC";
|
||||||
|
if ($dlnb != -1) {
|
||||||
|
$sql .= " LIMIT " . $dlnb;
|
||||||
|
}
|
||||||
|
$db_results = Dba::read($sql, array($this->id));
|
||||||
|
while ($row = Dba::fetch_row($db_results)) {
|
||||||
|
$episode = new Podcast_Episode($row[0]);
|
||||||
|
$episode->change_state('pending');
|
||||||
|
if ($gather) {
|
||||||
|
$episode->gather();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Remove items outside limit
|
||||||
|
$keepnb = AmpConfig::get('podcast_keep');
|
||||||
|
if ($keepnb > 0) {
|
||||||
|
$sql = "SELECT `podcast_episode`.`id` FROM `podcast_episode` WHERE `podcast_episode`.`podcast` = ? " .
|
||||||
|
"ORDER BY `podcast_episode`.`pubdate` DESC LIMIT " . $keepnb . ",18446744073709551615";
|
||||||
|
$db_results = Dba::read($sql, array($this->id));
|
||||||
|
while ($row = Dba::fetch_row($db_results)) {
|
||||||
|
$episode = new Podcast_Episode($row[0]);
|
||||||
|
$episode->remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->update_lastsync(time());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function add_episode(SimpleXMLElement $episode, $afterdate=0)
|
||||||
|
{
|
||||||
|
debug_event('podcast', 'Adding new episode to podcast ' . $this->id . '...', 5);
|
||||||
|
|
||||||
|
$title = html_entity_decode($episode->title);
|
||||||
|
$website = $episode->link;
|
||||||
|
$guid = $episode->guid;
|
||||||
|
$description = html_entity_decode($episode->description);
|
||||||
|
$author = html_entity_decode($episode->author);
|
||||||
|
$category = html_entity_decode($episode->category);
|
||||||
|
$source = null;
|
||||||
|
$time = 0;
|
||||||
|
if ($episode->enclosure) {
|
||||||
|
$source = $episode->enclosure['url'];
|
||||||
|
}
|
||||||
|
$itunes = $episode->children('itunes', true);
|
||||||
|
if ($itunes) {
|
||||||
|
$ptime = date_parse($itunes->duration);
|
||||||
|
$time = $ptime['hour'] * 3600 + $ptime['minute'] * 60 + $ptime['second'];
|
||||||
|
}
|
||||||
|
$pubdate = 0;
|
||||||
|
$pubdatestr = $episode->pubDate;
|
||||||
|
if ($pubdatestr) {
|
||||||
|
$pubdate = strtotime($pubdatestr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($pubdate <= 0) {
|
||||||
|
debug_log('podcast', 'Invalid episode publication date, skipped', 3);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($pubdate > $afterdate) {
|
||||||
|
$sql = "INSERT INTO `podcast_episode` (`title`, `guid`, `podcast`, `state`, `source`, `website`, `description`, `author`, `category`, `time`, `pubdate`, `addition_time`) " .
|
||||||
|
"VALUES (?, ?, ?, 'skipped', ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||||
|
return Dba::write($sql, array($title, $guid, $this->id, $source, $website, $description, $author, $category, $time, $pubdate, time()));
|
||||||
|
} else {
|
||||||
|
debug_log('podcast', 'Episode published before ' . $afterdate . ', skipped', 5);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function update_lastsync($time)
|
||||||
|
{
|
||||||
|
$sql = "UPDATE `podcast` SET `lastsync` = ? WHERE `id` = ?";
|
||||||
|
return Dba::write($sql, array($time, $this->id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sync_episodes($gather=false)
|
||||||
|
{
|
||||||
|
$xmlstr = file_get_contents($this->feed);
|
||||||
|
if ($xmlstr === false) {
|
||||||
|
debug_event('podcast', 'Cannot access feed ' . $this->feed, 1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$xml = simplexml_load_string($xmlstr);
|
||||||
|
if ($xml === false) {
|
||||||
|
debug_event('podcast', 'Cannot read feed ' . $this->feed, 1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->add_episodes($xml->item, $this->lastsync, $gather);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function remove()
|
||||||
|
{
|
||||||
|
$episodes = $this->get_episodes();
|
||||||
|
foreach ($episodes as $episode_id) {
|
||||||
|
$episode = new Podcast_Episode($episode_id);
|
||||||
|
$episode->remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "DELETE FROM `podcast` WHERE `id` = ?";
|
||||||
|
return Dba::write($sql, array($this->id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_root_path()
|
||||||
|
{
|
||||||
|
$catalog = Catalog::create_from_id($this->catalog);
|
||||||
|
if (!$catalog->get_type() == 'local') {
|
||||||
|
debug_event('podcast', 'Bad catalog type.', 1);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$dirname = $this->title;
|
||||||
|
return $catalog->path . DIRECTORY_SEPARATOR . $dirname;
|
||||||
|
}
|
||||||
|
}
|
415
lib/class/podcast_episode.class.php
Normal file
415
lib/class/podcast_episode.class.php
Normal file
|
@ -0,0 +1,415 @@
|
||||||
|
<?php
|
||||||
|
/* vim:set softtabstop=4 shiftwidth=4 expandtab: */
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* LICENSE: GNU Affero General Public License, version 3 (AGPLv3)
|
||||||
|
* Copyright 2001 - 2015 Ampache.org
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Podcast_Episode extends database_object implements media, library_item
|
||||||
|
{
|
||||||
|
public $id;
|
||||||
|
public $title;
|
||||||
|
public $guid;
|
||||||
|
public $podcast;
|
||||||
|
public $state;
|
||||||
|
public $file;
|
||||||
|
public $source;
|
||||||
|
public $size;
|
||||||
|
public $time;
|
||||||
|
public $website;
|
||||||
|
public $description;
|
||||||
|
public $author;
|
||||||
|
public $category;
|
||||||
|
public $pubdate;
|
||||||
|
|
||||||
|
public $catalog;
|
||||||
|
public $f_title;
|
||||||
|
public $f_file;
|
||||||
|
public $f_size;
|
||||||
|
public $f_time;
|
||||||
|
public $f_time_h;
|
||||||
|
public $f_description;
|
||||||
|
public $f_author;
|
||||||
|
public $f_category;
|
||||||
|
public $f_website;
|
||||||
|
public $f_pubdate;
|
||||||
|
public $f_state;
|
||||||
|
public $link;
|
||||||
|
public $f_link;
|
||||||
|
public $f_podcast;
|
||||||
|
public $f_podcast_link;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* Podcast Episode class
|
||||||
|
* @param int|null $id
|
||||||
|
*/
|
||||||
|
public function __construct($id = null)
|
||||||
|
{
|
||||||
|
if (!$id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->id = intval($id);
|
||||||
|
|
||||||
|
if ($info = $this->get_info($this->id)) {
|
||||||
|
foreach ($info as $key => $value) {
|
||||||
|
$this->$key = $value;
|
||||||
|
}
|
||||||
|
if (!empty($this->file)) {
|
||||||
|
$data = pathinfo($this->file);
|
||||||
|
$this->type = strtolower($data['extension']);
|
||||||
|
$this->mime = Song::type_to_mime($this->type);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->id = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} // constructor
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gc
|
||||||
|
*
|
||||||
|
* Cleans up the podcast_episode table
|
||||||
|
*/
|
||||||
|
public static function gc()
|
||||||
|
{
|
||||||
|
Dba::write('DELETE FROM `podcast_episode` USING `podcast_episode` LEFT JOIN `podcast` ON `podcast`.`id` = `podcast_episode`.`podcast` WHERE `podcast`.`id` IS NULL');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_catalogs
|
||||||
|
*
|
||||||
|
* Get all catalog ids related to this item.
|
||||||
|
* @return int[]
|
||||||
|
*/
|
||||||
|
public function get_catalogs()
|
||||||
|
{
|
||||||
|
return array($this->catalog);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* format
|
||||||
|
* this function takes the object and reformats some values
|
||||||
|
*/
|
||||||
|
public function format($details = true)
|
||||||
|
{
|
||||||
|
$this->f_title = scrub_out($this->title);
|
||||||
|
$this->f_description = scrub_out($this->description);
|
||||||
|
$this->f_category = scrub_out($this->category);
|
||||||
|
$this->f_author = scrub_out($this->author);
|
||||||
|
$this->f_website = scrub_out($this->website);
|
||||||
|
$this->f_pubdate = date("m\/d\/Y - H:i", $this->pubdate);
|
||||||
|
$this->f_state = ucfirst($this->state);
|
||||||
|
|
||||||
|
// Format the Time
|
||||||
|
$min = floor($this->time/60);
|
||||||
|
$sec = sprintf("%02d", ($this->time%60));
|
||||||
|
$this->f_time = $min . ":" . $sec;
|
||||||
|
$hour = sprintf("%02d", floor($min/60));
|
||||||
|
$min_h = sprintf("%02d", ($min%60));
|
||||||
|
$this->f_time_h = $hour . ":" . $min_h . ":" . $sec;
|
||||||
|
// Format the Size
|
||||||
|
$this->f_size = UI::format_bytes($this->size);
|
||||||
|
$this->f_file = $this->f_title . '.' . $this->type;
|
||||||
|
|
||||||
|
$this->link = AmpConfig::get('web_path') . '/podcast_episode.php?action=show&podcast_episode=' . $this->id;
|
||||||
|
$this->f_link = '<a href="' . $this->link . '" title="' . $this->f_title . '">' . $this->f_title . '</a>';
|
||||||
|
|
||||||
|
if ($details) {
|
||||||
|
$podcast = new Podcast($this->podcast);
|
||||||
|
$podcast->format();
|
||||||
|
$this->catalog = $podcast->catalog;
|
||||||
|
$this->f_podcast = $podcast->f_title;
|
||||||
|
$this->f_podcast_link = $podcast->f_link;
|
||||||
|
$this->f_file = $this->f_podcast . ' - ' . $this->f_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_keywords()
|
||||||
|
{
|
||||||
|
$keywords = array();
|
||||||
|
$keywords['podcast'] = array('important' => true,
|
||||||
|
'label' => T_('Podcast'),
|
||||||
|
'value' => $this->f_podcast);
|
||||||
|
$keywords['title'] = array('important' => true,
|
||||||
|
'label' => T_('Title'),
|
||||||
|
'value' => $this->f_title);
|
||||||
|
|
||||||
|
return $keywords;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_fullname()
|
||||||
|
{
|
||||||
|
return $this->f_title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_parent()
|
||||||
|
{
|
||||||
|
return array('object_type' => 'podcast', 'object_id' => $this->podcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_childrens()
|
||||||
|
{
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function search_childrens($name)
|
||||||
|
{
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_medias($filter_type = null)
|
||||||
|
{
|
||||||
|
$medias = array();
|
||||||
|
if (!$filter_type || $filter_type == 'podcast_episode') {
|
||||||
|
$medias[] = array(
|
||||||
|
'object_type' => 'podcast_episode',
|
||||||
|
'object_id' => $this->id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return $medias;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_user_owner()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_default_art_kind()
|
||||||
|
{
|
||||||
|
return 'default';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get_description()
|
||||||
|
{
|
||||||
|
return $this->f_description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function display_art($thumb = 2)
|
||||||
|
{
|
||||||
|
$id = null;
|
||||||
|
$type = null;
|
||||||
|
|
||||||
|
if (Art::has_db($this->id, 'podcast_episode')) {
|
||||||
|
$id = $this->id;
|
||||||
|
$type = 'podcast_episode';
|
||||||
|
} else {
|
||||||
|
if (Art::has_db($this->podcast, 'podcast')) {
|
||||||
|
$id = $this->podcast;
|
||||||
|
$type = 'podcast';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($id !== null && $type !== null) {
|
||||||
|
Art::display($type, $id, $this->get_fullname(), $thumb, $this->link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update
|
||||||
|
* This takes a key'd array of data and updates the current podcast episode
|
||||||
|
*/
|
||||||
|
public function update(array $data)
|
||||||
|
{
|
||||||
|
$title = isset($data['title']) ? $data['title'] : $this->title;
|
||||||
|
$website = isset($data['website']) ? $data['website'] : $this->website;
|
||||||
|
$description = isset($data['description']) ? $data['description'] : $this->description;
|
||||||
|
$author = isset($data['author']) ? $data['author'] : $this->author;
|
||||||
|
$category = isset($data['category']) ? $data['category'] : $this->category;
|
||||||
|
|
||||||
|
$sql = 'UPDATE `podcast_episode` SET `title` = ?, `website` = ?, `description` = ?, `author` = ?, `category` = ? WHERE `id` = ?';
|
||||||
|
Dba::write($sql, array($title, $website, $description, $author, $category, $this->id));
|
||||||
|
|
||||||
|
$this->title = $title;
|
||||||
|
$this->website = $website;
|
||||||
|
$this->description = $description;
|
||||||
|
$this->author = $author;
|
||||||
|
$this->category = $category;
|
||||||
|
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set_played
|
||||||
|
* this checks to see if the current object has been played
|
||||||
|
* if not then it sets it to played. In any case it updates stats.
|
||||||
|
* @param int $user
|
||||||
|
* @param string $agent
|
||||||
|
* @param array $location
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function set_played($user, $agent, $location)
|
||||||
|
{
|
||||||
|
Stats::insert('podcast', $this->podcast, $user, $agent, $location);
|
||||||
|
Stats::insert('podcast_episode', $this->id, $user, $agent, $location);
|
||||||
|
|
||||||
|
if ($this->played) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If it hasn't been played, set it! */
|
||||||
|
Podcast_Episode::update_played(true, $this->id);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} // set_played
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update_played
|
||||||
|
* sets the played flag
|
||||||
|
* @param boolean $new_played
|
||||||
|
* @param int $id
|
||||||
|
*/
|
||||||
|
public static function update_played($new_played, $id)
|
||||||
|
{
|
||||||
|
self::_update_item('played', ($new_played ? 1 : 0),$id,'25');
|
||||||
|
} // update_played
|
||||||
|
|
||||||
|
/**
|
||||||
|
* _update_item
|
||||||
|
* This is a private function that should only be called from within the podcast episode class.
|
||||||
|
* It takes a field, value video id and level. first and foremost it checks the level
|
||||||
|
* against $GLOBALS['user'] to make sure they are allowed to update this record
|
||||||
|
* it then updates it and sets $this->{$field} to the new value
|
||||||
|
* @param string $field
|
||||||
|
* @param mixed $value
|
||||||
|
* @param int $song_id
|
||||||
|
* @param int $level
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
private static function _update_item($field, $value, $song_id, $level)
|
||||||
|
{
|
||||||
|
/* Check them Rights! */
|
||||||
|
if (!Access::check('interface',$level)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Can't update to blank */
|
||||||
|
if (!strlen(trim($value))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "UPDATE `podcast_episode` SET `$field` = ? WHERE `id` = ?";
|
||||||
|
Dba::write($sql, array($value, $song_id));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} // _update_item
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get stream name.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function get_stream_name()
|
||||||
|
{
|
||||||
|
return $this->f_podcast . " - " . $this->f_title;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get transcode settings.
|
||||||
|
* @param string $target
|
||||||
|
* @param array $options
|
||||||
|
* @return array|boolean
|
||||||
|
*/
|
||||||
|
public function get_transcode_settings($target = null, $player = null, $options=array())
|
||||||
|
{
|
||||||
|
return Song::get_transcode_settings_for_media($this->type, $target, $player, 'song', $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* play_url
|
||||||
|
* This function takes all the song information and correctly formats a
|
||||||
|
* a stream URL taking into account the downsmapling mojo and everything
|
||||||
|
* else, this is the true function
|
||||||
|
* @param int $oid
|
||||||
|
* @param string $additional_params
|
||||||
|
* @param boolean $local
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function play_url($oid, $additional_params='', $player=null, $local=false)
|
||||||
|
{
|
||||||
|
return Song::generic_play_url('podcast_episode', $oid, $additional_params, $player, $local);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get stream types.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function get_stream_types($player = null)
|
||||||
|
{
|
||||||
|
return Song::get_stream_types_for_type($this->type, $player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function remove()
|
||||||
|
{
|
||||||
|
debug_event('podcast_episode', 'Removing podcast episode ' . $this->id, 5);
|
||||||
|
|
||||||
|
if (AmpConfig::get('delete_from_disk') && !empty($this->file)) {
|
||||||
|
if (!unlink($this->file)) {
|
||||||
|
debug_event('podcast_episode', 'Cannot delete file ' . $this->file, 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "DELETE FROM `podcast_episode` WHERE `id` = ?";
|
||||||
|
return Dba::write($sql, array($this->id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function change_state($state)
|
||||||
|
{
|
||||||
|
$sql = "UPDATE `podcast_episode` SET `state` = ? WHERE `id` = ?";
|
||||||
|
return Dba::write($sql, array($state, $this->id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function gather()
|
||||||
|
{
|
||||||
|
if (!empty($this->source)) {
|
||||||
|
$podcast = new Podcast($this->podcast);
|
||||||
|
$file = $podcast->get_root_path();
|
||||||
|
if (!empty($file)) {
|
||||||
|
$pinfo = pathinfo($this->source);
|
||||||
|
$file .= DIRECTORY_SEPARATOR . $this->id . '-' . $pinfo['basename'];
|
||||||
|
debug_event('podcast_episode', 'Downloading ' . $this->source . ' to ' . $file . ' ...', 5);
|
||||||
|
if (file_put_contents($file, fopen($this->source, 'r')) !== false) {
|
||||||
|
debug_event('podcast_episode', 'Download completed.', 5);
|
||||||
|
$this->file = $file;
|
||||||
|
|
||||||
|
$vainfo = new vainfo($this->file);
|
||||||
|
$vainfo->get_info();
|
||||||
|
$key = vainfo::get_tag_type($vainfo->tags);
|
||||||
|
$infos = vainfo::clean_tag_info($vainfo->tags, $key, $file);
|
||||||
|
// No time information, get it from file
|
||||||
|
if ($this->time <= 0) {
|
||||||
|
$this->time = $infos['time'];
|
||||||
|
}
|
||||||
|
$this->size = $infos['size'];
|
||||||
|
|
||||||
|
$sql = "UPDATE `podcast_episode` SET `file` = ?, `size` = ?, `time` = ?, `state` = 'completed' WHERE `id` = ?";
|
||||||
|
Dba::write($sql, array($this->file, $this->size, $this->time, $this->id));
|
||||||
|
} else {
|
||||||
|
debug_event('podcast_episode', 'Error when downloading podcast episode.', 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
debug_event('podcast_episode', 'Cannot download podcast episode ' . $this->id . ', empty source.', 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -230,6 +230,18 @@ class Query
|
||||||
'follower' => array(
|
'follower' => array(
|
||||||
'user',
|
'user',
|
||||||
'to_user',
|
'to_user',
|
||||||
|
),
|
||||||
|
'podcast' => array(
|
||||||
|
'alpha_match',
|
||||||
|
'regex_match',
|
||||||
|
'regex_not_match',
|
||||||
|
'starts_with'
|
||||||
|
),
|
||||||
|
'podcast_episode' => array(
|
||||||
|
'alpha_match',
|
||||||
|
'regex_match',
|
||||||
|
'regex_not_match',
|
||||||
|
'starts_with'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -392,6 +404,16 @@ class Query
|
||||||
'user',
|
'user',
|
||||||
'follow_user',
|
'follow_user',
|
||||||
'follow_date'
|
'follow_date'
|
||||||
|
),
|
||||||
|
'podcast' => array(
|
||||||
|
'title'
|
||||||
|
),
|
||||||
|
'podcast_episode' => array(
|
||||||
|
'title',
|
||||||
|
'category',
|
||||||
|
'author',
|
||||||
|
'time',
|
||||||
|
'pubDate'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -715,6 +737,8 @@ class Query
|
||||||
case 'label':
|
case 'label':
|
||||||
case 'pvmsg':
|
case 'pvmsg':
|
||||||
case 'follower':
|
case 'follower':
|
||||||
|
case 'podcast':
|
||||||
|
case 'podcast_episode':
|
||||||
// Set it
|
// Set it
|
||||||
$this->_state['type'] = $type;
|
$this->_state['type'] = $type;
|
||||||
$this->set_base_sql(true, $custom_base);
|
$this->set_base_sql(true, $custom_base);
|
||||||
|
@ -1061,6 +1085,14 @@ class Query
|
||||||
$this->set_select("`user_follower`.`id`");
|
$this->set_select("`user_follower`.`id`");
|
||||||
$sql = "SELECT %%SELECT%% FROM `user_follower` ";
|
$sql = "SELECT %%SELECT%% FROM `user_follower` ";
|
||||||
break;
|
break;
|
||||||
|
case 'podcast':
|
||||||
|
$this->set_select("`podcast`.`id`");
|
||||||
|
$sql = "SELECT %%SELECT%% FROM `podcast` ";
|
||||||
|
break;
|
||||||
|
case 'podcast_episode':
|
||||||
|
$this->set_select("`podcast_episode`.`id`");
|
||||||
|
$sql = "SELECT %%SELECT%% FROM `podcast_episode` ";
|
||||||
|
break;
|
||||||
case 'playlist_song':
|
case 'playlist_song':
|
||||||
case 'song':
|
case 'song':
|
||||||
default:
|
default:
|
||||||
|
@ -1775,6 +1807,52 @@ class Query
|
||||||
break;
|
break;
|
||||||
} // end filter
|
} // end filter
|
||||||
break;
|
break;
|
||||||
|
case 'podcast':
|
||||||
|
switch ($filter) {
|
||||||
|
case 'alpha_match':
|
||||||
|
$filter_sql = " `podcast`.`title` LIKE '%" . Dba::escape($value) . "%' AND ";
|
||||||
|
break;
|
||||||
|
case 'regex_match':
|
||||||
|
if (!empty($value)) {
|
||||||
|
$filter_sql = " `podcast`.`title` REGEXP '" . Dba::escape($value) . "' AND ";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'regex_not_match':
|
||||||
|
if (!empty($value)) {
|
||||||
|
$filter_sql = " `podcast`.`title` NOT REGEXP '" . Dba::escape($value) . "' AND ";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'starts_with':
|
||||||
|
$filter_sql = " `podcast`.`title` LIKE '" . Dba::escape($value) . "%' AND ";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Rien a faire
|
||||||
|
break;
|
||||||
|
} // end filter
|
||||||
|
break;
|
||||||
|
case 'podcast_episode':
|
||||||
|
switch ($filter) {
|
||||||
|
case 'alpha_match':
|
||||||
|
$filter_sql = " `podcast_episode`.`title` LIKE '%" . Dba::escape($value) . "%' AND ";
|
||||||
|
break;
|
||||||
|
case 'regex_match':
|
||||||
|
if (!empty($value)) {
|
||||||
|
$filter_sql = " `podcast_episode`.`title` REGEXP '" . Dba::escape($value) . "' AND ";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'regex_not_match':
|
||||||
|
if (!empty($value)) {
|
||||||
|
$filter_sql = " `podcast_episode`.`title` NOT REGEXP '" . Dba::escape($value) . "' AND ";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'starts_with':
|
||||||
|
$filter_sql = " `podcast_episode`.`title` LIKE '" . Dba::escape($value) . "%' AND ";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Rien a faire
|
||||||
|
break;
|
||||||
|
} // end filter
|
||||||
|
break;
|
||||||
} // end switch on type
|
} // end switch on type
|
||||||
|
|
||||||
return $filter_sql;
|
return $filter_sql;
|
||||||
|
@ -2147,6 +2225,32 @@ class Query
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'podcast':
|
||||||
|
switch ($field) {
|
||||||
|
case 'title':
|
||||||
|
$sql = "`podcast`.`title`";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'podcast_episode':
|
||||||
|
switch ($field) {
|
||||||
|
case 'title':
|
||||||
|
$sql = "`podcast_episode`.`title`";
|
||||||
|
break;
|
||||||
|
case 'category':
|
||||||
|
$sql = "`podcast_episode`.`category`";
|
||||||
|
break;
|
||||||
|
case 'author':
|
||||||
|
$sql = "`podcast_episode`.`author`";
|
||||||
|
break;
|
||||||
|
case 'time':
|
||||||
|
$sql = "`podcast_episode`.`time`";
|
||||||
|
break;
|
||||||
|
case 'pubDate':
|
||||||
|
$sql = "`podcast_episode`.`pubDate`";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// Rien a faire
|
// Rien a faire
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -52,7 +52,7 @@ class Rating extends database_object
|
||||||
*/
|
*/
|
||||||
public static function gc()
|
public static function gc()
|
||||||
{
|
{
|
||||||
$types = array('song', 'album', 'artist', 'video', 'tvshow', 'tvshow_season', 'playlist', 'label');
|
$types = array('song', 'album', 'artist', 'video', 'tvshow', 'tvshow_season', 'playlist', 'label', 'podcast', 'podcast_episode');
|
||||||
|
|
||||||
if ($object_type != null) {
|
if ($object_type != null) {
|
||||||
if (in_array($object_type, $types)) {
|
if (in_array($object_type, $types)) {
|
||||||
|
|
|
@ -1650,6 +1650,7 @@ class Song extends database_object implements media, library_item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$media->format();
|
||||||
$media_name = $media->get_stream_name() . "." . $type;
|
$media_name = $media->get_stream_name() . "." . $type;
|
||||||
$media_name = str_replace("/", "-", $media_name);
|
$media_name = str_replace("/", "-", $media_name);
|
||||||
$media_name = str_replace("?", "", $media_name);
|
$media_name = str_replace("?", "", $media_name);
|
||||||
|
|
|
@ -204,6 +204,12 @@ class Stream_Playlist
|
||||||
case 'channel':
|
case 'channel':
|
||||||
$url['title'] = $object->name;
|
$url['title'] = $object->name;
|
||||||
break;
|
break;
|
||||||
|
case 'podcast_episode':
|
||||||
|
$url['title'] = $object->f_title;
|
||||||
|
$url['author'] = $object->f_podcast;
|
||||||
|
$url['info_url'] = $object->f_link;
|
||||||
|
$url['image_url'] = Art::url($object->podcast, 'podcast', $api_session, (AmpConfig::get('ajax_load') ? 3 : 4));
|
||||||
|
break;
|
||||||
case 'random':
|
case 'random':
|
||||||
$url['title'] = 'Random URL';
|
$url['title'] = 'Random URL';
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1016,10 +1016,10 @@ class Subsonic_Api
|
||||||
$url = '';
|
$url = '';
|
||||||
if (Subsonic_XML_Data::isVideo($fileid)) {
|
if (Subsonic_XML_Data::isVideo($fileid)) {
|
||||||
$url = Video::play_url(Subsonic_XML_Data::getAmpacheId($fileid), $params, 'api', function_exists('curl_version'));
|
$url = Video::play_url(Subsonic_XML_Data::getAmpacheId($fileid), $params, 'api', function_exists('curl_version'));
|
||||||
} else {
|
} elseif (Subsonic_XML_Data::isSong($fileid)) {
|
||||||
if (Subsonic_XML_Data::isSong($fileid)) {
|
$url = Song::play_url(Subsonic_XML_Data::getAmpacheId($fileid), $params, 'api', function_exists('curl_version'));
|
||||||
$url = Song::play_url(Subsonic_XML_Data::getAmpacheId($fileid), $params, 'api', function_exists('curl_version'));
|
} elseif (Subsonic_XML_Data::isPodcastEp($fileid)) {
|
||||||
}
|
$url = Podcast_Episode::play_url(Subsonic_XML_Data::getAmpacheId($fileid), $params, 'api', function_exists('curl_version'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($url)) {
|
if (!empty($url)) {
|
||||||
|
@ -1098,6 +1098,8 @@ class Subsonic_Api
|
||||||
$song = new Song(Subsonic_XML_Data::getAmpacheId(Subsonic_XML_Data::getAmpacheId($id)));
|
$song = new Song(Subsonic_XML_Data::getAmpacheId(Subsonic_XML_Data::getAmpacheId($id)));
|
||||||
$art = new Art(Subsonic_XML_Data::getAmpacheId($song->album), "album");
|
$art = new Art(Subsonic_XML_Data::getAmpacheId($song->album), "album");
|
||||||
}
|
}
|
||||||
|
} elseif (Subsonic_XML_Data::isPodcast($id)) {
|
||||||
|
$art = new Art(Subsonic_XML_Data::getAmpacheId($id), "podcast");
|
||||||
}
|
}
|
||||||
|
|
||||||
header("Access-Control-Allow-Origin: *");
|
header("Access-Control-Allow-Origin: *");
|
||||||
|
@ -1864,19 +1866,54 @@ class Subsonic_Api
|
||||||
return self::getsimilarsongs($input);
|
return self::getsimilarsongs($input);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**** CURRENT UNSUPPORTED FUNCTIONS ****/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getPodcasts
|
* getPodcasts
|
||||||
* Get all podcast channels.
|
* Get all podcast channels.
|
||||||
* Takes the optional includeEpisodes and channel id in parameters
|
* Takes the optional includeEpisodes and channel id in parameters
|
||||||
* Not supported.
|
|
||||||
*/
|
*/
|
||||||
public static function getpodcasts($input)
|
public static function getpodcasts($input)
|
||||||
{
|
{
|
||||||
self::check_version($input, "1.6.0");
|
self::check_version($input, "1.6.0");
|
||||||
|
$id = $input['id'];
|
||||||
|
$includeEpisodes = isset($input['includeEpisodes']) ? $input['includeEpisodes'] : true;
|
||||||
|
|
||||||
$r = Subsonic_XML_Data::createError(Subsonic_XML_Data::SSERROR_DATA_NOTFOUND);
|
if (AmpConfig::get('podcast')) {
|
||||||
|
if ($id) {
|
||||||
|
$podcast = new Podcast(Subsonic_XML_Data::getAmpacheId($id));
|
||||||
|
if ($podcast->id) {
|
||||||
|
$r = Subsonic_XML_Data::createSuccessResponse();
|
||||||
|
Subsonic_XML_Data::addPodcasts($r, array($podcast), $includeEpisodes);
|
||||||
|
} else {
|
||||||
|
$r = Subsonic_XML_Data::createError(Subsonic_XML_Data::SSERROR_DATA_NOTFOUND);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$podcasts = Catalog::get_podcasts();
|
||||||
|
$r = Subsonic_XML_Data::createSuccessResponse();
|
||||||
|
Subsonic_XML_Data::addPodcasts($r, $podcasts, $includeEpisodes);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$r = Subsonic_XML_Data::createError(Subsonic_XML_Data::SSERROR_UNAUTHORIZED);
|
||||||
|
}
|
||||||
|
self::apiOutput($input, $r);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getNewestPodcasts
|
||||||
|
* Get the most recently published podcast episodes.
|
||||||
|
* Takes the optional count in parameters
|
||||||
|
*/
|
||||||
|
public static function getnewestpodcasts($input)
|
||||||
|
{
|
||||||
|
self::check_version($input, "1.13.0");
|
||||||
|
$count = $input['count'] ?: 20;
|
||||||
|
|
||||||
|
if (AmpConfig::get('podcast')) {
|
||||||
|
$r = Subsonic_XML_Data::createSuccessResponse();
|
||||||
|
$episodes = Catalog::get_newest_podcasts($count);
|
||||||
|
Subsonic_XML_Data::addNewestPodcastEpisodes($r, $episodes);
|
||||||
|
} else {
|
||||||
|
$r = Subsonic_XML_Data::createError(Subsonic_XML_Data::SSERROR_UNAUTHORIZED);
|
||||||
|
}
|
||||||
self::apiOutput($input, $r);
|
self::apiOutput($input, $r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1884,13 +1921,20 @@ class Subsonic_Api
|
||||||
* refreshPodcasts
|
* refreshPodcasts
|
||||||
* Request the server to check for new podcast episodes.
|
* Request the server to check for new podcast episodes.
|
||||||
* Takes no parameters.
|
* Takes no parameters.
|
||||||
* Not supported.
|
|
||||||
*/
|
*/
|
||||||
public static function refreshpodcasts($input)
|
public static function refreshpodcasts($input)
|
||||||
{
|
{
|
||||||
self::check_version($input, "1.9.0");
|
self::check_version($input, "1.9.0");
|
||||||
|
|
||||||
$r = Subsonic_XML_Data::createError(Subsonic_XML_Data::SSERROR_DATA_NOTFOUND);
|
if (AmpConfig::get('podcast') && Access::check('interface', 75)) {
|
||||||
|
$podcasts = Catalog::get_podcasts();
|
||||||
|
foreach ($podcasts as $podcast) {
|
||||||
|
$podcast->sync_episodes(true);
|
||||||
|
}
|
||||||
|
$r = Subsonic_XML_Data::createSuccessResponse();
|
||||||
|
} else {
|
||||||
|
$r = Subsonic_XML_Data::createError(Subsonic_XML_Data::SSERROR_UNAUTHORIZED);
|
||||||
|
}
|
||||||
self::apiOutput($input, $r);
|
self::apiOutput($input, $r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1898,13 +1942,29 @@ class Subsonic_Api
|
||||||
* createPodcastChannel
|
* createPodcastChannel
|
||||||
* Add a new podcast channel.
|
* Add a new podcast channel.
|
||||||
* Takes the podcast url in parameter.
|
* Takes the podcast url in parameter.
|
||||||
* Not supported.
|
|
||||||
*/
|
*/
|
||||||
public static function createpodcastchannel($input)
|
public static function createpodcastchannel($input)
|
||||||
{
|
{
|
||||||
self::check_version($input, "1.9.0");
|
self::check_version($input, "1.9.0");
|
||||||
|
$url = self::check_parameter($input, 'url');
|
||||||
$r = Subsonic_XML_Data::createError(Subsonic_XML_Data::SSERROR_DATA_NOTFOUND);
|
|
||||||
|
if (AmpConfig::get('podcast') && Access::check('interface', 75)) {
|
||||||
|
$catalogs = Catalog::get_catalogs('podcast');
|
||||||
|
if (count($catalogs) > 0) {
|
||||||
|
$data = array();
|
||||||
|
$data['feed'] = $url;
|
||||||
|
$data['catalog'] = $catalogs[0];
|
||||||
|
if (Podcast::create($data)) {
|
||||||
|
$r = Subsonic_XML_Data::createSuccessResponse();
|
||||||
|
} else {
|
||||||
|
$r = Subsonic_XML_Data::createError(Subsonic_XML_Data::SSERROR_GENERIC);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$r = Subsonic_XML_Data::createError(Subsonic_XML_Data::SSERROR_UNAUTHORIZED);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$r = Subsonic_XML_Data::createError(Subsonic_XML_Data::SSERROR_UNAUTHORIZED);
|
||||||
|
}
|
||||||
self::apiOutput($input, $r);
|
self::apiOutput($input, $r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1912,13 +1972,26 @@ class Subsonic_Api
|
||||||
* deletePodcastChannel
|
* deletePodcastChannel
|
||||||
* Delete an existing podcast channel
|
* Delete an existing podcast channel
|
||||||
* Takes the podcast id in parameter.
|
* Takes the podcast id in parameter.
|
||||||
* Not supported.
|
|
||||||
*/
|
*/
|
||||||
public static function deletepodcastchannel($input)
|
public static function deletepodcastchannel($input)
|
||||||
{
|
{
|
||||||
self::check_version($input, "1.9.0");
|
self::check_version($input, "1.9.0");
|
||||||
|
$id = self::check_parameter($input, 'id');
|
||||||
$r = Subsonic_XML_Data::createError(Subsonic_XML_Data::SSERROR_DATA_NOTFOUND);
|
|
||||||
|
if (AmpConfig::get('podcast') && Access::check('interface', 75)) {
|
||||||
|
$podcast = new Podcast(Subsonic_XML_Data::getAmpacheId($id));
|
||||||
|
if ($podcast->id) {
|
||||||
|
if ($podcast->remove()) {
|
||||||
|
$r = Subsonic_XML_Data::createSuccessResponse();
|
||||||
|
} else {
|
||||||
|
$r = Subsonic_XML_Data::createError(Subsonic_XML_Data::SSERROR_GENERIC);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$r = Subsonic_XML_Data::createError(Subsonic_XML_Data::SSERROR_DATA_NOTFOUND);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$r = Subsonic_XML_Data::createError(Subsonic_XML_Data::SSERROR_UNAUTHORIZED);
|
||||||
|
}
|
||||||
self::apiOutput($input, $r);
|
self::apiOutput($input, $r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1926,13 +1999,26 @@ class Subsonic_Api
|
||||||
* deletePodcastEpisode
|
* deletePodcastEpisode
|
||||||
* Delete a podcast episode
|
* Delete a podcast episode
|
||||||
* Takes the podcast episode id in parameter.
|
* Takes the podcast episode id in parameter.
|
||||||
* Not supported.
|
|
||||||
*/
|
*/
|
||||||
public static function deletepodcastepisode($input)
|
public static function deletepodcastepisode($input)
|
||||||
{
|
{
|
||||||
self::check_version($input, "1.9.0");
|
self::check_version($input, "1.9.0");
|
||||||
|
$id = self::check_parameter($input, 'id');
|
||||||
$r = Subsonic_XML_Data::createError(Subsonic_XML_Data::SSERROR_DATA_NOTFOUND);
|
|
||||||
|
if (AmpConfig::get('podcast') && Access::check('interface', 75)) {
|
||||||
|
$episode = new Podcast_Episode(Subsonic_XML_Data::getAmpacheId($id));
|
||||||
|
if ($episode->id) {
|
||||||
|
if ($episode->remove()) {
|
||||||
|
$r = Subsonic_XML_Data::createSuccessResponse();
|
||||||
|
} else {
|
||||||
|
$r = Subsonic_XML_Data::createError(Subsonic_XML_Data::SSERROR_GENERIC);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$r = Subsonic_XML_Data::createError(Subsonic_XML_Data::SSERROR_DATA_NOTFOUND);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$r = Subsonic_XML_Data::createError(Subsonic_XML_Data::SSERROR_UNAUTHORIZED);
|
||||||
|
}
|
||||||
self::apiOutput($input, $r);
|
self::apiOutput($input, $r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1940,15 +2026,27 @@ class Subsonic_Api
|
||||||
* downloadPodcastEpisode
|
* downloadPodcastEpisode
|
||||||
* Request the server to download a podcast episode
|
* Request the server to download a podcast episode
|
||||||
* Takes the podcast episode id in parameter.
|
* Takes the podcast episode id in parameter.
|
||||||
* Not supported.
|
|
||||||
*/
|
*/
|
||||||
public static function downloadpodcastepisode($input)
|
public static function downloadpodcastepisode($input)
|
||||||
{
|
{
|
||||||
self::check_version($input, "1.9.0");
|
self::check_version($input, "1.9.0");
|
||||||
|
$id = self::check_parameter($input, 'id');
|
||||||
$r = Subsonic_XML_Data::createError(Subsonic_XML_Data::SSERROR_DATA_NOTFOUND);
|
|
||||||
|
if (AmpConfig::get('podcast') && Access::check('interface', 75)) {
|
||||||
|
$episode = new Podcast_Episode(Subsonic_XML_Data::getAmpacheId($id));
|
||||||
|
if ($episode->id) {
|
||||||
|
$episode->gather();
|
||||||
|
$r = Subsonic_XML_Data::createSuccessResponse();
|
||||||
|
} else {
|
||||||
|
$r = Subsonic_XML_Data::createError(Subsonic_XML_Data::SSERROR_DATA_NOTFOUND);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$r = Subsonic_XML_Data::createError(Subsonic_XML_Data::SSERROR_UNAUTHORIZED);
|
||||||
|
}
|
||||||
self::apiOutput($input, $r);
|
self::apiOutput($input, $r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**** CURRENT UNSUPPORTED FUNCTIONS ****/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getChatMessages
|
* getChatMessages
|
||||||
|
|
|
@ -41,11 +41,13 @@ class Subsonic_XML_Data
|
||||||
const SSERROR_DATA_NOTFOUND = 70;
|
const SSERROR_DATA_NOTFOUND = 70;
|
||||||
|
|
||||||
// Ampache doesn't have a global unique id but each items are unique per category. We use id pattern to identify item category.
|
// Ampache doesn't have a global unique id but each items are unique per category. We use id pattern to identify item category.
|
||||||
const AMPACHEID_ARTIST = 100000000;
|
const AMPACHEID_ARTIST = 100000000;
|
||||||
const AMPACHEID_ALBUM = 200000000;
|
const AMPACHEID_ALBUM = 200000000;
|
||||||
const AMPACHEID_SONG = 300000000;
|
const AMPACHEID_SONG = 300000000;
|
||||||
const AMPACHEID_SMARTPL = 400000000;
|
const AMPACHEID_SMARTPL = 400000000;
|
||||||
const AMPACHEID_VIDEO = 500000000;
|
const AMPACHEID_VIDEO = 500000000;
|
||||||
|
const AMPACHEID_PODCAST = 600000000;
|
||||||
|
const AMPACHEID_PODCASTEP = 700000000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* constructor
|
* constructor
|
||||||
|
@ -81,6 +83,16 @@ class Subsonic_XML_Data
|
||||||
return $id + Subsonic_XML_Data::AMPACHEID_VIDEO;
|
return $id + Subsonic_XML_Data::AMPACHEID_VIDEO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getPodcastId($id)
|
||||||
|
{
|
||||||
|
return $id + Subsonic_XML_Data::AMPACHEID_PODCAST;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getPodcastEpId($id)
|
||||||
|
{
|
||||||
|
return $id + Subsonic_XML_Data::AMPACHEID_PODCASTEP;
|
||||||
|
}
|
||||||
|
|
||||||
private static function cleanId($id)
|
private static function cleanId($id)
|
||||||
{
|
{
|
||||||
// Remove all al-, ar-, ... prefixs
|
// Remove all al-, ar-, ... prefixs
|
||||||
|
@ -120,19 +132,31 @@ class Subsonic_XML_Data
|
||||||
public static function isSong($id)
|
public static function isSong($id)
|
||||||
{
|
{
|
||||||
$id = self::cleanId($id);
|
$id = self::cleanId($id);
|
||||||
return ($id >= Subsonic_XML_Data::AMPACHEID_SONG);
|
return ($id >= Subsonic_XML_Data::AMPACHEID_SONG && $id < Subsonic_XML_Data::AMPACHEID_SMARTPL);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function isSmartPlaylist($id)
|
public static function isSmartPlaylist($id)
|
||||||
{
|
{
|
||||||
$id = self::cleanId($id);
|
$id = self::cleanId($id);
|
||||||
return ($id >= Subsonic_XML_Data::AMPACHEID_SMARTPL);
|
return ($id >= Subsonic_XML_Data::AMPACHEID_SMARTPL && $id < Subsonic_XML_Data::AMPACHEID_VIDEO);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function isVideo($id)
|
public static function isVideo($id)
|
||||||
{
|
{
|
||||||
$id = self::cleanId($id);
|
$id = self::cleanId($id);
|
||||||
return ($id >= Subsonic_XML_Data::AMPACHEID_VIDEO);
|
return ($id >= Subsonic_XML_Data::AMPACHEID_VIDEO && $id < Subsonic_XML_Data::AMPACHEID_PODCAST);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function isPodcast($id)
|
||||||
|
{
|
||||||
|
$id = self::cleanId($id);
|
||||||
|
return ($id >= Subsonic_XML_Data::AMPACHEID_PODCAST && $id < Subsonic_XML_Data::AMPACHEID_PODCASTEP);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function isPodcastEp($id)
|
||||||
|
{
|
||||||
|
$id = self::cleanId($id);
|
||||||
|
return ($id >= Subsonic_XML_Data::AMPACHEID_PODCASTEP);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function createFailedResponse($version = "")
|
public static function createFailedResponse($version = "")
|
||||||
|
@ -820,4 +844,65 @@ class Subsonic_XML_Data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function addPodcasts($xml, $podcasts, $includeEpisodes = false)
|
||||||
|
{
|
||||||
|
$xpodcasts = $xml->addChild("podcasts");
|
||||||
|
foreach ($podcasts as $podcast) {
|
||||||
|
$podcast->format();
|
||||||
|
$xchannel = $xpodcasts->addChild("channel");
|
||||||
|
$xchannel->addAttribute("id", self::getPodcastId($podcast->id));
|
||||||
|
$xchannel->addAttribute("url", $podcast->feed);
|
||||||
|
$xchannel->addAttribute("title", $podcast->f_title);
|
||||||
|
$xchannel->addAttribute("description", $podcast->f_description);
|
||||||
|
if (Art::has_db($podcast->id, 'podcast')) {
|
||||||
|
$xchannel->addAttribute("coverArt", "pod-" . self::getPodcastId($podcast->id));
|
||||||
|
}
|
||||||
|
$xchannel->addAttribute("status", "completed");
|
||||||
|
if ($includeEpisodes) {
|
||||||
|
$episodes = $podcast->get_episodes();
|
||||||
|
foreach ($episodes as $episode_id) {
|
||||||
|
$episode = new Podcast_Episode($episode_id);
|
||||||
|
self::addPodcastEpisode($xchannel, $episode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function addPodcastEpisode($xml, $episode)
|
||||||
|
{
|
||||||
|
$episode->format();
|
||||||
|
$xepisode = $xml->addChild("episode");
|
||||||
|
$xepisode->addAttribute("id", self::getPodcastEpId($episode->id));
|
||||||
|
$xepisode->addAttribute("channelId", self::getPodcastId($episode->podcast));
|
||||||
|
$xepisode->addAttribute("title", $episode->f_title);
|
||||||
|
$xepisode->addAttribute("album", $episode->f_podcast);
|
||||||
|
$xepisode->addAttribute("description", $episode->f_description);
|
||||||
|
$xepisode->addAttribute("duration", $episode->time);
|
||||||
|
$xepisode->addAttribute("genre", "Podcast");
|
||||||
|
$xepisode->addAttribute("isDir", "false");
|
||||||
|
$xepisode->addAttribute("publishDate", date("c", $episode->pubdate));
|
||||||
|
$xepisode->addAttribute("status", $episode->state);
|
||||||
|
if (Art::has_db($episode->podcast, 'podcast')) {
|
||||||
|
$xepisode->addAttribute("coverArt",self::getPodcastId($episode->podcast));
|
||||||
|
}
|
||||||
|
if ($episode->file) {
|
||||||
|
$xepisode->addAttribute("streamId", self::getPodcastEpId($episode->id));
|
||||||
|
$xepisode->addAttribute("size", $episode->size);
|
||||||
|
$xepisode->addAttribute("suffix", $episode->type);
|
||||||
|
$xepisode->addAttribute("contentType", $episode->mime);
|
||||||
|
// Create a clean fake path instead of song real file path to have better offline mode storage on Subsonic clients
|
||||||
|
$path = basename($episode->file);
|
||||||
|
$xepisode->addAttribute("path", $path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function addNewestPodcastEpisodes($xml, $episodes)
|
||||||
|
{
|
||||||
|
$xpodcasts = $xml->addChild("newestPodcasts");
|
||||||
|
foreach ($episodes as $episode) {
|
||||||
|
$episode->format();
|
||||||
|
self::addPodcastEpisode($xpodcasts, $episode);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ class TVShow extends database_object implements library_item
|
||||||
} // get_seasons
|
} // get_seasons
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get_songs
|
* get_episodes
|
||||||
* gets all episodes for this tv show
|
* gets all episodes for this tv show
|
||||||
*/
|
*/
|
||||||
public function get_episodes()
|
public function get_episodes()
|
||||||
|
|
|
@ -522,6 +522,9 @@ class Update
|
||||||
|
|
||||||
$update_string = "- Add basic metadata tables.<br />";
|
$update_string = "- Add basic metadata tables.<br />";
|
||||||
$version[] = array('version' => '370041', 'description' => $update_string);
|
$version[] = array('version' => '370041', 'description' => $update_string);
|
||||||
|
|
||||||
|
$update_string = "- Add podcasts.<br />";
|
||||||
|
$version[] = array('version' => '380001', 'description' => $update_string);
|
||||||
|
|
||||||
return $version;
|
return $version;
|
||||||
}
|
}
|
||||||
|
@ -2882,7 +2885,7 @@ class Update
|
||||||
$retval = true;
|
$retval = true;
|
||||||
|
|
||||||
$sql = "ALTER TABLE `video` ADD `release_date` date NULL AFTER `enabled`, " .
|
$sql = "ALTER TABLE `video` ADD `release_date` date NULL AFTER `enabled`, " .
|
||||||
"ADD `played` tinyint(1) unsigned DEFAULT '1' NOT NULL AFTER `enabled`";
|
"ADD `played` tinyint(1) unsigned DEFAULT '0' NOT NULL AFTER `enabled`";
|
||||||
$retval &= Dba::write($sql);
|
$retval &= Dba::write($sql);
|
||||||
|
|
||||||
$sql = "CREATE TABLE `tvshow` (" .
|
$sql = "CREATE TABLE `tvshow` (" .
|
||||||
|
@ -2932,7 +2935,7 @@ class Update
|
||||||
$retval &= Dba::write($sql);
|
$retval &= Dba::write($sql);
|
||||||
|
|
||||||
$sql = "INSERT INTO `preference` (`name`,`value`,`description`,`level`,`type`,`catagory`) " .
|
$sql = "INSERT INTO `preference` (`name`,`value`,`description`,`level`,`type`,`catagory`) " .
|
||||||
"VALUES ('allow_video','1','Allow video features',25,'integer','system')";
|
"VALUES ('allow_video','1','Allow video features',75,'integer','system')";
|
||||||
$retval &= Dba::write($sql);
|
$retval &= Dba::write($sql);
|
||||||
$id = Dba::insert_id();
|
$id = Dba::insert_id();
|
||||||
$sql = "INSERT INTO `user_preference` VALUES (-1,?,'1')";
|
$sql = "INSERT INTO `user_preference` VALUES (-1,?,'1')";
|
||||||
|
@ -3612,7 +3615,7 @@ class Update
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* update_370040
|
* update_370041
|
||||||
*
|
*
|
||||||
* Add Metadata tables and preferences
|
* Add Metadata tables and preferences
|
||||||
*/
|
*/
|
||||||
|
@ -3656,4 +3659,66 @@ class Update
|
||||||
|
|
||||||
return $retval;
|
return $retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update_380001
|
||||||
|
*
|
||||||
|
* Add podcasts
|
||||||
|
*/
|
||||||
|
public static function update_380001()
|
||||||
|
{
|
||||||
|
$retval = true;
|
||||||
|
|
||||||
|
$sql = "CREATE TABLE `podcast` (`id` int( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY , " .
|
||||||
|
"`feed` varchar(4096) NOT NULL , " .
|
||||||
|
"`catalog` int(11) NOT NULL , " .
|
||||||
|
"`title` varchar(255) CHARACTER SET utf8 NOT NULL , " .
|
||||||
|
"`website` varchar(255) NULL , " .
|
||||||
|
"`description` varchar(4096) CHARACTER SET utf8 NULL , " .
|
||||||
|
"`language` varchar(5) NULL , " .
|
||||||
|
"`copyright` varchar(64) NULL , " .
|
||||||
|
"`generator` varchar(64) NULL , " .
|
||||||
|
"`lastbuilddate` int(11) UNSIGNED DEFAULT '0' NOT NULL , " .
|
||||||
|
"`lastsync` int(11) UNSIGNED DEFAULT '0' NOT NULL" .
|
||||||
|
") ENGINE = MYISAM";
|
||||||
|
$retval &= Dba::write($sql);
|
||||||
|
|
||||||
|
$sql = "CREATE TABLE `podcast_episode` (`id` int( 11 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY , " .
|
||||||
|
"`title` varchar(255) CHARACTER SET utf8 NOT NULL , " .
|
||||||
|
"`guid` varchar(255) NOT NULL , " .
|
||||||
|
"`podcast` int(11) NOT NULL , " .
|
||||||
|
"`state` varchar(32) NOT NULL , " .
|
||||||
|
"`file` varchar(4096) CHARACTER SET utf8 NULL , " .
|
||||||
|
"`source` varchar(4096) NULL , " .
|
||||||
|
"`size` bigint(20) UNSIGNED DEFAULT '0' NOT NULL , " .
|
||||||
|
"`time` smallint(5) UNSIGNED DEFAULT '0' NOT NULL , " .
|
||||||
|
"`website` varchar(255) NULL , " .
|
||||||
|
"`description` varchar(4096) CHARACTER SET utf8 NULL , " .
|
||||||
|
"`author` varchar(64) NULL , " .
|
||||||
|
"`category` varchar(64) NULL , " .
|
||||||
|
"`played` tinyint(1) unsigned DEFAULT '0' NOT NULL , " .
|
||||||
|
"`pubdate` int(11) UNSIGNED NOT NULL , " .
|
||||||
|
"`addition_time` int(11) UNSIGNED NOT NULL" .
|
||||||
|
") ENGINE = MYISAM";
|
||||||
|
$retval &= Dba::write($sql);
|
||||||
|
|
||||||
|
$sql = "INSERT INTO `preference` (`name`,`value`,`description`,`level`,`type`,`catagory`) " .
|
||||||
|
"VALUES ('podcast_keep','10','Podcast: # latest episodes to keep',100,'integer','system')";
|
||||||
|
$retval &= Dba::write($sql);
|
||||||
|
$id = Dba::insert_id();
|
||||||
|
$sql = "INSERT INTO `user_preference` VALUES (-1,?,'10')";
|
||||||
|
$retval &= Dba::write($sql, array($id));
|
||||||
|
|
||||||
|
$sql = "INSERT INTO `preference` (`name`,`value`,`description`,`level`,`type`,`catagory`) " .
|
||||||
|
"VALUES ('podcast_new_download','1','Podcast: # episodes to download when new episodes are available',100,'integer','system')";
|
||||||
|
$retval &= Dba::write($sql);
|
||||||
|
$id = Dba::insert_id();
|
||||||
|
$sql = "INSERT INTO `user_preference` VALUES (-1,?,'1')";
|
||||||
|
$retval &= Dba::write($sql, array($id));
|
||||||
|
|
||||||
|
$sql = "ALTER TABLE `rating` CHANGE `object_type` `object_type` ENUM ('artist','album','song','stream','video','playlist','tvshow','tvshow_season','podcast','podcast_episode') NULL";
|
||||||
|
$retval &= Dba::write($sql);
|
||||||
|
|
||||||
|
return $retval;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -460,6 +460,38 @@ class Upnp_Api
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'podcasts':
|
||||||
|
switch (count($pathreq)) {
|
||||||
|
case 1:
|
||||||
|
$counts = Catalog::count_medias();
|
||||||
|
$meta = array(
|
||||||
|
'id' => $root . '/podcasts',
|
||||||
|
'parentID' => $root,
|
||||||
|
'restricted' => '1',
|
||||||
|
'childCount' => $counts['podcasts'],
|
||||||
|
'dc:title' => T_('Podcasts'),
|
||||||
|
'upnp:class' => 'object.container',
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
$podcast = new Podcast($pathreq[1]);
|
||||||
|
if ($podcast->id) {
|
||||||
|
$podcast->format();
|
||||||
|
$meta = self::_itemPodcast($podcast, $root . '/podcasts');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
$episode = new Podcast_Episode($pathreq[2]);
|
||||||
|
if ($episode->id) {
|
||||||
|
$episode->format();
|
||||||
|
$meta = self::_itemPodcastEpisode($episode, $root . '/podcasts/' . $pathreq[1]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$meta = array(
|
$meta = array(
|
||||||
|
@ -638,6 +670,31 @@ class Upnp_Api
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'podcasts':
|
||||||
|
switch (count($pathreq)) {
|
||||||
|
case 1: // Get podcasts list
|
||||||
|
$podcasts = Catalog::get_podcasts();
|
||||||
|
list($maxCount, $podcasts) = self::_slice($podcasts, $start, $count);
|
||||||
|
foreach ($podcasts as $podcast) {
|
||||||
|
$podcast->format();
|
||||||
|
$mediaItems[] = self::_itemPodcast($podcast, $parent);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: // Get podcast episodes list
|
||||||
|
$podcast = new Podcast($pathreq[1]);
|
||||||
|
if ($podcast->id) {
|
||||||
|
$episodes = $podcast->get_episodes();
|
||||||
|
list($maxCount, $episodes) = self::_slice($episodes, $start, $count);
|
||||||
|
foreach ($episodes as $episode_id) {
|
||||||
|
$episode = new Podcast_Episode($episode_id);
|
||||||
|
$episode->format();
|
||||||
|
$mediaItems[] = self::_itemPodcastEpisode($episode, $parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$mediaItems[] = self::_musicMetadata('artists');
|
$mediaItems[] = self::_musicMetadata('artists');
|
||||||
|
@ -645,7 +702,12 @@ class Upnp_Api
|
||||||
$mediaItems[] = self::_musicMetadata('songs');
|
$mediaItems[] = self::_musicMetadata('songs');
|
||||||
$mediaItems[] = self::_musicMetadata('playlists');
|
$mediaItems[] = self::_musicMetadata('playlists');
|
||||||
$mediaItems[] = self::_musicMetadata('smartplaylists');
|
$mediaItems[] = self::_musicMetadata('smartplaylists');
|
||||||
$mediaItems[] = self::_musicMetadata('live_streams');
|
if (AmpConfig::get('live_stream')) {
|
||||||
|
$mediaItems[] = self::_musicMetadata('live_streams');
|
||||||
|
}
|
||||||
|
if (AmpConfig::get('podcast')) {
|
||||||
|
$mediaItems[] = self::_musicMetadata('podcasts');
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1068,6 +1130,44 @@ class Upnp_Api
|
||||||
'duration' => $video->f_time_h . '.0',
|
'duration' => $video->f_time_h . '.0',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function _itemPodcast($podcast, $parent)
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'id' => 'amp://music/podcasts/' . $podcast->id,
|
||||||
|
'parentID' => $parent,
|
||||||
|
'restricted' => '1',
|
||||||
|
'childCount' => count($podcast->get_episodes()),
|
||||||
|
'dc:title' => self::_replaceSpecialSymbols($podcast->f_title),
|
||||||
|
'upnp:class' => 'object.container',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function _itemPodcastEpisode($episode, $parent)
|
||||||
|
{
|
||||||
|
$api_session = (AmpConfig::get('require_session')) ? Stream::get_session() : false;
|
||||||
|
$art_url = Art::url($episode->podcast, 'podcast', $api_session);
|
||||||
|
|
||||||
|
$fileTypesByExt = self::_getFileTypes();
|
||||||
|
$arrFileType = (!empty($episode->type)) ? $fileTypesByExt[$episode->type] : array();
|
||||||
|
|
||||||
|
$ret = array(
|
||||||
|
'id' => 'amp://music/podcasts/' . $episode->podcast . '/' . $episode->id,
|
||||||
|
'parentID' => $parent,
|
||||||
|
'restricted' => '1',
|
||||||
|
'dc:title' => self::_replaceSpecialSymbols($episode->f_title),
|
||||||
|
'upnp:album' => self::_replaceSpecialSymbols($episode->f_podcast),
|
||||||
|
'upnp:class' => (isset($arrFileType['class'])) ? $arrFileType['class'] : 'object.item.unknownItem',
|
||||||
|
'upnp:albumArtURI' => $art_url
|
||||||
|
);
|
||||||
|
if (isset($arrFileType['mime'])) {
|
||||||
|
$ret['res'] = Podcast_Episode::play_url($episode->id, '', 'api');
|
||||||
|
$ret['protocolInfo'] = $arrFileType['mime'];
|
||||||
|
$ret['size'] = $episode->size;
|
||||||
|
$ret['duration'] = $episode->f_time_h . '.0';
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
private static function _getFileTypes()
|
private static function _getFileTypes()
|
||||||
{
|
{
|
||||||
|
|
|
@ -91,7 +91,7 @@ class Userflag extends database_object
|
||||||
*/
|
*/
|
||||||
public static function gc($object_type = null, $object_id = null)
|
public static function gc($object_type = null, $object_id = null)
|
||||||
{
|
{
|
||||||
$types = array('song', 'album', 'artist', 'video', 'tvshow', 'tvshow_season');
|
$types = array('song', 'album', 'artist', 'video', 'tvshow', 'tvshow_season', 'podcast', 'podcast_episode');
|
||||||
|
|
||||||
if ($object_type != null) {
|
if ($object_type != null) {
|
||||||
if (in_array($object_type, $types)) {
|
if (in_array($object_type, $types)) {
|
||||||
|
|
|
@ -290,7 +290,7 @@ class WebPlayer
|
||||||
|
|
||||||
$js['filetype'] = $types['player'];
|
$js['filetype'] = $types['player'];
|
||||||
$js['url'] = $url;
|
$js['url'] = $url;
|
||||||
if ($urlinfo['type'] == 'song') {
|
if ($urlinfo['type'] == 'song' || $urlinfo['type'] == 'podcast_episode') {
|
||||||
$js['poster'] = $item->image_url;
|
$js['poster'] = $item->image_url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -815,23 +815,24 @@ class XML_Data
|
||||||
|
|
||||||
public static function podcast(library_item $libitem)
|
public static function podcast(library_item $libitem)
|
||||||
{
|
{
|
||||||
$xml = new SimpleXMLElement('<rss />');
|
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><rss />');
|
||||||
$xml->addAttribute("version", "2.0");
|
|
||||||
$xml->addAttribute("xmlns:xmlns:atom", "http://www.w3.org/2005/Atom");
|
$xml->addAttribute("xmlns:xmlns:atom", "http://www.w3.org/2005/Atom");
|
||||||
$xml->addAttribute("xmlns:xmlns:itunes", "http://www.itunes.com/dtds/podcast-1.0.dtd");
|
$xml->addAttribute("xmlns:xmlns:itunes", "http://www.itunes.com/dtds/podcast-1.0.dtd");
|
||||||
|
$xml->addAttribute("version", "2.0");
|
||||||
$xchannel = $xml->addChild("channel");
|
$xchannel = $xml->addChild("channel");
|
||||||
$xchannel->addChild("title", $libitem->get_fullname() . " Podcast");
|
$xchannel->addChild("title", $libitem->get_fullname() . " Podcast");
|
||||||
$xlink = $xchannel->addChild("atom:link");
|
$xlink = $xchannel->addChild("atom:link", htmlentities($libitem->link));
|
||||||
$xlink->addAttribute("type", "text/html");
|
|
||||||
$xlink->addAttribute("href", $libitem->link);
|
|
||||||
if (Art::has_db($libitem->id, get_class($libitem))) {
|
if (Art::has_db($libitem->id, get_class($libitem))) {
|
||||||
$ximg = $xchannel->addChild("xmlns:itunes:image");
|
$ximg = $xchannel->addChild("xmlns:itunes:image");
|
||||||
$ximg->addAttribute("href", Art::url($libitem->id, get_class($libitem)));
|
$ximg->addAttribute("href", Art::url($libitem->id, get_class($libitem)));
|
||||||
}
|
}
|
||||||
$summary = $libitem->get_description();
|
$summary = $libitem->get_description();
|
||||||
if (!empty($summary)) {
|
if (!empty($summary)) {
|
||||||
|
$summary = htmlentities($summary);
|
||||||
|
$xchannel->addChild("description", $summary);
|
||||||
$xchannel->addChild("xmlns:itunes:summary", $summary);
|
$xchannel->addChild("xmlns:itunes:summary", $summary);
|
||||||
}
|
}
|
||||||
|
$xchannel->addChild("generator", "Ampache");
|
||||||
$xchannel->addChild("xmlns:itunes:category", "Music");
|
$xchannel->addChild("xmlns:itunes:category", "Music");
|
||||||
$owner = $libitem->get_user_owner();
|
$owner = $libitem->get_user_owner();
|
||||||
if ($owner) {
|
if ($owner) {
|
||||||
|
@ -846,34 +847,38 @@ class XML_Data
|
||||||
$media = new $media_info['object_type']($media_info['object_id']);
|
$media = new $media_info['object_type']($media_info['object_id']);
|
||||||
$media->format();
|
$media->format();
|
||||||
$xitem = $xchannel->addChild("item");
|
$xitem = $xchannel->addChild("item");
|
||||||
$xitem->addChild("title", $media->get_fullname());
|
$xitem->addChild("title", htmlentities($media->get_fullname()));
|
||||||
if ($media->f_artist) {
|
if ($media->f_artist) {
|
||||||
$xitem->addChild("xmlns:itunes:author", $media->f_artist);
|
$xitem->addChild("xmlns:itunes:author", $media->f_artist);
|
||||||
}
|
}
|
||||||
$xmlink = $xitem->addChild("link");
|
$xmlink = $xitem->addChild("link", htmlentities($media->link));
|
||||||
$xmlink->addAttribute("href", $media->link);
|
$xitem->addChild("guid", htmlentities($media->link));
|
||||||
$xitem->addChild("guid", $media->link);
|
|
||||||
if ($media->addition_time) {
|
if ($media->addition_time) {
|
||||||
$xitem->addChild("pubDate", date("r", $media->addition_time));
|
$xitem->addChild("pubDate", date("r", $media->addition_time));
|
||||||
}
|
}
|
||||||
$description = $media->get_description();
|
$description = $media->get_description();
|
||||||
if (!empty($description)) {
|
if (!empty($description)) {
|
||||||
$xitem->addChild("description", $description);
|
$xitem->addChild("description", htmlentities($description));
|
||||||
}
|
}
|
||||||
$xitem->addChild("xmlns:itunes:duration", $media->f_time);
|
$xitem->addChild("xmlns:itunes:duration", $media->f_time);
|
||||||
$xencl = $xitem->addChild("enclosure");
|
if ($media->mime) {
|
||||||
$xencl->addAttribute("type", $media->mime);
|
$surl = $media_info['object_type']::play_url($media_info['object_id']);
|
||||||
$xencl->addAttribute("length", $media->size);
|
$xencl = $xitem->addChild("enclosure");
|
||||||
$surl = $media_info['object_type']::play_url($media_info['object_id']);
|
$xencl->addAttribute("type", $media->mime);
|
||||||
$xencl->addAttribute("url", $surl);
|
$xencl->addAttribute("length", $media->size);
|
||||||
|
$xencl->addAttribute("url", $surl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$xmlstr = $xml->asXml();
|
$xmlstr = $xml->asXml();
|
||||||
// Format xml output
|
// Format xml output
|
||||||
$dom = new DOMDocument();
|
$dom = new DOMDocument();
|
||||||
$dom->loadXML($xmlstr);
|
if ($dom->loadXML($xmlstr) !== false) {
|
||||||
$dom->formatOutput = true;
|
$dom->formatOutput = true;
|
||||||
return $dom->saveXML($dom->documentElement);
|
return $dom->saveXML();
|
||||||
|
} else {
|
||||||
|
return $xmlstr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // XML_Data
|
} // XML_Data
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ if (!empty($link)) {
|
||||||
$results['load_time_begin'] = $load_time_begin;
|
$results['load_time_begin'] = $load_time_begin;
|
||||||
/** This is the version.... fluf nothing more... **/
|
/** This is the version.... fluf nothing more... **/
|
||||||
$results['version'] = '3.8.2-develop';
|
$results['version'] = '3.8.2-develop';
|
||||||
$results['int_config_version'] = '32';
|
$results['int_config_version'] = '33';
|
||||||
|
|
||||||
if (!empty($results['force_ssl'])) {
|
if (!empty($results['force_ssl'])) {
|
||||||
$http_type = 'https://';
|
$http_type = 'https://';
|
||||||
|
|
|
@ -449,8 +449,10 @@ function install_config_use_case($case)
|
||||||
$dbconfig['download'] = '0';
|
$dbconfig['download'] = '0';
|
||||||
$dbconfig['allow_video'] = '0';
|
$dbconfig['allow_video'] = '0';
|
||||||
|
|
||||||
// Hide sidebar by default to have a better 'minimalist first look'.
|
// Default local UI preferences to have a better 'minimalist first look'.
|
||||||
setcookie('sidebar_state', 'collapsed', time() + (30 * 24 * 60 * 60), '/');
|
setcookie('sidebar_state', 'collapsed', time() + (30 * 24 * 60 * 60), '/');
|
||||||
|
setcookie('browse_album_grid_view', 'false', time() + (30 * 24 * 60 * 60), '/');
|
||||||
|
setcookie('browse_artist_grid_view', 'false', time() + (30 * 24 * 60 * 60), '/');
|
||||||
break;
|
break;
|
||||||
case 'community':
|
case 'community':
|
||||||
$trconfig['use_auth'] = 'false';
|
$trconfig['use_auth'] = 'false';
|
||||||
|
|
|
@ -398,12 +398,18 @@ function show_tvshow_season_select($name='tvshow_season', $season_id, $allow_add
|
||||||
* Yet another one of these buggers. this shows a drop down of all of your
|
* Yet another one of these buggers. this shows a drop down of all of your
|
||||||
* catalogs.
|
* catalogs.
|
||||||
*/
|
*/
|
||||||
function show_catalog_select($name='catalog',$catalog_id=0,$style='', $allow_none=false)
|
function show_catalog_select($name='catalog', $catalog_id=0, $style='', $allow_none=false, $filter_type='')
|
||||||
{
|
{
|
||||||
echo "<select name=\"$name\" style=\"$style\">\n";
|
echo "<select name=\"$name\" style=\"$style\">\n";
|
||||||
|
|
||||||
$sql = "SELECT `id`, `name` FROM `catalog` ORDER BY `name`";
|
$params = array();
|
||||||
$db_results = Dba::read($sql);
|
$sql = "SELECT `id`, `name` FROM `catalog` ";
|
||||||
|
if (!empty($filter_type)) {
|
||||||
|
$sql .= "WHERE `gather_types` = ?";
|
||||||
|
$params[] = $filter_type;
|
||||||
|
}
|
||||||
|
$sql .= "ORDER BY `name`";
|
||||||
|
$db_results = Dba::read($sql, $params);
|
||||||
|
|
||||||
if ($allow_none) {
|
if ($allow_none) {
|
||||||
echo "\t<option value=\"-1\">" . T_('None') . "</option>\n";
|
echo "\t<option value=\"-1\">" . T_('None') . "</option>\n";
|
||||||
|
|
|
@ -435,29 +435,34 @@ class Catalog_local extends Catalog
|
||||||
// Prevent the script from timing out and flush what we've got
|
// Prevent the script from timing out and flush what we've got
|
||||||
set_time_limit(0);
|
set_time_limit(0);
|
||||||
|
|
||||||
/* Get the songs and then insert them into the db */
|
// If podcast catalog, we don't want to analyze files for now
|
||||||
$this->add_files($this->path, $options);
|
if ($this->gather_types == "podcast") {
|
||||||
|
$this->sync_podcasts();
|
||||||
|
} else {
|
||||||
|
/* Get the songs and then insert them into the db */
|
||||||
|
$this->add_files($this->path, $options);
|
||||||
|
|
||||||
if ($options['parse_playlist'] && count($this->_playlists)) {
|
if ($options['parse_playlist'] && count($this->_playlists)) {
|
||||||
// Foreach Playlists we found
|
// Foreach Playlists we found
|
||||||
foreach ($this->_playlists as $full_file) {
|
foreach ($this->_playlists as $full_file) {
|
||||||
$result = $this->import_playlist($full_file);
|
$result = $this->import_playlist($full_file);
|
||||||
if ($result['success']) {
|
if ($result['success']) {
|
||||||
$file = basename($full_file);
|
$file = basename($full_file);
|
||||||
} // end if import worked
|
} // end if import worked
|
||||||
} // end foreach playlist files
|
} // end foreach playlist files
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do a little stats mojo here */
|
/* Do a little stats mojo here */
|
||||||
$current_time = time();
|
$current_time = time();
|
||||||
|
|
||||||
if ($options['gather_art']) {
|
if ($options['gather_art']) {
|
||||||
$catalog_id = $this->id;
|
$catalog_id = $this->id;
|
||||||
if (!defined('SSE_OUTPUT')) {
|
if (!defined('SSE_OUTPUT')) {
|
||||||
require AmpConfig::get('prefix') . UI::find_template('show_gather_art.inc.php');
|
require AmpConfig::get('prefix') . UI::find_template('show_gather_art.inc.php');
|
||||||
flush();
|
flush();
|
||||||
|
}
|
||||||
|
$this->gather_art($this->added_songs_to_gather, $this->added_videos_to_gather);
|
||||||
}
|
}
|
||||||
$this->gather_art($this->added_songs_to_gather, $this->added_videos_to_gather);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the Catalog last_update */
|
/* Update the Catalog last_update */
|
||||||
|
@ -755,6 +760,19 @@ class Catalog_local extends Catalog
|
||||||
return $id;
|
return $id;
|
||||||
} // insert_local_video
|
} // insert_local_video
|
||||||
|
|
||||||
|
private function sync_podcasts()
|
||||||
|
{
|
||||||
|
$podcasts = $this->get_podcasts();
|
||||||
|
foreach ($podcasts as $podcast) {
|
||||||
|
$episodes = $podcast->get_episodes('pending');
|
||||||
|
foreach ($episodes as $episode_id) {
|
||||||
|
$episode = new Podcast_Episode($episode_id);
|
||||||
|
$episode->gather();
|
||||||
|
$this->count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check_local_mp3
|
* check_local_mp3
|
||||||
* Checks the song to see if it's there already returns true if found, false if not
|
* Checks the song to see if it's there already returns true if found, false if not
|
||||||
|
|
|
@ -320,7 +320,7 @@ http://www.consulenza-web.com/2012/01/mediatable-jquery-plugin/
|
||||||
$.fn.mediaTable = function() {
|
$.fn.mediaTable = function() {
|
||||||
|
|
||||||
var cfg = false;
|
var cfg = false;
|
||||||
var hasMenu = !$(this).hasClass('disablegv');
|
var hasMenu = (!$(this).hasClass('disablegv') && ($(this).attr('data-objecttype') !== undefined));
|
||||||
|
|
||||||
// Default configuration block
|
// Default configuration block
|
||||||
if ( !arguments.length || $.isPlainObject(arguments[0]) ) cfg = $.extend({},{
|
if ( !arguments.length || $.isPlainObject(arguments[0]) ) cfg = $.extend({},{
|
||||||
|
|
|
@ -283,18 +283,19 @@ if ($type == 'song') {
|
||||||
/* Base Checks passed create the song object */
|
/* Base Checks passed create the song object */
|
||||||
$media = new Song($oid);
|
$media = new Song($oid);
|
||||||
$media->format();
|
$media->format();
|
||||||
|
} elseif ($type == 'song_preview') {
|
||||||
|
$media = new Song_Preview($oid);
|
||||||
|
$media->format();
|
||||||
|
} elseif ($type == 'podcast_episode') {
|
||||||
|
$media = new Podcast_Episode($oid);
|
||||||
|
$media->format();
|
||||||
} else {
|
} else {
|
||||||
if ($type == 'song_preview') {
|
$type = 'video';
|
||||||
$media = new Song_Preview($oid);
|
$media = new Video($oid);
|
||||||
$media->format();
|
if (isset($_REQUEST['subtitle'])) {
|
||||||
} else {
|
$subtitle = $media->get_subtitle_file($_REQUEST['subtitle']);
|
||||||
$type = 'video';
|
|
||||||
$media = new Video($oid);
|
|
||||||
if (isset($_REQUEST['subtitle'])) {
|
|
||||||
$subtitle = $media->get_subtitle_file($_REQUEST['subtitle']);
|
|
||||||
}
|
|
||||||
$media->format();
|
|
||||||
}
|
}
|
||||||
|
$media->format();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!User::stream_control(array(array('object_type' => $type, 'object_id' => $media->id)))) {
|
if (!User::stream_control(array(array('object_type' => $type, 'object_id' => $media->id)))) {
|
||||||
|
@ -308,7 +309,7 @@ if ($media->catalog) {
|
||||||
$catalog = Catalog::create_from_id($media->catalog);
|
$catalog = Catalog::create_from_id($media->catalog);
|
||||||
|
|
||||||
/* If the media is disabled */
|
/* If the media is disabled */
|
||||||
if (!make_bool($media->enabled)) {
|
if (isset($media->enabled) && !make_bool($media->enabled)) {
|
||||||
debug_event('Play', "Error: $media->file is currently disabled, song skipped", '5');
|
debug_event('Play', "Error: $media->file is currently disabled, song skipped", '5');
|
||||||
// Check to see if this is a democratic playlist, if so remove it completely
|
// Check to see if this is a democratic playlist, if so remove it completely
|
||||||
if ($demo_id && isset($democratic)) {
|
if ($demo_id && isset($democratic)) {
|
||||||
|
|
105
podcast.php
Normal file
105
podcast.php
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
<?php
|
||||||
|
/* vim:set softtabstop=4 shiftwidth=4 expandtab: */
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* LICENSE: GNU Affero General Public License, version 3 (AGPLv3)
|
||||||
|
* Copyright 2001 - 2015 Ampache.org
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once 'lib/init.php';
|
||||||
|
|
||||||
|
if (!AmpConfig::get('podcast')) {
|
||||||
|
UI::access_denied();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
UI::show_header();
|
||||||
|
|
||||||
|
// Switch on Action
|
||||||
|
switch ($_REQUEST['action']) {
|
||||||
|
case 'show_create':
|
||||||
|
if (!Access::check('interface', 75)) {
|
||||||
|
UI::access_denied();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once AmpConfig::get('prefix') . UI::find_template('show_add_podcast.inc.php');
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'create':
|
||||||
|
if (!Access::check('interface', 75) || AmpConfig::get('demo_mode')) {
|
||||||
|
UI::access_denied();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Core::form_verify('add_podcast','post')) {
|
||||||
|
UI::access_denied();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to create the sucker
|
||||||
|
$results = Podcast::create($_POST);
|
||||||
|
|
||||||
|
if (!$results) {
|
||||||
|
require_once AmpConfig::get('prefix') . UI::find_template('show_add_podcast.inc.php');
|
||||||
|
} else {
|
||||||
|
$title = T_('Subscribed to Podcast');
|
||||||
|
$body = '';
|
||||||
|
show_confirmation($title,$body,AmpConfig::get('web_path') . '/browse.php?action=podcast');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
if (!Access::check('interface', 75) || AmpConfig::get('demo_mode')) {
|
||||||
|
UI::access_denied();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$podcast_id = scrub_in($_REQUEST['podcast_id']);
|
||||||
|
show_confirmation(
|
||||||
|
T_('Podcast Deletion'),
|
||||||
|
T_('Are you sure you want to delete this podcast?'),
|
||||||
|
AmpConfig::get('web_path') . "/podcast.php?action=confirm_delete&podcast_id=" . $podcast_id,
|
||||||
|
1,
|
||||||
|
'delete_podcast'
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'confirm_delete':
|
||||||
|
if (!Access::check('interface', 75) || AmpConfig::get('demo_mode')) {
|
||||||
|
UI::access_denied();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$podcast = new Podcast($_REQUEST['podcast_id']);
|
||||||
|
if ($podcast->remove()) {
|
||||||
|
show_confirmation(T_('Podcast Deletion'), T_('Podcast has been deleted.'), AmpConfig::get('web_path') . '/browse.php?action=podcast');
|
||||||
|
} else {
|
||||||
|
show_confirmation(T_('Podcast Deletion'), T_('Cannot delete this podcast.'), AmpConfig::get('web_path') . '/browse.php?action=podcast');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'show':
|
||||||
|
$podcast_id = intval($_REQUEST['podcast']);
|
||||||
|
if ($podcast_id > 0) {
|
||||||
|
$podcast = new Podcast($podcast_id);
|
||||||
|
$podcast->format();
|
||||||
|
$object_ids = $podcast->get_episodes();
|
||||||
|
$object_type = 'podcast_episode';
|
||||||
|
require_once AmpConfig::get('prefix') . UI::find_template('show_podcast.inc.php');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} // end data collection
|
||||||
|
|
||||||
|
UI::show_footer();
|
68
podcast_episode.php
Normal file
68
podcast_episode.php
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
<?php
|
||||||
|
/* vim:set softtabstop=4 shiftwidth=4 expandtab: */
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* LICENSE: GNU Affero General Public License, version 3 (AGPLv3)
|
||||||
|
* Copyright 2001 - 2015 Ampache.org
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once 'lib/init.php';
|
||||||
|
|
||||||
|
UI::show_header();
|
||||||
|
|
||||||
|
switch ($_REQUEST['action']) {
|
||||||
|
case 'delete':
|
||||||
|
if (AmpConfig::get('demo_mode')) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$episode_id = scrub_in($_REQUEST['podcast_episode_id']);
|
||||||
|
show_confirmation(
|
||||||
|
T_('Podcast Episode Deletion'),
|
||||||
|
T_('Are you sure you want to permanently delete this episode?'),
|
||||||
|
AmpConfig::get('web_path') . "/podcast_episode.php?action=confirm_delete&podcast_episode_id=" . $episode_id,
|
||||||
|
1,
|
||||||
|
'delete_podcast_episode'
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'confirm_delete':
|
||||||
|
if (AmpConfig::get('demo_mode')) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$episode = new Podcast_Episode($_REQUEST['podcast_episode_id']);
|
||||||
|
if (!Catalog::can_remove($episode)) {
|
||||||
|
debug_event('video', 'Unauthorized to remove the episode `.' . $episode->id . '`.', 1);
|
||||||
|
UI::access_denied();
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($episode->remove()) {
|
||||||
|
show_confirmation(T_('Podcast Episode Deletion'), T_('Episode has been deleted.'), AmpConfig::get('web_path'));
|
||||||
|
} else {
|
||||||
|
show_confirmation(T_('Podcast Episode Deletion'), T_('Cannot delete this episode.'), AmpConfig::get('web_path'));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'show':
|
||||||
|
default:
|
||||||
|
$episode = new Podcast_Episode($_REQUEST['podcast_episode']);
|
||||||
|
$episode->format();
|
||||||
|
require_once AmpConfig::get('prefix') . UI::find_template('show_podcast_episode.inc.php');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
UI::show_footer();
|
|
@ -77,6 +77,9 @@ switch ($page) {
|
||||||
case 'user':
|
case 'user':
|
||||||
require_once AmpConfig::get('prefix') . '/server/user.ajax.php';
|
require_once AmpConfig::get('prefix') . '/server/user.ajax.php';
|
||||||
exit;
|
exit;
|
||||||
|
case 'podcast':
|
||||||
|
require_once AmpConfig::get('prefix') . '/server/podcast.ajax.php';
|
||||||
|
exit;
|
||||||
default:
|
default:
|
||||||
// A taste of compatibility
|
// A taste of compatibility
|
||||||
break;
|
break;
|
||||||
|
|
52
server/podcast.ajax.php
Normal file
52
server/podcast.ajax.php
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
<?php
|
||||||
|
/* vim:set softtabstop=4 shiftwidth=4 expandtab: */
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* LICENSE: GNU Affero General Public License, version 3 (AGPLv3)
|
||||||
|
* Copyright 2001 - 2015 Ampache.org
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sub-Ajax page, requires AJAX_INCLUDE
|
||||||
|
*/
|
||||||
|
if (!defined('AJAX_INCLUDE')) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($_REQUEST['action']) {
|
||||||
|
case 'sync':
|
||||||
|
if (!Access::check('interface','75')) {
|
||||||
|
debug_event('DENIED', $GLOBALS['user']->username . ' attempted to sync podcast', '1');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($_REQUEST['podcast_id'])) {
|
||||||
|
$podcast = new Podcast($_REQUEST['podcast_id']);
|
||||||
|
$podcast->sync_episodes(true);
|
||||||
|
} elseif (isset($_REQUEST['podcast_episode_id'])) {
|
||||||
|
$episode = new Podcast_Episode($_REQUEST['podcast_episode_id']);
|
||||||
|
$episode->gather();
|
||||||
|
}
|
||||||
|
$results['rfc3514'] = '0x1';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$results['rfc3514'] = '0x1';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We always do this
|
||||||
|
echo xoutput_from_array($results);
|
|
@ -1315,7 +1315,7 @@ CREATE TABLE IF NOT EXISTS `video` (
|
||||||
`addition_time` int(11) unsigned NOT NULL,
|
`addition_time` int(11) unsigned NOT NULL,
|
||||||
`update_time` int(11) unsigned DEFAULT NULL,
|
`update_time` int(11) unsigned DEFAULT NULL,
|
||||||
`enabled` tinyint(1) NOT NULL DEFAULT '1',
|
`enabled` tinyint(1) NOT NULL DEFAULT '1',
|
||||||
`played` tinyint(1) unsigned NOT NULL DEFAULT '1',
|
`played` tinyint(1) unsigned NOT NULL DEFAULT '0',
|
||||||
`release_date` int(11) DEFAULT NULL,
|
`release_date` int(11) DEFAULT NULL,
|
||||||
`channels` mediumint(9) DEFAULT NULL,
|
`channels` mediumint(9) DEFAULT NULL,
|
||||||
`bitrate` mediumint(8) DEFAULT NULL,
|
`bitrate` mediumint(8) DEFAULT NULL,
|
||||||
|
|
11
stream.php
11
stream.php
|
@ -129,13 +129,16 @@ switch ($_REQUEST['action']) {
|
||||||
'object_type' => 'song',
|
'object_type' => 'song',
|
||||||
'object_id' => scrub_in($_REQUEST['song_id'])
|
'object_id' => scrub_in($_REQUEST['song_id'])
|
||||||
);
|
);
|
||||||
} else {
|
} elseif (isset($_REQUEST['video_id'])) {
|
||||||
if (isset($_REQUEST['video_id'])) {
|
$media_ids[] = array(
|
||||||
$media_ids[] = array(
|
|
||||||
'object_type' => 'video',
|
'object_type' => 'video',
|
||||||
'object_id' => scrub_in($_REQUEST['video_id'])
|
'object_id' => scrub_in($_REQUEST['video_id'])
|
||||||
);
|
);
|
||||||
}
|
} elseif (isset($_REQUEST['podcast_episode_id'])) {
|
||||||
|
$media_ids[] = array(
|
||||||
|
'object_type' => 'podcast_episode',
|
||||||
|
'object_id' => scrub_in($_REQUEST['podcast_episode_id'])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -82,7 +82,15 @@ $default_sort = "%a/%A";
|
||||||
?></option>
|
?></option>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
} ?>
|
}
|
||||||
|
if (AmpConfig::get('podcast')) {
|
||||||
|
?>
|
||||||
|
<option value="podcast"><?php echo T_('Podcast');
|
||||||
|
?></option>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
46
templates/show_add_podcast.inc.php
Normal file
46
templates/show_add_podcast.inc.php
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
/* vim:set softtabstop=4 shiftwidth=4 expandtab: */
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* LICENSE: GNU Affero General Public License, version 3 (AGPLv3)
|
||||||
|
* Copyright 2001 - 2015 Ampache.org
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
?>
|
||||||
|
<?php UI::show_box_top(T_('Subscribe to Podcast'), 'box box_add_podcast'); ?>
|
||||||
|
<form name="share" method="post" action="<?php echo AmpConfig::get('web_path'); ?>/podcast.php?action=create">
|
||||||
|
<table class="tabledata" cellspacing="0" cellpadding="0">
|
||||||
|
<tr>
|
||||||
|
<td><?php echo T_('Podcast feed url'); ?></td>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="feed" value="<?php echo scrub_out($_REQUEST['feed']) ?: 'http://'; ?>" />
|
||||||
|
<?php AmpError::display('feed'); ?>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><?php echo T_('Catalog'); ?></td>
|
||||||
|
<td>
|
||||||
|
<?php show_catalog_select('catalog', scrub_out($_REQUEST['catalog']), '', false, 'podcast'); ?>
|
||||||
|
<?php AmpError::display('catalog'); ?>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<div class="formValidation">
|
||||||
|
<?php echo Core::form_register('add_podcast'); ?>
|
||||||
|
<input class="button" type="submit" value="<?php echo T_('Subscribe'); ?>" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<?php UI::show_box_bottom(); ?>
|
54
templates/show_edit_podcast_episode_row.inc.php
Normal file
54
templates/show_edit_podcast_episode_row.inc.php
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?php
|
||||||
|
/* vim:set softtabstop=4 shiftwidth=4 expandtab: */
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* LICENSE: GNU Affero General Public License, version 3 (AGPLv3)
|
||||||
|
* Copyright 2001 - 2015 Ampache.org
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
?>
|
||||||
|
<div>
|
||||||
|
<form method="post" id="edit_podcast_episode_<?php echo $libitem->id; ?>" class="edit_dialog_content">
|
||||||
|
<table class="tabledata" cellspacing="0" cellpadding="0">
|
||||||
|
<tr>
|
||||||
|
<td class="edit_dialog_content_header"><?php echo T_('Title') ?></td>
|
||||||
|
<td><input type="text" name="title" value="<?php echo scrub_out($libitem->title); ?>" autofocus /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="edit_dialog_content_header"><?php echo T_('Description') ?></td>
|
||||||
|
<td><textarea name="description" cols="44" rows="4"><?php echo scrub_out($libitem->description); ?></textarea></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="edit_dialog_content_header"><?php echo T_('GUID') ?></td>
|
||||||
|
<td><input type="text" name="guid" value="<?php echo scrub_out($libitem->guid); ?>" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="edit_dialog_content_header"><?php echo T_('Author') ?></td>
|
||||||
|
<td><input type="text" name="author" value="<?php echo scrub_out($libitem->author); ?>" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="edit_dialog_content_header"><?php echo T_('Category') ?></td>
|
||||||
|
<td><input type="text" name="category" value="<?php echo scrub_out($libitem->category); ?>" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="edit_dialog_content_header"><?php echo T_('Website') ?></td>
|
||||||
|
<td><input type="text" name="website" value="<?php echo scrub_out($libitem->website); ?>" /></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<input type="hidden" name="id" value="<?php echo $libitem->id; ?>" />
|
||||||
|
<input type="hidden" name="type" value="podcast_episode_row" />
|
||||||
|
</form>
|
||||||
|
</div>
|
54
templates/show_edit_podcast_row.inc.php
Normal file
54
templates/show_edit_podcast_row.inc.php
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?php
|
||||||
|
/* vim:set softtabstop=4 shiftwidth=4 expandtab: */
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* LICENSE: GNU Affero General Public License, version 3 (AGPLv3)
|
||||||
|
* Copyright 2001 - 2015 Ampache.org
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
?>
|
||||||
|
<div>
|
||||||
|
<form method="post" id="edit_podcast_<?php echo $libitem->id; ?>" class="edit_dialog_content">
|
||||||
|
<table class="tabledata" cellspacing="0" cellpadding="0">
|
||||||
|
<tr>
|
||||||
|
<td class="edit_dialog_content_header"><?php echo T_('Feed') ?></td>
|
||||||
|
<td><input type="text" name="feed" value="<?php echo scrub_out($libitem->feed); ?>" autofocus /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="edit_dialog_content_header"><?php echo T_('Title') ?></td>
|
||||||
|
<td><input type="text" name="title" value="<?php echo scrub_out($libitem->title); ?>" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="edit_dialog_content_header"><?php echo T_('Description') ?></td>
|
||||||
|
<td><textarea name="description" cols="44" rows="4"><?php echo scrub_out($libitem->description); ?></textarea></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="edit_dialog_content_header"><?php echo T_('Language') ?></td>
|
||||||
|
<td><input type="text" name="language" value="<?php echo scrub_out($libitem->language); ?>" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="edit_dialog_content_header"><?php echo T_('Copyright') ?></td>
|
||||||
|
<td><input type="text" name="copyright" value="<?php echo scrub_out($libitem->copyright); ?>" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="edit_dialog_content_header"><?php echo T_('Website') ?></td>
|
||||||
|
<td><input type="text" name="website" value="<?php echo scrub_out($libitem->website); ?>" /></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<input type="hidden" name="id" value="<?php echo $libitem->id; ?>" />
|
||||||
|
<input type="hidden" name="type" value="podcast_row" />
|
||||||
|
</form>
|
||||||
|
</div>
|
|
@ -156,8 +156,8 @@ if (!$isVideo && !$isRadio && !$is_share) {
|
||||||
echo "ajaxPut(jsAjaxUrl + '?page=song&action=shouts&object_type=song&object_id=' + currenti.attr('data-media_id'),'shouts_data');";
|
echo "ajaxPut(jsAjaxUrl + '?page=song&action=shouts&object_type=song&object_id=' + currenti.attr('data-media_id'),'shouts_data');";
|
||||||
}
|
}
|
||||||
echo "ajaxPut(jsAjaxUrl + '?action=action_buttons&object_type=song&object_id=' + currenti.attr('data-media_id'));";
|
echo "ajaxPut(jsAjaxUrl + '?action=action_buttons&object_type=song&object_id=' + currenti.attr('data-media_id'));";
|
||||||
echo "var titleobj = (currenti.attr('data-album_id') != null) ? '<a href=\"javascript:NavigateTo(\'" . AmpConfig::get('web_path') . "/albums.php?action=show&album=' + currenti.attr('data-album_id') + '\');\" title=\"' + obj.title + '\">' + obj.title + '</a>' : obj.title;";
|
echo "var titleobj = (currenti.attr('data-album_id') !== 'undefined') ? '<a href=\"javascript:NavigateTo(\'" . AmpConfig::get('web_path') . "/albums.php?action=show&album=' + currenti.attr('data-album_id') + '\');\" title=\"' + obj.title + '\">' + obj.title + '</a>' : obj.title;";
|
||||||
echo "var artistobj = '<a href=\"javascript:NavigateTo(\'" . AmpConfig::get('web_path') . "/artists.php?action=show&artist=' + currenti.attr('data-artist_id') + '\');\" title=\"' + obj.artist + '\">' + obj.artist + '</a>';";
|
echo "var artistobj = (currenti.attr('data-artist_id') !== 'undefined') ?'<a href=\"javascript:NavigateTo(\'" . AmpConfig::get('web_path') . "/artists.php?action=show&artist=' + currenti.attr('data-artist_id') + '\');\" title=\"' + obj.artist + '\">' + obj.artist + '</a>' : obj.artist;";
|
||||||
echo "var lyricsobj = '<a href=\"javascript:NavigateTo(\'" . AmpConfig::get('web_path') . "/song.php?action=show_lyrics&song_id=' + currenti.attr('data-media_id') + '\');\">" . T_('Show Lyrics') . "</a>';";
|
echo "var lyricsobj = '<a href=\"javascript:NavigateTo(\'" . AmpConfig::get('web_path') . "/song.php?action=show_lyrics&song_id=' + currenti.attr('data-media_id') + '\');\">" . T_('Show Lyrics') . "</a>';";
|
||||||
echo "var actionsobj = '|';";
|
echo "var actionsobj = '|';";
|
||||||
if (AmpConfig::get('sociable') && (!AmpConfig::get('use_auth') || Access::check('interface','25'))) {
|
if (AmpConfig::get('sociable') && (!AmpConfig::get('use_auth') || Access::check('interface','25'))) {
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$web_path = AmpConfig::get('web_path');
|
|
||||||
?>
|
?>
|
||||||
<?php if ($browse->get_show_header()) {
|
<?php if ($browse->get_show_header()) {
|
||||||
require AmpConfig::get('prefix') . UI::find_template('list_header.inc.php');
|
require AmpConfig::get('prefix') . UI::find_template('list_header.inc.php');
|
||||||
|
|
166
templates/show_podcast.inc.php
Normal file
166
templates/show_podcast.inc.php
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
<?php
|
||||||
|
/* vim:set softtabstop=4 shiftwidth=4 expandtab: */
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* LICENSE: GNU Affero General Public License, version 3 (AGPLv3)
|
||||||
|
* Copyright 2001 - 2015 Ampache.org
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
$browse = new Browse();
|
||||||
|
$browse->set_type($object_type);
|
||||||
|
|
||||||
|
UI::show_box_top($podcast->f_title, 'info-box');
|
||||||
|
?>
|
||||||
|
<div class="item_right_info">
|
||||||
|
<?php
|
||||||
|
$thumb = UI::is_grid_view('podcast') ? 2 : 11;
|
||||||
|
Art::display('podcast', $podcast->id, $podcast->f_title, $thumb);
|
||||||
|
?>
|
||||||
|
<?php if ($podcast->description) {
|
||||||
|
?>
|
||||||
|
<div id="item_summary">
|
||||||
|
<?php echo $podcast->description;
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
} ?>
|
||||||
|
</div>
|
||||||
|
<?php if (User::is_registered()) {
|
||||||
|
?>
|
||||||
|
<?php
|
||||||
|
if (AmpConfig::get('ratings')) {
|
||||||
|
?>
|
||||||
|
<div id="rating_<?php echo intval($podcast->id);
|
||||||
|
?>_podcast" style="display:inline;">
|
||||||
|
<?php show_rating($podcast->id, 'podcast');
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php if (AmpConfig::get('userflags')) {
|
||||||
|
?>
|
||||||
|
<div style="display:table-cell;" id="userflag_<?php echo $podcast->id;
|
||||||
|
?>_podcast">
|
||||||
|
<?php Userflag::show($podcast->id,'podcast');
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php
|
||||||
|
} ?>
|
||||||
|
<div id="information_actions">
|
||||||
|
<h3><?php echo T_('Actions'); ?>:</h3>
|
||||||
|
<ul>
|
||||||
|
<?php if (AmpConfig::get('directplay')) {
|
||||||
|
?>
|
||||||
|
<li>
|
||||||
|
<?php echo Ajax::button('?page=stream&action=directplay&object_type=podcast&object_id=' . $podcast->id,'play', T_('Play all'),'directplay_full_' . $podcast->id);
|
||||||
|
?>
|
||||||
|
<?php echo Ajax::text('?page=stream&action=directplay&object_type=podcast&object_id=' . $podcast->id, T_('Play all'),'directplay_full_text_' . $podcast->id);
|
||||||
|
?>
|
||||||
|
</li>
|
||||||
|
<?php
|
||||||
|
} ?>
|
||||||
|
<?php if (Stream_Playlist::check_autoplay_append()) {
|
||||||
|
?>
|
||||||
|
<li>
|
||||||
|
<?php echo Ajax::button('?page=stream&action=directplay&object_type=podcast&object_id=' . $podcast->id . '&append=true','play_add', T_('Play all last'),'addplay_podcast_' . $podcast->id);
|
||||||
|
?>
|
||||||
|
<?php echo Ajax::text('?page=stream&action=directplay&object_type=podcast&object_id=' . $podcast->id . '&append=true', T_('Play all last'),'addplay_podcast_text_' . $podcast->id);
|
||||||
|
?>
|
||||||
|
</li>
|
||||||
|
<?php
|
||||||
|
} ?>
|
||||||
|
<?php if (Access::check('interface','50')) {
|
||||||
|
?>
|
||||||
|
<?php if (AmpConfig::get('statistical_graphs')) {
|
||||||
|
?>
|
||||||
|
<li>
|
||||||
|
<a href="<?php echo AmpConfig::get('web_path');
|
||||||
|
?>/stats.php?action=graph&object_type=podcast&object_id=<?php echo $podcast->id;
|
||||||
|
?>"><?php echo UI::get_icon('statistics', T_('Graphs'));
|
||||||
|
?></a>
|
||||||
|
<a href="<?php echo AmpConfig::get('web_path');
|
||||||
|
?>/stats.php?action=graph&object_type=podcast&object_id=<?php echo $podcast->id;
|
||||||
|
?>"><?php echo T_('Graphs');
|
||||||
|
?></a>
|
||||||
|
</li>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php if (AmpConfig::get('use_rss')) {
|
||||||
|
?>
|
||||||
|
<li>
|
||||||
|
<?php echo Ampache_RSS::get_display('podcast', T_('Podcast'), array('object_type' => 'podcast', 'object_id' => $podcast->id));
|
||||||
|
?>
|
||||||
|
</li>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<li>
|
||||||
|
<a id="<?php echo 'edit_podcast_' . $podcast->id ?>" onclick="showEditDialog('podcast_row', '<?php echo $podcast->id ?>', '<?php echo 'edit_podcast_' . $podcast->id ?>', '<?php echo T_('Podcast edit') ?>', '')">
|
||||||
|
<?php echo UI::get_icon('edit', T_('Edit'));
|
||||||
|
?>
|
||||||
|
</a>
|
||||||
|
<a id="<?php echo 'edit_podcast_' . $podcast->id ?>" onclick="showEditDialog('podcast_row', '<?php echo $podcast->id ?>', '<?php echo 'edit_podcast_' . $podcast->id ?>', '<?php echo T_('Podcast edit') ?>', '')">
|
||||||
|
<?php echo T_('Edit Podcast');
|
||||||
|
?>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<?php echo Ajax::button('?page=podcast&action=sync&podcast_id=' . $libitem->id, 'file_refresh', T_('Sync'),'sync_podcast_' . $podcast->id);
|
||||||
|
?>
|
||||||
|
<?php echo Ajax::text('?page=podcast&action=sync&podcast_id=' . $libitem->id, T_('Sync'),'sync_podcast_text_' . $podcast->id);
|
||||||
|
?>
|
||||||
|
</li>
|
||||||
|
<?php
|
||||||
|
} ?>
|
||||||
|
<?php if (Access::check('interface','75')) {
|
||||||
|
?>
|
||||||
|
<li>
|
||||||
|
<a id="<?php echo 'delete_podcast_' . $podcast->id ?>" href="<?php echo AmpConfig::get('web_path');
|
||||||
|
?>/podcast.php?action=delete&podcast_id=<?php echo $podcast->id;
|
||||||
|
?>">
|
||||||
|
<?php echo UI::get_icon('delete', T_('Delete'));
|
||||||
|
?> <?php echo T_('Delete');
|
||||||
|
?>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<?php
|
||||||
|
} ?>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<?php UI::show_box_bottom(); ?>
|
||||||
|
<div class="tabs_wrapper">
|
||||||
|
<div id="tabs_container">
|
||||||
|
<ul id="tabs">
|
||||||
|
<li class="tab_active"><a href="#episodes"><?php echo T_('Episodes'); ?></a></li>
|
||||||
|
<!-- Needed to avoid the 'only one' bug -->
|
||||||
|
<li></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div id="tabs_content">
|
||||||
|
<div id="episodes" class="tab_content" style="display: block;">
|
||||||
|
<?php
|
||||||
|
$browse->show_objects($object_ids, true);
|
||||||
|
$browse->store();
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
197
templates/show_podcast_episode.inc.php
Normal file
197
templates/show_podcast_episode.inc.php
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
<?php
|
||||||
|
/* vim:set softtabstop=4 shiftwidth=4 expandtab: */
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* LICENSE: GNU Affero General Public License, version 3 (AGPLv3)
|
||||||
|
* Copyright 2001 - 2015 Ampache.org
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
?>
|
||||||
|
<?php UI::show_box_top($episode->f_title . ' - ' . $episode->f_podcast_link, 'box box_podcast_episode_details'); ?>
|
||||||
|
<dl class="media_details">
|
||||||
|
|
||||||
|
<?php if (User::is_registered()) {
|
||||||
|
?>
|
||||||
|
<?php if (AmpConfig::get('ratings')) {
|
||||||
|
?>
|
||||||
|
<?php $rowparity = UI::flip_class();
|
||||||
|
?>
|
||||||
|
<dt class="<?php echo $rowparity;
|
||||||
|
?>"><?php echo T_('Rating');
|
||||||
|
?></dt>
|
||||||
|
<dd class="<?php echo $rowparity;
|
||||||
|
?>">
|
||||||
|
<div id="rating_<?php echo $episode->id;
|
||||||
|
?>_podcast_episode"><?php Rating::show($episode->id,'podcast_episode');
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</dd>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<?php if (AmpConfig::get('userflags')) {
|
||||||
|
?>
|
||||||
|
<?php $rowparity = UI::flip_class();
|
||||||
|
?>
|
||||||
|
<dt class="<?php echo $rowparity;
|
||||||
|
?>"><?php echo T_('Fav.');
|
||||||
|
?></dt>
|
||||||
|
<dd class="<?php echo $rowparity;
|
||||||
|
?>">
|
||||||
|
<div id="userflag_<?php echo $episode->id;
|
||||||
|
?>_podcast_episode"><?php Userflag::show($episode->id,'podcast_episode');
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</dd>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
} ?>
|
||||||
|
<?php $rowparity = UI::flip_class(); ?>
|
||||||
|
<dt class="<?php echo $rowparity; ?>"><?php echo T_('Action'); ?></dt>
|
||||||
|
<dd class="<?php echo $rowparity; ?>">
|
||||||
|
<?php if (!empty($episode->file)) {
|
||||||
|
?>
|
||||||
|
<?php if (AmpConfig::get('directplay')) {
|
||||||
|
?>
|
||||||
|
<?php echo Ajax::button('?page=stream&action=directplay&object_type=podcast_episode&object_id=' . $episode->id, 'play', T_('Play'),'play_podcast_episode_' . $episode->id);
|
||||||
|
?>
|
||||||
|
<?php if (Stream_Playlist::check_autoplay_append()) {
|
||||||
|
?>
|
||||||
|
<?php echo Ajax::button('?page=stream&action=directplay&object_type=podcast_episode&object_id=' . $episode->id . '&append=true','play_add', T_('Play last'),'addplay_podcast_episode_' . $episode->id);
|
||||||
|
?>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php if (Stream_Playlist::check_autoplay_next()) {
|
||||||
|
?>
|
||||||
|
<?php echo Ajax::button('?page=stream&action=directplay&object_type=podcast_episode&object_id=' . $episode->id . '&playnext=true','play_next', T_('Play next'),'nextplay_podcast_episode_' . $episode->id);
|
||||||
|
?>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php
|
||||||
|
} ?>
|
||||||
|
<?php if (!AmpConfig::get('use_auth') || Access::check('interface','25')) {
|
||||||
|
?>
|
||||||
|
<?php if (AmpConfig::get('sociable')) {
|
||||||
|
?>
|
||||||
|
<a href="<?php echo AmpConfig::get('web_path');
|
||||||
|
?>/shout.php?action=show_add_shout&type=podcast_episode&id=<?php echo $episode->id;
|
||||||
|
?>">
|
||||||
|
<?php echo UI::get_icon('comment', T_('Post Shout'));
|
||||||
|
?>
|
||||||
|
</a>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php if (Access::check('interface','25')) {
|
||||||
|
?>
|
||||||
|
<?php if (AmpConfig::get('share')) {
|
||||||
|
?>
|
||||||
|
<?php Share::display_ui('podcast_episode', $episode->id, false);
|
||||||
|
?>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
} ?>
|
||||||
|
<?php if (Access::check_function('download') && !empty($episode->file)) {
|
||||||
|
?>
|
||||||
|
<a rel="nohtml" href="<?php echo Podcast_Episode::play_url($episode->id);
|
||||||
|
?>"><?php echo UI::get_icon('link', T_('Link'));
|
||||||
|
?></a>
|
||||||
|
<a rel="nohtml" href="<?php echo AmpConfig::get('web_path');
|
||||||
|
?>/stream.php?action=download&podcast_episode_id=<?php echo $episode->id;
|
||||||
|
?>"><?php echo UI::get_icon('download', T_('Download'));
|
||||||
|
?></a>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
} ?>
|
||||||
|
<?php if (Access::check('interface','50')) {
|
||||||
|
?>
|
||||||
|
<?php if (AmpConfig::get('statistical_graphs')) {
|
||||||
|
?>
|
||||||
|
<a href="<?php echo AmpConfig::get('web_path');
|
||||||
|
?>/stats.php?action=graph&object_type=podcast_episode&object_id=<?php echo $episode->id;
|
||||||
|
?>"><?php echo UI::get_icon('statistics', T_('Graphs'));
|
||||||
|
?></a>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<a onclick="showEditDialog('podcast_episode_row', '<?php echo $episode->id ?>', '<?php echo 'edit_podcast_episode_' . $episode->id ?>', '<?php echo T_('Edit') ?>', '')">
|
||||||
|
<?php echo UI::get_icon('edit', T_('Edit'));
|
||||||
|
?>
|
||||||
|
</a>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
} ?>
|
||||||
|
<?php if (Catalog::can_remove($episode)) {
|
||||||
|
?>
|
||||||
|
<a href="<?php echo AmpConfig::get('web_path');
|
||||||
|
?>/podcast_episode.php?action=delete&podcast_episode_id=<?php echo $episode->id;
|
||||||
|
?>">
|
||||||
|
<?php echo UI::get_icon('delete', T_('Delete'));
|
||||||
|
?>
|
||||||
|
</a>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
} ?>
|
||||||
|
</dd>
|
||||||
|
<?php
|
||||||
|
$songprops[gettext_noop('Title')] = $episode->f_title;
|
||||||
|
$songprops[gettext_noop('Description')] = $episode->f_description;
|
||||||
|
$songprops[gettext_noop('Category')] = $episode->f_category;
|
||||||
|
$songprops[gettext_noop('Author')] = $episode->f_author;
|
||||||
|
$songprops[gettext_noop('Publication Date')] = $episode->f_pubdate;
|
||||||
|
$songprops[gettext_noop('State')] = $episode->f_state;
|
||||||
|
$songprops[gettext_noop('Website')] = $episode->f_website;
|
||||||
|
if ($episode->time > 0) {
|
||||||
|
$songprops[gettext_noop('Length')] = $episode->f_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($episode->file)) {
|
||||||
|
$songprops[gettext_noop('File')] = $episode->file;
|
||||||
|
$songprops[gettext_noop('Size')] = $episode->f_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($songprops as $key => $value) {
|
||||||
|
if (trim($value)) {
|
||||||
|
$rowparity = UI::flip_class();
|
||||||
|
echo "<dt class=\"" . $rowparity . "\">" . T_($key) . "</dt><dd class=\"" . $rowparity . "\">" . $value . "</dd>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</dl>
|
||||||
|
<?php UI::show_box_bottom(); ?>
|
101
templates/show_podcast_episode_row.inc.php
Normal file
101
templates/show_podcast_episode_row.inc.php
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
<?php
|
||||||
|
/* vim:set softtabstop=4 shiftwidth=4 expandtab: */
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* LICENSE: GNU Affero General Public License, version 3 (AGPLv3)
|
||||||
|
* Copyright 2001 - 2015 Ampache.org
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
?>
|
||||||
|
<td class="cel_play">
|
||||||
|
<span class="cel_play_content"> </span>
|
||||||
|
<div class="cel_play_hover">
|
||||||
|
<?php
|
||||||
|
if (AmpConfig::get('directplay') && !empty($libitem->file)) {
|
||||||
|
echo Ajax::button('?page=stream&action=directplay&object_type=podcast_episode&object_id=' . $libitem->id,'play', T_('Play'),'play_podcast_episode_' . $libitem->id);
|
||||||
|
if (Stream_Playlist::check_autoplay_next()) {
|
||||||
|
echo Ajax::button('?page=stream&action=directplay&object_type=podcast_episode&object_id=' . $libitem->id . '&playnext=true', 'play_next', T_('Play next'), 'nextplay_podcast_episode_' . $libitem->id);
|
||||||
|
if (Stream_Playlist::check_autoplay_append()) {
|
||||||
|
echo Ajax::button('?page=stream&action=directplay&object_type=podcast_episode&object_id=' . $libitem->id . '&append=true', 'play_add', T_('Play last'), 'addplay_podcast_episode_' . $libitem->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td class="cel_title"><?php echo $libitem->f_link; ?></td>
|
||||||
|
<td class="cel_podcast"><?php echo $libitem->f_podcast_link; ?></td>
|
||||||
|
<td class="cel_time"><?php echo $libitem->f_time; ?></td>
|
||||||
|
<td class="cel_pubdate"><?php echo $libitem->f_pubdate; ?></td>
|
||||||
|
<td class="cel_state"><?php echo $libitem->f_state; ?></td>
|
||||||
|
<?php
|
||||||
|
if (User::is_registered()) {
|
||||||
|
if (AmpConfig::get('ratings')) {
|
||||||
|
?>
|
||||||
|
<td class="cel_rating" id="rating_<?php echo $libitem->id;
|
||||||
|
?>_podcast_episode">
|
||||||
|
<?php Rating::show($libitem->id,'podcast_episode');
|
||||||
|
?>
|
||||||
|
</td>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
if (AmpConfig::get('userflags')) {
|
||||||
|
?>
|
||||||
|
<td class="cel_userflag" id="userflag_<?php echo $libitem->id;
|
||||||
|
?>_podcast_episode">
|
||||||
|
<?php Userflag::show($libitem->id,'podcast_episode');
|
||||||
|
?>
|
||||||
|
</td>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<td class="cel_action">
|
||||||
|
<?php if (Access::check_function('download') && !empty($libitem->file)) {
|
||||||
|
?>
|
||||||
|
<a rel="nohtml" href="<?php echo AmpConfig::get('web_path');
|
||||||
|
?>/stream.php?action=download&podcast_episode_id=<?php echo $libitem->id;
|
||||||
|
?>"><?php echo UI::get_icon('download', T_('Download'));
|
||||||
|
?></a>
|
||||||
|
<?php
|
||||||
|
|
||||||
|
} ?>
|
||||||
|
<?php
|
||||||
|
if (Access::check('interface','50')) {
|
||||||
|
?>
|
||||||
|
<span id="button_sync_<?php echo $libitem->id;
|
||||||
|
?>">
|
||||||
|
<?php echo Ajax::button('?page=podcast&action=sync&podcast_episode_id=' . $libitem->id, 'file_refresh', T_('Sync'),'sync_podcast_episode_' . $libitem->id);
|
||||||
|
?>
|
||||||
|
</span>
|
||||||
|
<a id="<?php echo 'edit_podcast_episode_' . $libitem->id ?>" onclick="showEditDialog('podcast_episode_row', '<?php echo $libitem->id ?>', '<?php echo 'edit_podcast_episode_' . $libitem->id ?>', '<?php echo T_('Podcast Episode edit') ?>', 'podcast_episode_')">
|
||||||
|
<?php echo UI::get_icon('edit', T_('Edit'));
|
||||||
|
?>
|
||||||
|
</a>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
if (Catalog::can_remove($libitem)) {
|
||||||
|
?>
|
||||||
|
<a id="<?php echo 'delete_podcast_episode_' . $libitem->id ?>" href="<?php echo AmpConfig::get('web_path');
|
||||||
|
?>/podcast_episode.php?action=delete&podcast_episode_id=<?php echo $libitem->id;
|
||||||
|
?>">
|
||||||
|
<?php echo UI::get_icon('delete', T_('Delete'));
|
||||||
|
?>
|
||||||
|
</a>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</td>
|
130
templates/show_podcast_episodes.inc.php
Normal file
130
templates/show_podcast_episodes.inc.php
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
<?php
|
||||||
|
/* vim:set softtabstop=4 shiftwidth=4 expandtab: */
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* LICENSE: GNU Affero General Public License, version 3 (AGPLv3)
|
||||||
|
* Copyright 2001 - 2015 Ampache.org
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
$thcount = 7;
|
||||||
|
?>
|
||||||
|
<?php if ($browse->get_show_header()) {
|
||||||
|
require AmpConfig::get('prefix') . UI::find_template('list_header.inc.php');
|
||||||
|
} ?>
|
||||||
|
<table class="tabledata <?php echo $browse->get_css_class() ?>" cellpadding="0" cellspacing="0" data-objecttype="podcast_episode">
|
||||||
|
<thead>
|
||||||
|
<tr class="th-top">
|
||||||
|
<th class="cel_play essential"></th>
|
||||||
|
<th class="cel_title essential persist"><?php echo Ajax::text('?page=browse&action=set_sort&browse_id=' . $browse->id . '&sort=title', T_('Title'),'podcast_episode_sort_title'); ?></th>
|
||||||
|
<th class="cel_podcast optional"><?php echo T_('Podcast'); ?></th>
|
||||||
|
<th class="cel_time optional"><?php echo T_('Time'); ?></th>
|
||||||
|
<th class="cel_pubdate optional"><?php echo T_('Publication Date'); ?></th>
|
||||||
|
<th class="cel_state optional"><?php echo T_('State'); ?></th>
|
||||||
|
<?php if (User::is_registered()) {
|
||||||
|
?>
|
||||||
|
<?php if (AmpConfig::get('ratings')) {
|
||||||
|
++$thcount;
|
||||||
|
?>
|
||||||
|
<th class="cel_rating optional"><?php echo T_('Rating');
|
||||||
|
?></th>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php if (AmpConfig::get('userflags')) {
|
||||||
|
++$thcount;
|
||||||
|
?>
|
||||||
|
<th class="cel_userflag optional"><?php echo T_('Fav.');
|
||||||
|
?></th>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php
|
||||||
|
} ?>
|
||||||
|
<th class="cel_action essential"><?php echo T_('Actions'); ?></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php
|
||||||
|
if (AmpConfig::get('ratings')) {
|
||||||
|
Rating::build_cache('podcast_episode',$object_ids);
|
||||||
|
}
|
||||||
|
if (AmpConfig::get('userflags')) {
|
||||||
|
Userflag::build_cache('podcast_episode',$object_ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($object_ids as $episode_id) {
|
||||||
|
$libitem = new Podcast_Episode($episode_id);
|
||||||
|
$libitem->format();
|
||||||
|
?>
|
||||||
|
<tr id="podcast_episode_<?php echo $libitem->id;
|
||||||
|
?>" class="<?php echo UI::flip_class();
|
||||||
|
?>">
|
||||||
|
<?php require AmpConfig::get('prefix') . UI::find_template('show_podcast_episode_row.inc.php');
|
||||||
|
?>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
} ?>
|
||||||
|
<?php if (!count($object_ids)) {
|
||||||
|
?>
|
||||||
|
<tr class="<?php echo UI::flip_class();
|
||||||
|
?>">
|
||||||
|
<td colspan="<?php echo $thcount;
|
||||||
|
?>"><span class="nodata"><?php echo T_('No podcast episode found');
|
||||||
|
?></span></td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
} ?>
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr class="th-bottom">
|
||||||
|
<th class="cel_play"></th>
|
||||||
|
<?php if (Art::is_enabled()) {
|
||||||
|
?>
|
||||||
|
<th class="cel_cover"><?php echo T_('Art');
|
||||||
|
?></th>
|
||||||
|
<?php
|
||||||
|
} ?>
|
||||||
|
<th class="cel_title"><?php echo Ajax::text('?page=browse&action=set_sort&browse_id=' . $browse->id . '&sort=title', T_('Title'),'podcast_episode_sort_title_bottom'); ?></th>
|
||||||
|
<th class="cel_podcast"><?php echo T_('Podcast'); ?></th>
|
||||||
|
<th class="cel_time"><?php echo T_('Time'); ?></th>
|
||||||
|
<th class="cel_pubdate"><?php echo T_('Publication Date'); ?></th>
|
||||||
|
<th class="cel_state"><?php echo T_('State'); ?></th>
|
||||||
|
<?php if (User::is_registered()) {
|
||||||
|
?>
|
||||||
|
<?php if (AmpConfig::get('ratings')) {
|
||||||
|
?>
|
||||||
|
<th class="cel_rating"><?php echo T_('Rating');
|
||||||
|
?></th>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php if (AmpConfig::get('userflags')) {
|
||||||
|
?>
|
||||||
|
<th class="cel_userflag"><?php echo T_('Fav.');
|
||||||
|
?></th>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php
|
||||||
|
} ?>
|
||||||
|
<th class="cel_action"><?php echo T_('Actions'); ?></th>
|
||||||
|
</tr>
|
||||||
|
<tfoot>
|
||||||
|
</table>
|
||||||
|
<?php show_table_render(); ?>
|
||||||
|
<?php if ($browse->get_show_header()) {
|
||||||
|
require AmpConfig::get('prefix') . UI::find_template('list_header.inc.php');
|
||||||
|
} ?>
|
94
templates/show_podcast_row.inc.php
Normal file
94
templates/show_podcast_row.inc.php
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
<?php
|
||||||
|
/* vim:set softtabstop=4 shiftwidth=4 expandtab: */
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* LICENSE: GNU Affero General Public License, version 3 (AGPLv3)
|
||||||
|
* Copyright 2001 - 2015 Ampache.org
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
?>
|
||||||
|
<td class="cel_play">
|
||||||
|
<span class="cel_play_content"> </span>
|
||||||
|
<div class="cel_play_hover">
|
||||||
|
<?php
|
||||||
|
if (AmpConfig::get('directplay')) {
|
||||||
|
echo Ajax::button('?page=stream&action=directplay&object_type=podcast&object_id=' . $libitem->id,'play', T_('Play'),'play_podcast_' . $libitem->id);
|
||||||
|
if (Stream_Playlist::check_autoplay_append()) {
|
||||||
|
echo Ajax::button('?page=stream&action=directplay&object_type=podcast&object_id=' . $libitem->id . '&append=true','play_add', T_('Play last'),'addplay_podcast_' . $libitem->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<?php if (Art::is_enabled()) {
|
||||||
|
?>
|
||||||
|
<td class="cel_cover">
|
||||||
|
<?php Art::display('podcast', $libitem->id, $libitem->f_name, 2, $libitem->link);
|
||||||
|
?>
|
||||||
|
</td>
|
||||||
|
<?php
|
||||||
|
} ?>
|
||||||
|
<td class="cel_title"><?php echo $libitem->f_link; ?></td>
|
||||||
|
<td class="cel_episodes"><?php echo $libitem->episodes; ?></td>
|
||||||
|
<?php
|
||||||
|
if (User::is_registered()) {
|
||||||
|
if (AmpConfig::get('ratings')) {
|
||||||
|
?>
|
||||||
|
<td class="cel_rating" id="rating_<?php echo $libitem->id;
|
||||||
|
?>_podcast">
|
||||||
|
<?php Rating::show($libitem->id,'podcast');
|
||||||
|
?>
|
||||||
|
</td>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
if (AmpConfig::get('userflags')) {
|
||||||
|
?>
|
||||||
|
<td class="cel_userflag" id="userflag_<?php echo $libitem->id;
|
||||||
|
?>_podcast">
|
||||||
|
<?php Userflag::show($libitem->id,'podcast');
|
||||||
|
?>
|
||||||
|
</td>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<td class="cel_action">
|
||||||
|
<?php
|
||||||
|
if (Access::check('interface','50')) {
|
||||||
|
?>
|
||||||
|
<a id="<?php echo 'edit_podcast_' . $libitem->id ?>" onclick="showEditDialog('podcast_row', '<?php echo $libitem->id ?>', '<?php echo 'edit_podcast_' . $libitem->id ?>', '<?php echo T_('Podcast edit') ?>', 'podcast_')">
|
||||||
|
<?php echo UI::get_icon('edit', T_('Edit'));
|
||||||
|
?>
|
||||||
|
</a>
|
||||||
|
<span id="button_sync_<?php echo $libitem->id;
|
||||||
|
?>">
|
||||||
|
<?php echo Ajax::button('?page=podcast&action=sync&podcast_id=' . $libitem->id, 'file_refresh', T_('Sync'),'sync_podcast_' . $libitem->id);
|
||||||
|
?>
|
||||||
|
</span>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
if (Access::check('interface','75')) {
|
||||||
|
?>
|
||||||
|
<a id="<?php echo 'delete_podcast_' . $libitem->id ?>" href="<?php echo AmpConfig::get('web_path');
|
||||||
|
?>/podcast.php?action=delete&podcast_id=<?php echo $libitem->id;
|
||||||
|
?>">
|
||||||
|
<?php echo UI::get_icon('delete', T_('Delete'));
|
||||||
|
?>
|
||||||
|
</a>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</td>
|
145
templates/show_podcasts.inc.php
Normal file
145
templates/show_podcasts.inc.php
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
<?php
|
||||||
|
/* vim:set softtabstop=4 shiftwidth=4 expandtab: */
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* LICENSE: GNU Affero General Public License, version 3 (AGPLv3)
|
||||||
|
* Copyright 2001 - 2015 Ampache.org
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
$thcount = 5;
|
||||||
|
?>
|
||||||
|
<div id="information_actions">
|
||||||
|
<ul>
|
||||||
|
<?php if (Access::check('interface', 75)) {
|
||||||
|
?>
|
||||||
|
<li>
|
||||||
|
<a href="<?php echo AmpConfig::get('web_path');
|
||||||
|
?>/podcast.php?action=show_create"><?php echo UI::get_icon('add', T_('Add'));
|
||||||
|
?> <?php echo T_('Subscribe Podcast');
|
||||||
|
?></a>
|
||||||
|
</li>
|
||||||
|
<?php
|
||||||
|
} ?>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<?php if ($browse->get_show_header()) {
|
||||||
|
require AmpConfig::get('prefix') . UI::find_template('list_header.inc.php');
|
||||||
|
} ?>
|
||||||
|
<table class="tabledata <?php echo $browse->get_css_class() ?>" cellpadding="0" cellspacing="0" data-objecttype="podcast">
|
||||||
|
<thead>
|
||||||
|
<tr class="th-top">
|
||||||
|
<th class="cel_play essential"></th>
|
||||||
|
<?php if (Art::is_enabled()) {
|
||||||
|
++$thcount;
|
||||||
|
?>
|
||||||
|
<th class="cel_cover"><?php echo T_('Art');
|
||||||
|
?></th>
|
||||||
|
<?php
|
||||||
|
} ?>
|
||||||
|
<th class="cel_title essential persist"><?php echo Ajax::text('?page=browse&action=set_sort&browse_id=' . $browse->id . '&sort=title', T_('Title'),'podcast_sort_title'); ?></th>
|
||||||
|
<th class="cel_episodes optional"><?php echo T_('Episodes'); ?></th>
|
||||||
|
<?php if (User::is_registered()) {
|
||||||
|
?>
|
||||||
|
<?php if (AmpConfig::get('ratings')) {
|
||||||
|
++$thcount;
|
||||||
|
?>
|
||||||
|
<th class="cel_rating optional"><?php echo T_('Rating');
|
||||||
|
?></th>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php if (AmpConfig::get('userflags')) {
|
||||||
|
++$thcount;
|
||||||
|
?>
|
||||||
|
<th class="cel_userflag optional"><?php echo T_('Fav.');
|
||||||
|
?></th>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php
|
||||||
|
} ?>
|
||||||
|
<th class="cel_action essential"><?php echo T_('Actions'); ?></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php
|
||||||
|
if (AmpConfig::get('ratings')) {
|
||||||
|
Rating::build_cache('podcast',$object_ids);
|
||||||
|
}
|
||||||
|
if (AmpConfig::get('userflags')) {
|
||||||
|
Userflag::build_cache('podcast',$object_ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($object_ids as $podcast_id) {
|
||||||
|
$libitem = new Podcast($podcast_id);
|
||||||
|
$libitem->format();
|
||||||
|
?>
|
||||||
|
<tr id="podcast_<?php echo $libitem->id;
|
||||||
|
?>" class="<?php echo UI::flip_class();
|
||||||
|
?>">
|
||||||
|
<?php require AmpConfig::get('prefix') . UI::find_template('show_podcast_row.inc.php');
|
||||||
|
?>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
} ?>
|
||||||
|
<?php if (!count($object_ids)) {
|
||||||
|
?>
|
||||||
|
<tr class="<?php echo UI::flip_class();
|
||||||
|
?>">
|
||||||
|
<td colspan="<?php echo $thcount;
|
||||||
|
?>"><span class="nodata"><?php echo T_('No podcast found');
|
||||||
|
?></span></td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
} ?>
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr class="th-bottom">
|
||||||
|
<th class="cel_play"></th>
|
||||||
|
<?php if (Art::is_enabled()) {
|
||||||
|
?>
|
||||||
|
<th class="cel_cover"><?php echo T_('Art');
|
||||||
|
?></th>
|
||||||
|
<?php
|
||||||
|
} ?>
|
||||||
|
<th class="cel_title"><?php echo Ajax::text('?page=browse&action=set_sort&browse_id=' . $browse->id . '&sort=title', T_('Title'),'podcast_sort_title_bottom'); ?></th>
|
||||||
|
<th class="cel_episodes"><?php echo T_('Episodes'); ?></th>
|
||||||
|
<?php if (User::is_registered()) {
|
||||||
|
?>
|
||||||
|
<?php if (AmpConfig::get('ratings')) {
|
||||||
|
?>
|
||||||
|
<th class="cel_rating"><?php echo T_('Rating');
|
||||||
|
?></th>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php if (AmpConfig::get('userflags')) {
|
||||||
|
?>
|
||||||
|
<th class="cel_userflag"><?php echo T_('Fav.');
|
||||||
|
?></th>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<?php
|
||||||
|
} ?>
|
||||||
|
<th class="cel_action"><?php echo T_('Actions'); ?></th>
|
||||||
|
</tr>
|
||||||
|
<tfoot>
|
||||||
|
</table>
|
||||||
|
<?php show_table_render(); ?>
|
||||||
|
<?php if ($browse->get_show_header()) {
|
||||||
|
require AmpConfig::get('prefix') . UI::find_template('list_header.inc.php');
|
||||||
|
} ?>
|
|
@ -62,6 +62,13 @@
|
||||||
?>/browse.php?action=live_stream"><?php echo T_('Radio Stations');
|
?>/browse.php?action=live_stream"><?php echo T_('Radio Stations');
|
||||||
?></a></li>
|
?></a></li>
|
||||||
<?php
|
<?php
|
||||||
|
} ?>
|
||||||
|
<?php if (AmpConfig::get('podcast')) {
|
||||||
|
?>
|
||||||
|
<li id="sb_home_browse_music_podcast"><a href="<?php echo $web_path;
|
||||||
|
?>/browse.php?action=podcast"><?php echo T_('Podcasts');
|
||||||
|
?></a></li>
|
||||||
|
<?php
|
||||||
} ?>
|
} ?>
|
||||||
<?php if (AmpConfig::get('allow_upload') && Access::check('interface', '25')) {
|
<?php if (AmpConfig::get('allow_upload') && Access::check('interface', '25')) {
|
||||||
?>
|
?>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue