I think we're done

This commit is contained in:
cdricms
2026-03-21 18:25:21 +01:00
parent 2d1e8e1044
commit ba9e2db1b9
26 changed files with 281 additions and 63 deletions

View File

@@ -1,6 +1,6 @@
import Foundation
public struct Area: MusicBrainzSearchable {
public struct Area: MusicBrainzSearchable, Identifiable, Hashable, Equatable {
public static let entityType: MusicBrainzEntity = .area
public let id: String
@@ -12,7 +12,7 @@ public struct Area: MusicBrainzSearchable {
public let relations: [Relation]?
public let score: Int?
enum CodingKeys: String, CodingKey {
enum CodingKeys: String, CodingKey, Hashable, Equatable {
case id, type, name, disambiguation, score, relations
case sortName = "sort-name"
case lifeSpan = "life-span"

View File

@@ -1,6 +1,6 @@
import Foundation
public struct Artist: MusicBrainzSearchable {
public struct Artist: MusicBrainzSearchable, Identifiable, Hashable, Equatable {
public static let entityType: MusicBrainzEntity = .artist
public let id: String
@@ -11,9 +11,11 @@ public struct Artist: MusicBrainzSearchable {
public let disambiguation: String?
public let lifeSpan: LifeSpan?
public let relations: [Relation]?
public let releases: [Release]?
public let releaseGroups: [ReleaseGroup]?
public let score: Int?
enum CodingKeys: String, CodingKey {
enum CodingKeys: String, CodingKey, Hashable, Equatable {
case id
case name
case sortName = "sort-name"
@@ -22,6 +24,8 @@ public struct Artist: MusicBrainzSearchable {
case disambiguation
case lifeSpan = "life-span"
case relations
case releases
case releaseGroups = "release-groups"
case score
}
@@ -31,7 +35,15 @@ public struct Artist: MusicBrainzSearchable {
for rel in relations {
if rel.type == "image" || rel.type == "wikimedia commons" {
if let resource = rel.url?.resource {
return URL(string: resource)
var urlString = resource
// Handle Wikimedia Commons page URLs by converting to Special:FilePath
if urlString.contains("commons.wikimedia.org/wiki/File:") {
let filename = urlString.components(separatedBy: "/wiki/File:").last ?? ""
if !filename.isEmpty {
urlString = "https://commons.wikimedia.org/wiki/Special:FilePath/\(filename)"
}
}
return URL(string: urlString)
}
}
}

View File

@@ -1,6 +1,6 @@
import Foundation
public struct Event: MusicBrainzSearchable {
public struct Event: MusicBrainzSearchable, Identifiable, Hashable, Equatable {
public static let entityType: MusicBrainzEntity = .event
public let id: String
@@ -11,7 +11,7 @@ public struct Event: MusicBrainzSearchable {
public let relations: [Relation]?
public let score: Int?
enum CodingKeys: String, CodingKey {
enum CodingKeys: String, CodingKey, Hashable, Equatable {
case id, name, time, disambiguation, score, relations
case lifeSpan = "life-span"
}

View File

@@ -1,6 +1,6 @@
import Foundation
public struct Instrument: MusicBrainzSearchable {
public struct Instrument: MusicBrainzSearchable, Identifiable, Hashable, Equatable {
public static let entityType: MusicBrainzEntity = .instrument
public let id: String
@@ -11,7 +11,7 @@ public struct Instrument: MusicBrainzSearchable {
public let relations: [Relation]?
public let score: Int?
enum CodingKeys: String, CodingKey {
enum CodingKeys: String, CodingKey, Hashable, Equatable {
case id, name, type, description, disambiguation, score, relations
}
}

View File

@@ -1,6 +1,6 @@
import Foundation
public struct Label: MusicBrainzSearchable {
public struct Label: MusicBrainzSearchable, Identifiable, Hashable, Equatable {
public static let entityType: MusicBrainzEntity = .label
public let id: String
@@ -13,7 +13,7 @@ public struct Label: MusicBrainzSearchable {
public let relations: [Relation]?
public let score: Int?
enum CodingKeys: String, CodingKey {
enum CodingKeys: String, CodingKey, Hashable, Equatable {
case id, name, type, country, disambiguation, score, relations
case labelCode = "label-code"
case lifeSpan = "life-span"

View File

@@ -1,6 +1,6 @@
import Foundation
public struct Place: MusicBrainzSearchable {
public struct Place: MusicBrainzSearchable, Identifiable, Hashable, Equatable {
public static let entityType: MusicBrainzEntity = .place
public let id: String
@@ -12,7 +12,7 @@ public struct Place: MusicBrainzSearchable {
public let relations: [Relation]?
public let score: Int?
enum CodingKeys: String, CodingKey {
enum CodingKeys: String, CodingKey, Hashable, Equatable {
case id, name, type, address, area, disambiguation, score, relations
}
}

View File

@@ -1,6 +1,6 @@
import Foundation
public struct Recording: MusicBrainzSearchable {
public struct Recording: MusicBrainzSearchable, Identifiable, Hashable, Equatable {
public static let entityType: MusicBrainzEntity = .recording
public let id: String
@@ -12,7 +12,7 @@ public struct Recording: MusicBrainzSearchable {
public let relations: [Relation]?
public let score: Int?
enum CodingKeys: String, CodingKey {
enum CodingKeys: String, CodingKey, Hashable, Equatable {
case id
case title
case length
@@ -22,4 +22,16 @@ public struct Recording: MusicBrainzSearchable {
case relations
case score
}
public var youtubeURL: URL? {
guard let relations else { return nil }
for rel in relations {
if let resource = rel.url?.resource {
if rel.type == "youtube" || resource.contains("youtube.com") || resource.contains("youtu.be") {
return URL(string: resource)
}
}
}
return nil
}
}

View File

@@ -1,6 +1,6 @@
import Foundation
public struct Release: MusicBrainzSearchable {
public struct Release: MusicBrainzSearchable, Identifiable, Hashable, Equatable {
public static let entityType: MusicBrainzEntity = .release
public let id: String
@@ -11,9 +11,10 @@ public struct Release: MusicBrainzSearchable {
public let barcode: String?
public let disambiguation: String?
public let relations: [Relation]?
public let media: [Media]?
public let score: Int?
enum CodingKeys: String, CodingKey {
enum CodingKeys: String, CodingKey, Hashable, Equatable {
case id
case title
case status
@@ -22,6 +23,7 @@ public struct Release: MusicBrainzSearchable {
case barcode
case disambiguation
case relations
case media
case score
}
}

View File

@@ -1,6 +1,6 @@
import Foundation
public struct ReleaseGroup: MusicBrainzSearchable {
public struct ReleaseGroup: MusicBrainzSearchable, Identifiable, Hashable, Equatable {
public static let entityType: MusicBrainzEntity = .releaseGroup
public let id: String
@@ -11,7 +11,7 @@ public struct ReleaseGroup: MusicBrainzSearchable {
public let relations: [Relation]?
public let score: Int?
enum CodingKeys: String, CodingKey {
enum CodingKeys: String, CodingKey, Hashable, Equatable {
case id, title, disambiguation, score, relations
case primaryType = "primary-type"
case artistCredit = "artist-credit"

View File

@@ -1,6 +1,6 @@
import Foundation
public struct Series: MusicBrainzSearchable {
public struct Series: MusicBrainzSearchable, Identifiable, Hashable, Equatable {
public static let entityType: MusicBrainzEntity = .series
public let id: String
@@ -10,7 +10,7 @@ public struct Series: MusicBrainzSearchable {
public let relations: [Relation]?
public let score: Int?
enum CodingKeys: String, CodingKey {
enum CodingKeys: String, CodingKey, Hashable, Equatable {
case id, name, type, disambiguation, score, relations
}
}

View File

@@ -1,6 +1,6 @@
import Foundation
public struct ArtistCredit: Codable, Sendable {
public struct ArtistCredit: Codable, Sendable, Hashable, Equatable {
public let name: String
public let artist: Artist?
public let joinphrase: String?

View File

@@ -1,6 +1,6 @@
import Foundation
public struct CoverArtImage: Codable, Sendable {
public struct CoverArtImage: Codable, Sendable, Identifiable, Hashable, Equatable {
public let image: String
public let thumbnails: [String: String]
public let types: [String]
@@ -11,7 +11,7 @@ public struct CoverArtImage: Codable, Sendable {
public let id: String
}
public struct CoverArtResponse: Codable, Sendable {
public struct CoverArtResponse: Codable, Sendable, Hashable, Equatable {
public let images: [CoverArtImage]
public let release: String

View File

@@ -1,6 +1,6 @@
import Foundation
public struct LifeSpan: Codable, Sendable {
public struct LifeSpan: Codable, Sendable, Hashable, Equatable {
public let begin: String?
public let end: String?
public let ended: Bool?

View File

@@ -0,0 +1,22 @@
import Foundation
public struct Track: Codable, Sendable, Identifiable, Hashable, Equatable {
public let id: String
public let number: String
public let position: Int
public let title: String
public let length: Int?
public let recording: Recording?
}
public struct Media: Codable, Sendable, Hashable, Equatable {
public let position: Int
public let format: ReleaseFormat?
public let trackCount: Int
public let tracks: [Track]?
enum CodingKeys: String, CodingKey {
case position, format, tracks
case trackCount = "track-count"
}
}

View File

@@ -1,6 +1,6 @@
import Foundation
public struct Relation: Codable, Sendable {
public struct Relation: Codable, Sendable, Hashable, Equatable {
public let type: String
public let direction: String
public let url: URLResource?

View File

@@ -1,6 +1,6 @@
import Foundation
public struct URLResource: Codable, Sendable {
public struct URLResource: Codable, Sendable, Identifiable, Hashable, Equatable {
public let id: String
public let resource: String
}

View File

@@ -0,0 +1,20 @@
import Foundation
public struct WikimediaResponse: Codable, Sendable {
public let query: WikimediaQuery
}
public struct WikimediaQuery: Codable, Sendable {
public let pages: [String: WikimediaPage]
}
public struct WikimediaPage: Codable, Sendable {
public let pageid: Int?
public let title: String
public let imageinfo: [WikimediaImageInfo]?
}
public struct WikimediaImageInfo: Codable, Sendable {
public let url: String
public let descriptionurl: String
}

View File

@@ -1,6 +1,6 @@
import Foundation
public struct URLReference: MusicBrainzSearchable {
public struct URLReference: MusicBrainzSearchable, Identifiable, Hashable, Equatable {
public static let entityType: MusicBrainzEntity = .url
public let id: String

View File

@@ -1,6 +1,6 @@
import Foundation
public struct Work: MusicBrainzSearchable {
public struct Work: MusicBrainzSearchable, Identifiable, Hashable, Equatable {
public static let entityType: MusicBrainzEntity = .work
public let id: String
@@ -11,7 +11,7 @@ public struct Work: MusicBrainzSearchable {
public let relations: [Relation]?
public let score: Int?
enum CodingKeys: String, CodingKey {
enum CodingKeys: String, CodingKey, Hashable, Equatable {
case id, title, type, language, disambiguation, score, relations
}
}