You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

961 lines
35 KiB

"""
Django settings for backend project.
Generated by 'django-admin startproject' using Django 5.0.4.
For more information on this file, see
https://docs.djangoproject.com/en/5.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.0/ref/settings/
"""
import os
from pathlib import Path
from django.templatetags.static import static
from django.urls import reverse_lazy
import environ
from django.utils.translation import gettext_lazy as _
env = environ.Env(
# set casting, default value
# DEBUG=(bool, False)
)
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent.parent
environ.Env.read_env(os.path.join(BASE_DIR, '.env'))
ALLOWED_HOSTS = env('DJANGO_ALLOWED_HOSTS').split(',')
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-7=3it+m^28^+0c1*9-*c*6g3ej63sz(97rq1^mp=!6e(mhmysh'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
X_FRAME_OPTIONS = 'SAMEORIGIN'
LOCAL_APPS = [
'apps.account.apps.AccountConfig',
'apps.api.apps.ApiConfig',
'apps.course.apps.CourseConfig',
'apps.chat.apps.ChatConfig',
'apps.quiz.apps.QuizConfig',
'apps.transaction.apps.TransactionConfig',
'apps.certificate.apps.CertificateConfig',
'apps.hadis.apps.HadisConfig',
'apps.library.apps.LibraryConfig',
'apps.video.apps.VideoConfig',
'apps.podcast.apps.PodcastConfig',
'apps.bookmark.apps.BookmarkConfig',
'apps.article.apps.ArticleConfig',
'apps.dobodbi_calendar.apps.DobodbiCalendarConfig',
'apps.blog.apps.BlogConfig',
'dynamic_preferences',
]
THIRD_PARTY_APPS = [
'rest_framework',
'rest_framework.authtoken',
'drf_yasg',
'rosetta',
'easy_thumbnails',
'phonenumber_field',
'dj_language',
'dj_filer',
'ajaxdatatable',
'dj_category',
'corsheaders',
'django_filters',
]
INSTALLED_APPS = [
"unfold",
"unfold.contrib.filters",
"unfold.contrib.import_export",
"unfold.contrib.guardian",
"unfold.contrib.simple_history",
"unfold.contrib.forms",
"unfold.contrib.inlines",
"whitenoise.runserver_nostatic",
# 'limitless_dashboard.apps.DashboardConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize', # Added for humanize template tags
*THIRD_PARTY_APPS,
*LOCAL_APPS,
]
AUTHENTICATION_BACKENDS = [
'django.contrib.auth.backends.ModelBackend', # این خط را نگه دارید تا احراز هویت پیش‌فرض کار کند
'apps.account.custom_user_login.CustomLoginBackend', # مسیر به کلاس سفارشی خود
]
REDIS_URL = env('REDIS_URL')
OTP_SERIVCE_KEY = "33213d78f1234e99b81f94eefda77e45"
PHONENUMBER_DEFAULT_REGION = "IR"
PHONENUMBER_DB_FORMAT = 'INTERNATIONAL'
PHONENUMBER_DEFAULT_FORMAT = 'INTERNATIONAL'
AUTH_USER_MODEL = "account.User"
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
"whitenoise.middleware.WhiteNoiseMiddleware",
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
# "django.contrib.auth.middleware.LoginRequiredMiddleware",
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'config.language_code_middleware.language_middleware',
'config.enhanced_auth_middleware.enhanced_auth_middleware',
'apps.account.middleware.admin_access.AdminAccessMiddleware',
]
ROOT_URLCONF = 'config.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
BASE_DIR / 'templates',
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'django.template.context_processors.i18n',
"utils.admin.variables",
],
},
},
]
WSGI_APPLICATION = 'config.wsgi.application'
# django google recaptcha default keys
RECAPTCHA_PUBLIC_KEY = env('captcha_public_key')
RECAPTCHA_PRIVATE_KEY = env('captcha_private_key')
APPS_REORDER = {
'auth': {
'icon': 'icon-shield-check',
'name': 'Authentication'
},
'account': {
# 'icon': 'icon-',
'name': 'account'
}
}
# Database
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': env('POSTGRES_DB'),
'USER': env('POSTGRES_USER'),
'PASSWORD': env('POSTGRES_PASSWORD'),
'HOST': env('POSTGRES_HOST'),
'PORT': env('POSTGRES_PORT'),
'ATOMIC_REQUESTS': True,
},
}
CORS_ALLOW_ALL_ORIGINS = True
THUMBNAIL_ALIASES = {
'': {
'icon': {'size': (50, 50), 'crop': True},
'large': {'size': (1200, 620), 'crop': False},
'medium': {'size': (545, 545), 'crop': False},
'small': {'size': (150, 150), 'crop': False},
},
}
LANGUAGES = [
('en', _('English')),
('fa', _('Persian')),
('ru', _('Russia')),
]
LOCALE_PATHS = [
os.path.join(BASE_DIR, 'locale'),
]
CELERY_BROKER_URL = env("REDIS_URL")
CELERY_RESULT_BACKEND = env("REDIS_URL")
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_TIMEZONE = 'Asia/Tehran'
CELERY_BROKER_TRANSPORT = 'redis'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_BROKER_CONNECTION_RETRY_ON_STARTUP = True
# Password validation
# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
'OPTIONS': {
'min_length': 6,
}
},
]
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 16,
# 'DEFAULT_AUTHENTICATION_CLASSES': [
# 'apps.account.auth_back.TokenAuthentication2',
# ],
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
# 'rest_framework.authentication.SessionAuthentication',
],
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
'EXCEPTION_HANDLER': 'utils.exceptions.exception_handler',
}
# Internationalization
# https://docs.djangoproject.com/en/5.0/topics/i18n/
LANGUAGE_CODE = 'en'
TIME_ZONE = 'Asia/Tehran'
USE_I18N = True
USE_L10N = True
USE_TZ = False
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
# *********************************************************
STATIC_ROOT = BASE_DIR/'staticfiles'
MEDIA_ROOT = BASE_DIR/'media'
# os.path.join(BASE_DIR, 'static', 'media')
# FILER_ADMIN_ICON_SIZES = ('32', '48')
FILER_ENABLE_LOGGING = True
FILER_DEBUG = True
ADMIN_TITLE = 'Imam Javad App'
ADMIN_INDEX_TITLE = 'Imam Javad Administration'
SITE_DOMAIN = "https://imamjavad.nwhco.ir"
ONLINE_CLASS_FRONTEND_DOMAIN = env('ONLINE_CLASS_FRONTEND_DOMAIN', default=SITE_DOMAIN)
ONLINE_CLASS_TOKEN_TTL = env.int('ONLINE_CLASS_TOKEN_TTL', default=3000)
PLUGNMEET_SERVER_URL = env('PLUGNMEET_SERVER_URL', default='https://meet.newhorizonco.uk')
PLUGNMEET_API_KEY = env('PLUGNMEET_API_KEY', default='habibmeet_api_key_2024')
PLUGNMEET_API_SECRET = env('PLUGNMEET_API_SECRET', default='habibmeet_secret_zumyyYWqv7KR2kUqvYdq4z4sXg7XTBD2ljT6_2024')
PLUGNMEET_TIMEOUT = env.float('PLUGNMEET_TIMEOUT', default=10.0)
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.0/howto/static-files/
# Default primary key field type
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
FILE_UPLOAD_HANDLERS = [
'django.core.files.uploadhandler.TemporaryFileUploadHandler',
]
######################################################################
# Sessions
######################################################################
SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"
LOGIN_URL = "admin:login"
LOGIN_REDIRECT_URL = reverse_lazy("admin:index")
# STORAGES = {
# "default": {
# "BACKEND": "django.core.files.storage.FileSystemStorage",
# },
# "staticfiles": {
# "BACKEND": "whitenoise.storage.CompressedStaticFilesStorage",
# },
# }
######################################################################
# Unfold
######################################################################
UNFOLD = {
"SITE_TITLE": _("Imam Jawad Admin"),
"SITE_HEADER": _("Imam Jawad Admin"),
"SITE_SUBHEADER": _("Imam Jawad Online School"),
"SITE_DROPDOWN": [
{
"icon": "diamond",
"title": _("Imam Javad Site"),
"link": "https://habibapp.com",
},
],
"SITE_SYMBOL": "settings",
"SHOW_HISTORY": True,
"SHOW_LANGUAGES": True,
"ENVIRONMENT": "utils.environment_callback",
"DASHBOARD_CALLBACK": "utils.admin.dashboard_callback",
"SITE_ICON": {
"light": lambda request: static("images/logo1.svg"), # light mode
"dark": lambda request: static("images/logo1.svg"), # dark mode
},
"SITE_SYMBOL": "speed",
"SHOW_BACK_BUTTON": True, # show/hide "Back" button on changeform in header, default: False
"THEME": "dark",
"LOGIN": {
"image": lambda request: static("images/image1.jpg"),
},
"COLORS": {
"base": {
"50": "249 250 251",
"100": "243 244 246",
"200": "229 231 235",
"300": "209 213 219",
"400": "156 163 175",
"500": "107 114 128",
"600": "75 85 99",
"700": "55 65 81",
"800": "31 41 55",
"900": "17 24 39",
"950": "3 7 18",
},
"primary": {
"50": "234 253 243",
"100": "208 251 232",
"200": "167 247 216",
"300": "110 240 189",
"400": "37 213 152",
"500": "37 208 118", # #25D076 - رنگ دکمه اصلی
"600": "29 166 94",
"700": "25 136 80",
"800": "22 108 66",
"900": "20 89 57",
"950": "10 53 34",
},
"secondary": {
"50": "240 253 250",
"100": "204 251 241",
"200": "153 246 228",
"300": "94 234 212",
"400": "45 212 191",
"500": "1 53 59", # #01353B - رنگ پس‌زمینه
"600": "1 43 48",
"700": "1 36 40",
"800": "1 30 34",
"900": "0 26 29",
"950": "0 13 15",
},
"font": {
"subtle-light": "var(--color-base-500)",
"subtle-dark": "var(--color-base-400)",
"default-light": "var(--color-secondary-500)", # استفاده از رنگ ثانویه برای متن
"default-dark": "var(--color-base-300)",
"important-light": "var(--color-base-900)",
"important-dark": "255 255 255", # #FFFFFF - برای متن سفید در دکمه‌ها
},
},
"STYLES": [
# lambda request: static("css/styles.css"),
],
"SCRIPTS": [
# lambda request: static("js/chart.min.js"),
],
"TABS": [
{
"page": "video",
"models": ["video.videocollection", "video.pinnedvideocollection", 'video.middlevideocollection',],
"items": [
{
"title": _("Collections"),
"icon": "collections_bookmark",
"link": reverse_lazy("admin:video_pinnedvideocollection_changelist"),
"active": lambda request: "video/pinnedvideocollection" in request.path and "library/middlevideocollection" not in request.path,
},
{
"title": _("Middle Collections"),
"icon": "view_module",
"link": reverse_lazy("admin:video_middlevideocollection_changelist"),
"active": lambda request: "video/middlevideocollection" in request.path,
},
],
},
{
"page": "library",
"models": ["library.bookcollection", "library.pinnedbookcollection", 'library.middlebookcollection'],
"items": [
{
"title": _("Collections"),
"icon": "collections_bookmark",
"link": reverse_lazy("admin:library_pinnedbookcollection_changelist"),
"active": lambda request: "library/pinnedbookcollection" in request.path and "library/middlebookcollection" not in request.path,
},
{
"title": _("Middle Collections"),
"icon": "view_module",
"link": reverse_lazy("admin:library_middlebookcollection_changelist"),
"active": lambda request: "library/middlebookcollection" in request.path,
},
],
},
{
"page": "article",
"models": ["article.articlecollection", "article.pinnedarticlecollection", "article.middlearticlecollection"],
"items": [
{
"title": _("Pinned Collections"),
"icon": "collections_bookmark",
"link": reverse_lazy("admin:article_pinnedarticlecollection_changelist"),
"active": lambda request: "article/pinnedarticlecollection" in request.path and "article/middlearticlecollection" not in request.path,
},
{
"title": _("Regular Collections"),
"icon": "view_module",
"link": reverse_lazy("admin:article_middlearticlecollection_changelist"),
"active": lambda request: "article/middlearticlecollection" in request.path,
},
],
},
{
"page": "accounts",
"models": ["account.user", 'auth.group'],
"items": [
{
"title": _("Users"),
"icon": "sports_motorsports",
"link": reverse_lazy("admin:account_user_changelist"),
"active": lambda request: request.path
== reverse_lazy("admin:account_user_changelist")
and "email__isnull" not in request.GET,
},
{
"title": _("Guest Users"),
"icon": "sports_motorsports",
"link": lambda request: f"{reverse_lazy('admin:account_user_changelist')}?email__isnull=true",
},
],
},
{
"page": "authentication",
"models": ["auth.group", "auth.permission"],
"permission": lambda request: request.user.is_staff,
"items": [
{
"title": _("Groups"),
"icon": "shield",
"link": reverse_lazy("admin:auth_group_changelist"),
},
],
},
{
"page": "courses",
"models": [
"course.course",
"course.courselesson",
"course.courseglossary",
"course.courseattachment",
],
"items": [
{
"title": _("Courses"),
"icon": "school",
"link": reverse_lazy("admin:course_course_changelist"),
"active": lambda request: request.path.startswith(str(reverse_lazy("admin:course_course_changelist"))),
},
{
"title": _("Course Lessons"),
"icon": "menu_book",
"link": reverse_lazy("admin:course_courselesson_changelist"),
"active": lambda request: request.path.startswith(str(reverse_lazy("admin:course_courselesson_changelist"))),
},
{
"title": _("Course Attachments"),
"icon": "attach_file",
"link": reverse_lazy("admin:course_courseattachment_changelist"),
"active": lambda request: request.path.startswith(str(reverse_lazy("admin:course_courseattachment_changelist"))),
},
{
"title": _("Course Glossary"),
"icon": "book",
"link": reverse_lazy("admin:course_courseglossary_changelist"),
"active": lambda request: request.path.startswith(str(reverse_lazy("admin:course_courseglossary_changelist"))),
},
],
},
{
"page": "course_online",
"models": [
"course.courselivesession",
"course.livesessionuser",
"course.livesessionrecording",
],
"items": [
{
"title": _("Course Onlines"),
"icon": "video_call",
"link": reverse_lazy("admin:course_courselivesession_changelist"),
"active": lambda request: request.path.startswith(str(reverse_lazy("admin:course_courselivesession_changelist"))),
},
{
"title": _("Session Users"),
"icon": "groups",
"link": reverse_lazy("admin:course_livesessionuser_changelist"),
"active": lambda request: request.path.startswith(str(reverse_lazy("admin:course_livesessionuser_changelist"))),
},
{
"title": _("Session Recordings"),
"icon": "play_circle",
"link": reverse_lazy("admin:course_livesessionrecording_changelist"),
"active": lambda request: request.path.startswith(str(reverse_lazy("admin:course_livesessionrecording_changelist"))),
},
],
},
{
"page": "podcast",
"models": ["podcast.podcastcollection", "podcast.pinnedpodcastcollection", "podcast.middlepodcastcollection"],
"items": [
{
"title": _("Pinned Collections"),
"icon": "collections_bookmark",
"link": reverse_lazy("admin:podcast_pinnedpodcastcollection_changelist"),
"active": lambda request: "podcast/pinnedpodcastcollection" in request.path and "podcast/middlepodcastcollection" not in request.path,
},
{
"title": _("Regular Collections"),
"icon": "view_module",
"link": reverse_lazy("admin:podcast_middlepodcastcollection_changelist"),
"active": lambda request: "podcast/middlepodcastcollection" in request.path,
},
],
},
],
"SIDEBAR": {
"show_search": True,
"show_all_applications": True,
"navigation": [
{
"title": _(""),
"separator": True,
"collapsible": True,
"items": [
{
"title": _("Dashboard"),
"icon": "dashboard",
"link": reverse_lazy("admin:index"),
},
],
},
{
"title": _(""),
"items": [
{
"title": _("Authentication"),
"icon": "shield",
"link": reverse_lazy("admin:auth_group_changelist"),
"permission": lambda request: request.user.is_staff,
},
],
},
{
"title": _(""),
"items": [
{
"title": _("Users"),
"icon": "person",
"link": reverse_lazy("admin:account_user_changelist"),
"permission": lambda request: request.user.is_staff,
},
],
},
{
"title": _(""),
"items": [
{
"title": _("Students"),
"icon": "school",
"link": reverse_lazy("admin:account_studentuser_changelist"),
"permission": lambda request: request.user.is_staff,
},
]
},
{
"title": _(""),
"items": [
{
"title": _("Professors"),
"icon": "person_book",
"link": reverse_lazy("admin:account_professoruser_changelist"),
"permission": lambda request: request.user.is_staff,
},
]
},
{
"title": _(""),
"items": [
{
"title": _("Calender"),
"icon": "calendar_today",
"link": reverse_lazy("admin:dobodbi_calendar_calendaroccasions_changelist"),
"permission": lambda request: request.user.is_staff,
},
],
},
{
"title": _("Courses"),
"collapsible": True,
"separator": True,
"items": [
{
"title": _("Categories"),
"icon": "category",
"link": reverse_lazy("admin:course_coursecategory_changelist"),
},
{
"title": _("Courses"),
"icon": "school",
"link": reverse_lazy("admin:course_course_changelist"),
},
{
"title": _("Lessons"),
"icon": "menu_book",
"link": reverse_lazy("admin:course_lesson_changelist"),
},
{
"title": _("Attachments"),
"icon": "attach_file",
"link": reverse_lazy("admin:course_attachment_changelist"),
},
{
"title": _("Glossary"),
"icon": "book",
"link": reverse_lazy("admin:course_glossary_changelist"),
},
{
"title": _("Live Sessions"),
"icon": "video_call",
"link": reverse_lazy("admin:course_courselivesession_changelist"),
},
{
"title": _("Session Users"),
"icon": "groups",
"link": reverse_lazy("admin:course_livesessionuser_changelist"),
},
{
"title": _("Session Recordings"),
"icon": "play_circle",
"link": reverse_lazy("admin:course_livesessionrecording_changelist"),
},
{
"title": _("Certificates"),
"icon": "workspace_premium",
"link": reverse_lazy("admin:certificate_certificate_changelist"),
},
]
},
{
"title": _("Quizzes"),
"collapsible": True,
"separator": True,
"items": [
{
"title": _("Quizzes"),
"icon": "quiz",
"link": reverse_lazy("admin:quiz_quiz_changelist"),
},
{
"title": _("Quiz Participants"),
"icon": "group",
"link": reverse_lazy("admin:quiz_quizparticipant_changelist"),
},
]
},
{
"title": _("Transactions"),
"collapsible": True,
"separator": True,
"items": [
{
"title": _("Transactions"),
"icon": "payments",
"link": reverse_lazy("admin:transaction_transactionparticipant_changelist"),
},
]
},
{
"title": _("Libraries"),
"collapsible": True,
"separator": True,
"items": [
{
"title": _("Books"),
"icon": "menu_book",
"link": reverse_lazy("admin:library_book_changelist"),
},
{
"title": _("Categories"),
"icon": "category",
"link": reverse_lazy("admin:library_category_changelist"),
},
{
"title": _("Collections"),
"icon": "view_module",
"link": reverse_lazy("admin:library_pinnedbookcollection_changelist"),
},
]
},
{
"title": _("Videos"),
"collapsible": True,
"separator": True,
"items": [
{
"title": _("Videos"),
"icon": "live_tv",
"link": reverse_lazy("admin:video_video_changelist"),
},
{
"title": _("Categories"),
"icon": "category",
"link": reverse_lazy("admin:video_videocategory_changelist"),
},
{
"title": _("Collections"),
"icon": "view_module",
"link": reverse_lazy("admin:video_pinnedvideocollection_changelist"),
},
{
"title": _("Playlists"),
"icon": "playlist_play",
"link": reverse_lazy("admin:video_videoplaylist_changelist"),
# "active": lambda request: "video/videoplaylist" in request.path,
},
]
},
{
"title": _("Blog"),
"collapsible": True,
"separator": True,
"items": [
{
"title": _("Comments"),
"icon": "comment",
"link": reverse_lazy("admin:api_comment_changelist"),
},
{
"title": _("Blogs"),
"icon": "article",
"link": reverse_lazy("admin:blog_blog_changelist"),
},
]
},
{
"title": _(""),
"items": [
{
"title": _("App Versions"),
"icon": "system_update",
"link": reverse_lazy("admin:api_appversion_changelist"),
},
],
},
{
"title": _("Articles"),
"collapsible": True,
"separator": True,
"items": [
{
"title": _("Articles"),
"icon": "article",
"link": reverse_lazy("admin:article_article_changelist"),
},
{
"title": _("Categories"),
"icon": "category",
"link": reverse_lazy("admin:article_articlecategory_changelist"),
},
{
"title": _("Pinned Collections"),
"icon": "collections_bookmark",
"link": reverse_lazy("admin:article_pinnedarticlecollection_changelist"),
},
{
"title": _("Regular Collections"),
"icon": "view_module",
"link": reverse_lazy("admin:article_middlearticlecollection_changelist"),
},
{
"title": _("Article Contents"),
"icon": "text_snippet",
"link": reverse_lazy("admin:article_articlecontent_changelist"),
},
]
},
{
"title": _("Podcasts"),
"collapsible": True,
"separator": True,
"items": [
{
"title": _("Podcasts"),
"icon": "headset",
"link": reverse_lazy("admin:podcast_podcast_changelist"),
},
{
"title": _("Categories"),
"icon": "category",
"link": reverse_lazy("admin:podcast_podcastcategory_changelist"),
},
{
"title": _("Pinned Collections"),
"icon": "collections_bookmark",
"link": reverse_lazy("admin:podcast_pinnedpodcastcollection_changelist"),
},
{
"title": _("Regular Collections"),
"icon": "view_module",
"link": reverse_lazy("admin:podcast_middlepodcastcollection_changelist"),
},
{
"title": _("Playlists"),
"icon": "playlist_play",
"link": reverse_lazy("admin:podcast_podcastplaylist_changelist"),
},
{
"title": _("User Playlists"),
"icon": "person_add",
"link": reverse_lazy("admin:podcast_userplaylist_changelist"),
},
]
},
{
"title": _("Chats"),
"collapsible": True,
"separator": True,
"items": [
{
"title": _("Chat Rooms"),
"icon": "forum",
"link": reverse_lazy("admin:chat_roommessage_changelist"),
},
# {
# "title": _("Chat Messages"),
# "icon": "chat",
# "link": reverse_lazy("admin:apps_chat_chatmessage_changelist"),
# },
# {
# "title": _("Read Status"),
# "icon": "mark_chat_read",
# "link": reverse_lazy("admin:apps_chat_messagereadstatus_changelist"),
# },
]
},
{
"title": _("Hadis"),
"collapsible": True,
"separator": True,
"items": [
{
"title": _("Hadis Sects"),
"icon": "account_tree",
"link": reverse_lazy("admin:hadis_hadissect_changelist"),
},
{
"title": _("Hadis Categories"),
"icon": "category",
"link": reverse_lazy("admin:hadis_hadiscategory_changelist"),
},
{
"title": _("Hadis"),
"icon": "format_quote",
"link": reverse_lazy("admin:hadis_hadis_changelist"),
},
{
"title": _("Hadis References"),
"icon": "link",
"link": reverse_lazy("admin:hadis_hadisreference_changelist"),
},
{
"title": _("Hadis Tags"),
"icon": "label",
"link": reverse_lazy("admin:hadis_hadistag_changelist"),
},
{
"title": _("Hadis Status"),
"icon": "flag",
"link": reverse_lazy("admin:hadis_hadisstatus_changelist"),
},
{
"title": _("Transmitters"),
"icon": "person",
"link": reverse_lazy("admin:hadis_transmitters_changelist"),
},
{
"title": _("Hadis Transmitters"),
"icon": "group",
"link": reverse_lazy("admin:hadis_hadistransmitter_changelist"),
},
]
},
{
"title": "",
"items": [
{
"title": _("Global Preferences"),
"icon": "settings",
"link": reverse_lazy("admin:dynamic_preferences_globalpreferencemodel_changelist"),
},
# You can add more preference sections here
],
},
# "STYLES": [
# lambda request: static("css/styles.css"),
# ],
# "SCRIPTS": [
# lambda request: static("js/scripts.js"),
# ],
],
},
}
UNFOLD_STUDIO_DEFAULT_FRAGMENT = "color-schemes"
UNFOLD_STUDIO_PERMISSION = lambda request: request.user.is_authenticated
PLAUSIBLE_DOMAIN = env("PLAUSIBLE_DOMAIN")