541 lines
14 KiB
Python
541 lines
14 KiB
Python
"""
|
|
Django settings for NorahUniversity project.
|
|
|
|
Generated by 'django-admin startproject' using Django 5.2.1.
|
|
|
|
For more information on this file, see
|
|
https://docs.djangoproject.com/en/5.2/topics/settings/
|
|
|
|
For the full list of settings and their values, see
|
|
https://docs.djangoproject.com/en/5.2/ref/settings/
|
|
"""
|
|
|
|
import os
|
|
from pathlib import Path
|
|
from django.templatetags.static import static
|
|
from dotenv import load_dotenv
|
|
|
|
load_dotenv()
|
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
|
BASE_DIR = Path(__file__).resolve().parent.parent
|
|
|
|
# Quick-start development settings - unsuitable for production
|
|
# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/
|
|
|
|
# SECURITY WARNING: keep the secret key used in production secret!
|
|
SECRET_KEY = "django-insecure-_!ew&)1&r--3h17knd27^x8(xu(&-f4q3%x543lv5vx2!784s*"
|
|
|
|
# SECURITY WARNING: don't run with debug turned on in production!
|
|
DEBUG = True
|
|
|
|
ALLOWED_HOSTS = ["*"]
|
|
|
|
# Application definition
|
|
|
|
INSTALLED_APPS = [
|
|
"django.contrib.admin",
|
|
"django.contrib.humanize",
|
|
"django.contrib.auth",
|
|
"django.contrib.contenttypes",
|
|
"django.contrib.sessions",
|
|
"django.contrib.messages",
|
|
"django.contrib.staticfiles",
|
|
"rest_framework",
|
|
"recruitment.apps.RecruitmentConfig",
|
|
"corsheaders",
|
|
"django.contrib.sites",
|
|
"allauth",
|
|
"allauth.account",
|
|
"allauth.socialaccount",
|
|
"allauth.socialaccount.providers.linkedin_oauth2",
|
|
"channels",
|
|
"django_filters",
|
|
"crispy_forms",
|
|
# 'django_summernote',
|
|
# 'ckeditor',
|
|
"django_ckeditor_5",
|
|
"crispy_bootstrap5",
|
|
"django_extensions",
|
|
"template_partials",
|
|
"django_countries",
|
|
"django_celery_results",
|
|
"django_q",
|
|
"widget_tweaks",
|
|
"easyaudit",
|
|
"mathfilters"
|
|
]
|
|
|
|
|
|
SITE_ID = 1
|
|
|
|
|
|
LOGIN_REDIRECT_URL = '/'
|
|
|
|
|
|
ACCOUNT_LOGOUT_REDIRECT_URL = "/"
|
|
|
|
|
|
ACCOUNT_SIGNUP_REDIRECT_URL = "/"
|
|
|
|
|
|
LOGIN_URL = "/accounts/login/"
|
|
|
|
|
|
AUTHENTICATION_BACKENDS = [
|
|
"recruitment.backends.CustomAuthenticationBackend",
|
|
"django.contrib.auth.backends.ModelBackend",
|
|
"allauth.account.auth_backends.AuthenticationBackend",
|
|
]
|
|
|
|
MIDDLEWARE = [
|
|
"corsheaders.middleware.CorsMiddleware",
|
|
"django.middleware.security.SecurityMiddleware",
|
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
|
"django.middleware.locale.LocaleMiddleware",
|
|
"django.middleware.common.CommonMiddleware",
|
|
"django.middleware.csrf.CsrfViewMiddleware",
|
|
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
|
"django.contrib.messages.middleware.MessageMiddleware",
|
|
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
|
"allauth.account.middleware.AccountMiddleware",
|
|
"easyaudit.middleware.easyaudit.EasyAuditMiddleware",
|
|
]
|
|
|
|
ROOT_URLCONF = "NorahUniversity.urls"
|
|
|
|
CORS_ALLOW_ALL_ORIGINS = True
|
|
|
|
ASGI_APPLICATION = "hospital_recruitment.asgi.application"
|
|
CHANNEL_LAYERS = {
|
|
"default": {
|
|
"BACKEND": "channels_redis.core.RedisChannelLayer",
|
|
"CONFIG": {
|
|
"hosts": [("127.0.0.1", 6379)],
|
|
},
|
|
},
|
|
}
|
|
|
|
TEMPLATES = [
|
|
{
|
|
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
|
"DIRS": [os.path.join(BASE_DIR, "templates")],
|
|
"APP_DIRS": True,
|
|
"OPTIONS": {
|
|
"context_processors": [
|
|
"django.template.context_processors.request",
|
|
"django.contrib.auth.context_processors.auth",
|
|
"django.contrib.messages.context_processors.messages",
|
|
],
|
|
},
|
|
},
|
|
]
|
|
|
|
WSGI_APPLICATION = "NorahUniversity.wsgi.application"
|
|
|
|
# Database
|
|
# https://docs.djangoproject.com/en/5.2/ref/settings/#databases
|
|
|
|
DATABASES = {
|
|
'default': {
|
|
'ENGINE': 'django.db.backends.postgresql_psycopg2',
|
|
'NAME': os.getenv("DB_NAME"),
|
|
'USER': os.getenv("DB_USER"),
|
|
'PASSWORD': os.getenv("DB_PASSWORD"),
|
|
'HOST': '127.0.0.1',
|
|
'PORT': '5432',
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
# DATABASES = {
|
|
# 'default': {
|
|
# 'ENGINE': 'django.db.backends.sqlite3',
|
|
# 'NAME': BASE_DIR / 'db.sqlite3',
|
|
# }
|
|
# }
|
|
|
|
# Password validation
|
|
# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators
|
|
|
|
|
|
|
|
# AUTH_PASSWORD_VALIDATORS = [
|
|
# {
|
|
# 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
|
# },
|
|
# {
|
|
# 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
|
# },
|
|
# {
|
|
# 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
|
# },
|
|
# {
|
|
# 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
|
# },
|
|
# ]
|
|
|
|
# settings.py
|
|
|
|
AUTH_PASSWORD_VALIDATORS = [
|
|
{
|
|
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
|
},
|
|
{
|
|
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
|
},
|
|
{
|
|
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
|
},
|
|
{
|
|
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
|
},
|
|
]
|
|
|
|
|
|
ACCOUNT_LOGIN_METHODS = ["email"]
|
|
ACCOUNT_SIGNUP_FIELDS = ["email*", "password1*", "password2*"]
|
|
|
|
ACCOUNT_UNIQUE_EMAIL = True
|
|
ACCOUNT_EMAIL_VERIFICATION = 'none'
|
|
ACCOUNT_USER_MODEL_USERNAME_FIELD = None
|
|
ACCOUNT_EMAIL_VERIFICATION = "optional"
|
|
ACCOUNT_LOGIN_ON_EMAIL_CONFIRMATION = True
|
|
|
|
|
|
ACCOUNT_FORMS = {"signup": "recruitment.forms.StaffSignupForm"}
|
|
|
|
|
|
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
|
|
EMAIL_HOST = "10.10.1.110"
|
|
EMAIL_PORT = 2225
|
|
|
|
# Crispy Forms Configuration
|
|
CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5"
|
|
CRISPY_TEMPLATE_PACK = "bootstrap5"
|
|
|
|
# Bootstrap 5 Configuration
|
|
CRISPY_BS5 = {
|
|
"include_placeholder_text": True,
|
|
"use_css_helpers": True,
|
|
}
|
|
|
|
ACCOUNT_RATE_LIMITS = {
|
|
"send_email_confirmation": None, # Disables the limit
|
|
}
|
|
|
|
# Internationalization
|
|
# https://docs.djangoproject.com/en/5.2/topics/i18n/
|
|
|
|
LANGUAGES = [
|
|
("en", "English"),
|
|
("ar", "Arabic"),
|
|
]
|
|
|
|
LANGUAGE_CODE = "en-us"
|
|
|
|
LOCALE_PATHS = [
|
|
BASE_DIR / "locale",
|
|
]
|
|
|
|
TIME_ZONE = "Asia/Riyadh"
|
|
|
|
USE_I18N = True
|
|
|
|
USE_TZ = True
|
|
|
|
# Static files (CSS, JavaScript, Images)
|
|
# https://docs.djangoproject.com/en/5.2/howto/static-files/
|
|
|
|
STATIC_URL = "/static/"
|
|
MEDIA_URL = "/media/"
|
|
STATICFILES_DIRS = [BASE_DIR / "static"]
|
|
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
|
|
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
|
|
|
|
# Default primary key field type
|
|
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field
|
|
|
|
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
|
|
|
# LinkedIn OAuth Config
|
|
SOCIALACCOUNT_PROVIDERS = {
|
|
"linkedin_oauth2": {
|
|
"SCOPE": [
|
|
"r_liteprofile",
|
|
"r_emailaddress",
|
|
"w_member_social",
|
|
"rw_organization_admin",
|
|
"w_organization_social",
|
|
],
|
|
"PROFILE_FIELDS": ["id", "first-name", "last-name", "email-address"],
|
|
}
|
|
}
|
|
|
|
# Dynamic Zoom Configuration - will be loaded from database
|
|
# These are fallback values - actual values will be loaded from database at runtime
|
|
ZOOM_ACCOUNT_ID = "HoGikHXsQB2GNDC5Rvyw9A"
|
|
ZOOM_CLIENT_ID = "brC39920R8C8azfudUaQgA"
|
|
ZOOM_CLIENT_SECRET = "rvfhjlbID4ychXPOvZ2lYsoAC0B0Ny2L"
|
|
SECRET_TOKEN = "6KdTGyF0SSCSL_V4Xa34aw"
|
|
ZOOM_WEBHOOK_API_KEY = "2GNDC5Rvyw9AHoGikHXsQB"
|
|
|
|
# Maximum file upload size (in bytes)
|
|
DATA_UPLOAD_MAX_MEMORY_SIZE = 10485760 # 10MB
|
|
FILE_UPLOAD_MAX_MEMORY_SIZE = 10485760 # 10MB
|
|
|
|
CORS_ALLOW_CREDENTIALS = True
|
|
|
|
CELERY_BROKER_URL = "redis://localhost:6379/0" # Or your message broker URL
|
|
CELERY_RESULT_BACKEND = "django-db" # If using django-celery-results
|
|
CELERY_ACCEPT_CONTENT = ["application/json"]
|
|
CELERY_TASK_SERIALIZER = "json"
|
|
CELERY_RESULT_SERIALIZER = "json"
|
|
CELERY_TIMEZONE = "UTC"
|
|
|
|
# Dynamic LinkedIn Configuration - will be loaded from database
|
|
# These are fallback values - actual values will be loaded from database at runtime
|
|
LINKEDIN_CLIENT_ID = "867jwsiyem1504"
|
|
LINKEDIN_CLIENT_SECRET = "WPL_AP1.QNH5lYnfRSQpp0Qp.GO8Srw=="
|
|
LINKEDIN_REDIRECT_URI = "http://127.0.0.1:8000/jobs/linkedin/callback/"
|
|
|
|
|
|
Q_CLUSTER = {
|
|
"name": "KAAUH_CLUSTER",
|
|
"workers": 2,
|
|
"recycle": 500,
|
|
"timeout": 120,
|
|
"max_attempts": 1,
|
|
"compress": True,
|
|
"save_limit": 250,
|
|
"queue_limit": 500,
|
|
"cpu_affinity": 1,
|
|
"label": "Django Q2",
|
|
"redis": {
|
|
"host": "127.0.0.1",
|
|
"port": 6379,
|
|
"db": 3,
|
|
},
|
|
"ALT_CLUSTERS": {
|
|
"long": {
|
|
"timeout": 3000,
|
|
"retry": 3600,
|
|
"max_attempts": 2,
|
|
},
|
|
"short": {
|
|
"timeout": 10,
|
|
"max_attempts": 1,
|
|
},
|
|
},
|
|
}
|
|
|
|
|
|
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_CUSTOM_CSS = 'path_to.css' # optional
|
|
# CKEDITOR_5_FILE_STORAGE = "path_to_storage.CustomStorage" # optional
|
|
CKEDITOR_5_CONFIGS = {
|
|
"default": {
|
|
"toolbar": {
|
|
"items": [
|
|
"heading",
|
|
"|",
|
|
"bold",
|
|
"italic",
|
|
"link",
|
|
"bulletedList",
|
|
"numberedList",
|
|
"blockQuote",
|
|
"imageUpload",
|
|
],
|
|
}
|
|
},
|
|
"extends": {
|
|
"blockToolbar": [
|
|
"paragraph",
|
|
"heading1",
|
|
"heading2",
|
|
"heading3",
|
|
"|",
|
|
"bulletedList",
|
|
"numberedList",
|
|
"|",
|
|
"blockQuote",
|
|
],
|
|
"toolbar": {
|
|
"items": [
|
|
"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",
|
|
],
|
|
"shouldNotGroupWhenFull": "true",
|
|
},
|
|
"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",
|
|
}
|
|
},
|
|
}
|
|
|
|
# Define a constant in settings.py to specify file upload permissions
|
|
CKEDITOR_5_FILE_UPLOAD_PERMISSION = (
|
|
"staff" # Possible values: "staff", "authenticated", "any"
|
|
)
|
|
|
|
|
|
|
|
from django.contrib.messages import constants as messages
|
|
MESSAGE_TAGS = {
|
|
messages.ERROR: 'danger',
|
|
}
|
|
|
|
|
|
# Custom User Model
|
|
AUTH_USER_MODEL = "recruitment.CustomUser"
|
|
|
|
|
|
ZOOM_WEBHOOK_API_KEY = "2GNDC5Rvyw9AHoGikHXsQB"
|
|
|
|
|
|
|
|
#logger:
|
|
LOGGING={
|
|
"version": 1,
|
|
"disable_existing_loggers": False,
|
|
"handlers": {
|
|
"file": {
|
|
"class": "logging.FileHandler",
|
|
"filename": os.path.join(BASE_DIR, "general.log"),
|
|
"level": "DEBUG",
|
|
"formatter": "verbose",
|
|
},
|
|
"console":{
|
|
"class": "logging.StreamHandler",
|
|
"level": "DEBUG",
|
|
"formatter": "simple"
|
|
}
|
|
|
|
},
|
|
"loggers": {
|
|
"": {
|
|
"handlers": ["file", "console"],
|
|
"level": "DEBUG",
|
|
"propagate": True,
|
|
},
|
|
},
|
|
"formatters": {
|
|
"verbose": {
|
|
"format": "[{asctime}] {levelname} [{name}:{lineno}] {message}",
|
|
"style": "{",
|
|
},
|
|
"simple": {
|
|
"format": "{levelname} {message}",
|
|
"style": "{",
|
|
},
|
|
}
|
|
}
|
|
|
|
|