CC-5709: Airtime Analyzer
* Basic HTTP reporting back to the File API works (PUT) * Use the database table names as JSON field names. * Fixed result returning bug in message_listener.py * Fixed API key verification to adhere with the HTTP Basic Auth spec
This commit is contained in:
parent
59535850e2
commit
4e39fce701
|
@ -14,8 +14,9 @@ class Rest_MediaController extends Zend_Rest_Controller
|
||||||
}
|
}
|
||||||
$this->getResponse()
|
$this->getResponse()
|
||||||
->setHttpResponseCode(200)
|
->setHttpResponseCode(200)
|
||||||
->appendBody(json_encode(CcFilesQuery::create()->find()->toArray()));
|
->appendBody(json_encode(CcFilesQuery::create()->find()->toArray(/*BasePeer::TYPE_FIELDNAME*/)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAction()
|
public function getAction()
|
||||||
{
|
{
|
||||||
if (!$this->verifyApiKey()) {
|
if (!$this->verifyApiKey()) {
|
||||||
|
@ -30,7 +31,7 @@ class Rest_MediaController extends Zend_Rest_Controller
|
||||||
if ($file) {
|
if ($file) {
|
||||||
$this->getResponse()
|
$this->getResponse()
|
||||||
->setHttpResponseCode(200)
|
->setHttpResponseCode(200)
|
||||||
->appendBody(json_encode($file->toArray()));
|
->appendBody(json_encode($file->toArray(BasePeer::TYPE_FIELDNAME)));
|
||||||
} else {
|
} else {
|
||||||
$this->fileNotFoundResponse();
|
$this->fileNotFoundResponse();
|
||||||
}
|
}
|
||||||
|
@ -56,7 +57,7 @@ class Rest_MediaController extends Zend_Rest_Controller
|
||||||
|
|
||||||
$this->getResponse()
|
$this->getResponse()
|
||||||
->setHttpResponseCode(201)
|
->setHttpResponseCode(201)
|
||||||
->appendBody(json_encode($file->toArray()));
|
->appendBody(json_encode($file->toArray(BasePeer::TYPE_FIELDNAME)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function putAction()
|
public function putAction()
|
||||||
|
@ -72,11 +73,11 @@ class Rest_MediaController extends Zend_Rest_Controller
|
||||||
$file = CcFilesQuery::create()->findPk($id);
|
$file = CcFilesQuery::create()->findPk($id);
|
||||||
if ($file)
|
if ($file)
|
||||||
{
|
{
|
||||||
$file->fromArray(json_decode($this->getRequest()->getRawBody(), true));
|
$file->fromArray(json_decode($this->getRequest()->getRawBody(), true), BasePeer::TYPE_FIELDNAME);
|
||||||
$file->save();
|
$file->save();
|
||||||
$this->getResponse()
|
$this->getResponse()
|
||||||
->setHttpResponseCode(200)
|
->setHttpResponseCode(200)
|
||||||
->appendBody(json_encode($file->toArray()));
|
->appendBody(json_encode($file->toArray(BasePeer::TYPE_FIELDNAME)));
|
||||||
} else {
|
} else {
|
||||||
$this->fileNotFoundResponse();
|
$this->fileNotFoundResponse();
|
||||||
}
|
}
|
||||||
|
@ -119,9 +120,13 @@ class Rest_MediaController extends Zend_Rest_Controller
|
||||||
|
|
||||||
$CC_CONFIG = Config::getConfig();
|
$CC_CONFIG = Config::getConfig();
|
||||||
|
|
||||||
|
//Decode the API key that was passed to us in the HTTP request.
|
||||||
$authHeader = $this->getRequest()->getHeader("Authorization");
|
$authHeader = $this->getRequest()->getHeader("Authorization");
|
||||||
|
$encodedRequestApiKey = substr($authHeader, strlen("Basic "));
|
||||||
if (in_array($authHeader, $CC_CONFIG["apiKey"])) {
|
$encodedStoredApiKey = base64_encode($CC_CONFIG["apiKey"][0] . ":");
|
||||||
|
|
||||||
|
if ($encodedRequestApiKey === $encodedStoredApiKey)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
$resp = $this->getResponse();
|
$resp = $this->getResponse();
|
||||||
|
|
|
@ -136,3 +136,5 @@ class MessageListener:
|
||||||
else:
|
else:
|
||||||
raise Exception("Analyzer process terminated unexpectedly.")
|
raise Exception("Analyzer process terminated unexpectedly.")
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
|
@ -19,18 +19,34 @@ class MetadataAnalyzer(Analyzer):
|
||||||
info = audio_file.info
|
info = audio_file.info
|
||||||
metadata["sample_rate"] = info.sample_rate
|
metadata["sample_rate"] = info.sample_rate
|
||||||
metadata["length_seconds"] = info.length
|
metadata["length_seconds"] = info.length
|
||||||
metadata["bitrate"] = info.bitrate
|
metadata["bit_rate"] = info.bitrate
|
||||||
|
#metadata["channels"] = info.channels
|
||||||
|
|
||||||
#Use the python-magic module to get the MIME type.
|
#Use the python-magic module to get the MIME type.
|
||||||
mime_magic = magic.Magic(mime=True)
|
mime_magic = magic.Magic(mime=True)
|
||||||
metadata["mime_type"] = mime_magic.from_file(filename)
|
metadata["mime_type"] = mime_magic.from_file(filename)
|
||||||
|
|
||||||
|
#Try to get the number of channels if mutagen can...
|
||||||
|
try:
|
||||||
|
#Special handling for getting the # of channels from MP3s. It's in the "mode" field
|
||||||
|
#which is 0=Stereo, 1=Joint Stereo, 2=Dual Channel, 3=Mono. Part of the ID3 spec...
|
||||||
|
if metadata["mime_type"] == "audio/mpeg":
|
||||||
|
if info.mode == 3:
|
||||||
|
metadata["channels"] = 1
|
||||||
|
else:
|
||||||
|
metadata["channels"] = 2
|
||||||
|
else:
|
||||||
|
metadata["channels"] = info.channels
|
||||||
|
except (AttributeError, KeyError):
|
||||||
|
#If mutagen can't figure out the number of channels, we'll just leave it out...
|
||||||
|
pass
|
||||||
|
|
||||||
#We normalize the mutagen tags slightly here, so in case mutagen changes,
|
#We normalize the mutagen tags slightly here, so in case mutagen changes,
|
||||||
#we find the
|
#we find the
|
||||||
mutagen_to_analyzer_mapping = {
|
mutagen_to_airtime_mapping = {
|
||||||
'title': 'title',
|
'title': 'track_title',
|
||||||
'artist': 'artist',
|
'artist': 'artist_name',
|
||||||
'album': 'album',
|
'album': 'album_title',
|
||||||
'bpm': 'bpm',
|
'bpm': 'bpm',
|
||||||
'composer': 'composer',
|
'composer': 'composer',
|
||||||
'conductor': 'conductor',
|
'conductor': 'conductor',
|
||||||
|
@ -43,20 +59,21 @@ class MetadataAnalyzer(Analyzer):
|
||||||
'last_modified':'last_modified',
|
'last_modified':'last_modified',
|
||||||
'mood': 'mood',
|
'mood': 'mood',
|
||||||
'replay_gain': 'replaygain',
|
'replay_gain': 'replaygain',
|
||||||
'track_number': 'tracknumber',
|
'track_number': 'track_number',
|
||||||
'track_total': 'tracktotal',
|
'track_total': 'track_total',
|
||||||
'website': 'website',
|
'website': 'website',
|
||||||
'year': 'year',
|
'year': 'year',
|
||||||
|
'mime_type': 'mime',
|
||||||
}
|
}
|
||||||
|
|
||||||
for mutagen_tag, analyzer_tag in mutagen_to_analyzer_mapping.iteritems():
|
for mutagen_tag, airtime_tag in mutagen_to_airtime_mapping.iteritems():
|
||||||
try:
|
try:
|
||||||
metadata[analyzer_tag] = audio_file[mutagen_tag]
|
metadata[airtime_tag] = audio_file[mutagen_tag]
|
||||||
|
|
||||||
# Some tags are returned as lists because there could be multiple values.
|
# Some tags are returned as lists because there could be multiple values.
|
||||||
# This is unusual so we're going to always just take the first item in the list.
|
# This is unusual so we're going to always just take the first item in the list.
|
||||||
if isinstance(metadata[analyzer_tag], list):
|
if isinstance(metadata[airtime_tag], list):
|
||||||
metadata[analyzer_tag] = metadata[analyzer_tag][0]
|
metadata[airtime_tag] = metadata[airtime_tag][0]
|
||||||
|
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -12,8 +12,9 @@ class StatusReporter():
|
||||||
def report_success_to_callback_url(self, callback_url, api_key, audio_metadata):
|
def report_success_to_callback_url(self, callback_url, api_key, audio_metadata):
|
||||||
|
|
||||||
# Encode the audio metadata as JSON and post it back to the callback_url
|
# Encode the audio metadata as JSON and post it back to the callback_url
|
||||||
post_payload = json.dumps(audio_metadata)
|
put_payload = json.dumps(audio_metadata)
|
||||||
r = requests.put(callback_url, data=post_payload,
|
logging.debug("Sending HTTP PUT with payload: " + put_payload)
|
||||||
|
r = requests.put(callback_url, data=put_payload,
|
||||||
auth=requests.auth.HTTPBasicAuth(api_key, ''),
|
auth=requests.auth.HTTPBasicAuth(api_key, ''),
|
||||||
timeout=StatusReporter._HTTP_REQUEST_TIMEOUT)
|
timeout=StatusReporter._HTTP_REQUEST_TIMEOUT)
|
||||||
logging.debug("HTTP request returned status: " + str(r.status_code))
|
logging.debug("HTTP request returned status: " + str(r.status_code))
|
||||||
|
|
Loading…
Reference in New Issue