tangled
alpha
login
or
join now
t1c.dev
/
rocksky
forked from
rocksky.app/rocksky
2
fork
atom
A decentralized music tracking and discovery platform built on AT Protocol 🎵
2
fork
atom
overview
issues
pulls
pipelines
Create songs and ensure entities on scrobble
tsiry-sandratraina.com
1 month ago
3576bd98
8406bf6c
+195
-1
1 changed file
expand all
collapse all
unified
split
apps
cli
src
cmd
sync.ts
+195
-1
apps/cli/src/cmd/sync.ts
···
624
624
) => {
625
625
const { title, artist, album } = record;
626
626
logger.info` New song: ${title} by ${artist} from ${album}`;
627
627
+
await createSongs(
628
628
+
[
629
629
+
{
630
630
+
cid,
631
631
+
uri,
632
632
+
value: record,
633
633
+
},
634
634
+
],
635
635
+
user,
636
636
+
);
627
637
};
628
638
629
639
const onNewAlbum = async (
···
672
682
uri: string,
673
683
user: SelectUser,
674
684
) => {
675
675
-
const { title, createdAt } = record;
685
685
+
const { title, createdAt, artist, album, albumArtist } = record;
676
686
logger.info` New scrobble: ${title} at ${createdAt}`;
687
687
+
688
688
+
// Check if the artist exists, create if not
689
689
+
let [artistRecord] = await ctx.db
690
690
+
.select()
691
691
+
.from(schema.artists)
692
692
+
.where(eq(schema.artists.name, record.albumArtist))
693
693
+
.execute();
694
694
+
695
695
+
if (!artistRecord) {
696
696
+
logger.info` ⚙️ Artist not found, creating: "${albumArtist}"`;
697
697
+
698
698
+
// Create a synthetic artist record from scrobble data
699
699
+
const artistUri = `at://${user.did}/app.rocksky.artist/${createId()}`;
700
700
+
const artistCid = createId();
701
701
+
702
702
+
await createArtists(
703
703
+
[
704
704
+
{
705
705
+
cid: artistCid,
706
706
+
uri: artistUri,
707
707
+
value: {
708
708
+
$type: "app.rocksky.artist",
709
709
+
name: record.albumArtist,
710
710
+
createdAt: new Date().toISOString(),
711
711
+
tags: record.tags || [],
712
712
+
} as Artist.Record,
713
713
+
},
714
714
+
],
715
715
+
user,
716
716
+
);
717
717
+
718
718
+
[artistRecord] = await ctx.db
719
719
+
.select()
720
720
+
.from(schema.artists)
721
721
+
.where(eq(schema.artists.name, record.albumArtist))
722
722
+
.execute();
723
723
+
724
724
+
if (!artistRecord) {
725
725
+
logger.error` ❌ Failed to create artist. Skipping scrobble.`;
726
726
+
return;
727
727
+
}
728
728
+
}
729
729
+
730
730
+
// Check if the album exists, create if not
731
731
+
let [albumRecord] = await ctx.db
732
732
+
.select()
733
733
+
.from(schema.albums)
734
734
+
.where(
735
735
+
and(
736
736
+
eq(schema.albums.title, record.album),
737
737
+
eq(schema.albums.artist, record.albumArtist),
738
738
+
),
739
739
+
)
740
740
+
.execute();
741
741
+
742
742
+
if (!albumRecord) {
743
743
+
logger.info` ⚙️ Album not found, creating: "${album}" by ${albumArtist}`;
744
744
+
745
745
+
// Create a synthetic album record from scrobble data
746
746
+
const albumUri = `at://${user.did}/app.rocksky.album/${createId()}`;
747
747
+
const albumCid = createId();
748
748
+
749
749
+
await createAlbums(
750
750
+
[
751
751
+
{
752
752
+
cid: albumCid,
753
753
+
uri: albumUri,
754
754
+
value: {
755
755
+
$type: "app.rocksky.album",
756
756
+
title: record.album,
757
757
+
artist: record.albumArtist,
758
758
+
createdAt: new Date().toISOString(),
759
759
+
releaseDate: record.releaseDate,
760
760
+
year: record.year,
761
761
+
albumArt: record.albumArt,
762
762
+
artistUri: artistRecord.uri,
763
763
+
spotifyLink: record.spotifyLink,
764
764
+
appleMusicLink: record.appleMusicLink,
765
765
+
tidalLink: record.tidalLink,
766
766
+
youtubeLink: record.youtubeLink,
767
767
+
} as Album.Record,
768
768
+
},
769
769
+
],
770
770
+
user,
771
771
+
);
772
772
+
773
773
+
// Fetch the newly created album
774
774
+
[albumRecord] = await ctx.db
775
775
+
.select()
776
776
+
.from(schema.albums)
777
777
+
.where(
778
778
+
and(
779
779
+
eq(schema.albums.title, record.album),
780
780
+
eq(schema.albums.artist, record.albumArtist),
781
781
+
),
782
782
+
)
783
783
+
.execute();
784
784
+
785
785
+
if (!albumRecord) {
786
786
+
logger.error` ❌ Failed to create album. Skipping scrobble.`;
787
787
+
return;
788
788
+
}
789
789
+
}
790
790
+
791
791
+
// Check if the track exists, create if not
792
792
+
let [track] = await ctx.db
793
793
+
.select()
794
794
+
.from(schema.tracks)
795
795
+
.where(
796
796
+
and(
797
797
+
eq(schema.tracks.title, record.title),
798
798
+
eq(schema.tracks.artist, record.artist),
799
799
+
eq(schema.tracks.album, record.album),
800
800
+
eq(schema.tracks.albumArtist, record.albumArtist),
801
801
+
),
802
802
+
)
803
803
+
.execute();
804
804
+
805
805
+
if (!track) {
806
806
+
logger.info` ⚙️ Track not found, creating: "${title}" by ${artist} from ${album}`;
807
807
+
808
808
+
// Create a synthetic track record from scrobble data
809
809
+
const trackUri = `at://${user.did}/app.rocksky.song/${createId()}`;
810
810
+
const trackCid = createId();
811
811
+
812
812
+
await createSongs(
813
813
+
[
814
814
+
{
815
815
+
cid: trackCid,
816
816
+
uri: trackUri,
817
817
+
value: {
818
818
+
$type: "app.rocksky.song",
819
819
+
title: record.title,
820
820
+
artist: record.artist,
821
821
+
albumArtist: record.albumArtist,
822
822
+
album: record.album,
823
823
+
duration: record.duration,
824
824
+
trackNumber: record.trackNumber,
825
825
+
discNumber: record.discNumber,
826
826
+
releaseDate: record.releaseDate,
827
827
+
year: record.year,
828
828
+
genre: record.genre,
829
829
+
tags: record.tags,
830
830
+
composer: record.composer,
831
831
+
lyrics: record.lyrics,
832
832
+
copyrightMessage: record.copyrightMessage,
833
833
+
albumArt: record.albumArt,
834
834
+
youtubeLink: record.youtubeLink,
835
835
+
spotifyLink: record.spotifyLink,
836
836
+
tidalLink: record.tidalLink,
837
837
+
appleMusicLink: record.appleMusicLink,
838
838
+
createdAt: new Date().toISOString(),
839
839
+
mbId: record.mbid,
840
840
+
label: record.label,
841
841
+
albumUri: albumRecord.uri,
842
842
+
artistUri: artistRecord.uri,
843
843
+
} as Song.Record,
844
844
+
},
845
845
+
],
846
846
+
user,
847
847
+
);
848
848
+
849
849
+
// Fetch the newly created track
850
850
+
[track] = await ctx.db
851
851
+
.select()
852
852
+
.from(schema.tracks)
853
853
+
.where(
854
854
+
and(
855
855
+
eq(schema.tracks.title, record.title),
856
856
+
eq(schema.tracks.artist, record.artist),
857
857
+
eq(schema.tracks.album, record.album),
858
858
+
eq(schema.tracks.albumArtist, record.albumArtist),
859
859
+
),
860
860
+
)
861
861
+
.execute();
862
862
+
863
863
+
if (!track) {
864
864
+
logger.error` ❌ Failed to create track. Skipping scrobble.`;
865
865
+
return;
866
866
+
}
867
867
+
}
868
868
+
869
869
+
logger.info` ✓ All required entities ready. Creating scrobble...`;
870
870
+
677
871
await createScrobbles(
678
872
[
679
873
{