gealogiuya
Some checks failed
Deploy Django Application to Server / deploy (push) Failing after 19s
Telegram Notifications / Telegram Gate (push) Failing after 5s

This commit is contained in:
2026-02-27 14:56:23 +05:00
commit 0229a0595c
118 changed files with 33948 additions and 0 deletions

9
core/config/__init__.py Normal file
View File

@@ -0,0 +1,9 @@
from .apps import * # noqa
# from .cache import * # noqa
# from .ckeditor5 import * # noqa
# from .jazzmin import * # noqa
from .jwt import * # noqa
from .rest_framework import * # noqa
from .unfold import * # noqa
from .unfold_navigation import * # noqa

30
core/config/apps.py Normal file
View File

@@ -0,0 +1,30 @@
THIRD_PARTY_APPS = [
# "jazzmin",
"unfold",
"unfold.contrib.filters",
"unfold.contrib.forms",
"unfold.contrib.import_export",
"unfold.contrib.guardian",
"unfold.contrib.simple_history",
"modeltranslation",
"django_ckeditor_5",
"corsheaders",
"rosetta",
"rest_framework",
"drf_spectacular",
"drf_spectacular_sidecar",
]
DEFAULT_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]
PROJECT_APPS = [
"apps.shared.apps.SharedConfig",
"apps.geology.apps.GeologyConfig",
]

17
core/config/cache.py Normal file
View File

@@ -0,0 +1,17 @@
import os
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": os.getenv("REDIS_CACHE_URL"),
"OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient"},
"KEY_PREFIX": "core",
}
}
CACHE_MIDDLEWARE_SECONDS = os.getenv("CACHE_TIMEOUT")
# In your Django settings.py or a dedicated Celery configuration module
CELERY_BROKER_URL = os.getenv("CELERY_BROKER", "redis://redis:6379/0")
CELERY_RESULT_BACKEND = os.getenv("RABBITMQ_RESULT_BACKEND")

140
core/config/ckeditor5.py Normal file
View File

@@ -0,0 +1,140 @@
customColorPalette = [
{"color": "hsl(4, 90%, 58%)", "label": "Red"},
{"color": "hsl(340, 82%, 52%)", "label": "Pink"},
{"color": "hsl(291, 64%, 42%)", "label": "Purple"},
{"color": "hsl(262, 52%, 47%)", "label": "Deep Purple"},
{"color": "hsl(231, 48%, 48%)", "label": "Indigo"},
{"color": "hsl(207, 90%, 54%)", "label": "Blue"},
]
CKEDITOR_5_CONFIGS = {
"default": {
"toolbar": [
"heading",
"|",
"bold",
"italic",
"link",
"bulletedList",
"numberedList",
"blockQuote",
"imageUpload",
],
},
"extends": {
"blockToolbar": [
"paragraph",
"heading1",
"heading2",
"heading3",
"|",
"bulletedList",
"numberedList",
"|",
"blockQuote",
],
"toolbar": [
"heading",
"|",
"outdent",
"indent",
"|",
"bold",
"italic",
"link",
"underline",
"strikethrough",
"code",
"subscript",
"superscript",
"highlight",
"|",
"codeBlock",
"sourceEditing",
"insertImage",
"bulletedList",
"numberedList",
"todoList",
"|",
"blockQuote",
"imageUpload",
"|",
"fontSize",
"fontFamily",
"fontColor",
"fontBackgroundColor",
"mediaEmbed",
"removeFormat",
"insertTable",
],
"image": {
"toolbar": [
"imageTextAlternative",
"|",
"imageStyle:alignLeft",
"imageStyle:alignRight",
"imageStyle:alignCenter",
"imageStyle:side",
"|",
],
"styles": [
"full",
"side",
"alignLeft",
"alignRight",
"alignCenter",
],
},
"table": {
"contentToolbar": [
"tableColumn",
"tableRow",
"mergeTableCells",
"tableProperties",
"tableCellProperties",
],
"tableProperties": {
"borderColors": customColorPalette,
"backgroundColors": customColorPalette,
},
"tableCellProperties": {
"borderColors": customColorPalette,
"backgroundColors": customColorPalette,
},
},
"heading": {
"options": [
{
"model": "paragraph",
"title": "Paragraph",
"class": "ck-heading_paragraph",
},
{
"model": "heading1",
"view": "h1",
"title": "Heading 1",
"class": "ck-heading_heading1",
},
{
"model": "heading2",
"view": "h2",
"title": "Heading 2",
"class": "ck-heading_heading2",
},
{
"model": "heading3",
"view": "h3",
"title": "Heading 3",
"class": "ck-heading_heading3",
},
]
},
},
"list": {
"properties": {
"styles": "true",
"startIndex": "true",
"reversed": "true",
}
},
}

69
core/config/jazzmin.py Normal file
View File

