diff --git a/api/v1/music/music.go b/api/v1/music/music.go index e85b6f5..6aecb61 100644 --- a/api/v1/music/music.go +++ b/api/v1/music/music.go @@ -1,638 +1,638 @@ package music import ( - "fmt" - "time" + "fmt" + "time" ) var ari = Artist{ - Id: "arimelody", - Name: "ari melody", - Website: "https://arimelody.me", + Id: "arimelody", + Name: "ari melody", + Website: "https://arimelody.me", } var mellodoot = Artist{ - Id: "mellodoot", - Name: "mellodoot", - Website: "https://mellodoot.com", + Id: "mellodoot", + Name: "mellodoot", + Website: "https://mellodoot.com", } var zaire = Artist{ - Id: "zaire", - Name: "zaire", - Website: "https://supitszaire.com", + Id: "zaire", + Name: "zaire", + Website: "https://supitszaire.com", } var mae = Artist{ - Id: "maetaylor", - Name: "mae taylor", - Website: "https://mae.wtf", + Id: "maetaylor", + Name: "mae taylor", + Website: "https://mae.wtf", } var loudar = Artist{ - Id: "loudar", - Name: "Loudar", - Website: "https://alex.targoninc.com", + Id: "loudar", + Name: "Loudar", + Website: "https://alex.targoninc.com", } var red = Artist { - Id: "smoljorb", - Name: "smoljorb", + Id: "smoljorb", + Name: "smoljorb", } func make_date_work(date string) time.Time { - res, err := time.Parse("2-Jan-2006", date) - if err != nil { - fmt.Printf("somehow we failed to parse %s! falling back to epoch :]\n", date) - return time.Unix(0, 0) - } - return res + res, err := time.Parse("2-Jan-2006", date) + if err != nil { + fmt.Printf("somehow we failed to parse %s! falling back to epoch :]\n", date) + return time.Unix(0, 0) + } + return res } var placeholders = []MusicRelease{ - { - Id: "test", - Title: "test album", - // Type: "album", - ReleaseDate: make_date_work("18-Mar-2024"), - Buyname: "go get it!!", - Buylink: "https://arimelody.me/", - Links: []MusicLink{ - { - Name: "youtube", - Url: "https://youtu.be/dQw4w9WgXcQ", - }, - }, - 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: []MusicCredit{ - { - Artist: &ari, - Role: "having the swag", - }, - { - Artist: &zaire, - Role: "having the swag", - }, - { - Artist: &mae, - Role: "having the swag", - }, - { - Artist: &loudar, - Role: "having the swag", - }, - }, - Lyrics: - `(call me when you fall asleep) - (all in, let me ride the wave) + { + Id: "test", + Title: "test album", + // Type: "album", + ReleaseDate: make_date_work("18-Mar-2024"), + Buyname: "go get it!!", + Buylink: "https://arimelody.me/", + Links: []MusicLink{ + { + Name: "youtube", + Url: "https://youtu.be/dQw4w9WgXcQ", + }, + }, + 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: []MusicCredit{ + { + Artist: &ari, + Role: "having the swag", + }, + { + Artist: &zaire, + Role: "having the swag", + }, + { + Artist: &mae, + Role: "having the swag", + }, + { + Artist: &loudar, + Role: "having the swag", + }, + }, + Lyrics: + `(call me when you fall asleep) + (all in, let me ride the wave) - (okay!) + (okay!) - call me - when you fall asleep - (fall asleep, call on me) - (oh babe, why don'cha) - yeah, it's how you feel - when the stars come out - (you're never gonna get it) - (while you've lost yourself in a rut) - all in - let me ride the wave - (i'm so stressed) - (i need to fly out of this place) - yeah, 'cause we can drift - 'til the break of dawn - (i think i'll be okay) - (if i can sleep today) + call me + when you fall asleep + (fall asleep, call on me) + (oh babe, why don'cha) + yeah, it's how you feel + when the stars come out + (you're never gonna get it) + (while you've lost yourself in a rut) + all in + let me ride the wave + (i'm so stressed) + (i need to fly out of this place) + yeah, 'cause we can drift + 'til the break of dawn + (i think i'll be okay) + (if i can sleep today) - (switch it up!) + (switch it up!) - slumber party at 2AM - could think of nothing more perfect - than a moonlight jam + slumber party at 2AM + could think of nothing more perfect + than a moonlight jam - yeah, i've got no sleep - but I'm free today - yeah you could even say - that i'm free2play + yeah, i've got no sleep + but I'm free today + yeah you could even say + that i'm free2play - you ain't here by my side - and i try to get by - with my head out the window - get a listen of this + you ain't here by my side + and i try to get by + with my head out the window + get a listen of this - the whispers of the trees - the crickets do be chirpin' - i guess that's how it goes + the whispers of the trees + the crickets do be chirpin' + i guess that's how it goes - (call me when you fall asleep) - (all in, let me ride the wave) + (call me when you fall asleep) + (all in, let me ride the wave) - (let's go!) + (let's go!) - call me - when you fall asleep - (fall asleep, call on me) - (oh babe, why don'cha) - yeah, it's how you feel - when the stars come out - (you're never gonna get it) - (while you've lost yourself in a rut) - all in - let me ride the wave - (i'm so stressed) - (i need to fly out of this place) - yeah, 'cause we can drift - 'til the break of dawn - (i think i'll be okay) - (if i can sleep today) + call me + when you fall asleep + (fall asleep, call on me) + (oh babe, why don'cha) + yeah, it's how you feel + when the stars come out + (you're never gonna get it) + (while you've lost yourself in a rut) + all in + let me ride the wave + (i'm so stressed) + (i need to fly out of this place) + yeah, 'cause we can drift + 'til the break of dawn + (i think i'll be okay) + (if i can sleep today) - yeah... woo! - (BASS) - oh man... - i'm just sitting here - feeling the breeze - hanging out - listening to the crickets - and the trees in the breeze - living my best life`, - }, - // { - // Id: "free2play", - // Title: "free2play", - // Type: "upcoming", - // ReleaseDate: make_date_work("17-Mar-2024"), - // Buyname: "pre-order", - // Buylink: "https://arimelody.me/", - // Description: "hello from your local SPACEGIRL! 💫", - // Credits: []AlbumCredit{ - // AlbumCredit{ - // Artist: &ari, - // Role: "vocals", - // }, - // AlbumCredit{ - // Artist: &ari, - // Role: "production", - // }, - // AlbumCredit{ - // Artist: &ari, - // Role: "artwork", - // }, - // }, - // }, - { - Id: "dream", - Title: "Dream", - Type: "single", - ReleaseDate: make_date_work("11-Nov-2022"), - Artwork: "https://mellodoot.com/img/music_artwork/mellodoot_-_Dream.webp", - Buylink: "https://arimelody.bandcamp.com/track/dream", - Links: []MusicLink{ - { - Name: "spotify", - Url: "https://open.spotify.com/album/5talRpqzjExP1w6j5LFIAh", - }, - { - Name: "apple music", - Url: "https://music.apple.com/ie/album/dream-single/1650037132", - }, - { - Name: "soundcloud", - Url: "https://soundcloud.com/arimelody/dream2022", - }, - { - Name: "youtube", - Url: "https://www.youtube.com/watch?v=nfFgtMuYAx8", - }, - }, - Description: "living the dream 🌌 ✨", - Credits: []MusicCredit{ - { - Artist: &mellodoot, - Role: "vocals", - }, - { - Artist: &mellodoot, - Role: "production", - }, - { - Artist: &mellodoot, - Role: "artwork", - }, - }, - Lyrics: - `the truth is what you make of it - in the end, what you spend, is the end of it - when you're lost in the life - the life that you created on your own - i'm becoming one - with the soul that i see in the mirror - blending one and whole - this time, i'm real + yeah... woo! + (BASS) + oh man... + i'm just sitting here + feeling the breeze + hanging out + listening to the crickets + and the trees in the breeze + living my best life`, + }, + // { + // Id: "free2play", + // Title: "free2play", + // Type: "upcoming", + // ReleaseDate: make_date_work("17-Mar-2024"), + // Buyname: "pre-order", + // Buylink: "https://arimelody.me/", + // Description: "hello from your local SPACEGIRL! 💫", + // Credits: []AlbumCredit{ + // AlbumCredit{ + // Artist: &ari, + // Role: "vocals", + // }, + // AlbumCredit{ + // Artist: &ari, + // Role: "production", + // }, + // AlbumCredit{ + // Artist: &ari, + // Role: "artwork", + // }, + // }, + // }, + { + Id: "dream", + Title: "Dream", + Type: "single", + ReleaseDate: make_date_work("11-Nov-2022"), + Artwork: "https://mellodoot.com/img/music_artwork/mellodoot_-_Dream.webp", + Buylink: "https://arimelody.bandcamp.com/track/dream", + Links: []MusicLink{ + { + Name: "spotify", + Url: "https://open.spotify.com/album/5talRpqzjExP1w6j5LFIAh", + }, + { + Name: "apple music", + Url: "https://music.apple.com/ie/album/dream-single/1650037132", + }, + { + Name: "soundcloud", + Url: "https://soundcloud.com/arimelody/dream2022", + }, + { + Name: "youtube", + Url: "https://www.youtube.com/watch?v=nfFgtMuYAx8", + }, + }, + Description: "living the dream 🌌 ✨", + Credits: []MusicCredit{ + { + Artist: &mellodoot, + Role: "vocals", + }, + { + Artist: &mellodoot, + Role: "production", + }, + { + Artist: &mellodoot, + Role: "artwork", + }, + }, + Lyrics: + `the truth is what you make of it + in the end, what you spend, is the end of it + when you're lost in the life + the life that you created on your own + i'm becoming one + with the soul that i see in the mirror + blending one and whole + this time, i'm real - i'm living the dream - i'm living my best life - running out of time - i gotta make this right - whenever you rise - whenever you come down - fall away from the light - and then fall into our arms + i'm living the dream + i'm living my best life + running out of time + i gotta make this right + whenever you rise + whenever you come down + fall away from the light + and then fall into our arms - the truth is what you make of it - in the end, what you spend, is the end of it - when you're lost in the life - the life that you created on your own - i'm becoming one - with the soul that i see in the mirror - blending one and whole - this time, i'm real`, - }, - { - Id: "gomyway", - Title: "Go My Way", - Type: "single", - ReleaseDate: make_date_work("24-Jan-2021"), - Artwork: "https://mellodoot.com/img/music_artwork/mellodoot_-_Go_My_Way.webp", - Buylink: "https://arimelody.bandcamp.com/track/go-my-way", - Links: []MusicLink{ - { - Name: "spotify", - Url: "https://open.spotify.com/album/35WNtxK12IDHCUoXHDePGE", - }, - { - Name: "apple music", - Url: "https://music.apple.com/ie/album/go-my-way-single/1547145699", - }, - { - Name: "soundcloud", - Url: "https://soundcloud.com/arimelody/go-my-way", - }, - { - Name: "youtube", - Url: "https://www.youtube.com/watch?v=CNptNQdLkl0", - }, - }, - Description: "hey! go my way! 💥 ✨", - Credits: []MusicCredit{ - { - Artist: &mellodoot, - Role: "vocals", - }, - { - Artist: &mellodoot, - Role: "production", - }, - { - Artist: &mellodoot, - Role: "artwork", - }, - }, - }, - { - Id: "rowboat", - Title: "Rowboat", - Type: "single", - ReleaseDate: make_date_work("12-Mar-2020"), - Artwork: "https://mellodoot.com/img/music_artwork/mellodoot_-_Rowboat.webp", - Buylink: "https://arimelody.bandcamp.com/track/rowboat", - Links: []MusicLink{ - { - Name: "spotify", - Url: "https://open.spotify.com/album/7jyqJFVKaENCPm58v5O44Y", - }, - { - Name: "apple music", - Url: "https://music.apple.com/ie/album/rowboat-single/1502608714", - }, - { - Name: "soundcloud", - Url: "https://soundcloud.com/arimelody/rowboat", - }, - { - Name: "youtube", - Url: "https://www.youtube.com/watch?v=uOQyILDTzME", - }, - }, - Description: "let's take a trip. i've got a goddamn boat ⛵️", - Credits: []MusicCredit{ - { - Artist: &mellodoot, - Role: "vocals", - }, - { - Artist: &mellodoot, - Role: "production", - }, - { - Artist: &mellodoot, - Role: "artwork", - }, - }, - }, - { - Id: "helloworld", - Title: "Hello World", - Type: "single", - ReleaseDate: make_date_work("25-Dec-2019"), - Artwork: "https://mellodoot.com/img/music_artwork/mellodoot_-_Hello_World.webp", - Buylink: "https://arimelody.bandcamp.com/track/hello-world", - Links: []MusicLink{ - { - Name: "spotify", - Url: "https://open.spotify.com/album/3LbElPXD4dsDumttGBuYxx", - }, - { - Name: "apple music", - Url: "https://music.apple.com/ie/album/hello-world-single/1491880155", - }, - { - Name: "soundcloud", - Url: "https://soundcloud.com/arimelody/helloworld", - }, - { - Name: "youtube", - Url: "https://www.youtube.com/watch?v=CQhlRsl0Mjk", - }, - }, - Description: "we'll dawn a new frontier! 👾", - Credits: []MusicCredit{ - { - Artist: &mellodoot, - Role: "vocals", - }, - { - Artist: &mellodoot, - Role: "production", - }, - { - Artist: &mellodoot, - Role: "artwork", - }, - }, - }, - { - Id: "sine", - Title: "Sine", - Type: "single", - ReleaseDate: make_date_work("07-Dec-2019"), - Artwork: "https://mellodoot.com/img/music_artwork/zaire_-_Sine_ft._mellodoot.webp", - Links: []MusicLink{ - { - Name: "spotify", - Url: "https://open.spotify.com/album/4WPuaJtTV7z86KubD9Rnmk", - }, - { - Name: "apple music", - Url: "https://music.apple.com/us/album/sine-feat-mellodoot/1489163020", - }, - { - Name: "youtube", - Url: "https://www.youtube.com/watch?v=z1H1s6VRnyY", - }, - }, - Credits: []MusicCredit{ - { - Artist: &zaire, - Role: "production", - }, - { - Artist: &mellodoot, - Role: "production", - }, - }, - }, - { - Id: "10", - Title: "10", - Type: "single", - ReleaseDate: make_date_work("29-Sep-2019"), - Artwork: "https://mellodoot.com/img/music_artwork/mellodoot_-_10.webp", - Buylink: "https://arimelody.bandcamp.com/track/10", - Links: []MusicLink{ - { - Name: "spotify", - Url: "https://open.spotify.com/album/2x4gbACfDm99unaXpLXyj0", - }, - { - Name: "apple music", - Url: "https://music.apple.com/ie/album/ten-single/1483193041", - }, - { - Name: "soundcloud", - Url: "https://soundcloud.com/arimelody/ten", - }, - { - Name: "youtube", - Url: "https://www.youtube.com/watch?v=C7WP5L2BK4U", - }, - }, - Credits: []MusicCredit{ - { - Artist: &mellodoot, - Role: "production", - }, - { - Artist: &mellodoot, - Role: "artwork", - }, - }, - }, - { - Id: "mad", - Title: "MAD", - Type: "single", - ReleaseDate: make_date_work("03-Nov-2018"), - Artwork: "https://mellodoot.com/img/music_artwork/mellodoot_-_MAD.webp", - Buylink: "https://arimelody.bandcamp.com/track/mad", - Links: []MusicLink{ - { - Name: "spotify", - Url: "https://open.spotify.com/album/59nFXw1WNoRhXou7lXqBZd", - }, - { - Name: "apple music", - Url: "https://music.apple.com/ie/album/mad/1441233120", - }, - { - Name: "soundcloud", - Url: "https://soundcloud.com/arimelody/mad", - }, - { - Name: "youtube", - Url: "https://www.youtube.com/watch?v=OB-Pk6p6mfQ", - }, - }, - Credits: []MusicCredit{ - { - Artist: &mellodoot, - Role: "vocals", - }, - { - Artist: &mellodoot, - Role: "production", - }, - { - Artist: &mellodoot, - Role: "artwork", - }, - }, - }, - { - Id: "welcomingparty", - Title: "Welcoming Party", - Type: "album", - ReleaseDate: make_date_work("01-Nov-2018"), - Artwork: "https://mellodoot.com/img/music_artwork/mellodoot_-_Welcoming_Party.webp", - Buylink: "https://arimelody.bandcamp.com/album/welcoming-party", - Links: []MusicLink{ - { - Name: "spotify", - Url: "https://open.spotify.com/album/3EPa4HZpkISQVRAks64LfR", - }, - { - Name: "apple music", - Url: "https://music.apple.com/ie/album/welcoming-party-ep/1441161424", - }, - { - Name: "soundcloud", - Url: "https://soundcloud.com/arimelody/sets/welcoming-party", - }, - { - Name: "youtube", - Url: "https://www.youtube.com/playlist?list=PLBG_QJeOHrB5EeniiXBIlHpoQbD6CUJca", - }, - }, - Credits: []MusicCredit{ - { - Artist: &mellodoot, - Role: "production", - }, - { - Artist: &mellodoot, - Role: "artwork", - }, - }, - // "tracks": [ - // { - // "title": "Paradigm" - // }, - // { - // "title": "Mitrio" - // }, - // { - // "title": "Level One" - // }, - // { - // "title": "Cubes" - // }, - // { - // "title": "Aria" - // } - // ] - }, - { - Id: "howtheyknow2018", - Title: "How They Know (2018)", - Type: "single", - ReleaseDate: make_date_work("27-Feb-2018"), - Artwork: "https://mellodoot.com/img/music_artwork/mellodoot_-_How_They_Know_2018.webp", - Buyname: "free download", - Buylink: "https://arimelody.bandcamp.com/track/how-they-know-2018-remastered", - Links: []MusicLink{ - { - Name: "soundcloud", - Url: "https://soundcloud.com/arimelody/how-they-know-2018", - }, - { - Name: "youtube", - Url: "https://www.youtube.com/watch?v=mbAgSwCzyMw", - }, - }, - Credits: []MusicCredit{ - { - Artist: &mellodoot, - Role: "production", - }, - { - Artist: &red, - Role: "artwork", - Meta: true, - }, - }, - }, - { - Id: "howtheyknow", - Title: "How They Know", - Type: "single", - ReleaseDate: make_date_work("29-Nov-2017"), - Artwork: "https://mellodoot.com/img/music_artwork/mellodoot_-_How_They_Know.webp", - Buyname: "free download", - Buylink: "https://arimelody.bandcamp.com/track/how-they-know", - Links: []MusicLink{ - { - Name: "soundcloud", - Url: "https://soundcloud.com/arimelody/how-they-know", - }, - { - Name: "youtube", - Url: "https://www.youtube.com/watch?v=q6lzKuG1Emo", - }, - }, - Credits: []MusicCredit{ - { - Artist: &mellodoot, - Role: "production", - }, - { - Artist: &red, - Role: "artwork", - Meta: true, - }, - }, - }, - { - Id: "traveller", - Title: "Traveller", - Type: "single", - ReleaseDate: make_date_work("24-Sep-2017"), - Artwork: "https://mellodoot.com/img/music_artwork/mellodoot_-_Traveller.webp", - Buyname: "free download", - Buylink: "https://arimelody.bandcamp.com/track/traveller", - Links: []MusicLink{ - { - Name: "soundcloud", - Url: "https://soundcloud.com/arimelody/traveller", - }, - { - Name: "youtube", - Url: "https://www.youtube.com/watch?v=ZTO7IQZ-yXA", - }, - }, - Description: "an 8-bit expedition! ⚔️🛡️", - Credits: []MusicCredit{ - { - Artist: &mellodoot, - Role: "production", - }, - { - Artist: &mellodoot, - Role: "artwork", - }, - }, - }, + the truth is what you make of it + in the end, what you spend, is the end of it + when you're lost in the life + the life that you created on your own + i'm becoming one + with the soul that i see in the mirror + blending one and whole + this time, i'm real`, + }, + { + Id: "gomyway", + Title: "Go My Way", + Type: "single", + ReleaseDate: make_date_work("24-Jan-2021"), + Artwork: "https://mellodoot.com/img/music_artwork/mellodoot_-_Go_My_Way.webp", + Buylink: "https://arimelody.bandcamp.com/track/go-my-way", + Links: []MusicLink{ + { + Name: "spotify", + Url: "https://open.spotify.com/album/35WNtxK12IDHCUoXHDePGE", + }, + { + Name: "apple music", + Url: "https://music.apple.com/ie/album/go-my-way-single/1547145699", + }, + { + Name: "soundcloud", + Url: "https://soundcloud.com/arimelody/go-my-way", + }, + { + Name: "youtube", + Url: "https://www.youtube.com/watch?v=CNptNQdLkl0", + }, + }, + Description: "hey! go my way! 💥 ✨", + Credits: []MusicCredit{ + { + Artist: &mellodoot, + Role: "vocals", + }, + { + Artist: &mellodoot, + Role: "production", + }, + { + Artist: &mellodoot, + Role: "artwork", + }, + }, + }, + { + Id: "rowboat", + Title: "Rowboat", + Type: "single", + ReleaseDate: make_date_work("12-Mar-2020"), + Artwork: "https://mellodoot.com/img/music_artwork/mellodoot_-_Rowboat.webp", + Buylink: "https://arimelody.bandcamp.com/track/rowboat", + Links: []MusicLink{ + { + Name: "spotify", + Url: "https://open.spotify.com/album/7jyqJFVKaENCPm58v5O44Y", + }, + { + Name: "apple music", + Url: "https://music.apple.com/ie/album/rowboat-single/1502608714", + }, + { + Name: "soundcloud", + Url: "https://soundcloud.com/arimelody/rowboat", + }, + { + Name: "youtube", + Url: "https://www.youtube.com/watch?v=uOQyILDTzME", + }, + }, + Description: "let's take a trip. i've got a goddamn boat ⛵️", + Credits: []MusicCredit{ + { + Artist: &mellodoot, + Role: "vocals", + }, + { + Artist: &mellodoot, + Role: "production", + }, + { + Artist: &mellodoot, + Role: "artwork", + }, + }, + }, + { + Id: "helloworld", + Title: "Hello World", + Type: "single", + ReleaseDate: make_date_work("25-Dec-2019"), + Artwork: "https://mellodoot.com/img/music_artwork/mellodoot_-_Hello_World.webp", + Buylink: "https://arimelody.bandcamp.com/track/hello-world", + Links: []MusicLink{ + { + Name: "spotify", + Url: "https://open.spotify.com/album/3LbElPXD4dsDumttGBuYxx", + }, + { + Name: "apple music", + Url: "https://music.apple.com/ie/album/hello-world-single/1491880155", + }, + { + Name: "soundcloud", + Url: "https://soundcloud.com/arimelody/helloworld", + }, + { + Name: "youtube", + Url: "https://www.youtube.com/watch?v=CQhlRsl0Mjk", + }, + }, + Description: "we'll dawn a new frontier! 👾", + Credits: []MusicCredit{ + { + Artist: &mellodoot, + Role: "vocals", + }, + { + Artist: &mellodoot, + Role: "production", + }, + { + Artist: &mellodoot, + Role: "artwork", + }, + }, + }, + { + Id: "sine", + Title: "Sine", + Type: "single", + ReleaseDate: make_date_work("07-Dec-2019"), + Artwork: "https://mellodoot.com/img/music_artwork/zaire_-_Sine_ft._mellodoot.webp", + Links: []MusicLink{ + { + Name: "spotify", + Url: "https://open.spotify.com/album/4WPuaJtTV7z86KubD9Rnmk", + }, + { + Name: "apple music", + Url: "https://music.apple.com/us/album/sine-feat-mellodoot/1489163020", + }, + { + Name: "youtube", + Url: "https://www.youtube.com/watch?v=z1H1s6VRnyY", + }, + }, + Credits: []MusicCredit{ + { + Artist: &zaire, + Role: "production", + }, + { + Artist: &mellodoot, + Role: "production", + }, + }, + }, + { + Id: "10", + Title: "10", + Type: "single", + ReleaseDate: make_date_work("29-Sep-2019"), + Artwork: "https://mellodoot.com/img/music_artwork/mellodoot_-_10.webp", + Buylink: "https://arimelody.bandcamp.com/track/10", + Links: []MusicLink{ + { + Name: "spotify", + Url: "https://open.spotify.com/album/2x4gbACfDm99unaXpLXyj0", + }, + { + Name: "apple music", + Url: "https://music.apple.com/ie/album/ten-single/1483193041", + }, + { + Name: "soundcloud", + Url: "https://soundcloud.com/arimelody/ten", + }, + { + Name: "youtube", + Url: "https://www.youtube.com/watch?v=C7WP5L2BK4U", + }, + }, + Credits: []MusicCredit{ + { + Artist: &mellodoot, + Role: "production", + }, + { + Artist: &mellodoot, + Role: "artwork", + }, + }, + }, + { + Id: "mad", + Title: "MAD", + Type: "single", + ReleaseDate: make_date_work("03-Nov-2018"), + Artwork: "https://mellodoot.com/img/music_artwork/mellodoot_-_MAD.webp", + Buylink: "https://arimelody.bandcamp.com/track/mad", + Links: []MusicLink{ + { + Name: "spotify", + Url: "https://open.spotify.com/album/59nFXw1WNoRhXou7lXqBZd", + }, + { + Name: "apple music", + Url: "https://music.apple.com/ie/album/mad/1441233120", + }, + { + Name: "soundcloud", + Url: "https://soundcloud.com/arimelody/mad", + }, + { + Name: "youtube", + Url: "https://www.youtube.com/watch?v=OB-Pk6p6mfQ", + }, + }, + Credits: []MusicCredit{ + { + Artist: &mellodoot, + Role: "vocals", + }, + { + Artist: &mellodoot, + Role: "production", + }, + { + Artist: &mellodoot, + Role: "artwork", + }, + }, + }, + { + Id: "welcomingparty", + Title: "Welcoming Party", + Type: "album", + ReleaseDate: make_date_work("01-Nov-2018"), + Artwork: "https://mellodoot.com/img/music_artwork/mellodoot_-_Welcoming_Party.webp", + Buylink: "https://arimelody.bandcamp.com/album/welcoming-party", + Links: []MusicLink{ + { + Name: "spotify", + Url: "https://open.spotify.com/album/3EPa4HZpkISQVRAks64LfR", + }, + { + Name: "apple music", + Url: "https://music.apple.com/ie/album/welcoming-party-ep/1441161424", + }, + { + Name: "soundcloud", + Url: "https://soundcloud.com/arimelody/sets/welcoming-party", + }, + { + Name: "youtube", + Url: "https://www.youtube.com/playlist?list=PLBG_QJeOHrB5EeniiXBIlHpoQbD6CUJca", + }, + }, + Credits: []MusicCredit{ + { + Artist: &mellodoot, + Role: "production", + }, + { + Artist: &mellodoot, + Role: "artwork", + }, + }, + // "tracks": [ + // { + // "title": "Paradigm" + // }, + // { + // "title": "Mitrio" + // }, + // { + // "title": "Level One" + // }, + // { + // "title": "Cubes" + // }, + // { + // "title": "Aria" + // } + // ] + }, + { + Id: "howtheyknow2018", + Title: "How They Know (2018)", + Type: "single", + ReleaseDate: make_date_work("27-Feb-2018"), + Artwork: "https://mellodoot.com/img/music_artwork/mellodoot_-_How_They_Know_2018.webp", + Buyname: "free download", + Buylink: "https://arimelody.bandcamp.com/track/how-they-know-2018-remastered", + Links: []MusicLink{ + { + Name: "soundcloud", + Url: "https://soundcloud.com/arimelody/how-they-know-2018", + }, + { + Name: "youtube", + Url: "https://www.youtube.com/watch?v=mbAgSwCzyMw", + }, + }, + Credits: []MusicCredit{ + { + Artist: &mellodoot, + Role: "production", + }, + { + Artist: &red, + Role: "artwork", + Meta: true, + }, + }, + }, + { + Id: "howtheyknow", + Title: "How They Know", + Type: "single", + ReleaseDate: make_date_work("29-Nov-2017"), + Artwork: "https://mellodoot.com/img/music_artwork/mellodoot_-_How_They_Know.webp", + Buyname: "free download", + Buylink: "https://arimelody.bandcamp.com/track/how-they-know", + Links: []MusicLink{ + { + Name: "soundcloud", + Url: "https://soundcloud.com/arimelody/how-they-know", + }, + { + Name: "youtube", + Url: "https://www.youtube.com/watch?v=q6lzKuG1Emo", + }, + }, + Credits: []MusicCredit{ + { + Artist: &mellodoot, + Role: "production", + }, + { + Artist: &red, + Role: "artwork", + Meta: true, + }, + }, + }, + { + Id: "traveller", + Title: "Traveller", + Type: "single", + ReleaseDate: make_date_work("24-Sep-2017"), + Artwork: "https://mellodoot.com/img/music_artwork/mellodoot_-_Traveller.webp", + Buyname: "free download", + Buylink: "https://arimelody.bandcamp.com/track/traveller", + Links: []MusicLink{ + { + Name: "soundcloud", + Url: "https://soundcloud.com/arimelody/traveller", + }, + { + Name: "youtube", + Url: "https://www.youtube.com/watch?v=ZTO7IQZ-yXA", + }, + }, + Description: "an 8-bit expedition! ⚔️🛡️", + Credits: []MusicCredit{ + { + Artist: &mellodoot, + Role: "production", + }, + { + Artist: &mellodoot, + Role: "artwork", + }, + }, + }, } func GetRelease(id string) (MusicRelease, bool) { - for _, album := range placeholders { - if album.Id == id { - return album, true - } - } - return MusicRelease{}, false + for _, album := range placeholders { + if album.Id == id { + return album, true + } + } + return MusicRelease{}, false } func QueryAllMusic() ([]MusicRelease) { - return placeholders + return placeholders } func QueryAllArtists() ([]Artist) { - return []Artist{ ari, mellodoot, zaire, mae, loudar, red } + return []Artist{ ari, mellodoot, zaire, mae, loudar, red } } diff --git a/api/v1/music/music_types.go b/api/v1/music/music_types.go index 573b82a..046143f 100644 --- a/api/v1/music/music_types.go +++ b/api/v1/music/music_types.go @@ -1,172 +1,172 @@ package music import ( - "regexp" - "strings" - "time" + "regexp" + "strings" + "time" ) type ( - Artist struct { - Id string - Name string - Website string - } + Artist struct { + Id string + Name string + Website string + } - MusicRelease struct { - Id string - Title string - Type string - ReleaseDate time.Time - Artwork string - Buyname string - Buylink string - Links []MusicLink - Description string - Credits []MusicCredit - Lyrics string - } + MusicRelease struct { + Id string + Title string + Type string + ReleaseDate time.Time + Artwork string + Buyname string + Buylink string + Links []MusicLink + Description string + Credits []MusicCredit + Lyrics string + } - MusicLink struct { - Name string - Url string - } + MusicLink struct { + Name string + Url string + } - MusicCredit struct { - Artist *Artist - Role string - Meta bool // for "meta" contributors (i.e. not credited for the musical work, but other related assets) - } - ) + MusicCredit struct { + Artist *Artist + Role string + Meta bool // for "meta" contributors (i.e. not credited for the musical work, but other related assets) + } +) func (album MusicRelease) GetUniqueArtists() []Artist { - if len(album.Credits) == 1 { - return []Artist{*album.Credits[0].Artist} - } + if len(album.Credits) == 1 { + return []Artist{*album.Credits[0].Artist} + } - // create a map of artists to prevent duplicates - res := []Artist{} - for _, credit := range album.Credits { - artist := *credit.Artist - exists := false - for _, c := range res { - if c == *credit.Artist { - exists = true - break - } - } - if exists { - continue - } - res = append(res, artist) - } + // create a map of artists to prevent duplicates + res := []Artist{} + for _, credit := range album.Credits { + 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 + // now create the actual array to send + return res } func (album MusicRelease) GetUniqueNonMetaArtists() []Artist { - if len(album.Credits) == 1 { - return []Artist{*album.Credits[0].Artist} - } + if len(album.Credits) == 1 { + return []Artist{*album.Credits[0].Artist} + } - // 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) - } + // 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 + // now create the actual array to send + return res } func (album MusicRelease) GetUniqueArtistNames() []string { - if len(album.Credits) == 1 { - return []string{album.Credits[0].Artist.Name} - } + if len(album.Credits) == 1 { + return []string{album.Credits[0].Artist.Name} + } - artists := album.GetUniqueArtists() - names := []string{} - for _, artist := range artists { - names = append(names, artist.Name) - } + artists := album.GetUniqueArtists() + names := []string{} + for _, artist := range artists { + names = append(names, artist.Name) + } - return names + return names } func (album MusicRelease) GetUniqueNonMetaArtistNames() []string { - if len(album.Credits) == 1 { - return []string{album.Credits[0].Artist.Name} - } + 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) - } + artists := album.GetUniqueNonMetaArtists() + names := []string{} + for _, artist := range artists { + names = append(names, artist.Name) + } - return names + return names } func (album MusicRelease) PrintPrimaryArtists() string { - names := album.GetUniqueNonMetaArtistNames() - if len(names) == 1 { - return names[0] - } - res := strings.Join(names[:len(names)-1], ", ") - res += " & " + names[len(names)-1] - return res + names := album.GetUniqueNonMetaArtistNames() + if len(names) == 1 { + return names[0] + } + res := strings.Join(names[:len(names)-1], ", ") + res += " & " + names[len(names)-1] + return res } func (album MusicRelease) PrintCommaPrimaryArtists() string { - names := album.GetUniqueNonMetaArtistNames() - if len(names) == 1 { - return names[0] - } - return strings.Join(names[:], ", ") + names := album.GetUniqueNonMetaArtistNames() + if len(names) == 1 { + return names[0] + } + return strings.Join(names[:], ", ") } func (album MusicRelease) ResolveType() string { - if album.Type != "" { - return album.Type - } - return "unknown" + if album.Type != "" { + return album.Type + } + return "unknown" } func (album MusicRelease) ResolveArtwork() string { - if album.Artwork != "" { - return album.Artwork - } - return "/img/music-artwork/default.png" + if album.Artwork != "" { + return album.Artwork + } + return "/img/music-artwork/default.png" } func (album MusicRelease) PrintReleaseDate() string { - return album.ReleaseDate.Format("02 January 2006") + return album.ReleaseDate.Format("02 January 2006") } func (album MusicRelease) GetReleaseYear() int { - return album.ReleaseDate.Year() + return album.ReleaseDate.Year() } func (link MusicLink) NormaliseName() string { - re := regexp.MustCompile(`[^a-z0-9]`) - return strings.ToLower(re.ReplaceAllString(link.Name, "")) + re := regexp.MustCompile(`[^a-z0-9]`) + return strings.ToLower(re.ReplaceAllString(link.Name, "")) } func (credit MusicCredit) ResolveArtist() Artist { - return *credit.Artist + return *credit.Artist } diff --git a/db.go b/db.go index de7d7cf..8777aaf 100644 --- a/db.go +++ b/db.go @@ -1,97 +1,97 @@ package main import ( - "arimelody.me/arimelody.me/api/v1/music" + "arimelody.me/arimelody.me/api/v1/music" - "fmt" - "os" - "time" + "fmt" + "os" + "time" - _ "github.com/lib/pq" - "github.com/jmoiron/sqlx" + _ "github.com/lib/pq" + "github.com/jmoiron/sqlx" ) var schema = `CREATE TABLE IF NOT EXISTS artists ( - id TEXT PRIMARY KEY, - name TEXT, - website TEXT + id TEXT PRIMARY KEY, + name TEXT, + website TEXT ); CREATE TABLE IF NOT EXISTS musicreleases ( - id VARCHAR(64) PRIMARY KEY, - title TEXT NOT NULL, - type TEXT, - release_date DATE NOT NULL, - artwork TEXT, - buyname TEXT, - buylink TEXT, - description TEXT, - lyrics TEXT + id VARCHAR(64) PRIMARY KEY, + title TEXT NOT NULL, + type TEXT, + release_date DATE NOT NULL, + artwork TEXT, + buyname TEXT, + buylink TEXT, + description TEXT, + lyrics TEXT ); CREATE TABLE IF NOT EXISTS musiclinks ( - album VARCHAR(64) REFERENCES musicreleases(id) ON DELETE CASCADE ON UPDATE CASCADE, - name TEXT, - url TEXT, - CONSTRAINT musiclinks_pk PRIMARY KEY (album, name) + album VARCHAR(64) REFERENCES musicreleases(id) ON DELETE CASCADE ON UPDATE CASCADE, + name TEXT, + url TEXT, + CONSTRAINT musiclinks_pk PRIMARY KEY (album, name) ); CREATE TABLE IF NOT EXISTS musiccredits ( - album VARCHAR(64) REFERENCES musicreleases(ID) ON DELETE CASCADE, - artist TEXT REFERENCES artists(id) ON DELETE CASCADE, - role TEXT, - meta BOOLEAN, - constraint musiccredits_pk PRIMARY KEY (album, artist, role) + album VARCHAR(64) REFERENCES musicreleases(ID) ON DELETE CASCADE, + artist TEXT REFERENCES artists(id) ON DELETE CASCADE, + role TEXT, + meta BOOLEAN, + constraint musiccredits_pk PRIMARY KEY (album, artist, role) );` func PushArtist(db *sqlx.DB, artist music.Artist) { - fmt.Printf("syncing artist [%s] to database...", artist.Name) + fmt.Printf("syncing artist [%s] to database...", artist.Name) - db.MustExec("INSERT INTO artists (id, name, website) VALUES ($1, $2, $3) ON CONFLICT (id) DO UPDATE SET name=$2, website=$3", - &artist.Id, - &artist.Name, - &artist.Website, - ) - - fmt.Printf("done!\n") + db.MustExec("INSERT INTO artists (id, name, website) VALUES ($1, $2, $3) ON CONFLICT (id) DO UPDATE SET name=$2, website=$3", + &artist.Id, + &artist.Name, + &artist.Website, +) + +fmt.Printf("done!\n") } func PushRelease(db *sqlx.DB, release music.MusicRelease) { - fmt.Printf("syncing release [%s] to database...", release.Id) + fmt.Printf("syncing release [%s] to database...", release.Id) - tx := db.MustBegin() - tx.MustExec("INSERT INTO musicreleases (id, title, release_date, artwork, buyname, buylink, description, lyrics) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) "+ - "ON CONFLICT (id) DO UPDATE SET title=$2, release_date=$3, artwork=$4, buyname=$5, buylink=$6, description=$7, lyrics=$8", - &release.Id, &release.Title, release.ReleaseDate.Format("2-Jan-2006"), &release.Artwork, &release.Buyname, &release.Buylink, &release.Description, &release.Lyrics) + tx := db.MustBegin() + tx.MustExec("INSERT INTO musicreleases (id, title, release_date, artwork, buyname, buylink, description, lyrics) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) "+ + "ON CONFLICT (id) DO UPDATE SET title=$2, release_date=$3, artwork=$4, buyname=$5, buylink=$6, description=$7, lyrics=$8", + &release.Id, &release.Title, release.ReleaseDate.Format("2-Jan-2006"), &release.Artwork, &release.Buyname, &release.Buylink, &release.Description, &release.Lyrics) - for _, link := range release.Links { - tx.MustExec("INSERT INTO musiclinks (album, name, url) VALUES ($1, $2, $3) ON CONFLICT (album, name) DO UPDATE SET url=$3", - &release.Id, &link.Name, &link.Url) - } - for _, credit := range release.Credits { - tx.MustExec("INSERT INTO musiccredits (album, artist, role, meta) VALUES ($1, $2, $3, $4) ON CONFLICT DO NOTHING", - &release.Id, &credit.Artist.Id, &credit.Role, &credit.Meta) - } + for _, link := range release.Links { + tx.MustExec("INSERT INTO musiclinks (album, name, url) VALUES ($1, $2, $3) ON CONFLICT (album, name) DO UPDATE SET url=$3", + &release.Id, &link.Name, &link.Url) + } + for _, credit := range release.Credits { + tx.MustExec("INSERT INTO musiccredits (album, artist, role, meta) VALUES ($1, $2, $3, $4) ON CONFLICT DO NOTHING", + &release.Id, &credit.Artist.Id, &credit.Role, &credit.Meta) + } - tx.Commit() + tx.Commit() - fmt.Printf("done!\n") + fmt.Printf("done!\n") } func InitDatabase() *sqlx.DB { - db, err := sqlx.Connect("postgres", "user=arimelody dbname=arimelody password=fuckingpassword sslmode=disable") - if err != nil { - fmt.Fprintf(os.Stderr, "unable to create database connection pool: %v\n", err) - os.Exit(1) - } - - db.SetConnMaxLifetime(time.Minute * 3) - db.SetMaxOpenConns(10) - db.SetMaxIdleConns(10) + db, err := sqlx.Connect("postgres", "user=arimelody dbname=arimelody password=fuckingpassword sslmode=disable") + if err != nil { + fmt.Fprintf(os.Stderr, "unable to create database connection pool: %v\n", err) + os.Exit(1) + } - db.MustExec(schema) - fmt.Printf("database schema synchronised.\n") + db.SetConnMaxLifetime(time.Minute * 3) + db.SetMaxOpenConns(10) + db.SetMaxIdleConns(10) - return db + db.MustExec(schema) + fmt.Printf("database schema synchronised.\n") + + return db } diff --git a/go.mod b/go.mod index a20b06c..1f74015 100644 --- a/go.mod +++ b/go.mod @@ -1,15 +1,18 @@ module arimelody.me/arimelody.me -go 1.22.1 +go 1.22 + +require ( + github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47 + github.com/jmoiron/sqlx v1.3.5 + github.com/lib/pq v1.10.9 +) require ( - github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/pgx/v5 v5.5.5 // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect - github.com/jmoiron/sqlx v1.3.5 // indirect - github.com/lib/pq v1.10.9 // indirect golang.org/x/crypto v0.17.0 // indirect golang.org/x/sync v0.1.0 // indirect golang.org/x/text v0.14.0 // indirect diff --git a/main.go b/main.go index 0087639..cb283bb 100644 --- a/main.go +++ b/main.go @@ -1,220 +1,220 @@ package main import ( - "fmt" - "html/template" - "log" - "net/http" - "os" - "regexp" - "strconv" - "strings" - "time" + "fmt" + "html/template" + "log" + "net/http" + "os" + "regexp" + "strconv" + "strings" + "time" - "arimelody.me/arimelody.me/api/v1/music" + "arimelody.me/arimelody.me/api/v1/music" - "github.com/gomarkdown/markdown" - "github.com/gomarkdown/markdown/html" - "github.com/gomarkdown/markdown/parser" + "github.com/gomarkdown/markdown" + "github.com/gomarkdown/markdown/html" + "github.com/gomarkdown/markdown/parser" ) const PORT int = 8080 var mime_types = map[string]string{ - "css": "text/css; charset=utf-8", - "png": "image/png", - "jpg": "image/jpg", - "webp": "image/webp", - "html": "text/html", - "asc": "text/plain", - "pub": "text/plain", - "js": "application/javascript", + "css": "text/css; charset=utf-8", + "png": "image/png", + "jpg": "image/jpg", + "webp": "image/webp", + "html": "text/html", + "asc": "text/plain", + "pub": "text/plain", + "js": "application/javascript", } var base_template = template.Must(template.ParseFiles( - "views/base.html", - "views/header.html", - "views/footer.html", - "views/prideflag.html", + "views/base.html", + "views/header.html", + "views/footer.html", + "views/prideflag.html", )) var htmx_template = template.Must(template.New("root").Parse(`{{block "head" .}}{{end}}{{block "content" .}}{{end}}`)) func log_request(req *http.Request, code int, start_time time.Time) { - now := time.Now() - difference := (now.Nanosecond() - start_time.Nanosecond()) / 1_000_000 - elapsed := "<1" - if difference >= 1 { - elapsed = strconv.Itoa(difference) - } + now := time.Now() + difference := (now.Nanosecond() - start_time.Nanosecond()) / 1_000_000 + elapsed := "<1" + if difference >= 1 { + elapsed = strconv.Itoa(difference) + } - fmt.Printf("[%s] %s %s - %d (%sms) (%s)\n", - now.Format(time.UnixDate), - req.Method, - req.URL.Path, - code, - elapsed, - req.Header["User-Agent"][0], - ) + fmt.Printf("[%s] %s %s - %d (%sms) (%s)\n", + now.Format(time.UnixDate), + req.Method, + req.URL.Path, + code, + elapsed, + req.Header["User-Agent"][0], +) } func handle_request(writer http.ResponseWriter, req *http.Request) { - uri := req.URL.Path - start_time := time.Now() + uri := req.URL.Path + start_time := time.Now() - hx_request := len(req.Header["Hx-Request"]) > 0 && req.Header["Hx-Request"][0] == "true" + hx_request := len(req.Header["Hx-Request"]) > 0 && req.Header["Hx-Request"][0] == "true" - // don't bother fulfilling requests to a page that's already loaded on the client! - if hx_request && len(req.Header["Referer"]) > 0 && len(req.Header["Hx-Current-Url"]) > 0 { - regex := regexp.MustCompile(`https?:\/\/[^\/]+`) - current_location := regex.ReplaceAllString(req.Header["Hx-Current-Url"][0], "") - if current_location == req.URL.Path { - writer.WriteHeader(204); - return - } - } + // don't bother fulfilling requests to a page that's already loaded on the client! + if hx_request && len(req.Header["Referer"]) > 0 && len(req.Header["Hx-Current-Url"]) > 0 { + regex := regexp.MustCompile(`https?:\/\/[^\/]+`) + current_location := regex.ReplaceAllString(req.Header["Hx-Current-Url"][0], "") + if current_location == req.URL.Path { + writer.WriteHeader(204); + return + } + } - code := func(writer http.ResponseWriter, req *http.Request) int { - var root *template.Template - if hx_request { - root = template.Must(htmx_template.Clone()) - } else { - root = template.Must(base_template.Clone()) - } + code := func(writer http.ResponseWriter, req *http.Request) int { + var root *template.Template + if hx_request { + root = template.Must(htmx_template.Clone()) + } else { + root = template.Must(base_template.Clone()) + } - if req.URL.Path == "/" { - return index_handler(writer, root) - } + if req.URL.Path == "/" { + return index_handler(writer, root) + } - if uri == "/music" || uri == "/music/" { - return music_directory_handler(writer, root) - } + if uri == "/music" || uri == "/music/" { + return music_directory_handler(writer, root) + } - if strings.HasPrefix(uri, "/music/") { - return music_gateway_handler(writer, req, root) - } + if strings.HasPrefix(uri, "/music/") { + return music_gateway_handler(writer, req, root) + } - return static_handler(writer, req) - }(writer, req) + return static_handler(writer, req) + }(writer, req) - log_request(req, code, start_time) + log_request(req, code, start_time) } func index_handler(writer http.ResponseWriter, root *template.Template) int { - index_template := template.Must(root.ParseFiles("views/index.html")) - err := index_template.Execute(writer, nil) - if err != nil { - http.Error(writer, err.Error(), http.StatusInternalServerError) - return 500 - } - return 200 + index_template := template.Must(root.ParseFiles("views/index.html")) + err := index_template.Execute(writer, nil) + if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + return 500 + } + return 200 } func music_directory_handler(writer http.ResponseWriter, root *template.Template) int { - music_template := template.Must(root.ParseFiles("views/music.html")) - music := music.QueryAllMusic() - err := music_template.Execute(writer, music) - if err != nil { - http.Error(writer, err.Error(), http.StatusInternalServerError) - return 500 - } - return 200 + music_template := template.Must(root.ParseFiles("views/music.html")) + music := music.QueryAllMusic() + err := music_template.Execute(writer, music) + if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + return 500 + } + return 200 } func music_gateway_handler(writer http.ResponseWriter, req *http.Request, root *template.Template) int { - id := req.URL.Path[len("/music/"):] - // http.Redirect(writer, req, "https://mellodoot.com/music/"+title, 302) - // return - release, ok := music.GetRelease(id) - if !ok { - http.Error(writer, "404 not found", http.StatusNotFound) - return 404 - } - gateway_template := template.Must(root.ParseFiles("views/music-gateway.html")) - err := gateway_template.Execute(writer, release) - if err != nil { - http.Error(writer, err.Error(), http.StatusInternalServerError) - return 500 - } - return 200 + id := req.URL.Path[len("/music/"):] + // http.Redirect(writer, req, "https://mellodoot.com/music/"+title, 302) + // return + release, ok := music.GetRelease(id) + if !ok { + http.Error(writer, "404 not found", http.StatusNotFound) + return 404 + } + gateway_template := template.Must(root.ParseFiles("views/music-gateway.html")) + err := gateway_template.Execute(writer, release) + if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + return 500 + } + return 200 } func static_handler(writer http.ResponseWriter, req *http.Request) int { - filename := "public/" + req.URL.Path[1:] + filename := "public/" + req.URL.Path[1:] - // check the file's metadata - info, err := os.Stat(filename) - if err != nil { - http.Error(writer, "404 not found", http.StatusNotFound) - return 404 - } + // check the file's metadata + info, err := os.Stat(filename) + if err != nil { + http.Error(writer, "404 not found", http.StatusNotFound) + return 404 + } - if len(req.Header["If-Modified-Since"]) > 0 && req.Header["If-Modified-Since"][0] != "" { - if_modified_since_time, err := time.Parse(http.TimeFormat, req.Header["If-Modified-Since"][0]) - if err != nil { - http.Error(writer, "400 bad request", http.StatusBadRequest) - return 400 - } - if req.Header["If-Modified-Since"][0] == info.ModTime().Format(http.TimeFormat) || if_modified_since_time.After(info.ModTime()) { - writer.WriteHeader(304) // not modified - return 304 - } - } + if len(req.Header["If-Modified-Since"]) > 0 && req.Header["If-Modified-Since"][0] != "" { + if_modified_since_time, err := time.Parse(http.TimeFormat, req.Header["If-Modified-Since"][0]) + if err != nil { + http.Error(writer, "400 bad request", http.StatusBadRequest) + return 400 + } + if req.Header["If-Modified-Since"][0] == info.ModTime().Format(http.TimeFormat) || if_modified_since_time.After(info.ModTime()) { + writer.WriteHeader(304) // not modified + return 304 + } + } - // set other nice headers - writer.Header().Set("Cache-Control", "max-age=86400") - writer.Header().Set("Last-Modified", info.ModTime().Format(http.TimeFormat)) - // Last-Modified: , :: GMT - // Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT + // set other nice headers + writer.Header().Set("Cache-Control", "max-age=86400") + writer.Header().Set("Last-Modified", info.ModTime().Format(http.TimeFormat)) + // Last-Modified: , :: GMT + // Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT - // read the file - body, err := os.ReadFile(filename) - if err != nil { - http.Error(writer, err.Error(), http.StatusInternalServerError) - return 500 - } + // read the file + body, err := os.ReadFile(filename) + if err != nil { + http.Error(writer, err.Error(), http.StatusInternalServerError) + return 500 + } - // setting MIME types - filetype := filename[strings.LastIndex(filename, ".")+1:] - if mime_type, ok := mime_types[filetype]; ok { - writer.Header().Set("Content-Type", mime_type) - } else { - writer.Header().Set("Content-Type", "text/plain; charset=utf-8") - } + // setting MIME types + filetype := filename[strings.LastIndex(filename, ".")+1:] + if mime_type, ok := mime_types[filetype]; ok { + writer.Header().Set("Content-Type", mime_type) + } else { + writer.Header().Set("Content-Type", "text/plain; charset=utf-8") + } - writer.Write([]byte(body)) - return 200 + writer.Write([]byte(body)) + return 200 } func parse_markdown(md []byte) []byte { - extensions := parser.CommonExtensions | parser.AutoHeadingIDs | parser.NoEmptyLineBeforeBlock - p := parser.NewWithExtensions(extensions) - doc := p.Parse(md) + extensions := parser.CommonExtensions | parser.AutoHeadingIDs | parser.NoEmptyLineBeforeBlock + p := parser.NewWithExtensions(extensions) + doc := p.Parse(md) - htmlFlags := html.CommonFlags - opts := html.RendererOptions{Flags: htmlFlags} - renderer := html.NewRenderer(opts) + htmlFlags := html.CommonFlags + opts := html.RendererOptions{Flags: htmlFlags} + renderer := html.NewRenderer(opts) - return markdown.Render(doc, renderer) + return markdown.Render(doc, renderer) } func push_to_db_this_is_a_testing_thing_and_will_be_superfluous_later() { - db := InitDatabase() - defer db.Close() + db := InitDatabase() + defer db.Close() - for _, artist := range music.QueryAllArtists() { - PushArtist(db, artist) - } + for _, artist := range music.QueryAllArtists() { + PushArtist(db, artist) + } - for _, album := range music.QueryAllMusic() { - PushRelease(db, album) - } + for _, album := range music.QueryAllMusic() { + PushRelease(db, album) + } } func main() { - push_to_db_this_is_a_testing_thing_and_will_be_superfluous_later() + push_to_db_this_is_a_testing_thing_and_will_be_superfluous_later() - http.HandleFunc("/", handle_request) + http.HandleFunc("/", handle_request) - fmt.Printf("now serving at http://127.0.0.1:%d\n", PORT) - log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", PORT), nil)) + fmt.Printf("now serving at http://127.0.0.1:%d\n", PORT) + log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", PORT), nil)) }