Merge branch 'cc-5709-airtime-analyzer' into cc-5709-airtime-analyzer-refactor

This commit is contained in:
Albert Santoni 2015-02-24 11:16:44 -05:00
commit 7600b8ae82
48 changed files with 236 additions and 8770 deletions

View File

@ -71,13 +71,28 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
} }
$view->headScript()->appendScript("var userType = '$userType';"); $view->headScript()->appendScript("var userType = '$userType';");
} }
/**
* Create a global namespace to hold a session token for CSRF prevention
*/
protected function _initCsrfNamespace() {
$csrf_namespace = new Zend_Session_Namespace('csrf_namespace');
// Check if the token exists
if (!$csrf_namespace->authtoken) {
// If we don't have a token, regenerate it and set a 2 hour timeout
// Should we log the user out here if the token is expired?
$csrf_namespace->authtoken = sha1(uniqid(rand(),1));
$csrf_namespace->setExpirationSeconds(2*60*60);
}
}
/** /**
* Ideally, globals should be written to a single js file once * Ideally, globals should be written to a single js file once
* from a php init function. This will save us from having to * from a php init function. This will save us from having to
* reinitialize them every request * reinitialize them every request
*/ */
private function _initTranslationGlobals($view) { protected function _initTranslationGlobals() {
$view = $this->getResource('view');
$view->headScript()->appendScript("var PRODUCT_NAME = '" . PRODUCT_NAME . "';"); $view->headScript()->appendScript("var PRODUCT_NAME = '" . PRODUCT_NAME . "';");
$view->headScript()->appendScript("var USER_MANUAL_URL = '" . USER_MANUAL_URL . "';"); $view->headScript()->appendScript("var USER_MANUAL_URL = '" . USER_MANUAL_URL . "';");
$view->headScript()->appendScript("var COMPANY_NAME = '" . COMPANY_NAME . "';"); $view->headScript()->appendScript("var COMPANY_NAME = '" . COMPANY_NAME . "';");

View File

@ -19,9 +19,9 @@ class FileDataHelper {
} }
if (array_key_exists("bpm", $data)) { if (array_key_exists("bpm", $data)) {
//Some BPM tags are silly and include the word "BPM". Let's strip that... //Some BPM tags are silly and include the word "BPM". Let's strip that...
$data["year"] = str_ireplace("BPM", "", $data["year"]); $data["bpm"] = str_ireplace("BPM", "", $data["bpm"]);
// This will convert floats to ints too. // This will convert floats to ints too.
$data["year"] = intval($data["year"]); $data["bpm"] = intval($data["bpm"]);
} }
} }

View File

