major database optimisations
Signed-off-by: ari melody <ari@arimelody.me>
This commit is contained in:
parent
4f488d7bd8
commit
9f1a64b59b
|
@ -6,21 +6,34 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var ari = Artist{
|
var ari = Artist{
|
||||||
|
Id: "arimelody",
|
||||||
Name: "ari melody",
|
Name: "ari melody",
|
||||||
Website: "https://arimelody.me",
|
Website: "https://arimelody.me",
|
||||||
}
|
}
|
||||||
|
var mellodoot = Artist{
|
||||||
|
Id: "mellodoot",
|
||||||
|
Name: "mellodoot",
|
||||||
|
Website: "https://mellodoot.com",
|
||||||
|
}
|
||||||
var zaire = Artist{
|
var zaire = Artist{
|
||||||
|
Id: "zaire",
|
||||||
Name: "zaire",
|
Name: "zaire",
|
||||||
Website: "https://supitszaire.com",
|
Website: "https://supitszaire.com",
|
||||||
}
|
}
|
||||||
var mae = Artist{
|
var mae = Artist{
|
||||||
|
Id: "maetaylor",
|
||||||
Name: "mae taylor",
|
Name: "mae taylor",
|
||||||
Website: "https://mae.wtf",
|
Website: "https://mae.wtf",
|
||||||
}
|
}
|
||||||
var loudar = Artist{
|
var loudar = Artist{
|
||||||
|
Id: "loudar",
|
||||||
Name: "Loudar",
|
Name: "Loudar",
|
||||||
Website: "https://alex.targoninc.com",
|
Website: "https://alex.targoninc.com",
|
||||||
}
|
}
|
||||||
|
var red = Artist {
|
||||||
|
Id: "smoljorb",
|
||||||
|
Name: "smoljorb",
|
||||||
|
}
|
||||||
|
|
||||||
func make_date_work(date string) time.Time {
|
func make_date_work(date string) time.Time {
|
||||||
res, err := time.Parse("2-Jan-2006", date)
|
res, err := time.Parse("2-Jan-2006", date)
|
||||||
|
@ -35,7 +48,7 @@ var placeholders = []Album{
|
||||||
{
|
{
|
||||||
Id: "test",
|
Id: "test",
|
||||||
Title: "test album",
|
Title: "test album",
|
||||||
Type: "album",
|
// Type: "album",
|
||||||
ReleaseDate: make_date_work("18-Mar-2024"),
|
ReleaseDate: make_date_work("18-Mar-2024"),
|
||||||
Buyname: "go get it!!",
|
Buyname: "go get it!!",
|
||||||
Buylink: "https://arimelody.me/",
|
Buylink: "https://arimelody.me/",
|
||||||
|
@ -45,7 +58,8 @@ var placeholders = []Album{
|
||||||
Url: "https://youtu.be/dQw4w9WgXcQ",
|
Url: "https://youtu.be/dQw4w9WgXcQ",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Description: "she sample on my text 'til i 🚫🚫🚫",
|
Description:
|
||||||
|
`Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas viverra ligula interdum, tempor metus venenatis, tempus est. Praesent semper vulputate nulla, a venenatis libero elementum id. Proin maximus aliquet accumsan. Integer eu orci congue, ultrices leo sed, maximus risus. Integer laoreet non urna non accumsan. Cras ut sollicitudin justo. Vivamus eu orci tempus, aliquet est rhoncus, tempus neque. Aliquam tempor sit amet nibh sed tempus. Nulla vitae bibendum purus. Sed in mi enim. Nam pharetra enim lorem, vel tristique diam malesuada a. Duis dignissim nunc mi, id semper ex tincidunt a. Sed laoreet consequat lacus a consectetur. Nulla est diam, tempus eget lacus ullamcorper, tincidunt faucibus ex. Duis consectetur felis sit amet ante fermentum interdum. Sed pulvinar laoreet tellus.`,
|
||||||
Credits: []AlbumCredit{
|
Credits: []AlbumCredit{
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &ari,
|
||||||
|
@ -190,15 +204,15 @@ var placeholders = []Album{
|
||||||
Description: "living the dream 🌌 ✨",
|
Description: "living the dream 🌌 ✨",
|
||||||
Credits: []AlbumCredit{
|
Credits: []AlbumCredit{
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "vocals",
|
Role: "vocals",
|
||||||
},
|
},
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "production",
|
Role: "production",
|
||||||
},
|
},
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "artwork",
|
Role: "artwork",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -258,15 +272,15 @@ var placeholders = []Album{
|
||||||
Description: "hey! go my way! 💥 ✨",
|
Description: "hey! go my way! 💥 ✨",
|
||||||
Credits: []AlbumCredit{
|
Credits: []AlbumCredit{
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "vocals",
|
Role: "vocals",
|
||||||
},
|
},
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "production",
|
Role: "production",
|
||||||
},
|
},
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "artwork",
|
Role: "artwork",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -299,15 +313,15 @@ var placeholders = []Album{
|
||||||
Description: "let's take a trip. i've got a goddamn boat ⛵️",
|
Description: "let's take a trip. i've got a goddamn boat ⛵️",
|
||||||
Credits: []AlbumCredit{
|
Credits: []AlbumCredit{
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "vocals",
|
Role: "vocals",
|
||||||
},
|
},
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "production",
|
Role: "production",
|
||||||
},
|
},
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "artwork",
|
Role: "artwork",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -340,15 +354,15 @@ var placeholders = []Album{
|
||||||
Description: "we'll dawn a new frontier! 👾",
|
Description: "we'll dawn a new frontier! 👾",
|
||||||
Credits: []AlbumCredit{
|
Credits: []AlbumCredit{
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "vocals",
|
Role: "vocals",
|
||||||
},
|
},
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "production",
|
Role: "production",
|
||||||
},
|
},
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "artwork",
|
Role: "artwork",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -379,7 +393,7 @@ var placeholders = []Album{
|
||||||
Role: "production",
|
Role: "production",
|
||||||
},
|
},
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "production",
|
Role: "production",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -411,11 +425,11 @@ var placeholders = []Album{
|
||||||
},
|
},
|
||||||
Credits: []AlbumCredit{
|
Credits: []AlbumCredit{
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "production",
|
Role: "production",
|
||||||
},
|
},
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "artwork",
|
Role: "artwork",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -447,15 +461,15 @@ var placeholders = []Album{
|
||||||
},
|
},
|
||||||
Credits: []AlbumCredit{
|
Credits: []AlbumCredit{
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "vocals",
|
Role: "vocals",
|
||||||
},
|
},
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "production",
|
Role: "production",
|
||||||
},
|
},
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "artwork",
|
Role: "artwork",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -487,11 +501,11 @@ var placeholders = []Album{
|
||||||
},
|
},
|
||||||
Credits: []AlbumCredit{
|
Credits: []AlbumCredit{
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "production",
|
Role: "production",
|
||||||
},
|
},
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "artwork",
|
Role: "artwork",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -533,9 +547,14 @@ var placeholders = []Album{
|
||||||
},
|
},
|
||||||
Credits: []AlbumCredit{
|
Credits: []AlbumCredit{
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "production",
|
Role: "production",
|
||||||
},
|
},
|
||||||
|
AlbumCredit{
|
||||||
|
Artist: &red,
|
||||||
|
Role: "artwork",
|
||||||
|
Meta: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -558,9 +577,14 @@ var placeholders = []Album{
|
||||||
},
|
},
|
||||||
Credits: []AlbumCredit{
|
Credits: []AlbumCredit{
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "production",
|
Role: "production",
|
||||||
},
|
},
|
||||||
|
AlbumCredit{
|
||||||
|
Artist: &red,
|
||||||
|
Role: "artwork",
|
||||||
|
Meta: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -584,11 +608,11 @@ var placeholders = []Album{
|
||||||
Description: "an 8-bit expedition! ⚔️🛡️",
|
Description: "an 8-bit expedition! ⚔️🛡️",
|
||||||
Credits: []AlbumCredit{
|
Credits: []AlbumCredit{
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "production",
|
Role: "production",
|
||||||
},
|
},
|
||||||
AlbumCredit{
|
AlbumCredit{
|
||||||
Artist: &ari,
|
Artist: &mellodoot,
|
||||||
Role: "artwork",
|
Role: "artwork",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -609,6 +633,6 @@ func QueryAllAlbums() ([]Album) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func QueryAllArtists() ([]Artist) {
|
func QueryAllArtists() ([]Artist) {
|
||||||
return []Artist{ ari, zaire, mae, loudar }
|
return []Artist{ ari, mellodoot, zaire, mae, loudar, red }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
type (
|
type (
|
||||||
Artist struct {
|
Artist struct {
|
||||||
|
Id string;
|
||||||
Name string;
|
Name string;
|
||||||
Website string;
|
Website string;
|
||||||
}
|
}
|
||||||
|
@ -34,6 +35,7 @@ type (
|
||||||
AlbumCredit struct {
|
AlbumCredit struct {
|
||||||
Artist *Artist;
|
Artist *Artist;
|
||||||
Role string;
|
Role string;
|
||||||
|
Meta bool; // for "meta" contributors (i.e. not credited for the musical work, but other related assets)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -63,36 +65,88 @@ func (album Album) GetUniqueArtists() []Artist {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func (album Album) PrintArtists() string {
|
func (album Album) GetUniqueNonMetaArtists() []Artist {
|
||||||
artists := album.GetUniqueArtists()
|
if len(album.Credits) == 1 {
|
||||||
if len(artists) == 1 {
|
return []Artist{ *album.Credits[0].Artist }
|
||||||
return artists[0].Name
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create a map of artists to prevent duplicates
|
||||||
|
res := []Artist{}
|
||||||
|
for _, credit := range album.Credits {
|
||||||
|
if credit.Meta {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
artist := *credit.Artist
|
||||||
|
exists := false
|
||||||
|
for _, c := range res {
|
||||||
|
if c == *credit.Artist {
|
||||||
|
exists = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if exists {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
res = append(res, artist)
|
||||||
|
}
|
||||||
|
|
||||||
|
// now create the actual array to send
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (album Album) GetUniqueArtistNames() []string {
|
||||||
|
if len(album.Credits) == 1 {
|
||||||
|
return []string{ album.Credits[0].Artist.Name }
|
||||||
|
}
|
||||||
|
|
||||||
|
artists := album.GetUniqueArtists()
|
||||||
names := []string{}
|
names := []string{}
|
||||||
for _, artist := range artists {
|
for _, artist := range artists {
|
||||||
names = append(names, artist.Name)
|
names = append(names, artist.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (album Album) GetUniqueNonMetaArtistNames() []string {
|
||||||
|
if len(album.Credits) == 1 {
|
||||||
|
return []string{ album.Credits[0].Artist.Name }
|
||||||
|
}
|
||||||
|
|
||||||
|
artists := album.GetUniqueNonMetaArtists()
|
||||||
|
names := []string{}
|
||||||
|
for _, artist := range artists {
|
||||||
|
names = append(names, artist.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (album Album) PrintPrimaryArtists() string {
|
||||||
|
names := album.GetUniqueNonMetaArtistNames();
|
||||||
|
if len(names) == 1 {
|
||||||
|
return names[0]
|
||||||
|
}
|
||||||
res := strings.Join(names[:len(names) - 1], ", ")
|
res := strings.Join(names[:len(names) - 1], ", ")
|
||||||
res += " & " + names[len(names) - 1]
|
res += " & " + names[len(names) - 1]
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func (album Album) PrintCommaArtists() string {
|
func (album Album) PrintCommaPrimaryArtists() string {
|
||||||
if len(album.Credits) == 1 {
|
names := album.GetUniqueNonMetaArtistNames();
|
||||||
return album.Credits[0].Artist.Name
|
if len(names) == 1 {
|
||||||
|
return names[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
artists := album.GetUniqueArtists()
|
|
||||||
names := []string{}
|
|
||||||
for _, artist := range artists {
|
|
||||||
names = append(names, artist.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.Join(names[:len(names)], ", ")
|
return strings.Join(names[:len(names)], ", ")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (album Album) ResolveType() string {
|
||||||
|
if album.Type != "" {
|
||||||
|
return album.Type
|
||||||
|
}
|
||||||
|
return "unknown"
|
||||||
|
}
|
||||||
|
|
||||||
func (album Album) ResolveArtwork() string {
|
func (album Album) ResolveArtwork() string {
|
||||||
if album.Artwork != "" {
|
if album.Artwork != "" {
|
||||||
return album.Artwork
|
return album.Artwork
|
||||||
|
|
132
db.go
132
db.go
|
@ -13,126 +13,67 @@ import (
|
||||||
|
|
||||||
var schema =
|
var schema =
|
||||||
`CREATE TABLE IF NOT EXISTS Artists (
|
`CREATE TABLE IF NOT EXISTS Artists (
|
||||||
id SERIAL primary key,
|
id TEXT PRIMARY KEY,
|
||||||
name text,
|
name TEXT,
|
||||||
website text
|
website TEXT
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS Albums (
|
CREATE TABLE IF NOT EXISTS Albums (
|
||||||
id varchar(64) primary key,
|
id VARCHAR(64) PRIMARY KEY,
|
||||||
title text not null,
|
title TEXT NOT NULL,
|
||||||
release_date date not null,
|
type TEXT,
|
||||||
artwork text,
|
release_date DATE NOT NULL,
|
||||||
buyname text,
|
artwork TEXT,
|
||||||
buylink text,
|
buyname TEXT,
|
||||||
description text,
|
buylink TEXT,
|
||||||
lyrics text
|
description TEXT,
|
||||||
|
lyrics TEXT
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS AlbumLinks (
|
CREATE TABLE IF NOT EXISTS AlbumLinks (
|
||||||
album varchar(64) references Albums(id) on delete cascade,
|
album VARCHAR(64) REFERENCES Albums(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
name text,
|
name TEXT,
|
||||||
url text,
|
url TEXT,
|
||||||
constraint albumlinks_pk primary key (album, name)
|
CONSTRAINT albumlinks_pk PRIMARY KEY (album, name)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS AlbumCredits (
|
CREATE TABLE IF NOT EXISTS AlbumCredits (
|
||||||
album varchar(64) references Albums(id) on delete cascade,
|
album VARCHAR(64) REFERENCES Albums(ID) ON DELETE CASCADE,
|
||||||
artist int references Artists(id) on delete cascade,
|
artist TEXT REFERENCES Artists(id) ON DELETE CASCADE,
|
||||||
role text
|
role TEXT,
|
||||||
constraint albumcredits_pk primary key (album, artist, role)
|
meta BOOLEAN,
|
||||||
|
constraint albumcredits_pk PRIMARY KEY (album, artist, role)
|
||||||
);`
|
);`
|
||||||
|
|
||||||
func PushArtist(db *sqlx.DB, artist music.Artist) {
|
func PushArtist(db *sqlx.DB, artist music.Artist) {
|
||||||
query := "SELECT count(*) FROM Artists WHERE name=$1"
|
fmt.Printf("syncing artist [%s] to database...", artist.Name)
|
||||||
var count int
|
|
||||||
err := db.Get(&count, query, artist.Name)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("error while pushing artist [%s] to the database: %v\n", artist.Name, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
query = "INSERT INTO artists (name, website) VALUES ($1, $2)"
|
db.MustExec("INSERT INTO artists (id, name, website) VALUES ($1, $2, $3) ON CONFLICT (id) DO UPDATE SET name=$2, website=$3",
|
||||||
if count != 0 {
|
&artist.Id,
|
||||||
query = "UPDATE artists SET website=$2 WHERE name=$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("saving artist [%s] to the database...", artist.Name)
|
|
||||||
_, err = db.Exec(query,
|
|
||||||
&artist.Name,
|
&artist.Name,
|
||||||
&artist.Website,
|
&artist.Website,
|
||||||
)
|
)
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("error while pushing artist [%s] to the database: %v\n", artist.Name, err)
|
|
||||||
}
|
|
||||||
fmt.Printf("done!\n")
|
fmt.Printf("done!\n")
|
||||||
|
|
||||||
// defer db.Close()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func PushAlbum(db *sqlx.DB, album music.Album) {
|
func PushAlbum(db *sqlx.DB, album music.Album) {
|
||||||
var count int
|
fmt.Printf("syncing album [%s] to database...", album.Id)
|
||||||
err := db.Get(&count, "SELECT count(*) FROM Albums WHERE id=$1", album.Id)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("error while pushing album [%s] to the database: %v\n", album.Id, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
artist_ids := map[string]int{};
|
|
||||||
for _, credit := range album.Credits {
|
|
||||||
if _, ok := artist_ids[credit.Artist.Name]; ok {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var id int
|
|
||||||
err := db.Get(&id, "SELECT id FROM Artists WHERE name=$1", credit.Artist.Name)
|
|
||||||
if err != nil {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
artist_ids[credit.Artist.Name] = id
|
|
||||||
}
|
|
||||||
|
|
||||||
if count == 0 {
|
|
||||||
fmt.Printf("creating album [%s]...", album.Id)
|
|
||||||
|
|
||||||
tx := db.MustBegin()
|
|
||||||
tx.MustExec("INSERT INTO Albums VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", &album.Id, &album.Title, album.ReleaseDate.Format("2-Jan-2006"), &album.Artwork, &album.Buyname, &album.Buylink, &album.Description, &album.Lyrics)
|
|
||||||
for _, link := range album.Links {
|
|
||||||
tx.MustExec("INSERT INTO AlbumLinks (album, name, url) VALUES ($1, $2, $3)", &album.Id, &link.Name, &link.Url)
|
|
||||||
}
|
|
||||||
for _, credit := range album.Credits {
|
|
||||||
artist_id := artist_ids[credit.Artist.Name]
|
|
||||||
tx.MustExec("INSERT INTO AlbumCredits (album, artist, role) VALUES ($1, $2, $3)", &album.Id, &artist_id, &credit.Role)
|
|
||||||
}
|
|
||||||
tx.Commit()
|
|
||||||
|
|
||||||
fmt.Printf("done!\n")
|
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("updating album [%s]...", album.Id)
|
|
||||||
|
|
||||||
tx := db.MustBegin()
|
tx := db.MustBegin()
|
||||||
tx.MustExec("UPDATE Albums SET title=$2, release_date=$3, artwork=$4, buyname=$5, buylink=$6, description=$7, lyrics=$8 WHERE id=$1",
|
tx.MustExec("INSERT INTO albums (id, title, release_date, artwork, buyname, buylink, description, lyrics) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) "+
|
||||||
&album.Id,
|
"ON CONFLICT (id) DO UPDATE SET title=$2, release_date=$3, artwork=$4, buyname=$5, buylink=$6, description=$7, lyrics=$8",
|
||||||
&album.Title,
|
&album.Id, &album.Title, album.ReleaseDate.Format("2-Jan-2006"), &album.Artwork, &album.Buyname, &album.Buylink, &album.Description, &album.Lyrics)
|
||||||
album.ReleaseDate.Format("2-Jan-2006"),
|
|
||||||
&album.Artwork,
|
|
||||||
&album.Buyname,
|
|
||||||
&album.Buylink,
|
|
||||||
&album.Description,
|
|
||||||
&album.Lyrics,
|
|
||||||
)
|
|
||||||
// we're just gonna completely fresh them because
|
|
||||||
// like hell am i actually gonna comb through every
|
|
||||||
// single one of these
|
|
||||||
tx.MustExec("DELETE FROM AlbumLinks WHERE album=$1", &album.Id)
|
|
||||||
tx.MustExec("DELETE FROM AlbumCredits WHERE album=$1", &album.Id)
|
|
||||||
for _, link := range album.Links {
|
for _, link := range album.Links {
|
||||||
tx.MustExec("INSERT INTO AlbumLinks (album, name, url) VALUES ($1, $2, $3)", &album.Id, &link.Name, &link.Url)
|
tx.MustExec("INSERT INTO albumlinks (album, name, url) VALUES ($1, $2, $3) ON CONFLICT (album, name) DO UPDATE SET url=$3",
|
||||||
|
&album.Id, &link.Name, &link.Url)
|
||||||
}
|
}
|
||||||
for _, credit := range album.Credits {
|
for _, credit := range album.Credits {
|
||||||
artist_id := artist_ids[credit.Artist.Name]
|
tx.MustExec("INSERT INTO albumcredits (album, artist, role, meta) VALUES ($1, $2, $3, $4) ON CONFLICT DO NOTHING",
|
||||||
tx.MustExec("INSERT INTO AlbumCredits (album, artist, role) VALUES ($1, $2, $3)", &album.Id, &artist_id, &credit.Role)
|
&album.Id, &credit.Artist.Id, &credit.Role, &credit.Meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
tx.Commit()
|
tx.Commit()
|
||||||
|
|
||||||
fmt.Printf("done!\n")
|
fmt.Printf("done!\n")
|
||||||
|
@ -149,7 +90,8 @@ func InitDatabase() *sqlx.DB {
|
||||||
db.SetMaxOpenConns(10)
|
db.SetMaxOpenConns(10)
|
||||||
db.SetMaxIdleConns(10)
|
db.SetMaxIdleConns(10)
|
||||||
|
|
||||||
// db.MustExec(schema)
|
db.MustExec(schema)
|
||||||
|
fmt.Printf("database schema synchronised.\n")
|
||||||
|
|
||||||
return db
|
return db
|
||||||
}
|
}
|
||||||
|
|
2
main.go
2
main.go
|
@ -17,7 +17,7 @@ import (
|
||||||
"github.com/gomarkdown/markdown/parser"
|
"github.com/gomarkdown/markdown/parser"
|
||||||
)
|
)
|
||||||
|
|
||||||
const PORT int = 8080
|
const PORT int = 8081
|
||||||
|
|
||||||
var mime_types = map[string]string{
|
var mime_types = map[string]string{
|
||||||
"css": "text/css; charset=utf-8",
|
"css": "text/css; charset=utf-8",
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import "./header.js";
|
import "./header.js";
|
||||||
|
import "./accessibility.js";
|
||||||
|
|
||||||
function type_out(e) {
|
function type_out(e) {
|
||||||
const text = e.innerText;
|
const text = e.innerText;
|
||||||
|
|
|
@ -28,6 +28,16 @@ function apply_funny_bob_to_upcoming_tags() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.querySelectorAll("div#extras ul li a[href]").forEach(link => {
|
||||||
|
link.addEventListener("click", event => {
|
||||||
|
event.preventDefault();
|
||||||
|
location.replace(link.href);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* handling track previews (currently not implemented)
|
||||||
|
|
||||||
const previews = document.querySelectorAll("[id^=preview-]");
|
const previews = document.querySelectorAll("[id^=preview-]");
|
||||||
for (const preview of previews) {
|
for (const preview of previews) {
|
||||||
preview.addEventListener("click", (e) => {
|
preview.addEventListener("click", (e) => {
|
||||||
|
@ -67,3 +77,5 @@ function stopPreview(preview) {
|
||||||
}
|
}
|
||||||
|
|
||||||
stopPreviews();
|
stopPreviews();
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
|
@ -332,28 +332,43 @@ div#info {
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul#extras {
|
div#extras ul {
|
||||||
list-style: none;
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
gap: .6em;
|
gap: .6em;
|
||||||
|
list-style: none;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-evenly;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul#extras li a {
|
div#extras ul li a {
|
||||||
color: #888;
|
color: #888;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
writing-mode: vertical-rl;
|
||||||
|
transition: color .1s linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#extras ul li a:hover {
|
||||||
|
color: #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
div#info > div {
|
div#info > div {
|
||||||
max-height: 360px;
|
max-height: 360px;
|
||||||
min-height: 360px;
|
min-height: 360px;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
padding: 2rem 4rem;
|
padding: 2rem 1rem 2rem 4rem;
|
||||||
margin: -2rem -4rem;
|
margin: -2rem -3.5rem -2rem -4rem;
|
||||||
mask-image: linear-gradient(to bottom, transparent 0%, black 10%, black 90%, transparent 100%);
|
mask-image: linear-gradient(to bottom, transparent 0%, black 10%, black 90%, transparent 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div#info p {
|
||||||
|
max-width: 500px;
|
||||||
|
white-space: pre-line;
|
||||||
|
}
|
||||||
|
|
||||||
a.scrollback {
|
a.scrollback {
|
||||||
color: #888;
|
color: #888;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
@ -367,11 +382,6 @@ a.scrollback {
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
#lyrics p {
|
|
||||||
max-width: 500px;
|
|
||||||
white-space: pre-line;
|
|
||||||
}
|
|
||||||
|
|
||||||
#share {
|
#share {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -481,12 +491,28 @@ footer a:hover {
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (min-width: 800px) {
|
@media only screen and (min-width: 800px) {
|
||||||
div#info:has(> #credits:target) {
|
div#music-container:has(:not(> div#info #credits:target):not(> div#info #credits:target)) {
|
||||||
transform: translateY(calc(-360px + -6rem));
|
div#extras ul li:first-of-type a {
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
div#info:has(> #lyrics:target) {
|
div#music-container:has(> div#info #credits:target) {
|
||||||
transform: translateY(calc((-360px + -6rem) * 2));
|
div#info {
|
||||||
|
transform: translateY(calc(-360px + -6rem));
|
||||||
|
}
|
||||||
|
div#extras ul li a[href="#credits"] {
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
div#music-container:has(> div#info #lyrics:target) {
|
||||||
|
div#info {
|
||||||
|
transform: translateY(calc((-360px + -6rem) * 2));
|
||||||
|
}
|
||||||
|
div#extras ul li a[href="#lyrics"] {
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,7 +558,7 @@ footer a:hover {
|
||||||
mask-image: none;
|
mask-image: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
a.scrollback {
|
div#extras {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
<link rel="stylesheet" href="style/index.css">
|
<link rel="stylesheet" href="style/index.css">
|
||||||
|
|
||||||
<script type="module" src="/script/main.js" defer></script>
|
<script type="module" src="/script/main.js" defer></script>
|
||||||
<script type="application/javascript" src="/script/accessibility.js" defer></script>
|
|
||||||
<link rel="me" href="https://wetdry.world/@ari">
|
<link rel="me" href="https://wetdry.world/@ari">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -6,19 +6,19 @@
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
<title>{{.PrintArtists}} - {{.Title}}</title>
|
<title>{{.PrintPrimaryArtists}} - {{.Title}}</title>
|
||||||
<link rel="icon" href="{{.ResolveArtwork}}">
|
<link rel="icon" href="{{.ResolveArtwork}}">
|
||||||
|
|
||||||
<meta name="description" content="Stream "{{.Title}}" by {{.PrintArtists}} on all platforms!">
|
<meta name="description" content="Stream "{{.Title}}" by {{.PrintPrimaryArtists}} on all platforms!">
|
||||||
<meta name="author" content="{{.PrintArtists}}">
|
<meta name="author" content="{{.PrintPrimaryArtists}}">
|
||||||
<meta name="keywords" content="{{.PrintCommaArtists}}, music, {{.Title}}, {{.Id}}, {{.GetReleaseYear}}">
|
<meta name="keywords" content="{{.PrintCommaPrimaryArtists}}, music, {{.Title}}, {{.Id}}, {{.GetReleaseYear}}">
|
||||||
|
|
||||||
<meta property="og:url" content="https://arimelody.me/music/{{.Id}}">
|
<meta property="og:url" content="https://arimelody.me/music/{{.Id}}">
|
||||||
<meta property="og:type" content="website">
|
<meta property="og:type" content="website">
|
||||||
<meta property="og:locale" content="en_IE">
|
<meta property="og:locale" content="en_IE">
|
||||||
<meta property="og:site_name" content="ari melody music">
|
<meta property="og:site_name" content="ari melody music">
|
||||||
<meta property="og.Title" content="{{.PrintArtists}} - {{.Title}}">
|
<meta property="og.Title" content="{{.PrintPrimaryArtists}} - {{.Title}}">
|
||||||
<meta property="og:description" content="Stream "{{.Title}}" by {{.PrintArtists}} on all platforms!">
|
<meta property="og:description" content="Stream "{{.Title}}" by {{.PrintPrimaryArtists}} on all platforms!">
|
||||||
<meta property="og:image" content="https://arimelody.me{{.ResolveArtwork}}">
|
<meta property="og:image" content="https://arimelody.me{{.ResolveArtwork}}">
|
||||||
|
|
||||||
<meta name="twitter:card" content="summary_large_image">
|
<meta name="twitter:card" content="summary_large_image">
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
<meta name="twitter:creator" content="@funniduck">
|
<meta name="twitter:creator" content="@funniduck">
|
||||||
<meta property="twitter:domain" content="arimelody.me">
|
<meta property="twitter:domain" content="arimelody.me">
|
||||||
<meta property="twitter:url" content="https://arimelody.me/music/{{.Id}}">
|
<meta property="twitter:url" content="https://arimelody.me/music/{{.Id}}">
|
||||||
<meta name="twitter.Title" content="{{.PrintArtists}} - {{.Title}}">
|
<meta name="twitter.Title" content="{{.PrintPrimaryArtists}} - {{.Title}}">
|
||||||
<meta name="twitter:description" content="Stream "{{.Title}}" by mellodoot on all platforms!">
|
<meta name="twitter:description" content="Stream "{{.Title}}" by mellodoot on all platforms!">
|
||||||
<meta name="twitter:image" content="https://arimelody.me{{.ResolveArtwork}}">
|
<meta name="twitter:image" content="https://arimelody.me{{.ResolveArtwork}}">
|
||||||
<meta name="twitter:image:alt" content="Cover art for "{{.Title}}"">
|
<meta name="twitter:image:alt" content="Cover art for "{{.Title}}"">
|
||||||
|
@ -63,23 +63,13 @@
|
||||||
<h1 id="title">{{.Title}}</h1>
|
<h1 id="title">{{.Title}}</h1>
|
||||||
<span id="year">{{.GetReleaseYear}}</span>
|
<span id="year">{{.GetReleaseYear}}</span>
|
||||||
</div>
|
</div>
|
||||||
<p id="artist">{{.PrintArtists}}</p>
|
<p id="artist">{{.PrintPrimaryArtists}}</p>
|
||||||
<p id="type" class="{{.Type}}">{{.Type}}</p>
|
<p id="type" class="{{.ResolveType}}">{{.ResolveType}}</p>
|
||||||
|
|
||||||
{{if .Description}}
|
|
||||||
<p id="description">
|
|
||||||
{{.Description}}
|
|
||||||
</p>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
<div id="links">
|
<div id="links">
|
||||||
{{if .Buylink}}
|
{{if .Buylink}}
|
||||||
<a href="{{.Buylink}}" target="_blank" class="buy">
|
<a href="{{.Buylink}}" target="_blank" class="buy">
|
||||||
{{if .Buyname}}
|
{{if .Buyname}}{{.Buyname}}{{else}}buy{{end}}
|
||||||
{{.Buyname}}
|
|
||||||
{{else}}
|
|
||||||
buy
|
|
||||||
{{end}}
|
|
||||||
</a>
|
</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
@ -90,16 +80,10 @@
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{if or .Credits .Lyrics}}
|
{{if .Description}}
|
||||||
<ul id="extras">
|
<p id="description">
|
||||||
{{if .Credits}}
|
{{.Description}}
|
||||||
<li><a href="#credits">credits</a></li>
|
</p>
|
||||||
{{end}}
|
|
||||||
|
|
||||||
{{if .Lyrics}}
|
|
||||||
<li><a href="#lyrics">lyrics</a></li>
|
|
||||||
{{end}}
|
|
||||||
</ul>
|
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
<p id="share">share</p>
|
<p id="share">share</p>
|
||||||
|
@ -107,12 +91,15 @@
|
||||||
|
|
||||||
{{if .Credits}}
|
{{if .Credits}}
|
||||||
<div id="credits">
|
<div id="credits">
|
||||||
<a href="#" class="scrollback">go back</a>
|
|
||||||
<h2>credits:</h2>
|
<h2>credits:</h2>
|
||||||
<ul>
|
<ul>
|
||||||
{{range .Credits}}
|
{{range .Credits}}
|
||||||
{{$Artist := .ResolveArtist}}
|
{{$Artist := .ResolveArtist}}
|
||||||
<li><strong><a href="{{$Artist.Website}}">{{$Artist.Name}}</a></strong>: {{.Role}}</li>
|
{{if $Artist.Website}}
|
||||||
|
<li><strong><a href="{{$Artist.Website}}">{{$Artist.Name}}</a></strong>: {{.Role}}</li>
|
||||||
|
{{else}}
|
||||||
|
<li><strong>{{$Artist.Name}}</strong>: {{.Role}}</li>
|
||||||
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -120,12 +107,27 @@
|
||||||
|
|
||||||
{{if .Lyrics}}
|
{{if .Lyrics}}
|
||||||
<div id="lyrics">
|
<div id="lyrics">
|
||||||
<a href="#" class="scrollback">go back</a>
|
|
||||||
<h2>lyrics:</h2>
|
<h2>lyrics:</h2>
|
||||||
<p>{{.Lyrics}}</p>
|
<p>{{.Lyrics}}</p>
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{if or .Credits .Lyrics}}
|
||||||
|
<div id="extras">
|
||||||
|
<ul>
|
||||||
|
<li><a href="#">overview</a></li>
|
||||||
|
|
||||||
|
{{if .Credits}}
|
||||||
|
<li><a href="#credits">credits</a></li>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{if .Lyrics}}
|
||||||
|
<li><a href="#lyrics">lyrics</a></li>
|
||||||
|
{{end}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
<!-- <div id="tracks"> -->
|
<!-- <div id="tracks"> -->
|
||||||
<!-- <% var file = `/audio/preview/${data.id}.webm` %> -->
|
<!-- <% var file = `/audio/preview/${data.id}.webm` %> -->
|
||||||
<!-- <% if (data.tracks && typeof(data.tracks) == typeof([])) { %> -->
|
<!-- <% if (data.tracks && typeof(data.tracks) == typeof([])) { %> -->
|
||||||
|
|
|
@ -78,8 +78,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="music-details">
|
<div class="music-details">
|
||||||
<a href="/music/{{$Album.Id}}"><h1 class="music-title">{{$Album.Title}}</h1></a>
|
<a href="/music/{{$Album.Id}}"><h1 class="music-title">{{$Album.Title}}</h1></a>
|
||||||
<h2 class="music-artist">{{$Album.PrintArtists}}</h2>
|
<h2 class="music-artist">{{$Album.PrintPrimaryArtists}}</h2>
|
||||||
<h3 class="music-type-{{.Type}}">{{$Album.Type}}</h3>
|
<h3 class="music-type-{{.ResolveType}}">{{$Album.ResolveType}}</h3>
|
||||||
<ul class="music-links">
|
<ul class="music-links">
|
||||||
{{range $Link := $Album.Links}}
|
{{range $Link := $Album.Links}}
|
||||||
<li>
|
<li>
|
||||||
|
|
Loading…
Reference in a new issue