Merge remote-tracking branch 'upstream/master' into js

This commit is contained in:
Zachary Klosko 2021-01-01 15:28:35 -05:00
commit 1924fe4a81
46 changed files with 1436 additions and 2461 deletions

2
Vagrantfile vendored
View File

@ -57,7 +57,7 @@ Vagrant.configure("2") do |config|
provision_libretime(os, "debian.sh", installer_args)
end
config.vm.define "centos" do |os|
os.vm.box = 'centos/7'
os.vm.box = 'centos/8'
provision_libretime(os, "centos.sh", installer_args + "--selinux")
end

View File

@ -79,9 +79,6 @@ return array (
'BaseCcShowRebroadcast' => 'airtime/om/BaseCcShowRebroadcast.php',
'BaseCcShowRebroadcastPeer' => 'airtime/om/BaseCcShowRebroadcastPeer.php',
'BaseCcShowRebroadcastQuery' => 'airtime/om/BaseCcShowRebroadcastQuery.php',
'BaseCcSmemb' => 'airtime/om/BaseCcSmemb.php',
'BaseCcSmembPeer' => 'airtime/om/BaseCcSmembPeer.php',
'BaseCcSmembQuery' => 'airtime/om/BaseCcSmembQuery.php',
'BaseCcStreamSetting' => 'airtime/om/BaseCcStreamSetting.php',
'BaseCcStreamSettingPeer' => 'airtime/om/BaseCcStreamSettingPeer.php',
'BaseCcStreamSettingQuery' => 'airtime/om/BaseCcStreamSettingQuery.php',
@ -228,10 +225,6 @@ return array (
'CcShowRebroadcastQuery' => 'airtime/CcShowRebroadcastQuery.php',
'CcShowRebroadcastTableMap' => 'airtime/map/CcShowRebroadcastTableMap.php',
'CcShowTableMap' => 'airtime/map/CcShowTableMap.php',
'CcSmemb' => 'airtime/CcSmemb.php',
'CcSmembPeer' => 'airtime/CcSmembPeer.php',
'CcSmembQuery' => 'airtime/CcSmembQuery.php',
'CcSmembTableMap' => 'airtime/map/CcSmembTableMap.php',
'CcStreamSetting' => 'airtime/CcStreamSetting.php',
'CcStreamSettingPeer' => 'airtime/CcStreamSettingPeer.php',
'CcStreamSettingQuery' => 'airtime/CcStreamSettingQuery.php',
@ -288,4 +281,4 @@ return array (
'ThirdPartyTrackReferencesPeer' => 'airtime/ThirdPartyTrackReferencesPeer.php',
'ThirdPartyTrackReferencesQuery' => 'airtime/ThirdPartyTrackReferencesQuery.php',
'ThirdPartyTrackReferencesTableMap' => 'airtime/map/ThirdPartyTrackReferencesTableMap.php',
);
);

View File

@ -0,0 +1,10 @@
CREATE TABLE "cc_smemb"
(
"id" INTEGER NOT NULL,
"uid" INTEGER DEFAULT 0 NOT NULL,
"gid" INTEGER DEFAULT 0 NOT NULL,
"level" INTEGER DEFAULT 0 NOT NULL,
"mid" INTEGER,
PRIMARY KEY ("id"),
CONSTRAINT "cc_smemb_id_idx" UNIQUE ("id")
);

View File

@ -144,6 +144,11 @@ class PageLayoutInitPlugin extends Zend_Controller_Plugin_Abstract
$track_type_options = array();
$track_types = Application_Model_Tracktype::getTracktypes();
array_multisort(array_map(function($element) {
return $element['type_name'];
}, $track_types), SORT_ASC, $track_types);
foreach ($track_types as $key => $tt) {
$track_type_options[$tt['code']] = $tt['type_name'];
}

View File

@ -0,0 +1 @@
DROP TABLE IF EXISTS "cc_smemb" CASCADE;

View File

@ -94,6 +94,11 @@ class Application_Form_EditAudioMD extends Zend_Form
// Add track type dropdown
$track_type_options = array();
$track_types = Application_Model_Tracktype::getTracktypes();
array_multisort(array_map(function($element) {
return $element['type_name'];
}, $track_types), SORT_ASC, $track_types);
$track_type_options[""] = _('Select a Type');
foreach ($track_types as $key => $tt) {
$track_type_options[$tt['code']] = $tt['type_name'];

View File

@ -61,6 +61,11 @@ class Application_Model_Library
{
$track_type_options = array(NULL => _("None"));
$track_types = Application_Model_Tracktype::getTracktypes();
array_multisort(array_map(function($element) {
return $element['type_name'];
}, $track_types), SORT_ASC, $track_types);
foreach ($track_types as $key => $tt) {
$track_type_options[$tt['code']] = $tt['type_name'];
}

View File

@ -1,7 +1,4 @@
<?php
define('ALIBERR_NOTGR', 20);
define('ALIBERR_BADSMEMB', 21);
/**
* Subj class
*

View File

@ -1,18 +0,0 @@
<?php
/**
* Skeleton subclass for representing a row from the 'cc_smemb' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcSmemb extends BaseCcSmemb {
} // CcSmemb

View File

@ -1,18 +0,0 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_smemb' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcSmembPeer extends BaseCcSmembPeer {
} // CcSmembPeer

View File

@ -1,18 +0,0 @@
<?php
/**
* Skeleton subclass for performing query and update operations on the 'cc_smemb' table.
*
*
*
* You should add additional methods to this class to meet the
* application requirements. This class will only be generated as
* long as it does not already exist in the output directory.
*
* @package propel.generator.airtime
*/
class CcSmembQuery extends BaseCcSmembQuery {
} // CcSmembQuery

View File

@ -1,56 +0,0 @@
<?php
/**
* This class defines the structure of the 'cc_smemb' table.
*
*
*
* This map class is used by Propel to do runtime db structure discovery.
* For example, the createSelectSql() method checks the type of a given column used in an
* ORDER BY clause to know whether it needs to apply SQL to make the ORDER BY case-insensitive
* (i.e. if it's a text column type).
*
* @package propel.generator.airtime.map
*/
class CcSmembTableMap extends TableMap
{
/**
* The (dot-path) name of this class
*/
const CLASS_NAME = 'airtime.map.CcSmembTableMap';
/**
* Initialize the table attributes, columns and validators
* Relations are not initialized by this method since they are lazy loaded
*
* @return void
* @throws PropelException
*/
public function initialize()
{
// attributes
$this->setName('cc_smemb');
$this->setPhpName('CcSmemb');
$this->setClassname('CcSmemb');
$this->setPackage('airtime');
$this->setUseIdGenerator(false);
// columns
$this->addPrimaryKey('id', 'Id', 'INTEGER', true, null, null);
$this->addColumn('uid', 'Uid', 'INTEGER', true, null, 0);
$this->addColumn('gid', 'Gid', 'INTEGER', true, null, 0);
$this->addColumn('level', 'Level', 'INTEGER', true, null, 0);
$this->addColumn('mid', 'Mid', 'INTEGER', false, null, null);
// validators
} // initialize()
/**
* Build the RelationMap objects for this table relationships
*/
public function buildRelations()
{
} // buildRelations()
} // CcSmembTableMap

File diff suppressed because it is too large Load Diff

View File

@ -1,772 +0,0 @@
<?php
/**
* Base static class for performing query and update operations on the 'cc_smemb' table.
*
*
*
* @package propel.generator.airtime.om
*/
abstract class BaseCcSmembPeer
{
/** the default database name for this class */
const DATABASE_NAME = 'airtime';
/** the table name for this class */
const TABLE_NAME = 'cc_smemb';
/** the related Propel class for this table */
const OM_CLASS = 'CcSmemb';
/** the related TableMap class for this table */
const TM_CLASS = 'CcSmembTableMap';
/** The total number of columns. */
const NUM_COLUMNS = 5;
/** The number of lazy-loaded columns. */
const NUM_LAZY_LOAD_COLUMNS = 0;
/** The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */
const NUM_HYDRATE_COLUMNS = 5;
/** the column name for the id field */
const ID = 'cc_smemb.id';
/** the column name for the uid field */
const UID = 'cc_smemb.uid';
/** the column name for the gid field */
const GID = 'cc_smemb.gid';
/** the column name for the level field */
const LEVEL = 'cc_smemb.level';
/** the column name for the mid field */
const MID = 'cc_smemb.mid';
/** The default string format for model objects of the related table **/
const DEFAULT_STRING_FORMAT = 'YAML';
/**
* An identity map to hold any loaded instances of CcSmemb objects.
* This must be public so that other peer classes can access this when hydrating from JOIN
* queries.
* @var array CcSmemb[]
*/
public static $instances = array();
/**
* holds an array of fieldnames
*
* first dimension keys are the type constants
* e.g. CcSmembPeer::$fieldNames[CcSmembPeer::TYPE_PHPNAME][0] = 'Id'
*/
protected static $fieldNames = array (
BasePeer::TYPE_PHPNAME => array ('Id', 'Uid', 'Gid', 'Level', 'Mid', ),
BasePeer::TYPE_STUDLYPHPNAME => array ('id', 'uid', 'gid', 'level', 'mid', ),
BasePeer::TYPE_COLNAME => array (CcSmembPeer::ID, CcSmembPeer::UID, CcSmembPeer::GID, CcSmembPeer::LEVEL, CcSmembPeer::MID, ),
BasePeer::TYPE_RAW_COLNAME => array ('ID', 'UID', 'GID', 'LEVEL', 'MID', ),
BasePeer::TYPE_FIELDNAME => array ('id', 'uid', 'gid', 'level', 'mid', ),
BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, )
);
/**
* holds an array of keys for quick access to the fieldnames array
*
* first dimension keys are the type constants
* e.g. CcSmembPeer::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0
*/
protected static $fieldKeys = array (
BasePeer::TYPE_PHPNAME => array ('Id' => 0, 'Uid' => 1, 'Gid' => 2, 'Level' => 3, 'Mid' => 4, ),
BasePeer::TYPE_STUDLYPHPNAME => array ('id' => 0, 'uid' => 1, 'gid' => 2, 'level' => 3, 'mid' => 4, ),
BasePeer::TYPE_COLNAME => array (CcSmembPeer::ID => 0, CcSmembPeer::UID => 1, CcSmembPeer::GID => 2, CcSmembPeer::LEVEL => 3, CcSmembPeer::MID => 4, ),
BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'UID' => 1, 'GID' => 2, 'LEVEL' => 3, 'MID' => 4, ),
BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'uid' => 1, 'gid' => 2, 'level' => 3, 'mid' => 4, ),
BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, )
);
/**
* Translates a fieldname to another type
*
* @param string $name field name
* @param string $fromType One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME
* BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM
* @param string $toType One of the class type constants
* @return string translated name of the field.
* @throws PropelException - if the specified name could not be found in the fieldname mappings.
*/
public static function translateFieldName($name, $fromType, $toType)
{
$toNames = CcSmembPeer::getFieldNames($toType);
$key = isset(CcSmembPeer::$fieldKeys[$fromType][$name]) ? CcSmembPeer::$fieldKeys[$fromType][$name] : null;
if ($key === null) {
throw new PropelException("'$name' could not be found in the field names of type '$fromType'. These are: " . print_r(CcSmembPeer::$fieldKeys[$fromType], true));
}
return $toNames[$key];
}
/**
* Returns an array of field names.
*
* @param string $type The type of fieldnames to return:
* One of the class type constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME
* BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM
* @return array A list of field names
* @throws PropelException - if the type is not valid.
*/
public static function getFieldNames($type = BasePeer::TYPE_PHPNAME)
{
if (!array_key_exists($type, CcSmembPeer::$fieldNames)) {
throw new PropelException('Method getFieldNames() expects the parameter $type to be one of the class constants BasePeer::TYPE_PHPNAME, BasePeer::TYPE_STUDLYPHPNAME, BasePeer::TYPE_COLNAME, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_NUM. ' . $type . ' was given.');
}
return CcSmembPeer::$fieldNames[$type];
}
/**
* Convenience method which changes table.column to alias.column.
*
* Using this method you can maintain SQL abstraction while using column aliases.
* <code>
* $c->addAlias("alias1", TablePeer::TABLE_NAME);
* $c->addJoin(TablePeer::alias("alias1", TablePeer::PRIMARY_KEY_COLUMN), TablePeer::PRIMARY_KEY_COLUMN);
* </code>
* @param string $alias The alias for the current table.
* @param string $column The column name for current table. (i.e. CcSmembPeer::COLUMN_NAME).
* @return string
*/
public static function alias($alias, $column)
{
return str_replace(CcSmembPeer::TABLE_NAME.'.', $alias.'.', $column);
}
/**
* Add all the columns needed to create a new object.
*
* Note: any columns that were marked with lazyLoad="true" in the
* XML schema will not be added to the select list and only loaded
* on demand.
*
* @param Criteria $criteria object containing the columns to add.
* @param string $alias optional table alias
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function addSelectColumns(Criteria $criteria, $alias = null)
{
if (null === $alias) {
$criteria->addSelectColumn(CcSmembPeer::ID);
$criteria->addSelectColumn(CcSmembPeer::UID);
$criteria->addSelectColumn(CcSmembPeer::GID);
$criteria->addSelectColumn(CcSmembPeer::LEVEL);
$criteria->addSelectColumn(CcSmembPeer::MID);
} else {
$criteria->addSelectColumn($alias . '.id');
$criteria->addSelectColumn($alias . '.uid');
$criteria->addSelectColumn($alias . '.gid');
$criteria->addSelectColumn($alias . '.level');
$criteria->addSelectColumn($alias . '.mid');
}
}
/**
* Returns the number of rows matching criteria.
*
* @param Criteria $criteria
* @param boolean $distinct Whether to select only distinct columns; deprecated: use Criteria->setDistinct() instead.
* @param PropelPDO $con
* @return int Number of matching rows.
*/
public static function doCount(Criteria $criteria, $distinct = false, PropelPDO $con = null)
{
// we may modify criteria, so copy it first
$criteria = clone $criteria;
// We need to set the primary table name, since in the case that there are no WHERE columns
// it will be impossible for the BasePeer::createSelectSql() method to determine which
// tables go into the FROM clause.
$criteria->setPrimaryTableName(CcSmembPeer::TABLE_NAME);
if ($distinct && !in_array(Criteria::DISTINCT, $criteria->getSelectModifiers())) {
$criteria->setDistinct();
}
if (!$criteria->hasSelectClause()) {
CcSmembPeer::addSelectColumns($criteria);
}
$criteria->clearOrderByColumns(); // ORDER BY won't ever affect the count
$criteria->setDbName(CcSmembPeer::DATABASE_NAME); // Set the correct dbName
if ($con === null) {
$con = Propel::getConnection(CcSmembPeer::DATABASE_NAME, Propel::CONNECTION_READ);
}
// BasePeer returns a PDOStatement
$stmt = BasePeer::doCount($criteria, $con);
if ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$count = (int) $row[0];
} else {
$count = 0; // no rows returned; we infer that means 0 matches.
}
$stmt->closeCursor();
return $count;
}
/**
* Selects one object from the DB.
*
* @param Criteria $criteria object used to create the SELECT statement.
* @param PropelPDO $con
* @return CcSmemb
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doSelectOne(Criteria $criteria, PropelPDO $con = null)
{
$critcopy = clone $criteria;
$critcopy->setLimit(1);
$objects = CcSmembPeer::doSelect($critcopy, $con);
if ($objects) {
return $objects[0];
}
return null;
}
/**
* Selects several row from the DB.
*
* @param Criteria $criteria The Criteria object used to build the SELECT statement.
* @param PropelPDO $con
* @return array Array of selected Objects
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doSelect(Criteria $criteria, PropelPDO $con = null)
{
return CcSmembPeer::populateObjects(CcSmembPeer::doSelectStmt($criteria, $con));
}
/**
* Prepares the Criteria object and uses the parent doSelect() method to execute a PDOStatement.
*
* Use this method directly if you want to work with an executed statement directly (for example
* to perform your own object hydration).
*
* @param Criteria $criteria The Criteria object used to build the SELECT statement.
* @param PropelPDO $con The connection to use
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
* @return PDOStatement The executed PDOStatement object.
* @see BasePeer::doSelect()
*/
public static function doSelectStmt(Criteria $criteria, PropelPDO $con = null)
{
if ($con === null) {
$con = Propel::getConnection(CcSmembPeer::DATABASE_NAME, Propel::CONNECTION_READ);
}
if (!$criteria->hasSelectClause()) {
$criteria = clone $criteria;
CcSmembPeer::addSelectColumns($criteria);
}
// Set the correct dbName
$criteria->setDbName(CcSmembPeer::DATABASE_NAME);
// BasePeer returns a PDOStatement
return BasePeer::doSelect($criteria, $con);
}
/**
* Adds an object to the instance pool.
*
* Propel keeps cached copies of objects in an instance pool when they are retrieved
* from the database. In some cases -- especially when you override doSelect*()
* methods in your stub classes -- you may need to explicitly add objects
* to the cache in order to ensure that the same objects are always returned by doSelect*()
* and retrieveByPK*() calls.
*
* @param CcSmemb $obj A CcSmemb object.
* @param string $key (optional) key to use for instance map (for performance boost if key was already calculated externally).
*/
public static function addInstanceToPool($obj, $key = null)
{
if (Propel::isInstancePoolingEnabled()) {
if ($key === null) {
$key = (string) $obj->getId();
} // if key === null
CcSmembPeer::$instances[$key] = $obj;
}
}
/**
* Removes an object from the instance pool.
*
* Propel keeps cached copies of objects in an instance pool when they are retrieved
* from the database. In some cases -- especially when you override doDelete
* methods in your stub classes -- you may need to explicitly remove objects
* from the cache in order to prevent returning objects that no longer exist.
*
* @param mixed $value A CcSmemb object or a primary key value.
*
* @return void
* @throws PropelException - if the value is invalid.
*/
public static function removeInstanceFromPool($value)
{
if (Propel::isInstancePoolingEnabled() && $value !== null) {
if (is_object($value) && $value instanceof CcSmemb) {
$key = (string) $value->getId();
} elseif (is_scalar($value)) {
// assume we've been passed a primary key
$key = (string) $value;
} else {
$e = new PropelException("Invalid value passed to removeInstanceFromPool(). Expected primary key or CcSmemb object; got " . (is_object($value) ? get_class($value) . ' object.' : var_export($value,true)));
throw $e;
}
unset(CcSmembPeer::$instances[$key]);
}
} // removeInstanceFromPool()
/**
* Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table.
*
* For tables with a single-column primary key, that simple pkey value will be returned. For tables with
* a multi-column primary key, a serialize()d version of the primary key will be returned.
*
* @param string $key The key (@see getPrimaryKeyHash()) for this instance.
* @return CcSmemb Found object or null if 1) no instance exists for specified key or 2) instance pooling has been disabled.
* @see getPrimaryKeyHash()
*/
public static function getInstanceFromPool($key)
{
if (Propel::isInstancePoolingEnabled()) {
if (isset(CcSmembPeer::$instances[$key])) {
return CcSmembPeer::$instances[$key];
}
}
return null; // just to be explicit
}
/**
* Clear the instance pool.
*
* @return void
*/
public static function clearInstancePool($and_clear_all_references = false)
{
if ($and_clear_all_references) {
foreach (CcSmembPeer::$instances as $instance) {
$instance->clearAllReferences(true);
}
}
CcSmembPeer::$instances = array();
}
/**
* Method to invalidate the instance pool of all tables related to cc_smemb
* by a foreign key with ON DELETE CASCADE
*/
public static function clearRelatedInstancePool()
{
}
/**
* Retrieves a string version of the primary key from the DB resultset row that can be used to uniquely identify a row in this table.
*
* For tables with a single-column primary key, that simple pkey value will be returned. For tables with
* a multi-column primary key, a serialize()d version of the primary key will be returned.
*
* @param array $row PropelPDO resultset row.
* @param int $startcol The 0-based offset for reading from the resultset row.
* @return string A string version of PK or null if the components of primary key in result array are all null.
*/
public static function getPrimaryKeyHashFromRow($row, $startcol = 0)
{
// If the PK cannot be derived from the row, return null.
if ($row[$startcol] === null) {
return null;
}
return (string) $row[$startcol];
}
/**
* Retrieves the primary key from the DB resultset row
* For tables with a single-column primary key, that simple pkey value will be returned. For tables with
* a multi-column primary key, an array of the primary key columns will be returned.
*
* @param array $row PropelPDO resultset row.
* @param int $startcol The 0-based offset for reading from the resultset row.
* @return mixed The primary key of the row
*/
public static function getPrimaryKeyFromRow($row, $startcol = 0)
{
return (int) $row[$startcol];
}
/**
* The returned array will contain objects of the default type or
* objects that inherit from the default.
*
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function populateObjects(PDOStatement $stmt)
{
$results = array();
// set the class once to avoid overhead in the loop
$cls = CcSmembPeer::getOMClass();
// populate the object(s)
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$key = CcSmembPeer::getPrimaryKeyHashFromRow($row, 0);
if (null !== ($obj = CcSmembPeer::getInstanceFromPool($key))) {
// We no longer rehydrate the object, since this can cause data loss.
// See http://www.propelorm.org/ticket/509
// $obj->hydrate($row, 0, true); // rehydrate
$results[] = $obj;
} else {
$obj = new $cls();
$obj->hydrate($row);
$results[] = $obj;
CcSmembPeer::addInstanceToPool($obj, $key);
} // if key exists
}
$stmt->closeCursor();
return $results;
}
/**
* Populates an object of the default type or an object that inherit from the default.
*
* @param array $row PropelPDO resultset row.
* @param int $startcol The 0-based offset for reading from the resultset row.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
* @return array (CcSmemb object, last column rank)
*/
public static function populateObject($row, $startcol = 0)
{
$key = CcSmembPeer::getPrimaryKeyHashFromRow($row, $startcol);
if (null !== ($obj = CcSmembPeer::getInstanceFromPool($key))) {
// We no longer rehydrate the object, since this can cause data loss.
// See http://www.propelorm.org/ticket/509
// $obj->hydrate($row, $startcol, true); // rehydrate
$col = $startcol + CcSmembPeer::NUM_HYDRATE_COLUMNS;
} else {
$cls = CcSmembPeer::OM_CLASS;
$obj = new $cls();
$col = $obj->hydrate($row, $startcol);
CcSmembPeer::addInstanceToPool($obj, $key);
}
return array($obj, $col);
}
/**
* Returns the TableMap related to this peer.
* This method is not needed for general use but a specific application could have a need.
* @return TableMap
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function getTableMap()
{
return Propel::getDatabaseMap(CcSmembPeer::DATABASE_NAME)->getTable(CcSmembPeer::TABLE_NAME);
}
/**
* Add a TableMap instance to the database for this peer class.
*/
public static function buildTableMap()
{
$dbMap = Propel::getDatabaseMap(BaseCcSmembPeer::DATABASE_NAME);
if (!$dbMap->hasTable(BaseCcSmembPeer::TABLE_NAME)) {
$dbMap->addTableObject(new \CcSmembTableMap());
}
}
/**
* The class that the Peer will make instances of.
*
*
* @return string ClassName
*/
public static function getOMClass($row = 0, $colnum = 0)
{
return CcSmembPeer::OM_CLASS;
}
/**
* Performs an INSERT on the database, given a CcSmemb or Criteria object.
*
* @param mixed $values Criteria or CcSmemb object containing data that is used to create the INSERT statement.
* @param PropelPDO $con the PropelPDO connection to use
* @return mixed The new primary key.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doInsert($values, PropelPDO $con = null)
{
if ($con === null) {
$con = Propel::getConnection(CcSmembPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
}
if ($values instanceof Criteria) {
$criteria = clone $values; // rename for clarity
} else {
$criteria = $values->buildCriteria(); // build Criteria from CcSmemb object
}
// Set the correct dbName
$criteria->setDbName(CcSmembPeer::DATABASE_NAME);
try {
// use transaction because $criteria could contain info
// for more than one table (I guess, conceivably)
$con->beginTransaction();
$pk = BasePeer::doInsert($criteria, $con);
$con->commit();
} catch (Exception $e) {
$con->rollBack();
throw $e;
}
return $pk;
}
/**
* Performs an UPDATE on the database, given a CcSmemb or Criteria object.
*
* @param mixed $values Criteria or CcSmemb object containing data that is used to create the UPDATE statement.
* @param PropelPDO $con The connection to use (specify PropelPDO connection object to exert more control over transactions).
* @return int The number of affected rows (if supported by underlying database driver).
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doUpdate($values, PropelPDO $con = null)
{
if ($con === null) {
$con = Propel::getConnection(CcSmembPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
}
$selectCriteria = new Criteria(CcSmembPeer::DATABASE_NAME);
if ($values instanceof Criteria) {
$criteria = clone $values; // rename for clarity
$comparison = $criteria->getComparison(CcSmembPeer::ID);
$value = $criteria->remove(CcSmembPeer::ID);
if ($value) {
$selectCriteria->add(CcSmembPeer::ID, $value, $comparison);
} else {
$selectCriteria->setPrimaryTableName(CcSmembPeer::TABLE_NAME);
}
} else { // $values is CcSmemb object
$criteria = $values->buildCriteria(); // gets full criteria
$selectCriteria = $values->buildPkeyCriteria(); // gets criteria w/ primary key(s)
}
// set the correct dbName
$criteria->setDbName(CcSmembPeer::DATABASE_NAME);
return BasePeer::doUpdate($selectCriteria, $criteria, $con);
}
/**
* Deletes all rows from the cc_smemb table.
*
* @param PropelPDO $con the connection to use
* @return int The number of affected rows (if supported by underlying database driver).
* @throws PropelException
*/
public static function doDeleteAll(PropelPDO $con = null)
{
if ($con === null) {
$con = Propel::getConnection(CcSmembPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
}
$affectedRows = 0; // initialize var to track total num of affected rows
try {
// use transaction because $criteria could contain info
// for more than one table or we could emulating ON DELETE CASCADE, etc.
$con->beginTransaction();
$affectedRows += BasePeer::doDeleteAll(CcSmembPeer::TABLE_NAME, $con, CcSmembPeer::DATABASE_NAME);
// Because this db requires some delete cascade/set null emulation, we have to
// clear the cached instance *after* the emulation has happened (since
// instances get re-added by the select statement contained therein).
CcSmembPeer::clearInstancePool();
CcSmembPeer::clearRelatedInstancePool();
$con->commit();
return $affectedRows;
} catch (Exception $e) {
$con->rollBack();
throw $e;
}
}
/**
* Performs a DELETE on the database, given a CcSmemb or Criteria object OR a primary key value.
*
* @param mixed $values Criteria or CcSmemb object or primary key or array of primary keys
* which is used to create the DELETE statement
* @param PropelPDO $con the connection to use
* @return int The number of affected rows (if supported by underlying database driver). This includes CASCADE-related rows
* if supported by native driver or if emulated using Propel.
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function doDelete($values, PropelPDO $con = null)
{
if ($con === null) {
$con = Propel::getConnection(CcSmembPeer::DATABASE_NAME, Propel::CONNECTION_WRITE);
}
if ($values instanceof Criteria) {
// invalidate the cache for all objects of this type, since we have no
// way of knowing (without running a query) what objects should be invalidated
// from the cache based on this Criteria.
CcSmembPeer::clearInstancePool();
// rename for clarity
$criteria = clone $values;
} elseif ($values instanceof CcSmemb) { // it's a model object
// invalidate the cache for this single object
CcSmembPeer::removeInstanceFromPool($values);
// create criteria based on pk values
$criteria = $values->buildPkeyCriteria();
} else { // it's a primary key, or an array of pks
$criteria = new Criteria(CcSmembPeer::DATABASE_NAME);
$criteria->add(CcSmembPeer::ID, (array) $values, Criteria::IN);
// invalidate the cache for this object(s)
foreach ((array) $values as $singleval) {
CcSmembPeer::removeInstanceFromPool($singleval);
}
}
// Set the correct dbName
$criteria->setDbName(CcSmembPeer::DATABASE_NAME);
$affectedRows = 0; // initialize var to track total num of affected rows
try {
// use transaction because $criteria could contain info
// for more than one table or we could emulating ON DELETE CASCADE, etc.
$con->beginTransaction();
$affectedRows += BasePeer::doDelete($criteria, $con);
CcSmembPeer::clearRelatedInstancePool();
$con->commit();
return $affectedRows;
} catch (Exception $e) {
$con->rollBack();
throw $e;
}
}
/**
* Validates all modified columns of given CcSmemb object.
* If parameter $columns is either a single column name or an array of column names
* than only those columns are validated.
*
* NOTICE: This does not apply to primary or foreign keys for now.
*
* @param CcSmemb $obj The object to validate.
* @param mixed $cols Column name or array of column names.
*
* @return mixed TRUE if all columns are valid or the error message of the first invalid column.
*/
public static function doValidate($obj, $cols = null)
{
$columns = array();
if ($cols) {
$dbMap = Propel::getDatabaseMap(CcSmembPeer::DATABASE_NAME);
$tableMap = $dbMap->getTable(CcSmembPeer::TABLE_NAME);
if (! is_array($cols)) {
$cols = array($cols);
}
foreach ($cols as $colName) {
if ($tableMap->hasColumn($colName)) {
$get = 'get' . $tableMap->getColumn($colName)->getPhpName();
$columns[$colName] = $obj->$get();
}
}
} else {
}
return BasePeer::doValidate(CcSmembPeer::DATABASE_NAME, CcSmembPeer::TABLE_NAME, $columns);
}
/**
* Retrieve a single object by pkey.
*
* @param int $pk the primary key.
* @param PropelPDO $con the connection to use
* @return CcSmemb
*/
public static function retrieveByPK($pk, PropelPDO $con = null)
{
if (null !== ($obj = CcSmembPeer::getInstanceFromPool((string) $pk))) {
return $obj;
}
if ($con === null) {
$con = Propel::getConnection(CcSmembPeer::DATABASE_NAME, Propel::CONNECTION_READ);
}
$criteria = new Criteria(CcSmembPeer::DATABASE_NAME);
$criteria->add(CcSmembPeer::ID, $pk);
$v = CcSmembPeer::doSelect($criteria, $con);
return !empty($v) > 0 ? $v[0] : null;
}
/**
* Retrieve multiple objects by pkey.
*
* @param array $pks List of primary keys
* @param PropelPDO $con the connection to use
* @return CcSmemb[]
* @throws PropelException Any exceptions caught during processing will be
* rethrown wrapped into a PropelException.
*/
public static function retrieveByPKs($pks, PropelPDO $con = null)
{
if ($con === null) {
$con = Propel::getConnection(CcSmembPeer::DATABASE_NAME, Propel::CONNECTION_READ);
}
$objs = null;
if (empty($pks)) {
$objs = array();
} else {
$criteria = new Criteria(CcSmembPeer::DATABASE_NAME);
$criteria->add(CcSmembPeer::ID, $pks, Criteria::IN);
$objs = CcSmembPeer::doSelect($criteria, $con);
}
return $objs;
}
} // BaseCcSmembPeer
// This is the static code needed to register the TableMap for this table with the main Propel class.
//
BaseCcSmembPeer::buildTableMap();

