Add downgrade action to UpgradeController, fix SoundCloud schema and bugs

This commit is contained in:
Duncan Sommerville 2015-06-24 18:38:04 -04:00
parent 8fcaf7fc74
commit 67155b136a
14 changed files with 361 additions and 93 deletions

View file

@ -33,4 +33,35 @@ class UpgradeController extends Zend_Controller_Action
->appendBody($e->getMessage()); ->appendBody($e->getMessage());
} }
} }
public function downgradeAction() {
$this->view->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);
if (!RestAuth::verifyAuth(true, false, $this)) {
return;
}
$request = $this->getRequest();
$toVersion = $request->getParam("version");
try {
$downgradePerformed = UpgradeManager::doDowngrade($toVersion);
if (!$downgradePerformed) {
$this->getResponse()
->setHttpResponseCode(200)
->appendBody("No downgrade was performed. The current schema version is " . Application_Model_Preference::GetSchemaVersion() . ".<br>");
} else {
$this->getResponse()
->setHttpResponseCode(200)
->appendBody("Downgrade to Airtime schema version " . Application_Model_Preference::GetSchemaVersion() . " OK<br>");
}
} catch (Exception $e) {
$this->getResponse()
->setHttpResponseCode(400)
->appendBody($e->getMessage());
}
}
} }

View file

@ -0,0 +1,11 @@
-----------------------------------------------------------------------
-- third_party_track_references
-----------------------------------------------------------------------
DROP TABLE IF EXISTS "third_party_track_references" CASCADE;
-----------------------------------------------------------------------
-- celery_tasks
-----------------------------------------------------------------------
DROP TABLE IF EXISTS "celery_tasks" CASCADE;

View file

