Files
EeveeSpotifyReborn/Sources/EeveeSpotify/Lyrics/DataSources/MusixmatchLyricsDataSource.swift
T

97 lines
3.1 KiB
Swift

import Foundation
struct MusixmatchLyricsDataSource {
private let apiUrl = "https://apic.musixmatch.com"
private func perform(
_ path: String,
query: [String:Any] = [:]
) throws -> Data {
var stringUrl = "\(apiUrl)\(path)"
var finalQuery = query
finalQuery["usertoken"] = UserDefaults.musixmatchToken
finalQuery["app_id"] = "mac-ios-v2.0"
let queryString = finalQuery.queryString.addingPercentEncoding(
withAllowedCharacters: .urlHostAllowed
)!
stringUrl += "?\(queryString)"
let request = URLRequest(url: URL(string: stringUrl)!)
let semaphore = DispatchSemaphore(value: 0)
var data: Data?
var error: Error?
let task = URLSession.shared.dataTask(with: request) { response, _, err in
error = err
data = response
semaphore.signal()
}
task.resume()
semaphore.wait()
if let error = error {
throw error
}
return data!
}
func getLyrics(_ spotifyTrackId: String) throws -> PlainLyrics {
let data = try perform(
"/ws/1.1/macro.subtitles.get",
query: [
"track_spotify_id": spotifyTrackId,
"subtitle_format": "mxm",
"q_track": " "
]
)
// 😭😭😭
guard
let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
let message = json["message"] as? [String: Any],
let body = message["body"] as? [String: Any],
let macroCalls = body["macro_calls"] as? [String: Any]
else {
throw LyricsError.DecodingError
}
if let header = message["header"] as? [String: Any],
header["status_code"] as? Int == 401 {
throw LyricsError.InvalidMusixmatchToken
}
if let trackSubtitlesGet = macroCalls["track.subtitles.get"] as? [String: Any],
let subtitlesMessage = trackSubtitlesGet["message"] as? [String: Any],
let subtitlesBody = subtitlesMessage["body"] as? [String: Any],
let subtitlesList = subtitlesBody["subtitle_list"] as? [Any],
let firstSubtitle = subtitlesList.first as? [String: Any],
let subtitle = firstSubtitle["subtitle"] as? [String: Any],
let subtitleBody = subtitle["subtitle_body"] as? String {
return PlainLyrics(content: subtitleBody, timeSynced: true)
}
guard
let trackLyricsGet = macroCalls["track.lyrics.get"] as? [String: Any],
let lyricsMessage = trackLyricsGet["message"] as? [String: Any],
let lyricsBody = lyricsMessage["body"] as? [String: Any],
let lyrics = lyricsBody["lyrics"] as? [String: Any],
let plainLyrics = lyrics["lyrics_body"] as? String
else {
throw LyricsError.DecodingError
}
return PlainLyrics(content: plainLyrics, timeSynced: false)
}
}