Compare commits

18 Commits

Author SHA1 Message Date
Logan Cusano
925243b53c Merge remote-tracking branch 'origin/master' into fix-disconnection-bug
Some checks failed
Lint / lint (pull_request) Failing after 43s
2025-02-23 20:35:56 -05:00
Logan Cusano
acb72eff03 Reset build step and disabled for now
All checks were successful
Lint / lint (push) Successful in 19s
2025-02-23 20:33:36 -05:00
Logan Cusano
d41ed60ee6 Update dockerfile to speed up debugging
Some checks failed
release-tag / release-image (push) Failing after 1m42s
Lint / lint (push) Successful in 39s
2025-02-23 17:42:26 -05:00
Logan Cusano
3ded857456 testing just arm64 build
Some checks failed
release-tag / release-image (push) Failing after 18m48s
Lint / lint (push) Failing after 14s
2025-02-23 16:36:30 -05:00
Logan Cusano
78432c07a0 Remove arm64 for testing
All checks were successful
Lint / lint (push) Successful in 6s
release-tag / release-image (push) Successful in 12m0s
2025-02-23 16:06:11 -05:00
Logan Cusano
f20b6cc0ed Add validation and remove armv7 (for testing)(
Some checks failed
Lint / lint (push) Successful in 10s
release-tag / release-image (push) Failing after 19m41s
2025-02-23 15:27:38 -05:00
Logan Cusano
c872a27017 Update build workfloow
Some checks failed
release-tag / release-image (push) Failing after 21m8s
Lint / lint (push) Successful in 31s
2025-02-23 13:47:36 -05:00
Logan Cusano
af6c9fb763 Undo version bump
Some checks failed
release-tag / release-image (push) Failing after 19m22s
Lint / lint (push) Failing after 39s
2025-02-23 12:24:45 -05:00
Logan Cusano
3dbbdaeec2 Update dockerfile
Some checks failed
Lint / lint (push) Successful in 29s
release-tag / release-image (push) Failing after 54s
- Bump ubuntu version
- Switch to apt from apt-get
- Add extra install for apt-transport-https
2025-02-23 12:20:06 -05:00
55ee80ce22 Merge pull request 'Correctly implement actions' (#3) from implement-actions into master
Some checks failed
Lint / lint (push) Successful in 12s
release-tag / release-image (push) Failing after 19m3s
Reviewed-on: #3
2025-02-23 11:31:30 -05:00
8f0df2e3e1 Linting
All checks were successful
Lint / lint (pull_request) Successful in 1m15s
2025-02-22 22:51:01 -05:00
1de9e9ce1d remove test for another time
Some checks failed
Lint / lint (pull_request) Failing after 22s
2025-02-22 22:43:07 -05:00
3c99d05708 Bumb versions in linting
Some checks failed
Lint / lint (pull_request) Failing after 2m1s
Test / test (pull_request) Failing after 29s
2025-02-22 22:40:19 -05:00
57e93eaa81 Fix actions
Some checks failed
Test / test (pull_request) Failing after 56s
Lint / lint (pull_request) Failing after 47s
- Fix branch names
- Update PRs to run on any branch
2025-02-22 22:31:39 -05:00
597c73f45e Update yaml on something that will run on PR 2025-02-22 22:26:17 -05:00
7c9b9ba446 Use 'yaml' instead of 'yml' 2025-02-22 22:25:34 -05:00
d753f8aebb Merge remote-tracking branch 'origin/master' into implement-actions 2025-02-22 22:23:33 -05:00
f14fe1f789 Move the action configs to correct dir 2025-02-22 22:22:58 -05:00
9 changed files with 44 additions and 69 deletions

View File

@@ -3,7 +3,7 @@ name: release-tag
on: on:
push: push:
branches: branches:
- main - master
jobs: jobs:
release-image: release-image:
@@ -11,9 +11,8 @@ jobs:
container: container:
image: catthehacker/ubuntu:act-latest image: catthehacker/ubuntu:act-latest
env: env:
DOCKER_ORG: teacup
DOCKER_LATEST: nightly DOCKER_LATEST: nightly
RUNNER_TOOL_CACHE: /toolcache CONTAINER_NAME: drb-client-discord-bot
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -42,15 +41,19 @@ jobs:
echo REPO_NAME=$(echo ${GITHUB_REPOSITORY} | awk -F"/" '{print $2}') >> $GITHUB_OUTPUT echo REPO_NAME=$(echo ${GITHUB_REPOSITORY} | awk -F"/" '{print $2}') >> $GITHUB_OUTPUT
echo REPO_VERSION=$(git describe --tags --always | sed 's/^v//') >> $GITHUB_OUTPUT echo REPO_VERSION=$(git describe --tags --always | sed 's/^v//') >> $GITHUB_OUTPUT
- name: Validate build configuration
uses: docker/build-push-action@v6
with:
call: check
- name: Build and push - name: Build and push
uses: docker/build-push-action@v4 uses: docker/build-push-action@v6
with: with:
context: . context: .
file: ./Dockerfile file: ./Dockerfile
platforms: | platforms: |
linux/amd64 linux/amd64
linux/arm64
push: true push: true
tags: | # replace it with your local IP and tags tags: | # replace it with your local IP and tags
git.vpn.cusano.net/${{ vars.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ steps.meta.outputs.REPO_VERSION }} git.vpn.cusano.net/${{ vars.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}/${{ env.CONTAINER_NAME }}:${{ steps.meta.outputs.REPO_VERSION }}
git.vpn.cusano.net/${{ vars.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}:${{ env.DOCKER_LATEST }} git.vpn.cusano.net/${{ vars.DOCKER_ORG }}/${{ steps.meta.outputs.REPO_NAME }}/${{ env.CONTAINER_NAME }}:${{ env.DOCKER_LATEST }}

View File

@@ -3,22 +3,22 @@ name: Lint
on: on:
push: push:
branches: branches:
- main - master
pull_request: pull_request:
branches: branches:
- main - "*"
jobs: jobs:
lint: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v4
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v2 uses: actions/setup-python@v5
with: with:
python-version: 3.x python-version: '3.13'
- name: Install dependencies - name: Install dependencies
run: | run: |

View File

@@ -1,30 +0,0 @@
name: Test
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.x
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pytest
- name: Run tests
run: |
pytest

View File

@@ -5,8 +5,9 @@ FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive ENV DEBIAN_FRONTEND=noninteractive
# Install system dependencies # Install system dependencies
RUN apt-get update && \ RUN apt update && \
apt-get install -y git \ apt-get install -y --no-install-recommends libc-bin apt-transport-https && \
apt install -y --no-install-recommends git \
curl \ curl \
python3 \ python3 \
python3-pip \ python3-pip \

View File

@@ -30,15 +30,15 @@ class AudioStream:
if _input: if _input:
self.paInstance_kwargs['input_device_index'] = _input_device_index self.paInstance_kwargs['input_device_index'] = _input_device_index
else: else:
LOGGER.warning(f"[AudioStream.__init__]:\tInput was not enabled." LOGGER.warning("[AudioStream.__init__]:\tInput was not enabled."
f" Reinitialize with '_input=True'") " Reinitialize with '_input=True'")
if _output_device_index: if _output_device_index:
if _output: if _output:
self.paInstance_kwargs['output_device_index'] = _output_device_index self.paInstance_kwargs['output_device_index'] = _output_device_index
else: else:
LOGGER.warning(f"[AudioStream.__init__]:\tOutput was not enabled." LOGGER.warning("[AudioStream.__init__]:\tOutput was not enabled."
f" Reinitialize with '_output=True'") " Reinitialize with '_output=True'")
if _init_on_startup: if _init_on_startup:
# Init PyAudio instance # Init PyAudio instance
@@ -59,15 +59,15 @@ class AudioStream:
if self.paInstance_kwargs['input']: if self.paInstance_kwargs['input']:
self.paInstance_kwargs['input_device_index'] = _new_input_device_index self.paInstance_kwargs['input_device_index'] = _new_input_device_index
else: else:
LOGGER.warning(f"[AudioStream.init_stream]:\tInput was not enabled when initialized." LOGGER.warning("[AudioStream.init_stream]:\tInput was not enabled when initialized."
f" Reinitialize with '_input=True'") " Reinitialize with '_input=True'")
if _new_output_device_index: if _new_output_device_index:
if self.paInstance_kwargs['output']: if self.paInstance_kwargs['output']:
self.paInstance_kwargs['output_device_index'] = _new_output_device_index self.paInstance_kwargs['output_device_index'] = _new_output_device_index
else: else:
LOGGER.warning(f"[AudioStream.init_stream]:\tOutput was not enabled when initialized." LOGGER.warning("[AudioStream.init_stream]:\tOutput was not enabled when initialized."
f" Reinitialize with '_output=True'") " Reinitialize with '_output=True'")
self.close_if_open() self.close_if_open()
@@ -80,7 +80,7 @@ class AudioStream:
if self.stream.is_active(): if self.stream.is_active():
self.stream.stop_stream() self.stream.stop_stream()
self.stream.close() self.stream.close()
LOGGER.debug(f"[ReopenStream.close_if_open]:\t Stream was open; It was closed.") LOGGER.debug("[ReopenStream.close_if_open]:\t Stream was open; It was closed.")
def list_devices(self, _display_input_devices: bool = True, _display_output_devices: bool = True): def list_devices(self, _display_input_devices: bool = True, _display_output_devices: bool = True):
LOGGER.info('Getting a list of the devices connected') LOGGER.info('Getting a list of the devices connected')
@@ -126,7 +126,7 @@ class NoiseGate(AudioStream):
def run(self) -> None: def run(self) -> None:
global voice_connection global voice_connection
# Start the audio stream # Start the audio stream
LOGGER.debug(f"Starting stream") LOGGER.debug("Starting stream")
self.stream.start_stream() self.stream.start_stream()
# Start the stream to discord # Start the stream to discord
self.core() self.core()
@@ -139,15 +139,15 @@ class NoiseGate(AudioStream):
time.sleep(.2) time.sleep(.2)
if not voice_connection.is_playing(): if not voice_connection.is_playing():
LOGGER.debug(f"Playing stream to discord") LOGGER.debug("Playing stream to discord")
voice_connection.play(self.NGStream, after=self.core) voice_connection.play(self.NGStream, after=self.core)
async def close(self): async def close(self):
LOGGER.debug(f"Closing") LOGGER.debug("Closing")
await voice_connection.disconnect() await voice_connection.disconnect()
if self.stream.is_active: if self.stream.is_active:
self.stream.stop_stream() self.stream.stop_stream()
LOGGER.debug(f"Stopping stream") LOGGER.debug("Stopping stream")
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
@@ -155,7 +155,7 @@ class NoiseGateStream(discord.AudioSource):
def __init__(self, _stream): def __init__(self, _stream):
super(NoiseGateStream, self).__init__() super(NoiseGateStream, self).__init__()
self.stream = _stream # The actual audio stream object self.stream = _stream # The actual audio stream object
self.NG_fadeout = 240/20 # Fadeout value used to hold the noisegate after de-triggering self.NG_fadeout = 240 / 20 # Fadeout value used to hold the noisegate after de-triggering
self.NG_fadeout_count = 0 # A count set when the noisegate is triggered and was de-triggered self.NG_fadeout_count = 0 # A count set when the noisegate is triggered and was de-triggered
self.process_set_count = 0 # Counts how many processes have been made self.process_set_count = 0 # Counts how many processes have been made

View File

@@ -116,6 +116,7 @@ class DiscordBotManager:
del self.voice_clients[guild_id] del self.voice_clients[guild_id]
LOGGER.info(f"Left guild {guild_id} voice channel.") LOGGER.info(f"Left guild {guild_id} voice channel.")
# Initialize Discord Bot Manager
bot_manager = DiscordBotManager() bot_manager = DiscordBotManager()
# API Endpoints # API Endpoints
@@ -164,4 +165,4 @@ async def get_status():
return status return status
app.include_router(op25_controller.router, prefix="/op25") app.include_router(op25_controller.router, prefix="/op25")
app.include_router(pulse.router, prefix="/pulse") app.include_router(pulse.router, prefix="/pulse")

View File

@@ -8,4 +8,4 @@ for inputDevice in list_of_devices['Input']:
print("----- OUTPUT DEVICES -----") print("----- OUTPUT DEVICES -----")
for outputDevice in list_of_devices['Output']: for outputDevice in list_of_devices['Output']:
print(f"{outputDevice}\t-\t{list_of_devices['Output'][outputDevice]}") print(f"{outputDevice}\t-\t{list_of_devices['Output'][outputDevice]}")

View File

@@ -1,4 +1,4 @@
from fastapi import FastAPI, HTTPException, APIRouter from fastapi import HTTPException, APIRouter
from pydantic import BaseModel from pydantic import BaseModel
from enum import Enum from enum import Enum
import subprocess import subprocess
@@ -6,7 +6,7 @@ import os
import signal import signal
import json import json
import csv import csv
from typing import List, Optional, Union from typing import List, Optional
router = APIRouter() router = APIRouter()
@@ -87,7 +87,7 @@ class ChannelConfig(BaseModel):
symbol_rate: Optional[int] = 4800 symbol_rate: Optional[int] = 4800
blacklist: Optional[str] = "" blacklist: Optional[str] = ""
whitelist: Optional[str] = "" whitelist: Optional[str] = ""
class DeviceConfig(BaseModel): class DeviceConfig(BaseModel):
args: Optional[str] = "rtl" args: Optional[str] = "rtl"
gains: Optional[str] = "lna:39" gains: Optional[str] = "lna:39"
@@ -170,7 +170,7 @@ async def generate_config(generator: ConfigGenerator):
"audio": audio.dict(), "audio": audio.dict(),
"terminal": terminal.dict() "terminal": terminal.dict()
} }
elif generator.type == DecodeMode.ANALOG: elif generator.type == DecodeMode.ANALOG:
generator = generator.config generator = generator.config
channels = [ChannelConfig( channels = [ChannelConfig(
@@ -190,11 +190,11 @@ async def generate_config(generator: ConfigGenerator):
else: else:
raise HTTPException(status_code=400, detail="Invalid configuration type. Must be 'p25' or 'nbfm'.") raise HTTPException(status_code=400, detail="Invalid configuration type. Must be 'p25' or 'nbfm'.")
with open('/configs/active.cfg.json', 'w') as f: with open('/configs/active.cfg.json', 'w') as f:
json.dump(del_none_in_dict(config_dict), f, indent=2) json.dump(del_none_in_dict(config_dict), f, indent=2)
return {"message": f"Config exported to '/configs/active.cfg.json'"} return {"message": "Config exported to '/configs/active.cfg.json'"}
except Exception as e: except Exception as e:
raise HTTPException(status_code=500, detail=str(e)) raise HTTPException(status_code=500, detail=str(e))
@@ -222,7 +222,7 @@ def save_whitelist(talkgroup_tags: List[int]) -> None:
writer = csv.writer(file, delimiter='\t', lineterminator='\n') writer = csv.writer(file, delimiter='\t', lineterminator='\n')
# Write rows # Write rows
for tag in talkgroup_tags: for tag in talkgroup_tags:
writer.writerow([tag]) writer.writerow([tag])
def del_none_in_dict(d): def del_none_in_dict(d):
""" """
@@ -239,4 +239,4 @@ def del_none_in_dict(d):
elif isinstance(value, list): elif isinstance(value, list):
for iterative_value in value: for iterative_value in value:
del_none_in_dict(iterative_value) del_none_in_dict(iterative_value)
return d # For convenience return d # For convenience

View File

@@ -11,4 +11,4 @@ async def get_status():
return {"status": "running" if pulse_process else "stopped"} return {"status": "running" if pulse_process else "stopped"}
# subprocess.Popen(os.path.join(OP25_PATH, OP25_SCRIPT), shell=True, preexec_fn=os.setsid, cwd=OP25_PATH) # subprocess.Popen(os.path.join(OP25_PATH, OP25_SCRIPT), shell=True, preexec_fn=os.setsid, cwd=OP25_PATH)