Skip to content

Commit

Permalink
musixmatch anonymous tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
whoeevee committed Nov 6, 2024
1 parent d579470 commit 21b3267
Show file tree
Hide file tree
Showing 14 changed files with 120 additions and 54 deletions.
14 changes: 7 additions & 7 deletions Sources/EeveeSpotify/Lyrics/CustomLyrics.x.swift
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ class LyricsOnlyViewControllerHook: ClassHook<UIViewController> {

private func loadLyricsForCurrentTrack() throws {
guard let track = HookedInstances.currentTrack else {
throw LyricsError.NoCurrentTrack
throw LyricsError.noCurrentTrack
}

//
Expand All @@ -145,7 +145,7 @@ private func loadLyricsForCurrentTrack() throws {
case .lrclib: LrcLibLyricsRepository()
case .musixmatch: MusixmatchLyricsRepository.shared
case .petit: PetitLyricsRepository()
case .notReplaced: throw LyricsError.InvalidSource
case .notReplaced: throw LyricsError.invalidSource
}

let lyricsDto: LyricsDto
Expand All @@ -163,7 +163,7 @@ private func loadLyricsForCurrentTrack() throws {

switch error {

case .InvalidMusixmatchToken:
case .invalidMusixmatchToken:
if !hasShownUnauthorizedPopUp {
PopUpHelper.showPopUp(
delayed: false,
Expand All @@ -174,7 +174,7 @@ private func loadLyricsForCurrentTrack() throws {
hasShownUnauthorizedPopUp.toggle()
}

case .MusixmatchRestricted:
case .musixmatchRestricted:
if !hasShownRestrictedPopUp {
PopUpHelper.showPopUp(
delayed: false,
Expand All @@ -190,7 +190,7 @@ private func loadLyricsForCurrentTrack() throws {
}
}
else {
lastLyricsState.fallbackError = .UnknownError
lastLyricsState.fallbackError = .unknownError
}

if source == .genius || !UserDefaults.geniusFallback {
Expand Down Expand Up @@ -221,7 +221,7 @@ private func loadLyricsForCurrentTrack() throws {

func getLyricsForCurrentTrack(originalLyrics: Lyrics? = nil) throws -> Data {
guard let track = HookedInstances.currentTrack else {
throw LyricsError.NoCurrentTrack
throw LyricsError.noCurrentTrack
}

var lyrics = preloadedLyrics
Expand All @@ -232,7 +232,7 @@ func getLyricsForCurrentTrack(originalLyrics: Lyrics? = nil) throws -> Data {
}

guard var lyrics = lyrics else {
throw LyricsError.UnknownError
throw LyricsError.unknownError
}

let lyricsColorsSettings = UserDefaults.lyricsColors
Expand Down
28 changes: 14 additions & 14 deletions Sources/EeveeSpotify/Lyrics/Models/LyricsError.swift
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import Foundation

enum LyricsError: Error, CustomStringConvertible {
case NoCurrentTrack
case MusixmatchRestricted
case InvalidMusixmatchToken
case DecodingError
case NoSuchSong
case UnknownError
case InvalidSource
case noCurrentTrack
case musixmatchRestricted
case invalidMusixmatchToken
case decodingError
case noSuchSong
case unknownError
case invalidSource

var description: String {
switch self {
case .NoSuchSong: "no_such_song".localized
case .MusixmatchRestricted: "musixmatch_restricted".localized
case .InvalidMusixmatchToken: "invalid_musixmatch_token".localized
case .DecodingError: "decoding_error".localized
case .NoCurrentTrack: "no_current_track".localized
case .UnknownError: "unknown_error".localized
case .InvalidSource: ""
case .noSuchSong: "no_such_song".localized
case .musixmatchRestricted: "musixmatch_restricted".localized
case .invalidMusixmatchToken: "invalid_musixmatch_token".localized
case .decodingError: "decoding_error".localized
case .noCurrentTrack: "no_current_track".localized
case .unknownError: "unknown_error".localized
case .invalidSource: ""
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ struct GeniusLyricsRepository: LyricsRepository {
}

guard let rootResponse = try? jsonDecoder.decode(GeniusRootResponse.self, from: data!) else {
throw LyricsError.DecodingError
throw LyricsError.decodingError
}
return rootResponse.response
}
Expand All @@ -67,7 +67,7 @@ struct GeniusLyricsRepository: LyricsRepository {
case .sections(let sectionsResponse) = data,
let section = sectionsResponse.sections.first
else {
throw LyricsError.DecodingError
throw LyricsError.decodingError
}

return section.hits
Expand All @@ -77,7 +77,7 @@ struct GeniusLyricsRepository: LyricsRepository {
let data = try perform("/songs/\(songId)", query: ["text_format": "plain"])

guard case .song(let songResponse) = data else {
throw LyricsError.DecodingError
throw LyricsError.decodingError
}

return songResponse.song
Expand Down Expand Up @@ -131,7 +131,7 @@ struct GeniusLyricsRepository: LyricsRepository {
let hits = try searchSong("\(strippedTitle) \(query.primaryArtist)")

guard !hits.isEmpty else {
throw LyricsError.NoSuchSong
throw LyricsError.noSuchSong
}

var hasFoundRomanizedLyrics = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ struct LrcLibLyricsRepository: LyricsRepository {
let songs = try searchSong("\(strippedTitle) \(query.primaryArtist)")

guard let song = mostRelevantSong(songs: songs, strippedTitle: strippedTitle) else {
throw LyricsError.NoSuchSong
throw LyricsError.noSuchSong
}

if let syncedLyrics = song.syncedLyrics {
Expand All @@ -110,7 +110,7 @@ struct LrcLibLyricsRepository: LyricsRepository {
}

guard let plainLyrics = song.plainLyrics else {
throw LyricsError.DecodingError
throw LyricsError.decodingError
}

let lines = Array(plainLyrics.components(separatedBy: "\n").dropLast())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ class MusixmatchLyricsRepository: LyricsRepository {
var finalQuery = query

finalQuery["usertoken"] = UserDefaults.musixmatchToken
finalQuery["app_id"] = UIDevice.current.isIpad
? "mac-ios-ipad-v1.0"
: "mac-ios-v2.0"
finalQuery["app_id"] = UIDevice.current.musixmatchAppId

let queryString = finalQuery.queryString.addingPercentEncoding(
withAllowedCharacters: .urlHostAllowed
Expand Down Expand Up @@ -63,12 +61,12 @@ class MusixmatchLyricsRepository: LyricsRepository {
let body = message["body"] as? [String: Any],
let macroCalls = body["macro_calls"] as? [String: Any]
else {
throw LyricsError.DecodingError
throw LyricsError.decodingError
}

if let header = message["header"] as? [String: Any],
header["status_code"] as? Int == 401 {
throw LyricsError.InvalidMusixmatchToken
throw LyricsError.invalidMusixmatchToken
}

return macroCalls
Expand All @@ -81,11 +79,11 @@ class MusixmatchLyricsRepository: LyricsRepository {
let firstSubtitle = subtitleList.first,
let subtitle = firstSubtitle["subtitle"] as? [String: Any]
else {
throw LyricsError.DecodingError
throw LyricsError.decodingError
}

if let restricted = subtitle["restricted"] as? Bool, restricted {
throw LyricsError.MusixmatchRestricted
throw LyricsError.musixmatchRestricted
}

return subtitle
Expand All @@ -108,7 +106,7 @@ class MusixmatchLyricsRepository: LyricsRepository {
let body = message["body"] as? [String: Any],
let translationsList = body["translations_list"] as? [[String: Any]]
else {
throw LyricsError.DecodingError
throw LyricsError.decodingError
}

let translations = translationsList.compactMap {
Expand Down Expand Up @@ -236,7 +234,7 @@ class MusixmatchLyricsRepository: LyricsRepository {
let lyricsStatusCode = lyricsHeader["status_code"] as? Int {

if lyricsStatusCode == 404 {
throw LyricsError.NoSuchSong
throw LyricsError.noSuchSong
}

if let lyricsBody = lyricsMessage["body"] as? [String: Any],
Expand All @@ -245,7 +243,7 @@ class MusixmatchLyricsRepository: LyricsRepository {
let plainLyrics = lyrics["lyrics_body"] as? String {

if let restricted = lyrics["restricted"] as? Bool, restricted {
throw LyricsError.MusixmatchRestricted
throw LyricsError.musixmatchRestricted
}

return LyricsDto(
Expand All @@ -259,6 +257,6 @@ class MusixmatchLyricsRepository: LyricsRepository {
}
}

throw LyricsError.DecodingError
throw LyricsError.decodingError
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ struct PetitLyricsRepository: LyricsRepository {
}

guard let response = try? XMLDecoder().decode(PetitResponse.self, from: data!) else {
throw LyricsError.DecodingError
throw LyricsError.decodingError
}

return response
Expand All @@ -58,7 +58,7 @@ struct PetitLyricsRepository: LyricsRepository {
)

guard let song = response.songs.first else {
throw LyricsError.NoSuchSong
throw LyricsError.noSuchSong
}

return song
Expand All @@ -81,7 +81,7 @@ struct PetitLyricsRepository: LyricsRepository {
)

guard let song = response.songs.first else {
throw LyricsError.NoSuchSong
throw LyricsError.noSuchSong
}

return song
Expand All @@ -97,15 +97,15 @@ struct PetitLyricsRepository: LyricsRepository {
)

guard let lyricsData = Data(base64Encoded: song.lyricsData) else {
throw LyricsError.DecodingError
throw LyricsError.decodingError
}

switch song.lyricsType {

case .wordsSynced:
guard let lyrics = try? XMLDecoder().decode(PetitLyricsData.self, from: lyricsData)
else {
throw LyricsError.DecodingError
throw LyricsError.decodingError
}

return LyricsDto(
Expand All @@ -132,7 +132,7 @@ struct PetitLyricsRepository: LyricsRepository {
)

default:
throw LyricsError.DecodingError
throw LyricsError.decodingError
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,10 @@ extension UIDevice {
var isIpad: Bool {
self.userInterfaceIdiom == .pad
}

var musixmatchAppId: String {
UIDevice.current.isIpad
? "mac-ios-ipad-v1.0"
: "mac-ios-v2.0"
}
}
22 changes: 22 additions & 0 deletions Sources/EeveeSpotify/Settings/Helpers/AnonymousTokenHelper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Foundation
import UIKit

struct AnonymousTokenHelper {
private static let apiUrl = "https://apic.musixmatch.com"

static func requestAnonymousMusixmatchToken() async throws -> String {
let url = URL(string: "\(apiUrl)/ws/1.1/token.get?app_id=\(await UIDevice.current.musixmatchAppId)")!
let (data, _) = try await URLSession.shared.data(from: url)

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 userToken = body["user_token"] as? String
else {
throw AnonymousTokenError.invalidResponse
}

return userToken
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
enum AnonymousTokenError: Swift.Error {
case invalidResponse
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,17 @@ extension EeveeLyricsSettingsView {
return nil
}

func showMusixmatchTokenAlert(_ oldSource: LyricsSource) {
func showMusixmatchTokenAlert(_ oldSource: LyricsSource, showAnonymousTokenOption: Bool) {
var message = "enter_user_token_message".localized

if showAnonymousTokenOption {
message.append("\n\n")
message.append("request_anonymous_token_description".localized)
}

let alert = UIAlertController(
title: "enter_user_token".localized,
message: "enter_user_token_message".localized,
message: message,
preferredStyle: .alert
)

Expand All @@ -27,6 +34,25 @@ extension EeveeLyricsSettingsView {
alert.addAction(UIAlertAction(title: "Cancel".uiKitLocalized, style: .cancel) { _ in
lyricsSource = oldSource
})

if showAnonymousTokenOption {
alert.addAction(UIAlertAction(title: "request_anonymous_token".localized, style: .default) { _ in
Task {
defer {
isRequestingMusixmatchToken.toggle()
}
do {
isRequestingMusixmatchToken.toggle()

musixmatchToken = try await AnonymousTokenHelper.requestAnonymousMusixmatchToken()
UserDefaults.lyricsSource = .musixmatch
}
catch {
showMusixmatchTokenAlert(oldSource, showAnonymousTokenOption: false)
}
}
})
}

alert.addAction(UIAlertAction(title: "OK".uiKitLocalized, style: .default) { _ in
let text = alert.textFields!.first!.text!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ extension EeveeLyricsSettingsView {
}
.onChange(of: lyricsSource) { [lyricsSource] newSource in
if newSource == .musixmatch && musixmatchToken.isEmpty {
showMusixmatchTokenAlert(lyricsSource)
showMusixmatchTokenAlert(lyricsSource, showAnonymousTokenOption: true)
return
}

Expand Down
Loading

0 comments on commit 21b3267

Please sign in to comment.