View File

@ -1,460 +0,0 @@
<?php
/**
* Base class that represents a query for the 'cc_smemb' table.
*
*
*
* @method CcSmembQuery orderById($order = Criteria::ASC) Order by the id column
* @method CcSmembQuery orderByUid($order = Criteria::ASC) Order by the uid column
* @method CcSmembQuery orderByGid($order = Criteria::ASC) Order by the gid column
* @method CcSmembQuery orderByLevel($order = Criteria::ASC) Order by the level column
* @method CcSmembQuery orderByMid($order = Criteria::ASC) Order by the mid column
*
* @method CcSmembQuery groupById() Group by the id column
* @method CcSmembQuery groupByUid() Group by the uid column
* @method CcSmembQuery groupByGid() Group by the gid column
* @method CcSmembQuery groupByLevel() Group by the level column
* @method CcSmembQuery groupByMid() Group by the mid column
*
* @method CcSmembQuery leftJoin($relation) Adds a LEFT JOIN clause to the query
* @method CcSmembQuery rightJoin($relation) Adds a RIGHT JOIN clause to the query
* @method CcSmembQuery innerJoin($relation) Adds a INNER JOIN clause to the query
*
* @method CcSmemb findOne(PropelPDO $con = null) Return the first CcSmemb matching the query
* @method CcSmemb findOneOrCreate(PropelPDO $con = null) Return the first CcSmemb matching the query, or a new CcSmemb object populated from the query conditions when no match is found
*
* @method CcSmemb findOneByUid(int $uid) Return the first CcSmemb filtered by the uid column
* @method CcSmemb findOneByGid(int $gid) Return the first CcSmemb filtered by the gid column
* @method CcSmemb findOneByLevel(int $level) Return the first CcSmemb filtered by the level column
* @method CcSmemb findOneByMid(int $mid) Return the first CcSmemb filtered by the mid column
*
* @method array findById(int $id) Return CcSmemb objects filtered by the id column
* @method array findByUid(int $uid) Return CcSmemb objects filtered by the uid column
* @method array findByGid(int $gid) Return CcSmemb objects filtered by the gid column
* @method array findByLevel(int $level) Return CcSmemb objects filtered by the level column
* @method array findByMid(int $mid) Return CcSmemb objects filtered by the mid column
*
* @package propel.generator.airtime.om
*/
abstract class BaseCcSmembQuery extends ModelCriteria
{
/**
* Initializes internal state of BaseCcSmembQuery object.
*
* @param string $dbName The dabase name
* @param string $modelName The phpName of a model, e.g. 'Book'
* @param string $modelAlias The alias for the model in this query, e.g. 'b'
*/
public function __construct($dbName = null, $modelName = null, $modelAlias = null)
{
if (null === $dbName) {
$dbName = 'airtime';
}
if (null === $modelName) {
$modelName = 'CcSmemb';
}
parent::__construct($dbName, $modelName, $modelAlias);
}
/**
* Returns a new CcSmembQuery object.
*
* @param string $modelAlias The alias of a model in the query
* @param CcSmembQuery|Criteria $criteria Optional Criteria to build the query from
*
* @return CcSmembQuery
*/
public static function create($modelAlias = null, $criteria = null)
{
if ($criteria instanceof CcSmembQuery) {
return $criteria;
}
$query = new CcSmembQuery(null, null, $modelAlias);
if ($criteria instanceof Criteria) {
$query->mergeWith($criteria);
}
return $query;
}
/**
* Find object by primary key.
* Propel uses the instance pool to skip the database if the object exists.
* Go fast if the query is untouched.
*
* <code>
* $obj = $c->findPk(12, $con);
* </code>
*
* @param mixed $key Primary key to use for the query
* @param PropelPDO $con an optional connection object
*
* @return CcSmemb|CcSmemb[]|mixed the result, formatted by the current formatter
*/
public function findPk($key, $con = null)
{
if ($key === null) {
return null;
}
if ((null !== ($obj = CcSmembPeer::getInstanceFromPool((string) $key))) && !$this->formatter) {
// the object is already in the instance pool
return $obj;
}
if ($con === null) {
$con = Propel::getConnection(CcSmembPeer::DATABASE_NAME, Propel::CONNECTION_READ);
}
$this->basePreSelect($con);
if ($this->formatter || $this->modelAlias || $this->with || $this->select
|| $this->selectColumns || $this->asColumns || $this->selectModifiers
|| $this->map || $this->having || $this->joins) {
return $this->findPkComplex($key, $con);
} else {
return $this->findPkSimple($key, $con);
}
}
/**
* Alias of findPk to use instance pooling
*
* @param mixed $key Primary key to use for the query
* @param PropelPDO $con A connection object
*
* @return CcSmemb A model object, or null if the key is not found
* @throws PropelException
*/
public function findOneById($key, $con = null)
{
return $this->findPk($key, $con);
}
/**
* Find object by primary key using raw SQL to go fast.
* Bypass doSelect() and the object formatter by using generated code.
*
* @param mixed $key Primary key to use for the query
* @param PropelPDO $con A connection object
*
* @return CcSmemb A model object, or null if the key is not found
* @throws PropelException
*/
protected function findPkSimple($key, $con)
{
$sql = 'SELECT "id", "uid", "gid", "level", "mid" FROM "cc_smemb" WHERE "id" = :p0';
try {
$stmt = $con->prepare($sql);
$stmt->bindValue(':p0', $key, PDO::PARAM_INT);
$stmt->execute();
} catch (Exception $e) {
Propel::log($e->getMessage(), Propel::LOG_ERR);
throw new PropelException(sprintf('Unable to execute SELECT statement [%s]', $sql), $e);
}
$obj = null;
if ($row = $stmt->fetch(PDO::FETCH_NUM)) {
$obj = new CcSmemb();
$obj->hydrate($row);
CcSmembPeer::addInstanceToPool($obj, (string) $key);
}
$stmt->closeCursor();
return $obj;
}
/**
* Find object by primary key.
*
* @param mixed $key Primary key to use for the query
* @param PropelPDO $con A connection object
*
* @return CcSmemb|CcSmemb[]|mixed the result, formatted by the current formatter
*/
protected function findPkComplex($key, $con)
{
// As the query uses a PK condition, no limit(1) is necessary.
$criteria = $this->isKeepQuery() ? clone $this : $this;
$stmt = $criteria
->filterByPrimaryKey($key)
->doSelect($con);
return $criteria->getFormatter()->init($criteria)->formatOne($stmt);
}
/**
* Find objects by primary key
* <code>
* $objs = $c->findPks(array(12, 56, 832), $con);
* </code>
* @param array $keys Primary keys to use for the query
* @param PropelPDO $con an optional connection object
*
* @return PropelObjectCollection|CcSmemb[]|mixed the list of results, formatted by the current formatter
*/
public function findPks($keys, $con = null)
{
if ($con === null) {
$con = Propel::getConnection($this->getDbName(), Propel::CONNECTION_READ);
}
$this->basePreSelect($con);
$criteria = $this->isKeepQuery() ? clone $this : $this;
$stmt = $criteria
->filterByPrimaryKeys($keys)
->doSelect($con);
return $criteria->getFormatter()->init($criteria)->format($stmt);
}
/**
* Filter the query by primary key
*
* @param mixed $key Primary key to use for the query
*
* @return CcSmembQuery The current query, for fluid interface
*/
public function filterByPrimaryKey($key)
{
return $this->addUsingAlias(CcSmembPeer::ID, $key, Criteria::EQUAL);
}
/**
* Filter the query by a list of primary keys
*
* @param array $keys The list of primary key to use for the query
*
* @return CcSmembQuery The current query, for fluid interface
*/
public function filterByPrimaryKeys($keys)
{
return $this->addUsingAlias(CcSmembPeer::ID, $keys, Criteria::IN);
}
/**
* Filter the query on the id column
*
* Example usage:
* <code>
* $query->filterById(1234); // WHERE id = 1234
* $query->filterById(array(12, 34)); // WHERE id IN (12, 34)
* $query->filterById(array('min' => 12)); // WHERE id >= 12
* $query->filterById(array('max' => 12)); // WHERE id <= 12
* </code>
*
* @param mixed $id The value to use as filter.
* Use scalar values for equality.
* Use array values for in_array() equivalent.
* Use associative array('min' => $minValue, 'max' => $maxValue) for intervals.
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return CcSmembQuery The current query, for fluid interface
*/
public function filterById($id = null, $comparison = null)
{
if (is_array($id)) {
$useMinMax = false;
if (isset($id['min'])) {
$this->addUsingAlias(CcSmembPeer::ID, $id['min'], Criteria::GREATER_EQUAL);
$useMinMax = true;
}
if (isset($id['max'])) {
$this->addUsingAlias(CcSmembPeer::ID, $id['max'], Criteria::LESS_EQUAL);
$useMinMax = true;
}
if ($useMinMax) {
return $this;
}
if (null === $comparison) {
$comparison = Criteria::IN;
}
}
return $this->addUsingAlias(CcSmembPeer::ID, $id, $comparison);
}
/**
* Filter the query on the uid column
*
* Example usage:
* <code>
* $query->filterByUid(1234); // WHERE uid = 1234
* $query->filterByUid(array(12, 34)); // WHERE uid IN (12, 34)
* $query->filterByUid(array('min' => 12)); // WHERE uid >= 12
* $query->filterByUid(array('max' => 12)); // WHERE uid <= 12
* </code>
*
* @param mixed $uid The value to use as filter.
* Use scalar values for equality.
* Use array values for in_array() equivalent.
* Use associative array('min' => $minValue, 'max' => $maxValue) for intervals.
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return CcSmembQuery The current query, for fluid interface
*/
public function filterByUid($uid = null, $comparison = null)
{
if (is_array($uid)) {
$useMinMax = false;
if (isset($uid['min'])) {
$this->addUsingAlias(CcSmembPeer::UID, $uid['min'], Criteria::GREATER_EQUAL);
$useMinMax = true;
}
if (isset($uid['max'])) {
$this->addUsingAlias(CcSmembPeer::UID, $uid['max'], Criteria::LESS_EQUAL);
$useMinMax = true;
}
if ($useMinMax) {
return $this;
}
if (null === $comparison) {
$comparison = Criteria::IN;
}
}
return $this->addUsingAlias(CcSmembPeer::UID, $uid, $comparison);
}
/**
* Filter the query on the gid column
*
* Example usage:
* <code>
* $query->filterByGid(1234); // WHERE gid = 1234
* $query->filterByGid(array(12, 34)); // WHERE gid IN (12, 34)
* $query->filterByGid(array('min' => 12)); // WHERE gid >= 12
* $query->filterByGid(array('max' => 12)); // WHERE gid <= 12
* </code>
*
* @param mixed $gid The value to use as filter.
* Use scalar values for equality.
* Use array values for in_array() equivalent.
* Use associative array('min' => $minValue, 'max' => $maxValue) for intervals.
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return CcSmembQuery The current query, for fluid interface
*/
public function filterByGid($gid = null, $comparison = null)
{
if (is_array($gid)) {
$useMinMax = false;
if (isset($gid['min'])) {
$this->addUsingAlias(CcSmembPeer::GID, $gid['min'], Criteria::GREATER_EQUAL);
$useMinMax = true;
}
if (isset($gid['max'])) {
$this->addUsingAlias(CcSmembPeer::GID, $gid['max'], Criteria::LESS_EQUAL);
$useMinMax = true;
}
if ($useMinMax) {
return $this;
}
if (null === $comparison) {
$comparison = Criteria::IN;
}
}
return $this->addUsingAlias(CcSmembPeer::GID, $gid, $comparison);
}
/**
* Filter the query on the level column
*
* Example usage:
* <code>
* $query->filterByLevel(1234); // WHERE level = 1234
* $query->filterByLevel(array(12, 34)); // WHERE level IN (12, 34)
* $query->filterByLevel(array('min' => 12)); // WHERE level >= 12
* $query->filterByLevel(array('max' => 12)); // WHERE level <= 12
* </code>
*
* @param mixed $level The value to use as filter.
* Use scalar values for equality.
* Use array values for in_array() equivalent.
* Use associative array('min' => $minValue, 'max' => $maxValue) for intervals.
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return CcSmembQuery The current query, for fluid interface
*/
public function filterByLevel($level = null, $comparison = null)
{
if (is_array($level)) {
$useMinMax = false;
if (isset($level['min'])) {
$this->addUsingAlias(CcSmembPeer::LEVEL, $level['min'], Criteria::GREATER_EQUAL);
$useMinMax = true;
}
if (isset($level['max'])) {
$this->addUsingAlias(CcSmembPeer::LEVEL, $level['max'], Criteria::LESS_EQUAL);
$useMinMax = true;
}
if ($useMinMax) {
return $this;
}
if (null === $comparison) {
$comparison = Criteria::IN;
}
}
return $this->addUsingAlias(CcSmembPeer::LEVEL, $level, $comparison);
}
/**
* Filter the query on the mid column
*
* Example usage:
* <code>
* $query->filterByMid(1234); // WHERE mid = 1234
* $query->filterByMid(array(12, 34)); // WHERE mid IN (12, 34)
* $query->filterByMid(array('min' => 12)); // WHERE mid >= 12
* $query->filterByMid(array('max' => 12)); // WHERE mid <= 12
* </code>
*
* @param mixed $mid The value to use as filter.
* Use scalar values for equality.
* Use array values for in_array() equivalent.
* Use associative array('min' => $minValue, 'max' => $maxValue) for intervals.
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return CcSmembQuery The current query, for fluid interface
*/
public function filterByMid($mid = null, $comparison = null)
{
if (is_array($mid)) {
$useMinMax = false;
if (isset($mid['min'])) {
$this->addUsingAlias(CcSmembPeer::MID, $mid['min'], Criteria::GREATER_EQUAL);
$useMinMax = true;
}
if (isset($mid['max'])) {
$this->addUsingAlias(CcSmembPeer::MID, $mid['max'], Criteria::LESS_EQUAL);
$useMinMax = true;
}
if ($useMinMax) {
return $this;
}
if (null === $comparison) {
$comparison = Criteria::IN;
}
}
return $this->addUsingAlias(CcSmembPeer::MID, $mid, $comparison);
}
/**
* Exclude object from result
*
* @param CcSmemb $ccSmemb Object to remove from the list of results
*
* @return CcSmembQuery The current query, for fluid interface
*/
public function prune($ccSmemb = null)
{
if ($ccSmemb) {
$this->addUsingAlias(CcSmembPeer::ID, $ccSmemb->getId(), Criteria::NOT_EQUAL);
}
return $this;
}
}