@ -201,10 +201,14 @@ class AudiopreviewController extends Zend_Controller_Action
$elementMap['element_mp3'] = $track['item_id']; $elementMap['element_mp3'] = $track['item_id'];
} elseif (strtolower($mime) === 'audio/ogg') { } elseif (strtolower($mime) === 'audio/ogg') {
$elementMap['element_oga'] = $track['item_id']; $elementMap['element_oga'] = $track['item_id'];
} elseif (strtolower($mime) === 'audio/vorbis') {
$elementMap['element_oga'] = $track['item_id'];
} elseif (strtolower($mime) === 'audio/mp4') { } elseif (strtolower($mime) === 'audio/mp4') {
$elementMap['element_m4a'] = $track['item_id']; $elementMap['element_m4a'] = $track['item_id'];
} elseif (strtolower($mime) === 'audio/wav') { } elseif (strtolower($mime) === 'audio/wav') {
$elementMap['element_wav'] = $track['item_id']; $elementMap['element_wav'] = $track['item_id'];
} elseif (strtolower($mime) === 'audio/x-wav') {
$elementMap['element_wav'] = $track['item_id'];
} elseif (strtolower($mime) === 'audio/x-flac') { } elseif (strtolower($mime) === 'audio/x-flac') {
$elementMap['element_flac'] = $track['item_id']; $elementMap['element_flac'] = $track['item_id'];
} else { } else {
@ -286,10 +290,14 @@ class AudiopreviewController extends Zend_Controller_Action
$elementMap['element_mp3'] = $track['item_id']; $elementMap['element_mp3'] = $track['item_id'];
} elseif (strtolower($mime) === 'audio/ogg') { } elseif (strtolower($mime) === 'audio/ogg') {
$elementMap['element_oga'] = $track['item_id']; $elementMap['element_oga'] = $track['item_id'];
} elseif (strtolower($mime) === 'audio/vorbis') {
$elementMap['element_oga'] = $track['item_id'];
} elseif (strtolower($mime) === 'audio/mp4') { } elseif (strtolower($mime) === 'audio/mp4') {
$elementMap['element_m4a'] = $track['item_id']; $elementMap['element_m4a'] = $track['item_id'];
} elseif (strtolower($mime) === 'audio/wav') { } elseif (strtolower($mime) === 'audio/wav') {
$elementMap['element_wav'] = $track['item_id']; $elementMap['element_wav'] = $track['item_id'];
} elseif (strtolower($mime) === 'audio/x-wav') {
$elementMap['element_wav'] = $track['item_id'];
} elseif (strtolower($mime) === 'audio/x-flac') { } elseif (strtolower($mime) === 'audio/x-flac') {
$elementMap['element_flac'] = $track['item_id']; $elementMap['element_flac'] = $track['item_id'];
} else { } else {

View File

@ -98,6 +98,9 @@ class LoginController extends Zend_Controller_Action
{ {
$auth = Zend_Auth::getInstance(); $auth = Zend_Auth::getInstance();
$auth->clearIdentity(); $auth->clearIdentity();
// Unset all session variables relating to CSRF prevention on logout
$csrf_namespace = new Zend_Session_Namespace('csrf_namespace');
$csrf_namespace->unsetAll();
$this->_redirect('showbuilder/index'); $this->_redirect('showbuilder/index');
} }

View File

@ -31,9 +31,10 @@ class PluploadController extends Zend_Controller_Action
$this->view->quotaLimitReached = true; $this->view->quotaLimitReached = true;
} }
//Because uploads are done via AJAX (and we're not using Zend form for those), we manually add the CSRF
//token in here.
$csrf_namespace = new Zend_Session_Namespace('csrf_namespace'); $csrf_namespace = new Zend_Session_Namespace('csrf_namespace');
$csrf_namespace->setExpirationSeconds(5*60*60); //The CSRF token is generated in Bootstrap.php
$csrf_namespace->authtoken = sha1(uniqid(rand(),1));
$csrf_element = new Zend_Form_Element_Hidden('csrf'); $csrf_element = new Zend_Form_Element_Hidden('csrf');
$csrf_element->setValue($csrf_namespace->authtoken)->setRequired('true')->removeDecorator('HtmlTag')->removeDecorator('Label'); $csrf_element->setValue($csrf_namespace->authtoken)->setRequired('true')->removeDecorator('HtmlTag')->removeDecorator('Label');

View File

@ -136,7 +136,6 @@ class ScheduleController extends Zend_Controller_Action
$editable = $user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); $editable = $user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER));
$calendar_interval = Application_Model_Preference::GetCalendarTimeScale(); $calendar_interval = Application_Model_Preference::GetCalendarTimeScale();
Logging::info($calendar_interval);
if ($calendar_interval == "agendaDay") { if ($calendar_interval == "agendaDay") {
list($start, $end) = Application_Model_Show::getStartEndCurrentDayView(); list($start, $end) = Application_Model_Show::getStartEndCurrentDayView();
} else if ($calendar_interval == "agendaWeek") { } else if ($calendar_interval == "agendaWeek") {

View File

@ -283,6 +283,14 @@ class ShowbuilderController extends Zend_Controller_Action
$mediaItems = $request->getParam("mediaIds", array()); $mediaItems = $request->getParam("mediaIds", array());
$scheduledItems = $request->getParam("schedIds", array()); $scheduledItems = $request->getParam("schedIds", array());
$log_vars = array();
$log_vars["url"] = $_SERVER['HTTP_HOST'];
$log_vars["action"] = "showbuilder/schedule-add";
$log_vars["params"] = array();
$log_vars["params"]["media_items"] = $mediaItems;
$log_vars["params"]["scheduled_items"] = $scheduledItems;
Logging::info($log_vars);
try { try {
$scheduler = new Application_Model_Scheduler(); $scheduler = new Application_Model_Scheduler();
$scheduler->scheduleAfter($scheduledItems, $mediaItems); $scheduler->scheduleAfter($scheduledItems, $mediaItems);

View File

@ -148,17 +148,22 @@ class Zend_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract
} }
} }
} else { //We have a session/identity. } else { //We have a session/identity.
// If we have an identity and we're making a RESTful request, // If we have an identity and we're making a RESTful request,
// we need to check the CSRF token // we need to check the CSRF token
if ($request->_action != "get" && $request->getModuleName() == "rest") { if ($_SERVER['REQUEST_METHOD'] != "GET" && $request->getModuleName() == "rest") {
$tokenValid = $this->verifyCSRFToken($request->getParam("csrf_token")); $token = $request->getParam("csrf_token");
$tokenValid = $this->verifyCSRFToken($token);
if (!$tokenValid) { if (!$tokenValid) {
$csrf_namespace = new Zend_Session_Namespace('csrf_namespace');
$csrf_namespace->authtoken = sha1(openssl_random_pseudo_bytes(128));
Logging::warn("Invalid CSRF token: $token");
$this->getResponse() $this->getResponse()
->setHttpResponseCode(401) ->setHttpResponseCode(401)
->appendBody("ERROR: CSRF token mismatch."); ->appendBody("ERROR: CSRF token mismatch.")
return; ->sendResponse();
die();
} }
} }
@ -202,9 +207,7 @@ class Zend_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract
$current_namespace = new Zend_Session_Namespace('csrf_namespace'); $current_namespace = new Zend_Session_Namespace('csrf_namespace');
$observed_csrf_token = $token; $observed_csrf_token = $token;
$expected_csrf_token = $current_namespace->authtoken; $expected_csrf_token = $current_namespace->authtoken;
Logging::error("Observed: " . $observed_csrf_token);
Logging::error("Expected: " . $expected_csrf_token);
return ($observed_csrf_token == $expected_csrf_token); return ($observed_csrf_token == $expected_csrf_token);
} }

