WIP. A little custom music server
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

also parse musicbrainz bullshit

+38 -19
+19 -18
backend/src/file-parser.ts
··· 27 27 Stream.mapEffect((file) => parseFile(file), { 28 28 concurrency: 10, 29 29 }), 30 + Stream.tap(Console.log), 30 31 Stream.catchAll((err) => Stream.empty), 31 32 ); 32 33 ··· 34 35 }); 35 36 36 37 export const parseFile = Effect.fn("parse-file")(function* (path: string) { 37 - const extension = path.split(".").pop(); 38 - const assumedType = 39 - extension && SUPPORTED_EXTENSIONS.includes(extension as SupportedExtension) 40 - ? (extension as SupportedExtension) 41 - : null; 38 + const extension = path.split(".").pop(); 39 + const assumedType = 40 + extension && SUPPORTED_EXTENSIONS.includes(extension as SupportedExtension) 41 + ? (extension as SupportedExtension) 42 + : null; 42 43 43 - if (!assumedType) { 44 - return yield* Effect.fail(new UnsupportedFileError({ message: "File is unsupported" })); 45 - } 44 + if (!assumedType) { 45 + return yield* Effect.fail(new UnsupportedFileError({ message: "File is unsupported" })); 46 + } 46 47 47 - if (assumedType === "flac") { 48 + if (assumedType === "flac") { 49 + const flacService = yield* FlacService; 48 50 49 - const flacService = yield* FlacService; 50 - 51 - const isFlac = yield* flacService.isFlac(path); 52 - if (isFlac) { 53 - const metadata = yield* flacService.readMetadata(path); 51 + const isFlac = yield* flacService.isFlac(path); 52 + if (isFlac) { 53 + const metadata = yield* flacService.readMetadata(path); 54 54 55 - return metadata; 56 - } 55 + return metadata; 57 56 } 58 - return yield* Effect.fail(new UnsupportedFileError({ message: "File is unsupported" })); 59 - }); 57 + } 58 + return yield* Effect.fail(new UnsupportedFileError({ message: "File is unsupported" })); 59 + }); 60 +
+12 -1
backend/src/flac/transformers.ts
··· 99 99 metadata.trackNumber = parsedNumber.value; 100 100 } 101 101 break; 102 + 103 + case "MUSICBRAINZ_RELEASEGROUPID": 104 + metadata.musicBrainzReleaseGroupId = value; 105 + break; 106 + 107 + case "MUSICBRAINZ_ARTISTID": 108 + metadata.musicBrainzArtistId = value; 109 + break; 110 + 111 + case "MUSICBRAINZ_TRACKID": 112 + metadata.musicBrainzTrackId = value; 113 + break; 102 114 default: 103 115 continue; 104 116 } ··· 126 138 } 127 139 return { key: key.toUpperCase(), value }; 128 140 } 129 -
+7
backend/src/metadata.ts
··· 1 1 import { Schema } from "effect"; 2 2 3 + export const MusicbrainzSchema = Schema.Struct({ 4 + musicBrainzReleaseGroupId: Schema.optional(Schema.NonEmptyString), 5 + musicBrainzArtistId: Schema.optional(Schema.NonEmptyString), 6 + musicBrainzTrackId: Schema.optional(Schema.NonEmptyString), 7 + }); 8 + 3 9 export const MetadataSchema = Schema.Struct({ 4 10 album: Schema.NonEmptyString, 5 11 artists: Schema.Array(Schema.NonEmptyString), 6 12 albumArtist: Schema.optional(Schema.NonEmptyString), 7 13 title: Schema.NonEmptyString, 8 14 trackNumber: Schema.optional(Schema.Number), 15 + ...MusicbrainzSchema.fields, 9 16 }); 10 17 11 18 export const MetadataWithFilepathSchema = Schema.Struct({