From bcb65c4269cfec79ee4a330818c21de87e6413d3 Mon Sep 17 00:00:00 2001
From: Rudi Grinberg <rudi.grinberg@sourcefabric.org>
Date: Tue, 7 Aug 2012 16:57:35 -0400
Subject: [PATCH] cc-4105: fixed bug where program would crash on non integer
 track numbers

---
 python_apps/media-monitor2/media/monitor/log.py  |  1 -
 .../media-monitor2/media/monitor/metadata.py     |  6 ++++--
 python_apps/media-monitor2/media/monitor/pure.py | 10 +++++++++-
 .../media/monitor/watchersyncer.py               | 16 ++++++++++------
 python_apps/media-monitor2/mm2.py                |  2 --
 python_apps/media-monitor2/tests/live_client.cfg |  2 +-
 6 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/python_apps/media-monitor2/media/monitor/log.py b/python_apps/media-monitor2/media/monitor/log.py
index d01a96881..c73f8945b 100644
--- a/python_apps/media-monitor2/media/monitor/log.py
+++ b/python_apps/media-monitor2/media/monitor/log.py
@@ -3,7 +3,6 @@ import abc
 import traceback
 from media.monitor.pure import LazyProperty
 
-logfile = '/home/rudi/throwaway/mm2.log'
 #logger = None
 
 def setup_logging(log_path):
diff --git a/python_apps/media-monitor2/media/monitor/metadata.py b/python_apps/media-monitor2/media/monitor/metadata.py
index c2f99cae4..75302c9a7 100644
--- a/python_apps/media-monitor2/media/monitor/metadata.py
+++ b/python_apps/media-monitor2/media/monitor/metadata.py
@@ -123,8 +123,10 @@ class Metadata(Loggable):
         for k,v in full_mutagen.iteritems():
             # Special handling of attributes here
             if isinstance(v, list):
-                if len(v) == 1: metadata[k] = v[0]
-                else: raise Exception("Unknown mutagen %s:%s" % (k,str(v)))
+                # TODO : some files have multiple fields for the same metadata.
+                # genre is one example. In that case mutagen will return a list
+                # of values
+                metadata[k] = v[0]
             else: metadata[k] = v
         self.__metadata = {}
         # Start populating a dictionary of airtime metadata in __metadata
diff --git a/python_apps/media-monitor2/media/monitor/pure.py b/python_apps/media-monitor2/media/monitor/pure.py
index 8edc9bbc6..d224c791d 100644
--- a/python_apps/media-monitor2/media/monitor/pure.py
+++ b/python_apps/media-monitor2/media/monitor/pure.py
@@ -3,6 +3,7 @@ import copy
 import os
 from os.path import normpath
 import shutil
+from itertools import takewhile
 import sys
 import hashlib
 from configobj import ConfigObj
@@ -156,6 +157,13 @@ def remove_whitespace(dictionary):
     for bad_key in bad_keys: del nd[bad_key]
     return nd
 