View File

@ -29,8 +29,8 @@ class Application_Form_LiveStreamingPreferences extends Zend_Form_SubForm
$transition_fade = new Zend_Form_Element_Text("transition_fade"); $transition_fade = new Zend_Form_Element_Text("transition_fade");
$transition_fade->setLabel(_("Switch Transition Fade (s)")) $transition_fade->setLabel(_("Switch Transition Fade (s)"))
->setFilters(array('StringTrim')) ->setFilters(array('StringTrim'))
->addValidator('regex', false, array('/^[0-9]{1,2}(\.\d{1,3})?$/', ->addValidator('regex', false, array('/^\d*(\.\d+)?$/',
'messages' => _('enter a time in seconds 0{.000}'))) 'messages' => _('Please enter a time in seconds (eg. 0.5)')))
->setValue($defaultFade) ->setValue($defaultFade)
->setDecorators(array('ViewHelper')); ->setDecorators(array('ViewHelper'));
$this->addElement($transition_fade); $this->addElement($transition_fade);

View File

@ -38,52 +38,50 @@ class Logging {
return $p_msg; return $p_msg;
} }
} }
/** @param debugMode Prints the function name, file, and line number. This is slow as it uses debug_backtrace()
* so don't use it unless you need it.
*/
private static function getLinePrefix($debugMode=false)
{
$linePrefix = "";
if (array_key_exists('SERVER_NAME', $_SERVER)) {
$linePrefix .= $_SERVER['SERVER_NAME'] . " ";
}
if ($debugMode) {
//debug_backtrace is SLOW so we don't want this invoke unless there was a real error! (hence $debugMode)
$bt = debug_backtrace();
$caller = $bt[1];
$file = basename($caller['file']);
$line = $caller['line'];
$function = "Unknown function";
if (array_key_exists(2, $bt)) {
$function = $bt[2]['function'];
}
$linePrefix .= "[$file:$line - $function()] - ";
}
return $linePrefix;
}
public static function info($p_msg) public static function info($p_msg)
{ {
$bt = debug_backtrace();
$caller = array_shift($bt);
$file = basename($caller['file']);
$line = $caller['line'];
$caller = array_shift($bt);
$function = $caller['function'];
$logger = self::getLogger(); $logger = self::getLogger();
$logger->info("[$file : $function() : line $line] - ".self::toString($p_msg)); $logger->info(self::getLinePrefix() . self::toString($p_msg));
} }
public static function warn($p_msg) public static function warn($p_msg)
{ {
$bt = debug_backtrace();
$caller = array_shift($bt);
$file = basename($caller['file']);
$line = $caller['line'];
$caller = array_shift($bt);
$function = $caller['function'];
$logger = self::getLogger(); $logger = self::getLogger();
$logger->warn("[$file : $function() : line $line] - " $logger->warn(self::getLinePrefix() . self::toString($p_msg));
. self::toString($p_msg));
} }
public static function error($p_msg) public static function error($p_msg)
{ {
$bt = debug_backtrace();
$caller = array_shift($bt);
$file = basename($caller['file']);
$line = $caller['line'];
$caller = array_shift($bt);
$function = $caller['function'];
$logger = self::getLogger(); $logger = self::getLogger();
$logger->err("[$file : $function() : line $line] - " $logger->err(self::getLinePrefix(true) . self::toString($p_msg));
. self::toString($p_msg));
} }
public static function debug($p_msg) public static function debug($p_msg)
@ -92,17 +90,8 @@ class Logging {
return; return;
} }
$bt = debug_backtrace();
$caller = array_shift($bt);
$file = basename($caller['file']);
$line = $caller['line'];
$caller = array_shift($bt);
$function = $caller['function'];
$logger = self::getLogger(); $logger = self::getLogger();
$logger->debug("[$file : $function() : line $line] - ".self::toString($p_msg)); $logger->debug(self::getLinePrefix(true) . self::toString($p_msg));
} }
// kind of like debug but for printing arrays more compactly (skipping // kind of like debug but for printing arrays more compactly (skipping
// empty elements // empty elements
@ -134,4 +123,49 @@ class Logging {
Propel::setLogger(null); Propel::setLogger(null);
} }
public static function loggingShutdownCallback()
{
//Catch the types of errors that PHP doesn't normally let us catch and
//would otherwise log to the apache log. We route these to our Airtime log to improve the modularity
//and reliability of our error logging. (All errors are in one spot!)
$err = error_get_last();
if (!is_array($err) || !array_key_exists('type', $err)) {
return;
}
switch($err['type'])
{
case E_ERROR:
case E_PARSE:
case E_CORE_ERROR:
case E_CORE_WARNING:
case E_COMPILE_ERROR:
case E_COMPILE_WARNING:
//error_log("Oh noes, a fatal: " . var_export($err, true), 1, 'fatals@example.com');
$errorStr = '';
if (array_key_exists('message', $err)) {
$errorStr .= $err['message'];
}
if (array_key_exists('file', $err))
{
$errorStr .= ' at ' .$err['file'];
}
if (array_key_exists('line', $err))
{
$errorStr .= ':' . $err['line'];
}
$errorStr .= "\n" . var_export($err, true);
Logging::error($errorStr);
break;
}
}
public static function setupParseErrorLogging()
{
//Static callback:
register_shutdown_function('Logging::loggingShutdownCallback');
}
} }

