diff --git a/baps_types/marker.py b/baps_types/marker.py index d4f6bff..4d61726 100644 --- a/baps_types/marker.py +++ b/baps_types/marker.py @@ -1,5 +1,5 @@ import json -from typing import Dict, Literal, Optional, Union +from typing import Dict, Optional, Union POSITIONS = ["start", "mid", "end"] PARAMS = ["name", "time", "position", "section"] diff --git a/baps_types/plan.py b/baps_types/plan.py index e5afbbd..28406ea 100644 --- a/baps_types/plan.py +++ b/baps_types/plan.py @@ -14,7 +14,7 @@ import json -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Optional import os from time import time diff --git a/build/generate-build-exe-config.py b/build/generate-build-exe-config.py index fa729b9..8d5a60d 100644 --- a/build/generate-build-exe-config.py +++ b/build/generate-build-exe-config.py @@ -21,7 +21,8 @@ for option in config["pyinstallerOptions"]: if not isWindows(): option["value"] = option["value"].replace(";", ":") elif relative_fix: - option["value"] += "./" # Add the windows relative path. + # Add the windows relative path. + option["value"] += "./" out_file = open('build-exe-config.json', 'w') out_file.write(json.dumps(config, indent=2)) diff --git a/dev/pre-commit b/dev/pre-commit index 22aa5b4..7e330a9 100755 --- a/dev/pre-commit +++ b/dev/pre-commit @@ -7,10 +7,11 @@ import re import subprocess import sys -#See for codes https://pypi.org/project/autopep8/ #features +# See for codes https://pypi.org/project/autopep8/ #features # don't fill in both of these select_codes = [] -ignore_codes = ["E402","E226","E24","W50","W690"] #"E121", "E122", "E123", "E124", "E125", "E126", "E127", "E128", "E129", "E131", "E501"] +# "E121", "E122", "E123", "E124", "E125", "E126", "E127", "E128", "E129", "E131", "E501"] +ignore_codes = ["E402", "E226", "E24", "W50", "W690"] # Add things like "--max-line-length=120" below overrides = ["--max-line-length=127"] @@ -18,7 +19,7 @@ overrides = ["--max-line-length=127"] def system(*args, **kwargs): kwargs.setdefault('stdout', subprocess.PIPE) proc = subprocess.Popen(args, **kwargs) - out,_ = proc.communicate() + out, _ = proc.communicate() return out @@ -44,7 +45,7 @@ def main(): print("'autopep8' is required. Please install with `pip install autopep8`.", file=sys.stderr) exit(1) - modified = re.compile('^[AM]+\s+(?P.*\.py)', re.MULTILINE) + modified = re.compile('^[AM]+\\s+(?P.*\\.py)', re.MULTILINE) basedir = system('git', 'rev-parse', '--show-toplevel').decode("utf-8").strip() files = system('git', 'status', '--porcelain').decode("utf-8") files = modified.findall(files) diff --git a/file_manager.py b/file_manager.py index cb99c9b..06af766 100644 --- a/file_manager.py +++ b/file_manager.py @@ -62,9 +62,10 @@ class FileManager: if ( self.channel_received != [ False] * self.channel_count - and self.channel_received[channel] != True + and self.channel_received[channel] is False ): - # We've already received a delete trigger on a channel, let's not delete the folder more than once. + # We've already received a delete trigger on a channel, + # let's not delete the folder more than once. # If the channel was already in the process of being deleted, the user has # requested it again, so allow it. @@ -124,7 +125,8 @@ class FileManager: for item in show_plan: item_ids += item["timeslotitemid"] - # If the new status update has a different order / list of items, let's update the show plan we know about + # If the new status update has a different order / list of items, + # let's update the show plan we know about # This will trigger the chunk below to do the rounds again and preload any new files. if item_ids != self.last_known_item_ids[channel]: self.last_known_item_ids[channel] = item_ids diff --git a/helpers/myradio_api.py b/helpers/myradio_api.py index 77e8f65..f1cb32a 100644 --- a/helpers/myradio_api.py +++ b/helpers/myradio_api.py @@ -172,7 +172,7 @@ class MyRadioAPI: # Remove jukebox etc for show in shows: - if not "timeslot_id" in show: + if "timeslot_id" not in show: shows.remove(show) return shows @@ -248,7 +248,8 @@ class MyRadioAPI: ) while time_waiting_s < 20: # TODO: Make something better here. - # If the connectivity is super poor or we're loading reeaaaalllly long files, this may be annoying, but this is just in case somehow the other api download gives up. + # If the connectivity is super poor or we're loading reeaaaalllly long files, + # this may be annoying, but this is just in case somehow the other api download gives up. if os.path.isfile(filename): # Now the file is downloaded successfully return (filename, False) if did_download else filename @@ -305,7 +306,7 @@ class MyRadioAPI: async def get_playlist_aux_items(self, library_id: str): # Sometimes they have "aux-", we only need the index. if library_id.index("-") > -1: - library_id = library_id[library_id.index("-") + 1 :] + library_id = library_id[library_id.index("-") + 1:] url = "/nipswebPlaylist/{}/items".format(library_id) request = await self.async_api_call(url) diff --git a/helpers/normalisation.py b/helpers/normalisation.py index 35f1d3b..c7a8e1e 100644 --- a/helpers/normalisation.py +++ b/helpers/normalisation.py @@ -4,6 +4,8 @@ from pydub import AudioSegment, effects # Audio leveling! # Stuff to help make BAPSicle play out leveled audio. # Takes filename in, normalialises it and returns a normalised file path. + + def generate_normalised_file(filename: str): if not (isinstance(filename, str) and filename.endswith(".mp3")): raise ValueError("Invalid filename given.") diff --git a/helpers/state_manager.py b/helpers/state_manager.py index 52e1321..c6133b5 100644 --- a/helpers/state_manager.py +++ b/helpers/state_manager.py @@ -78,9 +78,10 @@ class StateManager: # If there are any new config options in the default state, save them. # Uses update() to save them to file too. - for key in default_state.keys(): - if key not in file_state.keys(): - self.update(key, default_state[key]) + if default_state: + for key in default_state.keys(): + if key not in file_state.keys(): + self.update(key, default_state[key]) except Exception: self._logException( @@ -186,7 +187,8 @@ class StateManager: if index > -1 and key in state_to_update: if not isinstance(state_to_update[key], list): self._log( - "Not updating state for key '{}' with value '{}' of type '{}' since index is set and key is not a list.".format( + "Not updating state for key '{}' with value '{}' of type '{}' since index is set and key is not a list." + .format( key, value, type(value) ), DEBUG, diff --git a/package.json b/package.json index 9b38633..ea10526 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "presenter-make": "npm run presenter-install && (rm -r presenter-build || true) && cd presenter && yarn build-baps && cp -r build ../presenter-build && cd ../ && npm install", "test": "echo \"Error: no test specified\" && exit 1", "presenter-start": "cd presenter && yarn start", - "lint": "autopep8 -r ./*.py -a -a --ignore E402,E226,E24,W50,W690 --max-line-length 127 --in-place" + "lint": "autopep8 -r -a -a --ignore E402,E226,E24,W50,W690 --max-line-length 127 --in-place --exclude=\"*node_modules*,*venv/*,presenter/*\" . " }, "repository": { "type": "git", diff --git a/player.py b/player.py index bcacec9..2f70f31 100644 --- a/player.py +++ b/player.py @@ -20,28 +20,29 @@ # that we respond with something, FAIL or OKAY. The server doesn't like to be kept waiting. # Stop the Pygame Hello message. -import package -from baps_types.marker import Marker -from baps_types.plan import PlanItem -from helpers.logging_manager import LoggingManager -from helpers.state_manager import StateManager -from helpers.myradio_api import MyRadioAPI -from helpers.normalisation import get_normalised_filename_if_available -from threading import Timer -from syncer import sync -from mutagen.mp3 import MP3 -from pygame import mixer -from typing import Any, Callable, Dict, List, Optional -import time -import json -import copy -import setproctitle -import multiprocessing -from queue import Empty import os os.environ["PYGAME_HIDE_SUPPORT_PROMPT"] = "hide" +from queue import Empty +import multiprocessing +import setproctitle +import copy +import json +import time +from typing import Any, Callable, Dict, List, Optional +from pygame import mixer +from mutagen.mp3 import MP3 +from syncer import sync +from threading import Timer + +from helpers.normalisation import get_normalised_filename_if_available +from helpers.myradio_api import MyRadioAPI +from helpers.state_manager import StateManager +from helpers.logging_manager import LoggingManager +from baps_types.plan import PlanItem +from baps_types.marker import Marker +import package # TODO ENUM VALID_MESSAGE_SOURCES = ["WEBSOCKET", "UI", "CONTROLLER", "TEST", "ALL"] @@ -300,8 +301,10 @@ class Player: def _check_ghosts(self, item: PlanItem): if isinstance(item.timeslotitemid, str) and item.timeslotitemid.startswith("I"): - # Kinda a bodge for the moment, each "Ghost" (item which is not saved in the database showplan yet) needs to have a unique temporary item. - # To do this, we'll start with the channel number the item was originally added to (to stop items somehow simultaneously added to different channels from having the same id) + # Kinda a bodge for the moment, each "Ghost" (item which is not saved in the database showplan yet) + # needs to have a unique temporary item. + # To do this, we'll start with the channel number the item was originally added to + # (to stop items somehow simultaneously added to different channels from having the same id) # And chuck in the unix epoch in ns for good measure. item.timeslotitemid = "GHOST-{}-{}".format( self.state.get()["channel"], time.time_ns() diff --git a/server.py b/server.py index eae1d52..83a80d0 100644 --- a/server.py +++ b/server.py @@ -113,7 +113,8 @@ class BAPSicleServer: ): for channel in range(self.state.get()["num_channels"]): - # Use pid_exists to confirm process is actually still running. Python may not report is_alive() correctly (especially over system sleeps etc.) + # Use pid_exists to confirm process is actually still running. + # Python may not report is_alive() correctly (especially over system sleeps etc.) # https://medium.com/pipedrive-engineering/encountering-some-python-trickery-683bd5f66750 if ( not self.player[channel] diff --git a/tests/test_player.py b/tests/test_player.py index 1767966..0667336 100644 --- a/tests/test_player.py +++ b/tests/test_player.py @@ -128,7 +128,7 @@ class TestPlayer(unittest.TestCase): source = response[: response.index(":")] if source in sources_filter: return response[ - len(source + ":" + msg) + 1 : + len(source + ":" + msg) + 1: ] # +1 to remove trailing : on source. except Empty: pass @@ -316,7 +316,8 @@ class TestPlayer(unittest.TestCase): self._send_msg_wait_OKAY("LOAD:2") # To test currently loaded marker sets. markers = [ - # Markers are stored as float, to compare against later, these must all be floats, despite int being supported. + # Markers are stored as float, to compare against later, + # these must all be floats, despite int being supported. getMarkerJSON("Intro Name", 2.0, "start", None), getMarkerJSON("Cue Name", 3.14, "mid", None), getMarkerJSON("Outro Name", 4.0, "end", None), @@ -358,7 +359,8 @@ class TestPlayer(unittest.TestCase): # In this case, we want to make sure both the current and loaded items are updated for item in [json_obj["show_plan"][2], json_obj["loaded_item"]]: self.assertEqual(item["weight"], 2) - # This is a loop marker. It should not appear as a standard intro, outro or cue. Default of 0.0 should apply to all. + # This is a loop marker. It should not appear as a standard intro, outro or cue. + # Default of 0.0 should apply to all. self.assertEqual(item["intro"], 0.0) self.assertEqual(item["outro"], 0.0) self.assertEqual(item["cue"], 0.0)