Compare commits

...
13 changed files with 100 additions and 8 deletions

No files matched your search

@@ -8,7 +8,7 @@ import { getGenres, getSong, getSongExternalMetadata } from "@/api/queries";
import type { ExternalMetadataSource } from "@/models/external-metadata";
import type Genre from "@/models/genre";
import type { Lyrics } from "@/models/lyrics";
import type Song from "@/models/song";
import type { SongWithRelations } from "@/models/song";
import { songTypeToTranslationKey } from "@/models/utils";
import { playTrackAtom, type TrackState } from "@/state/player";
import { LyricsIcon, PlayIcon, SongTypeIcon } from "@/ui/icons";
@@ -147,7 +147,11 @@ const LyricsView = ({
);
};
const InfoView = ({ song }: { song: Song | undefined }) => {
const InfoView = ({
song,
}: {
song: SongWithRelations<"master"> | undefined;
}) => {
const { t } = useTranslation();
const { items: genres } = useInfiniteQuery(
(songId) => getGenres({ song: songId }),
@@ -179,6 +183,18 @@ const InfoView = ({ song }: { song: Song | undefined }) => {
/>
</View>
</View>
{song?.master.ripSource ? (
<View style={styles.row}>
<Text
content={`${t("fileInfo.ripSource")}:`}
variant="itemLabel"
/>
<View style={styles.row}>
<Text content={song.master.ripSource} />
</View>
</View>
) : null}
{(genres === undefined || genres.length > 0) && (
<View style={styles.row}>
<Text
@@ -65,6 +65,9 @@ export const TrackInfo = ({ trackId }: { trackId: number }) => {
: undefined
}
/>
{track?.ripSource ? (
<Row label={t("fileInfo.ripSource")} value={track.ripSource} />
) : null}
<Row label={t("fileInfo.path")} value={file?.path} />
<Row
label={t("fileInfo.registrationDate")}
@@ -83,6 +83,9 @@ const TrackFileInfo = ({ trackId }: { trackId: number }) => {
"fileInfo.duration": track.data
? formatDuration(track.data.duration)
: undefined,
"fileInfo.ripSource": track.data
? (track.data.ripSource ?? t("fileInfo.unknown"))
: undefined,
"fileInfo.bitRate": track.data
? track.data.bitrate
? `${track.data.bitrate} kbps`
@@ -343,15 +343,18 @@ const SongPage: Page<GetPropsTypesFrom<typeof prepareSSR>> = ({ props }) => {
{song.data ? (
song.data.bpm ? (
<Typography
sx={{
paddingTop: 1,
paddingBottom: 4,
}}
sx={{ paddingBottom: 2 }}
>{`BPM: ${song.data.bpm}`}</Typography>
) : null
) : (
<Skeleton width={"50px"} />
)}
{song.data?.master.ripSource ? (
<Typography
sx={{ paddingBottom: 2 }}
>{`${t("fileInfo.ripSource")}: ${song.data.master.ripSource}`}</Typography>
) : null}
{(genres.items === undefined ||
genres.items.length !== 0) && (
<Stack
+15
View File
@@ -0,0 +1,15 @@
import * as yup from "yup";
export const RipSources = [
"CD",
"DVD",
"BluRay",
"Cassette",
"Digital",
"Vinyl",
"Other",
] as const;
export type RipSource = (typeof RipSources)[number];
export const RipSource = yup.mixed<RipSource>().oneOf(RipSources);
+2
View File
@@ -20,6 +20,7 @@ import * as yup from "yup";
import Illustration from "./illustration";
import Release from "./release";
import Resource from "./resource";
import { RipSource } from "./rip-source";
import Song from "./song";
import Video from "./video";
@@ -84,6 +85,7 @@ const Track = Resource.concat(
* If the Track is mixed with the previous/next track
*/
mixed: yup.boolean().required(),
ripSource: RipSource.required().nullable().default(null),
}),
);
+1
View File
@@ -210,6 +210,7 @@
"name": "Name",
"path": "Path",
"registrationDate": "Registration Date",
"ripSource": "Rip Source",
"type": "Type",
"unknown": "Unknown"
},
+1
View File
@@ -208,6 +208,7 @@
"name": "Nom",
"path": "Chemin",
"registrationDate": "Date d'ajout",
"ripSource": "Source du rip",
"type": "Type",
"unknown": "Inconnu"
},
+3
View File
@@ -170,6 +170,9 @@ func SaveMetadata(config config.Config, m internal.Metadata, saveMethod SaveMeta
mp.WriteField("label", m.Label)
}
mp.WriteField("type", string(m.Type))
if len(m.RipSource) > 0 {
mp.WriteField("ripSource", string(m.RipSource))
}
for i, genre := range m.Genres {
mp.WriteField(fmt.Sprintf("genres[%d]", i), genre)
}
+14
View File
@@ -69,6 +69,8 @@ type Metadata struct {
SeriesIndex float64
SeriesMbid string
RipSource RipSource
IllustrationLocation IllustrationLocation
IllustrationStreamIndex int
IllustrationPath string
@@ -87,6 +89,18 @@ const (
type AlbumType string
type RipSource string
const (
CD RipSource = "CD"
DVD RipSource = "DVD"
BluRay RipSource = "BluRay"
Cassette RipSource = "Cassette"
Vinyl RipSource = "Vinyl"
Digital RipSource = "Digital"
OtherRipSource RipSource = "Other"
)
const (
Studio AlbumType = "StudioRecording"
Live AlbumType = "LiveRecording"
+26
View File
@@ -240,6 +240,9 @@ func parseMetadataFromEmbeddedTags(filePath string, c config.UserSettings) (inte
metadata.SeriesMbid = value
})
ParseTag(tags, []string{"media", "rip source"}, func(value string) {
metadata.RipSource = parseRipSource(value)
})
if !c.UseEmbeddedThumbnails || metadata.Type != internal.Video {
if streamIndex := illustration.GetEmbeddedIllustrationStreamIndex(*probeData); streamIndex >= 0 {
metadata.IllustrationLocation = internal.Embedded
@@ -249,6 +252,29 @@ func parseMetadataFromEmbeddedTags(filePath string, c config.UserSettings) (inte
return metadata, errors
}
func parseRipSource(s string) internal.RipSource {
s = strings.ReplaceAll(strings.ToLower(s), "-", " ")
if strings.Contains(s, "vinyl") {
return internal.Vinyl
}
switch s {
case "cd", "sacd", "hdcd", "cd r", "cdr", "minidisc":
return internal.CD
case "dvd", "vcd", "cdv", "dvd audio", "dualdisc":
return internal.DVD
case "bluray", "hd dvd":
return internal.BluRay
case "cassette", "microcassette", "k7":
return internal.Cassette
case "vinyl", "record":
return internal.Vinyl
case "digital media":
return internal.Digital
default:
return internal.OtherRipSource
}
}
func parseLyrics(value string, metadata *internal.Metadata) {
parsedLyrics := internal.ParseLyrics(value)
switch l := parsedLyrics.(type) {
+1 -1
View File
@@ -318,6 +318,7 @@ export default class MetadataService {
mixed: parsedTrackName.mixed || releaseIsMixed,
isBonus: parsedTrackName.bonus,
isRemastered: parsedTrackName.remastered,
ripSource: metadata.ripSource ?? null,
discName: metadata.discName ?? null,
discIndex: metadata.discIndex ?? null,
trackIndex: metadata.index ?? null,
@@ -326,7 +327,6 @@ export default class MetadataService {
metadata.bitrate !== undefined
? Math.floor(metadata.bitrate)
: null,
ripSource: null,
duration:
metadata.duration !== undefined
? Math.floor(metadata.duration)
+6 -1
View File
@@ -34,7 +34,7 @@ import {
Min,
MinLength,
} from "class-validator";
import { AlbumType, TrackType } from "src/prisma/generated/client";
import { AlbumType, RipSource, TrackType } from "src/prisma/generated/client";
/**
* Extracted metadata from a track file
@@ -301,4 +301,9 @@ export default class Metadata {
@IsOptional()
@ApiPropertyOptional()
seriesMbid?: string;
@ApiProperty()
@IsEnum(RipSource)
@IsOptional()
ripSource?: RipSource;
}