Compare commits
28 commits
6d7c3aab2f
...
505a632200
Author | SHA1 | Date | |
---|---|---|---|
505a632200 | |||
a10c33a25c | |||
99933083e7 | |||
16a5a94fa0 | |||
f04e1ad8a9 | |||
5e489a6408 | |||
7a2145353d | |||
00c3cf9322 | |||
046fd3e86a | |||
c2795b84bb | |||
45a3568a9b | |||
1e26fc8838 | |||
ee93a45208 | |||
7018f91396 | |||
54097583b3 | |||
0e13dc08da | |||
237f21a5bc | |||
058e5299da | |||
3cd70699e0 | |||
4fcd72a2b1 | |||
ab2aead17e | |||
|
9e2eefa6fc | ||
|
6e921f6c9b | ||
|
570077a3aa | ||
|
3f1e73930d | ||
|
f44d22aad3 | ||
|
2fdc9bf0e9 | ||
|
7d2757a67d |
23 changed files with 5160 additions and 129 deletions
88
.github/workflows/build.yaml
vendored
88
.github/workflows/build.yaml
vendored
|
@ -2,42 +2,42 @@ name: Package
|
|||
on: [push]
|
||||
|
||||
jobs:
|
||||
build-macos:
|
||||
# build-macos:
|
||||
|
||||
runs-on: macos-latest
|
||||
timeout-minutes: 15
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ['3.9']
|
||||
node-version: ['14']
|
||||
# runs-on: macos-latest
|
||||
# timeout-minutes: 15
|
||||
# strategy:
|
||||
# fail-fast: false
|
||||
# matrix:
|
||||
# python-version: ['3.9', '3.11']
|
||||
# node-version: ['20']
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Node ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Build .app
|
||||
run: |
|
||||
npm run presenter-make
|
||||
build/build-macos.sh
|
||||
zip -r build/output/BAPSicle.zip build/output/BAPSicle.app
|
||||
- name: Extract branch name
|
||||
shell: bash
|
||||
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF##*/})"
|
||||
id: extract_branch
|
||||
- name: Archive Build
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: BAPSicle-${{ steps.extract_branch.outputs.branch }}-${{github.sha}}-MacOS
|
||||
path: |
|
||||
build/output/BAPSicle.zip
|
||||
# steps:
|
||||
# - uses: actions/checkout@v2
|
||||
# - name: Set up Python ${{ matrix.python-version }}
|
||||
# uses: actions/setup-python@v2
|
||||
# with:
|
||||
# python-version: ${{ matrix.python-version }}
|
||||
# - uses: actions/checkout@v2
|
||||
# - name: Set up Node ${{ matrix.node-version }}
|
||||
# uses: actions/setup-node@v2
|
||||
# with:
|
||||
# node-version: ${{ matrix.node-version }}
|
||||
# - name: Build .app
|
||||
# run: |
|
||||
# npm run presenter-make
|
||||
# build/build-macos.sh
|
||||
# zip -r build/output/BAPSicle.zip build/output/BAPSicle.app
|
||||
# - name: Extract branch name
|
||||
# shell: bash
|
||||
# run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF##*/})"
|
||||
# id: extract_branch
|
||||
# - name: Archive Build
|
||||
# uses: actions/upload-artifact@v2
|
||||
# with:
|
||||
# name: BAPSicle-${{ steps.extract_branch.outputs.branch }}-${{github.sha}}-MacOS
|
||||
# path: |
|
||||
# build/output/BAPSicle.zip
|
||||
|
||||
build-ubuntu:
|
||||
|
||||
|
@ -46,8 +46,8 @@ jobs:
|
|||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ['3.8','3.9']
|
||||
node-version: ['14']
|
||||
python-version: ['3.8','3.9', '3.11']
|
||||
node-version: ['20']
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
@ -55,6 +55,8 @@ jobs:
|
|||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Setup poetry
|
||||
uses: Gr1N/setup-poetry@v8
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Node ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2
|
||||
|
@ -69,9 +71,9 @@ jobs:
|
|||
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF##*/})"
|
||||
id: extract_branch
|
||||
- name: Archive Build
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: BAPSicle-${{ steps.extract_branch.outputs.branch }}-${{github.sha}}-Ubuntu
|
||||
name: BAPSicle-${{ steps.extract_branch.outputs.branch }}-${{github.sha}}-Ubuntu-python${{matrix.python-version}}-node${{matrix.node-version}}
|
||||
path: |
|
||||
build/output/BAPSicle
|
||||
|
||||
|
@ -82,8 +84,8 @@ jobs:
|
|||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: ['3.9']
|
||||
node-version: ['14']
|
||||
python-version: ['3.9', '3.11']
|
||||
node-version: ['20']
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
@ -91,6 +93,8 @@ jobs:
|
|||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Setup poetry
|
||||
uses: Gr1N/setup-poetry@v8
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up Node ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v2
|
||||
|
@ -105,9 +109,9 @@ jobs:
|
|||
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF##*/})"
|
||||
id: extract_branch
|
||||
- name: Archive Build
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: BAPSicle-${{ steps.extract_branch.outputs.branch }}-${{github.sha}}-Windows
|
||||
name: BAPSicle-${{ steps.extract_branch.outputs.branch }}-${{github.sha}}-Windows-python${{matrix.python-version}}-node${{matrix.node-version}}
|
||||
path: |
|
||||
build/output/BAPSicle.exe
|
||||
install/
|
||||
|
|
23
.github/workflows/test.yaml
vendored
23
.github/workflows/test.yaml
vendored
|
@ -10,7 +10,7 @@ jobs:
|
|||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: [3.8, 3.9]
|
||||
python-version: [3.8, 3.9, 3.11]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
@ -18,30 +18,25 @@ jobs:
|
|||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Setup poetry
|
||||
uses: Gr1N/setup-poetry@v8
|
||||
- name: Install Python dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r build/requirements-dev.txt
|
||||
pip install -r build/requirements.txt
|
||||
pip install -r build/requirements-macos.txt
|
||||
- name: Install bapsicle as module
|
||||
run: |
|
||||
pip install -e .
|
||||
run: poetry install --with=dev
|
||||
- name: Lint with flake8
|
||||
run: |
|
||||
# stop the build if there are Python syntax errors or undefined names
|
||||
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
|
||||
poetry run flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
|
||||
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
|
||||
flake8 . --count --ignore=E402,E226,E24,W50,W690 --max-complexity=25 --max-line-length=127 --statistics
|
||||
poetry run flake8 . --count --ignore=E402,E226,E24,W50,W690 --max-complexity=25 --max-line-length=127 --statistics
|
||||
- name: Test with unittest
|
||||
if: ${{ always() }}
|
||||
timeout-minutes: 10
|
||||
run: |
|
||||
python -m sounddevice
|
||||
python -m unittest
|
||||
poetry run python -m sounddevice
|
||||
poetry run python -m unittest
|
||||
- name: Archive test logs
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Logs - Python ${{ matrix.python-version }}
|
||||
path: |
|
||||
|
|
|
@ -38,7 +38,7 @@ Starting and stopping the server, as well as UI links, are available in the Syst
|
|||
|
||||
On all platforms:
|
||||
|
||||
- Python 3.8 - 3.9 Tested
|
||||
- Python 3.8 - 3.11 Tested
|
||||
- Git (Obviously)
|
||||
|
||||
On MacOS:
|
||||
|
|
|
@ -88,6 +88,10 @@
|
|||
{
|
||||
"optionDest": "collect-all",
|
||||
"value": "setproctitle"
|
||||
},
|
||||
{
|
||||
"optionDest": "collect-all",
|
||||
"value": "tracerite"
|
||||
}
|
||||
],
|
||||
"nonPyinstallerOptions": {
|
||||
|
|
|
@ -6,9 +6,9 @@ config = json.loads(file.read())
|
|||
file.close()
|
||||
|
||||
if isLinux():
|
||||
cmd_str = "python3 -m PyInstaller "
|
||||
cmd_str = "poetry run python3 -m PyInstaller "
|
||||
else:
|
||||
cmd_str = "pyinstaller "
|
||||
cmd_str = "poetry run pyinstaller "
|
||||
|
||||
json_dests = ["icon_file", "clean_build"]
|
||||
pyi_dests = ["icon", "clean"]
|
||||
|
|
|
@ -11,19 +11,13 @@ echo "BRANCH: str = \"$build_branch\"" >> ../build.py
|
|||
sudo apt install libportaudio2
|
||||
sudo apt install python3-pip python3-venv ffmpeg
|
||||
|
||||
python3 -m venv ../venv
|
||||
source ../venv/bin/activate
|
||||
poetry install
|
||||
|
||||
pip3 install wheel
|
||||
pip3 install -r requirements.txt
|
||||
pip3 install -r requirements-linux.txt
|
||||
pip3 install -e ../
|
||||
|
||||
python3 ./generate-build-exe-config.py
|
||||
poetry run python3 ./generate-build-exe-config.py
|
||||
|
||||
chmod +x output/BAPSicle
|
||||
|
||||
python3 ./build-exe.py
|
||||
poetry run python3 ./build-exe.py
|
||||
|
||||
bash ./build-exe-pyinstaller-command.sh
|
||||
|
||||
|
|
|
@ -8,24 +8,18 @@ build_branch="$(git branch --show-current)"
|
|||
echo "BUILD: str = \"$build_commit\"" > ../build.py
|
||||
echo "BRANCH: str = \"$build_branch\"" >> ../build.py
|
||||
|
||||
python3 -m venv ../venv
|
||||
source ../venv/bin/activate
|
||||
poetry install
|
||||
|
||||
pip3 install wheel
|
||||
pip3 install -r requirements.txt
|
||||
pip3 install -r requirements-macos.txt
|
||||
pip3 install -e ..\
|
||||
poetry run python3 ./generate-build-exe-config.py
|
||||
|
||||
python3 ./generate-build-exe-config.py
|
||||
|
||||
python3 ./build-exe.py
|
||||
poetry run python3 ./build-exe.py
|
||||
|
||||
bash ./build-exe-pyinstaller-command.sh
|
||||
|
||||
rm ./*.spec
|
||||
|
||||
cd ../
|
||||
python3 build/generate-platypus-config.py
|
||||
poetry run python3 build/generate-platypus-config.py
|
||||
cd build
|
||||
|
||||
brew install platypus
|
||||
|
|
|
@ -10,24 +10,14 @@ SET build_branch=%%F
|
|||
echo BUILD: str = "%build_commit%"> ..\build.py
|
||||
echo BRANCH: str = "%build_branch%">> ..\build.py
|
||||
|
||||
if "%1" == "no-venv" goto skip-venv
|
||||
|
||||
py -m venv ..\venv
|
||||
..\venv\Scripts\activate
|
||||
|
||||
:skip-venv
|
||||
|
||||
pip install wheel
|
||||
pip install -r requirements.txt
|
||||
pip install -r requirements-windows.txt
|
||||
pip install -e ..\
|
||||
poetry install
|
||||
|
||||
: Generate the json config in case you wanted to use the gui to regenerate the command below manually.
|
||||
python generate-build-exe-config.py
|
||||
poetry run python generate-build-exe-config.py
|
||||
|
||||
: auto-py-to-exe -c build-exe-config.json -o ../install
|
||||
|
||||
python build-exe.py
|
||||
poetry run python build-exe.py
|
||||
|
||||
build-exe-pyinstaller-command.bat
|
||||
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
wheel
|
||||
flake8
|
||||
black
|
||||
autopep8
|
|
@ -1 +0,0 @@
|
|||
pyinstaller
|
|
@ -1 +0,0 @@
|
|||
pyinstaller
|
|
@ -1,2 +0,0 @@
|
|||
pywin32
|
||||
auto-py-to-exe
|
|
@ -1,17 +0,0 @@
|
|||
wheel
|
||||
pygame==2.0.2
|
||||
sanic==21.9.3
|
||||
sanic-Cors==2.0.1
|
||||
syncer==1.3.0
|
||||
aiohttp==3.7.4
|
||||
mutagen==1.45.1
|
||||
sounddevice==0.4.2
|
||||
setproctitle==1.2.2
|
||||
pyttsx3==2.90
|
||||
websockets==10.1
|
||||
typing_extensions==3.10.0.0
|
||||
pyserial==3.5
|
||||
requests==2.26.0
|
||||
Jinja2==3.0.1
|
||||
pydub==0.25.1
|
||||
psutil
|
|
@ -1,5 +1,5 @@
|
|||
#!/bin/bash
|
||||
pip3 install autopep8
|
||||
poetry install
|
||||
cd "$(dirname "$0")"
|
||||
cp "./pre-commit" "../.git/hooks/"
|
||||
|
||||
|
|
|
@ -64,8 +64,7 @@ class DeviceManager:
|
|||
def getAudioDevices(cls) -> List[str]:
|
||||
mixer.init(44100, -16, 2, 1024)
|
||||
is_capture = 0 # zero to request playback devices, non-zero to request recording devices
|
||||
num = sdl2.get_num_audio_devices(is_capture)
|
||||
names = [str(sdl2.get_audio_device_name(i, is_capture), encoding="utf-8") for i in range(num)]
|
||||
names = sdl2.audio.get_audio_device_names(is_capture)
|
||||
mixer.quit()
|
||||
return names
|
||||
|
||||
|
|
24
package-lock.json
generated
24
package-lock.json
generated
|
@ -1,13 +1,29 @@
|
|||
{
|
||||
"name": "bapsicle",
|
||||
"version": "3.1.0",
|
||||
"lockfileVersion": 1,
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"yarn": {
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "bapsicle",
|
||||
"version": "3.1.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"yarn": "^1.22.15"
|
||||
}
|
||||
},
|
||||
"node_modules/yarn": {
|
||||
"version": "1.22.15",
|
||||
"resolved": "https://registry.npmjs.org/yarn/-/yarn-1.22.15.tgz",
|
||||
"integrity": "sha512-AzoEDxj256BOS/jqDXA3pjyhmi4FRBBUMgYoTHI4EIt2EhREkvH0soPVEtnD+DQIJfU5R9bKhcZ1H9l8zPWeoA=="
|
||||
"integrity": "sha512-AzoEDxj256BOS/jqDXA3pjyhmi4FRBBUMgYoTHI4EIt2EhREkvH0soPVEtnD+DQIJfU5R9bKhcZ1H9l8zPWeoA==",
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"yarn": "bin/yarn.js",
|
||||
"yarnpkg": "bin/yarn.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "bapsicle",
|
||||
"nice_name": "BAPSicle",
|
||||
"version": "3.1.0",
|
||||
"version": "3.1.1",
|
||||
"description": "BAPS3, the third generation of University Radio York's Broadcast and Presenting Suite. This package includes the Server (BAPSicle) and Presenter (WebStudio)",
|
||||
"main": "index.js",
|
||||
"directories": {
|
||||
|
|
152
player.py
152
player.py
|
@ -685,6 +685,158 @@ class Player:
|
|||
self.state.update("show_plan", [])
|
||||
return True
|
||||
|
||||
def load(self, weight: int):
|
||||
if not self.isPlaying:
|
||||
loaded_state = self.state.get()
|
||||
self.unload()
|
||||
|
||||
self.logger.log.info("Resetting output (in case of sound output gone silent somehow) to " + str(loaded_state["output"]))
|
||||
self.output(loaded_state["output"])
|
||||
|
||||
showplan = loaded_state["show_plan"]
|
||||
|
||||
loaded_item: Optional[PlanItem] = None
|
||||
|
||||
for i in range(len(showplan)):
|
||||
if showplan[i].weight == weight:
|
||||
loaded_item = showplan[i]
|
||||
break
|
||||
|
||||
if loaded_item is None:
|
||||
self.logger.log.error(
|
||||
"Failed to find weight: {}".format(weight))
|
||||
return False
|
||||
|
||||
reload = False
|
||||
if loaded_item.filename == "" or loaded_item.filename is None:
|
||||
self.logger.log.info(
|
||||
"Filename is not specified, loading from API.")
|
||||
reload = True
|
||||
elif not os.path.exists(loaded_item.filename):
|
||||
self.logger.log.warn(
|
||||
"Filename given doesn't exist. Re-loading from API."
|
||||
)
|
||||
reload = True
|
||||
|
||||
if reload:
|
||||
loaded_item.filename = sync(self.api.get_filename(item=loaded_item))
|
||||
|
||||
if not loaded_item.filename:
|
||||
return False
|
||||
|
||||
self.state.update("loaded_item", loaded_item)
|
||||
|
||||
for i in range(len(showplan)):
|
||||
if showplan[i].weight == weight:
|
||||
self.state.update("show_plan", index=i, value=loaded_item)
|
||||
break
|
||||
# TODO: Update the show plan filenames???
|
||||
|
||||
load_attempt = 0
|
||||
while load_attempt < 5:
|
||||
load_attempt += 1
|
||||
try:
|
||||
self.logger.log.info("Loading file: " +
|
||||
str(loaded_item.filename))
|
||||
mixer.music.load(loaded_item.filename)
|
||||
except Exception:
|
||||
# We couldn't load that file.
|
||||
self.logger.log.exception(
|
||||
"Couldn't load file: " + str(loaded_item.filename)
|
||||
)
|
||||
time.sleep(1)
|
||||
continue # Try loading again.
|
||||
|
||||
if not self.isLoaded:
|
||||
self.logger.log.error("Pygame loaded file without error, but never actually loaded.")
|
||||
time.sleep(1)
|
||||
continue # Try loading again.
|
||||
|
||||
try:
|
||||
if ".mp3" in loaded_item.filename:
|
||||
song = MP3(loaded_item.filename)
|
||||
self.state.update("length", song.info.length)
|
||||
else:
|
||||
self.state.update(
|
||||
"length", mixer.Sound(
|
||||
loaded_item.filename).get_length() / 1000
|
||||
)
|
||||
except Exception:
|
||||
self.logger.log.exception(
|
||||
"Failed to update the length of item.")
|
||||
time.sleep(1)
|
||||
continue # Try loading again.
|
||||
|
||||
# Everything worked, we made it!
|
||||
if loaded_item.cue > 0:
|
||||
self.seek(loaded_item.cue)
|
||||
else:
|
||||
self.seek(0)
|
||||
|
||||
if self.state.get()["play_on_load"]:
|
||||
self.unpause()
|
||||
|
||||
return True
|
||||
|
||||
self.logger.log.error("Failed to load track after numerous retries.")
|
||||
return False
|
||||
|
||||
return False
|
||||
|
||||
def unload(self):
|
||||
if not self.isPlaying:
|
||||
try:
|
||||
mixer.music.unload()
|
||||
self.state.update("paused", False)
|
||||
self.state.update("loaded_item", None)
|
||||
except Exception:
|
||||
self.logger.log.exception("Failed to unload channel.")
|
||||
return False
|
||||
|
||||
self._potentially_end_tracklist()
|
||||
# If we unloaded successfully, reset the tracklist_id, ready for the next item.
|
||||
if not self.isLoaded:
|
||||
self.state.update("tracklist_id", None)
|
||||
|
||||
return not self.isLoaded
|
||||
|
||||
def quit(self):
|
||||
try:
|
||||
mixer.quit()
|
||||
self.state.update("paused", False)
|
||||
self.logger.log.info("Quit mixer.")
|
||||
except Exception:
|
||||
self.logger.log.exception("Failed to quit mixer.")
|
||||
|
||||
def output(self, name: Optional[str] = None):
|
||||
wasPlaying = self.state.get()["playing"]
|
||||
oldPos = self.state.get()["pos_true"]
|
||||
|
||||
name = None if (not name or name.lower() == "none") else name
|
||||
|
||||
self.quit()
|
||||
self.state.update("output", name)
|
||||
try:
|
||||
if name:
|
||||
mixer.init(44100, -16, 2, 1024, devicename=name)
|
||||
else:
|
||||
mixer.init(44100, -16, 2, 1024)
|
||||
except Exception:
|
||||
self.logger.log.exception(
|
||||
"Failed to init mixer with device name: " + str(name)
|
||||
)
|
||||
return False
|
||||
|
||||
loadedItem = self.state.get()["loaded_item"]
|
||||
if loadedItem:
|
||||
self.logger.log.info("Reloading after output change.")
|
||||
self.load(loadedItem.weight)
|
||||
if wasPlaying:
|
||||
self.logger.log.info("Resuming playback after output change.")
|
||||
self.play(oldPos)
|
||||
|
||||
return True
|
||||
|
||||
# PlanItems can have markers. These are essentially bookmarked positions in the audio.
|
||||
# Timeslotitemid can be a ghost (un-submitted item), so may be "IXXX", hence str.
|
||||
def set_marker(self, timeslotitemid: str, marker_str: str):
|
||||
|
|
4863
poetry.lock
generated
Normal file
4863
poetry.lock
generated
Normal file
File diff suppressed because one or more lines are too long
|
@ -1 +1 @@
|
|||
Subproject commit 238da52d94f9a2e1f476e5c8e155e50dd8519cb7
|
||||
Subproject commit 8b7f59cdc6ed80b525b2dff665308d808a526d97
|
42
pyproject.toml
Normal file
42
pyproject.toml
Normal file
|
@ -0,0 +1,42 @@
|
|||
[tool.poetry]
|
||||
name = "bapsicle"
|
||||
version = "3.1.1"
|
||||
description = ""
|
||||
authors = ["University Radio York"]
|
||||
readme = "README.md"
|
||||
packages = [{include = "__init__.py"}]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.8.1,<3.13"
|
||||
wheel = "^0.43.0"
|
||||
pygame = "^2.5.2"
|
||||
sanic = "^23.12.1"
|
||||
sanic-cors = "^2.2.0"
|
||||
syncer = "^2.0.3"
|
||||
aiohttp = "^3.9.3"
|
||||
mutagen = "^1.47.0"
|
||||
sounddevice = "^0.4.6"
|
||||
setproctitle = "^1.3.3"
|
||||
pyttsx3 = "^2.90"
|
||||
websockets = "^12.0"
|
||||
typing-extensions = "^4.10.0"
|
||||
pyserial = "^3.5"
|
||||
requests = "^2.31.0"
|
||||
jinja2 = "^3.1.3"
|
||||
pydub = "^0.25.1"
|
||||
psutil = "^5.9.8"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
pyinstaller = [
|
||||
{version = "^6.5.0", platform = "linux"},
|
||||
{version = "^6.5.0", platform = "darwin"}
|
||||
]
|
||||
auto-py-to-exe = {version = "^2.43.3", platform = "win32"}
|
||||
pywin32 = {version = "^306", platform = "win32"}
|
||||
autopep8 = "^2.1.0"
|
||||
flake8 = "^7.0.0"
|
||||
black = "^24.3.0"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
|
@ -88,8 +88,10 @@ LOGGING_CONFIG = dict(
|
|||
},
|
||||
)
|
||||
|
||||
app = Sanic("BAPSicle-WebServer", log_config=LOGGING_CONFIG)
|
||||
# https://sanic.dev/en/guide/running/manager.html#overcoming-a-coderuntimeerrorcode
|
||||
Sanic.START_METHOD_SET = True
|
||||
|
||||
app = Sanic("BAPSicle-WebServer", log_config=LOGGING_CONFIG)
|
||||
|
||||
def render_template(file, data, status=200):
|
||||
template = env.get_template(file)
|
||||
|
@ -553,6 +555,7 @@ def WebServer(player_to: List[Queue], player_from: Queue, state: StateManager):
|
|||
host=server_state.get()["host"],
|
||||
port=server_state.get()["port"],
|
||||
auto_reload=False,
|
||||
single_process=True,
|
||||
debug=not package.BETA,
|
||||
access_log=not package.BETA,
|
||||
)
|
||||
|
|
|
@ -26,7 +26,7 @@ class WebsocketServer:
|
|||
logger: LoggingManager
|
||||
to_webstudio: Task
|
||||
from_webstudio: Task
|
||||
websocket_server: Serve
|
||||
websocket_server: serve
|
||||
|
||||
def __init__(self, in_q, out_q, state):
|
||||
|
||||
|
@ -92,7 +92,7 @@ class WebsocketServer:
|
|||
channel = int(data["channel"])
|
||||
self.sendCommand(channel, data)
|
||||
|
||||
await asyncio.wait([conn.send(message) for conn in self.baps_clients])
|
||||
await asyncio.wait([asyncio.Task(conn.send(message)) for conn in self.baps_clients])
|
||||
|
||||
except websockets.exceptions.ConnectionClosedError as e:
|
||||
self.logger.log.error(
|
||||
|
@ -244,7 +244,7 @@ class WebsocketServer:
|
|||
data = json.dumps(
|
||||
{"command": command, "data": message, "channel": channel}
|
||||
)
|
||||
await asyncio.wait([conn.send(data) for conn in self.baps_clients])
|
||||
await asyncio.wait([asyncio.Task(conn.send(data)) for conn in self.baps_clients])
|
||||
except queue.Empty:
|
||||
continue
|
||||
except ValueError:
|
||||
|
|
Loading…
Reference in a new issue