···11package music
2233import (
44- "fmt"
55- "time"
44+ "errors"
55+ "fmt"
66+ "time"
67)
7899+var Releases []*MusicRelease;
1010+var Artists []*Artist;
1111+812func make_date_work(date string) time.Time {
99- res, err := time.Parse("2-Jan-2006", date)
1010- if err != nil {
1111- fmt.Printf("somehow we failed to parse %s! falling back to epoch :]\n", date)
1212- return time.Unix(0, 0)
1313- }
1414- return res
1313+ res, err := time.Parse("2-Jan-2006", date)
1414+ if err != nil {
1515+ fmt.Printf("somehow we failed to parse %s! falling back to epoch :]\n", date)
1616+ return time.Unix(0, 0)
1717+ }
1818+ return res
1519}
16201717-func GetRelease(id string) (MusicRelease, bool) {
1818- for _, album := range placeholders {
1919- if album.Id == id {
2020- return album, true
2121- }
2121+func GetRelease(id string) (*MusicRelease, error) {
2222+ for _, release := range Releases {
2323+ if release.Id == id {
2424+ return release, nil
2225 }
2323- return MusicRelease{}, false
2626+ }
2727+ return nil, errors.New(fmt.Sprintf("Release %s not found", id))
2428}
25292626-func QueryAllMusic() ([]MusicRelease) {
2727- return placeholders
3030+func GetArtist(id string) (*Artist, error) {
3131+ for _, artist := range Artists {
3232+ if artist.Id == id {
3333+ return artist, nil
3434+ }
3535+ }
3636+ return nil, errors.New(fmt.Sprintf("Artist %s not found", id))
2837}
2929-3030-func QueryAllArtists() ([]Artist) {
3131- return []Artist{ ari, mellodoot, zaire, mae, loudar, red }
3232-}
3333-
-161
api/v1/music/music_placeholders.go
···11-package music
22-33-var ari = Artist{
44- Id: "arimelody",
55- Name: "ari melody",
66- Website: "https://arimelody.me",
77-}
88-var mellodoot = Artist{
99- Id: "mellodoot",
1010- Name: "mellodoot",
1111- Website: "https://mellodoot.com",
1212-}
1313-var zaire = Artist{
1414- Id: "zaire",
1515- Name: "zaire",
1616- Website: "https://supitszaire.com",
1717-}
1818-var mae = Artist{
1919- Id: "maetaylor",
2020- Name: "mae taylor",
2121- Website: "https://mae.wtf",
2222-}
2323-var loudar = Artist{
2424- Id: "loudar",
2525- Name: "Loudar",
2626- Website: "https://alex.targoninc.com",
2727-}
2828-var red = Artist {
2929- Id: "smoljorb",
3030- Name: "smoljorb",
3131-}
3232-3333-var placeholders = []MusicRelease{
3434- {
3535- Id: "test",
3636- Title: "test album",
3737- Type: "album",
3838- ReleaseDate: make_date_work("18-Mar-2024"),
3939- Buyname: "go get it!!",
4040- Buylink: "https://arimelody.me/",
4141- Links: []MusicLink{
4242- {
4343- Name: "youtube",
4444- Url: "https://youtu.be/dQw4w9WgXcQ",
4545- },
4646- },
4747- Description:
4848- `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.`,
4949- Credits: []MusicCredit{
5050- {
5151- Artist: &ari,
5252- Role: "having the swag",
5353- },
5454- {
5555- Artist: &zaire,
5656- Role: "having the swag",
5757- },
5858- {
5959- Artist: &mae,
6060- Role: "having the swag",
6161- },
6262- {
6363- Artist: &loudar,
6464- Role: "having the swag",
6565- },
6666- },
6767- Tracks: []MusicTrack{
6868- {
6969- Number: 0,
7070- Title: "track 1",
7171- Description: "sample track description",
7272- Lyrics: "sample lyrics for track 1!",
7373- PreviewUrl: "https://mellodoot.com/audio/preview/dream.webm",
7474- },
7575- {
7676- Number: 1,
7777- Title: "track 2",
7878- Description: "sample track description",
7979- Lyrics: "sample lyrics for track 2!",
8080- PreviewUrl: "https://mellodoot.com/audio/preview/dream.webm",
8181- },
8282- },
8383- },
8484- {
8585- Id: "dream",
8686- Title: "Dream",
8787- Type: "single",
8888- ReleaseDate: make_date_work("11-Nov-2022"),
8989- Artwork: "https://mellodoot.com/img/music_artwork/mellodoot_-_Dream.webp",
9090- Buylink: "https://arimelody.bandcamp.com/track/dream",
9191- Links: []MusicLink{
9292- {
9393- Name: "spotify",
9494- Url: "https://open.spotify.com/album/5talRpqzjExP1w6j5LFIAh",
9595- },
9696- {
9797- Name: "apple music",
9898- Url: "https://music.apple.com/ie/album/dream-single/1650037132",
9999- },
100100- {
101101- Name: "soundcloud",
102102- Url: "https://soundcloud.com/arimelody/dream2022",
103103- },
104104- {
105105- Name: "youtube",
106106- Url: "https://www.youtube.com/watch?v=nfFgtMuYAx8",
107107- },
108108- },
109109- Description: "living the dream 🌌 ✨",
110110- Credits: []MusicCredit{
111111- {
112112- Artist: &mellodoot,
113113- Role: "vocals",
114114- },
115115- {
116116- Artist: &mellodoot,
117117- Role: "production",
118118- },
119119- {
120120- Artist: &mellodoot,
121121- Role: "artwork",
122122- },
123123- },
124124- Tracks: []MusicTrack{
125125- {
126126- Number: 0,
127127- Title: "Dream",
128128- Description: "no description here!",
129129- Lyrics:
130130- `the truth is what you make of it
131131- in the end, what you spend, is the end of it
132132- when you're lost in the life
133133- the life that you created on your own
134134- i'm becoming one
135135- with the soul that i see in the mirror
136136- blending one and whole
137137- this time, i'm real
138138-139139- i'm living the dream
140140- i'm living my best life
141141- running out of time
142142- i gotta make this right
143143- whenever you rise
144144- whenever you come down
145145- fall away from the light
146146- and then fall into our arms
147147-148148- the truth is what you make of it
149149- in the end, what you spend, is the end of it
150150- when you're lost in the life
151151- the life that you created on your own
152152- i'm becoming one
153153- with the soul that i see in the mirror
154154- blending one and whole
155155- this time, i'm real`,
156156- PreviewUrl: "https://mellodoot.com/audio/preview/dream.webm",
157157- },
158158- },
159159- },
160160-}
161161-
+91-94
api/v1/music/music_types.go
···11package music
2233import (
44- "regexp"
55- "strings"
66- "time"
44+ "regexp"
55+ "strings"
66+ "time"
77)
8899type (
1010- Artist struct {
1111- Id string
1212- Name string
1313- Website string
1414- }
1010+ Artist struct {
1111+ Id string
1212+ Name string
1313+ Website string
1414+ }
15151616- MusicRelease struct {
1717- Id string
1818- Title string
1919- Type string
2020- ReleaseDate time.Time
2121- Artwork string
2222- Buyname string
2323- Buylink string
2424- Links []MusicLink
2525- Description string
2626- Credits []MusicCredit
2727- Tracks []MusicTrack
2828- }
1616+ MusicRelease struct {
1717+ Id string
1818+ Title string
1919+ Type string
2020+ ReleaseDate time.Time
2121+ Artwork string
2222+ Buyname string
2323+ Buylink string
2424+ Links []MusicLink
2525+ Description string
2626+ Credits []MusicCredit
2727+ Tracks []MusicTrack
2828+ }
29293030- MusicLink struct {
3131- Name string
3232- Url string
3333- }
3030+ MusicLink struct {
3131+ Name string
3232+ Url string
3333+ }
34343535- MusicCredit struct {
3636- Artist *Artist
3737- Role string
3838- Meta bool // for "meta" contributors (i.e. not credited for the musical work, but other related assets)
3939- }
3535+ MusicCredit struct {
3636+ Artist *Artist
3737+ Role string
3838+ Primary bool
3939+ }
40404141- MusicTrack struct {
4242- Number int
4343- Title string
4444- Description string
4545- Lyrics string
4646- PreviewUrl string
4747- }
4141+ MusicTrack struct {
4242+ Number int
4343+ Title string
4444+ Description string
4545+ Lyrics string
4646+ PreviewUrl string
4747+ }
4848)
49495050-func (release MusicRelease) GetUniqueArtists(include_meta bool) []*Artist {
5151- res := []*Artist{}
5252- for _, credit := range release.Credits {
5353- if !include_meta && credit.Meta {
5454- continue
5555- }
5050+func (release MusicRelease) GetUniqueArtists(include_non_primary bool) []*Artist {
5151+ res := []*Artist{}
5252+ for _, credit := range release.Credits {
5353+ if !include_non_primary && !credit.Primary {
5454+ continue
5555+ }
56565757- exists := false
5858- for _, a := range res {
5959- if a == credit.Artist {
6060- exists = true
6161- break
6262- }
6363- }
6464- if exists {
6565- continue
6666- }
5757+ exists := false
5858+ for _, a := range res {
5959+ if a == credit.Artist {
6060+ exists = true
6161+ break
6262+ }
6363+ }
6464+ if exists {
6565+ continue
6666+ }
67676868- res = append(res, credit.Artist)
6969- }
6868+ res = append(res, credit.Artist)
6969+ }
70707171- // now create the actual array to send
7272- return res
7171+ return res
7372}
74737575-func (release MusicRelease) GetUniqueArtistNames(include_meta bool) []string {
7676- artists := release.GetUniqueArtists(include_meta)
7777- names := []string{}
7878- for _, artist := range artists {
7979- names = append(names, artist.Name)
8080- }
7474+func (release MusicRelease) GetUniqueArtistNames(include_non_primary bool) []string {
7575+ artists := release.GetUniqueArtists(include_non_primary)
7676+ names := []string{}
7777+ for _, artist := range artists {
7878+ names = append(names, artist.Name)
7979+ }
81808282- return names
8181+ return names
8382}
84838585-func (album MusicRelease) PrintPrimaryArtists(include_meta bool) string {
8686- names := album.GetUniqueArtistNames(include_meta)
8787- if len(names) == 1 {
8888- return names[0]
8989- }
8484+func (release MusicRelease) PrintPrimaryArtists(include_non_primary bool, ampersand bool) string {
8585+ names := release.GetUniqueArtistNames(include_non_primary)
8686+ if len(names) == 0 {
8787+ return "Unknown Artist"
8888+ } else if len(names) == 1 {
8989+ return names[0]
9090+ }
9191+ if ampersand {
9092 res := strings.Join(names[:len(names)-1], ", ")
9193 res += " & " + names[len(names)-1]
9294 return res
9393-}
9494-9595-func (album MusicRelease) PrintCommaPrimaryArtists(include_meta bool) string {
9696- names := album.GetUniqueArtistNames(include_meta)
9797- if len(names) == 1 {
9898- return names[0]
9999- }
9595+ } else {
10096 return strings.Join(names[:], ", ")
9797+ }
10198}
10299103103-func (album MusicRelease) ResolveType() string {
104104- if album.Type != "" {
105105- return album.Type
106106- }
107107- return "unknown"
100100+func (release MusicRelease) ResolveType() string {
101101+ if release.Type != "" {
102102+ return release.Type
103103+ }
104104+ return "unknown"
108105}
109106110110-func (album MusicRelease) ResolveArtwork() string {
111111- if album.Artwork != "" {
112112- return album.Artwork
113113- }
114114- return "/img/music-artwork/default.png"
107107+func (release MusicRelease) ResolveArtwork() string {
108108+ if release.Artwork != "" {
109109+ return release.Artwork
110110+ }
111111+ return "/img/music-artwork/default.png"
115112}
116113117117-func (album MusicRelease) PrintReleaseDate() string {
118118- return album.ReleaseDate.Format("02 January 2006")
114114+func (release MusicRelease) PrintReleaseDate() string {
115115+ return release.ReleaseDate.Format("02 January 2006")
119116}
120117121121-func (album MusicRelease) GetReleaseYear() int {
122122- return album.ReleaseDate.Year()
118118+func (release MusicRelease) GetReleaseYear() int {
119119+ return release.ReleaseDate.Year()
123120}
124121125122func (link MusicLink) NormaliseName() string {
126126- re := regexp.MustCompile(`[^a-z0-9]`)
127127- return strings.ToLower(re.ReplaceAllString(link.Name, ""))
123123+ re := regexp.MustCompile(`[^a-z0-9]`)
124124+ return strings.ToLower(re.ReplaceAllString(link.Name, ""))
128125}
129126130127func (release MusicRelease) IsSingle() bool {
131131- return len(release.Tracks) == 1;
128128+ return len(release.Tracks) == 1;
132129}
133130134131func (credit MusicCredit) ResolveArtist() Artist {
135135- return *credit.Artist
132132+ return *credit.Artist
136133}
+151-57
db.go
···11package main
2233import (
44- "arimelody.me/arimelody.me/api/v1/music"
44+ "arimelody.me/arimelody.me/api/v1/music"
5566- "fmt"
77- "os"
88- "time"
66+ "fmt"
77+ "os"
88+ "time"
991010- _ "github.com/lib/pq"
1111- "github.com/jmoiron/sqlx"
1010+ "github.com/jmoiron/sqlx"
1111+ _ "github.com/lib/pq"
1212)
13131414-var schema =
1515-`CREATE TABLE IF NOT EXISTS artists (
1616- id TEXT PRIMARY KEY,
1717- name TEXT,
1818- website TEXT
1919-);
1414+func PushArtist(db *sqlx.DB, artist music.Artist) {
1515+ fmt.Printf("pushing artist [%s] to database...", artist.Name)
20162121-CREATE TABLE IF NOT EXISTS musicreleases (
2222- id VARCHAR(64) PRIMARY KEY,
2323- title TEXT NOT NULL,
2424- type TEXT,
2525- release_date DATE NOT NULL,
2626- artwork TEXT,
2727- buyname TEXT,
2828- buylink TEXT
2929-);
1717+ db.MustExec("INSERT INTO artists (id, name, website) VALUES ($1, $2, $3) ON CONFLICT (id) DO UPDATE SET name=$2, website=$3",
1818+ &artist.Id,
1919+ &artist.Name,
2020+ &artist.Website,
2121+ )
30223131-CREATE TABLE IF NOT EXISTS musiclinks (
3232- release VARCHAR(64) REFERENCES musicreleases(id) ON DELETE CASCADE ON UPDATE CASCADE,
3333- name TEXT,
3434- url TEXT,
3535- CONSTRAINT musiclinks_pk PRIMARY KEY (release, name)
3636-);
2323+ fmt.Printf("done!\n")
2424+}
37253838-CREATE TABLE IF NOT EXISTS musiccredits (
3939- release VARCHAR(64) REFERENCES musicreleases(ID) ON DELETE CASCADE,
4040- artist TEXT REFERENCES artists(id) ON DELETE CASCADE,
4141- role TEXT,
4242- meta BOOLEAN,
4343- constraint musiccredits_pk PRIMARY KEY (release, artist)
4444-);
2626+func PullAllArtists(db *sqlx.DB) ([]*music.Artist, error) {
2727+ artists := []*music.Artist{}
45284646-CREATE TABLE IF NOT EXISTS musictracks (
4747- release VARCHAR(64) REFERENCES musicreleases(ID) ON DELETE CASCADE,
4848- number INT NOT NULL,
4949- title TEXT NOT NULL,
5050- description TEXT,
5151- lyrics TEXT,
5252- preview_url TEXT,
5353- CONSTRAINT musictracks_pk PRIMARY KEY (release, number)
5454-);`
2929+ rows, err := db.Query("SELECT id, name, website FROM artists")
3030+ if err != nil {
3131+ return nil, err
3232+ }
55335656-func PushArtist(db *sqlx.DB, artist music.Artist) {
5757- fmt.Printf("syncing artist [%s] to database...", artist.Name)
3434+ for rows.Next() {
3535+ var artist = music.Artist{}
3636+ err = rows.Scan(&artist.Id, &artist.Name, &artist.Website)
3737+ if err != nil {
3838+ return nil, err
3939+ }
4040+ artists = append(artists, &artist)
4141+ }
58425959- db.MustExec("INSERT INTO artists (id, name, website) VALUES ($1, $2, $3) ON CONFLICT (id) DO UPDATE SET name=$2, website=$3",
6060- &artist.Id,
6161- &artist.Name,
6262- &artist.Website,
6363-)
4343+ return artists, nil
4444+}
4545+4646+func PullArtist(db *sqlx.DB, artistID string) (music.Artist, error) {
4747+ artist := music.Artist{}
4848+4949+ err := db.Get(&artist, "SELECT id, name, website FROM artists WHERE id=$1", artistID)
5050+ if err != nil {
5151+ return music.Artist{}, err
5252+ }
64536565-fmt.Printf("done!\n")
5454+ return artist, nil
6655}
67566857func PushRelease(db *sqlx.DB, release music.MusicRelease) {
6969- fmt.Printf("syncing release [%s] to database...", release.Id)
5858+ fmt.Printf("pushing release [%s] to database...", release.Id)
70597160 tx := db.MustBegin()
7261 tx.MustExec("INSERT INTO musicreleases (id, title, type, release_date, artwork, buyname, buylink) VALUES ($1, $2, $3, $4, $5, $6, $7) "+
···7867 &release.Id, &link.Name, &link.Url)
7968 }
8069 for _, credit := range release.Credits {
8181- tx.MustExec("INSERT INTO musiccredits (release, artist, role, meta) VALUES ($1, $2, $3, $4) ON CONFLICT DO NOTHING",
8282- &release.Id, &credit.Artist.Id, &credit.Role, &credit.Meta)
7070+ tx.MustExec("INSERT INTO musiccredits (release, artist, role, is_primary) VALUES ($1, $2, $3, $4) ON CONFLICT DO NOTHING",
7171+ &release.Id, &credit.Artist.Id, &credit.Role, &credit.Primary)
8372 }
8473 for _, track := range release.Tracks {
8574 tx.MustExec("INSERT INTO musictracks (release, number, title, description, lyrics, preview_url) VALUES ($1, $2, $3, $4, $5, $6) "+
···9281 fmt.Printf("done!\n")
9382}
94838484+func PullAllReleases(db *sqlx.DB) ([]*music.MusicRelease, error) {
8585+ releases := []*music.MusicRelease{}
8686+8787+ rows, err := db.Query("SELECT id, title, type, release_date, artwork, buyname, buylink FROM musicreleases")
8888+ if err != nil {
8989+ return nil, err
9090+ }
9191+9292+ for rows.Next() {
9393+ var release = music.MusicRelease{}
9494+ release.Credits = []music.MusicCredit{}
9595+ release.Links = []music.MusicLink{}
9696+ release.Tracks = []music.MusicTrack{}
9797+9898+ err = rows.Scan(
9999+ &release.Id,
100100+ &release.Title,
101101+ &release.Type,
102102+ &release.ReleaseDate,
103103+ &release.Artwork,
104104+ &release.Buyname,
105105+ &release.Buylink)
106106+ if err != nil {
107107+ continue
108108+ }
109109+110110+ // pull musiccredits for artist data
111111+ credit_rows, err := db.Query("SELECT artist, role, is_primary FROM musiccredits WHERE release=$1", release.Id)
112112+ if err != nil {
113113+ fmt.Printf("error pulling credits for %s: %v\n", release.Id, err)
114114+ continue
115115+ }
116116+ for credit_rows.Next() {
117117+ var artistID string
118118+ var credit = music.MusicCredit{}
119119+ err = credit_rows.Scan(
120120+ &artistID,
121121+ &credit.Role,
122122+ &credit.Primary)
123123+ if err != nil {
124124+ fmt.Printf("error pulling credit for %s: %v\n", release.Id, err)
125125+ continue
126126+ }
127127+ artist, err := music.GetArtist(artistID)
128128+ if err != nil {
129129+ fmt.Printf("error pulling credit for %s: %v\n", release.Id, err)
130130+ continue
131131+ }
132132+ credit.Artist = artist
133133+ release.Credits = append(release.Credits, credit)
134134+ }
135135+136136+ // pull musiclinks for link data
137137+ link_rows, err := db.Query("SELECT name, url FROM musiclinks WHERE release=$1", release.Id);
138138+ if err != nil {
139139+ fmt.Printf("error pulling links for %s: %v\n", release.Id, err)
140140+ continue
141141+ }
142142+ for link_rows.Next() {
143143+ var link = music.MusicLink{}
144144+ err = link_rows.Scan(
145145+ &link.Name,
146146+ &link.Url)
147147+ if err != nil {
148148+ fmt.Printf("error pulling link for %s: %v\n", release.Id, err)
149149+ continue
150150+ }
151151+ release.Links = append(release.Links, link)
152152+ }
153153+154154+ // pull musictracks for track data
155155+ track_rows, err := db.Query("SELECT number, title, description, lyrics, preview_url FROM musictracks WHERE release=$1", release.Id);
156156+ if err != nil {
157157+ fmt.Printf("error pulling tracks for %s: %v\n", release.Id, err)
158158+ continue
159159+ }
160160+ for track_rows.Next() {
161161+ var track = music.MusicTrack{}
162162+ err = track_rows.Scan(
163163+ &track.Number,
164164+ &track.Title,
165165+ &track.Description,
166166+ &track.Lyrics,
167167+ &track.PreviewUrl)
168168+ if err != nil {
169169+ fmt.Printf("error pulling track for %s: %v\n", release.Id, err)
170170+ continue
171171+ }
172172+ release.Tracks = append(release.Tracks, track)
173173+ }
174174+175175+ releases = append(releases, &release)
176176+ }
177177+178178+ return releases, nil
179179+}
180180+181181+func PullRelease(db *sqlx.DB, releaseID string) (music.MusicRelease, error) {
182182+ release := music.MusicRelease{}
183183+184184+ err := db.Get(&release, "SELECT id, title, type, release_date, artwork, buyname, buylink FROM musicreleases WHERE id=$1", releaseID)
185185+ if err != nil {
186186+ return music.MusicRelease{}, err
187187+ }
188188+189189+ return release, nil
190190+}
191191+95192func InitDatabase() *sqlx.DB {
96193 db, err := sqlx.Connect("postgres", "user=arimelody dbname=arimelody password=fuckingpassword sslmode=disable")
97194 if err != nil {
···102199 db.SetConnMaxLifetime(time.Minute * 3)
103200 db.SetMaxOpenConns(10)
104201 db.SetMaxIdleConns(10)
105105-106106- db.MustExec(schema)
107107- fmt.Printf("database schema synchronised.\n")
108202109203 return db
110204}
+44
discord/discord.go
···11+package discord
22+33+const API_ENDPOINT = "https://discord.com/api/v10"
44+const CLIENT_ID = "1268013769578119208"
55+// TODO: good GOD change this later please i beg you. we've already broken
66+// the rules by doing this at all
77+const CLIENT_SECRET = "JUEZnixhN7BxmLIHmbECiKETMP85VT0E"
88+const REDIRECT_URI = "https://discord.com/oauth2/authorize?client_id=1268013769578119208&response_type=code&redirect_uri=http%3A%2F%2F127.0.0.1%3A8080%2Fapi%2Fv1%2Fadmin%2Flogin&scope=identify"
99+// TODO: change before prod
1010+const MY_REDIRECT_URI = "http://127.0.0.1:8080/api/v1/admin/login"
1111+1212+type (
1313+ AccessTokenResponse struct {
1414+ TokenType string `json:"token_type"`
1515+ AccessToken string `json:"access_token"`
1616+ ExpiresIn int `json:"expires_in"`
1717+ RefreshToken string `json:"refresh_token"`
1818+ Scope string `json:"scope"`
1919+ }
2020+2121+ AuthInfoResponse struct {
2222+ Application struct {
2323+ Id string
2424+ Name string
2525+ Icon string
2626+ Description string
2727+ Hook bool
2828+ BotPublic bool
2929+ botRequireCodeGrant bool
3030+ VerifyKey bool
3131+ }
3232+ Scopes []string
3333+ Expires string
3434+ User struct {
3535+ Id string
3636+ Username string
3737+ Avatar string
3838+ Discriminator string
3939+ GlobalName string
4040+ PublicFlags int
4141+ }
4242+ }
4343+)
4444+
···3232 </div>
3333 <div class="music-details">
3434 <a href="/music/{{$Album.Id}}"><h1 class="music-title">{{$Album.Title}}</h1></a>
3535- <h2 class="music-artist">{{$Album.PrintPrimaryArtists false}}</h2>
3535+ <h2 class="music-artist">{{$Album.PrintPrimaryArtists false true}}</h2>
3636 <h3 class="music-type-{{.ResolveType}}">{{$Album.ResolveType}}</h3>
3737 <ul class="music-links">
3838 {{range $Link := $Album.Links}}
···4646 {{end}}
4747 </div>
48484949- <h2 id="usage" class="question" swap-url="/music#usage">
5050- <a href="#usage">
5151- > "can i use your music in my content?"
5252- </a>
4949+ <h2 id="usage" class="question">
5050+ <a href="#usage">
5151+ > "can i use your music in my content?"
5252+ </a>
5353 </h2>
5454 <div class="answer">
5555- <p>
5656- <strong class="big">yes!</strong> well, in most cases...
5757- </p>
5858- <p>
5959- from <a href="/music/dream">Dream (2022)</a> onward, all of my <em>self-released</em> songs are
6060- licensed under <a href="https://creativecommons.org/licenses/by-sa/3.0/" target="_blank">Creative Commons Attribution-ShareAlike 3.0</a>. anyone may use these
6161- songs freely, so long as they provide credit back to me!
6262- </p>
6363- <p>
6464- a great example of some credit text would be as follows:
6565- </p>
6666- <blockquote>
6767- music used: mellodoot - Dream<br>
6868- buy it here: <a href="/music/dream">https://arimelody.me/music/dream</a><br>
6969- licensed under CC BY-SA 3.0.
7070- </blockquote>
7171- <p>
7272- for any songs prior to this, they were all either released by me (in which case, i honestly
7373- don't mind), or in collaboration with chill people who i don't see having an issue with it.
7474- do be sure to ask them about it, though!
7575- </p>
7676- <p>
7777- in the event the song you want to use is released under some other label, their usage rights
7878- will more than likely trump whatever i'd otherwise have in mind. i'll try to negotiate some
7979- nice terms, though! ;3
8080- </p>
8181- <p>
8282- i love the idea of other creators using my songs in their work, so if you do happen to use
8383- my stuff in a work you're particularly proud of, feel free to send it my way!
8484- </p>
8585- <p>
8686- > <a href="mailto:ari@arimelody.me">ari@arimelody.me</a>
8787- </p>
5555+ <p>
5656+ <strong class="big">yes!</strong> well, in most cases...
5757+ </p>
5858+ <p>
5959+ from <a href="/music/dream">Dream (2022)</a> onward, all of my <em>self-released</em> songs are
6060+ licensed under <a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank">Creative Commons Attribution-ShareAlike 4.0</a>.
6161+ anyone may use and remix these songs freely, so long as they provide credit back to me and link back to this license!
6262+ please note that all derivative works must inherit this license.
6363+ </p>
6464+ <p>
6565+ a great example of some credit text would be as follows:
6666+ </p>
6767+ <blockquote>
6868+ music used: mellodoot - Dream<br>
6969+ <a href="/music/dream">https://arimelody.me/music/dream</a><br>
7070+ licensed under <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a>.
7171+ </blockquote>
7272+ <p>
7373+ for any songs prior to this, they were all either released by me (in which case, i honestly
7474+ don't mind), or in collaboration with chill people who i don't see having an issue with it.
7575+ do be sure to ask them about it, though!
7676+ </p>
7777+ <p>
7878+ in the event the song you want to use is released under some other label, their usage rights
7979+ will more than likely trump whatever i'd otherwise have in mind. i'll try to negotiate some
8080+ nice terms, though! ;3
8181+ </p>
8282+ <p>
8383+ i love the idea of other creators using my songs in their work, so if you do happen to use
8484+ my stuff in a work you're particularly proud of, feel free to send it my way!
8585+ </p>
8686+ <p>
8787+ > <a href="mailto:ari@arimelody.me">ari@arimelody.me</a>
8888+ </p>
8889 </div>
89909091 <a href="#" id="backtotop">back to top</a>