first commit

This commit is contained in:
mrtoine 2025-09-20 14:16:14 +02:00
parent b216a187bd
commit f73c77f548
119 changed files with 4504 additions and 4829 deletions

8
backend/.idea/.gitignore generated vendored Normal file
View file

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

16
backend/.idea/backend.iml generated Normal file
View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="Flask">
<option name="enabled" value="true" />
</component>
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.13 (backend)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TemplatesService">
<option name="TEMPLATE_CONFIGURATION" value="Jinja2" />
</component>
</module>

4
backend/.idea/encodings.xml generated Normal file
View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
</project>

View file

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

7
backend/.idea/misc.xml generated Normal file
View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.13 (backend)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.13 (backend)" project-jdk-type="Python SDK" />
</project>

8
backend/.idea/modules.xml generated Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/backend.iml" filepath="$PROJECT_DIR$/.idea/backend.iml" />
</modules>
</component>
</project>

6
backend/.idea/vcs.xml generated Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>

0
backend/__init__.py Normal file
View file

Binary file not shown.

32
backend/app.py Normal file
View file

@ -0,0 +1,32 @@
from flask import Flask, jsonify
from flask_cors import CORS
from routes.projects import projects_bp
from routes.contact import contact_bp
from routes.cv import cv_bp
from routes.services import services_bp
from dotenv import load_dotenv
import os
load_dotenv()
app = Flask(__name__)
CORS(app)
app.config["API_KEY"] = os.getenv("API_KEY")
@app.route('/api/')
@app.route('/')
def get_home():
return jsonify({
"return": "Welcome to API"
})
app.register_blueprint(projects_bp)
app.register_blueprint(contact_bp)
app.register_blueprint(cv_bp)
app.register_blueprint(services_bp)
if __name__ == '__main__':
app.run(debug=True, port=5000)

View file

@ -0,0 +1,9 @@
{
"first_name": "Anthony",
"last_name": "VIOLET",
"email": "tutu@tutu.com",
"phone_number": "bah nope",
"linkedin": "tjrs pas... quoique",
"git": "non",
"web": "ok"
}

36
backend/data/cv.json Normal file
View file

@ -0,0 +1,36 @@
[
{
"about_text": "Après environ 15 ans d'apprentissage en autodidacte, j'ai pu approfondir et expérimenter mes connaissances dans le développement web (PHP, POO, CSS, HTML, SQL...).",
"my_values": "la montagne, la neige et le caca",
"my_skills": [
{
"Python": [
"Numpy",
"Pandas"
],
"Javascript": [
"NodeJS",
"React"
]
}
],
"technologies": [
"PHP",
"Python"
],
"work_experience": [
{
"Vendanges": "lol"
}
],
"education": [
{
"Technofutur": "rien"
}
],
"hobbies": [
"manger",
"bouger"
]
}
]

View file

@ -0,0 +1,34 @@
[
{
"id": 1,
"name": "test",
"description": "test",
"technologies": "test",
"image": "test",
"url": "test",
"source": "test",
"created_at": 1758087635.903851,
"updated_at": 1758087635.903851,
"status": [
"En cours",
"Terminé",
"Futur projet"
]
},
{
"id": 2,
"name": "Maitre pokemon",
"description": "je suis le maitre Pokemon avec les 8 badges en ma possesion",
"technologies": "IT-PokeMaster",
"image": "Masterball.png",
"url": "Masterball.png",
"source": "Pokepedia",
"created_at": 1758089969.696575,
"updated_at": 1758089969.696576,
"status": [
"En cours",
"Terminé",
"Futur projet"
]
}
]

View file

@ -0,0 +1,14 @@
[
{
"id": 1,
"name" : "Création de site web",
"icon": "🌐",
"description": "Des sites web modernes, responsives et optimisés pour tous les appareils."
},
{
"id": 2,
"name" : "Création de site web",
"icon": "🌐",
"description": "Des sites web modernes, responsives et optimisés pour tous les appareils."
}
]

