| from rest_framework.views import APIView |
| from rest_framework.response import Response |
| from rest_framework import status |
| from .models import UserData, AIKey, AppVersion, Contact |
| from django.shortcuts import get_object_or_404 |
| from .serializers import ContactSerializer |
| from rest_framework.generics import CreateAPIView |
| import os |
| import smtplib |
| from email.mime.text import MIMEText |
| from email.mime.multipart import MIMEMultipart |
|
|
|
|
| class UserDataPostView(APIView): |
| def post(self, request): |
| user_id = request.data.get("user_id") |
| if not user_id: |
| return Response( |
| {"error": "user_id is required"}, status=status.HTTP_400_BAD_REQUEST |
| ) |
|
|
| obj, created = UserData.objects.get_or_create(user_id=user_id) |
|
|
| |
| updated = False |
| for key in ["expenses", "salary", "category", "user_data"]: |
| if key in request.data and getattr(obj, key) != request.data[key]: |
| setattr(obj, key, request.data[key]) |
| updated = True |
|
|
| if updated: |
| obj.save() |
|
|
| if created: |
| obj = get_object_or_404(UserData, user_id=user_id) |
| if obj.has_ai_access: |
| AI_KEY = get_object_or_404(AIKey, isActive=True).aikey |
| else: |
| AI_KEY = None |
| return Response( |
| { |
| "message": "Data created successfull", |
| "app_version": get_object_or_404(AppVersion, isActive=True).version, |
| "has_music_url_access": obj.has_music_url_access, |
| "has_ai_access": obj.has_ai_access, |
| "ai_key": AI_KEY, |
| }, |
| status=status.HTTP_201_CREATED, |
| ) |
| elif updated: |
| obj = get_object_or_404(UserData, user_id=user_id) |
| print(obj.has_ai_access) |
| if obj.has_ai_access: |
| AI_KEY = get_object_or_404(AIKey, isActive=True).aikey |
| else: |
| AI_KEY = None |
| return Response( |
| { |
| "message": "Data updated successfull", |
| "app_version": get_object_or_404(AppVersion, isActive=True).version, |
| "has_music_url_access": obj.has_music_url_access, |
| "has_ai_access": obj.has_ai_access, |
| "ai_key": AI_KEY, |
| }, |
| status=status.HTTP_200_OK, |
| ) |
| else: |
| obj = get_object_or_404(UserData, user_id=user_id) |
| if obj.has_ai_access: |
| AI_KEY = get_object_or_404(AIKey, isActive=True).aikey |
| else: |
| AI_KEY = None |
| return Response( |
| { |
| "message": "No changes made", |
| "app_version": get_object_or_404(AppVersion, isActive=True).version, |
| "has_music_url_access": obj.has_music_url_access, |
| "has_ai_access": obj.has_ai_access, |
| "ai_key": AI_KEY, |
| }, |
| status=status.HTTP_200_OK, |
| ) |
|
|
|
|
| class GetFieldView(APIView): |
| def get(self, request, field, user_id): |
| obj = get_object_or_404(UserData, user_id=user_id) |
| if field == "all": |
| data = { |
| "userData": obj.user_data, |
| "expenseData": obj.expenses, |
| "categoryData": obj.category, |
| "salaryData": obj.salary, |
| } |
| return Response(data) |
| if hasattr(obj, field): |
| return Response({field: getattr(obj, field)}) |
| return Response({"error": "Invalid field"}, status=status.HTTP_400_BAD_REQUEST) |
|
|
|
|
| upper_body = """ |
| <!DOCTYPE html> |
| <html lang="en"> |
| |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Contact Form Confirmation Template</title> |
| |
| <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet"> |
| |
| <style> |
| :root { |
| --brand-100: #dbeafe; |
| --brand-500: #3b82f6; |
| --brand-600: #2563eb; |
| --brand-900: #1e3a8a; |
| --gray-50: #f9fafb; |
| --gray-100: #f3f4f6; |
| --gray-200: #e5e7eb; |
| --gray-400: #9ca3af; |
| --gray-500: #6b7280; |
| --gray-600: #4b5563; |
| --gray-700: #374151; |
| --gray-900: #111827; |
| --white: #ffffff; |
| } |
| |
| body { |
| margin: 0; |
| padding: 20px; |
| background-color: var(--gray-100); |
| font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; |
| color: var(--gray-700); |
| display: flex; |
| flex-direction: column; |
| align-items: center; |
| min-height: 100vh; |
| } |
| |
| a { |
| text-decoration: none; |
| } |
| |
| strong { |
| font-weight: 700; |
| } |
| |
| .btn-copy { |
| background-color: var(--gray-900); |
| color: var(--white); |
| border: none; |
| padding: 8px 16px; |
| border-radius: 6px; |
| font-size: 14px; |
| font-weight: 500; |
| cursor: pointer; |
| display: flex; |
| align-items: center; |
| gap: 8px; |
| transition: background-color 0.2s; |
| } |
| |
| .btn-copy:hover { |
| background-color: #000000; |
| } |
| |
| #email-template { |
| width: 100%; |
| max-width: 600px; |
| background-color: var(--white); |
| border-radius: 12px; |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); |
| overflow: hidden; |
| border: 1px solid var(--gray-100); |
| margin: 0 auto; |
| } |
| |
| .email-header { |
| background-color: var(--brand-600); |
| padding: 32px; |
| text-align: left; |
| } |
| |
| .email-header h1 { |
| color: var(--white); |
| font-size: 24px; |
| font-weight: 700; |
| letter-spacing: 0.025em; |
| margin: 0; |
| text-transform: uppercase; |
| } |
| |
| .email-header p { |
| color: var(--brand-100); |
| margin-top: 4px; |
| margin-bottom: 0; |
| font-size: 14px; |
| } |
| |
| .email-body { |
| padding: 32px; |
| } |
| |
| .greeting { |
| font-size: 18px; |
| color: var(--gray-700); |
| margin-bottom: 24px; |
| } |
| |
| .highlight { |
| color: var(--brand-600); |
| font-weight: 600; |
| } |
| |
| .text-paragraph { |
| color: var(--gray-600); |
| line-height: 1.6; |
| margin-bottom: 24px; |
| margin-top: 0; |
| } |
| |
| .recap-box { |
| background-color: var(--gray-50); |
| border-radius: 8px; |
| padding: 24px; |
| border-left: 4px solid var(--brand-500); |
| margin-bottom: 32px; |
| } |
| |
| .recap-label { |
| font-size: 12px; |
| font-weight: 700; |
| color: var(--gray-400); |
| text-transform: uppercase; |
| letter-spacing: 0.05em; |
| margin: 0 0 8px 0; |
| } |
| |
| .recap-content { |
| font-style: italic; |
| color: var(--gray-600); |
| font-size: 14px; |
| margin: 0; |
| } |
| |
| .btn-container { |
| margin-top: 32px; |
| text-align: left; |
| } |
| |
| .btn-primary { |
| display: inline-block; |
| background-color: var(--brand-600); |
| color: var(--white); |
| font-weight: 500; |
| padding: 12px 24px; |
| border-radius: 8px; |
| font-size: 14px; |
| transition: background-color 0.2s; |
| } |
| |
| .btn-primary:hover { |
| background-color: var(--brand-900); |
| } |
| |
| .email-footer { |
| background-color: var(--gray-50); |
| padding: 24px 32px; |
| border-top: 1px solid var(--gray-100); |
| text-align: center; |
| } |
| |
| .social-icons { |
| margin-bottom: 16px; |
| } |
| |
| .social-link { |
| color: var(--gray-400); |
| margin: 0 8px; |
| font-size: 20px; |
| transition: color 0.2s; |
| } |
| |
| .social-link:hover { |
| color: var(--brand-600); |
| } |
| |
| .footer-text { |
| font-size: 12px; |
| color: var(--gray-400); |
| margin: 0; |
| line-height: 1.5; |
| } |
| |
| .footer-link { |
| color: var(--gray-400); |
| text-decoration: underline; |
| } |
| |
| .footer-link:hover { |
| color: var(--gray-600); |
| } |
| |
| #toast { |
| position: fixed; |
| bottom: 20px; |
| right: 20px; |
| background-color: var(--gray-900); |
| color: var(--white); |
| padding: 12px 24px; |
| border-radius: 8px; |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); |
| opacity: 0; |
| transform: translateY(20px); |
| transition: all 0.3s ease; |
| } |
| |
| #toast.show { |
| opacity: 1; |
| transform: translateY(0); |
| } |
| |
| @media (max-width: 600px) { |
| |
| .email-header, |
| .email-body, |
| .email-footer { |
| padding: 24px; |
| } |
| |
| .email-header, |
| .btn-container { |
| text-align: center; |
| } |
| .btn-copy { |
| width: 100%; |
| justify-content: center; |
| } |
| } |
| </style> |
| </head> |
| |
| <body> |
| <div id="email-template"> |
| <div class="email-header"> |
| <h1>THANK YOU!</h1> |
| <p>I've received your message.</p> |
| </div> |
| <div class="email-body"> |
| <p class="greeting">Hi <span class="highlight">""" |
|
|
| mid_body = """</span>,</p> |
| <p class="text-paragraph"> |
| Thanks for reaching out via my portfolio! I wanted to let you know that your message has landed safely |
| in my inbox. |
| </p> |
| <p class="text-paragraph"> |
| I appreciate your interest. I typically review inquiries within <strong>24 hours</strong> and will get |
| back to you as soon as possible. |
| </p> |
| <div class="recap-box"> |
| <h3 class="recap-label">You wrote:</h3> |
| <p class="recap-content"> |
| """ |
|
|
| lower_body = """ |
| </p> |
| </div> |
| <p class="text-paragraph" style="margin-bottom: 0;"> |
| Best regards,<br> |
| <span style="font-weight: 600; color: #111827;">Dev Namdev</span> |
| </p> |
| <div class="btn-container"> |
| <a href="https://devnamdev2003.github.io/" class="btn-primary"> |
| Return to Portfolio |
| </a> |
| </div> |
| </div> |
| <div class="email-footer"> |
| <div class="social-icons"> |
| <a href="https://www.linkedin.com/in/devnamdev/" class="social-link"><i class="fab fa-linkedin"></i></a> |
| <a href="https://github.com/devnamdev2003" class="social-link"><i class="fab fa-github"></i></a> |
| </div> |
| <p class="footer-text"> |
| © 2024 Dev Namdev. All rights reserved.<br> |
| </p> |
| </div> |
| </div> |
| |
| </body> |
| |
| </html> |
| """ |
|
|
| EMAIL_HOST = "smtp.gmail.com" |
| EMAIL_PORT = 587 |
| EMAIL_USER = os.getenv("EMAIL_HOST_USER") |
| EMAIL_PASSWORD = os.getenv("EMAIL_HOST_PASSWORD") |
|
|
|
|
| class ContactList1(CreateAPIView): |
| queryset = Contact.objects.all() |
| serializer_class = ContactSerializer |
|
|
| def perform_create(self, serializer): |
| instance = serializer.save() |
| user_ip = self.get_client_ip(self.request) |
|
|
| email = instance.email |
| name = instance.name |
| message = instance.message |
|
|
| try: |
| print("mail sending..") |
| msg = MIMEMultipart() |
| msg["From"] = EMAIL_USER |
| msg["To"] = email |
| msg["Subject"] = "Confirmation: We've Received Your Message" |
|
|
| body = upper_body + name + mid_body + message + lower_body |
| msg.attach(MIMEText(body, "html")) |
|
|
| |
| server = smtplib.SMTP(EMAIL_HOST, EMAIL_PORT, timeout=10) |
| server.starttls() |
| server.login(EMAIL_USER, EMAIL_PASSWORD) |
|
|
| server.sendmail(EMAIL_USER, email, msg.as_string()) |
| print("mail send to user") |
|
|
| admin_text = ( |
| f"Subject: Form Submission from {name}\n\n" |
| f"Name: {name}\n" |
| f"Email: {email}\n" |
| f"Message: {message}\n" |
| f"IP Address: {user_ip}" |
| ) |
|
|
| server.sendmail(EMAIL_USER, "devnamdevcse@gmail.com", admin_text) |
| print("mail send to devnamdevcse@gmail.com") |
| except Exception as e: |
| |
| print("Email error:", e) |
|
|
| finally: |
| try: |
| server.quit() |
| except: |
| pass |
|
|
| def get_client_ip(self, request): |
| x_forwarded_for = request.META.get("HTTP_X_FORWARDED_FOR") |
| if x_forwarded_for: |
| ip = x_forwarded_for.split(",")[0] |
| else: |
| ip = request.META.get("REMOTE_ADDR") |
| return ip |
|
|