diff --git a/.gitignore b/.gitignore index 62c8935..c9c738e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ -.idea/ \ No newline at end of file +.idea/ +.vscode/ + +.DS_Store diff --git a/README.md b/README.md index bb82315..0fa24e1 100644 --- a/README.md +++ b/README.md @@ -1,49 +1,56 @@ -![Hi I'm Lucàs👋](https://svg-banners.vercel.app/api?type=glitch&text1=Hi+I%27m+Luc%C3%A0s%F0%9F%91%8B&width=1000&height=400) +
+
+ +![Hi I'm Lucàs👋](assets/banner.svg) + +
+
## 🚀 About Me -I'm a passionate developer from 🇫🇷 **Albi, France**. -## 🔗 Links -[![My Portfolio](https://img.shields.io/static/v1?style=for-the-badge&label=+&logoColor=white&message=My+Portfolio&logo=ko-fi&color=000)](https://lucasvbr.github.io/links/?portfolio) -[![Linkedin](https://img.shields.io/static/v1?style=for-the-badge&label=+&logoColor=white&message=Linkedin&color=0e76a8&logo=linkedin)](https://www.linkedin.com/in/lucasvbr) -[![FreeCodeCamp](https://img.shields.io/static/v1?style=for-the-badge&label=+&logoColor=white&message=FreeCodeCamp&color=0a0a23&logo=freecodecamp)](https://www.freecodecamp.org/LucasVbr) -[![OpenClassRooms](https://img.shields.io/static/v1?style=for-the-badge&label=+&logoColor=white&message=OpenClassRooms&color=7451eb&logo=openclassrooms)](https://openclassrooms.com/fr/members/97j9zltv6225) -[![Exercism](https://img.shields.io/static/v1?style=for-the-badge&label=+&logoColor=white&message=Exercism&color=2e57e8&logo=exercism)](https://exercism.org/profiles/LucasVbr) +I'm a passionate developer from 🇫🇷 **Pau, France**. +## 🔗 Social Links + +[![Linkedin](https://img.shields.io/static/v1?message=LinkedIn&style=for-the-badge&logo=linkedin&logoColor=white&label=+&color=0A66C2&link=https%3A%2F%2Fwww.linkedin.com%2Fin%2Flucasvbr)](https://www.linkedin.com/in/lucasvbr) +[![FreeCodeCamp](https://img.shields.io/static/v1?message=freeCodeCamp&style=for-the-badge&logo=freecodecamp&logoColor=white&label=+&color=0A0A23&link=https%3A%2F%2Fwww.freecodecamp.org%2FLucasVbr)](https://www.freecodecamp.org/LucasVbr) +[![OpenClassRooms](https://img.shields.io/static/v1?message=OpenClassRooms&style=for-the-badge&logoColor=white&label=+&color=black&link=https%3A%2F%2Fopenclassrooms.com%2Ffr%2Fmembers%2F97j9zltv6225)](https://openclassrooms.com/fr/members/97j9zltv6225) +[![Exercism](https://img.shields.io/static/v1?message=Exercism&style=for-the-badge&logo=exercism&logoColor=white&label=+&color=009CAB&link=https%3A%2F%2Fexercism.org%2Fprofiles%2FLucasVbr)](https://exercism.org/profiles/LucasVbr) ## 🛠 Skills -![Android](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Android&color=3DDC84&logo=android) -![Angular](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Angular&color=DD0031&logo=angular) -![Bootstrap](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Bootstrap&color=7952B3&logo=bootstrap) -![Bulma](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Bulma&color=00D1B2&logo=bulma) -![C](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=C&color=A8B9CC&logo=c) -![CSS3](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=CSS3&color=1572B6&logo=css3) -![Deno](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Deno&color=000&logo=deno) -![Docker](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Docker&color=2496ED&logo=docker) -![Express](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Express&color=000&logo=express) -![Figma](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Figma&color=F24E1E&logo=figma) -![Git](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Git&color=F05032&logo=git) -![GNU Bash](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=GNU+Bash&color=4EAA25&logo=gnubash) -![HTML5](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=HTML5&color=E34F26&logo=html5) -![JavaScript](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=JavaScript&color=F7DF1E&logo=javascript) -![MariaDB](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=MariaDB&color=003545&logo=mariadb) -![MongoDB](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=MongoDB&color=47A248&logo=mongodb) -![MySQL](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=MySQL&color=4479A1&logo=mysql) -![Node.js](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Node.js&color=339933&logo=nodedotjs) -![Nunjucks](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Nunjucks&color=1C4913&logo=nunjucks) -![OCaml](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=OCaml&color=EC6813&logo=ocaml) -![PHP](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=PHP&color=777BB4&logo=php) -![PostgreSQL](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=PostgreSQL&color=4169E1&logo=postgresql) -![Pug](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Pug&color=A86454&logo=pug) -![Python](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Python&color=3776AB&logo=python) -![React](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=React&color=61DAFB&logo=react) -![SQLite](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=SQLite&color=003B57&logo=sqlite) -![Symfony](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=Symfony&color=000&logo=symfony) -![TypeScript](https://img.shields.io/static/v1?style=flat&label=+&logoColor=white&message=TypeScript&color=3178C6&logo=typescript) +![Android](https://img.shields.io/static/v1?message=Android&logo=android&logoColor=white&label=+&color=3DDC84) +![Angular](https://img.shields.io/static/v1?message=Angular&logo=angular&logoColor=white&label=+&color=DD0031) +![Bootstrap](https://img.shields.io/static/v1?message=Bootstrap&logo=bootstrap&logoColor=white&label=+&color=7952B3) +![Bulma](https://img.shields.io/static/v1?message=Bulma&logo=bulma&logoColor=white&label=+&color=00D1B2) +![C](https://img.shields.io/static/v1?message=C&logo=c&logoColor=white&label=+&color=A8B9CC) +![CSS3](https://img.shields.io/static/v1?message=CSS3&logo=css3&logoColor=white&label=+&color=1572B6) +![Deno](https://img.shields.io/static/v1?message=Deno&logo=deno&logoColor=white&label=+&color=000000) +![Docker](https://img.shields.io/static/v1?message=Docker&logo=docker&logoColor=white&label=+&color=2496ED) +![Express](https://img.shields.io/static/v1?message=Express&logo=express&logoColor=white&label=+&color=000000) +![Figma](https://img.shields.io/static/v1?message=Figma&logo=figma&logoColor=white&label=+&color=F24E1E) +![GNU Bash](https://img.shields.io/static/v1?message=GNU_Bash&logo=gnubash&logoColor=white&label=+&color=4EAA25) +![Git](https://img.shields.io/static/v1?message=Git&logo=git&logoColor=white&label=+&color=F05032) +![HTML5](https://img.shields.io/static/v1?message=HTML5&logo=html5&logoColor=white&label=+&color=E34F26) +![JavaScript](https://img.shields.io/static/v1?message=JavaScript&logo=javascript&logoColor=white&label=+&color=F7DF1E) +![MariaDB](https://img.shields.io/static/v1?message=MariaDB&logo=mariadb&logoColor=white&label=+&color=003545) +![MongoDB](https://img.shields.io/static/v1?message=MongoDB&logo=mongodb&logoColor=white&label=+&color=47A248) +![MySQL](https://img.shields.io/static/v1?message=MySQL&logo=mysql&logoColor=white&label=+&color=4479A1) +![Node.js](https://img.shields.io/static/v1?message=Node.js&logo=nodedotjs&logoColor=white&label=+&color=339933) +![Nunjucks](https://img.shields.io/static/v1?message=Nunjucks&logo=nunjucks&logoColor=white&label=+&color=1C4913) +![OCaml](https://img.shields.io/static/v1?message=OCaml&logo=ocaml&logoColor=white&label=+&color=EC6813) +![PHP](https://img.shields.io/static/v1?message=PHP&logo=php&logoColor=white&label=+&color=777BB4) +![PostgreSQL](https://img.shields.io/static/v1?message=PostgreSQL&logo=postgresql&logoColor=white&label=+&color=4169E1) +![Pug](https://img.shields.io/static/v1?message=Pug&logo=pug&logoColor=white&label=+&color=A86454) +![Python](https://img.shields.io/static/v1?message=Python&logo=python&logoColor=white&label=+&color=3776AB) +![React](https://img.shields.io/static/v1?message=React&logo=react&logoColor=white&label=+&color=61DAFB) +![SQLite](https://img.shields.io/static/v1?message=SQLite&logo=sqlite&logoColor=white&label=+&color=003B57) +![Symfony](https://img.shields.io/static/v1?message=Symfony&logo=symfony&logoColor=white&label=+&color=000000) +![TypeScript](https://img.shields.io/static/v1?message=TypeScript&logo=typescript&logoColor=white&label=+&color=3178C6) --- + \ No newline at end of file diff --git a/assets/banner.svg b/assets/banner.svg new file mode 100644 index 0000000..bb07842 --- /dev/null +++ b/assets/banner.svg @@ -0,0 +1,222 @@ + + +
+ +
+

Hi I'm Lucàs👋

+

Hi I'm Lucàs👋

+

Hi I'm Lucàs👋

+
+
+
+
\ No newline at end of file diff --git a/components/ImageComponent.ts b/components/ImageComponent.ts deleted file mode 100644 index ffbcdc9..0000000 --- a/components/ImageComponent.ts +++ /dev/null @@ -1,3 +0,0 @@ -const ImageComponent = (label: string, url: URL) => `![${label}](${url})`; - -export default ImageComponent \ No newline at end of file diff --git a/components/LinkComponent.ts b/components/LinkComponent.ts deleted file mode 100644 index c22d25a..0000000 --- a/components/LinkComponent.ts +++ /dev/null @@ -1,3 +0,0 @@ -const LinkComponent = (label: string, url: string) => `[${label}](${url})`; - -export default LinkComponent; \ No newline at end of file diff --git a/config.yaml b/config.yaml index 0062615..8c9a83b 100644 --- a/config.yaml +++ b/config.yaml @@ -1,128 +1,44 @@ -file: - template: "template.njk" - output: "README.md" +user: "LucasVbr" -view: - userName: "LucasVbr" +socials: + - name: "Linkedin" + url: "https://www.linkedin.com/in/lucasvbr" - banner: - type: "glitch" - text1: "Hi I'm Lucàs👋" - width: 1000 - height: 400 + - name: "FreeCodeCamp" + url: "https://www.freecodecamp.org/LucasVbr" - about: "I'm a passionate developer from 🇫🇷 **Albi, France**." + - name: "OpenClassRooms" + url: "https://openclassrooms.com/fr/members/97j9zltv6225" - links: - - label: - message: "My Portfolio" - logo: "ko-fi" - url: "https://lucasvbr.github.io/links/?portfolio" + - name: "Exercism" + url: "https://exercism.org/profiles/LucasVbr" - - label: - message: "Linkedin" - color: "0e76a8" - url: "https://www.linkedin.com/in/lucasvbr" - - - label: - message: "FreeCodeCamp" - color: "0a0a23" - url: "https://www.freecodecamp.org/LucasVbr" - - - label: - message: "OpenClassRooms" - color: "7451eb" - url: "https://openclassrooms.com/fr/members/97j9zltv6225" - - - label: - message: "Exercism" - color: "2e57e8" - url: "https://exercism.org/profiles/LucasVbr" - - skills: - - message: "Android" - color: "3DDC84" - - - message: "Angular" - color: "DD0031" - - - message: "Bootstrap" - color: "7952B3" - - - message: "Bulma" - color: "00D1B2" - - - message: "C" - color: "A8B9CC" - - - message: "CSS3" - color: "1572B6" - - - message: "Deno" - - - message: "Docker" - color: "2496ED" - - - message: "Express" - - - message: "Figma" - color: "F24E1E" - - - message: "Git" - color: "F05032" - - - message: "GNU Bash" - color: "4EAA25" - - - message: "HTML5" - color: "E34F26" - - - message: "JavaScript" - color: "F7DF1E" - - - message: "MariaDB" - color: "003545" - - - message: "MongoDB" - color: "47A248" - - - message: "MySQL" - color: "4479A1" - - - message: "Node.js" - color: "339933" - logo: "nodedotjs" - - - message: "Nunjucks" - color: "1C4913" - - - message: "OCaml" - color: "EC6813" - - - message: "PHP" - color: "777BB4" - - - message: "PostgreSQL" - color: "4169E1" - - - message: "Pug" - color: "A86454" - - - message: "Python" - color: "3776AB" - - - message: "React" - color: "61DAFB" - - - message: "SQLite" - color: "003B57" - - - message: "Symfony" - - - message: "TypeScript" - color: "3178C6" - - footer: - - "![Profile Views](https://komarev.com/ghpvc/?username=lucasvbr&label=Profile%20views&color=0e75b6&style=flat)" - - "![FreeCodeCamp Points](https://img.shields.io/freecodecamp/points/lucasvbr?label=FreeCodeCamp%20points)" - - "![Made with love](https://img.shields.io/badge/-made%20with%20%E2%9D%A4%EF%B8%8F-red)" \ No newline at end of file +skills: + - "Android" + - "Angular" + - "Bootstrap" + - "Bulma" + - "C" + - "CSS3" + - "Deno" + - "Docker" + - "Express" + - "Figma" + - "Git" + - "GNU Bash" + - "HTML5" + - "JavaScript" + - "MariaDB" + - "MongoDB" + - "MySQL" + - "Node.js" + - "Nunjucks" + - "OCaml" + - "PHP" + - "PostgreSQL" + - "Pug" + - "Python" + - "React" + - "SQLite" + - "Symfony" + - "TypeScript" \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..c878ea5 --- /dev/null +++ b/main.py @@ -0,0 +1,17 @@ +from src.config import Config +from src.template import Template + +CONFIG_FILE = 'config.yaml' +TEMPLATE_FILE = 'template.md' +OUTPUT_FILE = 'README.md' + +if __name__ == '__main__': + template = Template(TEMPLATE_FILE) + data = Config(CONFIG_FILE).get_data() + + # Generate README file + render = template.render(**data) + with open(OUTPUT_FILE, 'w') as f: + f.write(render) + + print(f"{OUTPUT_FILE} generated successfully! 🎉") diff --git a/main.ts b/main.ts deleted file mode 100644 index f630d6a..0000000 --- a/main.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {parse} from 'https://deno.land/std@0.82.0/encoding/yaml.ts'; -import nunjucks from 'https://deno.land/x/nunjucks@3.2.3-2/mod.js'; -import makeContext from './src/Context.ts'; -import type ConfigModel from './models/ConfigModel.ts'; - -// Load Config file -const config: ConfigModel = parse(await Deno.readTextFile('config.yaml')) as ConfigModel; -const context = makeContext(config.view) - -// Render -nunjucks.configure('views/', {autoescape: true}); -nunjucks.render(config.file.template, context, (err, res) => { - if (err) return console.error(err); - - Deno.writeTextFile(config.file.output, res ?? '') - .then(() => console.info(`[INFO] ${config.file.output} successfully generated`)) - .catch(err => console.error(err)); -}); \ No newline at end of file diff --git a/models/BadgeModel.ts b/models/BadgeModel.ts deleted file mode 100644 index e722f07..0000000 --- a/models/BadgeModel.ts +++ /dev/null @@ -1,13 +0,0 @@ -type BadgeModel = { - label?: string, - message?: string, - color?: string, - logo?: string, - style: "plastic" | "flat" | "flat-square" | "for-the-badge" | "social", - logoColor?: string, - logoWidth?: number, - link?: string, - labelColor?: string, - cacheSeconds?: number, -} -export default BadgeModel; \ No newline at end of file diff --git a/models/BannerModel.ts b/models/BannerModel.ts deleted file mode 100644 index d72058e..0000000 --- a/models/BannerModel.ts +++ /dev/null @@ -1,9 +0,0 @@ -type BannerModel = { - text1: string, - text2?: string, - type: "origin" | "textBox" | "glitch" | "luminance" | "typeWriter" | "rainbow", - width: number, - height: number, -} - -export default BannerModel; \ No newline at end of file diff --git a/models/ConfigModel.ts b/models/ConfigModel.ts deleted file mode 100644 index b21793d..0000000 --- a/models/ConfigModel.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type BannerModel from './BannerModel.ts'; -import type LinkModel from './LinkModel.ts'; -import type BadgeModel from './BadgeModel.ts'; - -type ConfigModel = { - file: { - template: string, - output: string - }, - view: { - userName: string, - banner: BannerModel, - about: string, - links: LinkModel[], - skills: BadgeModel[], - footer: string[] - } -} - -export default ConfigModel; \ No newline at end of file diff --git a/models/LinkModel.ts b/models/LinkModel.ts deleted file mode 100644 index 81e80cf..0000000 --- a/models/LinkModel.ts +++ /dev/null @@ -1,8 +0,0 @@ -import BadgeModel from './BadgeModel.ts'; - -type LinkModel = { - label: BadgeModel, - url: string -} - -export default LinkModel \ No newline at end of file diff --git a/requirements b/requirements new file mode 100644 index 0000000..5b4e75c --- /dev/null +++ b/requirements @@ -0,0 +1,4 @@ +pyyaml +json +requests +simpleicons \ No newline at end of file diff --git a/src/Banner.ts b/src/Banner.ts deleted file mode 100644 index 4f81a34..0000000 --- a/src/Banner.ts +++ /dev/null @@ -1,18 +0,0 @@ -import ImageComponent from '../components/ImageComponent.ts'; -import type BannerModel from '../models/BannerModel.ts'; -import BannerUrlBuilder from './url_builder/BannerUrlBuilder.ts'; - -export default class Banner { - - constructor(private model: BannerModel) { - }; - - toString(): string { - const url = new BannerUrlBuilder() - .setParameters({...this.model}) - .build() - ; - - return ImageComponent(this.model.text1, url); - } -} \ No newline at end of file diff --git a/src/Context.ts b/src/Context.ts deleted file mode 100644 index f5cacb3..0000000 --- a/src/Context.ts +++ /dev/null @@ -1,12 +0,0 @@ -import Skill from './Skill.ts'; -import Banner from './Banner.ts'; -import Link from './Link.ts'; - -export default function makeContext(viewConfig) { - return { - ...viewConfig, - banner: new Banner(viewConfig.banner).toString(), - links: viewConfig.links.map(link => (new Link(link)).toString()), - skills: viewConfig.skills.map(skill => (new Skill(skill)).toString()), - } -} \ No newline at end of file diff --git a/src/Link.ts b/src/Link.ts deleted file mode 100644 index 9e1aa96..0000000 --- a/src/Link.ts +++ /dev/null @@ -1,32 +0,0 @@ -import BadgeUrlBuilder from './url_builder/BadgeUrlBuilder.ts'; -import ImageComponent from '../components/ImageComponent.ts'; -import LinkModel from '../models/LinkModel.ts'; -import LinkComponent from '../components/LinkComponent.ts'; - -export default class Link { - - constructor(private model: LinkModel) {} - - handleLabel() { - const {label: badge} = this.model; - const defaultLogo = badge.message.toLowerCase().replace(/\s+/g, '') - - const url = new BadgeUrlBuilder() - .setParameters({ - ...badge, - style: "for-the-badge", - logo: badge.logo ?? defaultLogo, - color: badge.color ?? '000', - }, - ) - .build() - ; - - return ImageComponent(badge.message, url); - } - - toString(): string { - const label = this.handleLabel().toString() - return LinkComponent(label, this.model.url).toString() - } -} \ No newline at end of file diff --git a/src/Skill.ts b/src/Skill.ts deleted file mode 100644 index 0c2846a..0000000 --- a/src/Skill.ts +++ /dev/null @@ -1,24 +0,0 @@ -import BadgeUrlBuilder from './url_builder/BadgeUrlBuilder.ts'; -import ImageComponent from '../components/ImageComponent.ts'; -import type SkillModel from '../models/SkillModel.ts'; - -export default class Skill { - - constructor(private model: SkillModel) {}; - - toString(): string { - const defaultLogo = this.model.message.toLowerCase().replace(/\s+/g, ''); - - const url = new BadgeUrlBuilder() - .setParameters({ - ...this.model, - color: this.model.color ?? '000', - logo: this.model.logo ?? defaultLogo - }, - ) - .build() - ; - - return ImageComponent(this.model.message, url); - } -} \ No newline at end of file diff --git a/src/config.py b/src/config.py new file mode 100644 index 0000000..0f56f1b --- /dev/null +++ b/src/config.py @@ -0,0 +1,37 @@ +import yaml +from src.model.skill_list import SkillList +import requests +from src.model.social_list import SocialList + + +class Config: + config_file_path: str + config_data: dict[str, any] = None + + def __init__(self, config_file_path: str): + self.config_file_path = config_file_path + + def load_config_file(self): + with open(self.config_file_path, 'r') as config_file: + self.config_data = yaml.safe_load(config_file) + + def handle_user_info(self): + user = self.config_data["user"] + response = requests.get(f"https://api.github.com/users/{user}") + if response.status_code != 200: + raise Exception("User not found") + self.config_data["user"] = response.json() + + def handle_skill_section(self): + self.config_data["skills"] = str(SkillList(self.config_data["skills"])) + + def handle_social_section(self): + self.config_data["socials"] = str(SocialList(self.config_data["socials"])) + + def get_data(self): + self.load_config_file() + self.handle_user_info() + self.handle_skill_section() + self.handle_social_section() + + return self.config_data diff --git a/src/model/skill.py b/src/model/skill.py new file mode 100644 index 0000000..093024b --- /dev/null +++ b/src/model/skill.py @@ -0,0 +1,13 @@ +from src.shield.skill_shield import SkillShield + + +class Skill: + alt: str + src: str + + def __init__(self, name: str): + self.alt = name + self.src = SkillShield(name).__str__() + + def __str__(self) -> str: + return f"![{self.alt}]({self.src})" diff --git a/src/model/skill_list.py b/src/model/skill_list.py new file mode 100644 index 0000000..e30517d --- /dev/null +++ b/src/model/skill_list.py @@ -0,0 +1,15 @@ +from src.model.skill import Skill + + +class SkillList: + skills: list[Skill] + + 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: + return "\n".join([str(skill) for skill in self.skills]) diff --git a/src/model/social.py b/src/model/social.py new file mode 100644 index 0000000..a96ad54 --- /dev/null +++ b/src/model/social.py @@ -0,0 +1,14 @@ +from src.shield.social_shield import SocialShield + + +class Social: + name: str + img: str + + def __init__(self, name: str, url: str): + self.name = name + self.img = SocialShield(name, url).__str__() + self.url = url + + def __str__(self) -> str: + return f"[![{self.name}]({self.img})]({self.url})" diff --git a/src/model/social_list.py b/src/model/social_list.py new file mode 100644 index 0000000..0d6b2a9 --- /dev/null +++ b/src/model/social_list.py @@ -0,0 +1,11 @@ +from src.model.social import Social + + +class SocialList: + socials: list[Social] + + def __init__(self, socials: list): + self.socials = [Social(social.get("name"), social.get("url")) for social in socials] + + def __str__(self) -> str: + return "\n".join([str(social) for social in self.socials]) diff --git a/src/shield/shield_builder.py b/src/shield/shield_builder.py new file mode 100644 index 0000000..b9a2977 --- /dev/null +++ b/src/shield/shield_builder.py @@ -0,0 +1,94 @@ +from urllib.parse import urlunsplit, urlencode +from simpleicons.all import icons + +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 = icons.get(logo).slug if logo in icons else None + 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) diff --git a/src/shield/skill_shield.py b/src/shield/skill_shield.py new file mode 100644 index 0000000..3853513 --- /dev/null +++ b/src/shield/skill_shield.py @@ -0,0 +1,33 @@ +from simpleicons.all import icons + +from src.shield.shield_builder import ShieldBuilder + + +class SkillShield: + + def __init__(self, name: str = None): + self.builder = ShieldBuilder() + self.skill = self.set_skill(name) if name is not None else None + + def get_skill(self): + return self.skill + + def set_skill(self, name: str): + self.skill = icons.get(name) + + if self.skill is not None: + (self.builder.set_message(self.skill.title) + .set_logo(self.skill.slug) + .set_color(self.skill.hex) + ) + else: + self.builder.set_message(name) + + def get_builder(self): + return self.builder + + def __repr__(self): + self.__str__() + + def __str__(self): + return self.builder.build() diff --git a/src/shield/social_shield.py b/src/shield/social_shield.py new file mode 100644 index 0000000..d164572 --- /dev/null +++ b/src/shield/social_shield.py @@ -0,0 +1,37 @@ +from simpleicons.all import icons + +from src.shield.shield_builder import ShieldBuilder + + +class SocialShield: + + def __init__(self, name: str = None, url: str = None): + self.builder = ShieldBuilder().set_style("for-the-badge") + self.name = name + self.url = url + self.social = self.set_social(name, url) if name is not None and url is not None else None + + def get_social(self): + return self.social + + def set_social(self, name: str, url: str): + self.social = icons.get(name) + + if self.social is not None: + (self.builder.set_message(self.social.title) + .set_logo(self.social.slug) + .set_color(self.social.hex) + ) + else: + self.builder.set_message(name) + + self.builder.set_link(url) + + def get_builder(self): + return self.builder + + def __repr__(self): + self.__str__() + + def __str__(self): + return self.builder.build() diff --git a/src/template.py b/src/template.py new file mode 100644 index 0000000..c96987b --- /dev/null +++ b/src/template.py @@ -0,0 +1,10 @@ +class Template: + + def __init__(self, template_path: str): + 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) diff --git a/src/url_builder/BadgeUrlBuilder.ts b/src/url_builder/BadgeUrlBuilder.ts deleted file mode 100644 index 1ff113f..0000000 --- a/src/url_builder/BadgeUrlBuilder.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type BadgeModel from '../../models/BadgeModel.ts'; -import UrlBuilder from './UrlBuilder.ts'; - -export default class BadgeUrlBuilder extends UrlBuilder { - static BASE_URL = 'https://img.shields.io/static/v1'; - static DEFAULT_PARAMETERS: BadgeModel = {style: 'flat', label: " ", logoColor: "white"}; - - constructor(parameters?: BadgeModel) { - super(BadgeUrlBuilder.BASE_URL, - parameters, - BadgeUrlBuilder.DEFAULT_PARAMETERS, - ); - }; - - public setParameters(parameters: BadgeModel): this { - return super.setParameters(parameters); - } -} \ No newline at end of file diff --git a/src/url_builder/BannerUrlBuilder.ts b/src/url_builder/BannerUrlBuilder.ts deleted file mode 100644 index f350548..0000000 --- a/src/url_builder/BannerUrlBuilder.ts +++ /dev/null @@ -1,14 +0,0 @@ -import UrlBuilder from './UrlBuilder.ts'; -import type BannerModel from '../../models/BannerModel.ts'; - -export default class BannerUrlBuilder extends UrlBuilder { - static BASE_URL = 'https://svg-banners.vercel.app/api'; - - constructor(parameters: BannerModel) { - super(BannerUrlBuilder.BASE_URL, parameters, {}); - } - - public setParameters(parameters: BannerModel): this { - return super.setParameters(parameters); - } -} \ No newline at end of file diff --git a/src/url_builder/UrlBuilder.ts b/src/url_builder/UrlBuilder.ts deleted file mode 100644 index 35e9a64..0000000 --- a/src/url_builder/UrlBuilder.ts +++ /dev/null @@ -1,25 +0,0 @@ -export default abstract class UrlBuilder { - - private parameters; - - protected constructor( - private baseUrl: string, - parameters, - private defaultParameters, - ) { - this.parameters = {...defaultParameters, ...parameters}; - }; - - setParameters(parameters) { - this.parameters = {...this.parameters, ...parameters}; - return this; - } - - build(): URL { - const url = new URL(this.baseUrl); - for (const [key, value] of Object.entries(this.parameters)) { - if (value) url.searchParams.set(key, value); - } - return url; - }; -} \ No newline at end of file diff --git a/template.md b/template.md new file mode 100644 index 0000000..2fe98e1 --- /dev/null +++ b/template.md @@ -0,0 +1,33 @@ +
+
+ +![Hi I'm Lucàs👋](assets/banner.svg) + +
+
+ +## 🚀 About Me + +I'm a passionate developer from 🇫🇷 **{user[location]}**. + +## 🔗 Social Links + +{socials} + +## 🛠 Skills + +{skills} + +--- + + \ No newline at end of file diff --git a/views/template.njk b/views/template.njk deleted file mode 100644 index b49058a..0000000 --- a/views/template.njk +++ /dev/null @@ -1,26 +0,0 @@ -{{banner}} - -## 🚀 About Me -{{about}} - -## 🔗 Links -{% for link in links -%} - {{link}} -{% endfor %} - -## 🛠 Skills -{% for skill in skills -%} - {{skill}} -{% endfor %} - ---- - -
- -![SVG Stats](https://github-stats-alpha.vercel.app/api?username={{userName}}&cc=000&tc=fff&ic=fff&bc=000) - -{% for badge in footer -%} - {{badge}} -{% endfor %} - -
\ No newline at end of file