View file

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,24 @@
class ContactModel:
def __init__(self, data):
self.first_name = data.get('first_name')
self.last_name = data.get('last_name')
self.email = data.get('email')
self.phonenumber = data.get('phone_number')
self.linkedin = data.get('linkedin')
self.git = data.get('git')
self.web = data.get('web')
def is_valid(self):
return self.first_name is not None and self.last_name is not None and self.email is not None and self.phonenumber is not None
def to_dict(self):
return {
"first_name": self.first_name,
"last_name": self.last_name,
"email": self.email,
"phone_number": self.phonenumber,
"linkedin": self.linkedin,
"git": self.git,
"web": self.web,
}

View file

@ -0,0 +1,20 @@
class CVModel:
def __init__(self, data):
self.about_text = data.get("about_text")
self.my_values = data.get("my_values")
self.my_skills = data.get("my_skills")
self.technologies = data.get("technologies")
self.work_experience = data.get("work_experience")
self.education = data.get("education")
self.hobbies = data.get("hobbies")
def to_dict(self):
return {
"about_text": self.about_text,
"my_values": self.my_values,
"my_skills": self.my_skills,
"technologies": self.technologies,
"work_experience": self.work_experience,
"education": self.education,
"hobbies": self.hobbies
}

View file

@ -0,0 +1,31 @@
import time
from utils.enums import enumerates
class ProjectModel:
def __init__(self, data):
self.id = data.get('id')
self.name = data.get('name')
self.description = data.get('description')
self.technologies = data.get('technologies')
self.image = data.get('image')
self.url = data.get('url')
self.source = data.get('source')
self.created_at = data.get('created_at')
self.updated_at = data.get('updated_at')
self.status = data.get('status')
def is_valid(self):
return self.name is not None
def to_dict(self):
return {
"id": self.id,
"name": self.name,
"description": self.description,
"technologies": self.technologies,
"image": self.image,
"url": self.url,
"source": self.source,
"created_at": time.time() if self.created_at is None else self.created_at,
"updated_at": time.time() if self.updated_at is None else self.updated_at,
"status": enumerates["status"],
}

View file

@ -0,0 +1,14 @@
class ServiceModel:
def __init__(self, data):
self.service_id = data.get('id')
self.service_name = data.get('name')
self.service_icon = data.get('icon')
self.service_description = data.get('description')
def to_dict(self):
return {
"id": self.service_id,
"name": self.service_name,
"icon": self.service_icon,
"description": self.service_description
}

3
backend/requirements.txt Normal file
View file

@ -0,0 +1,3 @@
flask
flask-cors
dotenv

View file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

29
backend/routes/contact.py Normal file
View file

@ -0,0 +1,29 @@
from flask import Blueprint, jsonify, request, current_app
from utils.json_crud import load_json, save_json, add_entry, delete_entry, update_entry
from utils.data_loader import load_data
from models.contact_model import ContactModel
import os
DATA_DIR = os.path.join(os.path.dirname(__file__), '../data')
CONTACTS_FILE = os.path.join(DATA_DIR, 'contact.json')
contact_bp = Blueprint('contact', __name__, url_prefix='/api/contact')
@contact_bp.route('/', methods=['GET'])
def get_contact():
contacts = load_data('contact.json')
return jsonify(contacts)
@contact_bp.route('/', methods=['POST'])
def update_contact():
key = request.headers.get('x-api-key')
if key != current_app.config['API_KEY']:
return jsonify({
"error": "Unauthorized"
}), 401
data = request.json
new_entry = ContactModel(data).to_dict()
contact = [new_entry]
save_json(CONTACTS_FILE, contact)
return new_entry

41
backend/routes/cv.py Normal file
View file

