Compare commits
10 commits
c4e53afdf1
...
aaa16a35ef
Author | SHA1 | Date | |
---|---|---|---|
aaa16a35ef | |||
efa55bbd03 | |||
204c4cd4d7 | |||
c247c4ffda | |||
09dcfdac7a | |||
1af1e594ba | |||
177b419463 | |||
1f0c0ba4b1 | |||
9420df0a4c | |||
abd9218561 |
24 changed files with 284 additions and 232 deletions
|
@ -8,24 +8,24 @@ jobs:
|
||||||
- name: setup env
|
- name: setup env
|
||||||
run: |
|
run: |
|
||||||
. ./.env || true
|
. ./.env || true
|
||||||
if [ "${{ gitea.ref_name }}" == prod ] && [ -n "$PROD_URL" ]; then
|
if [ "${{ forgejo.ref_name }}" = prod ] && [ -n "$PROD_URL" ]; then
|
||||||
BASE_URL="$PROD_URL"
|
BASE_URL="$PROD_URL"
|
||||||
else
|
else
|
||||||
BASE_URL="${{ gitea.ref_name }}.$(tr / '\n' <<< "${{ gitea.repository }}" | tac | tr '\n' .)k8s.gmoker.com"
|
BASE_URL="${{ forgejo.ref_name }}.$(tr / '\n' <<< "${{ forgejo.repository }}" | tac | tr '\n' .)k3s.gmoker.com"
|
||||||
fi
|
fi
|
||||||
REGISTRY="$(sed 's .*:// ' <<< ${{ gitea.server_url }})"
|
REGISTRY="$(sed 's .*:// ' <<< ${{ forgejo.server_url }})"
|
||||||
cat <<EOF >> .env
|
cat <<EOF >> .env
|
||||||
BASE_URL="$BASE_URL"
|
BASE_URL="$BASE_URL"
|
||||||
REGISTRY="$REGISTRY"
|
REGISTRY="$REGISTRY"
|
||||||
IMAGEAPP="$REGISTRY/${{ gitea.repository }}:${{ gitea.ref_name }}"
|
IMAGEAPP="$REGISTRY/${{ forgejo.repository }}:${{ forgejo.ref_name }}"
|
||||||
EOF
|
EOF
|
||||||
cat .env
|
cat .env
|
||||||
|
|
||||||
- uses: actions/kaniko@v1
|
- uses: actions/buildkit@v1
|
||||||
with:
|
with:
|
||||||
password: "${{ secrets.PKGRW }}"
|
password: "${{ secrets.PKGRW }}"
|
||||||
|
|
||||||
- uses: actions/k8sdeploy@v1
|
- uses: actions/k8sdeploy@v2
|
||||||
with:
|
with:
|
||||||
kubeconfig: "${{ secrets.K8S }}"
|
kubeconfig: "${{ secrets.K3S }}"
|
||||||
registry_password: "${{ secrets.PKGRW }}"
|
registry_password: "${{ secrets.PKGRW }}"
|
|
@ -1,4 +1,4 @@
|
||||||
FROM docker.io/golang:1.23 AS build
|
FROM docker.io/golang:1.25 AS build
|
||||||
WORKDIR /build/
|
WORKDIR /build/
|
||||||
COPY go.mod go.sum .
|
COPY go.mod go.sum .
|
||||||
RUN go mod download
|
RUN go mod download
|
||||||
|
@ -11,5 +11,7 @@ COPY html/ html/
|
||||||
COPY css/ css/
|
COPY css/ css/
|
||||||
COPY static/ static/
|
COPY static/ static/
|
||||||
COPY tmpl/ tmpl/
|
COPY tmpl/ tmpl/
|
||||||
|
COPY ssh pgp.asc .
|
||||||
|
COPY aliases.txt aliases.txt
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
CMD ["./app"]
|
CMD ["./app"]
|
||||||
|
|
1
README.md
Normal file
1
README.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
# yw5n.com
|
4
aliases.txt
Normal file
4
aliases.txt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
termux.sh https://git.gmoker.com/ange/termux/raw/branch/main/install.sh
|
||||||
|
dotfiles https://git.gmoker.com/ange/dotfiles
|
||||||
|
arch https://git.gmoker.com/ange/archinstall
|
||||||
|
wg.sh https://git.gmoker.com/ange/wg/raw/branch/main/install.sh
|
|
@ -5,7 +5,15 @@
|
||||||
margin: 5mm;
|
margin: 5mm;
|
||||||
}
|
}
|
||||||
|
|
||||||
#menu, #credits {
|
#credits, #menu {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#main {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -1,3 +1,3 @@
|
||||||
module main
|
module main
|
||||||
|
|
||||||
go 1.23.3
|
go 1.25
|
||||||
|
|
|
@ -2,68 +2,66 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
{{template "head.tmpl" .}}
|
{{template "head.tmpl" .}}
|
||||||
<script src="static/copy.js"></script>
|
<script>
|
||||||
|
function copyElem(id, r='') {
|
||||||
|
navigator.clipboard.writeText(
|
||||||
|
document.getElementById(id).innerText.replaceAll(r, ''),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyFile(id) {
|
||||||
|
fetch(document.getElementById(id).childNodes[1].href).then(f => {
|
||||||
|
f.text().then(t => {
|
||||||
|
navigator.clipboard.writeText(t);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{{template "header.tmpl" .}}
|
{{template "header.tmpl" .}}
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<!--
|
|
||||||
<div id="nav">
|
|
||||||
<ul>
|
|
||||||
<li><a href="#matrix">Matrix</a></li>
|
|
||||||
<li><a href="#discord">Discord</a></li>
|
|
||||||
<li><a href="#phone">Phone (France)</a></li>
|
|
||||||
<li><a href="#email">Email</a></li>
|
|
||||||
<li><a href="#wa">WhatsApp</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
-->
|
|
||||||
<div id="main">
|
<div id="main">
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
|
||||||
<td>Matrix (Element)</td>
|
|
||||||
<td id="matrix"><a href="//app.element.io/#/user/@ange:gmoker.com" target="_blank" rel="noreferrer noopener">@ange:gmoker.com</a></td>
|
|
||||||
<td><button onclick="copyElem('matrix')">Copy</button></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>Discord</td>
|
<td>Discord</td>
|
||||||
<td id="discord">@elrilio</td>
|
<td id="discord">{{template "discord"}}</td>
|
||||||
<td><button onclick="copyElem('discord')">Copy</button></td>
|
<td><button onclick="copyElem('discord')">Copy</button></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Phone (France)</td>
|
<td>Phone (France)</td>
|
||||||
<td id="phone"><a href="tel:+33582951623" target="_blank" rel="noreferrer noopener">+33 5 82 95 16 23</a></td>
|
<td id="phone">{{template "phone"}}</td>
|
||||||
<td><button onclick="copyElem('phone', / /g)">Copy</button></td>
|
<td><button onclick="copyElem('phone', / /g)">Copy</button></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Email</td>
|
<td>Email</td>
|
||||||
<td id="email"><a href="mailto:ange@yw5n.com" target="_blank" rel="noreferrer noopener">ange@yw5n.com</a></td>
|
<td id="email">{{template "email"}}</td>
|
||||||
<td><button onclick="copyElem('email')">Copy</button></td>
|
<td><button onclick="copyElem('email')">Copy</button></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>WhatsApp</td>
|
<td>WhatsApp</td>
|
||||||
<td id="wa"><a href="//wa.me/6285333559453" target="_blank" rel="noreferrer noopener">+62 853-3355-9453</a></td>
|
<td id="wa">{{template "wa"}}</td>
|
||||||
<td><button onclick="copyElem('wa', /[ |-]/g)">Copy</button></td>
|
<td><button onclick="copyElem('wa', /[ |-]/g)">Copy</button></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>LinkedIn</td>
|
<td>LinkedIn</td>
|
||||||
<td id="in"><a href="https://www.linkedin.com/in/angedhn" target="_blank" rel="noreferrer noopener">www.linkedin.com/in/angedhn</a></td>
|
<td id="in">{{template "in"}}</td>
|
||||||
<td><button onclick="copyElem('in')">Copy</button></td>
|
<td><button onclick="copyElem('in')">Copy</button></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>PGP</td>
|
<td>PGP</td>
|
||||||
<td id="pgp"><a href="/static/pgp.asc" target="_blank" rel="noreferrer noopener">pgp.asc</a></td>
|
<td id="pgp">{{template "pgp"}}</td>
|
||||||
<td><button onclick="copyFile('pgp')">Copy</button></td>
|
<td><button onclick="copyFile('pgp')">Copy</button></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>SSH</td>
|
<td>SSH</td>
|
||||||
<td id="ssh"><a href="/static/ssh" target="_blank" rel="noreferrer noopener">ssh</a></td>
|
<td id="ssh">{{template "ssh"}}</td>
|
||||||
<td><button onclick="copyFile('ssh')">Copy</button></td>
|
<td><button onclick="copyFile('ssh')">Copy</button></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -8,14 +8,11 @@
|
||||||
{{template "header.tmpl" .}}
|
{{template "header.tmpl" .}}
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<div id="nav">
|
<div id="nav">
|
||||||
<!--
|
<img src="static/2404.webp" alt="Ange DUHAYON" width="128"><br>
|
||||||
<ul>
|
{{template "phone"}}<br>
|
||||||
<li><a href="#formation">Formation</a></li>
|
<a href="https://yw5n.com">yw5n.com<br>
|
||||||
<li><a href="#experience">Experience</a></li>
|
{{template "email"}}<br>
|
||||||
<li><a href="#competences">Competences</a></li>
|
{{template "in"}}<br>
|
||||||
</ul>
|
|
||||||
-->
|
|
||||||
<img src="static/2404.webp" alt="Ange DUHAYON" width="128">
|
|
||||||
</div>
|
</div>
|
||||||
<div id="main">
|
<div id="main">
|
||||||
|
|
||||||
|
@ -28,19 +25,22 @@
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2 id="experience">EXPERIENCE</h2>
|
<h2 id="experience">EXPERIENCE</h2>
|
||||||
<h3><b>Freelance</b> - DevOps</h3>
|
<h3><b>Freelance</b> - DevOps Engineer</h3>
|
||||||
SEPTEMBER 2023 - TODAY
|
SEPTEMBER 2023 - TODAY
|
||||||
<ul>
|
<ul>
|
||||||
<li>Server setup (Debian, Docker/K8S, web server, customer application)</li>
|
<li>Docker / K8S</li>
|
||||||
<li>CI/CD, real-time monitoring</li>
|
<li>GitHub Actions</li>
|
||||||
|
<li>Prometheus</li>
|
||||||
|
<li>Python / Go backend</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h3><b>Selfhost</b> - DevOps</h3>
|
<h3><b>Selfhost</b> - DevOps Engineer</h3>
|
||||||
JANUARY 2022 - TODAY
|
JANUARY 2022 - TODAY
|
||||||
<ul>
|
<ul>
|
||||||
<li>Debian, K8S, Gitea CI/CD</li>
|
<li>Bare metal K8S</li>
|
||||||
|
<li>Gitea Actions</li>
|
||||||
<li>Nextcloud, Matrix.org, Jellyfin, SearXNG</li>
|
<li>Nextcloud, Matrix.org, Jellyfin, SearXNG</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h3><b>EPITECH CodingClub association, Toulouse</b> - Cobra</h3>
|
<h3><b>EPITECH CodingClub association, Toulouse</b> - Trainer</h3>
|
||||||
JANUARY 2021 - JUNE 2024
|
JANUARY 2021 - JUNE 2024
|
||||||
<ul>
|
<ul>
|
||||||
<li>Coding workshops for high school students</li>
|
<li>Coding workshops for high school students</li>
|
||||||
|
@ -48,15 +48,16 @@
|
||||||
<h3><b>Predicloud, Toulouse</b> - DevOps SRE</h3>
|
<h3><b>Predicloud, Toulouse</b> - DevOps SRE</h3>
|
||||||
JUNE 2022 - JULY 2023
|
JUNE 2022 - JULY 2023
|
||||||
<ul>
|
<ul>
|
||||||
<li>CI/CD, K8S monitoring</li>
|
<li>GitLab CI</li>
|
||||||
<li>Authentication solution (LDAP, SSO, Webhook) + Python backend</li>
|
<li>Prometheus, Grafana</li>
|
||||||
<li>Mail server (Postfix, Dovecot)</li>
|
<li>OpenLDAP + Python frontend, Keycloak, K8S webhook</li>
|
||||||
<li>Customer communication and troubleshooting</li>
|
<li>Postfix, Dovecot</li>
|
||||||
|
<li>Customer troubleshooting</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2 id="competences">COMPETENCES</h2>
|
<h2 id="competences">COMPETENCES</h2>
|
||||||
<table>
|
<table>
|
||||||
<tr><th>LANGUAGES</th> <th>SOFTWARE</th></tr>
|
<tr><th>LANGUAGES</th><th>SOFTWARE</th></tr>
|
||||||
<tr><td>C/C++</td> <td>*nix</td></tr>
|
<tr><td>C/C++</td> <td>*nix</td></tr>
|
||||||
<tr><td>Python</td> <td>Git</td></tr>
|
<tr><td>Python</td> <td>Git</td></tr>
|
||||||
<tr><td>Bash</td> <td>Vim</td></tr>
|
<tr><td>Bash</td> <td>Vim</td></tr>
|
||||||
|
|
|
@ -1,34 +1,36 @@
|
||||||
#!/bin/bash -e
|
#!/bin/bash -e
|
||||||
set -o pipefail
|
set -o pipefail
|
||||||
|
|
||||||
function kapply() {
|
kapply() {
|
||||||
for f in "$@"; do
|
for f in "$@"; do
|
||||||
kubectl apply -f \
|
kubectl apply --server-side \
|
||||||
<(envsubst "$(env | xargs printf '$%s ')" < "manifests/$f")
|
-f<(envsubst "$(env | sed 's/^/$/')" < "manifests/$f")
|
||||||
done
|
done
|
||||||
}
|
}; export -f kapply
|
||||||
|
|
||||||
function kcreatesec() {
|
kcreatesec() {
|
||||||
kubectl create secret generic --save-config --dry-run=client -oyaml "$@" | kubectl apply -f-
|
kubectl apply --server-side \
|
||||||
}
|
-f<(kubectl create secret generic --dry-run=client -oyaml "$@")
|
||||||
|
}; export -f kcreatesec
|
||||||
|
|
||||||
function kcreatecm() {
|
kcreatecm() {
|
||||||
kubectl create configmap --dry-run=client -oyaml "$@" | kubectl apply -f-
|
kubectl apply --server-side \
|
||||||
}
|
-f<(kubectl create configmap --dry-run=client -oyaml "$@")
|
||||||
|
}; export -f kcreatecm
|
||||||
|
|
||||||
function kgseckey() {
|
kgseckey() {
|
||||||
local sec="$1"; shift
|
local sec="$1"; shift
|
||||||
local key="$1"; shift
|
local key="$1"; shift
|
||||||
|
|
||||||
kubectl get secret "$sec" -o jsonpath="{.data.$key}" | base64 -d
|
kubectl get secret "$sec" -ojson | jq -re ".data.\"$key\"" | base64 -d
|
||||||
}
|
}; export -f kgseckey
|
||||||
|
|
||||||
function kgcmkey() {
|
kgcmkey() {
|
||||||
local cm="$1"; shift
|
local cm="$1"; shift
|
||||||
local key="$1"; shift
|
local key="$1"; shift
|
||||||
|
|
||||||
kubectl get configmap "$cm" -o jsonpath="{.data.$key}"
|
kubectl get configmap "$cm" -ojson | jq -re ".data.\"$key\""
|
||||||
}
|
}; export -f kgcmkey
|
||||||
|
|
||||||
|
|
||||||
kapply common/app.yaml
|
kapply common/app.yaml
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#!/bin/bash -e
|
#!/bin/bash -e
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
export NB_REPLICAS=1
|
export NB_REPLICAS=1
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#!/bin/bash -e
|
#!/bin/bash -e
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
export NB_REPLICAS=3
|
export NB_REPLICAS=3
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ metadata:
|
||||||
annotations:
|
annotations:
|
||||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||||
spec:
|
spec:
|
||||||
ingressClassName: nginx
|
|
||||||
tls:
|
tls:
|
||||||
- secretName: tls-app
|
- secretName: tls-app
|
||||||
hosts:
|
hosts:
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
http.HandleFunc("/", route)
|
http.HandleFunc("/", route)
|
||||||
|
generateAliases()
|
||||||
generateTmpl()
|
generateTmpl()
|
||||||
if err := http.ListenAndServe(":3000", nil); err != nil {
|
if err := http.ListenAndServe(":3000", nil); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
|
|
@ -16,6 +16,7 @@ var routes = []struct {
|
||||||
handler http.HandlerFunc
|
handler http.HandlerFunc
|
||||||
}{
|
}{
|
||||||
{[]string{"GET"}, url(""), index},
|
{[]string{"GET"}, url(""), index},
|
||||||
|
{[]string{"GET"}, url("/(pgp.asc|ssh)"), static},
|
||||||
{[]string{"GET"}, url("/static/.+"), static},
|
{[]string{"GET"}, url("/static/.+"), static},
|
||||||
{[]string{"GET"}, url("/(.+\\.css)"), css},
|
{[]string{"GET"}, url("/(.+\\.css)"), css},
|
||||||
{[]string{"GET"}, url("/([^/]+)"), html},
|
{[]string{"GET"}, url("/([^/]+)"), html},
|
||||||
|
@ -42,8 +43,8 @@ func route(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
fmt.Println(r.Method, r.URL.Path)
|
fmt.Println(r.Method, r.URL.Path)
|
||||||
rt.handler(w, r.WithContext(
|
rt.handler(w, r.WithContext(
|
||||||
context.WithValue(r.Context(), URLParam{}, matches[1:])),
|
context.WithValue(r.Context(), URLParam{}, matches[1:]),
|
||||||
)
|
))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
31
src/tmpl.go
31
src/tmpl.go
|
@ -1,31 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"html/template"
|
|
||||||
"path/filepath"
|
|
||||||
"regexp"
|
|
||||||
)
|
|
||||||
|
|
||||||
var TMPL map[string][]byte
|
|
||||||
|
|
||||||
func generateTmpl() {
|
|
||||||
files, _ := filepath.Glob("html/*.html")
|
|
||||||
re := regexp.MustCompile("html/(.+).html")
|
|
||||||
names := make([]string, len(files))
|
|
||||||
|
|
||||||
for i, f := range files {
|
|
||||||
names[i] = re.FindStringSubmatch(f)[1]
|
|
||||||
}
|
|
||||||
TMPL = make(map[string][]byte, len(files))
|
|
||||||
for i, f := range files {
|
|
||||||
b := new(bytes.Buffer)
|
|
||||||
t, _ := template.ParseFiles(f)
|
|
||||||
t.ParseGlob("tmpl/*.tmpl")
|
|
||||||
t.Execute(b, map[string]any{
|
|
||||||
"name": names[i],
|
|
||||||
"names": names,
|
|
||||||
})
|
|
||||||
TMPL[names[i]] = b.Bytes()
|
|
||||||
}
|
|
||||||
}
|
|
50
src/util.go
Normal file
50
src/util.go
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"html/template"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ALIASES map[string]string
|
||||||
|
func generateAliases() {
|
||||||
|
f, err := os.ReadFile("aliases.txt")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ALIASES = make(map[string]string)
|
||||||
|
for l := range strings.SplitSeq(string(f), "\n") {
|
||||||
|
sp := strings.Fields(l)
|
||||||
|
|
||||||
|
if len(sp) == 2 {
|
||||||
|
ALIASES[sp[0]] = sp[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var TMPL map[string][]byte
|
||||||
|
func generateTmpl() {
|
||||||
|
files, _ := filepath.Glob("html/*.html")
|
||||||
|
re := regexp.MustCompile("html/(.+).html")
|
||||||
|
pages := make([]string, len(files))
|
||||||
|
|
||||||
|
for i, f := range files {
|
||||||
|
pages[i] = re.FindStringSubmatch(f)[1]
|
||||||
|
}
|
||||||
|
TMPL = make(map[string][]byte, len(files))
|
||||||
|
for i, f := range files {
|
||||||
|
b := new(bytes.Buffer)
|
||||||
|
t, _ := template.ParseFiles(f)
|
||||||
|
t.ParseGlob("tmpl/*.tmpl")
|
||||||
|
t.Execute(b, map[string]any{
|
||||||
|
"page": pages[i],
|
||||||
|
"pages": pages,
|
||||||
|
})
|
||||||
|
TMPL[pages[i]] = b.Bytes()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,8 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"fmt"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
func index(w http.ResponseWriter, r *http.Request) {
|
func index(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -15,12 +14,13 @@ func static(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func css(w http.ResponseWriter, r *http.Request) {
|
func css(w http.ResponseWriter, r *http.Request) {
|
||||||
fmt.Println(filepath.Join("css", getParam(r, 0)))
|
|
||||||
http.ServeFile(w, r, filepath.Join("css", getParam(r, 0)))
|
http.ServeFile(w, r, filepath.Join("css", getParam(r, 0)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func html(w http.ResponseWriter, r *http.Request) {
|
func html(w http.ResponseWriter, r *http.Request) {
|
||||||
if t, found := TMPL[getParam(r, 0)]; found {
|
if a, found := ALIASES[getParam(r, 0)]; found {
|
||||||
|
http.Redirect(w, r, a, http.StatusFound)
|
||||||
|
} else if t, found := TMPL[getParam(r, 0)]; found {
|
||||||
w.Write(t)
|
w.Write(t)
|
||||||
} else {
|
} else {
|
||||||
http.NotFound(w, r)
|
http.NotFound(w, r)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDUccdlgUHzV+AhWDyjwcG4QwSNbybIV8MF7c6XpKQl4
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDUccdlgUHzV+AhWDyjwcG4QwSNbybIV8MF7c6XpKQl4 ange@yw5n.com
|
|
@ -1,13 +0,0 @@
|
||||||
function copyElem(id, r='') {
|
|
||||||
navigator.clipboard.writeText(
|
|
||||||
document.getElementById(id).innerText.replaceAll(r, ''),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function copyFile(id) {
|
|
||||||
fetch(document.getElementById(id).childNodes[0].href).then(f => {
|
|
||||||
f.text().then(t => {
|
|
||||||
navigator.clipboard.writeText(t);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,3 +1,3 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Ange DUHAYON</title>
|
<title>Ange DUHAYON - {{.page}}</title>
|
||||||
<link rel="stylesheet" href="style.css"/>
|
<link rel="stylesheet" href="style.css"/>
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
<div id="header">
|
<div id="header">
|
||||||
<a id="headerLink" href="/">Ange DUHAYON</a>
|
<a id="headerLink" href="/">Ange DUHAYON</a>
|
||||||
<span id="headerSubtitle">DevOps Engineer</span>
|
<span id="headerSubtitle">DevOps Engineer</span>
|
||||||
<span id="credits" class="right" style="font-size: .4em;">Website heavily inspired from <a href="//suckless.org/" target="_blank" rel="noreferrer noopener">suckless.org</a></span>
|
<span id="credits" class="right" style="font-size: .4em;">Website heavily inspired from <a href="https://suckless.org/" target="_blank" rel="noreferrer noopener">suckless.org</a></span>
|
||||||
</div>
|
</div>
|
||||||
<div id="menu">
|
<div id="menu">
|
||||||
{{$name := .name}}
|
{{$page := .page}}
|
||||||
{{range .names}}
|
{{range .pages}}
|
||||||
<a href="/{{.}}">{{if eq $name .}}<b>{{.}}</b>{{else}}{{.}}{{end}}</a>
|
<a href="/{{.}}">{{if eq $page .}}<b>{{.}}</b>{{else}}{{.}}{{end}}</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
<span class="right">
|
<span class="right">
|
||||||
<a href="//git.gmoker.com/yw5n" target="_blank" rel="noreferrer noopener">source</a>
|
<a href="https://git.gmoker.com/yw5n" target="_blank" rel="noreferrer noopener">source</a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
27
tmpl/vars.tmpl
Normal file
27
tmpl/vars.tmpl
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{{define "discord"}}
|
||||||
|
@elrilio
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{define "phone"}}
|
||||||
|
<a href="tel:+33582951623">+33 5 82 95 16 23</a>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{define "email"}}
|
||||||
|
<a href="mailto:ange@yw5n.com">ange@yw5n.com</a>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{define "wa"}}
|
||||||
|
<a href="https://wa.me/6285333559453" target="_blank" rel="noreferrer noopener">+62 853-3355-9453</a>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{define "in"}}
|
||||||
|
<a href="https://www.linkedin.com/in/angedhn" target="_blank" rel="noreferrer noopener">angedhn</a>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{define "pgp"}}
|
||||||
|
<a href="pgp.asc" target="_blank">pgp.asc</a>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
{{define "ssh"}}
|
||||||
|
<a href="ssh" target="_blank">ssh</a>
|
||||||
|
{{end}}
|
Loading…
Add table
Add a link
Reference in a new issue