View File

@ -1517,24 +1517,27 @@ SQL;
$i++; $i++;
} }
} }
// check if file exists // check if file exists
$qry->add("file_exists", "true", Criteria::EQUAL); $qry->add("file_exists", "true", Criteria::EQUAL);
$qry->add("hidden", "false", Criteria::EQUAL); $qry->add("hidden", "false", Criteria::EQUAL);
if (isset($storedCrit['sort'])) { $sortTracks = 'random';
$sortTracks = $storedCrit['sort']['value']; if (isset($storedCrit['sort'])) {
} $sortTracks = $storedCrit['sort']['value'];
if ($sortTracks == 'newest') { }
$qry->addDescendingOrderByColumn('utime'); if ($sortTracks == 'newest') {
} $qry->addDescendingOrderByColumn('utime');
else if ($sortTracks == 'oldest') { }
$qry->addAscendingOrderByColumn('utime'); else if ($sortTracks == 'oldest') {
} $qry->addAscendingOrderByColumn('utime');
else { }
$qry->addAscendingOrderByColumn('random()'); else if ($sortTracks == 'random') {
} $qry->addAscendingOrderByColumn('random()');
} else {
Logging::warning("Unimplemented sortTracks type in ".__FILE__);
}
} }
// construct limit restriction // construct limit restriction
$limits = array(); $limits = array();

View File

