239 lines
7.4 KiB
Python
239 lines
7.4 KiB
Python
"""
|
|
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
|