View File

@ -239,12 +239,12 @@ abstract class AirtimeUpgrader
}
protected function _runUpgrade() {
passthru("export PGPASSWORD=".$this->password." && psql -h ".$this->host." -U ".$this->username." -q -f ".$this->_dir."/upgrade_sql/airtime_"
passthru("export PGPASSWORD=".$this->password." && /usr/bin/psql -h ".$this->host." -U ".$this->username." -q -f ".$this->_dir."/upgrade_sql/airtime_"
.$this->getNewVersion()."/upgrade.sql ".$this->database." 2>&1 | grep -v -E \"will create implicit sequence|will create implicit index\"");
}
protected function _runDowngrade() {
passthru("export PGPASSWORD=".$this->password." && psql -h ".$this->host." -U ".$this->username." -q -f ".$this->_dir."/downgrade_sql/airtime_"
passthru("export PGPASSWORD=".$this->password." && /usr/bin/psql -h ".$this->host." -U ".$this->username." -q -f ".$this->_dir."/downgrade_sql/airtime_"
.$this->getNewVersion()."/downgrade.sql ".$this->database." 2>&1 | grep -v -E \"will create implicit sequence|will create implicit index\"");
}
@ -625,3 +625,16 @@ class AirtimeUpgrader300alpha9_2 extends AirtimeUpgrader
return '3.0.0-alpha.9.2';
}
}
class AirtimeUpgrader200alpha9_3 extends AirtimeUpgrader
{
protected function getSupportedSchemaVersions() {
return array(
'3.0.0-alpha.9.2'
);
}
public function getNewVersion() {
return '3.0.0-alpha.9.3';
}
}