@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: Airtime\n" "Project-Id-Version: Airtime\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-11-13 13:55-0500\n" "POT-Creation-Date: 2014-11-13 13:55-0500\n"
"PO-Revision-Date: 2015-01-15 11:11+0000\n" "PO-Revision-Date: 2015-02-05 10:31+0000\n"
"Last-Translator: Daniel James <daniel@64studio.com>\n" "Last-Translator: Daniel James <daniel@64studio.com>\n"
"Language-Team: Azerbaijani (http://www.transifex.com/projects/p/airtime/language/az/)\n" "Language-Team: Azerbaijani (http://www.transifex.com/projects/p/airtime/language/az/)\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: Airtime\n" "Project-Id-Version: Airtime\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-11-13 13:55-0500\n" "POT-Creation-Date: 2014-11-13 13:55-0500\n"
"PO-Revision-Date: 2015-01-15 11:11+0000\n" "PO-Revision-Date: 2015-02-05 10:31+0000\n"
"Last-Translator: Daniel James <daniel@64studio.com>\n" "Last-Translator: Daniel James <daniel@64studio.com>\n"
"Language-Team: Armenian (Armenia) (http://www.transifex.com/projects/p/airtime/language/hy_AM/)\n" "Language-Team: Armenian (Armenia) (http://www.transifex.com/projects/p/airtime/language/hy_AM/)\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: Airtime\n" "Project-Id-Version: Airtime\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-11-13 13:55-0500\n" "POT-Creation-Date: 2014-11-13 13:55-0500\n"
"PO-Revision-Date: 2015-01-15 11:11+0000\n" "PO-Revision-Date: 2015-02-05 10:31+0000\n"
"Last-Translator: Daniel James <daniel@64studio.com>\n" "Last-Translator: Daniel James <daniel@64studio.com>\n"
"Language-Team: Georgian (http://www.transifex.com/projects/p/airtime/language/ka/)\n" "Language-Team: Georgian (http://www.transifex.com/projects/p/airtime/language/ka/)\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"

View File

@ -72,6 +72,7 @@ $application = new Zend_Application(
require_once (APPLICATION_PATH."/logging/Logging.php"); require_once (APPLICATION_PATH."/logging/Logging.php");
Logging::setLogPath('/var/log/airtime/zendphp.log'); Logging::setLogPath('/var/log/airtime/zendphp.log');
Logging::setupParseErrorLogging();
// Create application, bootstrap, and run // Create application, bootstrap, and run
try { try {
@ -83,15 +84,18 @@ try {
$application->bootstrap()->run(); $application->bootstrap()->run();
} }
} catch (Exception $e) { } catch (Exception $e) {
echo $e->getMessage();
echo "<pre>"; header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
echo $e->getTraceAsString();
echo "</pre>"; Logging::error($e->getMessage());
Logging::info($e->getMessage());
if (VERBOSE_STACK_TRACE) { if (VERBOSE_STACK_TRACE) {
Logging::info($e->getTraceAsString()); echo $e->getMessage();
echo "<pre>";
echo $e->getTraceAsString();
echo "</pre>";
Logging::error($e->getTraceAsString());
} else { } else {
Logging::info($e->getTrace()); Logging::error($e->getTrace());
} }
throw $e; throw $e;
} }

View File

@ -316,15 +316,24 @@ var AIRTIME = (function(AIRTIME) {
}; };
mod.fnDeleteItems = function(aMedia) { mod.fnDeleteItems = function(aMedia) {
//Prevent the user from spamming the delete button while the AJAX request is in progress
AIRTIME.button.disableButton("btn-group #sb-trash", false);
//Hack to immediately show the "Processing" div in DataTables to give the user some sort of feedback.
$(".dataTables_processing").css('visibility','visible');
$.post(baseUrl+"library/delete", $.post(baseUrl+"library/delete",
{"format": "json", "media": aMedia}, {"format": "json", "media": aMedia},
function(json){ function(json){
if (json.message !== undefined) { if (json.message !== undefined) {
alert(json.message); alert(json.message);
} }
chosenItems = {}; chosenItems = {};
oTable.fnStandingRedraw(); oTable.fnStandingRedraw();
//Re-enable the delete button
AIRTIME.button.enableButton("btn-group #sb-trash", false);
}); });
}; };

View File

@ -14,6 +14,7 @@
<column>live_stream_pass</column> <column>live_stream_pass</column>
<column>linked</column> <column>linked</column>
<column>is_linkable</column> <column>is_linkable</column>
<column>image_path</column>
<row> <row>
<value>1</value> <value>1</value>
<value>test show</value> <value>test show</value>
@ -28,6 +29,7 @@
<null /> <null />
<value></value> <value></value>
<value>1</value> <value>1</value>
<value></value>
</row> </row>
</table> </table>
@ -338,4 +340,4 @@
<table name="cc_show_hosts"> <table name="cc_show_hosts">
</table> </table>
</dataset> </dataset>

View File

@ -14,6 +14,7 @@
<column>live_stream_pass</column> <column>live_stream_pass</column>
<column>linked</column> <column>linked</column>
<column>is_linkable</column> <column>is_linkable</column>
<column>image_path</column>
<row> <row>
<value>1</value> <value>1</value>
<value>test show</value> <value>test show</value>
@ -28,6 +29,7 @@
<null /> <null />
<value></value> <value></value>
<value>1</value> <value>1</value>
<value></value>
</row> </row>
</table> </table>
</dataset> </dataset>

