CC-1799 Put Airtime Storage into a Human Readable File Naming Convention
selecting a mode to prevent some cases where a duplicate could be entered for only 1 file.
This commit is contained in:
parent
79049315c7
commit
71d853567e
7 changed files with 72 additions and 33 deletions
|
@ -409,18 +409,35 @@ class ApiController extends Zend_Controller_Action
|
||||||
}
|
}
|
||||||
|
|
||||||
$md = $this->_getParam('md');
|
$md = $this->_getParam('md');
|
||||||
$filepath = $md['MDATA_KEY_FILEPATH'];
|
$mode = $this->_getParam('mode');
|
||||||
$filepath = str_replace("\\", "", $filepath);
|
|
||||||
|
|
||||||
$file = StoredFile::RecallByFilepath($filepath);
|
if ($mode == "create") {
|
||||||
|
$md5 = $md['MDATA_KEY_MD5'];
|
||||||
|
|
||||||
//New file added to Airtime
|
$file = StoredFile::RecallByMd5($md5);
|
||||||
if (is_null($file)) {
|
|
||||||
$file = StoredFile::Insert($md);
|
if (is_null($file)) {
|
||||||
|
$file = StoredFile::Insert($md);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->view->error = "File already exists in Airtime.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//Updating a metadata change.
|
else if ($mode == "modify") {
|
||||||
else {
|
$filepath = $md['MDATA_KEY_FILEPATH'];
|
||||||
$file->setMetadata($md);
|
$filepath = str_replace("\\", "", $filepath);
|
||||||
|
$file = StoredFile::RecallByFilepath($filepath);
|
||||||
|
|
||||||
|
//File is not in database anymore.
|
||||||
|
if (is_null($file)) {
|
||||||
|
$this->view->error = "File does not exist in Airtime.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Updating a metadata change.
|
||||||
|
else {
|
||||||
|
$file->setMetadata($md);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->view->id = $file->getId();
|
$this->view->id = $file->getId();
|
||||||
|
|
|
@ -166,8 +166,8 @@ class LibraryController extends Zend_Controller_Action
|
||||||
|
|
||||||
$data = $formdata;
|
$data = $formdata;
|
||||||
$data['filepath'] = $file->getFilePath();
|
$data['filepath'] = $file->getFilePath();
|
||||||
//wait for 1.9.0 release
|
|
||||||
//RabbitMq::SendFileMetaData($data);
|
RabbitMq::SendFileMetaData($data);
|
||||||
|
|
||||||
$this->_helper->redirector('index');
|
$this->_helper->redirector('index');
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,9 +40,6 @@ class RabbitMq
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* wait for 1.9.0 release
|
|
||||||
|
|
||||||
public static function SendFileMetaData($md)
|
public static function SendFileMetaData($md)
|
||||||
{
|
{
|
||||||
global $CC_CONFIG;
|
global $CC_CONFIG;
|
||||||
|
@ -64,7 +61,5 @@ class RabbitMq
|
||||||
$channel->close();
|
$channel->close();
|
||||||
$conn->close();
|
$conn->close();
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -450,7 +450,7 @@ class StoredFile {
|
||||||
|
|
||||||
return $storedFile;
|
return $storedFile;
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -378,13 +378,14 @@ class AirTimeApiClient(ApiClientInterface):
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def update_media_metadata(self, md):
|
def update_media_metadata(self, md, mode):
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
response = None
|
response = None
|
||||||
try:
|
try:
|
||||||
url = "http://%s:%s/%s/%s" % (self.config["base_url"], str(self.config["base_port"]), self.config["api_base"], self.config["update_media_url"])
|
url = "http://%s:%s/%s/%s" % (self.config["base_url"], str(self.config["base_port"]), self.config["api_base"], self.config["update_media_url"])
|
||||||
logger.debug(url)
|
logger.debug(url)
|
||||||
url = url.replace("%%api_key%%", self.config["api_key"])
|
url = url.replace("%%api_key%%", self.config["api_key"])
|
||||||
|
url = url.replace("%%mode%%", mode)
|
||||||
|
|
||||||
data = recursive_urlencode(md)
|
data = recursive_urlencode(md)
|
||||||
req = urllib2.Request(url, data)
|
req = urllib2.Request(url, data)
|
||||||
|
|
|
@ -25,6 +25,9 @@ from kombu.connection import BrokerConnection
|
||||||
from kombu.messaging import Exchange, Queue, Consumer, Producer
|
from kombu.messaging import Exchange, Queue, Consumer, Producer
|
||||||
from api_clients import api_client
|
from api_clients import api_client
|
||||||
|
|
||||||
|
MODE_CREATE = "create"
|
||||||
|
MODE_MODIFY = "modify"
|
||||||
|
|
||||||
global storage_directory
|
global storage_directory
|
||||||
storage_directory = "/srv/airtime/stor"
|
storage_directory = "/srv/airtime/stor"
|
||||||
|
|
||||||
|
@ -48,14 +51,6 @@ list of supported easy tags in mutagen version 1.20
|
||||||
['albumartistsort', 'musicbrainz_albumstatus', 'lyricist', 'releasecountry', 'date', 'performer', 'musicbrainz_albumartistid', 'composer', 'encodedby', 'tracknumber', 'musicbrainz_albumid', 'album', 'asin', 'musicbrainz_artistid', 'mood', 'copyright', 'author', 'media', 'length', 'version', 'artistsort', 'titlesort', 'discsubtitle', 'website', 'musicip_fingerprint', 'conductor', 'compilation', 'barcode', 'performer:*', 'composersort', 'musicbrainz_discid', 'musicbrainz_albumtype', 'genre', 'isrc', 'discnumber', 'musicbrainz_trmid', 'replaygain_*_gain', 'musicip_puid', 'artist', 'title', 'bpm', 'musicbrainz_trackid', 'arranger', 'albumsort', 'replaygain_*_peak', 'organization']
|
['albumartistsort', 'musicbrainz_albumstatus', 'lyricist', 'releasecountry', 'date', 'performer', 'musicbrainz_albumartistid', 'composer', 'encodedby', 'tracknumber', 'musicbrainz_albumid', 'album', 'asin', 'musicbrainz_artistid', 'mood', 'copyright', 'author', 'media', 'length', 'version', 'artistsort', 'titlesort', 'discsubtitle', 'website', 'musicip_fingerprint', 'conductor', 'compilation', 'barcode', 'performer:*', 'composersort', 'musicbrainz_discid', 'musicbrainz_albumtype', 'genre', 'isrc', 'discnumber', 'musicbrainz_trmid', 'replaygain_*_gain', 'musicip_puid', 'artist', 'title', 'bpm', 'musicbrainz_trackid', 'arranger', 'albumsort', 'replaygain_*_peak', 'organization']
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def checkRabbitMQ(notifier):
|
|
||||||
try:
|
|
||||||
notifier.connection.drain_events(timeout=int(config["check_airtime_events"]))
|
|
||||||
except Exception, e:
|
|
||||||
logger = logging.getLogger('root')
|
|
||||||
logger.info("%s", e)
|
|
||||||
|
|
||||||
class AirtimeNotifier(Notifier):
|
class AirtimeNotifier(Notifier):
|
||||||
|
|
||||||
def __init__(self, watch_manager, default_proc_fun=None, read_freq=0, threshold=0, timeout=None):
|
def __init__(self, watch_manager, default_proc_fun=None, read_freq=0, threshold=0, timeout=None):
|
||||||
|
@ -136,6 +131,14 @@ class MediaMonitor(ProcessEvent):
|
||||||
self.temp_files = {}
|
self.temp_files = {}
|
||||||
self.imported_renamed_files = {}
|
self.imported_renamed_files = {}
|
||||||
|
|
||||||
|
schedule_exchange = Exchange("airtime-media-monitor", "direct", durable=True, auto_delete=True)
|
||||||
|
schedule_queue = Queue("media-monitor", exchange=schedule_exchange, key="filesystem")
|
||||||
|
connection = BrokerConnection(config["rabbitmq_host"], config["rabbitmq_user"], config["rabbitmq_password"], "/")
|
||||||
|
channel = connection.channel()
|
||||||
|
|
||||||
|
self.producer = Producer(channel, exchange=schedule_exchange, serializer="json")
|
||||||
|
#producer.publish({"name": "/tmp/lolcat1.avi", "size": 1301013})
|
||||||
|
|
||||||
def get_md5(self, filepath):
|
def get_md5(self, filepath):
|
||||||
f = open(filepath, 'rb')
|
f = open(filepath, 'rb')
|
||||||
m = hashlib.md5()
|
m = hashlib.md5()
|
||||||
|
@ -233,7 +236,7 @@ class MediaMonitor(ProcessEvent):
|
||||||
return filepath
|
return filepath
|
||||||
|
|
||||||
|
|
||||||
def update_airtime(self, filepath):
|
def update_airtime(self, filepath, mode):
|
||||||
self.logger.info("Updating Change to Airtime")
|
self.logger.info("Updating Change to Airtime")
|
||||||
md = {}
|
md = {}
|
||||||
md5 = self.get_md5(filepath)
|
md5 = self.get_md5(filepath)
|
||||||
|
@ -252,7 +255,7 @@ class MediaMonitor(ProcessEvent):
|
||||||
md['MDATA_KEY_DURATION'] = self.format_length(file_info.info.length)
|
md['MDATA_KEY_DURATION'] = self.format_length(file_info.info.length)
|
||||||
|
|
||||||
data = {'md': md}
|
data = {'md': md}
|
||||||
response = self.api_client.update_media_metadata(data)
|
response = self.api_client.update_media_metadata(data, mode)
|
||||||
|
|
||||||
def is_renamed_file(self, filename):
|
def is_renamed_file(self, filename):
|
||||||
if filename in self.imported_renamed_files:
|
if filename in self.imported_renamed_files:
|
||||||
|
@ -305,14 +308,14 @@ class MediaMonitor(ProcessEvent):
|
||||||
self.logger.debug("Cannot change owner of file.")
|
self.logger.debug("Cannot change owner of file.")
|
||||||
self.logger.debug("Error: %s:", e)
|
self.logger.debug("Error: %s:", e)
|
||||||
|
|
||||||
self.update_airtime(filepath)
|
self.update_airtime(filepath, MODE_CREATE)
|
||||||
|
|
||||||
self.logger.info("%s: %s", event.maskname, event.pathname)
|
self.logger.info("%s: %s", event.maskname, event.pathname)
|
||||||
|
|
||||||
def process_IN_MODIFY(self, event):
|
def process_IN_MODIFY(self, event):
|
||||||
if not event.dir and os.path.exists(event.pathname):
|
if not event.dir and os.path.exists(event.pathname):
|
||||||
if self.is_audio_file(event.name) :
|
if self.is_audio_file(event.name) :
|
||||||
self.update_airtime(event.pathname)
|
self.update_airtime(event.pathname, MODE_MODIFY)
|
||||||
|
|
||||||
self.logger.info("%s: %s", event.maskname, event.pathname)
|
self.logger.info("%s: %s", event.maskname, event.pathname)
|
||||||
|
|
||||||
|
@ -330,14 +333,37 @@ class MediaMonitor(ProcessEvent):
|
||||||
|
|
||||||
self.logger.info("%s: %s", event.maskname, event.pathname)
|
self.logger.info("%s: %s", event.maskname, event.pathname)
|
||||||
|
|
||||||
|
def process_IN_DELETE(self, event):
|
||||||
|
|
||||||
|
self.producer.publish({"name": "Hi!"})
|
||||||
|
|
||||||
|
self.logger.info("%s: %s", event.maskname, event.pathname)
|
||||||
|
|
||||||
|
def process_IN_DELETE_SELF(self, event):
|
||||||
|
|
||||||
|
self.logger.info("%s: %s", event.maskname, event.pathname)
|
||||||
|
|
||||||
def process_default(self, event):
|
def process_default(self, event):
|
||||||
self.logger.info("%s: %s", event.maskname, event.pathname)
|
self.logger.info("%s: %s", event.maskname, event.pathname)
|
||||||
|
|
||||||
|
|
||||||
|
def check_rabbit_MQ(self, notifier):
|
||||||
|
try:
|
||||||
|
notifier.connection.drain_events(timeout=int(config["check_airtime_events"]))
|
||||||
|
except Exception, e:
|
||||||
|
logger = logging.getLogger('root')
|
||||||
|
logger.info("%s", e)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# watched events
|
# watched events
|
||||||
mask = pyinotify.IN_CREATE | pyinotify.IN_MODIFY | pyinotify.IN_MOVED_FROM | pyinotify.IN_MOVED_TO
|
mask = pyinotify.IN_CREATE | \
|
||||||
|
pyinotify.IN_MODIFY | \
|
||||||
|
pyinotify.IN_MOVED_FROM | \
|
||||||
|
pyinotify.IN_MOVED_TO | \
|
||||||
|
pyinotify.IN_DELETE | \
|
||||||
|
pyinotify.IN_DELETE_SELF
|
||||||
#mask = pyinotify.ALL_EVENTS
|
#mask = pyinotify.ALL_EVENTS
|
||||||
|
|
||||||
wm = WatchManager()
|
wm = WatchManager()
|
||||||
|
@ -350,7 +376,7 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
notifier = AirtimeNotifier(wm, mm, read_freq=int(config["check_filesystem_events"]), timeout=1)
|
notifier = AirtimeNotifier(wm, mm, read_freq=int(config["check_filesystem_events"]), timeout=1)
|
||||||
notifier.coalesce_events()
|
notifier.coalesce_events()
|
||||||
notifier.loop(callback=checkRabbitMQ)
|
notifier.loop(callback=mm.check_rabbit_MQ)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
notifier.stop()
|
notifier.stop()
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
|
|
|
@ -23,7 +23,7 @@ version_url = 'version/api_key/%%api_key%%'
|
||||||
media_status_url = 'media-item-status/format/json/api_key/%%api_key%%/md5/%%md5%%'
|
media_status_url = 'media-item-status/format/json/api_key/%%api_key%%/md5/%%md5%%'
|
||||||
|
|
||||||
# URL to tell Airtime to update file's meta data
|
# URL to tell Airtime to update file's meta data
|
||||||
update_media_url = 'reload-metadata/format/json/api_key/%%api_key%%'
|
update_media_url = 'reload-metadata/format/json/api_key/%%api_key%%/mode/%%mode%%'
|
||||||
|
|
||||||
############################################
|
############################################
|
||||||
# RabbitMQ settings #
|
# RabbitMQ settings #
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue