plugin distribution system
This commit is contained in:
238
backend/igny8_core/plugins/serializers.py
Normal file
238
backend/igny8_core/plugins/serializers.py
Normal file
@@ -0,0 +1,238 @@
|
||||
"""
|
||||
Plugin Distribution System Serializers
|
||||
"""
|
||||
from rest_framework import serializers
|
||||
from .models import Plugin, PluginVersion, PluginInstallation, PluginDownload
|
||||
|
||||
|
||||
class PluginVersionSerializer(serializers.ModelSerializer):
|
||||
"""Serializer for plugin versions."""
|
||||
|
||||
download_count = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = PluginVersion
|
||||
fields = [
|
||||
'id',
|
||||
'version',
|
||||
'version_code',
|
||||
'status',
|
||||
'file_size',
|
||||
'checksum',
|
||||
'changelog',
|
||||
'min_api_version',
|
||||
'min_platform_version',
|
||||
'min_php_version',
|
||||
'force_update',
|
||||
'released_at',
|
||||
'created_at',
|
||||
'download_count',
|
||||
]
|
||||
read_only_fields = ['id', 'version_code', 'created_at', 'download_count']
|
||||
|
||||
def get_download_count(self, obj):
|
||||
return obj.get_download_count()
|
||||
|
||||
|
||||
class PluginSerializer(serializers.ModelSerializer):
|
||||
"""Serializer for plugins."""
|
||||
|
||||
latest_version = serializers.SerializerMethodField()
|
||||
download_count = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Plugin
|
||||
fields = [
|
||||
'id',
|
||||
'name',
|
||||
'slug',
|
||||
'platform',
|
||||
'description',
|
||||
'homepage_url',
|
||||
'is_active',
|
||||
'latest_version',
|
||||
'download_count',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
]
|
||||
read_only_fields = ['id', 'created_at', 'updated_at']
|
||||
|
||||
def get_latest_version(self, obj):
|
||||
latest = obj.get_latest_version()
|
||||
if latest:
|
||||
return {
|
||||
'version': latest.version,
|
||||
'version_code': latest.version_code,
|
||||
'released_at': latest.released_at,
|
||||
'changelog': latest.changelog,
|
||||
}
|
||||
return None
|
||||
|
||||
def get_download_count(self, obj):
|
||||
return obj.get_download_count()
|
||||
|
||||
|
||||
class PluginDetailSerializer(PluginSerializer):
|
||||
"""Detailed serializer for plugins including versions."""
|
||||
|
||||
versions = PluginVersionSerializer(many=True, read_only=True)
|
||||
|
||||
class Meta(PluginSerializer.Meta):
|
||||
fields = PluginSerializer.Meta.fields + ['versions']
|
||||
|
||||
|
||||
class PluginInfoSerializer(serializers.Serializer):
|
||||
"""
|
||||
Serializer for WordPress plugin info endpoint.
|
||||
Returns data in WordPress-compatible format.
|
||||
"""
|
||||
name = serializers.CharField()
|
||||
slug = serializers.CharField()
|
||||
version = serializers.CharField()
|
||||
author = serializers.CharField(default='IGNY8')
|
||||
homepage = serializers.URLField()
|
||||
description = serializers.CharField()
|
||||
changelog = serializers.CharField()
|
||||
download_url = serializers.URLField()
|
||||
file_size = serializers.IntegerField()
|
||||
requires_php = serializers.CharField()
|
||||
tested_wp = serializers.CharField(default='6.7')
|
||||
|
||||
|
||||
class CheckUpdateSerializer(serializers.Serializer):
|
||||
"""Serializer for update check response."""
|
||||
update_available = serializers.BooleanField()
|
||||
current_version = serializers.CharField()
|
||||
latest_version = serializers.CharField(allow_null=True)
|
||||
latest_version_code = serializers.IntegerField(allow_null=True)
|
||||
download_url = serializers.URLField(allow_null=True)
|
||||
changelog = serializers.CharField(allow_null=True)
|
||||
info_url = serializers.URLField(allow_null=True)
|
||||
force_update = serializers.BooleanField(default=False)
|
||||
checksum = serializers.CharField(allow_null=True)
|
||||
|
||||
|
||||
class RegisterInstallationSerializer(serializers.Serializer):
|
||||
"""Serializer for registering plugin installations."""
|
||||
site_id = serializers.IntegerField()
|
||||
version = serializers.CharField()
|
||||
|
||||
def validate_site_id(self, value):
|
||||
from igny8_core.auth.models import Site
|
||||
try:
|
||||
Site.objects.get(id=value)
|
||||
except Site.DoesNotExist:
|
||||
raise serializers.ValidationError("Site not found")
|
||||
return value
|
||||
|
||||
|
||||
class HealthCheckSerializer(serializers.Serializer):
|
||||
"""Serializer for plugin health check."""
|
||||
site_id = serializers.IntegerField()
|
||||
version = serializers.CharField()
|
||||
status = serializers.ChoiceField(choices=['active', 'inactive', 'error'])
|
||||
error_message = serializers.CharField(required=False, allow_blank=True)
|
||||
|
||||
|
||||
class PluginInstallationSerializer(serializers.ModelSerializer):
|
||||
"""Serializer for plugin installations."""
|
||||
|
||||
plugin_name = serializers.CharField(source='plugin.name', read_only=True)
|
||||
plugin_slug = serializers.CharField(source='plugin.slug', read_only=True)
|
||||
current_version_str = serializers.CharField(source='current_version.version', read_only=True)
|
||||
site_name = serializers.CharField(source='site.name', read_only=True)
|
||||
pending_update_version = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = PluginInstallation
|
||||
fields = [
|
||||
'id',
|
||||
'site',
|
||||
'site_name',
|
||||
'plugin',
|
||||
'plugin_name',
|
||||
'plugin_slug',
|
||||
'current_version',
|
||||
'current_version_str',
|
||||
'is_active',
|
||||
'last_health_check',
|
||||
'health_status',
|
||||
'pending_update',
|
||||
'pending_update_version',
|
||||
'update_notified_at',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
]
|
||||
read_only_fields = ['id', 'created_at', 'updated_at']
|
||||
|
||||
def get_pending_update_version(self, obj):
|
||||
if obj.pending_update:
|
||||
return obj.pending_update.version
|
||||
return None
|
||||
|
||||
|
||||
class PluginDownloadSerializer(serializers.ModelSerializer):
|
||||
"""Serializer for plugin downloads."""
|
||||
|
||||
plugin_name = serializers.CharField(source='plugin.name', read_only=True)
|
||||
version_str = serializers.CharField(source='version.version', read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = PluginDownload
|
||||
fields = [
|
||||
'id',
|
||||
'plugin',
|
||||
'plugin_name',
|
||||
'version',
|
||||
'version_str',
|
||||
'site',
|
||||
'account',
|
||||
'download_type',
|
||||
'created_at',
|
||||
]
|
||||
read_only_fields = ['id', 'created_at']
|
||||
|
||||
|
||||
# Admin Serializers
|
||||
|
||||
class AdminPluginVersionCreateSerializer(serializers.ModelSerializer):
|
||||
"""Serializer for creating new plugin versions (admin)."""
|
||||
|
||||
class Meta:
|
||||
model = PluginVersion
|
||||
fields = [
|
||||
'version',
|
||||
'status',
|
||||
'changelog',
|
||||
'min_api_version',
|
||||
'min_platform_version',
|
||||
'min_php_version',
|
||||
'force_update',
|
||||
]
|
||||
|
||||
def validate_version(self, value):
|
||||
"""Ensure version follows semantic versioning."""
|
||||
import re
|
||||
if not re.match(r'^\d+\.\d+\.\d+$', value):
|
||||
raise serializers.ValidationError(
|
||||
"Version must follow semantic versioning (e.g., 1.0.0)"
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
class AdminPluginVersionUploadSerializer(serializers.Serializer):
|
||||
"""Serializer for uploading plugin ZIP file."""
|
||||
file = serializers.FileField()
|
||||
|
||||
def validate_file(self, value):
|
||||
"""Ensure uploaded file is a ZIP."""
|
||||
if not value.name.endswith('.zip'):
|
||||
raise serializers.ValidationError("File must be a ZIP archive")
|
||||
|
||||
# Check file size (max 50MB)
|
||||
max_size = 50 * 1024 * 1024
|
||||
if value.size > max_size:
|
||||
raise serializers.ValidationError(
|
||||
f"File too large. Maximum size is {max_size / 1024 / 1024}MB"
|
||||
)
|
||||
return value
|
||||
Reference in New Issue
Block a user