View File

@ -14,6 +14,7 @@
<column>live_stream_pass</column> <column>live_stream_pass</column>
<column>linked</column> <column>linked</column>
<column>is_linkable</column> <column>is_linkable</column>
<column>image_path</column>
<row> <row>
<value>1</value> <value>1</value>
<value>test show</value> <value>test show</value>
@ -28,6 +29,7 @@
<null /> <null />
<value>1</value> <value>1</value>
<value>1</value> <value>1</value>
<value></value>
</row> </row>
</table> </table>
@ -134,4 +136,4 @@
<value>1</value> <value>1</value>
</row> </row>
</table> </table>
</dataset> </dataset>

View File

@ -14,6 +14,7 @@
<column>live_stream_pass</column> <column>live_stream_pass</column>
<column>linked</column> <column>linked</column>
<column>is_linkable</column> <column>is_linkable</column>
<column>image_path</column>
<row> <row>
<value>1</value> <value>1</value>
<value>test show</value> <value>test show</value>
@ -28,6 +29,7 @@
<null /> <null />
<value></value> <value></value>
<value>1</value> <value>1</value>
<value></value>
</row> </row>
</table> </table>
@ -104,4 +106,4 @@
<table name="cc_show_hosts"> <table name="cc_show_hosts">
</table> </table>
</dataset> </dataset>

View File

@ -14,6 +14,7 @@
<column>live_stream_pass</column> <column>live_stream_pass</column>
<column>linked</column> <column>linked</column>
<column>is_linkable</column> <column>is_linkable</column>
<column>image_path</column>
<row> <row>
<value>1</value> <value>1</value>
<value>test show</value> <value>test show</value>
@ -28,6 +29,7 @@
<null /> <null />
<value>1</value> <value>1</value>
<value>1</value> <value>1</value>
<value></value>
</row> </row>
</table> </table>
@ -134,4 +136,4 @@
<table name="cc_show_hosts"> <table name="cc_show_hosts">
</table> </table>
</dataset> </dataset>

View File

@ -14,6 +14,7 @@
<column>live_stream_pass</column> <column>live_stream_pass</column>
<column>linked</column> <column>linked</column>
<column>is_linkable</column> <column>is_linkable</column>
<column>image_path</column>
<row> <row>
<value>1</value> <value>1</value>
<value>test show</value> <value>test show</value>
@ -28,6 +29,7 @@
<null /> <null />
<value></value> <value></value>
<value>1</value> <value>1</value>
<value></value>
</row> </row>
</table> </table>
@ -94,4 +96,4 @@
<table name="cc_show_hosts"> <table name="cc_show_hosts">
</table> </table>
</dataset> </dataset>

View File

@ -14,6 +14,7 @@
<column>live_stream_pass</column> <column>live_stream_pass</column>
<column>linked</column> <column>linked</column>
<column>is_linkable</column> <column>is_linkable</column>
<column>image_path</column>
<row> <row>
<value>1</value> <value>1</value>
<value>test show</value> <value>test show</value>
@ -28,6 +29,7 @@
<null /> <null />
<value></value> <value></value>
<value>1</value> <value>1</value>
<value></value>
</row> </row>
</table> </table>
@ -94,4 +96,4 @@
<table name="cc_show_hosts"> <table name="cc_show_hosts">
</table> </table>
</dataset> </dataset>

View File

@ -14,6 +14,7 @@
<column>live_stream_pass</column> <column>live_stream_pass</column>
<column>linked</column> <column>linked</column>
<column>is_linkable</column> <column>is_linkable</column>
<column>image_path</column>
<row> <row>
<value>1</value> <value>1</value>
<value>test show</value> <value>test show</value>
@ -28,6 +29,7 @@
<null /> <null />
<value></value> <value></value>
<value>1</value> <value>1</value>
<value></value>
</row> </row>
</table> </table>
@ -84,4 +86,4 @@
<table name="cc_show_hosts"> <table name="cc_show_hosts">
</table> </table>
</dataset> </dataset>

View File

