mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-09 18:44:16 +00:00
split services
This commit is contained in:
parent
6eb69a8ef8
commit
5db0863943
@ -1,58 +1,8 @@
|
||||
const syncLyricsProvider = `https://spotify-lyric-api.herokuapp.com`
|
||||
const canvasProvider = `https://api.delitefully.com/api/canvas`
|
||||
|
||||
import { Track } from "@models"
|
||||
import axios from "axios"
|
||||
|
||||
const clearQueryRegexs = [
|
||||
// remove titles with (feat. Something)
|
||||
new RegExp(/\(feat\..*\)/, "gi"),
|
||||
// remplace $ with S
|
||||
new RegExp(/\$/, "gi"),
|
||||
// remove special characters
|
||||
new RegExp(/[\(\)\[\]\$\&\*\#\@\!\%\+\=\_\-\:\;\'\"\,\.]/, "gi"),
|
||||
// remove words like "official video", "official audio", "official music video"
|
||||
new RegExp(/official\s(video|audio|music\svideo)/, "gi"),
|
||||
]
|
||||
|
||||
async function findSpotifyTrack({
|
||||
title,
|
||||
artist,
|
||||
sessionToken,
|
||||
} = {}) {
|
||||
let query = `${title} artist:${artist}`
|
||||
|
||||
// run clear query regexs
|
||||
for (const regex of clearQueryRegexs) {
|
||||
query = query.replace(regex, "")
|
||||
}
|
||||
|
||||
const { data } = await global.comty.instances.default({
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Authorization": `Bearer ${sessionToken}`,
|
||||
},
|
||||
params: {
|
||||
query: query,
|
||||
type: "track",
|
||||
},
|
||||
url: "/sync/spotify/search",
|
||||
}).catch((error) => {
|
||||
console.error(error.response.data)
|
||||
|
||||
return null
|
||||
})
|
||||
|
||||
if (!data) {
|
||||
return null
|
||||
}
|
||||
|
||||
return data.tracks.items[0]
|
||||
}
|
||||
import getEnhancedLyricsFromTrack from "@services/getEnhancedLyricsFromTrack"
|
||||
|
||||
export default async (req, res) => {
|
||||
const noCache = req.query["no-cache"] === "true"
|
||||
|
||||
let track = await Track.findOne({
|
||||
_id: req.params.track_id,
|
||||
}).catch((error) => {
|
||||
@ -65,132 +15,43 @@ export default async (req, res) => {
|
||||
})
|
||||
}
|
||||
|
||||
console.log(track)
|
||||
|
||||
if (!track.lyricsEnabled) {
|
||||
return res.status(403).json({
|
||||
error: "Lyrics disabled for this track",
|
||||
})
|
||||
}
|
||||
|
||||
//console.log("Found track", track)
|
||||
const noCache = req.query["no-cache"] === "true"
|
||||
|
||||
track = track.toObject()
|
||||
let data = null
|
||||
|
||||
let lyricData = {
|
||||
syncType: null,
|
||||
lines: null,
|
||||
canvas_url: null,
|
||||
if (!noCache) {
|
||||
data = await global.redis.get(`lyrics:${track._id.toString()}`)
|
||||
|
||||
if (data) {
|
||||
data = JSON.parse(data)
|
||||
}
|
||||
}
|
||||
|
||||
let cachedData = null
|
||||
|
||||
try {
|
||||
if (!noCache) {
|
||||
cachedData = await global.redis.get(`lyrics:${track._id}`)
|
||||
if (!data) {
|
||||
data = await getEnhancedLyricsFromTrack(track, { req })
|
||||
|
||||
if (cachedData) {
|
||||
lyricData = JSON.parse(cachedData)
|
||||
}
|
||||
|
||||
if (track.videoCanvas) {
|
||||
lyricData.canvas_url = track.videoCanvas
|
||||
}
|
||||
await global.redis.set(`lyrics:${track._id.toString()}`, JSON.stringify(data), "EX", 60 * 60 * 24 * 30)
|
||||
}
|
||||
|
||||
if (!cachedData) {
|
||||
// no cache, recosntruct lyrics data
|
||||
|
||||
// first check if track has spotify id to fetch the lyrics
|
||||
// if not present, try to search from spotify api and update the track with the spotify id
|
||||
if (!track.spotifyId) {
|
||||
if (!req.session) {
|
||||
throw new Error("Session not found and track has no spotify id")
|
||||
}
|
||||
|
||||
console.log("Fetching spotify track")
|
||||
|
||||
const spotifyTrack = await findSpotifyTrack({
|
||||
title: track.title,
|
||||
artist: track.artist,
|
||||
sessionToken: req.sessionToken,
|
||||
})
|
||||
|
||||
console.log(spotifyTrack)
|
||||
|
||||
if (spotifyTrack.id) {
|
||||
track.spotifyId = spotifyTrack.id
|
||||
|
||||
console.log("Updating track with spotify id")
|
||||
|
||||
const result = await Track.findOneAndUpdate({
|
||||
_id: track._id.toString(),
|
||||
}, {
|
||||
spotifyId: spotifyTrack.id,
|
||||
})
|
||||
|
||||
console.log(result)
|
||||
} else {
|
||||
throw new Error("Failed to search spotify id")
|
||||
}
|
||||
}
|
||||
|
||||
// ok now we have the spotify id, try to fetch the lyrics
|
||||
console.log("Fetching lyrics from sync provider, ID:", track.spotifyId)
|
||||
|
||||
let { data } = await axios.get(`${syncLyricsProvider}/?trackid=${track.spotifyId}`)
|
||||
|
||||
lyricData.syncType = data.syncType
|
||||
lyricData.lines = data.lines
|
||||
|
||||
// so we have the lyrics, now check if track has videoCanvas
|
||||
// if not present, try to fetch from canvas provider and update the track with the videoCanvas
|
||||
// handle errors silently
|
||||
if (track.videoCanvas) {
|
||||
lyricData.canvas_url = track.videoCanvas
|
||||
} else {
|
||||
try {
|
||||
console.log("Fetching canvas for id", track.spotifyId)
|
||||
|
||||
const { data } = await axios.get(`${canvasProvider}/${track.spotifyId}`)
|
||||
|
||||
lyricData.canvas_url = data.canvas_url
|
||||
|
||||
console.log("Updating track with canvas url")
|
||||
|
||||
await Track.findOneAndUpdate({
|
||||
_id: track._id.toString(),
|
||||
}, {
|
||||
videoCanvas: data.canvas_url,
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
// force rewrite cache
|
||||
await global.redis.set(`lyrics:${track._id}`, JSON.stringify(data))
|
||||
|
||||
// check
|
||||
// const _cachedData = await global.redis.get(`lyrics:${track._id}`)
|
||||
|
||||
// console.log("Cached data", _cachedData, data)
|
||||
if (!data.lines) {
|
||||
return res.status(404).json({
|
||||
error: "Lyrics not found",
|
||||
})
|
||||
}
|
||||
|
||||
return res.json(data)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
|
||||
return res.status(500).json({
|
||||
error: `Failed to generate lyrics for track ${track._id}`,
|
||||
error: "Failed to generate lyrics",
|
||||
})
|
||||
}
|
||||
|
||||
if (!lyricData.lines) {
|
||||
return res.status(404).json({
|
||||
error: "Lyrics not found",
|
||||
})
|
||||
}
|
||||
|
||||
//console.log("Lyrics data", lyricData)
|
||||
|
||||
return res.json(lyricData)
|
||||
}
|
45
packages/music_server/src/services/findSpotifyId.js
Normal file
45
packages/music_server/src/services/findSpotifyId.js
Normal file
@ -0,0 +1,45 @@
|
||||
const clearQueryRegexs = [
|
||||
// remove titles with (feat. Something)
|
||||
new RegExp(/\(feat\..*\)/, "gi"),
|
||||
// remplace $ with S
|
||||
new RegExp(/\$/, "gi"),
|
||||
// remove special characters
|
||||
new RegExp(/[\(\)\[\]\$\&\*\#\@\!\%\+\=\_\-\:\;\'\"\,\.]/, "gi"),
|
||||
// remove words like "official video", "official audio", "official music video"
|
||||
new RegExp(/official\s(video|audio|music\svideo)/, "gi"),
|
||||
]
|
||||
|
||||
export default async ({
|
||||
title,
|
||||
artist,
|
||||
sessionToken,
|
||||
} = {}) => {
|
||||
let query = `${title} artist:${artist}`
|
||||
|
||||
// run clear query regexs
|
||||
for (const regex of clearQueryRegexs) {
|
||||
query = query.replace(regex, "")
|
||||
}
|
||||
|
||||
const { data } = await global.comty.instances.default({
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Authorization": `Bearer ${sessionToken}`,
|
||||
},
|
||||
params: {
|
||||
query: query,
|
||||
type: "track",
|
||||
},
|
||||
url: "/sync/spotify/search",
|
||||
}).catch((error) => {
|
||||
console.error(error.response.data)
|
||||
|
||||
return null
|
||||
})
|
||||
|
||||
if (!data) {
|
||||
return null
|
||||
}
|
||||
|
||||
return data.tracks.items[0]
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
import findSpotifyId from "@services/findSpotifyId"
|
||||
import { Track } from "@models"
|
||||
import axios from "axios"
|
||||
|
||||
const syncLyricsProvider = `https://spotify-lyric-api.herokuapp.com`
|
||||
const canvasProvider = `https://api.delitefully.com/api/canvas`
|
||||
|
||||
export default async (track, { req }) => {
|
||||
if (typeof track !== "object") {
|
||||
throw new Error("Track must be an object")
|
||||
}
|
||||
|
||||
if (!track._id) {
|
||||
throw new Error("Track must have an _id")
|
||||
}
|
||||
|
||||
if (!track.lyricsEnabled) {
|
||||
throw new Error("Track lyrics are not enabled")
|
||||
}
|
||||
|
||||
let lyricData = {
|
||||
syncType: null,
|
||||
lines: null,
|
||||
canvas_url: null,
|
||||
}
|
||||
|
||||
if (!track.spotifyId) {
|
||||
if (!req.session) {
|
||||
throw new Error("Session not found and track has no spotify id")
|
||||
}
|
||||
|
||||
const spotifyId = await findSpotifyId({
|
||||
track: track.title,
|
||||
artist: track.artist,
|
||||
sessionToken: req.sessionToken,
|
||||
}, { req })
|
||||
|
||||
if (!spotifyId) {
|
||||
throw new Error("Track has no spotify id")
|
||||
}
|
||||
|
||||
track.spotifyId = spotifyId
|
||||
|
||||
await Track.findOneAndUpdate({
|
||||
_id: track._id.toString(),
|
||||
}, { spotifyId })
|
||||
}
|
||||
|
||||
let { data } = await axios.get(`${syncLyricsProvider}/?trackid=${track.spotifyId}`)
|
||||
|
||||
lyricData.syncType = data.syncType
|
||||
lyricData.lines = data.lines
|
||||
|
||||
if (track.videoCanvas) {
|
||||
lyricData.canvas_url = track.videoCanvas
|
||||
} else {
|
||||
try {
|
||||
const { data } = await axios.get(`${canvasProvider}/${track.spotifyId}`)
|
||||
|
||||
lyricData.canvas_url = data.canvas_url
|
||||
|
||||
await Track.findOneAndUpdate({
|
||||
_id: track._id.toString(),
|
||||
}, {
|
||||
videoCanvas: data.canvas_url,
|
||||
})
|
||||
} catch (err) {
|
||||
//console.log(err.response.data)
|
||||
}
|
||||
}
|
||||
|
||||
return lyricData
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user