diff --git a/.env.example b/.env.example index b87fd085..2a7aaa4f 100644 --- a/.env.example +++ b/.env.example @@ -1,21 +1,35 @@ # ============================= # Email config -# For development or quick testing use console as the email backend +# This line is the "magic" fix. It tells Django to print emails to the terminal +# instead of trying to send them through a real server. EMAIL_BACKEND="django.core.mail.backends.console.EmailBackend" -# For production use smtp, uncomment the below variable -# EMAIL_BACKEND="django.core.mail.backends.smtp.EmailBackend" + EMAIL_HOST="smtp.gmail.com" EMAIL_PORT=587 EMAIL_USE_TLS=True EMAIL_FROM_ADDRESS="SkyLearn " -EMAIL_HOST_USER="" -EMAIL_HOST_PASSWORD="" + +# These two must exist for your config('NAME') calls to work +EMAIL_HOST_USER="youremail@example.com" +EMAIL_HOST_PASSWORD="yourpassword" # ============================= -# Other +# Database Neon - PostgresSQL +DB_ENGINE=django.db.backends.postgresql +DB_NAME=neondb +DB_USER=neondb_owner +DB_PASSWORD=npg_B0Hujnsh8zEv +DB_HOST=ep-gentle-shape-a1unb4h2-pooler.ap-southeast-1.aws.neon.tech +DB_PORT=5432 -DEBUG=True -SECRET_KEY="" +# ============================= +# Cloudinary Storage - Cloudinary +CLOUDINARY_CLOUD_NAME=ddr6xe1vn +CLOUDINARY_API_KEY=781526684325383 +CLOUDINARY_API_SECRET=F1IcPCOHWkItagYigXGm-3j6VHc -GOOGLE_API_KEY=your-api-key-here \ No newline at end of file +# ============================= +# Other +DEBUG=True +SECRET_KEY="any-random-string-here" diff --git a/config/settings.py b/config/settings.py index 3174e34b..4306fba8 100644 --- a/config/settings.py +++ b/config/settings.py @@ -13,6 +13,7 @@ import os from decouple import config from django.utils.translation import gettext_lazy as _ +import cloudinary # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -52,6 +53,8 @@ "crispy_forms", "crispy_bootstrap5", "django_filters", + "cloudinary_storage", + "cloudinary", ] # Custom apps @@ -108,11 +111,14 @@ # Database # https://docs.djangoproject.com/en/2.2/ref/settings/#databases +import dj_database_url + DATABASES = { - "default": { - "ENGINE": "django.db.backends.sqlite3", - "NAME": os.path.join(BASE_DIR, "db.sqlite3"), - } + 'default': dj_database_url.config( + default=f"postgres://{config('DB_USER')}:{config('DB_PASSWORD')}@{config('DB_HOST')}:{config('DB_PORT')}/{config('DB_NAME')}", + conn_max_age=600, + ssl_require=True + ) } # https://docs.djangoproject.com/en/stable/ref/settings/#std:setting-DEFAULT_AUTO_FIELD @@ -270,3 +276,13 @@ def gettext(s): (SECOND, _("Second")), (THIRD, _("Third")), ) + +# Read Cloudinary credentials from .env +CLOUDINARY_STORAGE = { + 'CLOUD_NAME': config('CLOUDINARY_CLOUD_NAME'), + 'API_KEY': config('CLOUDINARY_API_KEY'), + 'API_SECRET': config('CLOUDINARY_API_SECRET'), +} + +# Tell Django to upload all media files to Cloudinary +DEFAULT_FILE_STORAGE = 'cloudinary_storage.storage.RawMediaCloudinaryStorage' diff --git a/requirements/base.txt b/requirements/base.txt index 0bd2c434..85399f2f 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -10,6 +10,7 @@ crispy-bootstrap5>=2024.2 # https://github.com/django-crispy-forms/crispy-boots django-filter>=23.5,<24.0 # https://github.com/carltongibson/django-filter django-modeltranslation>=0.18,<0.19 # https://github.com/Buren/django-modeltranslation + # PDF generator reportlab>=4.0,<5.0 xhtml2pdf>=0.2.15,<1.0 @@ -29,8 +30,9 @@ stripe>=8.0,<9.0 gopay>=2.0,<3.0 # AI core -langchain-core>=0.3,<0.4 -langchain-google-genai>=2.1,<3.0 -PyPDF2>=3.0,<4.0 -python-pptx>=1.0,<2.0 -numpy>=1.26,<3.0 +langchain +langchain-google-genai + +#Cloudinary +psycopg2-binary dj-database-url +cloudinary django-cloudinary-storage diff --git a/templates/navbar.html b/templates/navbar.html index dece5ec0..6853536a 100644 --- a/templates/navbar.html +++ b/templates/navbar.html @@ -17,12 +17,16 @@