@ -0,0 +1,41 @@
from flask import Blueprint, jsonify, request, current_app
from utils.data_loader import load_data
from utils.json_crud import load_json, save_json, add_entry, delete_entry, update_entry
from models.cv_model import CVModel
import os
DATA_DIR = os.path.join(os.path.dirname(__file__), '../data')
CV_FILE = os.path.join(DATA_DIR, 'cv.json')
cv_bp = Blueprint('cv', __name__, url_prefix='/api/cv')
@cv_bp.route('/', methods=['GET'])
def get_cv():
cv = load_data('cv.json')
return jsonify(cv)
@cv_bp.route('/', methods=['POST'])
def update_cv():
#key = request.headers.get('x-api-key')
#if key != current_app.config['API_KEY']:
# return jsonify({
# "error": "Unauthorized"
# }), 401
data = request.json
new_entry = CVModel(data).to_dict()
cv = [new_entry]
save_json(CV_FILE, cv)
return jsonify(new_entry), 201
@cv_bp.route('/skills/', methods=['GET'])
def get_skills():
cv = load_data('cv.json')
skills = cv[0].get('my_skills')
return jsonify(skills)
@cv_bp.route('/about/', methods=['GET'])
def get_about():
cv = load_data('cv.json')
about = cv[0].get('about_text')
return jsonify(about)

View file

@ -0,0 +1,48 @@
from flask import Blueprint, jsonify, request, current_app
from utils.data_loader import load_data
from utils.json_crud import load_json, save_json, add_entry, delete_entry, update_entry
from models.project_model import ProjectModel
import os
DATA_DIR = os.path.join(os.path.dirname(__file__), '../data')
PROJECTS_FILE = os.path.join(DATA_DIR, 'projects.json')
projects_bp = Blueprint('projects', __name__, url_prefix='/api/projects')
@projects_bp.route('/', methods=['GET'])
def get_projects():
projects = load_data('projects.json')
return jsonify(projects)
@projects_bp.route('/<project_id>', methods=['GET'])
def get_project(project_id):
projects = load_data('projects.json')
project = next((p for p in projects if p.get('id') == project_id), None)
print(project)
return jsonify(project)
@projects_bp.route('/', methods=['POST'])
def create_project():
key = request.headers.get('x-api-key')
if key != current_app.config['API_KEY']:
return jsonify({
"error": "Unauthorized"
}), 401
projects = load_data('projects.json')
entry = request.json
project = ProjectModel(entry)
if not project.is_valid():
return jsonify({
"error": "Invalid project data"
}), 400
new_id = max((p.get('id') for p in projects), default=0) + 1
data = project.to_dict()
data['id'] = new_id
added = add_entry(PROJECTS_FILE, data)
return jsonify(added), 201

View file

@ -0,0 +1,15 @@
from flask import Blueprint, jsonify, request, current_app
from utils.data_loader import load_data
from utils.json_crud import load_json, save_json, add_entry, delete_entry, update_entry
from models.service_model import ServiceModel
import os
DATA_DIR = os.path.join(os.path.dirname(__file__), '../data')
SERVICES_FILE = os.path.join(DATA_DIR, 'services.json')
services_bp = Blueprint('services', __name__, url_prefix='/api/services')
@services_bp.route('/', methods=['GET'])
def get_services():
services = load_data('services.json')
return jsonify(services)

View file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,8 @@
import json
import os
DATA_DIR = os.path.join(os.path.dirname(__file__), '../data')
def load_data(filename):
with open(os.path.join(DATA_DIR, filename), 'r') as f:
return json.load(f)

21
backend/utils/enums.py Normal file
View file

@ -0,0 +1,21 @@
enumerates = {
"status": [
"En cours",
"Terminé",
"Futur projet"
],
"technologies": [
"HTML & CSS",
"Python",
"Django",
"React",
"NodeJS",
"Angular",
"C#",
"PHP",
"Javascript",
"TypeScript",
"Unity",
"Godot"
],
}

View file

@ -0,0 +1,33 @@
import json
import os
def load_json(filename):
if not os.path.exists(filename):
return []
with open(filename, 'r', encoding='utf-8') as f:
return json.load(f)
def save_json(filename, data):
with open(filename, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=4, ensure_ascii=False)
def add_entry(filename, entry):
data = load_json(filename)
data.append(entry)
save_json(filename, data)
return entry
def update_entry(filename, entry_id, new_entry):
data = load_json(filename)
for i, item in enumerate(data):
if item.get('id') == entry_id:
data[i] = new_entry
save_json(filename, data)
return new_entry
return None
def delete_entry(filename, entry_id):
data = load_json(filename)
new_data = [item for item in data if item.get('id') != entry_id]
save_json(filename, new_data)
return len(data) != len(new_data)