@ -20,7 +20,8 @@ CREATE TABLE IF NOT EXISTS "third_party_track_references"
CREATE TABLE IF NOT EXISTS "celery_tasks" CREATE TABLE IF NOT EXISTS "celery_tasks"
( (
"id" VARCHAR(256) NOT NULL, "id" serial NOT NULL,
"task_id" VARCHAR(256) NOT NULL,
"track_reference" INTEGER NOT NULL, "track_reference" INTEGER NOT NULL,
"name" VARCHAR(256), "name" VARCHAR(256),
"dispatch_time" TIMESTAMP, "dispatch_time" TIMESTAMP,

View file

@ -36,9 +36,11 @@ class CeleryTasksTableMap extends TableMap
$this->setPhpName('CeleryTasks'); $this->setPhpName('CeleryTasks');
$this->setClassname('CeleryTasks'); $this->setClassname('CeleryTasks');
$this->setPackage('airtime'); $this->setPackage('airtime');
$this->setUseIdGenerator(false); $this->setUseIdGenerator(true);
$this->setPrimaryKeyMethodInfo('celery_tasks_id_seq');
// columns // columns
$this->addPrimaryKey('id', 'DbId', 'VARCHAR', true, 256, null); $this->addPrimaryKey('id', 'DbId', 'INTEGER', true, null, null);
$this->addColumn('task_id', 'DbTaskId', 'VARCHAR', true, 256, null);
$this->addForeignKey('track_reference', 'DbTrackReference', 'INTEGER', 'third_party_track_references', 'id', true, null, null); $this->addForeignKey('track_reference', 'DbTrackReference', 'INTEGER', 'third_party_track_references', 'id', true, null, null);
$this->addColumn('name', 'DbName', 'VARCHAR', false, 256, null); $this->addColumn('name', 'DbName', 'VARCHAR', false, 256, null);
$this->addColumn('dispatch_time', 'DbDispatchTime', 'TIMESTAMP', false, null, null); $this->addColumn('dispatch_time', 'DbDispatchTime', 'TIMESTAMP', false, null, null);

View file

@ -31,10 +31,16 @@ abstract class BaseCeleryTasks extends BaseObject implements Persistent
/** /**
* The value for the id field. * The value for the id field.
* @var string * @var int
*/ */
protected $id; protected $id;
/**
* The value for the task_id field.
* @var string
*/
protected $task_id;
/** /**
* The value for the track_reference field. * The value for the track_reference field.
* @var int * @var int
@ -87,7 +93,7 @@ abstract class BaseCeleryTasks extends BaseObject implements Persistent
/** /**
* Get the [id] column value. * Get the [id] column value.
* *
* @return string * @return int
*/ */
public function getDbId() public function getDbId()
{ {
@ -95,6 +101,17 @@ abstract class BaseCeleryTasks extends BaseObject implements Persistent
return $this->id; return $this->id;
} }
/**
* Get the [task_id] column value.
*
* @return string
*/
public function getDbTaskId()
{
return $this->task_id;
}
/** /**
* Get the [track_reference] column value. * Get the [track_reference] column value.
* *
@ -166,13 +183,13 @@ abstract class BaseCeleryTasks extends BaseObject implements Persistent
/** /**
* Set the value of [id] column. * Set the value of [id] column.
* *
* @param string $v new value * @param int $v new value
* @return CeleryTasks The current object (for fluent API support) * @return CeleryTasks The current object (for fluent API support)
*/ */
public function setDbId($v) public function setDbId($v)
{ {
if ($v !== null && is_numeric($v)) { if ($v !== null && is_numeric($v)) {
$v = (string) $v; $v = (int) $v;
} }
if ($this->id !== $v) { if ($this->id !== $v) {
@ -184,6 +201,27 @@ abstract class BaseCeleryTasks extends BaseObject implements Persistent
return $this; return $this;
} // setDbId() } // setDbId()
/**
* Set the value of [task_id] column.
*
* @param string $v new value
* @return CeleryTasks The current object (for fluent API support)
*/
public function setDbTaskId($v)
{
if ($v !== null && is_numeric($v)) {
$v = (string) $v;
}
if ($this->task_id !== $v) {
$this->task_id = $v;
$this->modifiedColumns[] = CeleryTasksPeer::TASK_ID;
}
return $this;
} // setDbTaskId()
/** /**
* Set the value of [track_reference] column. * Set the value of [track_reference] column.
* *
@ -306,11 +344,12 @@ abstract class BaseCeleryTasks extends BaseObject implements Persistent
{ {
try { try {
$this->id = ($row[$startcol + 0] !== null) ? (string) $row[$startcol + 0] : null; $this->id = ($row[$startcol + 0] !== null) ? (int) $row[$startcol + 0] : null;
$this->track_reference = ($row[$startcol + 1] !== null) ? (int) $row[$startcol + 1] : null; $this->task_id = ($row[$startcol + 1] !== null) ? (string) $row[$startcol + 1] : null;
$this->name = ($row[$startcol + 2] !== null) ? (string) $row[$startcol + 2] : null; $this->track_reference = ($row[$startcol + 2] !== null) ? (int) $row[$startcol + 2] : null;
$this->dispatch_time = ($row[$startcol + 3] !== null) ? (string) $row[$startcol + 3] : null; $this->name = ($row[$startcol + 3] !== null) ? (string) $row[$startcol + 3] : null;
$this->status = ($row[$startcol + 4] !== null) ? (string) $row[$startcol + 4] : null; $this->dispatch_time = ($row[$startcol + 4] !== null) ? (string) $row[$startcol + 4] : null;
$this->status = ($row[$startcol + 5] !== null) ? (string) $row[$startcol + 5] : null;
$this->resetModified(); $this->resetModified();
$this->setNew(false); $this->setNew(false);
@ -320,7 +359,7 @@ abstract class BaseCeleryTasks extends BaseObject implements Persistent
} }
$this->postHydrate($row, $startcol, $rehydrate); $this->postHydrate($row, $startcol, $rehydrate);
return $startcol + 5; // 5 = CeleryTasksPeer::NUM_HYDRATE_COLUMNS. return $startcol + 6; // 6 = CeleryTasksPeer::NUM_HYDRATE_COLUMNS.
} catch (Exception $e) { } catch (Exception $e) {
throw new PropelException("Error populating CeleryTasks object", $e); throw new PropelException("Error populating CeleryTasks object", $e);
@ -542,11 +581,28 @@ abstract class BaseCeleryTasks extends BaseObject implements Persistent
$modifiedColumns = array(); $modifiedColumns = array();
$index = 0; $index = 0;
$this->modifiedColumns[] = CeleryTasksPeer::ID;
if (null !== $this->id) {
throw new PropelException('Cannot insert a value for auto-increment primary key (' . CeleryTasksPeer::ID . ')');
}
if (null === $this->id) {
try {
$stmt = $con->query("SELECT nextval('celery_tasks_id_seq')");
$row = $stmt->fetch(PDO::FETCH_NUM);
$this->id = $row[0];
} catch (Exception $e) {
throw new PropelException('Unable to get sequence id.', $e);
}
}
// check the columns in natural order for more readable SQL queries // check the columns in natural order for more readable SQL queries
if ($this->isColumnModified(CeleryTasksPeer::ID)) { if ($this->isColumnModified(CeleryTasksPeer::ID)) {
$modifiedColumns[':p' . $index++] = '"id"'; $modifiedColumns[':p' . $index++] = '"id"';
} }
if ($this->isColumnModified(CeleryTasksPeer::TASK_ID)) {
$modifiedColumns[':p' . $index++] = '"task_id"';
}
if ($this->isColumnModified(CeleryTasksPeer::TRACK_REFERENCE)) { if ($this->isColumnModified(CeleryTasksPeer::TRACK_REFERENCE)) {
$modifiedColumns[':p' . $index++] = '"track_reference"'; $modifiedColumns[':p' . $index++] = '"track_reference"';
} }
@ -571,7 +627,10 @@ abstract class BaseCeleryTasks extends BaseObject implements Persistent
foreach ($modifiedColumns as $identifier => $columnName) { foreach ($modifiedColumns as $identifier => $columnName) {
switch ($columnName) { switch ($columnName) {
case '"id"': case '"id"':
$stmt->bindValue($identifier, $this->id, PDO::PARAM_STR); $stmt->bindValue($identifier, $this->id, PDO::PARAM_INT);
break;
case '"task_id"':
$stmt->bindValue($identifier, $this->task_id, PDO::PARAM_STR);
break; break;
case '"track_reference"': case '"track_reference"':
$stmt->bindValue($identifier, $this->track_reference, PDO::PARAM_INT); $stmt->bindValue($identifier, $this->track_reference, PDO::PARAM_INT);
@ -728,15 +787,18 @@ abstract class BaseCeleryTasks extends BaseObject implements Persistent
return $this->getDbId(); return $this->getDbId();
break; break;
case 1: case 1:
return $this->getDbTrackReference(); return $this->getDbTaskId();
break; break;
case 2: case 2:
return $this->getDbName(); return $this->getDbTrackReference();
break; break;
case 3: case 3:
return $this->getDbDispatchTime(); return $this->getDbName();
break; break;
case 4: case 4:
return $this->getDbDispatchTime();
break;
case 5:
return $this->getDbStatus(); return $this->getDbStatus();
break; break;
default: default:
@ -769,10 +831,11 @@ abstract class BaseCeleryTasks extends BaseObject implements Persistent
$keys = CeleryTasksPeer::getFieldNames($keyType); $keys = CeleryTasksPeer::getFieldNames($keyType);
$result = array( $result = array(
$keys[0] => $this->getDbId(), $keys[0] => $this->getDbId(),
$keys[1] => $this->getDbTrackReference(), $keys[1] => $this->getDbTaskId(),
$keys[2] => $this->getDbName(), $keys[2] => $this->getDbTrackReference(),
$keys[3] => $this->getDbDispatchTime(), $keys[3] => $this->getDbName(),
$keys[4] => $this->getDbStatus(), $keys[4] => $this->getDbDispatchTime(),
$keys[5] => $this->getDbStatus(),
); );
$virtualColumns = $this->virtualColumns; $virtualColumns = $this->virtualColumns;
foreach ($virtualColumns as $key => $virtualColumn) { foreach ($virtualColumns as $key => $virtualColumn) {
@ -821,15 +884,18 @@ abstract class BaseCeleryTasks extends BaseObject implements Persistent
$this->setDbId($value); $this->setDbId($value);
break; break;
case 1: case 1:
$this->setDbTrackReference($value); $this->setDbTaskId($value);
break; break;
case 2: case 2:
$this->setDbName($value); $this->setDbTrackReference($value);
break; break;
case 3: case 3:
$this->setDbDispatchTime($value); $this->setDbName($value);
break; break;
case 4: case 4:
$this->setDbDispatchTime($value);
break;
case 5:
$this->setDbStatus($value); $this->setDbStatus($value);
break; break;
} // switch() } // switch()
@ -857,10 +923,11 @@ abstract class BaseCeleryTasks extends BaseObject implements Persistent
$keys = CeleryTasksPeer::getFieldNames($keyType); $keys = CeleryTasksPeer::getFieldNames($keyType);
if (array_key_exists($keys[0], $arr)) $this->setDbId($arr[$keys[0]]); if (array_key_exists($keys[0], $arr)) $this->setDbId($arr[$keys[0]]);
if (array_key_exists($keys[1], $arr)) $this->setDbTrackReference($arr[$keys[1]]); if (array_key_exists($keys[1], $arr)) $this->setDbTaskId($arr[$keys[1]]);
if (array_key_exists($keys[2], $arr)) $this->setDbName($arr[$keys[2]]); if (array_key_exists($keys[2], $arr)) $this->setDbTrackReference($arr[$keys[2]]);
if (array_key_exists($keys[3], $arr)) $this->setDbDispatchTime($arr[$keys[3]]); if (array_key_exists($keys[3], $arr)) $this->setDbName($arr[$keys[3]]);
if (array_key_exists($keys[4], $arr)) $this->setDbStatus($arr[$keys[4]]); if (array_key_exists($keys[4], $arr)) $this->setDbDispatchTime($arr[$keys[4]]);
if (array_key_exists($keys[5], $arr)) $this->setDbStatus($arr[$keys[5]]);
} }
/** /**
@ -873,6 +940,7 @@ abstract class BaseCeleryTasks extends BaseObject implements Persistent
$criteria = new Criteria(CeleryTasksPeer::DATABASE_NAME); $criteria = new Criteria(CeleryTasksPeer::DATABASE_NAME);
if ($this->isColumnModified(CeleryTasksPeer::ID)) $criteria->add(CeleryTasksPeer::ID, $this->id); if ($this->isColumnModified(CeleryTasksPeer::ID)) $criteria->add(CeleryTasksPeer::ID, $this->id);
if ($this->isColumnModified(CeleryTasksPeer::TASK_ID)) $criteria->add(CeleryTasksPeer::TASK_ID, $this->task_id);
if ($this->isColumnModified(CeleryTasksPeer::TRACK_REFERENCE)) $criteria->add(CeleryTasksPeer::TRACK_REFERENCE, $this->track_reference); if ($this->isColumnModified(CeleryTasksPeer::TRACK_REFERENCE)) $criteria->add(CeleryTasksPeer::TRACK_REFERENCE, $this->track_reference);
if ($this->isColumnModified(CeleryTasksPeer::NAME)) $criteria->add(CeleryTasksPeer::NAME, $this->name); if ($this->isColumnModified(CeleryTasksPeer::NAME)) $criteria->add(CeleryTasksPeer::NAME, $this->name);
if ($this->isColumnModified(CeleryTasksPeer::DISPATCH_TIME)) $criteria->add(CeleryTasksPeer::DISPATCH_TIME, $this->dispatch_time); if ($this->isColumnModified(CeleryTasksPeer::DISPATCH_TIME)) $criteria->add(CeleryTasksPeer::DISPATCH_TIME, $this->dispatch_time);
@ -899,7 +967,7 @@ abstract class BaseCeleryTasks extends BaseObject implements Persistent
/** /**
* Returns the primary key for this object (row). * Returns the primary key for this object (row).
* @return string * @return int
*/ */
public function getPrimaryKey() public function getPrimaryKey()
{ {
@ -909,7 +977,7 @@ abstract class BaseCeleryTasks extends BaseObject implements Persistent
/** /**
* Generic method to set the primary key (id column). * Generic method to set the primary key (id column).
* *
* @param string $key Primary key. * @param int $key Primary key.
* @return void * @return void
*/ */
public function setPrimaryKey($key) public function setPrimaryKey($key)
@ -940,6 +1008,7 @@ abstract class BaseCeleryTasks extends BaseObject implements Persistent
*/ */
public function copyInto($copyObj, $deepCopy = false, $makeNew = true) public function copyInto($copyObj, $deepCopy = false, $makeNew = true)
{ {
$copyObj->setDbTaskId($this->getDbTaskId());
$copyObj->setDbTrackReference($this->getDbTrackReference()); $copyObj->setDbTrackReference($this->getDbTrackReference());
$copyObj->setDbName($this->getDbName()); $copyObj->setDbName($this->getDbName());
$copyObj->setDbDispatchTime($this->getDbDispatchTime()); $copyObj->setDbDispatchTime($this->getDbDispatchTime());
@ -1060,6 +1129,7 @@ abstract class BaseCeleryTasks extends BaseObject implements Persistent
public function clear() public function clear()
{ {
$this->id = null; $this->id = null;
$this->task_id = null;
$this->track_reference = null; $this->track_reference = null;
$this->name = null; $this->name = null;
$this->dispatch_time = null; $this->dispatch_time = null;

View file

@ -24,17 +24,20 @@ abstract class BaseCeleryTasksPeer
const TM_CLASS = 'CeleryTasksTableMap'; const TM_CLASS = 'CeleryTasksTableMap';
/** The total number of columns. */ /** The total number of columns. */
const NUM_COLUMNS = 5; const NUM_COLUMNS = 6;
/** The number of lazy-loaded columns. */ /** The number of lazy-loaded columns. */
const NUM_LAZY_LOAD_COLUMNS = 0; const NUM_LAZY_LOAD_COLUMNS = 0;
/** The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */ /** The number of columns to hydrate (NUM_COLUMNS - NUM_LAZY_LOAD_COLUMNS) */
const NUM_HYDRATE_COLUMNS = 5; const NUM_HYDRATE_COLUMNS = 6;
/** the column name for the id field */ /** the column name for the id field */
const ID = 'celery_tasks.id'; const ID = 'celery_tasks.id';
/** the column name for the task_id field */
const TASK_ID = 'celery_tasks.task_id';
/** the column name for the track_reference field */ /** the column name for the track_reference field */
const TRACK_REFERENCE = 'celery_tasks.track_reference'; const TRACK_REFERENCE = 'celery_tasks.track_reference';
@ -66,12 +69,12 @@ abstract class BaseCeleryTasksPeer
* e.g. CeleryTasksPeer::$fieldNames[CeleryTasksPeer::TYPE_PHPNAME][0] = 'Id' * e.g. CeleryTasksPeer::$fieldNames[CeleryTasksPeer::TYPE_PHPNAME][0] = 'Id'
*/ */
protected static $fieldNames = array ( protected static $fieldNames = array (
BasePeer::TYPE_PHPNAME => array ('DbId', 'DbTrackReference', 'DbName', 'DbDispatchTime', 'DbStatus', ), BasePeer::TYPE_PHPNAME => array ('DbId', 'DbTaskId', 'DbTrackReference', 'DbName', 'DbDispatchTime', 'DbStatus', ),
BasePeer::TYPE_STUDLYPHPNAME => array ('dbId', 'dbTrackReference', 'dbName', 'dbDispatchTime', 'dbStatus', ), BasePeer::TYPE_STUDLYPHPNAME => array ('dbId', 'dbTaskId', 'dbTrackReference', 'dbName', 'dbDispatchTime', 'dbStatus', ),
BasePeer::TYPE_COLNAME => array (CeleryTasksPeer::ID, CeleryTasksPeer::TRACK_REFERENCE, CeleryTasksPeer::NAME, CeleryTasksPeer::DISPATCH_TIME, CeleryTasksPeer::STATUS, ), BasePeer::TYPE_COLNAME => array (CeleryTasksPeer::ID, CeleryTasksPeer::TASK_ID, CeleryTasksPeer::TRACK_REFERENCE, CeleryTasksPeer::NAME, CeleryTasksPeer::DISPATCH_TIME, CeleryTasksPeer::STATUS, ),
BasePeer::TYPE_RAW_COLNAME => array ('ID', 'TRACK_REFERENCE', 'NAME', 'DISPATCH_TIME', 'STATUS', ), BasePeer::TYPE_RAW_COLNAME => array ('ID', 'TASK_ID', 'TRACK_REFERENCE', 'NAME', 'DISPATCH_TIME', 'STATUS', ),
BasePeer::TYPE_FIELDNAME => array ('id', 'track_reference', 'name', 'dispatch_time', 'status', ), BasePeer::TYPE_FIELDNAME => array ('id', 'task_id', 'track_reference', 'name', 'dispatch_time', 'status', ),
BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, )
); );
/** /**
@ -81,12 +84,12 @@ abstract class BaseCeleryTasksPeer
* e.g. CeleryTasksPeer::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0 * e.g. CeleryTasksPeer::$fieldNames[BasePeer::TYPE_PHPNAME]['Id'] = 0
*/ */
protected static $fieldKeys = array ( protected static $fieldKeys = array (
BasePeer::TYPE_PHPNAME => array ('DbId' => 0, 'DbTrackReference' => 1, 'DbName' => 2, 'DbDispatchTime' => 3, 'DbStatus' => 4, ), BasePeer::TYPE_PHPNAME => array ('DbId' => 0, 'DbTaskId' => 1, 'DbTrackReference' => 2, 'DbName' => 3, 'DbDispatchTime' => 4, 'DbStatus' => 5, ),
BasePeer::TYPE_STUDLYPHPNAME => array ('dbId' => 0, 'dbTrackReference' => 1, 'dbName' => 2, 'dbDispatchTime' => 3, 'dbStatus' => 4, ), BasePeer::TYPE_STUDLYPHPNAME => array ('dbId' => 0, 'dbTaskId' => 1, 'dbTrackReference' => 2, 'dbName' => 3, 'dbDispatchTime' => 4, 'dbStatus' => 5, ),
BasePeer::TYPE_COLNAME => array (CeleryTasksPeer::ID => 0, CeleryTasksPeer::TRACK_REFERENCE => 1, CeleryTasksPeer::NAME => 2, CeleryTasksPeer::DISPATCH_TIME => 3, CeleryTasksPeer::STATUS => 4, ), BasePeer::TYPE_COLNAME => array (CeleryTasksPeer::ID => 0, CeleryTasksPeer::TASK_ID => 1, CeleryTasksPeer::TRACK_REFERENCE => 2, CeleryTasksPeer::NAME => 3, CeleryTasksPeer::DISPATCH_TIME => 4, CeleryTasksPeer::STATUS => 5, ),
BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'TRACK_REFERENCE' => 1, 'NAME' => 2, 'DISPATCH_TIME' => 3, 'STATUS' => 4, ), BasePeer::TYPE_RAW_COLNAME => array ('ID' => 0, 'TASK_ID' => 1, 'TRACK_REFERENCE' => 2, 'NAME' => 3, 'DISPATCH_TIME' => 4, 'STATUS' => 5, ),
BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'track_reference' => 1, 'name' => 2, 'dispatch_time' => 3, 'status' => 4, ), BasePeer::TYPE_FIELDNAME => array ('id' => 0, 'task_id' => 1, 'track_reference' => 2, 'name' => 3, 'dispatch_time' => 4, 'status' => 5, ),
BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, ) BasePeer::TYPE_NUM => array (0, 1, 2, 3, 4, 5, )
); );
/** /**
@ -161,12 +164,14 @@ abstract class BaseCeleryTasksPeer
{ {
if (null === $alias) { if (null === $alias) {
$criteria->addSelectColumn(CeleryTasksPeer::ID); $criteria->addSelectColumn(CeleryTasksPeer::ID);
$criteria->addSelectColumn(CeleryTasksPeer::TASK_ID);
$criteria->addSelectColumn(CeleryTasksPeer::TRACK_REFERENCE); $criteria->addSelectColumn(CeleryTasksPeer::TRACK_REFERENCE);
$criteria->addSelectColumn(CeleryTasksPeer::NAME); $criteria->addSelectColumn(CeleryTasksPeer::NAME);
$criteria->addSelectColumn(CeleryTasksPeer::DISPATCH_TIME); $criteria->addSelectColumn(CeleryTasksPeer::DISPATCH_TIME);
$criteria->addSelectColumn(CeleryTasksPeer::STATUS); $criteria->addSelectColumn(CeleryTasksPeer::STATUS);
} else { } else {
$criteria->addSelectColumn($alias . '.id'); $criteria->addSelectColumn($alias . '.id');
$criteria->addSelectColumn($alias . '.task_id');
$criteria->addSelectColumn($alias . '.track_reference'); $criteria->addSelectColumn($alias . '.track_reference');
$criteria->addSelectColumn($alias . '.name'); $criteria->addSelectColumn($alias . '.name');
$criteria->addSelectColumn($alias . '.dispatch_time'); $criteria->addSelectColumn($alias . '.dispatch_time');
@ -409,7 +414,7 @@ abstract class BaseCeleryTasksPeer
public static function getPrimaryKeyFromRow($row, $startcol = 0) public static function getPrimaryKeyFromRow($row, $startcol = 0)
{ {
return (string) $row[$startcol]; return (int) $row[$startcol];
} }
/** /**
@ -764,6 +769,10 @@ abstract class BaseCeleryTasksPeer
$criteria = $values->buildCriteria(); // build Criteria from CeleryTasks object $criteria = $values->buildCriteria(); // build Criteria from CeleryTasks object
} }
if ($criteria->containsKey(CeleryTasksPeer::ID) && $criteria->keyContainsValue(CeleryTasksPeer::ID) ) {
throw new PropelException('Cannot insert a value for auto-increment primary key ('.CeleryTasksPeer::ID.')');
}
// Set the correct dbName // Set the correct dbName
$criteria->setDbName(CeleryTasksPeer::DATABASE_NAME); $criteria->setDbName(CeleryTasksPeer::DATABASE_NAME);
@ -952,7 +961,7 @@ abstract class BaseCeleryTasksPeer
/** /**
* Retrieve a single object by pkey. * Retrieve a single object by pkey.
* *
* @param string $pk the primary key. * @param int $pk the primary key.
* @param PropelPDO $con the connection to use * @param PropelPDO $con the connection to use
* @return CeleryTasks * @return CeleryTasks
*/ */

View file

@ -7,12 +7,14 @@
* *
* *
* @method CeleryTasksQuery orderByDbId($order = Criteria::ASC) Order by the id column * @method CeleryTasksQuery orderByDbId($order = Criteria::ASC) Order by the id column
* @method CeleryTasksQuery orderByDbTaskId($order = Criteria::ASC) Order by the task_id column
* @method CeleryTasksQuery orderByDbTrackReference($order = Criteria::ASC) Order by the track_reference column * @method CeleryTasksQuery orderByDbTrackReference($order = Criteria::ASC) Order by the track_reference column
* @method CeleryTasksQuery orderByDbName($order = Criteria::ASC) Order by the name column * @method CeleryTasksQuery orderByDbName($order = Criteria::ASC) Order by the name column
* @method CeleryTasksQuery orderByDbDispatchTime($order = Criteria::ASC) Order by the dispatch_time column * @method CeleryTasksQuery orderByDbDispatchTime($order = Criteria::ASC) Order by the dispatch_time column
* @method CeleryTasksQuery orderByDbStatus($order = Criteria::ASC) Order by the status column * @method CeleryTasksQuery orderByDbStatus($order = Criteria::ASC) Order by the status column
* *
* @method CeleryTasksQuery groupByDbId() Group by the id column * @method CeleryTasksQuery groupByDbId() Group by the id column
* @method CeleryTasksQuery groupByDbTaskId() Group by the task_id column
* @method CeleryTasksQuery groupByDbTrackReference() Group by the track_reference column * @method CeleryTasksQuery groupByDbTrackReference() Group by the track_reference column
* @method CeleryTasksQuery groupByDbName() Group by the name column * @method CeleryTasksQuery groupByDbName() Group by the name column
* @method CeleryTasksQuery groupByDbDispatchTime() Group by the dispatch_time column * @method CeleryTasksQuery groupByDbDispatchTime() Group by the dispatch_time column
@ -29,12 +31,14 @@
* @method CeleryTasks findOne(PropelPDO $con = null) Return the first CeleryTasks matching the query * @method CeleryTasks findOne(PropelPDO $con = null) Return the first CeleryTasks matching the query
* @method CeleryTasks findOneOrCreate(PropelPDO $con = null) Return the first CeleryTasks matching the query, or a new CeleryTasks object populated from the query conditions when no match is found * @method CeleryTasks findOneOrCreate(PropelPDO $con = null) Return the first CeleryTasks matching the query, or a new CeleryTasks object populated from the query conditions when no match is found
* *
* @method CeleryTasks findOneByDbTaskId(string $task_id) Return the first CeleryTasks filtered by the task_id column
* @method CeleryTasks findOneByDbTrackReference(int $track_reference) Return the first CeleryTasks filtered by the track_reference column * @method CeleryTasks findOneByDbTrackReference(int $track_reference) Return the first CeleryTasks filtered by the track_reference column
* @method CeleryTasks findOneByDbName(string $name) Return the first CeleryTasks filtered by the name column * @method CeleryTasks findOneByDbName(string $name) Return the first CeleryTasks filtered by the name column
* @method CeleryTasks findOneByDbDispatchTime(string $dispatch_time) Return the first CeleryTasks filtered by the dispatch_time column * @method CeleryTasks findOneByDbDispatchTime(string $dispatch_time) Return the first CeleryTasks filtered by the dispatch_time column
* @method CeleryTasks findOneByDbStatus(string $status) Return the first CeleryTasks filtered by the status column * @method CeleryTasks findOneByDbStatus(string $status) Return the first CeleryTasks filtered by the status column
* *
* @method array findByDbId(string $id) Return CeleryTasks objects filtered by the id column * @method array findByDbId(int $id) Return CeleryTasks objects filtered by the id column
* @method array findByDbTaskId(string $task_id) Return CeleryTasks objects filtered by the task_id column
* @method array findByDbTrackReference(int $track_reference) Return CeleryTasks objects filtered by the track_reference column * @method array findByDbTrackReference(int $track_reference) Return CeleryTasks objects filtered by the track_reference column
* @method array findByDbName(string $name) Return CeleryTasks objects filtered by the name column * @method array findByDbName(string $name) Return CeleryTasks objects filtered by the name column
* @method array findByDbDispatchTime(string $dispatch_time) Return CeleryTasks objects filtered by the dispatch_time column * @method array findByDbDispatchTime(string $dispatch_time) Return CeleryTasks objects filtered by the dispatch_time column
@ -146,10 +150,10 @@ abstract class BaseCeleryTasksQuery extends ModelCriteria
*/ */
protected function findPkSimple($key, $con) protected function findPkSimple($key, $con)
{ {
$sql = 'SELECT "id", "track_reference", "name", "dispatch_time", "status" FROM "celery_tasks" WHERE "id" = :p0'; $sql = 'SELECT "id", "task_id", "track_reference", "name", "dispatch_time", "status" FROM "celery_tasks" WHERE "id" = :p0';
try { try {
$stmt = $con->prepare($sql); $stmt = $con->prepare($sql);
$stmt->bindValue(':p0', $key, PDO::PARAM_STR); $stmt->bindValue(':p0', $key, PDO::PARAM_INT);
$stmt->execute(); $stmt->execute();
} catch (Exception $e) { } catch (Exception $e) {
Propel::log($e->getMessage(), Propel::LOG_ERR); Propel::log($e->getMessage(), Propel::LOG_ERR);
@ -240,30 +244,72 @@ abstract class BaseCeleryTasksQuery extends ModelCriteria
* *
* Example usage: * Example usage:
* <code> * <code>
* $query->filterByDbId('fooValue'); // WHERE id = 'fooValue' * $query->filterByDbId(1234); // WHERE id = 1234
* $query->filterByDbId('%fooValue%'); // WHERE id LIKE '%fooValue%' * $query->filterByDbId(array(12, 34)); // WHERE id IN (12, 34)
* $query->filterByDbId(array('min' => 12)); // WHERE id >= 12
* $query->filterByDbId(array('max' => 12)); // WHERE id <= 12
* </code> * </code>
* *
* @param string $dbId The value to use as filter. * @param mixed $dbId The value to use as filter.
* Accepts wildcards (* and % trigger a LIKE) * 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 * @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
* *
* @return CeleryTasksQuery The current query, for fluid interface * @return CeleryTasksQuery The current query, for fluid interface
*/ */
public function filterByDbId($dbId = null, $comparison = null) public function filterByDbId($dbId = null, $comparison = null)
{ {
if (null === $comparison) {
if (is_array($dbId)) { if (is_array($dbId)) {
$useMinMax = false;
if (isset($dbId['min'])) {
$this->addUsingAlias(CeleryTasksPeer::ID, $dbId['min'], Criteria::GREATER_EQUAL);
$useMinMax = true;
}
if (isset($dbId['max'])) {
$this->addUsingAlias(CeleryTasksPeer::ID, $dbId['max'], Criteria::LESS_EQUAL);
$useMinMax = true;
}
if ($useMinMax) {
return $this;
}
if (null === $comparison) {
$comparison = Criteria::IN; $comparison = Criteria::IN;
} elseif (preg_match('/[\%\*]/', $dbId)) {
$dbId = str_replace('*', '%', $dbId);
$comparison = Criteria::LIKE;
} }
} }
return $this->addUsingAlias(CeleryTasksPeer::ID, $dbId, $comparison); return $this->addUsingAlias(CeleryTasksPeer::ID, $dbId, $comparison);
} }
/**
* Filter the query on the task_id column
*
* Example usage:
* <code>
* $query->filterByDbTaskId('fooValue'); // WHERE task_id = 'fooValue'
* $query->filterByDbTaskId('%fooValue%'); // WHERE task_id LIKE '%fooValue%'
* </code>
*
* @param string $dbTaskId The value to use as filter.
* Accepts wildcards (* and % trigger a LIKE)
* @param string $comparison Operator to use for the column comparison, defaults to Criteria::EQUAL
*
* @return CeleryTasksQuery The current query, for fluid interface
*/
public function filterByDbTaskId($dbTaskId = null, $comparison = null)
{
if (null === $comparison) {
if (is_array($dbTaskId)) {
$comparison = Criteria::IN;
} elseif (preg_match('/[\%\*]/', $dbTaskId)) {
$dbTaskId = str_replace('*', '%', $dbTaskId);
$comparison = Criteria::LIKE;
}
}
return $this->addUsingAlias(CeleryTasksPeer::TASK_ID, $dbTaskId, $comparison);
}
/** /**
* Filter the query on the track_reference column * Filter the query on the track_reference column
* *

View file

@ -75,7 +75,7 @@ class CeleryService {
$config = parse_ini_file(Application_Model_RabbitMq::getRmqConfigPath(), true); $config = parse_ini_file(Application_Model_RabbitMq::getRmqConfigPath(), true);
$queue = self::$_CELERY_RESULTS_EXCHANGE . "." . $task; $queue = self::$_CELERY_RESULTS_EXCHANGE . "." . $task;
$c = self::_setupCeleryExchange($config, self::$_CELERY_RESULTS_EXCHANGE, $queue); $c = self::_setupCeleryExchange($config, self::$_CELERY_RESULTS_EXCHANGE, $queue);
$message = $c->getAsyncResultMessage($task->getDbName(), $task->getDbId()); $message = $c->getAsyncResultMessage($task->getDbName(), $task->getDbTaskId());
// If the message isn't ready yet (Celery hasn't finished the task), // If the message isn't ready yet (Celery hasn't finished the task),
// only throw an exception if the message has timed out. // only throw an exception if the message has timed out.
@ -85,12 +85,12 @@ class CeleryService {
// track reference here in case it was a deletion that failed, for example. // track reference here in case it was a deletion that failed, for example.
$task->setDbStatus(CELERY_FAILED_STATUS)->save(); $task->setDbStatus(CELERY_FAILED_STATUS)->save();
throw new CeleryTimeoutException("Celery task " . $task->getDbName() throw new CeleryTimeoutException("Celery task " . $task->getDbName()
. " with ID " . $task->getDbId() . " timed out"); . " with ID " . $task->getDbTaskId() . " timed out");
} else { } else {
// The message hasn't timed out, but it's still false, which means it hasn't been // The message hasn't timed out, but it's still false, which means it hasn't been
// sent back from Celery yet. // sent back from Celery yet.
throw new CeleryException("Waiting on Celery task " . $task->getDbName() throw new CeleryException("Waiting on Celery task " . $task->getDbName()
. " with ID " . $task->getDbId()); . " with ID " . $task->getDbTaskId());
} }
} }
return $message; return $message;
@ -147,7 +147,7 @@ class CeleryService {
protected static function _getPendingTasks($taskName, $serviceName) { protected static function _getPendingTasks($taskName, $serviceName) {
$query = CeleryTasksQuery::create() $query = CeleryTasksQuery::create()
->filterByDbStatus(CELERY_PENDING_STATUS) ->filterByDbStatus(CELERY_PENDING_STATUS)
->filterByDbId('', Criteria::NOT_EQUAL); ->filterByDbTaskId('', Criteria::NOT_EQUAL);
if (!empty($taskName)) { if (!empty($taskName)) {
$query->filterByDbName($taskName); $query->filterByDbName($taskName);
} }

View file

@ -69,7 +69,6 @@ class SoundcloudService extends ThirdPartyCeleryService implements OAuth2 {
*/ */
protected function _getUploadData($file) { protected function _getUploadData($file) {
$file = $file->getPropelOrm(); $file = $file->getPropelOrm();
Logging::info($file);
// TODO: Move this into a proper serializer // TODO: Move this into a proper serializer
$trackArray = $this->_serializeTrack($file); $trackArray = $this->_serializeTrack($file);
foreach (self::$_SOUNDCLOUD_PREF_FUNCTIONS as $func => $param) { foreach (self::$_SOUNDCLOUD_PREF_FUNCTIONS as $func => $param) {

View file

@ -82,12 +82,8 @@ abstract class ThirdPartyCeleryService extends ThirdPartyService {
*/ */
protected function _createTaskReference($fileId, $brokerTaskId, $taskName) { protected function _createTaskReference($fileId, $brokerTaskId, $taskName) {
$trackId = $this->createTrackReference($fileId); $trackId = $this->createTrackReference($fileId);
// First, check if the track already has an entry in the database
$task = CeleryTasksQuery::create()->findOneByDbTrackReference($trackId);
if (is_null($task)) {
$task = new CeleryTasks(); $task = new CeleryTasks();
} $task->setDbTaskId($brokerTaskId);
$task->setDbId($brokerTaskId);
$task->setDbName($taskName); $task->setDbName($taskName);
$utc = new DateTimeZone("UTC"); $utc = new DateTimeZone("UTC");
$task->setDbDispatchTime(new DateTime("now", $utc)); $task->setDbDispatchTime(new DateTime("now", $utc));

View file

@ -22,7 +22,9 @@ function getUpgrades() {
class UpgradeManager class UpgradeManager
{ {
/** Used to determine if the database schema needs an upgrade in order for this version of the Airtime codebase to work correctly.
/**
* Used to determine if the database schema needs an upgrade in order for this version of the Airtime codebase to work correctly.
* @return array A list of schema versions that this version of the codebase supports. * @return array A list of schema versions that this version of the codebase supports.
*/ */
public static function getSupportedSchemaVersions() public static function getSupportedSchemaVersions()
@ -64,10 +66,35 @@ class UpgradeManager
return $upgradePerformed; return $upgradePerformed;
} }
/**
* Downgrade the Airtime schema version to match the given version
*
* @param string $toVersion the version we want to downgrade to
*
* @return boolean whether or not an upgrade was performed
*/
public static function doDowngrade($toVersion)
{
$downgraders = array_reverse(getUpgrades()); // Reverse the array because we're downgrading
$dir = (dirname(__DIR__) . "/controllers");
$downgradePerformed = false;
foreach ($downgraders as $downgrader) {
/** @var AirtimeUpgrader $downgrader */
$downgrader = new $downgrader($dir);
if ($downgrader->getNewVersion() == $toVersion) {
break; // We've reached the version we wanted to downgrade to, so break
}
$downgradePerformed = self::_runDowngrade($downgrader) ? true : $downgradePerformed;
}
return $downgradePerformed;
}
/** /**
* Run the given upgrade * Run the given upgrade
* *
* @param $upgrader AirtimeUpgrader the upgrade class to be executed * @param $upgrader AirtimeUpgrader the upgrader class to be executed
* *
* @return bool true if the upgrade was successful, otherwise false * @return bool true if the upgrade was successful, otherwise false
*/ */
@ -75,12 +102,26 @@ class UpgradeManager
return $upgrader->checkIfUpgradeSupported() && $upgrader->upgrade(); return $upgrader->checkIfUpgradeSupported() && $upgrader->upgrade();
} }
/**
* Run the given downgrade
*
* @param $downgrader AirtimeUpgrader the upgrader class to be executed
* @param $supportedVersions array array of supported versions
*
* @return bool true if the downgrade was successful, otherwise false
*/
private static function _runDowngrade(AirtimeUpgrader $downgrader) {
return $downgrader->checkIfDowngradeSupported() && $downgrader->downgrade();
}
} }
abstract class AirtimeUpgrader abstract class AirtimeUpgrader
{ {
protected $_dir; protected $_dir;
protected $username, $password, $host, $database;
/** /**
* @param $dir string directory housing upgrade files * @param $dir string directory housing upgrade files
*/ */
@ -105,7 +146,17 @@ abstract class AirtimeUpgrader
*/ */
public function checkIfUpgradeSupported() public function checkIfUpgradeSupported()
{ {
return in_array(AirtimeUpgrader::getCurrentSchemaVersion(), $this->getSupportedSchemaVersions()); return in_array(static::getCurrentSchemaVersion(), $this->getSupportedSchemaVersions());
}
/**
* This function checks to see if this class can perform a downgrade of your version of Airtime
*
* @return boolean True if we can downgrade your version of Airtime.
*/
public function checkIfDowngradeSupported()
{
return static::getCurrentSchemaVersion() == $this->getNewVersion();
} }
protected function toggleMaintenanceScreen($toggle) protected function toggleMaintenanceScreen($toggle)
@ -143,6 +194,7 @@ abstract class AirtimeUpgrader
// $this->toggleMaintenanceScreen(true); // $this->toggleMaintenanceScreen(true);
Cache::clear(); Cache::clear();
$this->_getDbValues();
$this->_runUpgrade(); $this->_runUpgrade();
Application_Model_Preference::SetSchemaVersion($this->getNewVersion()); Application_Model_Preference::SetSchemaVersion($this->getNewVersion());
@ -157,18 +209,57 @@ abstract class AirtimeUpgrader
return true; return true;
} }
protected function _runUpgrade() { /**
* Implement this for each new version of Airtime
* This function abstracts out the core downgrade functionality,
* allowing child classes to overwrite _runDowngrade to reduce duplication
*/
public function downgrade() {
Cache::clear();
try {
$this->_getDbValues();
$this->_runDowngrade();
$highestSupportedVersion = null;
foreach ($this->getSupportedSchemaVersions() as $v) {
// version_compare returns 1 (true) if the second parameter is lower
if (!$highestSupportedVersion || version_compare($v, $highestSupportedVersion)) {
$highestSupportedVersion = $v;
}
}
// Set the schema version to the highest supported version so we don't skip versions when downgrading
Application_Model_Preference::SetSchemaVersion($highestSupportedVersion);
Cache::clear();
} catch(Exception $e) {
return false;
}
return true;
}
protected function _getDbValues() {
$airtimeConf = isset($_SERVER['AIRTIME_CONF']) ? $_SERVER['AIRTIME_CONF'] : "/etc/airtime/airtime.conf"; $airtimeConf = isset($_SERVER['AIRTIME_CONF']) ? $_SERVER['AIRTIME_CONF'] : "/etc/airtime/airtime.conf";
$values = parse_ini_file($airtimeConf, true); $values = parse_ini_file($airtimeConf, true);
$username = $values['database']['dbuser']; $this->username = $values['database']['dbuser'];
$password = $values['database']['dbpass']; $this->password = $values['database']['dbpass'];
$host = $values['database']['host']; $this->host = $values['database']['host'];
$database = $values['database']['dbname']; $this->database = $values['database']['dbname'];
passthru("export PGPASSWORD=$password && psql -h $host -U $username -q -f ".$this->_dir."/upgrade_sql/airtime_"
.$this->getNewVersion()."/upgrade.sql $database 2>&1 | grep -v -E \"will create implicit sequence|will create implicit index\"");
} }
protected function _runUpgrade() {
passthru("export PGPASSWORD=".$this->password." && 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_"
.$this->getNewVersion()."/downgrade.sql ".$this->database." 2>&1 | grep -v -E \"will create implicit sequence|will create implicit index\"");
}
} }
class AirtimeUpgrader253 extends AirtimeUpgrader class AirtimeUpgrader253 extends AirtimeUpgrader
@ -330,18 +421,27 @@ class AirtimeUpgrader2512 extends AirtimeUpgrader
/** /**
* Class AirtimeUpgrader2513 - Celery and SoundCloud upgrade * Class AirtimeUpgrader2513 - Celery and SoundCloud upgrade
* *
* Adds third_party_track_references table for third party service * Adds third_party_track_references and celery_tasks tables for third party service
* authentication and task architecture. * authentication and task architecture.
* *
* Schema: * <br/><b>third_party_track_references</b> schema:
*
* id -> int PK * id -> int PK
* service -> string internal service name * service -> string internal service name
* foreign_id -> int external unique service id * foreign_id -> int external unique service id
* broker_task_id -> int external unique amqp results identifier
* broker_task_name -> string external Celery task name
* broker_task_dispatch_time -> timestamp internal message dispatch time
* file_id -> int internal FK->cc_files track id * file_id -> int internal FK->cc_files track id
* status -> string external Celery task status - PENDING, SUCCESS, or FAILED * upload_time -> timestamp internal upload timestamp
* status -> string external service status
*
* <br/><b>celery_tasks</b> schema:
*
* id -> int PK
* task_id -> string external unique amqp results identifier
* track_reference -> int internal FK->third_party_track_references id
* name -> string external Celery task name
* dispatch_time -> timestamp internal message dispatch time
* status -> string external Celery task status
*
*/ */
class AirtimeUpgrader2513 extends AirtimeUpgrader class AirtimeUpgrader2513 extends AirtimeUpgrader
{ {

View file

@ -548,7 +548,8 @@
</table> </table>
<table name="celery_tasks" phpName="CeleryTasks"> <table name="celery_tasks" phpName="CeleryTasks">
<column name="id" phpName="DbId" primaryKey="true" type="VARCHAR" size="256" required="true" /> <column name="id" phpName="DbId" primaryKey="true" type="INTEGER" autoIncrement="true" required="true" />
<column name="task_id" phpName="DbTaskId" type="VARCHAR" size="256" required="true" />
<column name="track_reference" phpName="DbTrackReference" type="INTEGER" required="true" /> <column name="track_reference" phpName="DbTrackReference" type="INTEGER" required="true" />
<column name="name" phpName="DbName" type="VARCHAR" size="256" /> <column name="name" phpName="DbName" type="VARCHAR" size="256" />
<column name="dispatch_time" phpName="DbDispatchTime" type="TIMESTAMP" /> <column name="dispatch_time" phpName="DbDispatchTime" type="TIMESTAMP" />

View file

@ -696,7 +696,8 @@ DROP TABLE IF EXISTS "celery_tasks" CASCADE;
CREATE TABLE "celery_tasks" CREATE TABLE "celery_tasks"
( (
"id" VARCHAR(256) NOT NULL, "id" serial NOT NULL,
"task_id" VARCHAR(256) NOT NULL,
"track_reference" INTEGER NOT NULL, "track_reference" INTEGER NOT NULL,
"name" VARCHAR(256), "name" VARCHAR(256),
"dispatch_time" TIMESTAMP, "dispatch_time" TIMESTAMP,

View file

@ -1018,7 +1018,8 @@ var AIRTIME = (function(AIRTIME) {
if (soundcloud.upload !== undefined) { if (soundcloud.upload !== undefined) {
callback = function() { callback = function() {
alert($.i18n._("Your track is being uploaded to SoundCloud")); alert($.i18n._("Your track is being uploaded and will " +
"appear on SoundCloud in a couple of minutes"));
$.post(soundcloud.upload.url, function(){}); $.post(soundcloud.upload.url, function(){});
}; };
soundcloud.upload.callback = callback; soundcloud.upload.callback = callback;