mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-09 18:44:16 +00:00
- Introduces a new Music Library system for managing favorites (tracks, playlists, releases), replacing the previous TrackLike model. - Completely revamps the Studio TV profile page, adding live statistics, stream configuration, restream management, and media URL display. - Enhances the media player with a custom seekbar and improved audio playback logic for MPD and non-MPD sources. - Lays foundational groundwork for chat encryption with new models and APIs. - Refactors critical UI components like PlaylistView and PagePanel. - Standardizes monorepo development scripts to use npm. - Updates comty.js submodule and adds various new UI components.
109 lines
2.1 KiB
JavaScript
109 lines
2.1 KiB
JavaScript
import { RadioProfile } from "@db_models"
|
|
|
|
async function scanKeysWithPagination(pattern, count = 10, cursor = "0") {
|
|
const result = await global.redis.scan(
|
|
cursor,
|
|
"MATCH",
|
|
pattern,
|
|
"COUNT",
|
|
count,
|
|
)
|
|
|
|
return result[1]
|
|
}
|
|
|
|
export default class Radio {
|
|
static async list({ limit = 50, offset = 0 } = {}) {
|
|
let result = await scanKeysWithPagination(
|
|
`radio-*`,
|
|
limit,
|
|
String(offset),
|
|
)
|
|
|
|
return await Radio.data(result.map((key) => key.split("radio-")[1]))
|
|
}
|
|
|
|
static async data(ids) {
|
|
if (typeof ids === "string") {
|
|
ids = [ids]
|
|
}
|
|
|
|
const results = []
|
|
|
|
let profiles = await RadioProfile.find({
|
|
_id: { $in: ids },
|
|
})
|
|
|
|
for await (const id of ids) {
|
|
let data = await redis.hgetall(`radio-${id}`)
|
|
|
|
if (!data) {
|
|
continue
|
|
}
|
|
|
|
let profile = profiles.find(
|
|
(profile) => profile._id.toString() === id,
|
|
)
|
|
|
|
if (!profile) {
|
|
continue
|
|
}
|
|
|
|
profile = profile.toObject()
|
|
|
|
data.now_playing = JSON.parse(data.now_playing)
|
|
data.online = ToBoolean(data.online)
|
|
data.listeners = parseInt(data.listeners)
|
|
|
|
results.push({ ...data, ...profile })
|
|
}
|
|
|
|
return results
|
|
}
|
|
|
|
static async trendings() {
|
|
const stationsWithListeners = []
|
|
|
|
let cursor = "0"
|
|
|
|
do {
|
|
const scanResult = await global.redis.scan(
|
|
cursor,
|
|
"MATCH",
|
|
"radio-*",
|
|
"COUNT",
|
|
100,
|
|
)
|
|
cursor = scanResult[0]
|
|
const keys = scanResult[1]
|
|
|
|
for (const key of keys) {
|
|
const id = key.split("radio-")[1]
|
|
const listenersStr = await global.redis.hget(key, "listeners")
|
|
|
|
if (listenersStr !== null) {
|
|
const listeners = parseInt(listenersStr, 10)
|
|
if (!isNaN(listeners)) {
|
|
stationsWithListeners.push({ id, listeners })
|
|
}
|
|
}
|
|
}
|
|
} while (cursor !== "0")
|
|
|
|
// Sort stations by listeners in descending order
|
|
stationsWithListeners.sort((a, b) => b.listeners - a.listeners)
|
|
|
|
// Get the IDs of the top 4 stations
|
|
const stationsIds = stationsWithListeners
|
|
.slice(0, 4)
|
|
.map((station) => station.id)
|
|
|
|
// If no stations found or no stations with valid listener counts, return an empty array
|
|
if (stationsIds.length === 0) {
|
|
return []
|
|
}
|
|
|
|
return await Radio.data(stationsIds)
|
|
}
|
|
}
|