- Modal display of privacy statement & Terms & Conditions - Consent-flag ==> check of privacy and Terms & Conditions - customisation option added to show or hide DynamicForm titles
223 lines
8.3 KiB
Python
223 lines
8.3 KiB
Python
import os
|
|
import re
|
|
import logging
|
|
from packaging import version
|
|
from flask import current_app
|
|
|
|
class ContentManager:
|
|
def __init__(self, app=None):
|
|
self.app = app
|
|
if app:
|
|
self.init_app(app)
|
|
|
|
def init_app(self, app):
|
|
self.app = app
|
|
|
|
# Controleer of het pad bestaat
|
|
# if not os.path.exists(app.config['CONTENT_DIR']):
|
|
# logger.warning(f"Content directory not found at: {app.config['CONTENT_DIR']}")
|
|
# else:
|
|
# logger.info(f"Content directory configured at: {app.config['CONTENT_DIR']}")
|
|
|
|
def get_content_path(self, content_type, major_minor=None, patch=None):
|
|
"""
|
|
Geef het volledige pad naar een contentbestand
|
|
|
|
Args:
|
|
content_type (str): Type content (bv. 'changelog', 'terms')
|
|
major_minor (str, optional): Major.Minor versie (bv. '1.0')
|
|
patch (str, optional): Patchnummer (bv. '5')
|
|
|
|
Returns:
|
|
str: Volledige pad naar de content map of bestand
|
|
"""
|
|
content_path = os.path.join(self.app.config['CONTENT_DIR'], content_type)
|
|
|
|
if major_minor:
|
|
content_path = os.path.join(content_path, major_minor)
|
|
|
|
if patch:
|
|
content_path = os.path.join(content_path, f"{major_minor}.{patch}.md")
|
|
|
|
return content_path
|
|
|
|
def _parse_version(self, filename):
|
|
"""Parse een versienummer uit een bestandsnaam"""
|
|
match = re.match(r'(\d+\.\d+)\.(\d+)\.md', filename)
|
|
if match:
|
|
return match.group(1), match.group(2)
|
|
return None, None
|
|
|
|
def get_latest_version(self, content_type, major_minor=None):
|
|
"""
|
|
Verkrijg de laatste versie van een bepaald contenttype
|
|
|
|
Args:
|
|
content_type (str): Type content (bv. 'changelog', 'terms')
|
|
major_minor (str, optional): Specifieke major.minor versie, anders de hoogste
|
|
|
|
Returns:
|
|
tuple: (major_minor, patch, full_version) of None als niet gevonden
|
|
"""
|
|
try:
|
|
# Basispad voor dit contenttype
|
|
content_path = os.path.join(self.app.config['CONTENT_DIR'], content_type)
|
|
|
|
if not os.path.exists(content_path):
|
|
current_app.logger.error(f"Content path does not exist: {content_path}")
|
|
return None
|
|
|
|
# Als geen major_minor opgegeven, vind de hoogste
|
|
if not major_minor:
|
|
available_versions = [f for f in os.listdir(content_path) if not f.startswith('.')]
|
|
if not available_versions:
|
|
return None
|
|
|
|
# Sorteer op versienummer (major.minor)
|
|
available_versions.sort(key=lambda v: version.parse(v))
|
|
major_minor = available_versions[-1]
|
|
|
|
# Nu we major_minor hebben, zoek de hoogste patch
|
|
major_minor_path = os.path.join(content_path, major_minor)
|
|
current_app.logger.debug(f"Major/Minor path: {major_minor_path}")
|
|
|
|
if not os.path.exists(major_minor_path):
|
|
current_app.logger.error(f"Version path does not exist: {major_minor_path}")
|
|
return None
|
|
|
|
files = [f for f in os.listdir(major_minor_path) if not f.startswith('.')]
|
|
current_app.logger.debug(f"Files in version path: {files}")
|
|
version_files = []
|
|
|
|
for file in files:
|
|
mm, p = self._parse_version(file)
|
|
current_app.logger.debug(f"File: {file}, mm: {mm}, p: {p}")
|
|
if mm == major_minor and p:
|
|
version_files.append((mm, p, f"{mm}.{p}"))
|
|
|
|
if not version_files:
|
|
return None
|
|
|
|
# Sorteer op patch nummer
|
|
version_files.sort(key=lambda v: int(v[1]))
|
|
|
|
current_app.logger.debug(f"Latest version: {version_files[-1]}")
|
|
return version_files[-1]
|
|
|
|
except Exception as e:
|
|
current_app.logger.error(f"Error finding latest version for {content_type}: {str(e)}")
|
|
return None
|
|
|
|
def read_content(self, content_type, major_minor=None, patch=None):
|
|
"""
|
|
Lees content met versieondersteuning
|
|
|
|
Als major_minor en patch niet zijn opgegeven, wordt de laatste versie gebruikt.
|
|
Als alleen major_minor is opgegeven, wordt de laatste patch van die versie gebruikt.
|
|
|
|
Args:
|
|
content_type (str): Type content (bv. 'changelog', 'terms')
|
|
major_minor (str, optional): Major.Minor versie (bv. '1.0')
|
|
patch (str, optional): Patchnummer (bv. '5')
|
|
|
|
Returns:
|
|
dict: {
|
|
'content': str,
|
|
'version': str,
|
|
'content_type': str
|
|
} of None bij fout
|
|
"""
|
|
try:
|
|
current_app.logger.debug(f"Reading content {content_type}")
|
|
# Als geen versie opgegeven, vind de laatste
|
|
if not major_minor:
|
|
version_info = self.get_latest_version(content_type)
|
|
if not version_info:
|
|
current_app.logger.error(f"No versions found for {content_type}")
|
|
return None
|
|
|
|
major_minor, patch, full_version = version_info
|
|
|
|
# Als geen patch opgegeven, vind de laatste patch voor deze major_minor
|
|
elif not patch:
|
|
version_info = self.get_latest_version(content_type, major_minor)
|
|
if not version_info:
|
|
current_app.logger.error(f"No versions found for {content_type} {major_minor}")
|
|
return None
|
|
|
|
major_minor, patch, full_version = version_info
|
|
else:
|
|
full_version = f"{major_minor}.{patch}"
|
|
|
|
# Nu hebben we major_minor en patch, lees het bestand
|
|
file_path = self.get_content_path(content_type, major_minor, patch)
|
|
current_app.logger.debug(f"Content File path: {file_path}")
|
|
|
|
if not os.path.exists(file_path):
|
|
current_app.logger.error(f"Content file does not exist: {file_path}")
|
|
return None
|
|
|
|
with open(file_path, 'r', encoding='utf-8') as file:
|
|
content = file.read()
|
|
|
|
current_app.logger.debug(f"Content read: {content}")
|
|
|
|
return {
|
|
'content': content,
|
|
'version': full_version,
|
|
'content_type': content_type
|
|
}
|
|
|
|
except Exception as e:
|
|
current_app.logger.error(f"Error reading content {content_type} {major_minor}.{patch}: {str(e)}")
|
|
return None
|
|
|
|
def list_content_types(self):
|
|
"""Lijst alle beschikbare contenttypes op"""
|
|
try:
|
|
return [d for d in os.listdir(self.app.config['CONTENT_DIR'])
|
|
if os.path.isdir(os.path.join(self.app.config['CONTENT_DIR'], d))]
|
|
except Exception as e:
|
|
current_app.logger.error(f"Error listing content types: {str(e)}")
|
|
return []
|
|
|
|
def list_versions(self, content_type):
|
|
"""
|
|
Lijst alle beschikbare versies voor een contenttype
|
|
|
|
Returns:
|
|
list: Lijst van dicts met versie-informatie
|
|
[{'version': '1.0.0', 'path': '/path/to/file', 'date_modified': datetime}]
|
|
"""
|
|
versions = []
|
|
try:
|
|
content_path = os.path.join(self.app.config['CONTENT_DIR'], content_type)
|
|
|
|
if not os.path.exists(content_path):
|
|
return []
|
|
|
|
for major_minor in os.listdir(content_path):
|
|
major_minor_path = os.path.join(content_path, major_minor)
|
|
|
|
if not os.path.isdir(major_minor_path):
|
|
continue
|
|
|
|
for file in os.listdir(major_minor_path):
|
|
mm, p = self._parse_version(file)
|
|
if mm and p:
|
|
file_path = os.path.join(major_minor_path, file)
|
|
mod_time = os.path.getmtime(file_path)
|
|
versions.append({
|
|
'version': f"{mm}.{p}",
|
|
'path': file_path,
|
|
'date_modified': mod_time
|
|
})
|
|
|
|
# Sorteer op versienummer
|
|
versions.sort(key=lambda v: version.parse(v['version']))
|
|
return versions
|
|
|
|
except Exception as e:
|
|
current_app.logger.error(f"Error listing versions for {content_type}: {str(e)}")
|
|
return []
|