wip
This commit is contained in:
BIN
build/__pycache__/sync_version.cpython-311.pyc
Normal file
BIN
build/__pycache__/sync_version.cpython-311.pyc
Normal file
Binary file not shown.
@@ -1,67 +0,0 @@
|
||||
{
|
||||
"features": {
|
||||
"basic": {
|
||||
"name": "Basic Text Generation",
|
||||
"description": "Core text texture generation functionality",
|
||||
"enabled_by_default": true,
|
||||
"components": [
|
||||
"core.text_processor",
|
||||
"core.generation_engine",
|
||||
"ui.panels.basic"
|
||||
]
|
||||
},
|
||||
"preview": {
|
||||
"name": "Live Preview",
|
||||
"description": "Real-time preview of text textures",
|
||||
"enabled_by_default": true,
|
||||
"components": ["ui.preview", "core.text_fitting"]
|
||||
},
|
||||
"advanced_styling": {
|
||||
"name": "Advanced Styling Options",
|
||||
"description": "Extended styling and customization options",
|
||||
"enabled_by_default": false,
|
||||
"components": ["ui.panels.advanced", "core.advanced_styling"]
|
||||
},
|
||||
"normal_maps": {
|
||||
"name": "Normal Map Generation",
|
||||
"description": "Generate normal maps from text",
|
||||
"enabled_by_default": false,
|
||||
"components": ["core.normal_maps", "ui.panels.normal_maps"]
|
||||
},
|
||||
"presets": {
|
||||
"name": "Preset Management",
|
||||
"description": "Save and load text style presets",
|
||||
"enabled_by_default": false,
|
||||
"components": [
|
||||
"presets.storage_system",
|
||||
"operators.preset_ops",
|
||||
"ui.panels.presets"
|
||||
]
|
||||
},
|
||||
"batch_processing": {
|
||||
"name": "Batch Processing",
|
||||
"description": "Process multiple text textures at once",
|
||||
"enabled_by_default": false,
|
||||
"components": ["operators.batch_ops", "ui.panels.batch"]
|
||||
}
|
||||
},
|
||||
"version_configs": {
|
||||
"free": {
|
||||
"enabled_features": ["basic", "preview"],
|
||||
"max_texture_size": 1024,
|
||||
"max_concurrent_operations": 1
|
||||
},
|
||||
"full": {
|
||||
"enabled_features": [
|
||||
"basic",
|
||||
"preview",
|
||||
"advanced_styling",
|
||||
"normal_maps",
|
||||
"presets",
|
||||
"batch_processing"
|
||||
],
|
||||
"max_texture_size": 4096,
|
||||
"max_concurrent_operations": 4
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,11 @@
|
||||
"description": "Free version - core text texture generation only",
|
||||
"exclude_files": [
|
||||
"core/normal_maps.py",
|
||||
"operators/preset_ops.py",
|
||||
"presets/",
|
||||
"operators/utility_ops.py",
|
||||
"presets/"
|
||||
"operators/preset_ops.py"
|
||||
],
|
||||
"exclude_patterns": ["*batch*", "*advanced*"],
|
||||
"exclude_patterns": ["*batch*", "*advanced*", "*overlay*", "*utility*"],
|
||||
"max_texture_size": 1024,
|
||||
"max_concurrent_operations": 1
|
||||
},
|
||||
@@ -25,6 +25,10 @@
|
||||
"feature_to_files_mapping": {
|
||||
"normal_maps": ["core/normal_maps.py"],
|
||||
"presets": ["presets/", "operators/preset_ops.py"],
|
||||
"batch_processing": ["operators/utility_ops.py"]
|
||||
"batch_processing": ["operators/utility_ops.py"],
|
||||
"image_overlays": ["operators/utility_ops.py"],
|
||||
"basic_utilities": ["operators/utility_ops.py"],
|
||||
"advanced_utilities": ["operators/utility_ops.py"],
|
||||
"advanced_styling": []
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,12 @@ def create_template_variables(config: Dict, version: str, version_type: str = "f
|
||||
# Get version-specific configuration
|
||||
version_config = exclusions_config['version_configs'][version_type]
|
||||
|
||||
# Define features based on version type
|
||||
if version_type == "free":
|
||||
enabled_features = ["basic", "preview", "image_overlays", "basic_utilities"]
|
||||
else: # full version
|
||||
enabled_features = ["basic", "preview", "image_overlays", "basic_utilities", "advanced_styling", "normal_maps", "presets", "batch_processing", "advanced_utilities"]
|
||||
|
||||
# Parse Blender version
|
||||
blender_version = config['project']['blender_version_min']
|
||||
blender_parts = blender_version.split('.')
|
||||
@@ -98,6 +104,7 @@ def create_template_variables(config: Dict, version: str, version_type: str = "f
|
||||
'BLENDER_VERSION_MINOR': str(blender_minor),
|
||||
'BLENDER_VERSION_PATCH': str(blender_patch),
|
||||
'DEPENDENCIES': dependencies_str,
|
||||
'ENABLED_FEATURES': json.dumps(enabled_features),
|
||||
'MAX_TEXTURE_SIZE': str(version_config['max_texture_size']),
|
||||
'MAX_CONCURRENT_OPERATIONS': str(version_config['max_concurrent_operations'])
|
||||
}
|
||||
|
||||
@@ -2,26 +2,39 @@
|
||||
Constants and metadata for the Text Texture Generator addon.
|
||||
"""
|
||||
|
||||
# Version information
|
||||
VERSION_TYPE = "{{VERSION_TYPE}}" # "free" or "full"
|
||||
|
||||
bl_info = {
|
||||
"name": "{{PROJECT_NAME}}",
|
||||
"name": "{{PROJECT_NAME}}" + (" Free" if VERSION_TYPE == "free" else " Full"),
|
||||
"author": "{{PROJECT_AUTHOR}}",
|
||||
"version": ({{VERSION_MAJOR}}, {{VERSION_MINOR}}, {{VERSION_PATCH}}),
|
||||
"blender": ({{BLENDER_VERSION_MAJOR}}, {{BLENDER_VERSION_MINOR}}, {{BLENDER_VERSION_PATCH}}),
|
||||
"location": "{{PROJECT_LOCATION}}",
|
||||
"description": "{{PROJECT_DESCRIPTION}}",
|
||||
"description": "{{PROJECT_DESCRIPTION}}" + (" - Free Version (Limited Features)" if VERSION_TYPE == "free" else " - Full Version"),
|
||||
"category": "{{PROJECT_CATEGORY}}",
|
||||
}
|
||||
|
||||
# Version information
|
||||
VERSION_TYPE = "{{VERSION_TYPE}}" # "free" or "full"
|
||||
# Feature configuration based on version type
|
||||
ENABLED_FEATURES = ["basic", "preview"] if VERSION_TYPE == "free" else [
|
||||
"basic", "preview", "presets", "normal_maps", "batch_processing",
|
||||
"image_overlays", "basic_utilities", "advanced_utilities", "advanced_styling",
|
||||
"stroke_effects", "blur_effects", "shadow_glow_effects", "shader_generation"
|
||||
]
|
||||
|
||||
# Version-specific limits (applied at build time through file exclusions)
|
||||
def get_version_limits():
|
||||
"""Get version-specific limits."""
|
||||
return {
|
||||
"max_texture_size": {{MAX_TEXTURE_SIZE}},
|
||||
"max_concurrent_operations": {{MAX_CONCURRENT_OPERATIONS}}
|
||||
}
|
||||
if VERSION_TYPE == "free":
|
||||
return {
|
||||
"max_texture_size": {{MAX_TEXTURE_SIZE}},
|
||||
"max_concurrent_operations": {{MAX_CONCURRENT_OPERATIONS}}
|
||||
}
|
||||
else:
|
||||
return {
|
||||
"max_texture_size": 4096,
|
||||
"max_concurrent_operations": 4
|
||||
}
|
||||
|
||||
def is_free_version():
|
||||
"""Check if this is the free version."""
|
||||
@@ -29,4 +42,118 @@ def is_free_version():
|
||||
|
||||
def is_full_version():
|
||||
"""Check if this is the full version."""
|
||||
return VERSION_TYPE == "full"
|
||||
return VERSION_TYPE == "full"
|
||||
|
||||
# UI Helper Functions for Version Display
|
||||
def get_version_badge_text():
|
||||
"""Get version badge text for UI display."""
|
||||
return "FREE" if is_free_version() else "PRO"
|
||||
|
||||
def get_version_badge_icon():
|
||||
"""Get appropriate icon for version badge."""
|
||||
return 'GIFT' if is_free_version() else 'STAR'
|
||||
|
||||
def get_upgrade_hint_text(feature_name):
|
||||
"""Get contextual upgrade hint text for specific features."""
|
||||
if not is_free_version():
|
||||
return ""
|
||||
|
||||
return f"Upgrade to Pro version to access {feature_name}"
|
||||
|
||||
# Feature availability functions
|
||||
def has_feature(feature_name):
|
||||
"""Check if a specific feature is available."""
|
||||
return feature_name in ENABLED_FEATURES
|
||||
|
||||
def has_image_overlays():
|
||||
"""Check if image overlay features are available"""
|
||||
return has_feature("image_overlays")
|
||||
|
||||
def has_basic_utilities():
|
||||
"""Check if basic utility operations are available"""
|
||||
return has_feature("basic_utilities")
|
||||
|
||||
def has_presets():
|
||||
"""Check if preset features are available"""
|
||||
return has_feature("presets")
|
||||
|
||||
def has_normal_maps():
|
||||
"""Check if normal map generation is available"""
|
||||
return has_feature("normal_maps")
|
||||
|
||||
def has_batch_processing():
|
||||
"""Check if batch processing is available"""
|
||||
return has_feature("batch_processing")
|
||||
|
||||
def has_advanced_utilities():
|
||||
"""Check if advanced utility operations are available"""
|
||||
return has_feature("advanced_utilities")
|
||||
|
||||
def has_advanced_styling():
|
||||
"""Check if advanced styling options are available"""
|
||||
return has_feature("advanced_styling")
|
||||
|
||||
def has_stroke_effects():
|
||||
"""Check if stroke effects are available"""
|
||||
return has_feature("stroke_effects")
|
||||
|
||||
def has_blur_effects():
|
||||
"""Check if blur effects are available"""
|
||||
return has_feature("blur_effects")
|
||||
|
||||
def has_shadow_glow_effects():
|
||||
"""Check if shadow and glow effects are available"""
|
||||
return has_feature("shadow_glow_effects")
|
||||
|
||||
def has_shader_generation():
|
||||
"""Check if shader generation is available"""
|
||||
return has_feature("shader_generation")
|
||||
|
||||
def get_max_resolution():
|
||||
"""Get maximum texture resolution based on version"""
|
||||
limits = get_version_limits()
|
||||
return limits.get("max_texture_size", 1024)
|
||||
|
||||
def should_show_feature_lock(feature_name):
|
||||
"""Check if feature lock indicator should be shown."""
|
||||
# Map feature names to their availability functions
|
||||
feature_checks = {
|
||||
'presets': has_presets,
|
||||
'normal_maps': has_normal_maps,
|
||||
'batch_processing': has_batch_processing,
|
||||
'advanced_utilities': has_advanced_utilities,
|
||||
'advanced_styling': has_advanced_styling,
|
||||
'image_overlays': has_image_overlays,
|
||||
'basic_utilities': has_basic_utilities,
|
||||
'stroke_effects': has_stroke_effects,
|
||||
'blur_effects': has_blur_effects,
|
||||
'shadow_glow_effects': has_shadow_glow_effects,
|
||||
'shader_generation': has_shader_generation
|
||||
}
|
||||
|
||||
if is_full_version():
|
||||
return False
|
||||
|
||||
# For free version, show lock if feature is not available
|
||||
if feature_name in feature_checks:
|
||||
return not feature_checks[feature_name]()
|
||||
|
||||
return True # Show lock for unknown features
|
||||
|
||||
def get_feature_availability_text():
|
||||
"""Get text describing current feature availability."""
|
||||
if is_free_version():
|
||||
return "Free version - Basic features available"
|
||||
return "Pro version - All features available"
|
||||
|
||||
def get_version_info_details():
|
||||
"""Get detailed version information for display."""
|
||||
limits = get_version_limits()
|
||||
info = {
|
||||
'version_type': VERSION_TYPE.upper(),
|
||||
'max_texture_size': limits.get('max_texture_size', 'Unlimited'),
|
||||
'max_concurrent_operations': limits.get('max_concurrent_operations', 'Unlimited'),
|
||||
'features_enabled': len(ENABLED_FEATURES),
|
||||
'upgrade_available': is_free_version()
|
||||
}
|
||||
return info
|
||||
@@ -186,6 +186,92 @@ def validate_constants(zip_path: Path, config: Dict, version_type: str) -> Valid
|
||||
|
||||
return result
|
||||
|
||||
def validate_version_differences(zip_path: Path, config: Dict, version_type: str) -> ValidationResult:
|
||||
"""Validate version-specific content and file exclusions."""
|
||||
result = ValidationResult()
|
||||
addon_id = config['project']['id']
|
||||
|
||||
# Load exclusions configuration
|
||||
exclusions_path = get_project_root() / "build" / "file_exclusions.json"
|
||||
try:
|
||||
with open(exclusions_path, 'r') as f:
|
||||
exclusions_config = json.load(f)
|
||||
except Exception as e:
|
||||
result.add_error(f"Could not load file exclusions config: {e}")
|
||||
return result
|
||||
|
||||
version_config = exclusions_config['version_configs'].get(version_type, {})
|
||||
excluded_files = version_config.get('exclude_files', [])
|
||||
excluded_patterns = version_config.get('exclude_patterns', [])
|
||||
|
||||
try:
|
||||
with zipfile.ZipFile(zip_path, 'r') as zip_file:
|
||||
file_list = zip_file.namelist()
|
||||
|
||||
# Check that excluded files are actually excluded in free version
|
||||
if version_type == "free":
|
||||
excluded_found = []
|
||||
for excluded_file in excluded_files:
|
||||
full_path = f"{addon_id}/{excluded_file}"
|
||||
if full_path in file_list or any(f.startswith(full_path) for f in file_list):
|
||||
excluded_found.append(excluded_file)
|
||||
|
||||
if excluded_found:
|
||||
result.add_error(f"Free version contains excluded files: {excluded_found}")
|
||||
else:
|
||||
result.add_info(f"Correctly excluded {len(excluded_files)} premium files from free version")
|
||||
|
||||
# Check for excluded patterns
|
||||
pattern_violations = []
|
||||
for file_path in file_list:
|
||||
for pattern in excluded_patterns:
|
||||
if pattern.strip('*').lower() in file_path.lower():
|
||||
pattern_violations.append((file_path, pattern))
|
||||
|
||||
if pattern_violations:
|
||||
result.add_warning(f"Files matching excluded patterns found: {pattern_violations}")
|
||||
|
||||
elif version_type == "full":
|
||||
# Full version should contain premium files
|
||||
missing_premium = []
|
||||
for premium_file in excluded_files:
|
||||
full_path = f"{addon_id}/{premium_file}"
|
||||
if full_path not in file_list and not any(f.startswith(full_path) for f in file_list):
|
||||
missing_premium.append(premium_file)
|
||||
|
||||
if missing_premium:
|
||||
result.add_error(f"Full version missing premium files: {missing_premium}")
|
||||
else:
|
||||
result.add_info(f"Full version correctly includes all {len(excluded_files)} premium features")
|
||||
|
||||
# Validate UI helper functions are present in constants.py
|
||||
constants_path = f"{addon_id}/utils/constants.py"
|
||||
if constants_path in file_list:
|
||||
constants_content = zip_file.read(constants_path).decode('utf-8')
|
||||
ui_functions = [
|
||||
'get_version_badge_text',
|
||||
'get_version_badge_icon',
|
||||
'get_upgrade_hint_text',
|
||||
'should_show_feature_lock',
|
||||
'get_feature_availability_text',
|
||||
'get_version_info_details'
|
||||
]
|
||||
|
||||
missing_ui_functions = []
|
||||
for func in ui_functions:
|
||||
if func not in constants_content:
|
||||
missing_ui_functions.append(func)
|
||||
|
||||
if missing_ui_functions:
|
||||
result.add_error(f"Missing UI helper functions in constants.py: {missing_ui_functions}")
|
||||
else:
|
||||
result.add_info("All UI helper functions present in constants.py")
|
||||
|
||||
except Exception as e:
|
||||
result.add_error(f"Error validating version differences: {e}")
|
||||
|
||||
return result
|
||||
|
||||
def validate_feature_flags(zip_path: Path, config: Dict) -> ValidationResult:
|
||||
"""Validate the feature flags system."""
|
||||
result = ValidationResult()
|
||||
@@ -278,6 +364,14 @@ def validate_package(zip_path: Path, version_type: Optional[str] = None) -> bool
|
||||
features_result.print_results()
|
||||
overall_valid &= features_result.is_valid
|
||||
|
||||
print("\n" + "─" * 60)
|
||||
|
||||
# Version differences validation
|
||||
print("Validating version-specific content and exclusions...")
|
||||
version_diff_result = validate_version_differences(zip_path, config, version_type)
|
||||
version_diff_result.print_results()
|
||||
overall_valid &= version_diff_result.is_valid
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print(f"Overall Validation: {'✅ PASS' if overall_valid else '❌ FAIL'}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user