+def parse_int(s):
+    if s.isdigit(): return s
+    else:
+        try:
+            return reduce(lambda x,y: x + y,
+                    takewhile(lambda x: x.isdigit(), s))
+        except: return 0
 
 def normalized_metadata(md, original_path):
     """ consumes a dictionary of metadata and returns a new dictionary with the
@@ -170,7 +178,7 @@ def normalized_metadata(md, original_path):
         # It's very likely that the following isn't strictly necessary. But the old
         # code would cast MDATA_KEY_TRACKNUMBER to an integer as a byproduct of
         # formatting the track number to 2 digits.
-        'MDATA_KEY_TRACKNUMBER' : lambda x: int(x),
+        'MDATA_KEY_TRACKNUMBER' : parse_int,
         'MDATA_KEY_BITRATE' : lambda x: str(int(x) / 1000) + "kbps",
         # note: you don't actually need the lambda here. It's only used for clarity
         'MDATA_KEY_FILEPATH' : lambda x: os.path.normpath(x),
diff --git a/python_apps/media-monitor2/media/monitor/watchersyncer.py b/python_apps/media-monitor2/media/monitor/watchersyncer.py
index 956f31173..68ebfa5f8 100644
--- a/python_apps/media-monitor2/media/monitor/watchersyncer.py
+++ b/python_apps/media-monitor2/media/monitor/watchersyncer.py
@@ -6,7 +6,7 @@ import traceback
 
 from media.monitor.handler import ReportHandler
 from media.monitor.log import Loggable
-from media.monitor.listeners import FileMediator
+#from media.monitor.listeners import FileMediator
 from media.monitor.exceptions import BadSongFile
 from media.monitor.pure import LazyProperty
 
@@ -17,7 +17,7 @@ class RequestSync(threading.Thread,Loggable):
         threading.Thread.__init__(self)
         self.watcher = watcher
         self.requests = requests
-        self.retries = 3
+        self.retries = 1
         self.request_wait = 0.3
 
     @LazyProperty
@@ -42,8 +42,8 @@ class RequestSync(threading.Thread,Loggable):
                 self.logger.info("Bad song file: '%s'" % e.path)
             except Exception as e:
                 self.logger.info("An evil exception occured")
-                import ipdb; ipdb.set_trace()
                 self.logger.error( traceback.format_exc() )
+                import ipdb; ipdb.set_trace()
         def make_req():
             self.apiclient.send_media_monitor_requests( packed_requests )
         # Is this retry shit even necessary? Consider getting rid of this.
@@ -55,6 +55,10 @@ class RequestSync(threading.Thread,Loggable):
                         it's not returning json when it should\n \
                         ... will fix once I setup the damn debugger")
                 self.logger.info("Trying again after %f seconds" % self.request_wait)
+                self.logger.info("==== choked on '%s' ====" % packed_requests)
+                print("==== choked on '%s' ====" % packed_requests)
+                #self.logger.info( traceback.format_exc() )
+                #import ipdb; ipdb.set_trace()
                 time.sleep( self.request_wait )
             except Exception as e:
                 self.unexpected_exception(e)
@@ -62,7 +66,7 @@ class RequestSync(threading.Thread,Loggable):
                 self.logger.info("Request worked on the '%d' try" % (try_index + 1))
                 break
         else: self.logger.info("Failed to send request after '%d' tries..." % self.retries)
-        self.logger.info("Now ignoring: %d files" % len(FileMediator.ignored_set))
+        #self.logger.info("Now ignoring: %d files" % len(FileMediator.ignored_set))
         self.watcher.flag_done()
 
 class TimeoutWatcher(threading.Thread,Loggable):
@@ -94,7 +98,7 @@ class WatchSyncer(ReportHandler,Loggable):
         self.path = '' # TODO : get rid of this attribute everywhere
         #self.signal = signal
         self.timeout = float(timeout)
-        self.chunking_number = chunking_number
+        self.chunking_number = int(chunking_number)
         self.__queue = []
         # Even though we are not blocking on the http requests, we are still
         # trying to send the http requests in order
@@ -135,7 +139,7 @@ class WatchSyncer(ReportHandler,Loggable):
 
     def push_queue(self, elem):
         self.logger.info("Added event into queue")
-        if self.events_left_count() == self.chunking_number:
+        if self.events_left_count() >= self.chunking_number:
             self.push_request()
             self.request_do() # Launch the request if nothing is running
         self.__queue.append(elem)
diff --git a/python_apps/media-monitor2/mm2.py b/python_apps/media-monitor2/mm2.py
index 765f44a3a..094ac78a1 100644
--- a/python_apps/media-monitor2/mm2.py
+++ b/python_apps/media-monitor2/mm2.py
@@ -23,7 +23,6 @@ api_client_config = u'/home/rudi/Airtime/python_apps/media-monitor2/tests/live_c
 # users of MMConfig instances to modify any config options directly through the
 # dictionary. Users of this object muse use the correct methods designated for
 # modification
-config = None
 try: config = MMConfig(global_config)
 except NoConfigFile as e:
     print("Cannot run mediamonitor2 without configuration file.")
@@ -34,7 +33,6 @@ except Exception as e:
     print(str(e))
 
 logfile = unicode( config['logpath'] )
-
 setup_logging(logfile)
 log = get_logger()
 log.info("Attempting to set the locale...")
diff --git a/python_apps/media-monitor2/tests/live_client.cfg b/python_apps/media-monitor2/tests/live_client.cfg
index 2146df488..468be306c 100644
--- a/python_apps/media-monitor2/tests/live_client.cfg
+++ b/python_apps/media-monitor2/tests/live_client.cfg
@@ -15,7 +15,7 @@ check_filesystem_events = 5 #how long to queue up events performed on the files
 check_airtime_events = 30 #how long to queue metadata input from airtime.
 
 touch_interval = 5
-chunking_number = 150
+chunking_number = 1
 request_max_wait = 3.0
 rmq_event_wait = 0.5
 logpath = '/home/rudi/throwaway/mm2.log'