ajout de CRUD total pour toute les routes
This commit is contained in:
parent
fec74d9f83
commit
da45beba93
5 changed files with 166 additions and 25 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
from flask import Blueprint, jsonify, request, current_app
|
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.json_crud import load_json, save_json
|
||||||
from utils.data_loader import load_data
|
from utils.data_loader import load_data
|
||||||
from models.contact_model import ContactModel
|
from models.contact_model import ContactModel
|
||||||
import os
|
import os
|
||||||
|
|
@ -11,19 +11,46 @@ contact_bp = Blueprint('contact', __name__, url_prefix='/api/contact')
|
||||||
|
|
||||||
@contact_bp.route('/', methods=['GET'])
|
@contact_bp.route('/', methods=['GET'])
|
||||||
def get_contact():
|
def get_contact():
|
||||||
contacts = load_data('contact.json')
|
contact = load_data('contact.json')
|
||||||
return jsonify(contacts)
|
return jsonify(contact)
|
||||||
|
|
||||||
@contact_bp.route('/', methods=['POST'])
|
@contact_bp.route('/', methods=['POST'])
|
||||||
|
def create_or_replace_contact():
|
||||||
|
key = request.headers.get('x-api-key')
|
||||||
|
if key != current_app.config['API_KEY']:
|
||||||
|
return jsonify({"error": "Unauthorized"}), 401
|
||||||
|
|
||||||
|
data = request.json or {}
|
||||||
|
model = ContactModel(data)
|
||||||
|
if not model.is_valid():
|
||||||
|
return jsonify({"error": "Invalid contact data"}), 400
|
||||||
|
new_entry = model.to_dict()
|
||||||
|
save_json(CONTACTS_FILE, new_entry)
|
||||||
|
return jsonify(new_entry), 201
|
||||||
|
|
||||||
|
@contact_bp.route('/', methods=['PUT', 'PATCH'])
|
||||||
def update_contact():
|
def update_contact():
|
||||||
key = request.headers.get('x-api-key')
|
key = request.headers.get('x-api-key')
|
||||||
if key != current_app.config['API_KEY']:
|
if key != current_app.config['API_KEY']:
|
||||||
return jsonify({
|
return jsonify({"error": "Unauthorized"}), 401
|
||||||
"error": "Unauthorized"
|
|
||||||
}), 401
|
|
||||||
|
|
||||||
data = request.json
|
current = load_json(CONTACTS_FILE) or {}
|
||||||
new_entry = ContactModel(data).to_dict()
|
payload = request.json or {}
|
||||||
contact = [new_entry]
|
updated = {**current, **payload}
|
||||||
save_json(CONTACTS_FILE, contact)
|
|
||||||
return new_entry
|
model = ContactModel(updated)
|
||||||
|
if not model.is_valid():
|
||||||
|
return jsonify({"error": "Invalid contact data"}), 400
|
||||||
|
|
||||||
|
save_json(CONTACTS_FILE, model.to_dict())
|
||||||
|
return jsonify(model.to_dict()), 200
|
||||||
|
|
||||||
|
@contact_bp.route('/', methods=['DELETE'])
|
||||||
|
def delete_contact():
|
||||||
|
key = request.headers.get('x-api-key')
|
||||||
|
if key != current_app.config['API_KEY']:
|
||||||
|
return jsonify({"error": "Unauthorized"}), 401
|
||||||
|
|
||||||
|
# Clear contact info
|
||||||
|
save_json(CONTACTS_FILE, {})
|
||||||
|
return jsonify({"status": "success"}), 200
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
from flask import Blueprint, jsonify, request, current_app
|
from flask import Blueprint, jsonify, request, current_app
|
||||||
from utils.data_loader import load_data
|
from utils.data_loader import load_data
|
||||||
from utils.json_crud import load_json, save_json, add_entry, delete_entry, update_entry
|
from utils.json_crud import load_json, save_json
|
||||||
from models.cv_model import CVModel
|
from models.cv_model import CVModel
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
@ -15,27 +15,53 @@ def get_cv():
|
||||||
return jsonify(cv)
|
return jsonify(cv)
|
||||||
|
|
||||||
@cv_bp.route('/', methods=['POST'])
|
@cv_bp.route('/', methods=['POST'])
|
||||||
def update_cv():
|
def create_or_replace_cv():
|
||||||
#key = request.headers.get('x-api-key')
|
key = request.headers.get('x-api-key')
|
||||||
#if key != current_app.config['API_KEY']:
|
if key != current_app.config['API_KEY']:
|
||||||
# return jsonify({
|
return jsonify({"error": "Unauthorized"}), 401
|
||||||
# "error": "Unauthorized"
|
|
||||||
# }), 401
|
|
||||||
|
|
||||||
data = request.json
|
data = request.json or {}
|
||||||
new_entry = CVModel(data).to_dict()
|
new_entry = CVModel(data).to_dict()
|
||||||
cv = [new_entry]
|
cv = [new_entry]
|
||||||
save_json(CV_FILE, cv)
|
save_json(CV_FILE, cv)
|
||||||
return jsonify(new_entry), 201
|
return jsonify(new_entry), 201
|
||||||
|
|
||||||
|
@cv_bp.route('/', methods=['PUT', 'PATCH'])
|
||||||
|
def update_cv():
|
||||||
|
key = request.headers.get('x-api-key')
|
||||||
|
if key != current_app.config['API_KEY']:
|
||||||
|
return jsonify({"error": "Unauthorized"}), 401
|
||||||
|
|
||||||
|
current_list = load_json(CV_FILE) or []
|
||||||
|
current = current_list[0] if current_list else {}
|
||||||
|
payload = request.json or {}
|
||||||
|
updated = {**current, **payload}
|
||||||
|
|
||||||
|
new_entry = CVModel(updated).to_dict()
|
||||||
|
save_json(CV_FILE, [new_entry])
|
||||||
|
return jsonify(new_entry), 200
|
||||||
|
|
||||||
|
@cv_bp.route('/', methods=['DELETE'])
|
||||||
|
def delete_cv():
|
||||||
|
key = request.headers.get('x-api-key')
|
||||||
|
if key != current_app.config['API_KEY']:
|
||||||
|
return jsonify({"error": "Unauthorized"}), 401
|
||||||
|
|
||||||
|
save_json(CV_FILE, [])
|
||||||
|
return jsonify({"status": "success"}), 200
|
||||||
|
|
||||||
@cv_bp.route('/skills/', methods=['GET'])
|
@cv_bp.route('/skills/', methods=['GET'])
|
||||||
def get_skills():
|
def get_skills():
|
||||||
cv = load_data('cv.json')
|
cv = load_data('cv.json')
|
||||||
|
if not cv:
|
||||||
|
return jsonify([])
|
||||||
skills = cv[0].get('my_skills')
|
skills = cv[0].get('my_skills')
|
||||||
return jsonify(skills)
|
return jsonify(skills)
|
||||||
|
|
||||||
@cv_bp.route('/about/', methods=['GET'])
|
@cv_bp.route('/about/', methods=['GET'])
|
||||||
def get_about():
|
def get_about():
|
||||||
cv = load_data('cv.json')
|
cv = load_data('cv.json')
|
||||||
|
if not cv:
|
||||||
|
return jsonify("")
|
||||||
about = cv[0].get('about_text')
|
about = cv[0].get('about_text')
|
||||||
return jsonify(about)
|
return jsonify(about)
|
||||||
|
|
@ -17,8 +17,10 @@ def get_projects():
|
||||||
@projects_bp.route('/<project_id>', methods=['GET'])
|
@projects_bp.route('/<project_id>', methods=['GET'])
|
||||||
def get_project(project_id):
|
def get_project(project_id):
|
||||||
projects = load_data('projects.json')
|
projects = load_data('projects.json')
|
||||||
project = next((p for p in projects if p.get('id') == project_id), None)
|
# Ensure numeric comparison for id
|
||||||
print(project)
|
project = next((p for p in projects if str(p.get('id')) == str(project_id)), None)
|
||||||
|
if not project:
|
||||||
|
return jsonify({"error": "Project not found"}), 404
|
||||||
return jsonify(project)
|
return jsonify(project)
|
||||||
|
|
||||||
@projects_bp.route('/', methods=['POST'])
|
@projects_bp.route('/', methods=['POST'])
|
||||||
|
|
@ -30,7 +32,7 @@ def create_project():
|
||||||
"error": "Unauthorized"
|
"error": "Unauthorized"
|
||||||
}), 401
|
}), 401
|
||||||
projects = load_data('projects.json')
|
projects = load_data('projects.json')
|
||||||
entry = request.json
|
entry = request.json or {}
|
||||||
|
|
||||||
project = ProjectModel(entry)
|
project = ProjectModel(entry)
|
||||||
|
|
||||||
|
|
@ -47,10 +49,39 @@ def create_project():
|
||||||
added = add_entry(PROJECTS_FILE, data)
|
added = add_entry(PROJECTS_FILE, data)
|
||||||
return jsonify(added), 201
|
return jsonify(added), 201
|
||||||
|
|
||||||
|
@projects_bp.route('/<project_id>', methods=['PUT', 'PATCH'])
|
||||||
|
def update_project(project_id):
|
||||||
|
key = request.headers.get('x-api-key')
|
||||||
|
if key != current_app.config['API_KEY']:
|
||||||
|
return jsonify({"error": "Unauthorized"}), 401
|
||||||
|
|
||||||
|
projects = load_json(PROJECTS_FILE)
|
||||||
|
project = next((p for p in projects if str(p.get('id')) == str(project_id)), None)
|
||||||
|
if not project:
|
||||||
|
return jsonify({"error": "Project not found"}), 404
|
||||||
|
|
||||||
|
payload = request.json or {}
|
||||||
|
# Merge existing with payload
|
||||||
|
updated = {**project, **payload}
|
||||||
|
# Preserve id
|
||||||
|
updated['id'] = project['id']
|
||||||
|
|
||||||
|
# Validate using model
|
||||||
|
model = ProjectModel(updated)
|
||||||
|
if not model.is_valid():
|
||||||
|
return jsonify({"error": "Invalid project data"}), 400
|
||||||
|
|
||||||
|
saved = update_entry(PROJECTS_FILE, updated['id'], model.to_dict())
|
||||||
|
return jsonify(saved), 200
|
||||||
|
|
||||||
@projects_bp.route('/<project_id>', methods=['DELETE'])
|
@projects_bp.route('/<project_id>', methods=['DELETE'])
|
||||||
def delete_project(project_id):
|
def delete_project(project_id):
|
||||||
projects = load_data(PROJECTS_FILE)
|
key = request.headers.get('x-api-key')
|
||||||
project = next((p for p in projects if str(p.get('id')) == project_id), None)
|
if key != current_app.config['API_KEY']:
|
||||||
|
return jsonify({"error": "Unauthorized"}), 401
|
||||||
|
|
||||||
|
projects = load_json(PROJECTS_FILE)
|
||||||
|
project = next((p for p in projects if str(p.get('id')) == str(project_id)), None)
|
||||||
|
|
||||||
if project:
|
if project:
|
||||||
deleted = delete_entry(PROJECTS_FILE, project_id)
|
deleted = delete_entry(PROJECTS_FILE, project_id)
|
||||||
|
|
|
||||||
|
|
@ -12,4 +12,60 @@ services_bp = Blueprint('services', __name__, url_prefix='/api/services')
|
||||||
@services_bp.route('/', methods=['GET'])
|
@services_bp.route('/', methods=['GET'])
|
||||||
def get_services():
|
def get_services():
|
||||||
services = load_data('services.json')
|
services = load_data('services.json')
|
||||||
return jsonify(services)
|
return jsonify(services)
|
||||||
|
|
||||||
|
@services_bp.route('/<service_id>', methods=['GET'])
|
||||||
|
def get_service(service_id):
|
||||||
|
services = load_data('services.json')
|
||||||
|
service = next((s for s in services if str(s.get('id')) == str(service_id)), None)
|
||||||
|
if not service:
|
||||||
|
return jsonify({"error": "Service not found"}), 404
|
||||||
|
return jsonify(service)
|
||||||
|
|
||||||
|
@services_bp.route('/', methods=['POST'])
|
||||||
|
def create_service():
|
||||||
|
key = request.headers.get('x-api-key')
|
||||||
|
if key != current_app.config['API_KEY']:
|
||||||
|
return jsonify({"error": "Unauthorized"}), 401
|
||||||
|
|
||||||
|
services = load_json(SERVICES_FILE)
|
||||||
|
entry = request.json or {}
|
||||||
|
# generate new id
|
||||||
|
new_id = max((s.get('id') for s in services), default=0) + 1
|
||||||
|
model = ServiceModel({**entry, 'id': new_id})
|
||||||
|
data = model.to_dict()
|
||||||
|
|
||||||
|
added = add_entry(SERVICES_FILE, data)
|
||||||
|
return jsonify(added), 201
|
||||||
|
|
||||||
|
@services_bp.route('/<service_id>', methods=['PUT', 'PATCH'])
|
||||||
|
def update_service(service_id):
|
||||||
|
key = request.headers.get('x-api-key')
|
||||||
|
if key != current_app.config['API_KEY']:
|
||||||
|
return jsonify({"error": "Unauthorized"}), 401
|
||||||
|
|
||||||
|
services = load_json(SERVICES_FILE)
|
||||||
|
service = next((s for s in services if str(s.get('id')) == str(service_id)), None)
|
||||||
|
if not service:
|
||||||
|
return jsonify({"error": "Service not found"}), 404
|
||||||
|
|
||||||
|
payload = request.json or {}
|
||||||
|
updated = {**service, **payload}
|
||||||
|
updated['id'] = service['id']
|
||||||
|
|
||||||
|
saved = update_entry(SERVICES_FILE, updated['id'], updated)
|
||||||
|
return jsonify(saved), 200
|
||||||
|
|
||||||
|
@services_bp.route('/<service_id>', methods=['DELETE'])
|
||||||
|
def delete_service(service_id):
|
||||||
|
key = request.headers.get('x-api-key')
|
||||||
|
if key != current_app.config['API_KEY']:
|
||||||
|
return jsonify({"error": "Unauthorized"}), 401
|
||||||
|
|
||||||
|
services = load_json(SERVICES_FILE)
|
||||||
|
service = next((s for s in services if str(s.get('id')) == str(service_id)), None)
|
||||||
|
if not service:
|
||||||
|
return jsonify({"error": "Service not found"}), 404
|
||||||
|
|
||||||
|
deleted = delete_entry(SERVICES_FILE, service_id)
|
||||||
|
return jsonify(deleted), 200
|
||||||
|
|
@ -15,6 +15,7 @@ export default function Footer() {
|
||||||
return (
|
return (
|
||||||
<footer className={isTop ? "sticky-footer" : "sticky-footer is-visible"}>
|
<footer className={isTop ? "sticky-footer" : "sticky-footer is-visible"}>
|
||||||
<p>© 2025 - Toine</p>
|
<p>© 2025 - Toine</p>
|
||||||
|
<p><small>Développé avec Python, JavaScript et React. Alimenté par Next.js.</small></p>
|
||||||
</footer>
|
</footer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue