Compare commits

...
Sign in to create a new pull request.

14 commits

18 changed files with 189 additions and 134 deletions

View file

@ -1,17 +1,12 @@
# arimelody.me
# ari melody website
home to your local SPACEGIRL! 💫
---
built up from the initial [static](https://git.arimelody.me/ari/arimelody.me-static)
branch, this powerful, server-side rendered version comes complete with live
updates, powered by a new database and handy admin panel!
the admin panel currently facilitates live updating of my music discography,
though i plan to expand it towards art portfolio and blog posts in the future.
if all goes well, i'd like to later separate these components into their own
library for others to use in their own sites. exciting stuff!
a slightly-overcomplicated webserver built to show off everything i've worked
on, and then some! this server comes complete with twitch live status tracking,
a portfolio database, and a full-fledged admin CMS panel to manage it all!
## build

View file

@ -18,7 +18,7 @@
<nav>
<img src="/img/favicon.png" alt="" class="icon">
<div class="nav-item">
<a href="/">arimelody.me</a>
<a href="/">ari melody</a>
</div>
<div class="nav-item">
<a href="/admin">home</a>

View file

@ -18,7 +18,7 @@ func GetConfig() model.Config {
}
config := model.Config{
BaseUrl: "https://arimelody.me",
BaseUrl: "https://arimelody.space",
Host: "0.0.0.0",
Port: 8080,
TrustedProxies: []string{ "127.0.0.1" },

View file

@ -188,3 +188,7 @@ func DeleteSession(db *sqlx.DB, token string) error {
return err
}
func DeleteExpiredSessions(db *sqlx.DB) error {
_, err := db.Exec("DELETE FROM session WHERE expires_at<current_timestamp")
return err
}

View file

@ -58,12 +58,12 @@ func GenerateTOTPURI(username string, secret string) string {
url := url.URL{
Scheme: "otpauth",
Host: "totp",
Path: url.QueryEscape("arimelody.me") + ":" + url.QueryEscape(username),
Path: url.QueryEscape("arimelody.space") + ":" + url.QueryEscape(username),
}
query := url.Query()
query.Set("secret", secret)
query.Set("issuer", "arimelody.me")
query.Set("issuer", "arimelody.space")
// query.Set("algorithm", "SHA1")
// query.Set("digits", fmt.Sprintf("%d", TOTP_CODE_LENGTH))
// query.Set("period", fmt.Sprintf("%d", TOTP_TIME_STEP))

View file

@ -1,6 +1,6 @@
services:
web:
image: docker.arimelody.me/arimelody.me:latest
image: docker.arimelody.space/arimelody-web:latest
build: .
ports:
- 8080:8080

49
main.go
View file

@ -33,6 +33,7 @@ import (
const DB_VERSION = 1
const DEFAULT_PORT int64 = 8080
const HRT_DATE int64 = 1756478697
func main() {
fmt.Printf("made with <3 by ari melody\n\n")
@ -487,6 +488,13 @@ func main() {
fmt.Printf("No accounts exist! Generated invite code: %s\n", invite.Code)
}
// delete expired sessions
err = controller.DeleteExpiredSessions(app.DB)
if err != nil {
fmt.Fprintf(os.Stderr, "FATAL: Failed to clear expired sessions: %v\n", err)
os.Exit(1)
}
// delete expired invites
err = controller.DeleteExpiredInvites(app.DB)
if err != nil {
@ -508,7 +516,7 @@ func main() {
fmt.Printf("Now serving at http://%s:%d\n", app.Config.Host, app.Config.Port)
stdLog.Fatal(
http.ListenAndServe(fmt.Sprintf("%s:%d", app.Config.Host, app.Config.Port),
HTTPLog(DefaultHeaders(mux)),
CheckRequest(&app, HTTPLog(DefaultHeaders(mux))),
))
}
@ -555,9 +563,40 @@ var PoweredByStrings = []string{
"30 billion dollars in VC funding",
}
func CheckRequest(app *model.AppState, next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// requests with empty user agents are considered suspicious.
// every browser supplies them; hell, even curl supplies them.
// i only ever see null user-agents paired with malicious requests,
// so i'm canning them altogether.
if len(r.Header.Get("User-Agent")) == 0 {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
// same with .php and awkward double-slash requests.
// obviously these don't affect me, but these tend to be lazy intrusion
// attempts. if that's what you're about, i don't want you on my site.
if strings.HasPrefix(r.URL.Path, "//") ||
strings.HasSuffix(r.URL.Path, ".php") ||
strings.HasSuffix(r.URL.Path, ".php7") {
http.NotFound(w, r)
fmt.Fprintf(
os.Stderr,
"WARN: Suspicious activity blocked: {\"path\":\"%s\",\"address\":\"%s\"}\n",
r.URL.Path,
r.RemoteAddr,
)
return
}
next.ServeHTTP(w, r)
})
}
func DefaultHeaders(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Server", "arimelody.me")
w.Header().Add("Server", "ari melody webbed site")
w.Header().Add("Do-Not-Stab", "1")
w.Header().Add("X-Clacks-Overhead", "GNU Terry Pratchett")
w.Header().Add("X-Hacker", "spare me please")
@ -567,6 +606,10 @@ func DefaultHeaders(next http.Handler) http.Handler {
"X-Powered-By",
PoweredByStrings[rand.Intn(len(PoweredByStrings))],
)
w.Header().Add(
"X-Days-Since-HRT",
fmt.Sprint(math.Round(time.Since(time.Unix(HRT_DATE, 0)).Hours() / 24)),
)
next.ServeHTTP(w, r)
})
}
@ -619,6 +662,6 @@ func HTTPLog(next http.Handler) http.Handler {
lrw.Status,
colour.Reset,
elapsed,
r.Header["User-Agent"][0])
r.Header.Get("User-Agent"))
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -1,32 +1,32 @@
<!--
pride flag - copyright (c) 2024 ari melody
this code is provided AS-IS, WITHOUT ANY WARRANTY, to be
freely redistributed and/or modified as you please, however
retaining this license in any redistribution.
please use this flag to link to an LGBTQI+-supporting page
of your choosing!
web: https://arimelody.me
source: https://git.arimelody.me/ari/prideflag
-->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="120" height="120">
<path id="red" d="M120,80 L100,100 L120,120 Z" style="fill:#d20605"/>
<path id="orange" d="M120,80 V40 L80,80 L100,100 Z" style="fill:#ef9c00"/>
<path id="yellow" d="M120,40 V0 L60,60 L80,80 Z" style="fill:#e5fe02"/>
<path id="green" d="M120,0 H80 L40,40 L60,60 Z" style="fill:#09be01"/>
<path id="blue" d="M80,0 H40 L20,20 L40,40 Z" style="fill:#081a9a"/>
<path id="purple" d="M40,0 H0 L20,20 Z" style="fill:#76008a"/>
<rect id="black" x="60" width="60" height="60" style="fill:#010101"/>
<rect id="brown" x="70" width="50" height="50" style="fill:#603814"/>
<rect id="lightblue" x="80" width="40" height="40" style="fill:#73d6ed"/>
<rect id="pink" x="90" width="30" height="30" style="fill:#ffafc8"/>
<rect id="white" x="100" width="20" height="20" style="fill:#fff"/>
<rect id="intyellow" x="110" width="10" height="10" style="fill:#fed800"/>
<circle id="intpurple" cx="120" cy="0" r="5" stroke="#7601ad" stroke-width="2" fill="none"/>
</svg>
<!--
pride flag - copyright (c) 2024 ari melody
this code is provided AS-IS, WITHOUT ANY WARRANTY, to be
freely redistributed and/or modified as you please, however
retaining this license in any redistribution.
please use this flag to link to an LGBTQI+-supporting page
of your choosing!
web: https://arimelody.space
source: https://forge.arimelody.space/ari/prideflag
-->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="120" height="120">
<path id="red" d="M120,80 L100,100 L120,120 Z" style="fill:#d20605"/>
<path id="orange" d="M120,80 V40 L80,80 L100,100 Z" style="fill:#ef9c00"/>
<path id="yellow" d="M120,40 V0 L60,60 L80,80 Z" style="fill:#e5fe02"/>
<path id="green" d="M120,0 H80 L40,40 L60,60 Z" style="fill:#09be01"/>
<path id="blue" d="M80,0 H40 L20,20 L40,40 Z" style="fill:#081a9a"/>
<path id="purple" d="M40,0 H0 L20,20 Z" style="fill:#76008a"/>
<rect id="black" x="60" width="60" height="60" style="fill:#010101"/>
<rect id="brown" x="70" width="50" height="50" style="fill:#603814"/>
<rect id="lightblue" x="80" width="40" height="40" style="fill:#73d6ed"/>
<rect id="pink" x="90" width="30" height="30" style="fill:#ffafc8"/>
<rect id="white" x="100" width="20" height="20" style="fill:#fff"/>
<rect id="intyellow" x="110" width="10" height="10" style="fill:#fed800"/>
<circle id="intpurple" cx="120" cy="0" r="5" stroke="#7601ad" stroke-width="2" fill="none"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before After
Before After

View file

@ -1,26 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEZNW03RYJKwYBBAHaRw8BAQdAuMUNVjXT7m/YisePPnSYY6lc1Xmm3oS79ZEO
JriRCZy0HWFyaSBtZWxvZHkgPGFyaUBhcmltZWxvZHkubWU+iJkEExYKAEECGwMF
CwkIBwICIgIGFQoJCAsCBBYCAwECHgcCF4AWIQTujeuNYocuegkeKt/PmYKckmeB
iAUCZ7UqUAUJCIMP8wAKCRDPmYKckmeBiO/NAP0SoJL4aKZqCeYiSoDF/Uw6nMmZ
+oR1Uig41wQ/IDbhCAEApP2vbjSIu6pcp0AQlL7qcoyPWv+XkqPSFqW9KEZZVwqI
kwQTFgoAOxYhBO6N641ihy56CR4q38+ZgpySZ4GIBQJk1bTdAhsDBQsJCAcCAiIC
BhUKCQgLAgQWAgMBAh4HAheAAAoJEM+ZgpySZ4GIYJsA/jBNwsJTlmV9JMmsW0aF
ApYDoPG1Q7sJ6CRW7xKCRjcqAQDX9iqNnW9Jqo8M3jXfu+aGSF926hg6M3SKm02P
f27bAbgzBGe1JooWCSsGAQQB2kcPAQEHQJbfh5iLHEpZndMgekqYzqTrUoAJ8ZIL
d4WH0dcw9tOaiPUEGBYKACYCGwIWIQTujeuNYocuegkeKt/PmYKckmeBiAUCZ7Uq
VgUJBaOeTACBdiAEGRYKAB0WIQQlu5dWmBR/P3ZxngxgtfA4bj3bfgUCZ7UmigAK
CRBgtfA4bj3bfux+AP4y5ydrjnGBMX7GuB2nh55SRdscSiXsZ66ntnjXyQcbWgEA
pDuu7FqXzXcnluuZxNFDT740Rnzs60tTeplDqGGWcAQJEM+ZgpySZ4GIc0kA/iSw
Nw+r3FC75omwrPpJF13B5fq93FweFx+oSaES6qzkAQDvgCK77qKKbvCju0g8zSsK
EZnv6xR4uvtGdVkvLpBdC7gzBGe1JpkWCSsGAQQB2kcPAQEHQGnU4lXFLchhKYkC
PshP+jvuRsNoedaDOK2p4dkQC8JuiH4EGBYKACYCGyAWIQTujeuNYocuegkeKt/P
mYKckmeBiAUCZ7UqXgUJBaOeRQAKCRDPmYKckmeBiL9KAQCJZIBhuSsoYa61I0XZ
cKzGZbB0h9pD6eg1VRswNIgHtQEAwu9Hgs1rs9cySvKbO7WgK6Qh6EfrvGgGOXCO
m3wVsg24OARntSo5EgorBgEEAZdVAQUBAQdA+/k586W1OHxndzDJNpbd+wqjyjr0
D5IXxfDs00advB0DAQgHiH4EGBYKACYWIQTujeuNYocuegkeKt/PmYKckmeBiAUC
Z7UqOQIbDAUJBaOagAAKCRDPmYKckmeBiEFxAQCgziQt2l3u7jnZVij4zop+K2Lv
TVFtkbG61tf6brRzBgD/X6c6X5BRyQC51JV1I1RFRBdeMAIXzcLFg2v3WUMccQs=
=YmHI
-----END PGP PUBLIC KEY BLOCK-----

View file

@ -0,0 +1,59 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mDMEZNW03RYJKwYBBAHaRw8BAQdAuMUNVjXT7m/YisePPnSYY6lc1Xmm3oS79ZEO
JriRCZy0IGFyaSBtZWxvZHkgPGFyaUBhcmltZWxvZHkuc3BhY2U+iQJJBBMWCgHx
AhsDBQsJCAcCAiICBhUKCQgLAgQWAgMBAh4HAheAAhkBNRSAAAAAABAAHHByb29m
QGFyaWFkbmUuaWRkbnM6YXJpbWVsb2R5LnNwYWNlP3R5cGU9VFhUOhSAAAAAABAA
IXByb29mQGFyaWFkbmUuaWRodHRwczovL2ZlZGkuYXJpbWVsb2R5LnNwYWNlL0Bh
cmlEFIAAAAAAEAArcHJvb2ZAYXJpYWRuZS5pZGh0dHBzOi8vZm9yZ2UuYmxpc3Mu
dG93bi9hcmkva2V5b3hpZGUtcHJvb2ZJFIAAAAAAEAAwcHJvb2ZAYXJpYWRuZS5p
ZGh0dHBzOi8vZm9yZ2UuYXJpbWVsb2R5LnNwYWNlL2FyaS9rZXlveGlkZS1wcm9v
ZkYUgAAAAAAQAC1wcm9vZkBhcmlhZG5lLmlkaHR0cHM6Ly9jb2RlYmVyZy5vcmcv
YXJpbWVsb2R5L2tleW94aWRlLXByb29mZRSAAAAAABAATHByb29mQGFyaWFkbmUu
aWRodHRwczovL2Jza3kuYXBwL3Byb2ZpbGUvZGlkOnBsYzp5Y3Q2Y3ZnZmlwbmdp
enJ5NXVtemt4cjMvcG9zdC8zbGlpbnFvdHF0YzIyFiEE7o3rjWKHLnoJHirfz5mC
nJJngYgFAmivQJsFCQ0/jT4ACgkQz5mCnJJngYgdtQD+K8AMkLvR1ZKxl0tw8/FO
vwS9HknEW13GajSAY/W1/NoA/17mnVnlTFhepKo1ETnxe2BpdOaKR85K0n2qffzC
8SAAtB1hcmkgbWVsb2R5IDxhcmlAYXJpbWVsb2R5Lm1lPoiTBBMWCgA7FiEE7o3r
jWKHLnoJHirfz5mCnJJngYgFAmTVtN0CGwMFCwkIBwICIgIGFQoJCAsCBBYCAwEC
HgcCF4AACgkQz5mCnJJngYhgmwD+ME3CwlOWZX0kyaxbRoUClgOg8bVDuwnoJFbv
EoJGNyoBANf2Ko2db0mqjwzeNd+75oZIX3bqGDozdIqbTY9/btsBiQIKBBMWCgGy
AhsDBQsJCAcCAiICBhUKCQgLAgQWAgMBAh4HAheABQkIgw/zFiEE7o3rjWKHLnoJ
Hirfz5mCnJJngYgFAme1wUA2FIAAAAAAEAAdcHJvb2ZAYXJpYWRuZS5pZGh0dHBz
Oi8vaWNlLmFyaW1lbG9keS5tZS9AYXJpWxSAAAAAABAAQnByb29mQGFyaWFkbmUu
aWRodHRwczovL2dpc3QuZ2l0aHViLmNvbS9hcmltZWxvZHkvMzY2ZGMyYjZhYWVk
ZWMxOWU2MTRiN2NlY2U5Yzg2OWQyFIAAAAAAEAAZcHJvb2ZAYXJpYWRuZS5pZGRu
czphcmltZWxvZHkubWU/dHlwZT1UWFRlFIAAAAAAEABMcHJvb2ZAYXJpYWRuZS5p
ZGh0dHBzOi8vYnNreS5hcHAvcHJvZmlsZS9kaWQ6cGxjOnljdDZjdmdmaXBuZ2l6
cnk1dW16a3hyMy9wb3N0LzNsaWlucW90cXRjMjJEFIAAAAAAEAArcHJvb2ZAYXJp
YWRuZS5pZGh0dHBzOi8vZ2l0LmFyaW1lbG9keS5tZS9hcmkva2V5b3hpZGVfcHJv
b2YACgkQz5mCnJJngYh3+QD+Pbo3bM4oWtUicGUGEp4jiFoBqSNlyl9rFPY0ODDS
DxEBANaXz/No/Hn3mEwNdrFigj/YPm7TH/4UBbHAxN6hDggPiQJGBBMWCgHuAhsD
BQsJCAcCAiICBhUKCQgLAgQWAgMBAh4HAheASRSAAAAAABAAMHByb29mQGFyaWFk
bmUuaWRodHRwczovL2ZvcmdlLmFyaW1lbG9keS5zcGFjZS9hcmkva2V5b3hpZGUt
cHJvb2ZGFIAAAAAAEAAtcHJvb2ZAYXJpYWRuZS5pZGh0dHBzOi8vY29kZWJlcmcu
b3JnL2FyaW1lbG9keS9rZXlveGlkZS1wcm9vZjoUgAAAAAAQACFwcm9vZkBhcmlh
ZG5lLmlkaHR0cHM6Ly9mZWRpLmFyaW1lbG9keS5zcGFjZS9AYXJpZRSAAAAAABAA
THByb29mQGFyaWFkbmUuaWRodHRwczovL2Jza3kuYXBwL3Byb2ZpbGUvZGlkOnBs
Yzp5Y3Q2Y3ZnZmlwbmdpenJ5NXVtemt4cjMvcG9zdC8zbGlpbnFvdHF0YzIyNRSA
AAAAABAAHHByb29mQGFyaWFkbmUuaWRkbnM6YXJpbWVsb2R5LnNwYWNlP3R5cGU9
VFhURBSAAAAAABAAK3Byb29mQGFyaWFkbmUuaWRodHRwczovL2ZvcmdlLmJsaXNz
LnRvd24vYXJpL2tleW94aWRlLXByb29mFiEE7o3rjWKHLnoJHirfz5mCnJJngYgF
AmivQJsFCQ0/jT4ACgkQz5mCnJJngYhk/wEAuQMYpUgyLqcYvOh1A+7f/t+DUXjz
YjQtLYw37oAESREA/074iJNi9GHGIjxYfp5lBkZxqGew1GAFIKx7Yzp64WQFuDME
Z7UmihYJKwYBBAHaRw8BAQdAlt+HmIscSlmd0yB6SpjOpOtSgAnxkgt3hYfR1zD2
05qI9QQYFgoAJgIbAhYhBO6N641ihy56CR4q38+ZgpySZ4GIBQJor0AjBQkKYBsZ
AIF2IAQZFgoAHRYhBCW7l1aYFH8/dnGeDGC18DhuPdt+BQJntSaKAAoJEGC18Dhu
Pdt+7H4A/jLnJ2uOcYExfsa4HaeHnlJF2xxKJexnrqe2eNfJBxtaAQCkO67sWpfN
dyeW65nE0UNPvjRGfOzrS1N6mUOoYZZwBAkQz5mCnJJngYgc2gD/cFhjrwPdex9g
ZYk7jH29wQ9RpR9dEhf0C20nFZJLawgBAOBbzw4/O7OslSoIjhGs4pw9hJIBK7ds
PI6g3CeX0DUFuDMEZ7UmmRYJKwYBBAHaRw8BAQdAadTiVcUtyGEpiQI+yE/6O+5G
w2h51oM4ranh2RALwm6IfgQYFgoAJgIbIBYhBO6N641ihy56CR4q38+ZgpySZ4GI
BQJor0AjBQkKYBsKAAoJEM+ZgpySZ4GIoMAA/jB/exnjGvsMKuNW09bI29bsKHNW
SQLjEnuuByN6Spq6AP9yPUumsSEHr0W71iefMuNFJZnF+8qSk+uywQ/5ET+PBbg4
BGe1KjkSCisGAQQBl1UBBQEBB0D7+TnzpbU4fGd3MMk2lt37CqPKOvQPkhfF8OzT
Rp28HQMBCAeIfgQYFgoAJgIbDBYhBO6N641ihy56CR4q38+ZgpySZ4GIBQJor0Ak
BQkKYBdqAAoJEM+ZgpySZ4GIlIoA/0fv2UQyhixu7Vkq7IeQ+NxUuEVCIGmrAu6k
ScT13ikjAQCPpIubU848yXcDUvxgcGAS7yNADU1dAWAZOi34WxajAQ==
=caf3
-----END PGP PUBLIC KEY BLOCK-----

View file

@ -1,4 +1,4 @@
const ARIMELODY_CONFIG_NAME = "arimelody.me-config";
const ARIMELODY_CONFIG_NAME = "arimelody-web-config";
class Config {
_crt = false;

View file

@ -8,11 +8,11 @@
// please use this flag to link to an LGBTQI+-supporting page
// of your choosing!
//
// web: https://arimelody.me
// source: https://git.arimelody.me/ari/prideflag
// web: https://arimelody.space
// source: https://forge.arimelody.space/ari/prideflag
//
const pride_url = "https://git.arimelody.me/ari/prideflag";
const pride_url = "https://forge.arimelody.space/ari/prideflag";
const pride_flag_svg =
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="120" height="120">

View file

@ -242,7 +242,7 @@ div#web-buttons {
.live-preview {
display: flex;
flex-direction: row;
justify-content: center;
justify-content: start;
gap: 1em;
}

View file

@ -5,7 +5,7 @@
<small>
<em>
*made with <span aria-label="love"></span> by ari, 2025*
<a href="https://git.arimelody.me/ari/arimelody.me" target="_blank">source</a>
<a href="https://forge.arimelody.space/ari/arimelody-web" target="_blank">source</a>
</em>
</small>
</div>

View file

@ -6,16 +6,15 @@
<meta property="og:title" content="ari melody">
<meta property="og:type" content="website">
<meta property="og:url" content="www.arimelody.me">
<meta property="og:image" content="https://www.arimelody.me/img/favicon.png">
<meta property="og:site_name" content="ari melody">
<meta property="og:url" content="www.arimelody.space">
<meta property="og:image" content="https://www.arimelody.space/img/favicon.png">
<meta property="og:site_name" content="ari melody 💫">
<meta property="og:description" content="home to your local SPACEGIRL 💫">
<link rel="stylesheet" href="/style/main.css">
<link rel="stylesheet" href="/style/index.css">
<link rel="me" href="https://ice.arimelody.me/@ari">
<link rel="me" href="https://wetdry.world/@ari">
<link rel="me" href="https://fedi.arimelody.space/@ari">
<script type="module" src="/script/index.js" defer></script>
{{end}}
@ -67,7 +66,7 @@
</p>
<p>
for anything else, you can reach me for any and all communications through
<a href="mailto:ari@arimelody.me">ari@arimelody.me</a>. if your message
<a href="mailto:ari@arimelody.space">ari@arimelody.space</a>. if your message
contains anything beyond a silly gag, i strongly recommend encrypting
your message using my public pgp key, listed below!
</p>
@ -94,35 +93,13 @@
<strong>my keys 🔑</strong>
</p>
<ul>
<li>pgp: <a href="/keys/ari melody_0x92678188_public.asc" target="_blank">[link]</a></li>
<li>pgp: <a href="/keys/ari@arimelody.space_public.asc" target="_blank">[link]</a></li>
<li>ssh (ed25519): <a href="/keys/id_ari_ed25519.pub" target="_blank">[link]</a></li>
</ul>
<p>
<strong>where to find me 🛰️</strong>
</p>
<!--
<ul class="links">
<li>
<a href="https://youtube.com/@arispacegirl">youtube</a>
</li>
<li>
<a href="https://twitch.tv/arispacegirl">twitch</a>
</li>
<li>
<a href="https://arimelody.bandcamp.com">bandcamp</a>
</li>
<li>
<a href="https://codeberg.org/arimelody">codeberg</a>
</li>
<li>
<a href="https://bsky.app/profile/arimelody.me">bluesky</a>
</li>
<li>
<a href="https://discord.gg/MmJtBebF28">discord</a>
</li>
</ul>
-->
<ul class="platform-links">
<li>
<a href="https://youtube.com/@arispacegirl" title="youtube">
@ -149,13 +126,13 @@
</a>
</li>
<li>
<a href="https://bsky.app/profile/arimelody.me" title="bluesky">
<a href="https://bsky.app/profile/arimelody.space" title="bluesky">
<img src="/img/brand/bluesky.svg" alt="bluesky" width="32" height="32"/>
bluesky
</a>
</li>
<li>
<a href="https://discord.gg/MmJtBebF28" title="discord">
<a href="https://arimelody.space/discord" title="discord">
<img src="/img/brand/discord.svg" alt="discord" width="32" height="32"/>
discord
</a>
@ -174,16 +151,16 @@
</div>
</li>
<li class="project-item">
<img src="https://catdance.arimelody.me/img/favicon.png" alt="catdance icon" aria-hidden=true class="project-icon" width="64" height="64">
<img src="https://catdance.arimelody.space/img/favicon.png" alt="catdance icon" aria-hidden=true class="project-icon" width="64" height="64">
<div class="project-info">
<a href="https://catdance.arimelody.me">catdance</a>
<a href="https://catdance.arimelody.space">catdance</a>
<p>watch the cat dance 🐱</p>
</div>
</li>
<li class="project-item">
<img src="https://git.arimelody.me/repo-avatars/6b0a1ffb78cbc6f906f83152ea42a710220174e8f48a3e44f159ae58dacd7a2f" alt="catdance icon" aria-hidden=true class="project-icon" width="64" height="64">
<img src="https://forge.arimelody.space/repo-avatars/6b0a1ffb78cbc6f906f83152ea42a710220174e8f48a3e44f159ae58dacd7a2f" alt="pride flag icon" aria-hidden=true class="project-icon" width="64" height="64">
<div class="project-info">
<a href="https://git.arimelody.me/ari/prideflag">pride flag</a>
<a href="https://forge.arimelody.space/ari/prideflag">pride flag</a>
<p>progressive pride flag widget for websites</p>
</div>
</li>
@ -195,16 +172,16 @@
</div>
</li>
<li class="project-item">
<img src="https://impact.arimelody.me/favicon.png" alt="impact meme icon" aria-hidden=true class="project-icon" width="64" height="64">
<img src="https://impact.arimelody.space/favicon.png" alt="impact meme icon" aria-hidden=true class="project-icon" width="64" height="64">
<div class="project-info">
<a href="https://impact.arimelody.me/">impact meme</a>
<a href="https://impact.arimelody.space/">impact meme</a>
<p>impact meme generator</p>
</div>
</li>
<li class="project-item">
<img src="https://codeberg.org/repo-avatars/e67303eeda4fa6d268948e71b7b0837357d8c519772701ffc36b84ae7975319f" alt="OpenTerminal icon" aria-hidden=true class="project-icon" width="64" height="64">
<div class="project-info">
<a href="https://term.arimelody.me/">OpenTerminal</a>
<a href="https://term.arimelody.space/">OpenTerminal</a>
<p>communal online text buffer</p>
</div>
</li>
@ -224,7 +201,7 @@
</h2>
<div id="web-buttons">
<a href="https://arimelody.me">
<a href="https://arimelody.space">
<img src="/img/buttons/ari melody.gif" alt="ari melody web button" width="88" height="31">
</a>
<a href="https://supitszaire.com">
@ -263,6 +240,9 @@
<a href="https://isabelroses.com/">
<img src="/img/buttons/isabelroses.gif" alt="isabel roses web button" width="88" height="31">
</a>
<a href="https://bubblegum.girlonthemoon.xyz/">
<img src="/img/buttons/girlonthemoon.png" alt="sweet like bubblegum web button" width="88" height="31">
</a>
<hr>

View file

@ -6,22 +6,22 @@
<meta name="author" content="{{.PrintArtists true true}}">
<meta name="keywords" content="{{.PrintArtists true false}}, music, {{.Title}}, {{.ID}}, {{.ReleaseDate.Year}}">
<meta property="og:url" content="https://arimelody.me/music/{{.ID}}">
<meta property="og:url" content="https://arimelody.space/music/{{.ID}}">
<meta property="og:type" content="website">
<meta property="og:locale" content="en_IE">
<meta property="og:site_name" content="ari melody music">
<meta property="og.Title" content="{{.Title}} - {{.PrintArtists true true}}">
<meta property="og:site_name" content="ari melody 💫">
<meta property="og:title" content="{{.PrintArtists true true}} - {{.Title}}">
<meta property="og:description" content="Stream &quot;{{.Title}}&quot; by {{.PrintArtists true true}} on all platforms!">
<meta property="og:image" content="https://arimelody.me{{.GetArtwork}}">
<meta property="og:image" content="https://arimelody.space{{.GetArtwork}}">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@funniduck">
<meta name="twitter:creator" content="@funniduck">
<meta property="twitter:domain" content="arimelody.me">
<meta property="twitter:url" content="https://arimelody.me/music/{{.ID}}">
<meta name="twitter.Title" content="{{.PrintArtists true true}} - {{.Title}}">
<meta property="twitter:domain" content="arimelody.space">
<meta property="twitter:url" content="https://arimelody.space/music/{{.ID}}">
<meta name="twitter:title" content="{{.PrintArtists true true}} - {{.Title}}">
<meta name="twitter:description" content="Stream &quot;{{.Title}}&quot; by {{.PrintArtists true true}} on all platforms!">
<meta name="twitter:image" content="https://arimelody.me{{.GetArtwork}}">
<meta name="twitter:image" content="https://arimelody.space{{.GetArtwork}}">
<meta name="twitter:image:alt" content="Cover art for &quot;{{.Title}}&quot;">
<link rel="stylesheet" href="/style/main.css">
@ -34,7 +34,7 @@
<div id="background" style="background-image: url({{.GetArtwork}})"></div>
<a href="/music" id="go-back" title="back to arimelody.me">&lt;</a>
<a href="/music" id="go-back" title="back to arimelody.space">&lt;</a>
<br><br>
<div id="music-container">

View file

@ -6,9 +6,9 @@
<meta property="og:title" content="ari melody music">
<meta property="og:type" content="website">
<meta property="og:url" content="www.arimelody.me/music">
<meta property="og:image" content="https://www.arimelody.me/img/favicon.png">
<meta property="og:site_name" content="ari melody">
<meta property="og:url" content="www.arimelody.space/music">
<meta property="og:image" content="https://www.arimelody.space/img/favicon.png">
<meta property="og:site_name" content="ari melody 💫">
<meta property="og:description" content="music from your local SPACEGIRL 💫">
<link rel="stylesheet" href="/style/main.css">
@ -72,7 +72,7 @@
</p>
<blockquote>
music used: ari melody - free2play<br>
<a href="/music/free2play">https://arimelody.me/music/free2play</a><br>
<a href="/music/free2play">https://arimelody.space/music/free2play</a><br>
licensed under <a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank">CC BY-SA 4.0</a>.
</blockquote>
<p>
@ -84,7 +84,7 @@
if you do happen to use my work in something you're particularly proud of, feel free to send it my way!
</p>
<p>
&gt; <a href="mailto:ari@arimelody.me">ari@arimelody.me</a>
&gt; <a href="mailto:ari@arimelody.space">ari@arimelody.space</a>
</p>
</div>
</main>