diff --git a/.travis.yml b/.travis.yml index 98b47313d..03fd55622 100644 --- a/.travis.yml +++ b/.travis.yml @@ -58,6 +58,7 @@ addons: - liquidsoap-plugin-faad - liquidsoap-plugin-vorbis - liquidsoap-plugin-opus + - python3 - python3-nose - python3-gst-1.0 - python3-magic diff --git a/python_apps/api_clients/api_clients/api_client.py b/python_apps/api_clients/api_clients/api_client.py index 1fd9300c2..95ad844e9 100644 --- a/python_apps/api_clients/api_clients/api_client.py +++ b/python_apps/api_clients/api_clients/api_client.py @@ -8,7 +8,6 @@ ############################################################################### import sys import time -import urllib.request, urllib.parse, urllib.error import urllib.request, urllib.error, urllib.parse import requests import socket @@ -21,26 +20,6 @@ from configobj import ConfigObj AIRTIME_API_VERSION = "1.1" -# TODO : Place these functions in some common module. Right now, media -# monitor uses the same functions and it would be better to reuse them -# instead of copy pasting them around - -def to_unicode(obj, encoding='utf-8'): - if isinstance(obj, str): - if not isinstance(obj, str): - obj = str(obj, encoding) - return obj - -def encode_to(obj, encoding='utf-8'): - if isinstance(obj, str): - obj = obj.encode(encoding) - 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 list(md.items())]) - - api_config = {} # URL to get the version number of the server API @@ -407,7 +386,7 @@ class AirtimeApiClient(object): # Note that we must prefix every key with: mdX where x is a number # Is there a way to format the next line a little better? The # parenthesis make the code almost unreadable - md_list = dict((("md%d" % i), json.dumps(convert_dict_value_to_utf8(md))) \ + md_list = dict((("md%d" % i), json.dumps(md)) \ for i,md in enumerate(valid_actions)) # For testing we add the following "dry" parameter to tell the # controller not to actually do any changes diff --git a/python_apps/pypo/liquidsoap/liquidsoap_prepare_terminate.py b/python_apps/pypo/liquidsoap/liquidsoap_prepare_terminate.py index 20766bebf..d40655fc9 100644 --- a/python_apps/pypo/liquidsoap/liquidsoap_prepare_terminate.py +++ b/python_apps/pypo/liquidsoap/liquidsoap_prepare_terminate.py @@ -14,6 +14,6 @@ try: tn.read_all() except Exception as e: - print(('Error loading config file: %s', e)) + print("Error loading config file: {}".format(e)) sys.exit() diff --git a/python_apps/pypo/pypo/__main__.py b/python_apps/pypo/pypo/__main__.py index 94c8af0b5..d9f3160a0 100644 --- a/python_apps/pypo/pypo/__main__.py +++ b/python_apps/pypo/pypo/__main__.py @@ -120,7 +120,7 @@ try: consoleHandler.setFormatter(logFormatter) rootLogger.addHandler(consoleHandler) except Exception as e: - print(("Couldn't configure logging", e)) + print("Couldn't configure logging: {}".format(e)) sys.exit(1) diff --git a/python_apps/pypo/pypo/listenerstat.py b/python_apps/pypo/pypo/listenerstat.py index 91a9e9487..e94c7f795 100644 --- a/python_apps/pypo/pypo/listenerstat.py +++ b/python_apps/pypo/pypo/listenerstat.py @@ -109,7 +109,7 @@ class ListenerStat(Thread): #Note that there can be optimizations done, since if all three #streams are the same server, we will still initiate 3 separate #connections - for k, v in list(stream_parameters.items()): + for k, v in stream_parameters.items(): if v["enable"] == 'true': try: if v["output"] == "icecast": diff --git a/python_apps/pypo/pypo/pypofetch.py b/python_apps/pypo/pypo/pypofetch.py index 827346888..b04aab7f3 100644 --- a/python_apps/pypo/pypo/pypofetch.py +++ b/python_apps/pypo/pypo/pypofetch.py @@ -344,20 +344,21 @@ class PypoFetch(Thread): media_item = media[key] if (media_item['type'] == 'file'): fileExt = self.sanity_check_media_item(media_item) - dst = os.path.join(download_dir, str(media_item['id']) + str(fileExt)) + dst = os.path.join(download_dir, media_item['id'] + fileExt) media_item['dst'] = dst media_item['file_ready'] = False media_filtered[key] = media_item - media_item['start'] = datetime.strptime(media_item['start'], + media_item['start'] = datetime.strptime(media_item['start'], "%Y-%m-%d-%H-%M-%S") - media_item['end'] = datetime.strptime(media_item['end'], + media_item['end'] = datetime.strptime(media_item['end'], "%Y-%m-%d-%H-%M-%S") media_copy[key] = media_item self.media_prepare_queue.put(copy.copy(media_filtered)) - except Exception as e: self.logger.error("%s", e) + except Exception as e: + self.logger.error(e) # Send the data to pypo-push self.logger.debug("Pushing to pypo-push") @@ -365,8 +366,10 @@ class PypoFetch(Thread): # cleanup - try: self.cache_cleanup(media) - except Exception as e: self.logger.error("%s", e) + try: + self.cache_cleanup(media) + except Exception as e: + self.logger.error(e) #do basic validation of file parameters. Useful for debugging #purposes @@ -408,7 +411,7 @@ class PypoFetch(Thread): for mkey in media: media_item = media[mkey] if media_item['type'] == 'file': - scheduled_file_set.add(str(media_item["id"]) + str(media_item["file_ext"])) + scheduled_file_set.add(media_item["id"] + media_item["file_ext"]) expired_files = cached_file_set - scheduled_file_set diff --git a/python_apps/pypo/pypo/pypoliquidsoap.py b/python_apps/pypo/pypo/pypoliquidsoap.py index d9feca6d5..773879020 100644 --- a/python_apps/pypo/pypo/pypoliquidsoap.py +++ b/python_apps/pypo/pypo/pypoliquidsoap.py @@ -125,7 +125,7 @@ class PypoLiquidsoap(): scheduled_now_webstream = \ [x for x in scheduled_now if x["type"] == eventtypes.STREAM_OUTPUT_START] - schedule_ids = set([x["row_id"] for x in scheduled_now_files]) + schedule_ids = {x["row_id"] for x in scheduled_now_files]} row_id_map = {} liq_queue_ids = set() @@ -199,7 +199,7 @@ class PypoLiquidsoap(): return media_item["type"] == eventtypes.FILE def clear_queue_tracker(self): - for i in list(self.liq_queue_tracker.keys()): + for i in self.liq_queue_tracker.keys(): self.liq_queue_tracker[i] = None def modify_cue_point(self, link): diff --git a/python_apps/pypo/pypo/recorder.py b/python_apps/pypo/pypo/recorder.py index 24850e7cc..6ed3f301d 100644 --- a/python_apps/pypo/pypo/recorder.py +++ b/python_apps/pypo/pypo/recorder.py @@ -37,7 +37,7 @@ def api_client(logger): try: config = ConfigObj('/etc/airtime/airtime.conf') except Exception as e: - print(('Error loading config file: %s', e)) + print("Error loading config file: {}".format(e)) sys.exit() # TODO : add docstrings everywhere in this module @@ -95,7 +95,7 @@ class ShowRecorder(Thread): self.logger.info("starting record") self.logger.info("command " + command) - + self.p = Popen(args,stdout=PIPE,stderr=PIPE) #blocks at the following line until the child process @@ -131,7 +131,7 @@ class ShowRecorder(Thread): register_openers() # files is what requests actually expects - files = {'file': open(filepath, "rb"), 'name': filename, 'show_instance': str(self.show_instance)} + files = {'file': open(filepath, "rb"), 'name': filename, 'show_instance': self.show_instance} self.api_client.upload_recorded_show(files, self.show_instance) @@ -153,7 +153,7 @@ class ShowRecorder(Thread): recorded_file['title'] = "%s-%s-%s" % (self.show_name, full_date, full_time) #You cannot pass ints into the metadata of a file. Even tracknumber needs to be a string - recorded_file['tracknumber'] = str(self.show_instance) + recorded_file['tracknumber'] = self.show_instance recorded_file.save() except Exception as e: @@ -246,11 +246,11 @@ class Recorder(Thread): self.logger.debug("Next show %s", next_show) self.logger.debug("Now %s", tnow) return out - + def cancel_recording(self): self.sr.cancel_recording() self.sr = None - + def currently_recording(self): if self.sr is not None and self.sr.is_recording(): return True @@ -278,23 +278,23 @@ class Recorder(Thread): start_time_formatted = '%(year)d-%(month)02d-%(day)02d %(hour)02d:%(min)02d:%(sec)02d' % \ {'year': start_time_on_server.year, 'month': start_time_on_server.month, 'day': start_time_on_server.day, \ 'hour': start_time_on_server.hour, 'min': start_time_on_server.minute, 'sec': start_time_on_server.second} - - + + seconds_waiting = 0 - + #avoiding CC-5299 while(True): if self.currently_recording(): self.logger.info("Previous record not finished, sleeping 100ms") seconds_waiting = seconds_waiting + 0.1 - time.sleep(0.1) + time.sleep(0.1) else: show_length_seconds = show_length.seconds - seconds_waiting - + self.sr = ShowRecorder(show_instance, show_name, show_length_seconds, start_time_formatted) self.sr.start() break - + #remove show from shows to record. del self.shows_to_record[start_time] #self.time_till_next_show = self.get_time_till_next_show() diff --git a/travis/python.sh b/travis/python.sh index 477d277a0..28ac33a6b 100755 --- a/travis/python.sh +++ b/travis/python.sh @@ -4,11 +4,12 @@ set -xe [[ "$PYTHON" == false ]] && exit 0 +python3 --version + pushd python_apps/airtime_analyzer -pyenv local 3.7 +pyenv local 3.4 pip3 install -e . -nosetests -a '!rgain' -echo "replaygain tests where skipped due to not having a reliable replaygain install on travis." +nosetests popd echo "Building docs..."