View File

@ -267,4 +267,4 @@
</div>
</body>
</html>
</html>

View File

@ -14,6 +14,11 @@
$used = $disk->totalSpace-$disk->totalFreeSpace;
$total = $disk->totalSpace;
$tracktypes = Application_Model_Tracktype::getTracktypes();
array_multisort(array_map(function($element) {
return $element['type_name'];
}, $tracktypes), SORT_ASC, $tracktypes);
if(count($tracktypes) == 0) {
$hasTracktypes = "disabled";
$showTracktypesDropdown = false;

View File

@ -407,16 +407,6 @@
<index-column name="userid"/>
</index>
</table>
<table name="cc_smemb" phpName="CcSmemb">
<column name="id" phpName="Id" type="INTEGER" primaryKey="true" required="true"/>
<column name="uid" phpName="Uid" type="INTEGER" required="true" defaultValue="0"/>
<column name="gid" phpName="Gid" type="INTEGER" required="true" defaultValue="0"/>
<column name="level" phpName="Level" type="INTEGER" required="true" defaultValue="0"/>
<column name="mid" phpName="Mid" type="INTEGER" required="false"/>
<unique name="cc_smemb_id_idx">
<unique-column name="id"/>
</unique>
</table>
<table name="cc_subjs" phpName="CcSubjs">
<column name="id" phpName="DbId" type="INTEGER" primaryKey="true" autoIncrement="true" required="true"/>
<column name="login" phpName="DbLogin" type="VARCHAR" size="255" required="true" defaultValue=""/>

View File

@ -428,23 +428,6 @@ CREATE INDEX "cc_sess_login_idx" ON "cc_sess" ("login");
CREATE INDEX "cc_sess_userid_idx" ON "cc_sess" ("userid");
-----------------------------------------------------------------------
-- cc_smemb
-----------------------------------------------------------------------
DROP TABLE IF EXISTS "cc_smemb" CASCADE;
CREATE TABLE "cc_smemb"
(
"id" INTEGER NOT NULL,
"uid" INTEGER DEFAULT 0 NOT NULL,
"gid" INTEGER DEFAULT 0 NOT NULL,
"level" INTEGER DEFAULT 0 NOT NULL,
"mid" INTEGER,
PRIMARY KEY ("id"),
CONSTRAINT "cc_smemb_id_idx" UNIQUE ("id")
);
-----------------------------------------------------------------------
-- cc_subjs
-----------------------------------------------------------------------

View File

@ -152,7 +152,7 @@ class DatabaseSetup extends Setup {
* have multiple issues; they similarly die on any SQL errors, fail to read in multi-line
* commands, and fail on any unescaped ? or $ characters.
*/
exec("export PGPASSWORD=" . self::$_properties["dbpass"] . " && psql -U " . self::$_properties["dbuser"]
exec("export PGPASSWORD=" . self::$_properties["dbpass"] . " && /usr/bin/psql -U " . self::$_properties["dbuser"]
. " --dbname " . self::$_properties["dbname"] . " -h " . self::$_properties["host"]
. " -f $sqlDir$f 2>/dev/null", $out, $status);
} catch (Exception $e) {

View File

@ -166,7 +166,7 @@ class AirtimeInstall
echo " * Creating Airtime database user".PHP_EOL;
$username = $CC_CONFIG['dsn']['username'];
$password = $CC_CONFIG['dsn']['password'];
$command = "echo \"CREATE USER $username ENCRYPTED PASSWORD '$password' LOGIN CREATEDB NOCREATEUSER;\" | su postgres -c psql 2>/dev/null";
$command = "echo \"CREATE USER $username ENCRYPTED PASSWORD '$password' LOGIN CREATEDB NOCREATEUSER;\" | su postgres -c /usr/bin/psql 2>/dev/null";
@exec($command, $output, $results);
if ($results == 0) {
echo " * Database user '{$CC_CONFIG['dsn']['username']}' created.".PHP_EOL;
@ -230,7 +230,7 @@ class AirtimeInstall
$dir = self::GetAirtimeSrcDir()."/build/sql/";
$files = array("schema.sql", "sequences.sql", "views.sql", "triggers.sql", "defaultdata.sql");
foreach ($files as $f){
$command = "export PGPASSWORD=$p_dbpasswd && psql --username $p_dbuser --dbname $p_dbname --host $p_dbhost --file $dir$f 2>&1";
$command = "export PGPASSWORD=$p_dbpasswd && /usr/bin/psql --username $p_dbuser --dbname $p_dbname --host $p_dbhost --file $dir$f 2>&1";
@exec($command, $output, $results);
}
AirtimeInstall::$databaseTablesCreated = true;

View File

@ -2,7 +2,7 @@
layout: article
title: Broadcasting live with MIXXX or B.U.T.T.
git: live-broadcast.md
category: dj
category: interface
---
## Live shows with MIXXX {#mixxx}

View File

@ -94,10 +94,10 @@ offers the option to choose a different operation system according to you needs.
| OS | Command | Comment |
| ------ | ------------------- | ------- |
| Debian 10 | `vagrant up debian-buster` | Install on Debian Buster. |
| Debian 9 | `vagrant up debian-stretch` | Install on current Debian Stretch. Needs manual intervention due to Liquidsoap 1.3.3. |
| Debian 9 | `vagrant up debian-stretch` | Install on current Debian Stretch. |
| Ubuntu 18.04 | `vagrant up ubuntu-bionic` | Install on current Ubuntu Bionic Beaver. |
| Ubuntu 16.04 | `vagrant up ubuntu-xenial` | Install on Ubuntu Xenial Xerus. |
| CentOS | `vagrant up centos` | Extremely experimental install on 7.3 with native systemd support and activated SELinux. Needs manual intervention due to Liquidsoap 1.3.3. |
| CentOS | `vagrant up centos` | CentOS 8 with native systemd support and activated SELinux. |
## Troubleshooting

21
install
View File

@ -624,6 +624,7 @@ is_ubuntu_bionic=false
is_ubuntu_xenial=false
is_centos_dist=false
is_centos_7=false
is_centos_8=false
# Use specified distribution and release or detected otherwise.
dist="${dist:-$ID}"
code="${code:-$VERSION_ID}"
@ -682,9 +683,9 @@ case "${dist}-${code}" in
echo -e "The LibreTime installer dropped support for installing LibreTime on Wheezy in 3.0.0-alpha.6." >&2
exit 1
;;
centos-7)
centos-8)
is_centos_dist=true
is_centos_7=true
is_centos_8=true
;;
*)
echo -e "ERROR: Distribution \"$PRETTY_NAME\" is not supported with \"${dist}-${code}\"!" >&2
@ -697,10 +698,12 @@ verbose "Using distribution id \"$dist\", release code \"$code\""
systemInitDetect
if $is_centos_dist; then
python_bin="python3.8"
apache_bin="httpd"
apache_service="httpd"
web_user="${web_user:-apache}"
else
python_bin="python3"
apache_bin="apache2ctl"
apache_service="apache2"
web_user="${web_user:-www-data}"
@ -712,7 +715,7 @@ if [ "$ignore_dependencies" = "f" ]; then
loud " * Installing External Dependencies * "
loud "-----------------------------------------------------"
if [ $is_ubuntu_dist ]; then
if $is_ubuntu_dist; then
loudCmd "add-apt-repository -y ppa:libretime/libretime"
fi
@ -957,11 +960,11 @@ loud "\n-----------------------------------------------------"
loud " * Installing Airtime Services * "
loud "-----------------------------------------------------"
python_version=$(python3 --version 2>&1 | awk '{ print $2 }')
python_version=$($python_bin --version 2>&1 | awk '{ print $2 }')
verbose "Detected Python version: $python_version"
verbose "\n * Installing necessary python services..."
loudCmd "pip3 install setuptools --upgrade"
loudCmd "$python_bin -mpip install setuptools --upgrade"
verbose "...Done"
verbose "\n * Creating /run/airtime..."
@ -984,11 +987,11 @@ if [ ! -d /var/log/airtime ]; then
fi
verbose "\n * Installing API client..."
loudCmd "python3 ${AIRTIMEROOT}/python_apps/api_clients/setup.py install --install-scripts=/usr/bin"
loudCmd "$python_bin ${AIRTIMEROOT}/python_apps/api_clients/setup.py install --install-scripts=/usr/bin"
verbose "...Done"
verbose "\n * Installing pypo and liquidsoap..."
loudCmd "python3 ${AIRTIMEROOT}/python_apps/pypo/setup.py install --install-scripts=/usr/bin --no-init-script"
loudCmd "$python_bin ${AIRTIMEROOT}/python_apps/pypo/setup.py install --install-scripts=/usr/bin --no-init-script"
loudCmd "mkdir -p /var/log/airtime/{pypo,pypo-liquidsoap} /var/tmp/airtime/pypo/{cache,files,tmp} /var/tmp/airtime/show-recorder/"
loudCmd "chown -R ${web_user}:${web_user} /var/log/airtime/{pypo,pypo-liquidsoap} /var/tmp/airtime/pypo/{cache,files,tmp} /var/tmp/airtime/show-recorder/"
systemInitInstall libretime-liquidsoap $web_user
@ -996,7 +999,7 @@ systemInitInstall libretime-playout $web_user
verbose "...Done"
verbose "\n * Installing airtime-celery..."
loudCmd "python3 ${AIRTIMEROOT}/python_apps/airtime-celery/setup.py install --no-init-script"
loudCmd "$python_bin ${AIRTIMEROOT}/python_apps/airtime-celery/setup.py install --no-init-script"
# Create the Celery user
if $is_centos_dist; then
loudCmd "id celery 2>/dev/null || adduser --no-create-home -c 'LibreTime Celery' -r celery || true"
@ -1012,7 +1015,7 @@ systemInitInstall libretime-celery
verbose "...Done"
verbose "\n * Installing airtime_analyzer..."
loudCmd "python3 ${AIRTIMEROOT}/python_apps/airtime_analyzer/setup.py install --install-scripts=/usr/bin --no-init-script"
loudCmd "$python_bin ${AIRTIMEROOT}/python_apps/airtime_analyzer/setup.py install --install-scripts=/usr/bin --no-init-script"
systemInitInstall libretime-analyzer $web_user
verbose "...Done"

View File

@ -3,16 +3,21 @@
# Additional Repos
yum install -y epel-release
# Nux Dextop
yum install -y http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.el7.nux.noarch.rpm
# RPMfusion (for ffmpeg) - needs PowerTools
dnf install -y https://mirrors.rpmfusion.org/free/el/rpmfusion-free-release-8.noarch.rpm
dnf config-manager --enable powertools
# xiph multimedia (for icecast)
curl -o /etc/yum.repos.d/multimedia:xiph.repo \
https://download.opensuse.org/repositories/multimedia:/xiph/CentOS_8/multimedia:xiph.repo
# RaBe Liquidsoap Distribution (RaBe LSD)
curl -o /etc/yum.repos.d/home:radiorabe:liquidsoap.repo \
http://download.opensuse.org/repositories/home:/radiorabe:/liquidsoap/CentOS_7/home:radiorabe:liquidsoap.repo
https://download.opensuse.org/repositories/home:/radiorabe:/liquidsoap/CentOS_8/home:radiorabe:liquidsoap.repo
# RaBe Audio Packages for Enterprise Linux (RaBe APEL)
curl -o /etc/yum.repos.d/home:radiorabe:audio.repo \
http://download.opensuse.org/repositories/home:/radiorabe:/audio/CentOS_7/home:radiorabe:audio.repo
https://download.opensuse.org/repositories/home:/radiorabe:/audio/CentOS_8/home:radiorabe:audio.repo
# Update all the things (just to be sure we are on latest)
yum update -y
@ -20,13 +25,13 @@ yum update -y
# Database
yum install -y postgresql-server patch
postgresql-setup initdb
postgresql-setup --initdb
patch -f /var/lib/pgsql/data/pg_hba.conf << EOD
--- /var/lib/pgsql/data/pg_hba.conf.orig2016-09-01 20:45:11.364000000 -0400
+++ /var/lib/pgsql/data/pg_hba.conf2016-09-01 20:46:17.939000000 -0400
--- pg_hba.conf.orig 2020-12-19 13:10:46.828960307 +0000
+++ pg_hba.conf 2020-12-19 13:11:37.356290128 +0000
@@ -78,10 +78,11 @@
# "local" is for Unix domain socket connections only
local all all peer
+local all all md5
@ -38,7 +43,7 @@ patch -f /var/lib/pgsql/data/pg_hba.conf << EOD
+host all all ::1/128 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
#local replication postgres peer
local replication all peer
EOD
systemctl enable postgresql
@ -55,6 +60,7 @@ echo "GRANT ALL PRIVILEGES ON DATABASE airtime TO airtime;" | su -l postgres bas
# RabbitMQ
curl -s https://packagecloud.io/install/repositories/rabbitmq/rabbitmq-server/script.rpm.sh | sudo bash
yum install -y rabbitmq-server
systemctl enable rabbitmq-server
@ -65,44 +71,56 @@ rabbitmqctl add_vhost /airtime
rabbitmqctl set_permissions -p /airtime airtime ".*" ".*" ".*"
# LibreTime deps
# TODO: move me to requirements-file ala debian e.a.
# some of these are needed to build pip deps and as such should no be installed
# on production grade systems (mostly the -devel packages)
yum install -y \
cairo-gobject-devel \
gcc \
git \
glib2-devel \
gobject-introspection-devel \
openssl-devel \
php \
php-xml \
php-pdo \
php-pgsql \
php-bcmath \
php-mbstring \
php-json \
php-process \
python36-devel \
httpd \
fdk-aac \
liquidsoap \
silan \
ecasound \
alsa-utils \
icecast \
python-pip \
liquidsoap \
alsa-utils \
selinux-policy \
policycoreutils-python \
python-celery \
python2-pika \
policycoreutils-python-utils \
lsof \
xmlstarlet
# for pip ssl install
yum install -y \
gcc \
python-devel \
python-lxml \
openssl-devel
# replace icecast init system with proper systemd unit ("ported" from CentOS 7)
cat > /etc/systemd/system/icecast.service << 'EOD'
[Unit]
Description=Icecast Network Audio Streeaming Server
After=network.target
[Service]
ExecStart=/usr/bin/icecast -c /etc/icecast.xml
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
EOD
# install manually since it isn't required somewhere later
python3 -mpip install pycairo
# SELinux Setup
setsebool -P httpd_can_network_connect 1
setsebool -P httpd_can_network_connect_db 1
setsebool -P httpd_execmem on # needed by liquidsoap to do stuff when called by php
setsebool -P httpd_use_nfs 1 # to get nfs mounted /vagrant
setsebool -P httpd_graceful_shutdown 1 # to allow prefork to shutdown gracefully
setsebool -P git_system_use_nfs 1 # same for git
semanage port -a -t http_port_t -p tcp 9080 # default vagrant web port
@ -117,10 +135,17 @@ restorecon -Rv /vagrant /etc/airtime /srv/airtime
# Disable default apache page
sed -i -e 's/^/#/' /etc/httpd/conf.d/welcome.conf
# Switch to prefork since CentOS will disable mod_php if we use mpm_event
sed -i \
-e 's/#LoadModule mpm_prefork_module/LoadModule mpm_prefork_module/' \
-e 's/LoadModule mpm_event_module/#LoadModule mpm_event_module/' \
/etc/httpd/conf.modules.d/00-mpm.conf
# celery will not run unless we install a specific version (https://github.com/pypa/setuptools/issues/942)
# this will need to be figured out later on and will get overriden by the docs installer anyhow :(
pip install setuptools==33.1.1
pip freeze setuptools==33.1.1
pip3 install setuptools==33.1.1
pip3 freeze setuptools==33.1.1
# the web will fail badly if this is not set, using my personal default just because
echo 'date.timezone=Europe/Zurich' >> /etc/php.d/timezone.ini

View File

@ -34,7 +34,7 @@ s2_namespace = ref ''
s3_namespace = ref ''
just_switched = ref false
%include "ls_lib_legacy.liq"
%include "ls_lib.liq"
sources = ref []
source_id = ref 0

View File

@ -0,0 +1,24 @@
if bitrate == 24 then
ignore(output_stereo(%fdkaac(bitrate = 24, aot="mpeg4_he_aac_v2", afterburner=false, sbr_mode=true), !source))
elsif bitrate == 32 then
ignore(output_stereo(%fdkaac(bitrate = 32, aot="mpeg4_he_aac_v2", afterburner=false, sbr_mode=true), !source))
elsif bitrate == 48 then
ignore(output_stereo(%fdkaac(bitrate = 48, aot="mpeg4_he_aac_v2", afterburner=false, sbr_mode=true), !source))
elsif bitrate == 64 then
ignore(output_stereo(%fdkaac(bitrate = 64, aot="mpeg4_he_aac_v2", afterburner=false, sbr_mode=true), !source))
elsif bitrate == 96 then
ignore(output_stereo(%fdkaac(bitrate = 96, aot="mpeg4_aac_lc", afterburner=false, sbr_mode=true), !source))
elsif bitrate == 128 then
ignore(output_stereo(%fdkaac(bitrate = 128, aot="mpeg4_aac_lc", afterburner=false, sbr_mode=true), !source))
elsif bitrate == 160 then
ignore(output_stereo(%fdkaac(bitrate = 160, aot="mpeg4_aac_lc", afterburner=true, sbr_mode=true), !source))
elsif bitrate == 192 then
ignore(output_stereo(%fdkaac(bitrate = 192, aot="mpeg4_aac_lc", afterburner=true, sbr_mode=true), !source))
elsif bitrate == 224 then
ignore(output_stereo(%fdkaac(bitrate = 224, aot="mpeg4_aac_lc", afterburner=true, sbr_mode=true), !source))
elsif bitrate == 256 then
ignore(output_stereo(%fdkaac(bitrate = 256, aot="mpeg4_aac_lc", afterburner=true, sbr_mode=true), !source))
elsif bitrate == 320 then
ignore(output_stereo(%fdkaac(bitrate = 320, aot="mpeg4_aac_lc", afterburner=true, sbr_mode=true), !source))
end

View File

@ -0,0 +1,68 @@
if bitrate == 24 then
if stereo then
ignore(output_stereo(%mp3(bitrate = 24, stereo = true), !source))
else
ignore(output_mono(%mp3(bitrate = 24, stereo = false), mean(!source)))
end
elsif bitrate == 32 then
if stereo then
ignore(output_stereo(%mp3(bitrate = 32, stereo = true), !source))
else
ignore(output_mono(%mp3(bitrate = 32, stereo = false), mean(!source)))
end
elsif bitrate == 48 then
if stereo then
ignore(output_stereo(%mp3(bitrate = 48, stereo = true), !source))
else
ignore(output_mono(%mp3(bitrate = 48, stereo = false), mean(!source)))
end
elsif bitrate == 64 then
if stereo then
ignore(output_stereo(%mp3(bitrate = 64, stereo = true), !source))
else
ignore(output_mono(%mp3(bitrate = 64, stereo = false), mean(!source)))
end
elsif bitrate == 96 then
if stereo then
ignore(output_stereo(%mp3(bitrate = 96, stereo = true), !source))
else
ignore(output_mono(%mp3(bitrate = 96, stereo = false), mean(!source)))
end
elsif bitrate == 128 then
if stereo then
ignore(output_stereo(%mp3(bitrate = 128, stereo = true), !source))
else
ignore(output_mono(%mp3(bitrate = 128, stereo = false), mean(!source)))
end
elsif bitrate == 160 then
if stereo then
ignore(output_stereo(%mp3(bitrate = 160, stereo = true), !source))
else
ignore(output_mono(%mp3(bitrate = 160, stereo = false), mean(!source)))
end
elsif bitrate == 192 then
if stereo then
ignore(output_stereo(%mp3(bitrate = 192, stereo = true), !source))
else
ignore(output_mono(%mp3(bitrate = 192, stereo = false), mean(!source)))
end
elsif bitrate == 224 then
if stereo then
ignore(output_stereo(%mp3(bitrate = 224, stereo = true), !source))
else
ignore(output_mono(%mp3(bitrate = 224, stereo = false), mean(!source)))
end
elsif bitrate == 256 then
if stereo then
ignore(output_stereo(%mp3(bitrate = 256, stereo = true), !source))
else
ignore(output_mono(%mp3(bitrate = 256, stereo = false), mean(!source)))
end
elsif bitrate == 320 then
if stereo then
ignore(output_stereo(%mp3(bitrate = 320, stereo = true), !source))
else
ignore(output_mono(%mp3(bitrate = 320, stereo = false), mean(!source)))
end
end

View File

@ -0,0 +1,60 @@
if not icecast_vorbis_metadata then
source := add(normalize=false, [amplify(0.00001, noise()), !source])
end
if bitrate == 24 or bitrate == 32 or bitrate == 48 then
if stereo then
ignore(output_stereo(%vorbis(quality=-0.1, channels = 2), !source))
else
ignore(output_mono(%vorbis(quality=-0.1, channels = 1), mean(!source)))
end
elsif bitrate == 64 then
if stereo then
ignore(output_stereo(%vorbis(quality=0, channels = 2), !source))
else
ignore(output_mono(%vorbis(quality=0, channels = 1), mean(!source)))
end
elsif bitrate == 96 then
if stereo then
ignore(output_stereo(%vorbis(quality=0.2, channels = 2), !source))
else
ignore(output_mono(%vorbis(quality=0.2, channels = 1), mean(!source)))
end
elsif bitrate == 128 then
if stereo then
ignore(output_stereo(%vorbis(quality=0.4, channels = 2), !source))
else
ignore(output_mono(%vorbis(quality=0.4, channels = 1), mean(!source)))
end
elsif bitrate == 160 then
if stereo then
ignore(output_stereo(%vorbis(quality=0.5, channels = 2), !source))
else
ignore(output_mono(%vorbis(quality=0.5, channels = 1), mean(!source)))
end
elsif bitrate == 192 then
if stereo then
ignore(output_stereo(%vorbis(quality=0.6, channels = 2), !source))
else
ignore(output_mono(%vorbis(quality=0.6, channels = 1), mean(!source)))
end
elsif bitrate == 224 then
if stereo then
ignore(output_stereo(%vorbis(quality=0.7, channels = 2), !source))
else
ignore(output_mono(%vorbis(quality=0.7, channels = 1), mean(!source)))
end
elsif bitrate == 256 then
if stereo then
ignore(output_stereo(%vorbis(quality=0.8, channels = 2), !source))
else
ignore(output_mono(%vorbis(quality=0.8, channels = 1), mean(!source)))
end
elsif bitrate == 320 then
if stereo then
ignore(output_stereo(%vorbis(quality=0.9, channels = 2), !source))
else
ignore(output_mono(%vorbis(quality=0.9, channels = 1), mean(!source)))
end
end

View File

@ -0,0 +1,68 @@
if bitrate == 24 then
if stereo then
ignore(output_stereo(%opus(bitrate = 24, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
else
ignore(output_mono(%opus(bitrate = 24, channels = 1, signal="music", application="audio", complexity=10, vbr="constrained"), mean(!source)))
end
elsif bitrate == 32 then
if stereo then
ignore(output_stereo(%opus(bitrate = 32, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
else
ignore(output_mono(%opus(bitrate = 32, channels = 1, signal="music", application="audio", complexity=10, vbr="constrained"), mean(!source)))
end
elsif bitrate == 48 then
if stereo then
ignore(output_stereo(%opus(bitrate = 48, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
else
ignore(output_mono(%opus(bitrate = 48, channels = 1, signal="music", application="audio", complexity=10, vbr="constrained"), mean(!source)))
end
elsif bitrate == 64 then
if stereo then
ignore(output_stereo(%opus(bitrate = 64, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
else
ignore(output_mono(%opus(bitrate = 64, channels = 1, signal="music", application="audio", complexity=10, vbr="constrained"), mean(!source)))
end
elsif bitrate == 96 then
if stereo then
ignore(output_stereo(%opus(bitrate = 96, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
else
ignore(output_mono(%opus(bitrate = 96, channels = 1, signal="music", application="audio", complexity=10, vbr="constrained"), mean(!source)))
end
elsif bitrate == 128 then
if stereo then
ignore(output_stereo(%opus(bitrate = 128, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
else
ignore(output_mono(%opus(bitrate = 128, channels = 1, signal="music", application="audio", complexity=10, vbr="constrained"), mean(!source)))
end
elsif bitrate == 160 then
if stereo then
ignore(output_stereo(%opus(bitrate = 160, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
else
ignore(output_mono(%opus(bitrate = 160, channels = 1, signal="music", application="audio", complexity=10, vbr="constrained"), mean(!source)))
end
elsif bitrate == 192 then
if stereo then
ignore(output_stereo(%opus(bitrate = 192, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
else
ignore(output_mono(%opus(bitrate = 192, channels = 1, signal="music", application="audio", complexity=10, vbr="constrained"), mean(!source)))
end
elsif bitrate == 224 then
if stereo then
ignore(output_stereo(%opus(bitrate = 224, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
else
ignore(output_mono(%opus(bitrate = 224, channels = 1, signal="music", application="audio", complexity=10, vbr="constrained"), mean(!source)))
end
elsif bitrate == 256 then
if stereo then
ignore(output_stereo(%opus(bitrate = 256, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
else
ignore(output_mono(%opus(bitrate = 256, channels = 1, signal="music", application="audio", complexity=10, vbr="constrained"), mean(!source)))
end
elsif bitrate == 320 then
if stereo then
ignore(output_stereo(%opus(bitrate = 320, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
else
ignore(output_mono(%opus(bitrate = 320, channels = 1, signal="music", application="audio", complexity=10, vbr="constrained"), mean(!source)))
end
end

View File

@ -0,0 +1,24 @@
if bitrate == 24 then
ignore(output_stereo(%fdkaac(bitrate = 24, aot="mpeg4_he_aac_v2", afterburner=false, sbr_mode=true), !source))
elsif bitrate == 32 then
ignore(output_stereo(%fdkaac(bitrate = 32, aot="mpeg4_he_aac_v2", afterburner=false, sbr_mode=true), !source))
elsif bitrate == 48 then
ignore(output_stereo(%fdkaac(bitrate = 48, aot="mpeg4_he_aac_v2", afterburner=false, sbr_mode=true), !source))
elsif bitrate == 64 then
ignore(output_stereo(%fdkaac(bitrate = 64, aot="mpeg4_he_aac_v2", afterburner=false, sbr_mode=true), !source))
elsif bitrate == 96 then
ignore(output_stereo(%fdkaac(bitrate = 96, aot="mpeg4_aac_lc", afterburner=false, sbr_mode=true), !source))
elsif bitrate == 128 then
ignore(output_stereo(%fdkaac(bitrate = 128, aot="mpeg4_aac_lc", afterburner=false, sbr_mode=true), !source))
elsif bitrate == 160 then
ignore(output_stereo(%fdkaac(bitrate = 160, aot="mpeg4_aac_lc", afterburner=true, sbr_mode=true), !source))
elsif bitrate == 192 then
ignore(output_stereo(%fdkaac(bitrate = 192, aot="mpeg4_aac_lc", afterburner=true, sbr_mode=true), !source))
elsif bitrate == 224 then
ignore(output_stereo(%fdkaac(bitrate = 224, aot="mpeg4_aac_lc", afterburner=true, sbr_mode=true), !source))
elsif bitrate == 256 then
ignore(output_stereo(%fdkaac(bitrate = 256, aot="mpeg4_aac_lc", afterburner=true, sbr_mode=true), !source))
elsif bitrate == 320 then
ignore(output_stereo(%fdkaac(bitrate = 320, aot="mpeg4_aac_lc", afterburner=true, sbr_mode=true), !source))
end

View File

@ -0,0 +1,389 @@
def notify(m)
command = "timeout --signal=KILL 45 pyponotify --media-id=#{m['schedule_table_id']} &"
log(command)
system(command)
end
def notify_queue(m)
f = !dynamic_metadata_callback
ignore(f(m))
notify(m)
end
def notify_stream(m)
json_str = string.replace(pattern="\n",(fun (s) -> ""), json_of(m))
#if a string has a single apostrophe in it, let's comment it out by ending the string before right before it
#escaping the apostrophe, and then starting a new string right after it. This is why we use 3 apostrophes.
json_str = string.replace(pattern="'",(fun (s) -> "'\''"), json_str)
command = "timeout --signal=KILL 45 pyponotify --webstream='#{json_str}' --media-id=#{!current_dyn_id} &"
if !current_dyn_id != "-1" then
log(command)
system(command)
end
end
# A function applied to each metadata chunk
def append_title(m) =
log("Using stream_format #{!stream_metadata_type}")
if list.mem_assoc("mapped", m) then
#protection against applying this function twice. It shouldn't be happening
#and bug file with Liquidsoap.
m
else
if !stream_metadata_type == 1 then
[("title", "#{!show_name} - #{m['artist']} - #{m['title']}"), ("mapped", "true")]
elsif !stream_metadata_type == 2 then
[("title", "#{!station_name} - #{!show_name}"), ("mapped", "true")]
else
if "#{m['artist']}" == "" then
[("title", "#{m['title']}"), ("mapped", "true")]
else
[("title", "#{m['artist']} - #{m['title']}"), ("mapped", "true")]
end
end
end
end
def transition(a,b) =
log("transition called...")
add(normalize=false,
[ sequence([ blank(duration=0.01),
fade.initial(duration=!default_dj_fade, b) ]),
fade.final(duration=!default_dj_fade, a) ])
end
# we need this function for special transition case(from default to queue)
# we don't want the trasition fade to have effect on the first song that would
# be played siwtching out of the default(silent) source
def transition_default(a,b) =
log("transition called...")
if !just_switched then
just_switched := false
add(normalize=false,
[ sequence([ blank(duration=0.01),
fade.initial(duration=!default_dj_fade, b) ]),
fade.final(duration=!default_dj_fade, a) ])
else
just_switched := false
b
end
end
# Define a transition that fades out the
# old source, adds a single, and then
# plays the new source
def to_live(old,new) =
# Fade out old source
old = fade.final(old)
# Compose this in sequence with
# the new source
sequence([old,new])
end
def output_to(output_type, type, bitrate, host, port, pass, mount_point, url, description, genre, user, s, stream, connected, name, channels) =
source = ref s
def on_error(msg)
connected := "false"
command = "timeout --signal=KILL 45 pyponotify --error='#{msg}' --stream-id=#{stream} --time=#{!time} &"
system(command)
log(command)
5.
end
def on_connect()
connected := "true"
command = "timeout --signal=KILL 45 pyponotify --connect --stream-id=#{stream} --time=#{!time} &"
system(command)
log(command)
end
stereo = (channels == "stereo")
if output_type == "icecast" then
user_ref = ref user
if user == "" then
user_ref := "source"
end
output_mono = output.icecast(host = host,
port = port,
password = pass,
mount = mount_point,
fallible = true,
url = url,
description = description,
name = name,
genre = genre,
user = !user_ref,
on_error = on_error,
on_connect = on_connect)
output_stereo = output.icecast(host = host,
port = port,
password = pass,
mount = mount_point,
fallible = true,
url = url,
description = description,
name = name,
genre = genre,
user = !user_ref,
on_error = on_error,
on_connect = on_connect)
if type == "mp3" then
%include "mp3.liq"
end
if type == "ogg" then
%include "ogg.liq"
end
%ifencoder %opus
if type == "opus" then
%include "opus.liq"
end
%endif
%ifencoder %fdkaac
if type == "aac" then
%include "fdkaac.liq"
end
%endif
else
user_ref = ref user
if user == "" then
user_ref := "source"
end
output_mono = output.shoutcast(id = "shoutcast_stream_#{stream}",
host = host,
port = port,
password = pass,
fallible = true,
url = url,
genre = genre,
name = description,
user = !user_ref,
on_error = on_error,
on_connect = on_connect)
output_stereo = output.shoutcast(id = "shoutcast_stream_#{stream}",
host = host,
port = port,
password = pass,
fallible = true,
url = url,
genre = genre,
name = description,
user = !user_ref,
on_error = on_error,
on_connect = on_connect)
if type == "mp3" then
%include "mp3.liq"
end
%ifencoder %fdkaac
if type == "aac" then
%include "fdkaac.liq"
end
%endif
end
end
# Add a skip function to a source
# when it does not have one
# by default
#def add_skip_command(s)
# # A command to skip
# def skip(_)
# # get playing (active) queue and flush it
# l = list.hd(server.execute("queue.secondary_queue"))
# l = string.split(separator=" ",l)
# list.iter(fun (rid) -> ignore(server.execute("queue.remove #{rid}")), l)
#
# l = list.hd(server.execute("queue.primary_queue"))
# l = string.split(separator=" ", l)
# if list.length(l) > 0 then
# source.skip(s)
# "Skipped"
# else
# "Not skipped"
# end
# end
# # Register the command:
# server.register(namespace="source",
# usage="skip",
# description="Skip the current song.",
# "skip",fun(s) -> begin log("source.skip") skip(s) end)
#end
def clear_queue(s)
source.skip(s)
end
def set_dynamic_source_id(id) =
current_dyn_id := id
string_of(!current_dyn_id)
end
def get_dynamic_source_id() =
string_of(!current_dyn_id)
end
#cc-4633
# NOTE
# A few values are hardcoded and may be dependent:
# - the delay in gracetime is linked with the buffer duration of input.http
# (delay should be a bit less than buffer)
# - crossing duration should be less than buffer length
# (at best, a higher duration will be ineffective)
# HTTP input with "restart" command that waits for "stop" to be effected
# before "start" command is issued. Optionally it takes a new URL to play,
# which makes it a convenient replacement for "url".
# In the future, this may become a core feature of the HTTP input.
# TODO If we stop and restart quickly several times in a row,
# the data bursts accumulate and create buffer overflow.
# Flushing the buffer on restart could be a good idea, but
# it would also create an interruptions while the buffer is
# refilling... on the other hand, this would avoid having to
# fade using both cross() and switch().
def input.http_restart(~id,~initial_url="http://dummy/url")
source = audio_to_stereo(input.http(buffer=5.,max=15.,id=id,autostart=false,initial_url))
def stopped()
"stopped" == list.hd(server.execute("#{id}.status"), default="")
end
server.register(namespace=id,
"restart",
usage="restart [url]",
fun (url) -> begin
if url != "" then
log(string_of(server.execute("#{id}.url #{url}")))
end
log(string_of(server.execute("#{id}.stop")))
add_timeout(0.5,
{ if stopped() then
log(string_of(server.execute("#{id}.start"))) ;
(-1.)
else 0.5 end})
"OK"
end)
# Dummy output should be useless if HTTP stream is meant
# to be listened to immediately. Otherwise, apply it.
#
# output.dummy(fallible=true,source)
source
end
# Transitions between URL changes in HTTP streams.
def cross_http(~debug=true,~http_input_id,source)
id = http_input_id
last_url = ref ""
change = ref false
def on_m(m)
notify_stream(m)
changed = m["source_url"] != !last_url
log("URL now #{m['source_url']} (change: #{changed})")
if changed then
if !last_url != "" then change := true end
last_url := m["source_url"]
end
end
# We use both metadata and status to know about the current URL.
# Using only metadata may be more precise is crazy corner cases,
# but it's also asking too much: the metadata may not pass through
# before the crosser is instantiated.
# Using only status in crosser misses some info, eg. on first URL.
source = on_metadata(on_m,source)
cross_d = 3.
def crosser(a,b,ma,mb,sa,sb)
url = list.hd(server.execute('#{id}.url'), default="")
status = list.hd(server.execute('#{id}.status'))
on_m([("source_url",url)])
if debug then
log("New track inside HTTP stream")
log(" status: #{status}")
log(" need to cross: #{!change}")
log(" remaining #{source.remaining(sa)} sec before, \
#{source.remaining(sb)} sec after")
end
if !change then
change := false
# In principle one should avoid crossing on a live stream
# it'd be okay to do it here (eg. use add instead of sequence)
# because it's only once per URL, but be cautious.
sequence([fade.out(duration=cross_d,sa),fade.in(sb)])
else
# This is done on tracks inside a single stream.
# Do NOT cross here or you'll gradually empty the buffer!
sequence([sa,sb])
end
end
# Setting conservative=true would mess with the delayed switch below
cross(duration=cross_d,conservative=false,crosser,source)
end
# Custom fallback between http and default source with fading of
# beginning and end of HTTP stream.
# It does not take potential URL changes into account, as long as
# they do not interrupt streaming (thanks to the HTTP buffer).
def http_fallback(~http_input_id,~http,~default)
id = http_input_id
# We use a custom switching predicate to trigger switching (and thus,
# transitions) before the end of a track (rather, end of HTTP stream).
# It is complexified because we don't want to trigger switching when
# HTTP disconnects for just an instant, when changing URL: for that
# we use gracetime below.
def gracetime(~delay=3.,f)
last_true = ref 0.
{ if f() then
last_true := gettimeofday()
true
else
gettimeofday() < !last_true+delay
end }
end
def connected()
status = list.hd(server.execute("#{id}.status"), default="")
not(list.mem(status,["polling","stopped"]))
end
connected = gracetime(connected)
def to_live(a,b) =
log("TRANSITION to live")
add(normalize=false,
[fade.initial(b),fade.final(a)])
end
def to_static(a,b) =
log("TRANSITION to static")
sequence([fade.out(a),fade.initial(b)])
end
switch(
track_sensitive=false,
transitions=[to_live,to_static],
[(# make sure it is connected, and not buffering
{connected() and source.is_ready(http) and !webstream_enabled}, http),
({true},default)])
end

View File

@ -0,0 +1,462 @@
%include "/etc/airtime/liquidsoap.cfg"
set("log.file.path", log_file)
set("server.telnet", true)
set("server.telnet.port", 1234)
# set("init.daemon.pidfile.path", "/var/run/airtime/airtime-liquidsoap.pid")
#Dynamic source list
#dyn_sources = ref []
webstream_enabled = ref false
time = ref string_of(gettimeofday())
#live stream setup
set("harbor.bind_addr", "0.0.0.0")
current_dyn_id = ref '-1'
pypo_data = ref '0'
stream_metadata_type = ref 0
default_dj_fade = ref 0.
station_name = ref ''
show_name = ref ''
dynamic_metadata_callback = ref fun (~new_track=false, s) -> begin () end
s1_connected = ref ''
s2_connected = ref ''
s3_connected = ref ''
s4_connected = ref ''
s1_namespace = ref ''
s2_namespace = ref ''
s3_namespace = ref ''
just_switched = ref false
%include "ls_lib.liq"
sources = ref []
source_id = ref 0
def check_version(~version=liquidsoap.version, major, minor) =
v = list.map(int_of_string, string.split(separator="\.", version))
list.nth(v,0,default=0) > major or list.nth(v,0,default=0) == major and list.nth(v,1,default=0) >= minor
end
# cue cut fix for liquidsoap <1.2.2
#
# This was most likely broken on 1.1.1 (debian) as well.
#
# adapted from https://github.com/savonet/liquidsoap/issues/390#issuecomment-277562081
#
def fix_cue_in(~cue_in_metadata='liq_cue_in', m) =
# 0.04 might need to be adjusted according to your frame size
if float_of_string(m[cue_in_metadata]) < 0.04 then
[(cue_in_metadata, "0")]
else
[]
end
end
def create_source()
l = request.equeue(id="s#{!source_id}", length=0.5)
l = audio_to_stereo(id="queue_src", l)
l = if not check_version(1, 3) then
map_metadata(fix_cue_in, l)
else
l
end
l = cue_cut(l)
l = amplify(1., override="replay_gain", l)
# the crossfade function controls fade in/out
l = crossfade(duration=0., smart=true, l)
l = on_metadata(notify_queue, l)
sources := list.append([l], !sources)
server.register(namespace="queues",
"s#{!source_id}_skip",
fun (s) -> begin log("queues.s#{!source_id}_skip")
clear_queue(l)
"Done"
end)
source_id := !source_id + 1
end
create_source()
create_source()
create_source()
create_source()
create_source()
create_source()
create_source()
create_source()
queue = add(!sources, normalize=false)
pair = insert_metadata(queue)
dynamic_metadata_callback := fst(pair)
queue = snd(pair)
output.dummy(fallible=true, queue)
http = input.http_restart(id="http")
http = cross_http(http_input_id="http",http)
output.dummy(fallible=true, http)
stream_queue = http_fallback(http_input_id="http", http=http, default=queue)
stream_queue = map_metadata(update=false, append_title, stream_queue)
ignore(output.dummy(stream_queue, fallible=true))
server.register(namespace="vars",
"pypo_data",
fun (s) -> begin log("vars.pypo_data") pypo_data := s "Done" end)
server.register(namespace="vars",
"stream_metadata_type",
fun (s) -> begin log("vars.stream_metadata_type") stream_metadata_type := int_of_string(s) s end)
server.register(namespace="vars",
"show_name",
fun (s) -> begin log("vars.show_name") show_name := s s end)
server.register(namespace="vars",
"station_name",
fun (s) -> begin log("vars.station_name") station_name := s s end)
server.register(namespace="vars",
"bootup_time",
fun (s) -> begin log("vars.bootup_time") time := s s end)
server.register(namespace="streams",
"connection_status",
fun (s) -> begin log("streams.connection_status") "1:#{!s1_connected},2:#{!s2_connected},3:#{!s3_connected},4:#{!s4_connected}" end)
server.register(namespace="vars",
"default_dj_fade",
fun (s) -> begin log("vars.default_dj_fade") default_dj_fade := float_of_string(s) s end)
server.register(namespace="dynamic_source",
description="Enable webstream output",
usage='start',
"output_start",
fun (s) -> begin log("dynamic_source.output_start")
notify([("schedule_table_id", !current_dyn_id)])
webstream_enabled := true "enabled" end)
server.register(namespace="dynamic_source",
description="Enable webstream output",
usage='stop',
"output_stop",
fun (s) -> begin log("dynamic_source.output_stop") webstream_enabled := false "disabled" end)
server.register(namespace="dynamic_source",
description="Set the streams cc_schedule row id",
usage="id <id>",
"id",
fun (s) -> begin log("dynamic_source.id") set_dynamic_source_id(s) end)
server.register(namespace="dynamic_source",
description="Get the streams cc_schedule row id",
usage="get_id",
"get_id",
fun (s) -> begin log("dynamic_source.get_id") get_dynamic_source_id() end)
#server.register(namespace="dynamic_source",
# description="Start a new dynamic source.",
# usage="start <uri>",
# "read_start",
# fun (uri) -> begin log("dynamic_source.read_start") begin_stream_read(uri) end)
#server.register(namespace="dynamic_source",
# description="Stop a dynamic source.",
# usage="stop <id>",
# "read_stop",
# fun (s) -> begin log("dynamic_source.read_stop") stop_stream_read(s) end)
#server.register(namespace="dynamic_source",
# description="Stop a dynamic source.",
# usage="stop <id>",
# "read_stop_all",
# fun (s) -> begin log("dynamic_source.read_stop") destroy_dynamic_source_all() end)
default = amplify(id="silence_src", 0.00001, noise())
ref_off_air_meta = ref off_air_meta
if !ref_off_air_meta == "" then
ref_off_air_meta := "LibreTime - offline"
end
def map_off_air_meta(m) =
[("title", !ref_off_air_meta)]
end
default = map_metadata(map_off_air_meta, default)
ignore(output.dummy(default, fallible=true))
master_dj_enabled = ref false
live_dj_enabled = ref false
scheduled_play_enabled = ref false
def make_master_dj_available()
master_dj_enabled := true
end
def make_master_dj_unavailable()
master_dj_enabled := false
end
def make_live_dj_available()
live_dj_enabled := true
end
def make_live_dj_unavailable()
live_dj_enabled := false
end
def make_scheduled_play_available()
scheduled_play_enabled := true
just_switched := true
end
def make_scheduled_play_unavailable()
scheduled_play_enabled := false
end
def update_source_status(sourcename, status) =
command = "timeout --signal=KILL 45 pyponotify --source-name=#{sourcename} --source-status=#{status} &"
system(command)
log(command)
end
def live_dj_connect(header) =
update_source_status("live_dj", true)
end
def live_dj_disconnect() =
update_source_status("live_dj", false)
end
def master_dj_connect(header) =
update_source_status("master_dj", true)
end
def master_dj_disconnect() =
update_source_status("master_dj", false)
end
# Auth function for live stream
# @Category LiveStream
# @param user Username to check against LibreTime API
# @param password Password to check against LibreTime API
# @param ~type Type of password to check, "dj" or "master, default: "master"
def check_auth(user="", password="", ~type="master") =
log("#{type} user #{user} connected",label="#{type}_source")
# Check auth based on return value from auth script
ret = test_process("python3 #{auth_path} --#{type} #{user} #{password}")
if ret then
log("#{type} user #{user} authenticated",label="#{type}_source")
else
log("#{type} user #{user} auth failed",label="#{type}_source",level=2)
end
ret
end
# Check master source auth
# @Category LiveStream
# @param user Username to check against LibreTime API
# @param password Password to check against LibreTime API
def check_master_dj_client(user, password) =
check_auth(user, password)
end
# Check dj/show source auth
# @Category LiveStream
# @param user Username to check against LibreTime API
# @param password Password to check against LibreTime API
def check_dj_client(user, password) =
check_auth(user, password, type="dj")
end
s = switch(id="schedule_noise_switch",
track_sensitive=false,
transitions=[transition_default, transition],
[({!scheduled_play_enabled}, stream_queue), ({true}, default)]
)
s = if dj_live_stream_port != 0 and dj_live_stream_mp != "" then
dj_live =
audio_to_stereo(
input.harbor(id="live_dj_harbor",
dj_live_stream_mp,
port=dj_live_stream_port,
auth=check_dj_client,
max=40.,
on_connect=live_dj_connect,
on_disconnect=live_dj_disconnect))
ignore(output.dummy(dj_live, fallible=true))
switch(id="show_schedule_noise_switch",
track_sensitive=false,
transitions=[transition, transition],
[({!live_dj_enabled}, dj_live), ({true}, s)]
)
else
s
end
s = if master_live_stream_port != 0 and master_live_stream_mp != "" then
master_dj =
audio_to_stereo(
input.harbor(id="master_harbor",
master_live_stream_mp,
port=master_live_stream_port,
auth=check_master_dj_client,
max=40.,
on_connect=master_dj_connect,
on_disconnect=master_dj_disconnect))
ignore(output.dummy(master_dj, fallible=true))
switch(id="master_show_schedule_noise_switch",
track_sensitive=false,
transitions=[transition, transition],
[({!master_dj_enabled}, master_dj), ({true}, s)]
)
else
s
end
# Attach a skip command to the source s:
#add_skip_command(s)
server.register(namespace="streams",
description="Stop Master DJ source.",
usage="master_dj_stop",
"master_dj_stop",
fun (s) -> begin log("streams.master_dj_stop") make_master_dj_unavailable() "Done." end)
server.register(namespace="streams",
description="Start Master DJ source.",
usage="master_dj_start",
"master_dj_start",
fun (s) -> begin log("streams.master_dj_start") make_master_dj_available() "Done." end)
server.register(namespace="streams",
description="Stop Live DJ source.",
usage="live_dj_stop",
"live_dj_stop",
fun (s) -> begin log("streams.live_dj_stop") make_live_dj_unavailable() "Done." end)
server.register(namespace="streams",
description="Start Live DJ source.",
usage="live_dj_start",
"live_dj_start",
fun (s) -> begin log("streams.live_dj_start") make_live_dj_available() "Done." end)
server.register(namespace="streams",
description="Stop Scheduled Play source.",
usage="scheduled_play_stop",
"scheduled_play_stop",
fun (s) -> begin log("streams.scheduled_play_stop") make_scheduled_play_unavailable() "Done." end)
server.register(namespace="streams",
description="Start Scheduled Play source.",
usage="scheduled_play_start",
"scheduled_play_start",
fun (s) -> begin log("streams.scheduled_play_start") make_scheduled_play_available() "Done." end)
if output_sound_device then
success = ref false
log(output_sound_device_type)
%ifdef output.alsa
if output_sound_device_type == "ALSA" then
ignore(output.alsa(s))
success := true
end
%endif
%ifdef output.ao
if output_sound_device_type == "AO" then
ignore(output.ao(s))
success := true
end
%endif
%ifdef output.oss
if output_sound_device_type == "OSS" then
ignore(output.oss(s))
success := true
end
%endif
%ifdef output.portaudio
if output_sound_device_type == "Portaudio" then
ignore(output.portaudio(s))
success := true
end
%endif
%ifdef output.pulseaudio
if output_sound_device_type == "Pulseaudio" then
ignore(output.pulseaudio(s))
success := true
end
%endif
if (!success == false) then
ignore(output.prefered(s))
end
end
if s1_enable == true then
if s1_output == 'shoutcast' then
s1_namespace := "shoutcast_stream_1"
else
s1_namespace := s1_mount
end
server.register(namespace=!s1_namespace, "connected", fun (s) -> begin log("#{!s1_namespace}.connected") !s1_connected end)
output_to(s1_output, s1_type, s1_bitrate, s1_host, s1_port, s1_pass,
s1_mount, s1_url, s1_description, s1_genre, s1_user, s, "1",
s1_connected, s1_name, s1_channels)
end
if s2_enable == true then
if s2_output == 'shoutcast' then
s2_namespace := "shoutcast_stream_2"
else
s2_namespace := s2_mount
end
server.register(namespace=!s2_namespace, "connected", fun (s) -> begin log("#{!s2_namespace}.connected") !s2_connected end)
output_to(s2_output, s2_type, s2_bitrate, s2_host, s2_port, s2_pass,
s2_mount, s2_url, s2_description, s2_genre, s2_user, s, "2",
s2_connected, s2_name, s2_channels)
end
if s3_enable == true then
if s3_output == 'shoutcast' then
s3_namespace := "shoutcast_stream_3"
else
s3_namespace := s3_mount
end
server.register(namespace=!s3_namespace, "connected", fun (s) -> begin log("#{!s3_namespace}.connected") !s3_connected end)
output_to(s3_output, s3_type, s3_bitrate, s3_host, s3_port, s3_pass,
s3_mount, s3_url, s3_description, s3_genre, s3_user, s, "3",
s3_connected, s3_name, s3_channels)
end
s4_namespace = ref ''
if s4_enable == true then
log("Stream 4 Enabled")
if s4_output == 'shoutcast' then
s4_namespace := "shoutcast_stream_4"
else
s4_namespace := s4_mount
end
server.register(namespace=!s4_namespace, "connected", fun (s) -> begin log("#{!s4_namespace}.connected") !s4_connected end)
output_to(s4_output, s4_type, s4_bitrate, s4_host, s4_port, s4_pass,
s4_mount, s4_url, s4_name, s4_genre, s4_user, s, "4",
s4_connected, s4_description, s4_channels)
end
command = "timeout --signal=KILL 45 pyponotify --liquidsoap-started &"
log(command)
system(command)

View File

@ -0,0 +1,68 @@
if bitrate == 24 then
if stereo then
ignore(output_stereo(%mp3(bitrate = 24, stereo = true), !source))
else
ignore(output_mono(%mp3(bitrate = 24, stereo = false), mean(!source)))
end
elsif bitrate == 32 then
if stereo then
ignore(output_stereo(%mp3(bitrate = 32, stereo = true), !source))
else
ignore(output_mono(%mp3(bitrate = 32, stereo = false), mean(!source)))
end
elsif bitrate == 48 then
if stereo then
ignore(output_stereo(%mp3(bitrate = 48, stereo = true), !source))
else
ignore(output_mono(%mp3(bitrate = 48, stereo = false), mean(!source)))
end
elsif bitrate == 64 then
if stereo then
ignore(output_stereo(%mp3(bitrate = 64, stereo = true), !source))
else
ignore(output_mono(%mp3(bitrate = 64, stereo = false), mean(!source)))
end
elsif bitrate == 96 then
if stereo then
ignore(output_stereo(%mp3(bitrate = 96, stereo = true), !source))
else
ignore(output_mono(%mp3(bitrate = 96, stereo = false), mean(!source)))
end
elsif bitrate == 128 then
if stereo then
ignore(output_stereo(%mp3(bitrate = 128, stereo = true), !source))
else
ignore(output_mono(%mp3(bitrate = 128, stereo = false), mean(!source)))
end
elsif bitrate == 160 then
if stereo then
ignore(output_stereo(%mp3(bitrate = 160, stereo = true), !source))
else
ignore(output_mono(%mp3(bitrate = 160, stereo = false), mean(!source)))
end
elsif bitrate == 192 then
if stereo then
ignore(output_stereo(%mp3(bitrate = 192, stereo = true), !source))
else
ignore(output_mono(%mp3(bitrate = 192, stereo = false), mean(!source)))
end
elsif bitrate == 224 then
if stereo then
ignore(output_stereo(%mp3(bitrate = 224, stereo = true), !source))
else
ignore(output_mono(%mp3(bitrate = 224, stereo = false), mean(!source)))
end
elsif bitrate == 256 then
if stereo then
ignore(output_stereo(%mp3(bitrate = 256, stereo = true), !source))
else
ignore(output_mono(%mp3(bitrate = 256, stereo = false), mean(!source)))
end
elsif bitrate == 320 then
if stereo then
ignore(output_stereo(%mp3(bitrate = 320, stereo = true), !source))
else
ignore(output_mono(%mp3(bitrate = 320, stereo = false), mean(!source)))
end
end

View File

@ -0,0 +1,60 @@
if not icecast_vorbis_metadata then
source := add(normalize=false, [amplify(0.00001, noise()), !source])
end
if bitrate == 24 or bitrate == 32 or bitrate == 48 then
if stereo then
ignore(output_stereo(%vorbis(quality=-0.1, channels = 2), !source))
else
ignore(output_mono(%vorbis(quality=-0.1, channels = 1), mean(!source)))
end
elsif bitrate == 64 then
if stereo then
ignore(output_stereo(%vorbis(quality=0, channels = 2), !source))
else
ignore(output_mono(%vorbis(quality=0, channels = 1), mean(!source)))
end
elsif bitrate == 96 then
if stereo then
ignore(output_stereo(%vorbis(quality=0.2, channels = 2), !source))
else
ignore(output_mono(%vorbis(quality=0.2, channels = 1), mean(!source)))
end
elsif bitrate == 128 then
if stereo then
ignore(output_stereo(%vorbis(quality=0.4, channels = 2), !source))
else
ignore(output_mono(%vorbis(quality=0.4, channels = 1), mean(!source)))
end
elsif bitrate == 160 then
if stereo then
ignore(output_stereo(%vorbis(quality=0.5, channels = 2), !source))
else
ignore(output_mono(%vorbis(quality=0.5, channels = 1), mean(!source)))
end
elsif bitrate == 192 then
if stereo then
ignore(output_stereo(%vorbis(quality=0.6, channels = 2), !source))
else
ignore(output_mono(%vorbis(quality=0.6, channels = 1), mean(!source)))
end
elsif bitrate == 224 then
if stereo then
ignore(output_stereo(%vorbis(quality=0.7, channels = 2), !source))
else
ignore(output_mono(%vorbis(quality=0.7, channels = 1), mean(!source)))
end
elsif bitrate == 256 then
if stereo then
ignore(output_stereo(%vorbis(quality=0.8, channels = 2), !source))
else
ignore(output_mono(%vorbis(quality=0.8, channels = 1), mean(!source)))
end
elsif bitrate == 320 then
if stereo then
ignore(output_stereo(%vorbis(quality=0.9, channels = 2), !source))
else
ignore(output_mono(%vorbis(quality=0.9, channels = 1), mean(!source)))
end
end

View File

@ -0,0 +1,68 @@
if bitrate == 24 then
if stereo then
ignore(output_stereo(%opus(bitrate = 24, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
else
ignore(output_mono(%opus(bitrate = 24, channels = 1, signal="music", application="audio", complexity=10, vbr="constrained"), mean(!source)))
end
elsif bitrate == 32 then
if stereo then
ignore(output_stereo(%opus(bitrate = 32, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
else
ignore(output_mono(%opus(bitrate = 32, channels = 1, signal="music", application="audio", complexity=10, vbr="constrained"), mean(!source)))
end
elsif bitrate == 48 then
if stereo then
ignore(output_stereo(%opus(bitrate = 48, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
else
ignore(output_mono(%opus(bitrate = 48, channels = 1, signal="music", application="audio", complexity=10, vbr="constrained"), mean(!source)))
end
elsif bitrate == 64 then
if stereo then
ignore(output_stereo(%opus(bitrate = 64, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
else
ignore(output_mono(%opus(bitrate = 64, channels = 1, signal="music", application="audio", complexity=10, vbr="constrained"), mean(!source)))
end
elsif bitrate == 96 then
if stereo then
ignore(output_stereo(%opus(bitrate = 96, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
else
ignore(output_mono(%opus(bitrate = 96, channels = 1, signal="music", application="audio", complexity=10, vbr="constrained"), mean(!source)))
end
elsif bitrate == 128 then
if stereo then
ignore(output_stereo(%opus(bitrate = 128, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
else
ignore(output_mono(%opus(bitrate = 128, channels = 1, signal="music", application="audio", complexity=10, vbr="constrained"), mean(!source)))
end
elsif bitrate == 160 then
if stereo then
ignore(output_stereo(%opus(bitrate = 160, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
else
ignore(output_mono(%opus(bitrate = 160, channels = 1, signal="music", application="audio", complexity=10, vbr="constrained"), mean(!source)))
end
elsif bitrate == 192 then
if stereo then
ignore(output_stereo(%opus(bitrate = 192, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
else
ignore(output_mono(%opus(bitrate = 192, channels = 1, signal="music", application="audio", complexity=10, vbr="constrained"), mean(!source)))
end
elsif bitrate == 224 then
if stereo then
ignore(output_stereo(%opus(bitrate = 224, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
else
ignore(output_mono(%opus(bitrate = 224, channels = 1, signal="music", application="audio", complexity=10, vbr="constrained"), mean(!source)))
end
elsif bitrate == 256 then
if stereo then
ignore(output_stereo(%opus(bitrate = 256, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
else
ignore(output_mono(%opus(bitrate = 256, channels = 1, signal="music", application="audio", complexity=10, vbr="constrained"), mean(!source)))
end
elsif bitrate == 320 then
if stereo then
ignore(output_stereo(%opus(bitrate = 320, channels = 2, signal="music", application="audio", complexity=10, vbr="constrained"), !source))
else
ignore(output_mono(%opus(bitrate = 320, channels = 1, signal="music", application="audio", complexity=10, vbr="constrained"), mean(!source)))
end
end

View File

@ -7,10 +7,11 @@ import logging
import subprocess
from pypo import pure
PYPO_HOME = '/var/tmp/airtime/pypo/'
PYPO_HOME = "/var/tmp/airtime/pypo/"
def run():
'''Entry-point for this application'''
"""Entry-point for this application"""
print("Airtime Liquidsoap")
parser = argparse.ArgumentParser()
parser.add_argument("-d", "--debug", help="run in debug mode", action="store_true")
@ -19,18 +20,29 @@ def run():
os.environ["HOME"] = PYPO_HOME
if args.debug:
logging.basicConfig(level=getattr(logging, 'DEBUG', None))
logging.basicConfig(level=getattr(logging, "DEBUG", None))
generate_liquidsoap_cfg.run()
''' check liquidsoap version if less than 1.3 use legacy liquidsoap script '''
liquidsoap_version = subprocess.check_output("liquidsoap --version", shell=True, universal_newlines=True)
if "1.1.1" not in liquidsoap_version:
script_path = os.path.join(os.path.dirname(__file__), 'ls_script.liq')
else:
script_path = os.path.join(os.path.dirname(__file__), 'ls_script_legacy.liq')
""" check liquidsoap version so we can run a scripts matching the liquidsoap minor version """
liquidsoap_version = subprocess.check_output(
"liquidsoap --force-start 'print(liquidsoap.version) shutdown()'",
shell=True,
universal_newlines=True,
)[0:3]
script_path = os.path.join(
os.path.dirname(__file__), liquidsoap_version, "ls_script.liq"
)
exec_args = [
"/usr/bin/liquidsoap",
"airtime-liquidsoap",
script_path,
"--verbose",
"-f",
]
if args.debug:
os.execl('/usr/bin/liquidsoap', 'airtime-liquidsoap', script_path, '--verbose', '-f', '--debug')
else:
os.execl('/usr/bin/liquidsoap', 'airtime-liquidsoap', script_path, '--verbose', '-f')
print(f"Liquidsoap {liquidsoap_version} using script: {script_path}")
exec_args.append("--debug")
os.execl(*exec_args)
run()

View File

@ -40,7 +40,7 @@ setup(name='airtime-playout',
license='AGPLv3',
packages=['pypo', 'pypo.media', 'pypo.media.update',
'liquidsoap'],
package_data={'': ['*.liq', '*.cfg', '*.types']},
package_data={'': ['**/*.liq', '*.cfg', '*.types']},
scripts=[
'bin/airtime-playout',
'bin/airtime-liquidsoap',