@ -14,6 +14,7 @@
<column>live_stream_pass</column> <column>live_stream_pass</column>
<column>linked</column> <column>linked</column>
<column>is_linkable</column> <column>is_linkable</column>
<column>image_path</column>
<row> <row>
<value>1</value> <value>1</value>
<value>test show</value> <value>test show</value>
@ -28,6 +29,7 @@
<null /> <null />
<value></value> <value></value>
<value>1</value> <value>1</value>
<value></value>
</row> </row>
</table> </table>
@ -248,4 +250,4 @@
<table name="cc_show_hosts"> <table name="cc_show_hosts">
</table> </table>
</dataset> </dataset>

View File

@ -14,6 +14,7 @@
<column>live_stream_pass</column> <column>live_stream_pass</column>
<column>linked</column> <column>linked</column>
<column>is_linkable</column> <column>is_linkable</column>
<column>image_path</column>
<row> <row>
<value>1</value> <value>1</value>
<value>test show</value> <value>test show</value>
@ -28,6 +29,7 @@
<null /> <null />
<value></value> <value></value>
<value>1</value> <value>1</value>
<value></value>
</row> </row>
</table> </table>
@ -94,4 +96,4 @@
<table name="cc_show_hosts"> <table name="cc_show_hosts">
</table> </table>
</dataset> </dataset>

View File

@ -14,6 +14,7 @@
<column>live_stream_pass</column> <column>live_stream_pass</column>
<column>linked</column> <column>linked</column>
<column>is_linkable</column> <column>is_linkable</column>
<column>image_path</column>
<row> <row>
<value>1</value> <value>1</value>
<value>test show</value> <value>test show</value>
@ -28,6 +29,7 @@
<null /> <null />
<value></value> <value></value>
<value>1</value> <value>1</value>
<value></value>
</row> </row>
</table> </table>
@ -94,4 +96,4 @@
<table name="cc_show_hosts"> <table name="cc_show_hosts">
</table> </table>
</dataset> </dataset>

View File

@ -14,6 +14,7 @@
<column>live_stream_pass</column> <column>live_stream_pass</column>
<column>linked</column> <column>linked</column>
<column>is_linkable</column> <column>is_linkable</column>
<column>image_path</column>
<row> <row>
<value>1</value> <value>1</value>
<value>test show</value> <value>test show</value>
@ -28,6 +29,7 @@
<null /> <null />
<value></value> <value></value>
<value>1</value> <value>1</value>
<value></value>
</row> </row>
</table> </table>
@ -134,4 +136,4 @@
<table name="cc_show_hosts"> <table name="cc_show_hosts">
</table> </table>
</dataset> </dataset>

View File

@ -14,6 +14,7 @@
<column>live_stream_pass</column> <column>live_stream_pass</column>
<column>linked</column> <column>linked</column>
<column>is_linkable</column> <column>is_linkable</column>
<column>image_path</column>
<row> <row>
<value>1</value> <value>1</value>
<value>test show</value> <value>test show</value>
@ -28,6 +29,7 @@
<null /> <null />
<value></value> <value></value>
<value>1</value> <value>1</value>
<value></value>
</row> </row>
</table> </table>
@ -270,4 +272,4 @@
<table name="cc_show_hosts"> <table name="cc_show_hosts">
</table> </table>
</dataset> </dataset>

View File

@ -14,6 +14,7 @@
<column>live_stream_pass</column> <column>live_stream_pass</column>
<column>linked</column> <column>linked</column>
<column>is_linkable</column> <column>is_linkable</column>
<column>image_path</column>
<row> <row>
<value>1</value> <value>1</value>
<value>test show</value> <value>test show</value>
@ -28,6 +29,7 @@
<null /> <null />
<value></value> <value></value>
<value>1</value> <value>1</value>
<value></value>
</row> </row>
</table> </table>
@ -134,4 +136,4 @@
<table name="cc_show_hosts"> <table name="cc_show_hosts">
</table> </table>
</dataset> </dataset>

View File

@ -14,6 +14,7 @@
<column>live_stream_pass</column> <column>live_stream_pass</column>
<column>linked</column> <column>linked</column>
<column>is_linkable</column> <column>is_linkable</column>
<column>image_path</column>
<row> <row>
<value>1</value> <value>1</value>
<value>test show</value> <value>test show</value>
@ -28,6 +29,7 @@
<null /> <null />
<value></value> <value></value>
<value>1</value> <value>1</value>
<value></value>
</row> </row>
</table> </table>
@ -260,4 +262,4 @@
<table name="cc_show_hosts"> <table name="cc_show_hosts">
</table> </table>
</dataset> </dataset>

View File

