132 lines
4.5 KiB
Python
132 lines
4.5 KiB
Python
from django.db import models
|
|
from django.core.exceptions import ValidationError
|
|
from django_softdelete.models import SoftDeleteModel
|
|
from PIL import Image
|
|
|
|
def validate_image_size(image):
|
|
if image.size > 1 * 1024 * 1024:
|
|
raise ValidationError("File size exceeds 1MB.")
|
|
|
|
def validate_image_ext(image):
|
|
allowed_extensions = ['png', 'jpg', 'jpeg']
|
|
ext = image.name.split('.')[-1].lower()
|
|
if ext not in allowed_extensions:
|
|
raise ValidationError("Invalid file type. Only PNG or JPEG allowed.")
|
|
|
|
def validate_image(image):
|
|
try:
|
|
img = Image.open(image)
|
|
img.verify()
|
|
except Exception:
|
|
raise ValidationError("Invalid image file.")
|
|
|
|
def validate_file_size(image):
|
|
if image.size > 10 * 1024 * 1024:
|
|
raise ValidationError("File size exceeds 10MB.")
|
|
|
|
class Content(SoftDeleteModel):
|
|
|
|
CONTENT_THEME_CHOICES = [
|
|
('furikake', 'Furikake'),
|
|
('gizi', 'Gizi'),
|
|
('kesehatan', 'Kesehatan'),
|
|
('pendidikan', 'Pendidikan'),
|
|
('keselamatan', 'Keselamatan'),
|
|
]
|
|
|
|
CONTENT_TOPIC_CHOICES = {
|
|
'furikake': [
|
|
('sejarah-furikake', 'Sejarah Furikake'),
|
|
('kandungan-furikake', 'Kandungan Furikake'),
|
|
('pembuatan-furikake', 'Pembuatan Furikake'),
|
|
('menikmati-furikake', 'Menikmati Furikake')
|
|
],
|
|
'gizi': [
|
|
('gizi-seimbang', 'Gizi Seimbang'),
|
|
('kecukupan-gizi', 'Kecukupan Gizi'),
|
|
('kualitas-pangan', 'Kualitas Bahan Pangan'),
|
|
('budaya-tradisi-pangan', 'Budaya dan Tradisi Pangan'),
|
|
('ketersediaan-aksesibilitas-pangan', 'Ketersediaan dan Aksesibilitas Gizi dan Pangan')
|
|
],
|
|
'kesehatan': [
|
|
('olahraga', 'Olahraga'),
|
|
('waktu-tidur', 'Waktu Tidur'),
|
|
('kesehatan-mental', 'Kesehatan Mental'),
|
|
('pendidikan-seksua', 'Pendidikan Seksual'),
|
|
('rokok-alkohol-narkoba', 'Bahaya Merokok dan Alkohol serta Pencegahan Narkoba'),
|
|
('sistem-imun', 'Sistem Imun')
|
|
],
|
|
'pendidikan': [
|
|
('berpikir-kreatif', 'Berpikir Kreatif'),
|
|
('berpikir-kritis', 'Berpikir Kritis'),
|
|
('pentingnya-membaca', 'Pentingnya Membaca'),
|
|
('literasi-digital', 'Literasi Digital'),
|
|
('kesadaran-lingkungan', 'Kesadaran Lingkungan'),
|
|
('pancasila', 'Pancasila'),
|
|
('biologi', 'Biologi'),
|
|
('aritmatika', 'Aritmatika'),
|
|
('bahasa-indonesia', 'Bahasa Indonesia'),
|
|
],
|
|
'keselamatan': [
|
|
('lalu-lintas', 'Keselamatan Berlalu Lintas'),
|
|
('pertolongan-pertama', 'Pertolongan Petrtama'),
|
|
('bencana', 'Kesiapsiagaan Bencana')
|
|
]
|
|
}
|
|
|
|
CONTENT_FORMAT_CHOICES = [
|
|
('teks','Teks'),
|
|
('infografis', 'Infografis'),
|
|
('gambar', 'Gambar'),
|
|
('video', 'Video'),
|
|
('branching-scenario', 'Pilihan Bercabang'),
|
|
('tts', 'Teka-teki Silang'),
|
|
('pencocokan', 'Pencocokan'),
|
|
('cari-kata', 'Cari Kata'),
|
|
('memory-game', 'Permainan Memori'),
|
|
('personality-quiz', 'Permainan Tebak Sifat'),
|
|
('game-map', 'Peta Permainan'),
|
|
('pilihan-ganda', 'Pilihan Ganda'),
|
|
]
|
|
|
|
title = models.CharField(max_length=255, null=False)
|
|
slug = models.SlugField(max_length=255)
|
|
|
|
featured_image = models.ImageField(
|
|
max_length=255,
|
|
upload_to="uploads/contents/",
|
|
validators=[validate_image_size, validate_image_ext, validate_image],
|
|
null=False, blank=False)
|
|
|
|
theme = models.CharField(max_length=25, choices=CONTENT_THEME_CHOICES)
|
|
topic = models.CharField(max_length=25)
|
|
format = models.CharField(max_length=25, choices=CONTENT_FORMAT_CHOICES)
|
|
|
|
description = models.CharField(max_length=255, null=True, blank=True)
|
|
content = models.TextField(null=True)
|
|
data = models.JSONField(null=True)
|
|
|
|
grades = models.JSONField(null=True)
|
|
|
|
point = models.IntegerField()
|
|
coin = models.IntegerField()
|
|
|
|
color = models.CharField(max_length=7, null=True, blank=True)
|
|
|
|
created_at = models.DateTimeField(auto_now_add=True)
|
|
updated_at = models.DateTimeField(auto_now=True)
|
|
|
|
def __str__(self):
|
|
return self.title
|
|
|
|
class Media(SoftDeleteModel):
|
|
|
|
name = models.CharField(max_length=255, null=False)
|
|
media = models.FileField(
|
|
max_length=255,
|
|
upload_to="uploads/medias/",
|
|
validators=[validate_file_size],
|
|
null=False, blank=False)
|
|
|
|
def __str__(self):
|
|
return self.name |