Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
4a78669
Start v1.6.1
markspolakovs Dec 30, 2023
10584c5
fix: startup failure when no show selected (#293)
alyxbb Dec 30, 2023
bb55f91
Merge pull request #295 from UniversityRadioYork/alyx-show-select-red…
alyxbb Dec 30, 2023
aa980bc
fixed wording when station off air. (#296)
alyxbb Jan 3, 2024
537e617
Merge pull request #297 from UniversityRadioYork/alyx-off-air
alyxbb Jan 3, 2024
72f363a
chore: update webpack and support building on node >=18
ashhhleyyy Mar 24, 2024
8b7f59c
Merge pull request #299 from UniversityRadioYork/ash-node-fix
ashhhleyyy Mar 29, 2024
226b367
Add button to open showplan from ID
ColinRoitt Oct 4, 2024
d9fe3c2
Merge pull request #300 from UniversityRadioYork/colin-enter-timeslot-id
ColinRoitt Oct 4, 2024
e519371
Use custom input text box
ColinRoitt Nov 20, 2024
3719c2f
Close select show popup when show is loaded
ColinRoitt Nov 20, 2024
ca52ec8
Click timeslot ID to copy to clipboard
ColinRoitt Nov 20, 2024
b04db3c
add cursor-pointer class
ColinRoitt Nov 20, 2024
ca4b8f6
Merge pull request #304 from UniversityRadioYork/colin-enter-timeslot-id
ColinRoitt Dec 2, 2024
9a831dc
chore: bump all dependencies
ashhhleyyy May 20, 2025
d7bfd80
Fix showplan repairing
markspolakovs Oct 4, 2025
46b056b
Bump actions/cache
markspolakovs Oct 4, 2025
1969fff
Stop Poetry complaining
markspolakovs Oct 4, 2025
b0e91a9
Attempt to satisfy mypy
markspolakovs Oct 4, 2025
35398d2
Merge pull request #305 from UniversityRadioYork/mp/fix-showplan-repair
mstratford Oct 4, 2025
3fa94e0
Fix ID in popup is null when trackId is present from baps but null.
mstratford Oct 5, 2025
d7e5738
Prettier
mstratford Oct 5, 2025
76a79e3
Merge pull request #308 from UniversityRadioYork/mstratford/baps-id-null
mstratford Oct 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"

- uses: actions/cache@v1
- uses: actions/cache@v4
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
Expand Down
14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "webstudio",
"version": "1.6.0",
"version": "1.6.1",
"private": true,
"dependencies": {
"@babel/core": "7.6.0",
Expand Down Expand Up @@ -107,19 +107,19 @@
"typescript": "3.7.2",
"url-loader": "2.1.0",
"wavesurfer.js": "4.1.1",
"webpack": "4.41.0",
"webpack": "4.47.0",
"webpack-dev-server": "3.2.1",
"webpack-manifest-plugin": "2.1.1",
"workbox-webpack-plugin": "^5.1.2",
"worklet-loader": "^1.0.0"
},
"homepage": "./",
"scripts": {
"start": "node scripts/start.js",
"start-baps": "node scripts/start.js baps",
"build": "node scripts/build.js",
"build-baps": "node scripts/build.js baps",
"test": "node scripts/test.js"
"start": "node --openssl-legacy-provider scripts/start.js",
"start-baps": "node --openssl-legacy-provider scripts/start.js baps",
"build": "node --openssl-legacy-provider scripts/build.js",
"build-baps": "node --openssl-legacy-provider scripts/build.js baps",
"test": "node --openssl-legacy-provider scripts/test.js"
},
"eslintConfig": {
"extends": "react-app"
Expand Down
2,655 changes: 1,403 additions & 1,252 deletions poetry.lock

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ version = "1.6.0"
description = ""
authors = ["Marks Polakovs <marks.polakovs@ury.org.uk>", "Matthew Stratford <matthew.stratford@ury.org.uk>"]
readme = "README.md"
package-mode = false

[tool.poetry.dependencies]
python = "^3.7"
aiohttp = "^3.8.4"
av = "^10.0.0"
python = "^3.9.2"
aiohttp = "^3.11.18"
av = "^14.0.0"
jack-client = "^0.5.4"
websockets = "^10.4"
aiortc = "^1.4.0"
websockets = "^15.0"
aiortc = "^1.12.0"
sentry-sdk = "^1.16.0"
requests = "^2.28.2"
flask = "^2.2.3"
Expand Down
24 changes: 12 additions & 12 deletions shittyserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@
from typing import Optional, Any, Type, Dict, List

import aiohttp
import av # type: ignore
import av
import jack as Jack
from jack import OwnPort
import websockets.exceptions, websockets.server, websockets.connection
from aiortc import MediaStreamTrack, RTCPeerConnection, RTCSessionDescription # type: ignore
from aiortc.mediastreams import MediaStreamError # type: ignore
from aiortc import MediaStreamTrack, RTCPeerConnection, RTCSessionDescription
from aiortc.mediastreams import MediaStreamError
import sentry_sdk

config = configparser.RawConfigParser()
Expand Down Expand Up @@ -131,7 +131,7 @@ class NotReadyException(BaseException):


class Session(object):
websocket: Optional[websockets.server.WebSocketServerProtocol]
websocket: Optional[websockets.server.WebSocketServerProtocol] # type: ignore
connection_state: Optional[str]
pc: Optional[Any]
connection_id: str
Expand Down Expand Up @@ -194,7 +194,7 @@ async def end(self) -> None:

if (
self.websocket is not None
and self.websocket.state == websockets.connection.State.OPEN
and self.websocket.state == websockets.connection.State.OPEN # type: ignore
):
try:
await self.websocket.send(json.dumps({"kind": "DIED"}))
Expand Down Expand Up @@ -225,15 +225,15 @@ def create_peerconnection(self) -> None:
self.pc = RTCPeerConnection()
assert self.pc is not None

@self.pc.on("signalingstatechange") # type: ignore
@self.pc.on("signalingstatechange")
async def on_signalingstatechange() -> None:
assert self.pc is not None
print(
self.connection_id,
"Signaling state is {}".format(self.pc.signalingState),
)

@self.pc.on("iceconnectionstatechange") # type: ignore
@self.pc.on("iceconnectionstatechange")
async def on_iceconnectionstatechange() -> None:
if self.pc is None:
print(
Expand All @@ -249,7 +249,7 @@ async def on_iceconnectionstatechange() -> None:
print(self.connection_id, "Ending due to ICE connection failure")
await self.end()

@self.pc.on("track") # type: ignore
@self.pc.on("track")
async def on_track(track: MediaStreamTrack) -> None:
global live_session, transfer_buffer1, transfer_buffer2
print(self.connection_id, "Received track")
Expand All @@ -258,7 +258,7 @@ async def on_track(track: MediaStreamTrack) -> None:

await notify_mattserver_about_sessions()

@track.on("ended") # type: ignore
@track.on("ended")
async def on_ended() -> None:
print(
self.connection_id,
Expand Down Expand Up @@ -325,7 +325,7 @@ async def process_ice(self, message: Any) -> None:
)

async def connect(
self, websocket: websockets.server.WebSocketServerProtocol
self, websocket: websockets.server.WebSocketServerProtocol # type: ignore
) -> None:
global active_sessions

Expand Down Expand Up @@ -369,7 +369,7 @@ async def connect(


async def serve(
websocket: websockets.server.WebSocketServerProtocol, path: str
websocket: websockets.server.WebSocketServerProtocol, path: str # type: ignore
) -> None:
if path == "/stream":
session = Session()
Expand All @@ -378,7 +378,7 @@ async def serve(
pass


start_server = websockets.server.serve(
start_server = websockets.server.serve( # type: ignore
serve, host=None, port=int(config.get("shittyserver", "websocket_port"))
)

Expand Down
4 changes: 4 additions & 0 deletions src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,7 @@ button {
.ReactModal__Overlay {
z-index: 10000;
}

.cursor-pointer {
cursor: pointer;
}
9 changes: 8 additions & 1 deletion src/navbar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,14 @@ export function NavBarMyRadio() {
<h6 className="dropdown-header">
{sessionState.currentTimeslot?.title}
</h6>
<h6 className="dropdown-header">
<h6
className="dropdown-header cursor-pointer"
onClick={() => {
navigator.clipboard.writeText(
sessionState.currentTimeslot?.timeslot_id.toString() || ""
);
}}
>
ID: {sessionState.currentTimeslot?.timeslot_id}
</h6>
</div>
Expand Down
37 changes: 37 additions & 0 deletions src/navbar/loadshow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
FaCircleNotch,
FaCog,
FaDownload,
FaKeyboard,
FaSearch,
FaTimesCircle,
FaTrashAlt,
Expand All @@ -15,9 +16,16 @@ type searchingStateEnum = "searching" | "results" | "no-results" | "error";

export function LoadShowDialogue({ close }: { close: () => any }) {
const [items, setItems] = useState<Timeslot[]>([]);
const [customTimeslotID, _setCustomTimeslotID] = useState("");
const [isInvalidShowId, setIsInvalidShowId] = useState(false);

const [state, setState] = useState<searchingStateEnum>("searching");

const setCustomTimeslotID = (value: string) => {
_setCustomTimeslotID(value);
setIsInvalidShowId(false);
};

useEffect(() => {
getTimeslots().then((timeslots) => {
if (!timeslots) {
Expand Down Expand Up @@ -59,6 +67,34 @@ export function LoadShowDialogue({ close }: { close: () => any }) {
>
<FaCircleNotch size={15} /> Mark All Unplayed
</div>
<div
className="btn btn-outline-dark outline float-right mr-4"
onClick={() => {
// check input is a number
if (isNaN(parseInt(customTimeslotID))) {
console.log("Invalid show ID provided; not loaded");
setIsInvalidShowId(true);
} else {
sendBAPSicleChannel({
command: "GETPLAN",
timeslotId: customTimeslotID,
});
close();
}
}}
>
<FaKeyboard size={15} /> Load Show ID
</div>
<input
className={
"form-control form-control-sm outline float-right mr-1 mt-1 w-25 p-1" +
(isInvalidShowId ? " is-invalid" : "")
}
type="text"
placeholder="Enter Show ID..."
value={customTimeslotID}
onChange={(e) => setCustomTimeslotID(e.target.value)}
/>

<h2>Load Show</h2>
<ResultsPlaceholder state={state} />
Expand All @@ -74,6 +110,7 @@ export function LoadShowDialogue({ close }: { close: () => any }) {
command: "GETPLAN",
timeslotId: item.timeslot_id,
});
close();
}}
>
<FaDownload size={15} /> Load Show Plan
Expand Down
5 changes: 2 additions & 3 deletions src/navbar/timelord.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ export function Timelord() {
if (process.env.REACT_APP_BAPSICLE_INTERFACE)
return { id: -1, name: "Unknown" };
let studio = await myradioApiRequest("/selector/studioattime", "GET", null);

const sourceNames = [
"Studio Red",
"Studio Blue",
Expand All @@ -23,7 +22,7 @@ export function Timelord() {
"WebStudio",
"Unknown",
"Sine Wave",
"Off Air",
"Station is Off Air",
];

let sourceName = "Unknown";
Expand Down Expand Up @@ -94,7 +93,7 @@ export function Timelord() {
source.id > -1 && (
<span className="source">
<span className={"studio studio" + source.id}>{source.name}</span>
&nbsp;is On Air
{source.id !== 8 ? " is On Air" : ""}
</span>
)
)}
Expand Down
3 changes: 1 addition & 2 deletions src/session/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ const SessionHandler: React.FC = function() {
error={userLoadError}
percent={71}
/>
{currentTimeslot === null &&
timeslotLoadError == null &&
{timeslotLoadError !== null &&
timeslotLoadError !== undefined &&
!timeslotLoading &&
redirectToTimeslotSelect()}
Expand Down
7 changes: 6 additions & 1 deletion src/showplanner/Item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,12 @@ export const Item = memo(function Item({
);
}
data.push(
"ID: " + ("trackid" in x ? x.trackid : "managedid" in x && x.managedid)
"ID: " +
("trackid" in x && x.trackid
? x.trackid
: "managedid" in x && x.managedid
? x.managedid
: "None")
);
if (showDebug) {
data.push(
Expand Down
4 changes: 1 addition & 3 deletions src/showplanner/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -668,9 +668,6 @@ export const getShowplan = (timeslotId: number): AppThunk => async (
}

if (ops.length > 0) {
console.log("Is corrupt, repairing locally");
dispatch(showplan.actions.applyOps(ops));

console.log("Repairing showplan", ops);
const updateResult = await api.updateShowplan(timeslotId, ops);
if (!updateResult.every((x) => x.status)) {
Expand All @@ -679,6 +676,7 @@ export const getShowplan = (timeslotId: number): AppThunk => async (
return;
}
}
// This is the fixed plan
dispatch(showplan.actions.getShowplanSuccess(plan.flat(2)));
} catch (e) {
console.error(e);
Expand Down
Loading
Loading