""" 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", ] 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": "{", }, } }