mirror of
https://github.com/LucasVbr/LucasVbr.git
synced 2026-05-13 17:11:52 +00:00
Add Builder for shields
This commit is contained in:
Generated
+32
-30
@@ -4,35 +4,20 @@
|
|||||||
<option name="autoReloadType" value="SELECTIVE" />
|
<option name="autoReloadType" value="SELECTIVE" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="b25cc8d3-396f-4036-b751-5d061242b2fc" name="Changes" comment="Add ts-node and some skills">
|
<list default="true" id="b25cc8d3-396f-4036-b751-5d061242b2fc" name="Changes" comment="Use only Python">
|
||||||
<change afterPath="$PROJECT_DIR$/assets/banner.svg" afterDir="false" />
|
<change afterPath="$PROJECT_DIR$/src/shield/shield_builder.py" afterDir="false" />
|
||||||
<change afterPath="$PROJECT_DIR$/main.py" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/requirements" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/src/config.py" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/src/model/skill.py" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/src/model/skill_list.py" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/src/model/social.py" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/src/model/social_list.py" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/src/template.py" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/template.md" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/components/ImageComponent.ts" beforeDir="false" />
|
<change beforePath="$PROJECT_DIR$/assets/banner.svg" beforeDir="false" afterPath="$PROJECT_DIR$/assets/banner.svg" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/components/LinkComponent.ts" beforeDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/config.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/config.yaml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/config.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/config.yaml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/main.ts" beforeDir="false" />
|
<change beforePath="$PROJECT_DIR$/main.py" beforeDir="false" afterPath="$PROJECT_DIR$/main.py" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/models/BadgeModel.ts" beforeDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/config.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/config.py" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/models/BannerModel.ts" beforeDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/model/skill.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/model/skill.py" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/models/ConfigModel.ts" beforeDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/model/skill_list.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/model/skill_list.py" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/models/LinkModel.ts" beforeDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/model/social.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/model/social.py" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/Banner.ts" beforeDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/model/social_list.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/model/social_list.py" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/Context.ts" beforeDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/template.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/template.py" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/Link.ts" beforeDir="false" />
|
<change beforePath="$PROJECT_DIR$/template.md" beforeDir="false" afterPath="$PROJECT_DIR$/template.md" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/Skill.ts" beforeDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/url_builder/BadgeUrlBuilder.ts" beforeDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/url_builder/BannerUrlBuilder.ts" beforeDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/url_builder/UrlBuilder.ts" beforeDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/views/template.njk" beforeDir="false" />
|
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
@@ -77,7 +62,10 @@
|
|||||||
<component name="PropertiesComponent"><
|