@@ -0,0 +1,69 @@
JAZZMIN_SETTINGS = {
"site_title": "Django Admin",
"site_header": "Django Admin",
"site_brand": "Django Admin",
"welcome_sign": "Django Admin",
"site_title_short": "Django Admin",
"login_logo": "image/logo.png",
"site_icon": "image/logo.png",
"site_logo": "image/logo.png",
"login_logo_dark": "image/logo.png",
"user_avatar": None,
"show_sidebar": True,
"navigation_expanded": True,
"icons": {
"auth": "fas fa-users-cog",
"auth.user": "fas fa-user",
"auth.Group": "fas fa-users",
},
"topmenu_links": [
{"name": "Home", "url": "/", "new_window": False},
],
"copyright": "University Admin",
"default_icon_parents": "fas fa-chevron-circle-right",
"default_icon_children": "fas fa-circle",
"related_modal_active": False,
"custom_js": None,
"custom_css": "css/jazzmin.css",
"use_google_fonts_cdn": True,
"changeform_format": "horizontal_tabs",
"changeform_format_overrides": {
"auth.user": "collapsible",
"auth.group": "vertical_tabs",
},
"site_logo_classes": "img-circle",
"language_chooser": True,
}
JAZZMIN_UI_TWEAKS = {
"navbar_small_text": False,
"footer_small_text": False,
"body_small_text": True,
"brand_small_text": False,
"brand_colour": "navbar-navy",
"accent": "accent-primary",
"navbar": "navbar-navy navbar-dark",
"no_navbar_border": False,
"navbar_fixed": False,
"layout_boxed": False,
"footer_fixed": False,
"sidebar_fixed": True,
"sidebar": "sidebar-dark-navy",
"sidebar_nav_small_text": False,
"sidebar_disable_expand": False,
"sidebar_nav_child_indent": False,
"sidebar_nav_compact_style": True,
"sidebar_nav_legacy_style": False,
"sidebar_nav_flat_style": False,
"theme": "minty",
"dark_mode_theme": None,
"button_classes": {
"primary": "btn-outline-primary",
"secondary": "btn-outline-secondary",
"info": "btn-outline-info",
"warning": "btn-warning",
"danger": "btn-danger",
"success": "btn-success",
},
"actions_sticky_top": False,
}

36
core/config/jwt.py Normal file
View File

@@ -0,0 +1,36 @@
import os
from datetime import timedelta
SIMPLE_JWT = {
"ACCESS_TOKEN_LIFETIME": timedelta(days=1),
"REFRESH_TOKEN_LIFETIME": timedelta(days=7),
"ROTATE_REFRESH_TOKENS": False,
"BLACKLIST_AFTER_ROTATION": False,
"UPDATE_LAST_LOGIN": False,
"ALGORITHM": "HS256",
"SIGNING_KEY": os.getenv("SECRET_KEY"),
"VERIFYING_KEY": "",
"AUDIENCE": None,
"ISSUER": None,
"JSON_ENCODER": None,
"JWK_URL": None,
"LEEWAY": 0,
"AUTH_HEADER_TYPES": ("Bearer",),
"AUTH_HEADER_NAME": "HTTP_AUTHORIZATION",
"USER_ID_FIELD": "id",
"USER_ID_CLAIM": "user_id",
"USER_AUTHENTICATION_RULE": "rest_framework_simplejwt.authentication.default_user_authentication_rule",
"AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",),
"TOKEN_TYPE_CLAIM": "token_type",
"TOKEN_USER_CLASS": "rest_framework_simplejwt.models.TokenUser",
"JTI_CLAIM": "jti",
"SLIDING_TOKEN_REFRESH_EXP_CLAIM": "refresh_exp",
"SLIDING_TOKEN_LIFETIME": timedelta(minutes=60),
"SLIDING_TOKEN_REFRESH_LIFETIME": timedelta(days=1),
"TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainPairSerializer",
"TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSerializer",
"TOKEN_VERIFY_SERIALIZER": "rest_framework_simplejwt.serializers.TokenVerifySerializer",
"TOKEN_BLACKLIST_SERIALIZER": "rest_framework_simplejwt.serializers.TokenBlacklistSerializer",
"SLIDING_TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainSlidingSerializer",
"SLIDING_TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSlidingSerializer",
}

View File

@@ -0,0 +1,20 @@
REST_FRAMEWORK = {
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework_simplejwt.authentication.JWTAuthentication",
),
"DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",),
"DEFAULT_THROTTLE_RATE": {
"anon": "1000/day",
"user": "1000/day",
"user_create": "1000/day",
},
}
SPECTACULAR_SETTINGS = {
"SWAGGER_UI_DIST": "SIDECAR",
"SWAGGER_UI_FAVICON_HREF": "SIDECAR",
"REDOC_DIST": "SIDECAR",
"TITLE": "Django Rest API",
"DESCRIPTION": "Django Rest API",
}

29
core/config/swagger.py Normal file
View File

