fix(svg): escape xml characters in productivity badge [skip ci]
This commit is contained in:
parent
c4c47ab445
commit
e7ffe773d7
57
README.md
57
README.md
@ -12,7 +12,7 @@
|
||||
<img src="https://img.shields.io/badge/Gitea_Server-Online_%E2%97%8F-2ea44f?style=flat-square&logo=gitea&logoColor=white" alt="Gitea Online" />
|
||||
<img src="https://img.shields.io/badge/Homelab-Debian_12_Bookworm-A81D33?style=flat-square&logo=debian&logoColor=white" alt="Debian 12" />
|
||||
<img src="https://img.shields.io/badge/CI%2FCD-Gitea_Act_Runner-609926?style=flat-square&logo=docker&logoColor=white" alt="Runner Active" />
|
||||
<img src="https://img.shields.io/badge/Telemetry-Zuletzt_aktualisiert_02.09.2026%2019%3A15_UTC-7e3f98?style=flat-square" alt="Last Sync" />
|
||||
<img src="https://img.shields.io/badge/Telemetry-Zuletzt_aktualisiert_02.09.2026%2019%3A31_UTC-7e3f98?style=flat-square" alt="Last Sync" />
|
||||
</p>
|
||||
<!-- END_SYS_TELEMETRY -->
|
||||
|
||||
@ -25,7 +25,6 @@
|
||||
[](https://mudblazor.com/)
|
||||
|
||||
[](https://www.jetbrains.com/rider/)
|
||||
[](https://pop.system76.com/)
|
||||
[](https://www.debian.org/)
|
||||
[](https://www.docker.com/)
|
||||
[](https://www.webcore-consulting.de)
|
||||
@ -42,7 +41,7 @@ Ich bin **Nicki (Nicklas)**, angehender Softwareentwickler mit fundiertem Fokus
|
||||
|
||||
- 💻 **Fokus:** C#, .NET 10, Cross-Platform Desktop mit **Avalonia UI**, moderne Web-Apps mit **Blazor / MudBlazor** und modulare Microservices.
|
||||
- 🏢 **Team & Consulting:** Softwareentwickler bei **WebCore Consulting** – Entwicklung von Management-Tools, Kundenportalen und Security-Services.
|
||||
- 🐧 **Entwicklungsumgebung:** Vollständiger Linux-Workflow mit **JetBrains Rider auf Pop!_OS** – maximale Produktivität ohne Windows-Overhead.
|
||||
- 🐧 **Entwicklungsumgebung:** Vollständiger Linux-Workflow mit **JetBrains Rider auf Fedora** – maximale Produktivität ohne Windows-Overhead.
|
||||
- 🏰 **Self-Hosted Homelab:** Eigener Debian-Rootserver mit Docker-Containern: Gitea & Gitea Actions, Mailcow Enterprise Suite, Nginx Reverse Proxy mit Let's Encrypt, gehärtet durch UFW & fail2ban.
|
||||
- 🎮 **Gaming Corner:** Wenn der Build grün ist: Redstone-Komplexe in **Minecraft**, taktische Runden in **Rainbow Six Siege** oder Grinden in **Warframe**.
|
||||
- 🦊 **Branding:** Lila Fuchs (Purple Fox) – steht für Agilität, Eleganz, Scharfsinn und sauberen Code.
|
||||
@ -64,11 +63,6 @@ Ich bin **Nicki (Nicklas)**, angehender Softwareentwickler mit fundiertem Fokus
|
||||
<img src="heatmap.svg" alt="Nicki's Gitea Contribution Heatmap" width="100%" />
|
||||
</div>
|
||||
|
||||
#### 📌 Zuletzt aktualisierte persönliche Projekte:
|
||||
<!-- START_LATEST_REPOS -->
|
||||
- 🚀 [**.profile**](https://git.webcore-consulting.dev/NickiCloud/.profile) – 🦊 Gitea-Profil & dynamische Aktivitäts-Statistiken mit .NET 10
|
||||
`C#` • 🕒 *Aktualisiert am 02.09.2026*
|
||||
<!-- END_LATEST_REPOS -->
|
||||
|
||||
</details>
|
||||
|
||||
@ -115,11 +109,11 @@ Ich bin **Nicki (Nicklas)**, angehender Softwareentwickler mit fundiertem Fokus
|
||||
> *Echtzeit-Feed der letzten Aktionen und Commits über alle privaten & Team-Repositories.*
|
||||
|
||||
<!-- START_RECENT_ACTIVITY -->
|
||||
- ⚡ **feat: add live commit radar, activity feed and homelab telemetry [skip ci]** auf [`NickiCloud/.profile`](https://git.webcore-consulting.dev/NickiCloud/.profile) • 🕒 *vor 2 Minuten*
|
||||
- ⚡ **feat: add team telemetry dashboard, byte-level language analytics and tabs [skip ci]** auf [`NickiCloud/.profile`](https://git.webcore-consulting.dev/NickiCloud/.profile) • 🕒 *vor 6 Minuten*
|
||||
- ⚡ **fix(svg): remove utf-8 bom and add xml declaration for gitea typesniffer [skip ci]** auf [`NickiCloud/.profile`](https://git.webcore-consulting.dev/NickiCloud/.profile) • 🕒 *vor 14 Minuten*
|
||||
- ⚡ **chore(profile): update activity heatmap & stats (22 contributions) [skip ci]** auf [`NickiCloud/.profile`](https://git.webcore-consulting.dev/NickiCloud/.profile) • 🕒 *vor 21 Minuten*
|
||||
- ⚡ **Initial profile setup** auf [`NickiCloud/.profile`](https://git.webcore-consulting.dev/NickiCloud/.profile) • 🕒 *vor 22 Minuten*
|
||||
- ⚡ **feat: add productivity biorhythm clock, developer achievements and quote [skip ci]** auf [`NickiCloud/.profile`](https://git.webcore-consulting.dev/NickiCloud/.profile) • 🕒 *vor 15 Minuten*
|
||||
- ⚡ **feat: add live commit radar, activity feed and homelab telemetry [skip ci]** auf [`NickiCloud/.profile`](https://git.webcore-consulting.dev/NickiCloud/.profile) • 🕒 *vor 18 Minuten*
|
||||
- ⚡ **feat: add team telemetry dashboard, byte-level language analytics and tabs [skip ci]** auf [`NickiCloud/.profile`](https://git.webcore-consulting.dev/NickiCloud/.profile) • 🕒 *vor 22 Minuten*
|
||||
- ⚡ **fix(svg): remove utf-8 bom and add xml declaration for gitea typesniffer [skip ci]** auf [`NickiCloud/.profile`](https://git.webcore-consulting.dev/NickiCloud/.profile) • 🕒 *vor 30 Minuten*
|
||||
- ⚡ **chore(profile): update activity heatmap & stats (22 contributions) [skip ci]** auf [`NickiCloud/.profile`](https://git.webcore-consulting.dev/NickiCloud/.profile) • 🕒 *vor 37 Minuten*
|
||||
<!-- END_RECENT_ACTIVITY -->
|
||||
|
||||
</details>
|
||||
@ -142,7 +136,7 @@ Ich bin **Nicki (Nicklas)**, angehender Softwareentwickler mit fundiertem Fokus
|
||||
| 🏆 **Streak Master** | `Gold` | Mindestens 4 Tage ununterbrochen aktiv gecodet | **4 Tage** ✅ |
|
||||
| 💾 **Code Sovereign** | `Diamond` | Über 1,5 MB Code in Gitea verwaltet | **1,9 MB** ✅ |
|
||||
| ⚡ **Zero-Dependency** | `Master` | Reines .NET 10 BCL ohne fremde NuGet-Pakete | **100% Native** ✅ |
|
||||
| 🌙 **Night-Owl Veteran** | `Elite` | Hohe nächtliche Coding-Aktivität | **26,3% Nachts** ✅ |
|
||||
| 🌙 **Night-Owl Veteran** | `Elite` | Hohe nächtliche Coding-Aktivität | **21,1% Nachts** ✅ |
|
||||
| 🏰 **Homelab Overlord** | `Legendary` | Self-Hosted Debian, Docker, Gitea, Mailcow | **Vollautonom** ✅ |
|
||||
<!-- END_ACHIEVEMENTS -->
|
||||
|
||||
@ -157,32 +151,11 @@ Ich bin **Nicki (Nicklas)**, angehender Softwareentwickler mit fundiertem Fokus
|
||||
<br/>
|
||||
|
||||
<details open>
|
||||
<summary><h3>🛡️ Tab 5: Homelab, Server-Infrastruktur & Telemetrie</h3></summary>
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 🌐 WebCore & HomeLab Architecture │
|
||||
│ │
|
||||
│ [ Internet / Cloudflare ] │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ [ Debian 12 Host ] ─── [ UFW & fail2ban Security Wall ] │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ [ Nginx Reverse Proxy (SSL/TLS Termination) ] │
|
||||
│ │ │
|
||||
│ ┌───────┼─────────────────────────┬──────────────┐ │
|
||||
│ ▼ ▼ ▼ ▼ │
|
||||
│ [Gitea] [Act-Runner] [Mailcow] [Services] │
|
||||
│ (Git) (C# / .NET 10 Actions) (E-Mail) (WebCore) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
| Service | Host / Umgebung | Funktion | Status |
|
||||
| :--- | :--- | :--- | :---: |
|
||||
| 🦊 **Gitea Service** | `git.webcore-consulting.dev` | Versionsverwaltung, API & Git LFS | `🟢 ONLINE` |
|
||||
| ⚡ **Gitea Act-Runner** | Docker `catthehacker/ubuntu:act` | Autonome CI/CD-Pipeline (.NET 10) | `🟢 AKTIV` |
|
||||
| ✉️ **Mailcow Suite** | Docker Stack / Debian 12 | Enterprise Mail (DKIM, SPF, DMARC) | `🟢 ONLINE` |
|
||||
| ✉️ **Mailcow Suite** | Docker Stack / Debian 13 | Enterprise Mail (DKIM, SPF, DMARC) | `🟢 ONLINE` |
|
||||
| 🛡️ **Nginx Proxy** | Reverse Proxy Host | SSL/TLS 1.3 Offloading & HSTS | `🟢 AKTIV` |
|
||||
| 🔒 **Security Wall** | UFW Firewall & fail2ban | SSH & HTTP Brute-Force Abwehr | `🟢 SCHARF` |
|
||||
|
||||
@ -191,13 +164,13 @@ Ich bin **Nicki (Nicklas)**, angehender Softwareentwickler mit fundiertem Fokus
|
||||
<br/>
|
||||
|
||||
<details open>
|
||||
<summary><h3>🎮 Tab 6: Gaming Battlestation & Loadouts</h3></summary>
|
||||
<summary><h3>🎮 Tab 5: Gaming Battlestation & Loadouts</h3></summary>
|
||||
|
||||
| Game | Fokus & Rolle | Lieblingselement / Operator |
|
||||
| :--- | :--- | :--- |
|
||||
| ⛏️ **Minecraft** | Technical Automation & Redstone | Automatisierte Farmen, Create Mod, Server-Hosting |
|
||||
| 🎯 **Rainbow Six Siege** | Tactical Anchor & Area Denial | Smoke, Mute, Thermite, Thatcher |
|
||||
| ⚔️ **Warframe** | High-Level Survival & Grinding | Mesa Prime, Wisp, Volt |
|
||||
| ⚔️ **Warframe** | High-Level Survival & Grinding | Harrow, Ash, Oberon |
|
||||
|
||||
</details>
|
||||
|
||||
@ -209,7 +182,7 @@ Ich bin **Nicki (Nicklas)**, angehender Softwareentwickler mit fundiertem Fokus
|
||||
| :--- | :---: | :--- |
|
||||
| 📝 **Markdown Editor Pro** | `Avalonia UI` • `C#` | Desktop-Editor mit Live-Rendering, Math-Support und Theme-Engine. |
|
||||
| 💧 **CloudDrop** | `ASP.NET Core` • `Docker` | Self-hosted File-Sharing Service für schnelle Uploads & temporäre Links. |
|
||||
| 💳 **KasseApp** | `C#` • `SQLite` • `Avalonia` | Modulares Kassensystem mit Offline-Synchronisation für Events & Vereine. |
|
||||
| 💳 **KasseApp** | `C#` • `PostgreSQL` • `Avalonia` | Modulares Kassensystem mit Offline-Synchronisation für Events & Vereine. |
|
||||
| 🥤 **DrinkReminder** | `C#` • `Avalonia UI` | Schicker Desktop- & Mobile-Helfer für gesunde Hydration im Entwickleralltag. |
|
||||
|
||||
---
|
||||
@ -219,9 +192,9 @@ Ich bin **Nicki (Nicklas)**, angehender Softwareentwickler mit fundiertem Fokus
|
||||
```csharp
|
||||
var nicki = new Developer
|
||||
{
|
||||
Drink = "Kühles Spezi oder Club-Mate",
|
||||
Workstation = "Pop!_OS on Linux Kernel",
|
||||
IDE = "JetBrains Rider 2024+",
|
||||
Drink = "Wasser",
|
||||
Workstation = "Fedora on Linux Kernel",
|
||||
IDE = "JetBrains Rider",
|
||||
Team = "WebCore Consulting",
|
||||
Motto = "Measure twice, refactor once, ship autonomously."
|
||||
};
|
||||
|
||||
24
heatmap.svg
24
heatmap.svg
@ -74,7 +74,7 @@
|
||||
<text class="title" x="0" y="14">🦊 NickiCloud <tspan font-weight="400" fill="var(--accent)">•</tspan> <tspan font-weight="500" font-size="12" fill="var(--text-sub)">Persönliche Aktivität</tspan></text>
|
||||
<rect x="510" y="0" width="190" height="22" rx="11" fill="var(--metric-bg)" stroke="var(--metric-border)" stroke-width="1" />
|
||||
<circle cx="522" cy="11" r="4" fill="var(--accent)" />
|
||||
<text class="subtitle" x="532" y="15" font-weight="600">26 Commits im letzten Jahr</text>
|
||||
<text class="subtitle" x="532" y="15" font-weight="600">27 Commits im letzten Jahr</text>
|
||||
</g>
|
||||
<!-- Month Labels -->
|
||||
<text class="lbl-month" x="34" y="54">Sep</text>
|
||||
@ -1173,7 +1173,7 @@
|
||||
<title>01.09.2026: 9 Commits</title>
|
||||
</rect>
|
||||
<rect class="cell lvl-4" x="697" y="90" width="10" height="10" rx="2" style="animation-delay: 612ms;">
|
||||
<title>02.09.2026: 10 Commits</title>
|
||||
<title>02.09.2026: 11 Commits</title>
|
||||
</rect>
|
||||
<rect class="cell lvl-0" x="697" y="103" width="10" height="10" rx="2" style="animation-delay: 612ms;">
|
||||
<title>03.09.2026: 0 Commits</title>
|
||||
@ -1192,7 +1192,7 @@
|
||||
<g transform="translate(34, 166)">
|
||||
<rect width="216" height="36" rx="8" fill="var(--metric-bg)" stroke="var(--metric-border)" stroke-width="1" />
|
||||
<text x="12" y="27" font-size="16">📦</text>
|
||||
<text class="stat-val" x="40" y="20">26</text>
|
||||
<text class="stat-val" x="40" y="20">27</text>
|
||||
<text class="stat-lbl" x="40" y="33">Jahres-Beiträge</text>
|
||||
</g>
|
||||
<g transform="translate(264, 166)">
|
||||
@ -1209,28 +1209,28 @@
|
||||
</g>
|
||||
<!-- Top Languages Bar -->
|
||||
<g clip-path="url(#langBarClip)">
|
||||
<rect x="34.0" y="215" width="388.0" height="8" fill="#a855f7">
|
||||
<title>C#: 57,4%</title>
|
||||
<rect x="34.0" y="215" width="390.1" height="8" fill="#a855f7">
|
||||
<title>C#: 57,7%</title>
|
||||
</rect>
|
||||
<rect x="422.0" y="215" width="265.0" height="8" fill="#e34c26">
|
||||
<title>HTML: 39,2%</title>
|
||||
<rect x="424.1" y="215" width="263.6" height="8" fill="#e34c26">
|
||||
<title>HTML: 39,0%</title>
|
||||
</rect>
|
||||
<rect x="687.0" y="215" width="14.9" height="8" fill="#563d7c">
|
||||
<rect x="687.7" y="215" width="14.9" height="8" fill="#563d7c">
|
||||
<title>CSS: 2,2%</title>
|
||||
</rect>
|
||||
<rect x="701.9" y="215" width="2.7" height="8" fill="#f1e05a">
|
||||
<rect x="702.6" y="215" width="2.7" height="8" fill="#f1e05a">
|
||||
<title>JavaScript: 0,4%</title>
|
||||
</rect>
|
||||
<rect x="704.6" y="215" width="2.7" height="8" fill="#012456">
|
||||
<rect x="705.3" y="215" width="2.7" height="8" fill="#012456">
|
||||
<title>PowerShell: 0,4%</title>
|
||||
</rect>
|
||||
</g>
|
||||
<!-- Language Legend -->
|
||||
<g transform="translate(34, 238)">
|
||||
<circle cx="4" cy="4" r="4" fill="#a855f7" />
|
||||
<text class="lang-lbl" x="13" y="7">C# 57,4%</text>
|
||||
<text class="lang-lbl" x="13" y="7">C# 57,7%</text>
|
||||
<circle cx="89" cy="4" r="4" fill="#e34c26" />
|
||||
<text class="lang-lbl" x="98" y="7">HTML 39,2%</text>
|
||||
<text class="lang-lbl" x="98" y="7">HTML 39,0%</text>
|
||||
<circle cx="188" cy="4" r="4" fill="#563d7c" />
|
||||
<text class="lang-lbl" x="197" y="7">CSS 2,2%</text>
|
||||
<circle cx="273" cy="4" r="4" fill="#f1e05a" />
|
||||
|
||||
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
@ -46,7 +46,7 @@
|
||||
<text class="title" x="0" y="14">⏱️ Coding Biorhythmus <tspan font-weight="400" fill="var(--accent)">•</tspan> <tspan font-weight="500" font-size="12" fill="var(--text-sub)">Aktivitäts-Phasen (CET)</tspan></text>
|
||||
<rect x="390" y="0" width="310" height="22" rx="11" fill="var(--metric-bg)" stroke="var(--metric-border)" stroke-width="1" />
|
||||
<circle cx="402" cy="11" r="4" fill="var(--accent)" />
|
||||
<text class="subtitle" x="412" y="15" font-weight="600">🌙 Night-Owl (Höchste Produktivität am Abend & nachts)</text>
|
||||
<text class="subtitle" x="412" y="15" font-weight="600">🌙 Night-Owl (Produktiv am Abend und nachts)</text>
|
||||
</g>
|
||||
<!-- Bucket: Morgen -->
|
||||
<g transform="translate(34, 60)">
|
||||
@ -69,15 +69,15 @@
|
||||
<text class="bar-lbl" x="0" y="12">🌆 Abend</text>
|
||||
<text class="bar-time" x="110" y="12">(18:00 - 24:00)</text>
|
||||
<rect x="200" y="0" width="430" height="16" rx="4" fill="var(--metric-bg)" stroke="var(--metric-border)" stroke-width="0.8" />
|
||||
<rect x="200" y="0" width="294.1" height="16" rx="4" fill="var(--bar-evening)" />
|
||||
<text class="stat-val" x="644" y="13" font-size="12">68,4%</text>
|
||||
<rect x="200" y="0" width="316.9" height="16" rx="4" fill="var(--bar-evening)" />
|
||||
<text class="stat-val" x="644" y="13" font-size="12">73,7%</text>
|
||||
</g>
|
||||
<!-- Bucket: Nacht -->
|
||||
<g transform="translate(34, 168)">
|
||||
<text class="bar-lbl" x="0" y="12">🌙 Nacht</text>
|
||||
<text class="bar-time" x="110" y="12">(00:00 - 06:00)</text>
|
||||
<rect x="200" y="0" width="430" height="16" rx="4" fill="var(--metric-bg)" stroke="var(--metric-border)" stroke-width="0.8" />
|
||||
<rect x="200" y="0" width="113.1" height="16" rx="4" fill="var(--bar-night)" />
|
||||
<text class="stat-val" x="644" y="13" font-size="12">26,3%</text>
|
||||
<rect x="200" y="0" width="90.7" height="16" rx="4" fill="var(--bar-night)" />
|
||||
<text class="stat-val" x="644" y="13" font-size="12">21,1%</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
@ -184,8 +184,8 @@ public static class StatsCalculator
|
||||
};
|
||||
|
||||
string archetype = (nightCount + eveningCount >= morningCount + afternoonCount)
|
||||
? "🌙 Night-Owl (Höchste Produktivität am Abend & nachts)"
|
||||
: "⚡ Day-Runner (Fokus während der regulären Tagesstunden)";
|
||||
? "🌙 Night-Owl (Produktiv am Abend und nachts)"
|
||||
: "⚡ Day-Runner (Fokus am Tag)";
|
||||
|
||||
var productivity = new ProductivityStats
|
||||
{
|
||||
|
||||
@ -387,7 +387,7 @@ public static class SvgGenerator
|
||||
sb.AppendLine(" <g transform=\"translate(24, 20)\">");
|
||||
sb.AppendLine(" <text class=\"title\" x=\"0\" y=\"14\">⏱️ Coding Biorhythmus <tspan font-weight=\"400\" fill=\"var(--accent)\">•</tspan> <tspan font-weight=\"500\" font-size=\"12\" fill=\"var(--text-sub)\">Aktivitäts-Phasen (CET)</tspan></text>");
|
||||
|
||||
string badgeText = prod.DevArchetype;
|
||||
string badgeText = XmlEscape(prod.DevArchetype);
|
||||
sb.AppendLine($" <rect x=\"390\" y=\"0\" width=\"310\" height=\"22\" rx=\"11\" fill=\"var(--metric-bg)\" stroke=\"var(--metric-border)\" stroke-width=\"1\" />");
|
||||
sb.AppendLine($" <circle cx=\"402\" cy=\"11\" r=\"4\" fill=\"var(--accent)\" />");
|
||||
sb.AppendLine($" <text class=\"subtitle\" x=\"412\" y=\"15\" font-weight=\"600\">{badgeText}</text>");
|
||||
@ -429,6 +429,16 @@ public static class SvgGenerator
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string XmlEscape(string? text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text)) return string.Empty;
|
||||
return text.Replace("&", "&")
|
||||
.Replace("<", "<")
|
||||
.Replace(">", ">")
|
||||
.Replace("\"", """)
|
||||
.Replace("'", "'");
|
||||
}
|
||||
|
||||
private static void RenderMetricCard(StringBuilder sb, int x, int y, int w, int h, string icon, string value, string label)
|
||||
{
|
||||
sb.AppendLine($" <g transform=\"translate({x}, {y})\">");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user