|
||||||
|
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
## 🚀 About Me
|
## 🚀 About Me
|
||||||
|
|
||||||
I'm a passionate developer from 🇫🇷 **Pau, France**.
|
I'm a passionate developer from 🇫🇷 **Pau, France**.
|
||||||
|
|
||||||
## 🔗 Social Links
|
## 🔗 Social Links
|
||||||
[](https://www.linkedin.com/in/lucasvbr)
|
|
||||||
[](https://www.freecodecamp.org/LucasVbr)
|

|
||||||
[](https://openclassrooms.com/fr/members/97j9zltv6225)
|

|
||||||
[](https://exercism.org/profiles/LucasVbr)
|

|
||||||
|

|
||||||
|
|
||||||
## 🛠 Skills
|
## 🛠 Skills
|
||||||

|
|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||

|

|
||||||
|

|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<footer align="center">
|
<footer>
|
||||||
|
<div align="center">
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -53,4 +59,5 @@ I'm a passionate developer from 🇫🇷 **Pau, France**.
|
|||||||

|

|
||||||

|

|
||||||
|
|
||||||
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
+187
-188
@@ -1,216 +1,215 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 800 400" width="800" height="400">
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 1000 400" width="1000" height="400">
|
||||||
<foreignObject width="100%" height="100%">
|
<foreignObject width="100%" height="100%">
|
||||||
<div xmlns="http://www.w3.org/1999/xhtml">
|
<div xmlns="http://www.w3.org/1999/xhtml">
|
||||||
<style>
|
<style>
|
||||||
.container {
|
.container {
|
||||||
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';
|
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji';
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
margin: 0;
|
||||||
margin: 0;
|
width: 100%;
|
||||||
width: 100%;
|
height: 400px;
|
||||||
height: 400px;
|
/* background: linear-gradient(-45deg, #fc5c7d, #6a82fb, #05dfd7); */
|
||||||
|
background: #333;
|
||||||
background: #333;
|
background-size: 600% 400%;
|
||||||
background-size: 600% 400%;
|
border-radius: 10px;
|
||||||
border-radius: 10px;
|
/* color: white; */
|
||||||
/* color: white; */
|
text-align: center;
|
||||||
text-align: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 5em;
|
font-size: 5em;
|
||||||
letter-spacing: 8px;
|
letter-spacing: 8px;
|
||||||
font-family: "Lucida Console", Monaco, monospace;
|
font-family: "Lucida Console", Monaco, monospace;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
/*Create overlap*/
|
/*Create overlap*/
|
||||||
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
line-height: 0;
|
line-height: 0;
|
||||||
/*Animation*/
|
/*Animation*/
|
||||||
|
|
||||||
animation: glitch1 2.5s infinite;
|
animation: glitch1 2.5s infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1:nth-child(2) {
|
h1:nth-child(2) {
|
||||||
color: #67f3da;
|
color: #67f3da;
|
||||||
animation: glitch2 2.5s infinite;
|
animation: glitch2 2.5s infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1:nth-child(3) {
|
h1:nth-child(3) {
|
||||||
color: #f16f6f;
|
color: #f16f6f;
|
||||||
animation: glitch3 2.5s infinite;
|
animation: glitch3 2.5s infinite;
|
||||||
}
|
}
|
||||||
/*Keyframes*/
|
/*Keyframes*/
|
||||||
|
|
||||||
@keyframes glitch1 {
|
@keyframes glitch1 {
|
||||||
0% {
|
0% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
7% {
|
7% {
|
||||||
transform: skew(-0.5deg, -0.9deg);
|
transform: skew(-0.5deg, -0.9deg);
|
||||||
opacity: 0.75;
|
opacity: 0.75;
|
||||||
}
|
}
|
||||||
10% {
|
10% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
27% {
|
27% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
30% {
|
30% {
|
||||||
transform: skew(0.8deg, -0.1deg);
|
transform: skew(0.8deg, -0.1deg);
|
||||||
opacity: 0.75;
|
opacity: 0.75;
|
||||||
}
|
}
|
||||||
35% {
|
35% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
52% {
|
52% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
55% {
|
55% {
|
||||||
transform: skew(-1deg, 0.2deg);
|
transform: skew(-1deg, 0.2deg);
|
||||||
opacity: 0.75;
|
opacity: 0.75;
|
||||||
}
|
}
|
||||||
50% {
|
50% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
72% {
|
72% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
75% {
|
75% {
|
||||||
transform: skew(0.4deg, 1deg);
|
transform: skew(0.4deg, 1deg);
|
||||||
opacity: 0.75;
|
opacity: 0.75;
|
||||||
}
|
}
|
||||||
80% {
|
80% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes glitch2 {
|
@keyframes glitch2 {
|
||||||
0% {
|
0% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
7% {
|
7% {
|
||||||
transform: translate(-2px, -3px);
|
transform: translate(-2px, -3px);
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
10% {
|
10% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
27% {
|
27% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
30% {
|
30% {
|
||||||
transform: translate(-5px, -2px);
|
transform: translate(-5px, -2px);
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
35% {
|
35% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
52% {
|
52% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
55% {
|
55% {
|
||||||
transform: translate(-5px, -1px);
|
transform: translate(-5px, -1px);
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
50% {
|
50% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
72% {
|
72% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
75% {
|
75% {
|
||||||
transform: translate(-2px, -6px);
|
transform: translate(-2px, -6px);
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
80% {
|
80% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes glitch3 {
|
@keyframes glitch3 {
|
||||||
0% {
|
0% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
7% {
|
7% {
|
||||||
transform: translate(2px, 3px);
|
transform: translate(2px, 3px);
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
10% {
|
10% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
27% {
|
27% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
30% {
|
30% {
|
||||||
transform: translate(5px, 2px);
|
transform: translate(5px, 2px);
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
35% {
|
35% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
52% {
|
52% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
55% {
|
55% {
|
||||||
transform: translate(5px, 1px);
|
transform: translate(5px, 1px);
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
50% {
|
50% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
72% {
|
72% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
75% {
|
75% {
|
||||||
transform: translate(2px, 6px);
|
transform: translate(2px, 6px);
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
80% {
|
80% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
transform: none;
|
transform: none;
|
||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@@ -220,4 +219,4 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</foreignObject>
|
</foreignObject>
|
||||||
</svg>
|
<script xmlns=""/></svg>
|
||||||
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 7.2 KiB |
+28
-91
@@ -1,107 +1,44 @@
|
|||||||
user: "LucasVbr"
|
user: "LucasVbr"
|
||||||
|
|
||||||
socials:
|
socials:
|
||||||
# - name: "My Portfolio"
|
|
||||||
# url: "https://lucasvbr.github.io/portfolio"
|
|
||||||
# img: "https://img.shields.io/static/v1?style=for-the-badge&label=+&logoColor=white&message=My+Portfolio&logo=ko-fi&color=000"
|
|
||||||
|
|
||||||
- name: "Linkedin"
|
- name: "Linkedin"
|
||||||
url: "https://www.linkedin.com/in/lucasvbr"
|
url: "https://www.linkedin.com/in/lucasvbr"
|
||||||
img: "https://img.shields.io/static/v1?style=for-the-badge&label=+&logoColor=white&message=Linkedin&color=0e76a8&logo=linkedin"
|
|
||||||
|
|
||||||
- name: "FreeCodeCamp"
|
- name: "FreeCodeCamp"
|
||||||
url: "https://www.freecodecamp.org/LucasVbr"
|
url: "https://www.freecodecamp.org/LucasVbr"
|
||||||
img: "https://img.shields.io/static/v1?style=for-the-badge&label=+&logoColor=white&message=FreeCodeCamp&color=0a0a23&logo=freecodecamp"
|
|
||||||
|
|
||||||
- name: "OpenClassRooms"
|
- name: "OpenClassRooms"
|
||||||
url: "https://openclassrooms.com/fr/members/97j9zltv6225"
|
url: "https://openclassrooms.com/fr/members/97j9zltv6225"
|
||||||
img: "https://img.shields.io/static/v1?style=for-the-badge&label=+&logoColor=white&message=OpenClassRooms&color=7451eb&logo=openclassrooms"
|
|
||||||
|
|
||||||
- name: "Exercism"
|
- name: "Exercism"
|
||||||
url: "https://exercism.org/profiles/LucasVbr"
|
url: "https://exercism.org/profiles/LucasVbr"
|
||||||
img: "https://img.shields.io/static/v1?style=for-the-badge&label=+&logoColor=white&message=Exercism&color=2e57e8&logo=exercism"
|
|
||||||
|
|
||||||
skills:
|
skills:
|
||||||
- name: "Android"
|
- "Android"
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Android&color=3DDC84&logo=android"
|
- "Angular"
|
||||||
|
- "Bootstrap"
|
||||||
- name: "Angular"
|
- "Bulma"
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Angular&color=DD0031&logo=angular"
|
- "C"
|
||||||
|
- "CSS3"
|
||||||
- name: "Bootstrap"
|
- "Deno"
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Bootstrap&color=7952B3&logo=bootstrap"
|
- "Docker"
|
||||||
|
- "Express"
|
||||||
- name: "Bulma"
|
- "Figma"
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Bulma&color=00D1B2&logo=bulma"
|
- "Git"
|
||||||
|
- "GNU Bash"
|
||||||
- name: "C"
|
- "HTML5"
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=C&color=A8B9CC&logo=c"
|
- "JavaScript"
|
||||||
|
- "MariaDB"
|
||||||
- name: "CSS3"
|
- "MongoDB"
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=CSS3&color=1572B6&logo=css3"
|
- "MySQL"
|
||||||
|
- "Node.js"
|
||||||
- name: "Deno"
|
- "Nunjucks"
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Deno&color=black&logo=deno"
|
- "OCaml"
|
||||||
|
- "PHP"
|
||||||
- name: "Docker"
|
- "PostgreSQL"
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Docker&color=2496ED&logo=docker"
|
- "Pug"
|
||||||
|
- "Python"
|
||||||
- name: "Express"
|
- "React"
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Express&color=black&logo=express"
|
- "SQLite"
|
||||||
|
- "Symfony"
|
||||||
- name: "Figma"
|
- "TypeScript"
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Figma&color=F24E1E&logo=figma"
|
|
||||||
|
|
||||||
- name: "Git"
|
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Git&color=F05032&logo=git"
|
|
||||||
|
|
||||||
- name: "GNU Bash"
|
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=GNU%20Bash&color=4EAA25&logo=gnu-bash"
|
|
||||||
|
|
||||||
- name: "HTML5"
|
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=HTML5&color=E34F26&logo=html5"
|
|
||||||
|
|
||||||
- name: "JavaScript"
|
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=JavaScript&color=F7DF1E&logo=javascript"
|
|
||||||
|
|
||||||
- name: "MariaDB"
|
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=MariaDB&color=003545&logo=mariadb"
|
|
||||||
|
|
||||||
- name: "MongoDB"
|
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=MongoDB&color=47A248&logo=mongodb"
|
|
||||||
|
|
||||||
- name: "MySQL"
|
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=MySQL&color=4479A1&logo=mysql"
|
|
||||||
|
|
||||||
- name: "Node.js"
|
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Node.js&color=339933&logo=node.js"
|
|
||||||
|
|
||||||
- name: "Nunjucks"
|
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Nunjucks&color=1C4913&logo=nunjucks"
|
|
||||||
|
|
||||||
- name: "OCaml"
|
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=OCaml&color=EC6813&logo=ocaml"
|
|
||||||
|
|
||||||
- name: "PHP"
|
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=PHP&color=777BB4&logo=php"
|
|
||||||
|
|
||||||
- name: "PostgreSQL"
|
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=PostgreSQL&color=4169E1&logo=postgresql"
|
|
||||||
|
|
||||||
- name: "Pug"
|
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Pug&color=A86454&logo=pug"
|
|
||||||
|
|
||||||
- name: "Python"
|
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Python&color=3776AB&logo=python"
|
|
||||||
|
|
||||||
- name: "React"
|
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=React&color=61DAFB&logo=react"
|
|
||||||
|
|
||||||
- name: "SQLite"
|
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=SQLite&color=003B57&logo=sqlite"
|
|
||||||
|
|
||||||
- name: "Symfony"
|
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Symfony&color=black&logo=symfony"
|
|
||||||
|
|
||||||
- name: "TypeScript"
|
|
||||||
url: "https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=TypeScript&color=3178C6&logo=typescript"
|
|
||||||
@@ -1,19 +1,17 @@
|
|||||||
from src.config import load_data
|
from src.config import Config
|
||||||
from src.template import load_template
|
from src.template import Template
|
||||||
|
|
||||||
CONFIG_FILE = 'config.yaml'
|
CONFIG_FILE = 'config.yaml'
|
||||||
TEMPLATE_FILE = 'template.md'
|
TEMPLATE_FILE = 'template.md'
|
||||||
OUTPUT_FILE = 'README.md'
|
OUTPUT_FILE = 'README.md'
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
data = load_data(CONFIG_FILE)
|
template = Template(TEMPLATE_FILE)
|
||||||
template = load_template(TEMPLATE_FILE)
|
data = Config(CONFIG_FILE).get_data()
|
||||||
|
|
||||||
# Add data to template
|
|
||||||
result = template.format(**data)
|
|
||||||
|
|
||||||
# Generate README file
|
# Generate README file
|
||||||
with open(OUTPUT_FILE, 'w') as readme_file:
|
render = template.render(**data)
|
||||||
readme_file.write(result)
|
with open(OUTPUT_FILE, 'w') as f:
|
||||||
|
f.write(render)
|
||||||
|
|
||||||
print(f"{OUTPUT_FILE} generated successfully! 🎉")
|
print(f"{OUTPUT_FILE} generated successfully! 🎉")
|
||||||
|
|||||||
+14
-57
@@ -1,80 +1,37 @@
|
|||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from src.model.skill_list import SkillList
|
from src.model.skill_list import SkillList
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from src.model.social_list import SocialList
|
from src.model.social_list import SocialList
|
||||||
|
|
||||||
|
|
||||||
def load_data(config_file_path: str) -> dict:
|
class Config:
|
||||||
"""Load data from config file and return a dict"""
|
config_file_path: str
|
||||||
config_data_builder = ConfigDataBuilder(config_file_path)
|
config_data: dict[str, any] = None
|
||||||
return (config_data_builder
|
|
||||||
.load_config_file()
|
|
||||||
.load_user_info()
|
|
||||||
.load_skill_section()
|
|
||||||
.load_social_section()
|
|
||||||
.build())
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigDataBuilder:
|
|
||||||
|
|
||||||
def __init__(self, config_file_path: str):
|
def __init__(self, config_file_path: str):
|
||||||
"""
|
|
||||||
Initialize ConfigDataBuilder
|
|
||||||
|
|
||||||
:param config_file_path: Path to config file
|
|
||||||
"""
|
|
||||||
self.config_file_path = config_file_path
|
self.config_file_path = config_file_path
|
||||||
self.config_data = None
|
|
||||||
|
|
||||||
def load_config_file(self) -> 'ConfigDataBuilder':
|
def load_config_file(self):
|
||||||
"""
|
|
||||||
Load config file and return ConfigDataBuilder
|
|
||||||
|
|
||||||
:return: ConfigDataBuilder
|
|
||||||
"""
|
|
||||||
with open(self.config_file_path, 'r') as config_file:
|
with open(self.config_file_path, 'r') as config_file:
|
||||||
self.config_data = yaml.safe_load(config_file)
|
self.config_data = yaml.safe_load(config_file)
|
||||||
return self
|
|
||||||
|
|
||||||
def load_user_info(self) -> 'ConfigDataBuilder':
|
def handle_user_info(self):
|
||||||
"""
|
|
||||||
Load user info from GitHub API and return ConfigDataBuilder
|
|
||||||
|
|
||||||
:return: ConfigDataBuilder
|
|
||||||
"""
|
|
||||||
user = self.config_data["user"]
|
user = self.config_data["user"]
|
||||||
response = requests.get(f"https://api.github.com/users/{user}")
|
response = requests.get(f"https://api.github.com/users/{user}")
|
||||||
|
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
raise Exception("User not found")
|
raise Exception("User not found")
|
||||||
|
|
||||||
self.config_data["user"] = response.json()
|
self.config_data["user"] = response.json()
|
||||||
return self
|
|
||||||
|
|
||||||
def load_social_section(self) -> 'ConfigDataBuilder':
|
def handle_skill_section(self):
|
||||||
"""
|
|
||||||
Load social section and return ConfigDataBuilder
|
|
||||||
|
|
||||||
:return: ConfigDataBuilder
|
|
||||||
"""
|
|
||||||
self.config_data["socials"] = str(SocialList(self.config_data["socials"]))
|
|
||||||
return self
|
|
||||||
|
|
||||||
def load_skill_section(self) -> 'ConfigDataBuilder':
|
|
||||||
"""
|
|
||||||
Load skill section and return ConfigDataBuilder
|
|
||||||
|
|
||||||
:return: ConfigDataBuilder
|
|
||||||
"""
|
|
||||||
self.config_data["skills"] = str(SkillList(self.config_data["skills"]))
|
self.config_data["skills"] = str(SkillList(self.config_data["skills"]))
|
||||||
return self
|
|
||||||
|
|
||||||
def build(self) -> dict:
|
def handle_social_section(self):
|
||||||
"""
|
self.config_data["socials"] = str(SocialList(self.config_data["socials"]))
|
||||||
Return config data
|
|
||||||
|
def get_data(self):
|
||||||
|
self.load_config_file()
|
||||||
|
self.handle_user_info()
|
||||||
|
self.handle_skill_section()
|
||||||
|
self.handle_social_section()
|
||||||
|
|
||||||
:return: dict
|
|
||||||
"""
|
|
||||||
return self.config_data
|
return self.config_data
|
||||||
|
|||||||
+15
-7
@@ -1,10 +1,18 @@
|
|||||||
|
from src.shield.shield_builder import ShieldBuilder
|
||||||
|
|
||||||
|
|
||||||
class Skill:
|
class Skill:
|
||||||
def __init__(self, name: str, url: str):
|
alt: str
|
||||||
self.name = name
|
src: str
|
||||||
self.url = url
|
|
||||||
|
|
||||||
def __str__(self):
|
def __init__(self, name: str):
|
||||||
return f""
|
self.alt = name
|
||||||
|
self.src = (
|
||||||
|
ShieldBuilder()
|
||||||
|
.set_message(name)
|
||||||
|
.set_logo(name)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
|
||||||
def __repr__(self):
|
def __str__(self) -> str:
|
||||||
return f""
|
return f""
|
||||||
|
|||||||
@@ -2,12 +2,14 @@ from src.model.skill import Skill
|
|||||||
|
|
||||||
|
|
||||||
class SkillList:
|
class SkillList:
|
||||||
def __init__(self, skills: list):
|
skills: list[Skill]
|
||||||
self.skills = [Skill(skill.get("name"), skill.get("url")) for skill in skills]
|
|
||||||
|
def __init__(self, skills: list[str]):
|
||||||
|
# Sort and remove duplicates
|
||||||
|
skills = list(set(skills))
|
||||||
|
skills.sort()
|
||||||
|
|
||||||
|
self.skills = [Skill(skill) for skill in skills]
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return "\n".join([str(skill) for skill in self.skills])
|
return "\n".join([str(skill) for skill in self.skills])
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
|
||||||
return "\n".join([repr(skill) for skill in self.skills])
|
|
||||||
|
|
||||||
|
|||||||
+18
-9
@@ -1,11 +1,20 @@
|
|||||||
class Social:
|
from src.shield.shield_builder import ShieldBuilder
|
||||||
def __init__(self, name: str, url: str, img: str):
|
|
||||||
self.name = name
|
|
||||||
self.url = url
|
class Social:
|
||||||
self.img = img
|
name: str
|
||||||
|
img: str
|
||||||
|
|
||||||
|
def __init__(self, name: str, url: str):
|
||||||
|
self.name = name
|
||||||
|
self.img = (
|
||||||
|
ShieldBuilder()
|
||||||
|
.set_message(name)
|
||||||
|
.set_logo(name)
|
||||||
|
.set_link(url)
|
||||||
|
.set_style("for-the-badge")
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
|
||||||
return f"[]({self.url})"
|
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return f"[]({self.url})"
|
return f""
|
||||||
|
|||||||
@@ -2,11 +2,10 @@ from src.model.social import Social
|
|||||||
|
|
||||||
|
|
||||||
class SocialList:
|
class SocialList:
|
||||||
|
socials: list[Social]
|
||||||
|
|
||||||
def __init__(self, socials: list):
|
def __init__(self, socials: list):
|
||||||
self.socials = [Social(social.get("name"), social.get("url"), social.get("img")) for social in socials]
|
self.socials = [Social(social.get("name"), social.get("url")) for social in socials]
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return "\n".join([str(social) for social in self.socials])
|
return "\n".join([str(social) for social in self.socials])
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
|
||||||
return "\n".join([str(social) for social in self.socials])
|
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
from urllib.parse import urlunsplit, urlencode
|
||||||
|
|
||||||
|
|
||||||
|
class ShieldBuilder:
|
||||||
|
BASE_URL = "https://img.shields.io/static/v1"
|
||||||
|
|
||||||
|
message: str = None
|
||||||
|
style: str = None
|
||||||
|
logo: str = None
|
||||||
|
logo_color: str = None
|
||||||
|
label: str = None
|
||||||
|
label_color: str = None
|
||||||
|
color: str = None
|
||||||
|
cache_seconds: int = None
|
||||||
|
link: str = None
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.logo_color = "white"
|
||||||
|
self.label = " "
|
||||||
|
self.color = "black"
|
||||||
|
|
||||||
|
def set_message(self, message: str):
|
||||||
|
self.message = (
|
||||||
|
message
|
||||||
|
.replace("_", "__")
|
||||||
|
.replace("-", "--")
|
||||||
|
.replace(" ", "_")
|
||||||
|
)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def set_style(self, style: str):
|
||||||
|
if not style in ["flat", "flat-square", "plastic", "for-the-badge", "social"]:
|
||||||
|
raise Exception("Invalid style")
|
||||||
|
|
||||||
|
self.style = style
|
||||||
|
return self
|
||||||
|
|
||||||
|
def set_logo(self, logo: str):
|
||||||
|
self.logo = logo
|
||||||
|
return self
|
||||||
|
|
||||||
|
def set_logo_color(self, logo_color: str):
|
||||||
|
self.logo_color = logo_color
|
||||||
|
return self
|
||||||
|
|
||||||
|
def set_label(self, label: str):
|
||||||
|
self.label = label
|
||||||
|
return self
|
||||||
|
|
||||||
|
def set_label_color(self, label_color: str):
|
||||||
|
self.label_color = label_color
|
||||||
|
return self
|
||||||
|
|
||||||
|
def set_color(self, color: str):
|
||||||
|
self.color = color
|
||||||
|
return self
|
||||||
|
|
||||||
|
def set_cache_seconds(self, cache_seconds: int):
|
||||||
|
self.cache_seconds = cache_seconds
|
||||||
|
return self
|
||||||
|
|
||||||
|
def set_link(self, link: str):
|
||||||
|
self.link = link
|
||||||
|
return self
|
||||||
|
|
||||||
|
def get_query(self):
|
||||||
|
query = {
|
||||||
|
"message": self.message,
|
||||||
|
"style": self.style,
|
||||||
|
"logo": self.logo,
|
||||||
|
"logoColor": self.logo_color,
|
||||||
|
"label": self.label,
|
||||||
|
"labelColor": self.label_color,
|
||||||
|
"color": self.color,
|
||||||
|
"cacheSeconds": self.cache_seconds,
|
||||||
|
"link": self.link
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove None values
|
||||||
|
return {k: v for k, v in query.items() if v is not None}
|
||||||
|
|
||||||
|
def build(self):
|
||||||
|
query = urlencode(self.get_query())
|
||||||
|
return urlunsplit(("", "", self.BASE_URL, query, ""))
|
||||||
|
|
||||||
|
|
||||||
|
if "__main__" == __name__:
|
||||||
|
shield_builder = (
|
||||||
|
ShieldBuilder()
|
||||||
|
.set_logo("HTML5")
|
||||||
|
.set_message("HTML5")
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
print(shield_builder)
|
||||||
+10
-4
@@ -1,4 +1,10 @@
|
|||||||
def load_template(template_file_path: str):
|
class Template:
|
||||||
with open(template_file_path, 'r') as template_file:
|
|
||||||
template_content = template_file.read()
|
def __init__(self, template_path: str):
|
||||||
return template_content
|
self.template_path = template_path
|
||||||
|
|
||||||
|
def render(self, **kwargs) -> str:
|
||||||
|
with open(self.template_path, 'r') as f:
|
||||||
|
template = f.read()
|
||||||
|
|
||||||
|
return template.format(**kwargs)
|
||||||
|
|||||||
+9
-2
@@ -1,21 +1,27 @@
|
|||||||
<header align="center">
|
<header>
|
||||||
|
<div align="center">
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
## 🚀 About Me
|
## 🚀 About Me
|
||||||
|
|
||||||
I'm a passionate developer from 🇫🇷 **{user[location]}**.
|
I'm a passionate developer from 🇫🇷 **{user[location]}**.
|
||||||
|
|
||||||
## 🔗 Social Links
|
## 🔗 Social Links
|
||||||
|
|
||||||
{socials}
|
{socials}
|
||||||
|
|
||||||
## 🛠 Skills
|
## 🛠 Skills
|
||||||
|
|
||||||
{skills}
|
{skills}
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<footer align="center">
|
<footer>
|
||||||
|
<div align="center">
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -23,4 +29,5 @@ I'm a passionate developer from 🇫🇷 **{user[location]}**.
|
|||||||

|

|
||||||

|

|
||||||
|
|
||||||
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
Reference in New Issue
Block a user