@@ -0,0 +1,29 @@
from django.contrib.auth.decorators import login_required
from django.urls import path
from drf_spectacular.views import (
SpectacularAPIView,
SpectacularRedocView,
SpectacularSwaggerView,
)
urlpatterns = [
path(
"schema/",
login_required(SpectacularAPIView.as_view(), login_url="/admin/"),
name="schema",
),
path(
"api/schema/swagger-ui/",
login_required(
SpectacularSwaggerView.as_view(url_name="schema"), login_url="/admin/"
),
name="swagger-ui",
),
path(
"api/schema/redoc/",
login_required(
SpectacularRedocView.as_view(url_name="schema"), login_url="/admin/"
),
name="redoc",
),
]

107
core/config/unfold.py Normal file
View File

@@ -0,0 +1,107 @@
from django.templatetags.static import static
from django.utils.translation import gettext_lazy as _
from django.urls import reverse_lazy
from . import unfold_navigation as navigation
UNFOLD = {
"SITE_TITLE": "Django Default",
"SITE_HEADER": "Django Default",
"SITE_URL": "/",
"SITE_ICON": {
"light": lambda request: static("images/django-logo.png"),
"dark": lambda request: static("images/django-logo.png"),
},
"SITE_FAVICONS": [
{
"rel": "icon",
"sizes": "32x32",
"type": "image/svg+xml",
"href": lambda request: static("images/django-logo.png"),
},
],
"SITE_SYMBOL": "speed",
"SHOW_HISTORY": True,
"SHOW_VIEW_ON_SITE": True,
"LOGIN": {
"image": lambda request: static("images/login.jpg"),
},
"STYLES": [
lambda request: static("css/tailwind.css"),
],
"COLORS": {
"font": {
"subtle-light": "107 114 128",
"subtle-dark": "156 163 175",
"default-light": "75 85 99",
"default-dark": "209 213 219",
"important-light": "17 24 39",
"important-dark": "243 244 246",
},
"primary": {
"50": "65 144 176",
"100": "65 144 176",
"200": "65 144 176",
"300": "65 144 176",
"400": "65 144 176",
"500": "65 144 176",
"600": "65 144 176",
"700": "65 144 176",
"800": "65 144 176",
"900": "65 144 176",
"950": "65 144 176",
},
},
"EXTENSIONS": {
"modeltranslation": {
"flags": {
"uz": "🇺🇿",
"ru": "🇷🇺",
},
},
},
"SIDEBAR": {
"show_search": True,
"show_all_applications": True,
"navigation": navigation.PAGES,
},
"TABS": [
{
"models": [
"geology.geology",
"geology.photo",
"geology.category",
],
"items": [
{
"title": _("Madanlar"),
"link": reverse_lazy("admin:geology_geology_changelist"),
},
{
"title": _("Fotolar"),
"link": reverse_lazy("admin:geology_photo_changelist"),
},
{
"title": _("Kategoriyalar"),
"link": reverse_lazy("admin:geology_category_changelist"),
},
],
},
{
"models": [
"geology.gallerycategory",
"geology.gallery",
],
"items": [
{
"title": _("Galereya kategoriyalari"),
"link": reverse_lazy("admin:geology_gallerycategory_changelist"),
},
{
"title": _("Galereya"),
"link": reverse_lazy("admin:geology_gallery_changelist"),
},
],
},
],
}

View File

@@ -0,0 +1,71 @@
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
def user_has_group_or_permission(user, permission):
if user.is_superuser:
return True
group_names = user.groups.values_list("name", flat=True)
if not group_names:
return True
return user.groups.filter(permissions__codename=permission).exists()
PAGES = [
{
"seperator": True,
"items": [
{
"title": _("Bosh sahifa"),
"icon": "home",
"link": reverse_lazy("admin:index"),
},
],
},
{
"seperator": True,
"title": _("Foydalanuvchilar"),
"items": [
{
"title": _("Guruhlar"),
"icon": "person_add",
"link": reverse_lazy("admin:auth_group_changelist"),
"permission": lambda request: user_has_group_or_permission(
request.user, "view_group"
),
},
{
"title": _("Foydalanuvchilar"),
"icon": "person_add",
"link": reverse_lazy("admin:auth_user_changelist"),
"permission": lambda request: user_has_group_or_permission(
request.user, "view_user"
),
},
],
},
{
"seperator": True,
"title": _("Geologiya"),
"items": [
{
"title": _("Madanlar"),
"icon": "hiking",
"link": reverse_lazy("admin:geology_geology_changelist"),
"permission": lambda request: user_has_group_or_permission(
request.user, "view_geology"
),
},
{
"title": _("Galereya"),
"icon": "gallery_thumbnail",
"link": reverse_lazy("admin:geology_gallerycategory_changelist"),
"permission": lambda request: user_has_group_or_permission(
request.user, "view_photo"
),
},
],
},
]