From 9964c826ab30643e3ff8887136c4e4f3ae6f517c Mon Sep 17 00:00:00 2001 From: Rudi Grinberg Date: Fri, 20 Jul 2012 11:13:18 -0400 Subject: [PATCH] cc-4105: Added problem dir moving. Also locale config from old media monitor --- .../application/controllers/ApiController.php | 2 +- .../media-monitor2/media/monitor/airtime.py | 2 +- .../media-monitor2/media/monitor/bootstrap.py | 6 +++ .../media/monitor/exceptions.py | 3 ++ .../media-monitor2/media/monitor/handler.py | 10 +++-- .../media-monitor2/media/monitor/pure.py | 38 +++++++++++++++++-- .../media-monitor2/tests/test_metadata.py | 1 + 7 files changed, 53 insertions(+), 9 deletions(-) diff --git a/airtime_mvc/application/controllers/ApiController.php b/airtime_mvc/application/controllers/ApiController.php index 2bbb02fcb..4d6ae2f9e 100644 --- a/airtime_mvc/application/controllers/ApiController.php +++ b/airtime_mvc/application/controllers/ApiController.php @@ -580,7 +580,7 @@ class ApiController extends Zend_Controller_Action $mode = $info_json['mode']; unset( $info_json['mode'] ); $response = $this->dispatchMetadataAction($info_json, $mode, $dry_run=$dry); - // We attack the 'key' back to every request in case the would like to associate + // We tack on the 'key' back to every request in case the would like to associate // his requests with particular responses $response['key'] = $k; array_push($responses, $response); diff --git a/python_apps/media-monitor2/media/monitor/airtime.py b/python_apps/media-monitor2/media/monitor/airtime.py index 4a21a3bf6..9281b90ae 100644 --- a/python_apps/media-monitor2/media/monitor/airtime.py +++ b/python_apps/media-monitor2/media/monitor/airtime.py @@ -84,7 +84,7 @@ class AirtimeMessageReceiver(Loggable): def supported_messages(self): return self.dispatch_table.keys() - # Handler methods - Should either fire the events directly with + # TODO : Handler methods - Should either fire the events directly with # pydispatcher or do the necessary changes on the filesystem that will fire # the events def md_update(self, msg): diff --git a/python_apps/media-monitor2/media/monitor/bootstrap.py b/python_apps/media-monitor2/media/monitor/bootstrap.py index 7e27ca1c7..8cffa5b5f 100644 --- a/python_apps/media-monitor2/media/monitor/bootstrap.py +++ b/python_apps/media-monitor2/media/monitor/bootstrap.py @@ -38,6 +38,12 @@ class Bootstrapper(Loggable): for pc in self.watch_channels: for f in mmp.walk_supported(pc.path, clean_empties=False): songs.add(f) + # We decide whether to update a file's metadata by checking + # its system modification date. If it's above the value + # self.last_run which is passed to us that means media monitor + # wasn't aware when this changes occured in the filesystem + # hence it will send the correct events to sync the database + # with the filesystem if os.path.getmtime(f) > self.last_ran: modded += 1 dispatcher.send(signal=pc.signal, sender=self, event=DeleteFile(f)) diff --git a/python_apps/media-monitor2/media/monitor/exceptions.py b/python_apps/media-monitor2/media/monitor/exceptions.py index 263f0763c..aaaf8b7d8 100644 --- a/python_apps/media-monitor2/media/monitor/exceptions.py +++ b/python_apps/media-monitor2/media/monitor/exceptions.py @@ -12,3 +12,6 @@ class NoConfigFile(Exception): class ConfigAccessViolation(Exception): def __init__(self,key): self.key = key def __str__(self): return "You must not access key '%s' directly" % self.key + +class FailedToSetLocale(Exception): + def __str__(self): return "Failed to set locale" diff --git a/python_apps/media-monitor2/media/monitor/handler.py b/python_apps/media-monitor2/media/monitor/handler.py index 7a1067bfc..f70d48177 100644 --- a/python_apps/media-monitor2/media/monitor/handler.py +++ b/python_apps/media-monitor2/media/monitor/handler.py @@ -3,6 +3,7 @@ from pydispatch import dispatcher import abc from media.monitor.log import Loggable +import media.monitor.pure as mmp # Defines the handle interface class Handles(object): @@ -10,7 +11,6 @@ class Handles(object): @abc.abstractmethod def handle(self, sender, event, *args, **kwargs): pass - # TODO : remove the code duplication between ReportHandler and # ProblemFileHandler. Namely the part where both initialize pydispatch # TODO : Investigate whether weak reffing in dispatcher.connect could possibly @@ -36,6 +36,8 @@ class ProblemFileHandler(Handles, Loggable): dispatcher.connect(dummy, signal=self.signal, sender=dispatcher.Any, weak=False) def handle(self, sender, event, exception=None): - self.logger.info("Received problem file: '%s'. Supposed to move it somewhere", event.path) - # TODO : not actually moving it anywhere yet - + self.logger.info("Received problem file: '%s'. Supposed to move it to problem dir", event.path) + try: mmp.move_to_dir(dir_path=self.problem_dir, file_path=event.path) + except Exception as e: + self.logger.info("Could not move file: '%s' to problem dir: '%s'" % (event.path, self.problem_dir)) + self.logger.info("Exception: %s" % str(e)) diff --git a/python_apps/media-monitor2/media/monitor/pure.py b/python_apps/media-monitor2/media/monitor/pure.py index a621e5458..6ca6630de 100644 --- a/python_apps/media-monitor2/media/monitor/pure.py +++ b/python_apps/media-monitor2/media/monitor/pure.py @@ -2,7 +2,13 @@ import copy import os import shutil +import sys import hashlib +from configobj import ConfigObj +import locale + +from media.monitor.exceptions import FailedToSetLocale + supported_extensions = ["mp3", "ogg"] unicode_unknown = u'unknown' @@ -21,7 +27,6 @@ class LazyProperty(object): setattr(obj,self.func_name,value) return value - class IncludeOnly(object): """ A little decorator to help listeners only be called on extensions they support @@ -40,6 +45,7 @@ class IncludeOnly(object): return _wrap def is_file_supported(path): + # TODO : test and document this function return extension(path) in supported_extensions # In the future we would like a better way to find out @@ -49,6 +55,7 @@ def is_airtime_recorded(md): def clean_empty_dirs(path): """ walks path and deletes every empty directory it finds """ + # TODO : test this function if path.endswith('/'): clean_empty_dirs(path[0:-1]) else: for root, dirs, _ in os.walk(path, topdown=False): @@ -99,11 +106,16 @@ def walk_supported(directory, clean_empties=False): if clean_empties: clean_empty_dirs(directory) def magic_move(old, new): - # TODO : document this + # TODO : document and test this function new_dir = os.path.dirname(new) if not os.path.exists(new_dir): os.makedirs(new_dir) shutil.move(old,new) +def move_to_dir(dir_path,file_path): + # TODO : document and test this function + bs = os.path.basename(file_path) + magic_move(file_path, os.path.join(dir_path, bs)) + def apply_rules_dict(d, rules): # TODO : document this new_d = copy.deepcopy(d) @@ -212,9 +224,29 @@ def encode_to(obj, encoding='utf-8'): return obj def convert_dict_value_to_utf8(md): - #list comprehension to convert all values of md to utf-8 return dict([(item[0], encode_to(item[1], "utf-8")) for item in md.items()]) +def configure_locale(): + current_locale = locale.getlocale() + if current_locale[1] is None: + default_locale = locale.getdefaultlocale() + if default_locale[1] is None: + if os.path.exists("/etc/default/locale"): + config = ConfigObj('/etc/default/locale') + lang = config.get('LANG') + new_locale = lang + else: + raise FailedToSetLocale() + else: + new_locale = default_locale + locale.setlocale(locale.LC_ALL, new_locale) + reload(sys) + sys.setdefaultencoding("UTF-8") + current_locale_encoding = locale.getlocale()[1].lower() + if current_locale_encoding not in ['utf-8', 'utf8']: + raise FailedToSetLocale() + + if __name__ == '__main__': import doctest doctest.testmod() diff --git a/python_apps/media-monitor2/tests/test_metadata.py b/python_apps/media-monitor2/tests/test_metadata.py index e7fea3363..6f24240b0 100644 --- a/python_apps/media-monitor2/tests/test_metadata.py +++ b/python_apps/media-monitor2/tests/test_metadata.py @@ -38,6 +38,7 @@ class TestMetadata(unittest.TestCase): self.assertEqual( mmm.airtime2mutagen[airtime], muta ) def test_format_length(self): + # TODO : add some real tests for this function x1 = 123456 print("Formatting '%s' to '%s'" % (x1, mmm.format_length(x1)))