@ -14,6 +14,7 @@
<column>live_stream_pass</column> <column>live_stream_pass</column>
<column>linked</column> <column>linked</column>
<column>is_linkable</column> <column>is_linkable</column>
<column>image_path</column>
<row> <row>
<value>1</value> <value>1</value>
<value>test show</value> <value>test show</value>
@ -28,6 +29,7 @@
<null /> <null />
<value></value> <value></value>
<value>1</value> <value>1</value>
<value></value>
</row> </row>
</table> </table>
@ -94,4 +96,4 @@
<table name="cc_show_hosts"> <table name="cc_show_hosts">
</table> </table>
</dataset> </dataset>

View File

@ -14,6 +14,7 @@
<column>live_stream_pass</column> <column>live_stream_pass</column>
<column>linked</column> <column>linked</column>
<column>is_linkable</column> <column>is_linkable</column>
<column>image_path</column>
<row> <row>
<value>1</value> <value>1</value>
<value>test show</value> <value>test show</value>
@ -28,6 +29,7 @@
<null /> <null />
<value></value> <value></value>
<value>1</value> <value>1</value>
<value></value>
</row> </row>
</table> </table>
@ -157,4 +159,4 @@
<table name="cc_show_hosts"> <table name="cc_show_hosts">
</table> </table>
</dataset> </dataset>

View File

@ -14,6 +14,7 @@
<column>live_stream_pass</column> <column>live_stream_pass</column>
<column>linked</column> <column>linked</column>
<column>is_linkable</column> <column>is_linkable</column>
<column>image_path</column>
<row> <row>
<value>1</value> <value>1</value>
<value>test show</value> <value>test show</value>
@ -28,6 +29,7 @@
<null /> <null />
<value>1</value> <value>1</value>
<value>1</value> <value>1</value>
<value></value>
</row> </row>
</table> </table>
@ -134,4 +136,4 @@
<value>1</value> <value>1</value>
</row> </row>
</table> </table>
</dataset> </dataset>

View File

@ -14,6 +14,7 @@
<column>live_stream_pass</column> <column>live_stream_pass</column>
<column>linked</column> <column>linked</column>
<column>is_linkable</column> <column>is_linkable</column>
<column>image_path</column>
<row> <row>
<value>1</value> <value>1</value>
<value>test show</value> <value>test show</value>
@ -28,6 +29,7 @@
<null /> <null />
<value></value> <value></value>
<value>1</value> <value>1</value>
<value></value>
</row> </row>
</table> </table>
@ -134,4 +136,4 @@
<table name="cc_show_hosts"> <table name="cc_show_hosts">
</table> </table>
</dataset> </dataset>

View File

@ -14,6 +14,7 @@
<column>live_stream_pass</column> <column>live_stream_pass</column>
<column>linked</column> <column>linked</column>
<column>is_linkable</column> <column>is_linkable</column>
<column>image_path</column>
<row> <row>
<value>1</value> <value>1</value>
<value>test show</value> <value>test show</value>
@ -28,6 +29,7 @@
<null /> <null />
<value></value> <value></value>
<value></value> <value></value>
<value></value>
</row> </row>
</table> </table>
@ -134,4 +136,4 @@
<table name="cc_show_hosts"> <table name="cc_show_hosts">
</table> </table>
</dataset> </dataset>

View File

@ -14,6 +14,7 @@
<column>live_stream_pass</column> <column>live_stream_pass</column>
<column>linked</column> <column>linked</column>
<column>is_linkable</column> <column>is_linkable</column>
<column>image_path</column>
<row> <row>
<value>1</value> <value>1</value>
<value>test show</value> <value>test show</value>
@ -28,6 +29,7 @@
<null /> <null />
<value></value> <value></value>
<value>1</value> <value>1</value>
<value></value>
</row> </row>
</table> </table>
@ -104,4 +106,4 @@
<table name="cc_show_hosts"> <table name="cc_show_hosts">
</table> </table>
</dataset> </dataset>

View File

@ -14,6 +14,7 @@
<column>live_stream_pass</column> <column>live_stream_pass</column>
<column>linked</column> <column>linked</column>
<column>is_linkable</column> <column>is_linkable</column>
<column>image_path</column>
<row> <row>
<value>1</value> <value>1</value>
<value>test show</value> <value>test show</value>
@ -28,6 +29,7 @@
<null /> <null />
<value></value> <value></value>
<value>1</value> <value>1</value>
<value></value>
</row> </row>
</table> </table>
@ -84,4 +86,4 @@
<table name="cc_show_hosts"> <table name="cc_show_hosts">
</table> </table>
</dataset> </dataset>