From ae46f837d6d46b29550f695d357c6c265cb53354 Mon Sep 17 00:00:00 2001 From: Sankha Das <54751139+sankha555@users.noreply.github.com> Date: Sun, 29 Dec 2019 14:13:46 +0530 Subject: [PATCH 1/4] Backend completed file handling, user management and mails added. Frontend templates left --- dbportal/db.sqlite3 | Bin 0 -> 131072 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 143 bytes .../__pycache__/settings.cpython-37.pyc | Bin 0 -> 2251 bytes .../dbportal/__pycache__/urls.cpython-37.pyc | Bin 0 -> 919 bytes .../dbportal/__pycache__/wsgi.cpython-37.pyc | Bin 0 -> 548 bytes dbportal/dbportal/settings.py | 142 +++++++++ dbportal/dbportal/urls.py | 23 ++ dbportal/dbportal/wsgi.py | 16 + dbportal/files/admin.py | 6 + dbportal/files/apps.py | 5 + dbportal/files/forms.py | 36 +++ dbportal/files/models.py | 21 ++ dbportal/files/tests.py | 3 + dbportal/files/urls.py | 16 + dbportal/files/views.py | 290 ++++++++++++++++++ dbportal/manage.py | 21 ++ dbportal/users/admin.py | 7 + dbportal/users/apps.py | 5 + dbportal/users/forms.py | 39 +++ dbportal/users/models.py | 33 ++ dbportal/users/tests.py | 3 + dbportal/users/urls.py | 13 + dbportal/users/views.py | 85 +++++ 23 files changed, 764 insertions(+) create mode 100644 dbportal/db.sqlite3 create mode 100644 dbportal/dbportal/__pycache__/__init__.cpython-37.pyc create mode 100644 dbportal/dbportal/__pycache__/settings.cpython-37.pyc create mode 100644 dbportal/dbportal/__pycache__/urls.cpython-37.pyc create mode 100644 dbportal/dbportal/__pycache__/wsgi.cpython-37.pyc create mode 100644 dbportal/dbportal/settings.py create mode 100644 dbportal/dbportal/urls.py create mode 100644 dbportal/dbportal/wsgi.py create mode 100644 dbportal/files/admin.py create mode 100644 dbportal/files/apps.py create mode 100644 dbportal/files/forms.py create mode 100644 dbportal/files/models.py create mode 100644 dbportal/files/tests.py create mode 100644 dbportal/files/urls.py create mode 100644 dbportal/files/views.py create mode 100644 dbportal/manage.py create mode 100644 dbportal/users/admin.py create mode 100644 dbportal/users/apps.py create mode 100644 dbportal/users/forms.py create mode 100644 dbportal/users/models.py create mode 100644 dbportal/users/tests.py create mode 100644 dbportal/users/urls.py create mode 100644 dbportal/users/views.py diff --git a/dbportal/db.sqlite3 b/dbportal/db.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..65586417850660f95e99d3314b58f3fbb014256b GIT binary patch literal 131072 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 literal 0 HcmV?d00001 diff --git a/dbportal/dbportal/__pycache__/__init__.cpython-37.pyc b/dbportal/dbportal/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a241397bb6e0ba7b014e01ca5cc1f0d445910605 GIT binary patch literal 143 zcmZ?b<>g`kg4oL}aUl9Jh=2h`Aj1KOi&=m~3PUi1CZpdyU!b3oRFGd(l9+>F#K&jmWtPOp>lIYq;;_lhPbtkwwF8;> H8HgDGgK8p6 literal 0 HcmV?d00001 diff --git a/dbportal/dbportal/__pycache__/settings.cpython-37.pyc b/dbportal/dbportal/__pycache__/settings.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ebb62f80698b340994780c808c961601ca2fad46 GIT binary patch literal 2251 zcmb7F$#UC95aj}q6fMe|ygM-xud*Y+mSx9I#fc#jmRaVaB0wuaRg41BBWNTnG-eQ4 z_!b}HV}2#q+;Gh)zmQWJAStmZS4AO+!Jxa}>z1C9lXp})PDo)OrhdC%g87eRjRi|WB z;S?-D4Hn@voPo1W**FE~j0HIFoh6B z7oQ67<;Mce8)x7Kh-i5OzRJe0v+*X)JA!c*ZW-s`ws9UKS;G4Q-WTDHaR~}qZuzdY zlF#L;ja|!k0+A8UsqZjxI|xM>41oTHPQ%2`x@Q92|&uAp@;g;89;> z+zR>F@~#*$q!GugtJ12phUiyF>IESYsgL}g#cAM+_~$zmJyMr^g8`804(CJmoh(CO zGil^w5`i6fGVx_3lzA|uHj^h2%OiTeL&WXKbw!slE(Y62E3$k*M}&srua+AT_J4eZ zWP8fd-&g^;PQ2=S5jSPmkt z<MG-%hj6;+3(^qW~`1w?ZN@Vn-q62a-0Pv=4Rh+AP)Bxip2>MzSf?@^L4)onGKe z_3ZHNvcmWPi%^+nHD_Ox<)G3ch33sGU{Y6mWJClSEB}+oR-7p`Lzb5iYg& zb}f4kD_;8PRcLvnJ4{QPP2p;jW|E@NWwAV_;lvxd*iX^`@x+Hoy-SU(we+!?8RxRy z|G-V`1RJ9YLKfefB{^;*0U1P2eE$TNA$gBo!Q%&G+rtV?6Z#qEG|}dkIPi?1B!Yo9q(vW7#g zgbGiaHR4309(Ap>FW!zUf-wH!q)ctOU`U*8_m?d)vPONp(Mg?K>cLCq3BBL zTuUx1ef_n$sc70(x7RS=Dy=3eyI5tlmeSeiD;ug=?>1DVZMId@=wew^`WSZe(X-BI z)_U}?lax}KZs1CE^i)ry`8^ljz|zTvf1b%{VKCXVe7fgaE?7)%5VnV(C3#Z2N0Z4{ zN*W#{mG8X(BA5Jd3dvXx2cb|YUM~wpp&*nB`N>rhCbRTeDhi|b!bG}Q63Xd(sah(g LSG9up(N+2v+>!VY literal 0 HcmV?d00001 diff --git a/dbportal/dbportal/__pycache__/urls.cpython-37.pyc b/dbportal/dbportal/__pycache__/urls.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..26fa7e465d60d800b732332d60dd9b4d939787e7 GIT binary patch literal 919 zcma)5O>fgM7*5i(8`%bb!M8M0iJ{_D!2}yjOhO!hT`EE5#%}A*AHjA8!ucK@z74Vw`3Qh?QEB6dKo@Ubp;N7vd{rCb zxK>H>Zq3kTZA3+!V@BCaB)E0R=-M&s4_M?hy5{VY&C!`QNNU3nS4(YV3xO)Zh-Jt! zHcJqUwR4r7VN7*tbGjjFr7NR1taN#)C1wgw^C@<^;-$qt8AExClNXPP61x5Nq!*Kp5RY{T~bM*35V!d23Wp=OtjZ>~G1&=jX&09%P*T!{}Ud zbuvxj-O;q}OgjmIWSM^7k*VCdqcQ8;km;_Z6Vl(k{*`^63`eX)GglRxqh<1}LFWlouLaXjp+}D`C~TWJC>;&1Rx$v?_&H zXlApB_aV~MXn`pc8S8a{p^4zivANRloH>AO;eF#?b1t!Txm*fU;Z{?LH3!4@^L@U+ zOOISaqw%T+nGdsa|hllQ@MUObc-TtD2hPQg~uBuc^L=DTU<*cQ|N+ODT^j#u~EWYTxcI2+@t(K zZ2OIC_xBY)bzmK@g;D2PXek^YfIIit@U4RXLCcaiSE2W2v*)+H2;^Fq(jI+CAJKow CPpmNj literal 0 HcmV?d00001 diff --git a/dbportal/dbportal/settings.py b/dbportal/dbportal/settings.py new file mode 100644 index 0000000..a3ae240 --- /dev/null +++ b/dbportal/dbportal/settings.py @@ -0,0 +1,142 @@ +""" +Django settings for dbportal project. + +Generated by 'django-admin startproject' using Django 2.2.4. + +For more information on this file, see +https://docs.djangoproject.com/en/2.2/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/2.2/ref/settings/ +""" + +import os + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'nmud+4cu4s^x$ir_nr#l9%w@32=s9=6x+(&5t_ago0)%r*k5_4' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + 'users.apps.UsersConfig', + 'files.apps.FilesConfig', + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + + 'crispy_forms', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'dbportal.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'dbportal.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/2.2/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + + +# Password validation +# https://docs.djangoproject.com/en/2.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', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/2.2/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + +#Email information + +SITE_ID = 1 + +EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' +EMAIL_PORT = 587 +EMAIL_HOST_USER = '############' +EMAIL_HOST_PASSWORD = '############' +EMAIL_USE_TLS = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/2.2/howto/static-files/ + +STATIC_URL = '/static/' + +MEDIA_ROOT = os.path.join(BASE_DIR, 'media') +MEDIA_URL = '/media/' + +CRISPY_TEMPLATE_PACK = 'bootstrap4' + +LOGIN_REDIRECT_URL = 'home' +LOGIN_URL = 'login' diff --git a/dbportal/dbportal/urls.py b/dbportal/dbportal/urls.py new file mode 100644 index 0000000..92b2552 --- /dev/null +++ b/dbportal/dbportal/urls.py @@ -0,0 +1,23 @@ +"""dbportal URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/2.2/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path, include + +urlpatterns = [ + path('admin/', admin.site.urls), + path('', include('files.urls')), + path('users/', include('users.urls')), +] diff --git a/dbportal/dbportal/wsgi.py b/dbportal/dbportal/wsgi.py new file mode 100644 index 0000000..472843a --- /dev/null +++ b/dbportal/dbportal/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for dbportal project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dbportal.settings') + +application = get_wsgi_application() diff --git a/dbportal/files/admin.py b/dbportal/files/admin.py new file mode 100644 index 0000000..7587366 --- /dev/null +++ b/dbportal/files/admin.py @@ -0,0 +1,6 @@ +from django.contrib import admin +from .models import File + +admin.site.register(File) + +# Register your models here. diff --git a/dbportal/files/apps.py b/dbportal/files/apps.py new file mode 100644 index 0000000..c86f272 --- /dev/null +++ b/dbportal/files/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class FilesConfig(AppConfig): + name = 'files' diff --git a/dbportal/files/forms.py b/dbportal/files/forms.py new file mode 100644 index 0000000..8402e92 --- /dev/null +++ b/dbportal/files/forms.py @@ -0,0 +1,36 @@ + from django import forms +from django.contrib.auth.models import User +from django.contrib.auth.forms import UserCreationForm +from .models import File +from users.models import Profile +from allauth.socialaccount.forms import SignupForm +from allauth.account.forms import LoginForm +from django.core import validators + +class FileUploadForm(forms.ModelForm): + botcatcher = forms.FileField(required = False, widget = forms.HiddenInput, + validators = [validators.MaxLengthValidator(0)]) + + class Meta: + model = File + fields = ['name', 'doc'] + +class SearchUIDForm(forms.ModelForm): + botcatcher = forms.CharField(required = False, widget = forms.HiddenInput, + validators = [validators.MaxLengthValidator(0)]) + + class Meta: + model = Profile + fields = ['uid'] + +class MailContentForm(forms.ModelForm): + subject = forms.CharField(max_length = 20) + content = forms.TextField(max_length = 264) + + fields = ['subject', 'content'] + +class AddDberForm(forms.ModelForm): + + class Meta: + model = Profile + fields = ['uid', 'name', 'dob', 'gender', 'city', 'state'] diff --git a/dbportal/files/models.py b/dbportal/files/models.py new file mode 100644 index 0000000..61f246b --- /dev/null +++ b/dbportal/files/models.py @@ -0,0 +1,21 @@ +from django.db import models +from django.contrib.auth.models import User +from PIL import Image +from django.dispatch import receiver +from django.db.models.signals import post_save +from django.utils import timezone +from django.urls import reverse +from users.models import Profile + +class File(models.Model): + + staff = models.ForeignKey(Profile, on_delete = models.CASCADE) + fname = models.CharField(max_length=20) + doc = models.FileField(upload_to='files/', blank=True) + up_date = models.DateField(default = timezone.now) + + def __str__(self): + return f'{self.fname}' + + def save(self, *args, **kwargs): + super().save(*args, **kwargs) diff --git a/dbportal/files/tests.py b/dbportal/files/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/dbportal/files/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/dbportal/files/urls.py b/dbportal/files/urls.py new file mode 100644 index 0000000..6d529a3 --- /dev/null +++ b/dbportal/files/urls.py @@ -0,0 +1,16 @@ +from django.contrib import admin +from django.urls import path +from .views import upload_file, search_dber, update_dber, delete_dber, add_dber, send_mail, send_mass_mails, home +from django.contrib.auth import views as auth_views + +urlpatterns = [ + + path('/', home, name='home'), + path('upload_file/', upload_file, name='upload_file'), + path('search_dber/', search_dber, name='search_dber'), + path('update_dber//', update_dber, name='update_dber'), + path('delete_dber//', delete_dber, name='delete_dber'), + path('add_dber/', add_dber, name='add_dber'), + path('send_mail//', send_mail, name='send_mail'), + path('send_mass_mails/', send_mass_mails, name='send_mass_mails'), +] diff --git a/dbportal/files/views.py b/dbportal/files/views.py new file mode 100644 index 0000000..da5cf4c --- /dev/null +++ b/dbportal/files/views.py @@ -0,0 +1,290 @@ +from django.shortcuts import render +from django.contrib.auth.decorators import login_required +from django.contrib import messages +import requests +from django.shortcuts import render, get_object_or_404, redirect +from django.contrib.auth.decorators import login_required +from .forms import FileUploadForm, SearchUIDForm, MailContentForm, AddDberForm +import xlrd, xlsxwriter +import openpyxl + + +def home(request): + return render(request, 'templates/home.html') + +@login_required +def upload_file(request): + if request.method == 'POST': + form = FileUploadForm(request.POST, request.FILES) + if form.is_valid(): + file = form.save(commit=False) + file.save() + + #file = request.FILES['filename'].temporary_file_path + document = file.doc + wb = xlrd.open_workbook(document.path) + sheet = wb.sheet_by_index(0) + sheet.cell_value(0, 0) + + rows = sheet.nrows + cols = sheet.ncols + + for i in range(2,rows): + dber_uid = sheet.cell_value(i, 0) + dber_name = sheet.cell_value(i, 1) + dber_dob = sheet.cell_value(i, 2) + dber_gender = sheet.cell_value(i, 3) + dber_city = sheet.cell_value(i, 4) + dber_state = sheet.cell_value(i, 5) + + new_dber = Profile.objects.get_or_create(uid = dber_uid) + new_dber.name = dber_name + new_dber.dob = dber_dob + new_dber.gender = dber_gender + new_dber.city = dber_city + new_dber.state = dber_state + new_dber.city_circle = file.staff.city_circle + + new_dber.save() + + return redirect('home') + else: + form = FileUploadForm() + + return render(request, 'templates/upload_file.html', { + 'form': form + }) + +def search_dber(request): + + file = get_object_or_404(File, staff = request.user.profile) + + if request.method == 'POST': + form = SearchUIDForm(request.POST) + if form.is_valid(): + form.save() + search_uid = form.cleaned_data['uid'] + + #file = request.FILES['filename'].temporary_file_path + document = file.doc + wb = xlrd.open_workbook(document.path) + sheet = wb.sheet_by_index(0) + + rows = sheet.nrows + cols = sheet.ncols + + flag = 0 + + for i in range(2,rows): + + if search_uid == sheet.cell_value(i, 0): + flag = 1 + dber = get_object_or_404(Profile, uid = search_uid) + return render(request, "templates/search_results.html", {'dber':dber}) + + if flag == 0: + return render(request, "templates/failed_search.html") + else: + form = SearchUIDForm() + + return render(request, 'templates/search_dber.html', { + 'form': form + }) + +@login_required +def update_dber(request, pk): + + dber = get_object_or_404(Profile, pk = pk) + if request.method == 'POST': + p_form = DberUpdateForm(request.POST, + instance=dber) + + if p_form.is_valid(): + dber.save() + p_form.save() + + # File updation begins + + file = get_object_or_404(File, staff = request.user.profile) + document = file.doc + wb = openpyxl.load_workbook(document.path) + sheet = wb.get_sheet(0) + + rows = sheet.max_row + + flag = 0 + for i in range(3,rows+1): + + cell_name = f'A{i}' + if dber.uid == sheet[cell_name].value: + flag = 1 + + list = [dber.uid, dber.name, dber.dob, dber.gender, dber.city, dber.state] + for j in range(2, 7): + cell = sheet.cell(row = i, column = j) + cell.value = list[j-1] + + break + + if flag == 0: + return render(request, "templates/failed_search.html") + + wb.save(document.path) + file.save() + #File Updation Ends + + return redirect('home') + + else: + p_form = DberUpdateForm(instance=dber) + + + context = { + 'p_form' : p_form + } + return render(request, 'templates/update_dber.html', context) + +@login_required +def delete_dber(request, pk): + + dber = get_object_or_404(Profile, pk = pk) + + # File updation begins + file = get_object_or_404(File, staff = request.user.profile) + document = file.doc + wb = openpyxl.load_workbook(document.path) + sheet = wb.get_sheet(0) + + rows = sheet.max_row + + flag = 0 + for i in range(3,rows+1): + cell_name = f'A{i}' + if dber.uid == sheet[cell_name].value: + flag = 1 + sheet.delete_rows(i, 1) + break + + Profile.objects.remove(dber) + + wb.save(document.path) + file.save() + #File Updation Ends + + return redirect('home') + +@login_required +def add_dber(request): + + if request.method == 'POST': + form = AddDberForm(request.POST) + + if form.is_valid(): + form.save() + dber_uid = form.cleaned_data['uid'] + + #new dber created in database + new_dber = Profile.objects.get_or_create(uid = dber_uid) + new_dber.name = form.cleaned_data['name'] + new_dber.dob = form.cleaned_data['dob'] + new_dber.gender = form.cleaned_data['gender'] + new_dber.city = form.cleaned_data['city'] + new_dber.state = form.cleaned_data['state'] + new_dber.city_circle = request.user.profile.city_circle + + new_dber.save() + + # File updation begins + file = get_object_or_404(File, staff = request.user.profile) + document = file.doc + wb = openpyxl.load_workbook(document.path) + sheet = wb.get_sheet(0) + + rows = sheet.max_row + cols = sheet.max_column + + sheet.insert_rows(3) #new dber insterted at top of sheet + + list = [new_dber.uid, new_dber.name, new_dber.dob, new_dber.gender, new_dber.city, new_dber.state] + for j in range(1, 7): + cell = sheet.cell(row = 3, column = j) + cell.value = list[j-1] + + + wb.save(document.path) + file.save() + #File Updation Ends + + else: + form = AddDberForm() + + return render(request, 'templates/add_dber.html', {'form':form}) + +@login_required +def send_mail(request, pk): + + dber = get_object_or_404(Profile, pk = pk) + if request.method == 'POST': + form = MailContentForm(request.POST) + + if form.is_valid(): + + form.save() + subject = form.cleaned_data['subject'] + content = form.cleaned_data['content'] + + mail = smtplib.SMTP(settings.EMAIL_HOST, settings.EMAIL_PORT) + mail.ehlo() + mail.starttls() + mail.login(settings.EMAIL_HOST_USER, settings.EMAIL_HOST_PASSWORD) + + message = f'**** SUBJECT : {subject} **** \n{content}\n\nRegards,\n{request.user.profile.name}' + + email = dber.user.email + try: + mail.sendmail(settings.EMAIL_HOST_USER, email, message) + except: + pass + + mail.close() + + else: + form = MailContentForm() + + return render(request, 'templates/mail_content.html', {'form':form}) + +@login_required +def send_mass_mails(request): + + if request.method == 'POST': + form = MailContentForm(request.POST) + + if form.is_valid(): + + form.save() + subject = form.cleaned_data['subject'] + content = form.cleaned_data['content'] + + mail = smtplib.SMTP(settings.EMAIL_HOST, settings.EMAIL_PORT) + mail.ehlo() + mail.starttls() + mail.login(settings.EMAIL_HOST_USER, settings.EMAIL_HOST_PASSWORD) + + message = f'**** SUBJECT : {subject} **** \n{content}\n\nRegards,\n{request.user.profile.name}' + + users = User.objects.all(profile) + for user in users: + if (user.profile.city_circle == request.user.profile.city_circle)&&(user.profile.qualifier == 0): + + email = user.email + try: + mail.sendmail(settings.EMAIL_HOST_USER, email, message) + except: + pass + + mail.close() + + else: + form = MailContentForm() + + return render(request, 'templates/mail_content.html', {'form':form}) diff --git a/dbportal/manage.py b/dbportal/manage.py new file mode 100644 index 0000000..bba21b4 --- /dev/null +++ b/dbportal/manage.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dbportal.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/dbportal/users/admin.py b/dbportal/users/admin.py new file mode 100644 index 0000000..e0406cb --- /dev/null +++ b/dbportal/users/admin.py @@ -0,0 +1,7 @@ +from django.contrib import admin +from .models import Profile + +admin.site.register(Profile) + + +# Register your models here. diff --git a/dbportal/users/apps.py b/dbportal/users/apps.py new file mode 100644 index 0000000..4ce1fab --- /dev/null +++ b/dbportal/users/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class UsersConfig(AppConfig): + name = 'users' diff --git a/dbportal/users/forms.py b/dbportal/users/forms.py new file mode 100644 index 0000000..7e3efa5 --- /dev/null +++ b/dbportal/users/forms.py @@ -0,0 +1,39 @@ +from django import forms +from django.contrib.auth.models import User +from django.contrib.auth.forms import UserCreationForm +from .models import Profile +from allauth.socialaccount.forms import SignupForm +from allauth.account.forms import LoginForm +from django.core import validators + +class RegForm(UserCreationForm): + email = forms.EmailField() + botcatcher = forms.CharField(required = False, widget = forms.HiddenInput, + validators = [validators.MaxLengthValidator(0)]) + + class Meta: + model = User + fields = ['username', 'email', 'password1', 'password2', 'botcatcher'] + + +class StaffUpdateForm(forms.ModelForm): + botcatcher = forms.CharField(required = False, widget = forms.HiddenInput, + validators = [validators.MaxLengthValidator(0)]) + + class Meta: + model = Profile + fields = ['uid', 'name', 'dob', 'gender', 'state', 'city', 'botcatcher'] + +class DberUpdateForm(forms.ModelForm): + botcatcher = forms.CharField(required = False, widget = forms.HiddenInput, + validators = [validators.MaxLengthValidator(0)]) + + class Meta: + model = Profile + fields = ['name', 'dob', 'gender', 'state', 'city', 'botcatcher'] + +class EmailChangeForm(forms.ModelForm): + + class Meta: + model = User + fields = ['email'] diff --git a/dbportal/users/models.py b/dbportal/users/models.py new file mode 100644 index 0000000..1e2d1b0 --- /dev/null +++ b/dbportal/users/models.py @@ -0,0 +1,33 @@ +from django.db import models +from django.contrib.auth.models import User +from PIL import Image +from django.dispatch import receiver +from django.db.models.signals import post_save +from django.utils import timezone +from django.urls import reverse + +sex_choices = [('MALE', 'Male'), ('FEMALE', 'Female'), ('OTHERS', 'Rather Not Say'),] + +class Profile(models.Model): + user = models.OneToOneField(User, on_delete=models.CASCADE) + uid = models.CharField(max_length=12) + name = models.CharField(max_length = 20) + dob = models.DateField(default = timezone.now) + gender = models.CharField(max_length = 6, choices = sex_choices, default = 1) + city = models.CharField(max_length = 20) + state = models.CharField(max_length = 20) + + city_circle = models.IntegerField(default=0) + qualifier = models.IntegerField(default = 0) # 1 - Staff 0 - DBer + + def profile_create_url(self): + return reverse('create_profile', kwargs={'pk': self.pk}) + + def __str__(self): + return f'{self.user.username} Profile' + + def save(self, *args, **kwargs): + super().save(*args, **kwargs) + + if self.qualifier == 0: + self.city_circle = ord(upper(self.city[0])) - 64 diff --git a/dbportal/users/tests.py b/dbportal/users/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/dbportal/users/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/dbportal/users/urls.py b/dbportal/users/urls.py new file mode 100644 index 0000000..009f0c9 --- /dev/null +++ b/dbportal/users/urls.py @@ -0,0 +1,13 @@ +from django.contrib import admin +from django.urls import path +from .views import register, update_staff, change_email, change_password +from django.contrib.auth import views as auth_views + +urlpatterns = [ + path('register/', register, name='register'), + path('update_staff/', update_staff, name='update_staff'), + path('login/', auth_views.LoginView.as_view(template_name='templates/login.html'), name='login'), + path('logout/', auth_views.LogoutView.as_view(template_name='templates/logout.html'), name='logout'), + path('change_email/', change_email, name='change_email'), + path('change_password/', change_password, name='change_password'), +] diff --git a/dbportal/users/views.py b/dbportal/users/views.py new file mode 100644 index 0000000..c0e2390 --- /dev/null +++ b/dbportal/users/views.py @@ -0,0 +1,85 @@ +from django.shortcuts import render +from django.contrib.auth.decorators import login_required +from django.contrib import messages +import requests +from django.shortcuts import render, get_object_or_404, redirect +from django.contrib.auth.decorators import login_required +from .forms import RegForm, StaffUpdateForm, DberUpdateForm, EmailChangeForm +from django.contrib.auth import update_session_auth_hash +from django.contrib.auth.forms import PasswordChangeForm + +def register(request): + if request.method == 'POST': + form = RegForm(request.POST) + if form.is_valid(): + form.save() + username = form.cleaned_data.get('username') + pwd = form.cleaned_data.get('password1') + messages.success(request, f'Account created successfully for {username}') + + Profile.objects.get_or_create(user = request.user) + + user = authenticate(username = username, password = pwd) + login(request, user) + + return redirect('home') + else : + form = RegForm() + + return render(request, 'templates/register.html', {'form' : form}) + +@login_required +def update_staff(request): + + if request.method == 'POST': + p_form = StaffUpdateForm(request.POST, + instance=request.user.profile) + + if p_form.is_valid(): + request.user.profile.save() + p_form.save() + + else: + p_form = StaffUpdateForm(instance=request.user.profile) + + context = { + 'p_form' : p_form + } + return render(request, 'templates/update_staff.html', context) + + +def change_password(request): + if request.method == 'POST': + form = PasswordChangeForm(request.user, request.POST) + if form.is_valid(): + user = form.save() + update_session_auth_hash(request, user) + return redirect('home') + + else: + form = PasswordChangeForm(request.user) + return render(request, 'templates/change_password.html', { + 'form': form + }) + +@login_required +def change_email(request): + + user = request.user + if request.method == 'POST': + form = EmailChangeForm(request.POST) + if form.is_valid(): + form.save() + + user.email = form.cleaned_data['email'] + user.save() + + return redirect('change_email') + + else: + form = EmailChangeForm() + + return render(request, 'templates/change_email.html', { + 'form': form + }) +# Create your views here. From a5784d5ddca8733c8f2cbbb0c040e881dab97461 Mon Sep 17 00:00:00 2001 From: Sankha Das <54751139+sankha555@users.noreply.github.com> Date: Mon, 30 Dec 2019 19:32:09 +0530 Subject: [PATCH 2/4] frontend changes added --- db.sqlite3 | Bin 0 -> 241664 bytes dbportal/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 143 bytes dbportal/__pycache__/settings.cpython-37.pyc | Bin 0 -> 4105 bytes dbportal/__pycache__/urls.cpython-37.pyc | Bin 0 -> 999 bytes dbportal/__pycache__/wsgi.cpython-37.pyc | Bin 0 -> 548 bytes dbportal/settings.py | 195 ++++++++++++++++++ dbportal/urls.py | 23 +++ dbportal/wsgi.py | 16 ++ manage.py | 21 ++ users/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 140 bytes users/__pycache__/admin.cpython-37.pyc | Bin 0 -> 254 bytes users/__pycache__/apps.cpython-37.pyc | Bin 0 -> 354 bytes users/__pycache__/forms.cpython-37.pyc | Bin 0 -> 2221 bytes users/__pycache__/models.cpython-37.pyc | Bin 0 -> 1651 bytes users/__pycache__/urls.cpython-37.pyc | Bin 0 -> 715 bytes users/__pycache__/views.cpython-37.pyc | Bin 0 -> 2145 bytes users/admin.py | 7 + users/apps.py | 5 + users/forms.py | 39 ++++ users/migrations/0001_initial.py | 33 +++ .../__pycache__/0001_initial.cpython-37.pyc | Bin 0 -> 1243 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 151 bytes users/models.py | 33 +++ users/templates/users/change_email.html | 36 ++++ users/templates/users/change_password.html | 36 ++++ users/templates/users/login.html | 42 ++++ users/templates/users/logout.html | 38 ++++ users/templates/users/register.html | 45 ++++ users/templates/users/update_staff.html | 40 ++++ users/tests.py | 3 + users/urls.py | 13 ++ users/views.py | 85 ++++++++ 32 files changed, 710 insertions(+) create mode 100644 db.sqlite3 create mode 100644 dbportal/__pycache__/__init__.cpython-37.pyc create mode 100644 dbportal/__pycache__/settings.cpython-37.pyc create mode 100644 dbportal/__pycache__/urls.cpython-37.pyc create mode 100644 dbportal/__pycache__/wsgi.cpython-37.pyc create mode 100644 dbportal/settings.py create mode 100644 dbportal/urls.py create mode 100644 dbportal/wsgi.py create mode 100644 manage.py create mode 100644 users/__pycache__/__init__.cpython-37.pyc create mode 100644 users/__pycache__/admin.cpython-37.pyc create mode 100644 users/__pycache__/apps.cpython-37.pyc create mode 100644 users/__pycache__/forms.cpython-37.pyc create mode 100644 users/__pycache__/models.cpython-37.pyc create mode 100644 users/__pycache__/urls.cpython-37.pyc create mode 100644 users/__pycache__/views.cpython-37.pyc create mode 100644 users/admin.py create mode 100644 users/apps.py create mode 100644 users/forms.py create mode 100644 users/migrations/0001_initial.py create mode 100644 users/migrations/__pycache__/0001_initial.cpython-37.pyc create mode 100644 users/migrations/__pycache__/__init__.cpython-37.pyc create mode 100644 users/models.py create mode 100644 users/templates/users/change_email.html create mode 100644 users/templates/users/change_password.html create mode 100644 users/templates/users/login.html create mode 100644 users/templates/users/logout.html create mode 100644 users/templates/users/register.html create mode 100644 users/templates/users/update_staff.html create mode 100644 users/tests.py create mode 100644 users/urls.py create mode 100644 users/views.py diff --git a/db.sqlite3 b/db.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..3c5e97c44202bfd2bfac9499e622df33b9430465 GIT binary patch literal 241664 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 H8HgDGgK8p6 literal 0 HcmV?d00001 diff --git a/dbportal/__pycache__/settings.cpython-37.pyc b/dbportal/__pycache__/settings.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4693522d1835ec749e566522111f9134e05b8dc7 GIT binary patch literal 4105 zcmb6c*>=-N){EjTaiBxk>Bh|x2oRYi(9qM+D7F$j@pdc+rt6_Kif=_JqQ$L}Iz->X znKL}h!+g!W>vf*`7v^bh$#Pj6aJA zyv8s8YdV#J6iGoEGFF+8r z42y6E&cZjaWG<2toP%XJ4;SDfT!PDHp3K7)vH(}%8hi`i!F8y>_izJlek_nO+#-u` z+f0E3D{u$y!YbS|C6O1c#M>f;7R;m zkKa#O+LXvSct)1t2XY>5zJTA0_`L+r;RXB%e=@W16TF01@H4yy#mvD5)R4FSF^f_! zgG#QzCbbpZW;MK9k)sc9ApH}t)%c@w6`xSTZa}vJi0fb=ns*p?eMW<2XKFV5UlfGKip!T?szw?7q<^zKY9F;zj*oV!~MG} zPkr4m-G{5Uy?X~w_4R&uA>h>GvN0TTc}IXX*V$ucctIRL!EXvM!7q=_FArSD_t>r+ z`#L-~jSc+$@ahy&uu#YMkA{?o7pFEknP?e<{W}BUCew9Ii;{(b$N2C_7fHjzwZt%+ z0a*0V@Tkn`An=%fBx?!KI^GM{r_Yg`T%O?9Mz{&C)i0G`?%A#**W!O)A?4nlT*KE} zMh_=Qf0(jGcx%!Q1=kodHi%1Of^qr~<0wrsw?>hh;CeRW5EdI8yf+31Sf27b1)}z=nJ|nz$3c_uA6ze{w{VbIem(&@@s&lYc z3fk2|G-nAXksOa*L5c=|PQ{7InL&ImeV81KETB~h}>c}d6fL&G|vLUsYgXIxdogQaf0t5BY3Lf4+EknQ{T>C1qP@$tY-9rlDgRhb& z1fnN~D>JFZmTaOY1mIw{hR?d58+V~mhm;2a_t6&#cWl7%!3Q42VHNY9!ZjEP;ixgg z!Jwpe>H~!ZVg!%f|>D8nzeQFOa)FcDFJWS@XF=QNb!mbLhRYhit`4b#3xbKjh>xj;`nk92utVz<}XY&2DUv!OQY8ktvi`fv2E(o|o88n@W3YN7+*KTBk0= zHd?AqI;f$rgJ)|zdfpyE%|{R0QBL6cgj^iiG&U4N`nFM5dm71WjXrYKqq5pk8cjWE zFi~l=>~?zn=*$QfZqZR*FFH4Y=qe){#{y!7O>`GJuivN%Cq-vRu*f29)UQe{wcb#4 z;l`*qf{~Cc*Ln@D`-?vI6{cBjJ6dXXunXxuWa+83*zZwsghQr(raT#wA%6Ymd36Vi zidSvJVF#9Bfx)YF$`9}-Pj%cGPXN3p#J}0(;Zaoh$#x;I=&N}Y#{Y&dDO1Q^%S%}) zBjqybsV9@HGdXE;CzqA7lj}^nAW7vIGv-Jy=A^v9ESGXw@stXvVe}wx;g~Lyma>at RFP%K7>TGr~EzJqse*t(Oe53#X literal 0 HcmV?d00001 diff --git a/dbportal/__pycache__/urls.cpython-37.pyc b/dbportal/__pycache__/urls.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9d5d759c6eff64f4d06372c527eca7374e051e9b GIT binary patch literal 999 zcma)5O^?$s5KYqbE8PWtf^Ti45{rsc1uI}-VWkxZU@tw;bz`@6H@1WA0Nd;S8Td=N za^k=r;KbNXMTLa4mg-DL<2UcUv0oe?CjqQq-})b4w}Rk@`?Fsi2%f>uT);+ySwKS? z6`_b`QRw1U(Gu}27VTL(3|LHK7HvA4?rj8do3&}@HuP~9;+~6Ftyz!u-v?(5aG3zN$2_T*)N)ux9A0(nU$EWm=jmRB&UFR+VMO9Wcl$^qI3SCPQaR zBcU`yTrQOs9s-pGBZeWv*fc?~*4CD0iZNBW$>@g2l`6H`u-s<35|~Lm$tKvUlII4y zVhrsKPF{T_0OFO9lZ4 z3gIY-U5|#taieRk1REns1baGk@i0wJ3u4T}1qh=DsQ+W3?3!suB=bh?>AV3f&;E{V zTzy8&+<}bJe;A$1yr?LbD=@+LbJB7c=H8!kZwvw|FdkRSMk!i0R!(d zbuvxj-O;q}OgjmIWSM^7k*VCdqcQ8;km;_Z6Vl(k{*`^63`eX)GglRxqh<1}LFWlouLaXjp+}D`C~TWJC>;&1Rx$v?_&H zXlApB_aV~MXn`pc8S8a{p^4zivANRloH>AO;eF#?b1t!Txm*fU;Z{?LH3!4@^L@U+ zOOISaqw%T+nGdsa|hllQ@MUObc-TtD2hPQg~uBuc^L=DTU<*cQ|N+ODT^j#u~EWYTxcI2+@t(K zZ2OIC_xBY)bzmK@g;D2PXek^YfIIit@U4RXLCcaiSE2W2v*)+H2;^Fq(jI+CAJKow CPpmNj literal 0 HcmV?d00001 diff --git a/dbportal/settings.py b/dbportal/settings.py new file mode 100644 index 0000000..190f29c --- /dev/null +++ b/dbportal/settings.py @@ -0,0 +1,195 @@ +""" +Django settings for dbportal project. + +Generated by 'django-admin startproject' using Django 2.2.4. + +For more information on this file, see +https://docs.djangoproject.com/en/2.2/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/2.2/ref/settings/ +""" + +import os + +# Build paths inside the project like this: os.path.join(BASE_DIR, ...) +BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'nmud+4cu4s^x$ir_nr#l9%w@32=s9=6x+(&5t_ago0)%r*k5_4' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + 'users.apps.UsersConfig', + 'files.apps.FilesConfig', + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'django.contrib.sites', + + 'allauth', + 'allauth.account', + 'allauth.socialaccount', + 'allauth.socialaccount.providers.google', + + 'crispy_forms', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'dbportal.urls' + +ACCOUNT_FORMS = { + 'login': 'allauth.account.forms.LoginForm', + 'signup': 'allauth.account.forms.SignupForm', + 'add_email': 'allauth.account.forms.AddEmailForm', + 'change_password': 'allauth.account.forms.ChangePasswordForm', + 'set_password': 'allauth.account.forms.SetPasswordForm', + 'reset_password': 'allauth.account.forms.ResetPasswordForm', + 'reset_password_from_key': 'allauth.account.forms.ResetPasswordKeyForm', + 'disconnect': 'allauth.socialaccount.forms.DisconnectForm', +} + +SOCIAL_AUTH_PIPELINE = ( + 'social_core.pipeline.social_auth.social_details', + 'social_core.pipeline.social_auth.social_uid', + 'social_core.pipeline.social_auth.auth_allowed', + 'social_core.pipeline.social_auth.social_user', + 'social_core.pipeline.user.get_username', + 'ProfilesConfig.custom_social_auth_pipeline.create_user', + 'social_core.pipeline.social_auth.associate_user', + 'social_core.pipeline.social_auth.load_extra_data', + 'social_core.pipeline.user.user_details', +) + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'dbportal.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/2.2/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + } +} + + +# Password validation +# https://docs.djangoproject.com/en/2.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', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/2.2/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_L10N = True + +USE_TZ = True + +SOCIALACCOUNT_PROVIDERS = { + 'google': { + 'SCOPE': ['profile', 'https://www.googleapis.com/auth/userinfo.profile','https://www.googleapis.com/auth/plus.login'], + 'PROFILE_FIELDS': [ + 'id', + 'first-name', + 'last-name', + 'email-address', + 'picture-url', + 'public-profile-url', + ], + 'AUTH_PARAMS': { + 'access_type' : 'online', + #'hd' : 'pilani.bits-pilani.ac.in', + } + } +} + +#Email information + +SITE_ID = 1 + +EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' +EMAIL_PORT = 587 +EMAIL_HOST_USER = '############' +EMAIL_HOST_PASSWORD = '############' +EMAIL_USE_TLS = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/2.2/howto/static-files/ + +STATIC_URL = '/static/' +STATICFILES_DIRS = [ + os.path.join(BASE_DIR, "static"), +] + +MEDIA_ROOT = os.path.join(BASE_DIR, 'media') +MEDIA_URL = '/media/' + +#TEMPLATES_ROOT = os.path.join(BASE_DIR, 'templates') +#TEMPLATES_URL = '/templates/' + +CRISPY_TEMPLATE_PACK = 'bootstrap4' + +LOGIN_REDIRECT_URL = 'home' +LOGIN_URL = 'login' diff --git a/dbportal/urls.py b/dbportal/urls.py new file mode 100644 index 0000000..92b2552 --- /dev/null +++ b/dbportal/urls.py @@ -0,0 +1,23 @@ +"""dbportal URL Configuration + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/2.2/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path, include + +urlpatterns = [ + path('admin/', admin.site.urls), + path('', include('files.urls')), + path('users/', include('users.urls')), +] diff --git a/dbportal/wsgi.py b/dbportal/wsgi.py new file mode 100644 index 0000000..472843a --- /dev/null +++ b/dbportal/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for dbportal project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dbportal.settings') + +application = get_wsgi_application() diff --git a/manage.py b/manage.py new file mode 100644 index 0000000..bba21b4 --- /dev/null +++ b/manage.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dbportal.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/users/__pycache__/__init__.cpython-37.pyc b/users/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..76fa8d26dd0c240d89cf8b2a977fd15e730d9933 GIT binary patch literal 140 zcmZ?b<>g`kg0q)d;z0Cc5CH>>K!yVl7qb9~6oz01O-8?!3`HPe1o6vMKeRZts8~NY zF)uSaCov}_u~^?FwK%&Zzd%1FsUW|oBr!+76s#mZJ~J<~BtBlRpz;=nO>TZlX-=vg K$hgly%m4sSa3PWa literal 0 HcmV?d00001 diff --git a/users/__pycache__/admin.cpython-37.pyc b/users/__pycache__/admin.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f57fab6ea28b0ebb64b99390e0f61bf2447296b6 GIT binary patch literal 254 zcmXv|yH3O~5cI~$5urQ2gEVJ}8X<(J5fY+F0rIiS$#-@f?fMG%8Yuatv{d&CRM9?+;D_Hc5=`0)p@$>7X2CS?68gNmpCML8?LftT7-z?h3i6UafzmuY3n2r ze<^OWJhz_<^C-k(f*su6TaQ-EEy+H`(cor`oUAv8*)k_sk8e|ZnXex_U6nLaUMyi* F{Q_#lK#l+a literal 0 HcmV?d00001 diff --git a/users/__pycache__/apps.cpython-37.pyc b/users/__pycache__/apps.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e878f2c0fe0de0c5c74b4e243d14edfe2757285d GIT binary patch literal 354 zcmYLEJ5B>J5FM`_X%iBOBhYRWi#|f(BhjTnX?LBPdGp3^e!iN`CP4P_Del)4zfy8EL1alD&j=8ZIjEUp3~m7neA@Im53@a@4knRiGN wLY#+}mQ!>3aV!W*mh)A*3!hB0_48EMCM_%fy9PEUp)VK1ffwnodCrvo0y~UR(f|Me literal 0 HcmV?d00001 diff --git a/users/__pycache__/forms.cpython-37.pyc b/users/__pycache__/forms.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fd188ac47160290c21e69db79615884056c939ca GIT binary patch literal 2221 zcmcIl&5j#I5T2g@8UL);y8)8$mjsY}u|>o&idG~nAZ1sGRXB_ithT#7JDZ*vr+bDZ zdkt4!0d0;v0q@dRPI(1RRQ1@qw%H&+FxHf-tGlbJ>-)Oq^G+wW;Q94&`28c#vVOzC z@^L}ggIE0wf?13RD<=sdsN2HMoy0M^Bi!6eJkVX{2|o{#z}S5e=1~$EJrHr;N?Jw_ zMLX{#9b$cHv53V#S}f+?ODE~VxW(EqZgX<71(qIII;;zp?!vMSmMzu;OK)N6v+W~m z(0>g%S_7iJSt)Y`iu+J;3I9F(zb84Zva;BR$=9S=8GIwlStdBFiI1|hsOLBfqv%1I zW@af){Xj*=XjMuz#SqKK2W1albq55u62h#+=FXY>%1S)$ocN4@40w1JG5Zxs33GmO zk{Hs5B0>7zOFL;XA5sr=@GVa<_P#W!IXaa5X`M;VwErw)DX(M%QP$!ESWW!**WxEG zBg|$FMo9sbCcb3AYmetN6FQnxrJj|NeR`qZ*72mQrnH(Kb9p%M zbvPd5p7B`6<8fZHTA{DpQg=PtNVNXU@5L|z5uaL|^0bi9LN7ljQ% z$6w%)_A$1^T{^mVOr;s?)>j#0y!g79*G)-v|A0P!z>Bmx{%(o0+(us*;v(@zdk1ZJ zUl0uyf(S`SV$!pXbq$|$etZVYF8FZ*_y8|F?wN^t7oF~IL}@tU)EU#RA&JAviS|=oFfO&H zD#%8=)2w=7Dh1To!~xGPub_Af#X0;dRmAe5eG}7o(-&eYucLSu1)f*FhvKhM!drpF zP?*aCBeebJ7DZ#e_s*Piw-^wb$jo4P0k4ZnGinr}GNcl~~cz@Ts9pZ*L8`3sfx0G&LA zR~rzVa4Jbb6G{<#(kuMLci5Lf5hkI-fov5~5;+{oxM(MBhg-5!bd#>bk?a-yqz^de zZQhyr$>4j!yS#Tpcu&x?;kBP^@cs!I4OZ}FGNQIsR9r|6DELte1#@^*q%#2^Rw5Jm zTW4%9Ds7lf-#UlM3vpSMh$AH+LW_}?1kZP$9e_+FYOTWqr?(D8(O6!*{^8)&$>rcx zYUV=i99L%NB)!Nmll2H2pnnG-NJ2SDJmH@OA_Upu^wvuvKr#2Ye@m0L!-2ycz+KTh z>+=vi1LtXpA&+=`3%u_{-n)Z00pEve;hG0`@I&6=-5ZiT;yvDn`SAyGO8I~fZ{lR@ z0|`j-1nRh9qnD~W&4Dtt?W$x@Oku>T2kC>QQ>5>i6y?m!R}X4a#Kmd4lxEceeMQme zD-5?$Hm~wbXf*&$p(jIu17~cSJ$Usd2m?*Sy(@A?a|+}=NF_K<2ALA65o}SXWWB{X zB+)v5m#Uc_c`AmL3YUX5&_bU6LDWM~|Nd%%hp#6^TIT06l|0pxeWA}ywV3efqEaT6 zlVu&^`enShu$#?iSo77Tl8<3C?SUZla=R(a`2S)5;f3Lj7t#hs!0A_D_ZxEZjxXb# zW}lH~15CljD9f~fk}E8#qfm=SpxTHrZ4_hMpsbS_u9IneA2aYF2rE0p;IBa#at#?= z(JSv4xR8*K$LYDJzBIlGKnpp2LaymGRDTP+ti=iB=^wlET0MmgMv)Emasi13cwcP$ z=VdDM(;N(brML~33+K#ob78wES(d8|I>>i)Y=Ebw?&DU_Q;cOY)ta$?8LCgfhp)yS zB6Q$&=w)xs&|T7P8#9JAV$60JgG;`Yh23c-DPC6~4s#*7!h+anZ}((x zcmF_bq1N7;r^9O>RsaVYHGV$yk|`_C#{(%xlrmej0v@Y zMYeZT8Zi^~p6YY(s83N~`zSm%$I$j0?wOEs%^%wp&ixAv!qZl55M6jRrW(@?+Jk3M z&mLee_G8~g9gptWHa||cnArPA%*NVM4a;kiV4qoahxAZD51I~u$b5- zvK6u`&z?-|DNo^S!cTYxPaWPT^#ax(gUz!$tTNaT8#9niiy-QmIouJ)MmAG?-)O^? zEr%YM;X7^E<)tkz4y@ht9ha;Tb~$N1)B2`U;KE%u{6>%YgFjXAeV(Xgl8@EnXjCO= z8xzs(o0g8NL35?4*R}^E1%|5(m%VWLox6>_aZK^*21Cb_zb>eHAM2u_GFFc(r7Crq zR{zyYRfhD3&C)L5h<$b2i>@`QIaj#cz|JRfP(rH^8I?QX8uFF``3TV26M25 zlRG~Uo4I?qMI2W9OCn~v==>eD9T~|Hhw+5la;}j`rg{E*9Q9-<4@zJQ}3c zfeC;uH^wHsFJb4ruKMX%4f=yr4q$9`CzbNJ7VK(9hI``W&z?un%ip1yI77(AAr-$V z0ydqJQ!*jv?u8@Hp!Y5u;!McUKMxqaAg6R@yI{L2JdY+0^Ct8U=TCY;iK80Bc(?@X zG@1Vja;sVsI&oR>ik^C^J#i-96r(yUoRVFq3KW?-r$jBoDiLc;NKU3MpdN2)Z|D2n zA9XaATvTbvbz?L;)aNJfJi%kH*!T=WL2EVKtR%kGK}O0EVq6A{c5Z8JTW{iC$Vnf7FQ#C0<( zcv^ARhm57#gQAjw_$OjrdwZ8MfQpxsJ+r-;gpd52C`KMHcmQaQU{q0p|5X`a zZSw*8n~R&g3m&-&jpN27AWe#p#ctb;sOW^d-btbbwB6Lnt7YK}viKV{b?21&km%KpAI9Of`C{DAES1 z5uH%1LSh?wpc7OhI)qwu7phV}w3tCfi5SG1ibA2HP}M*hF@Hj56(z7#(muyh3JSIe znYTHY7JUnl#TF>TDiq93$TraT2{!-3%|K?rL#N_+~h58;tWN5>83@&nmLGVDmm1JH6dR?_}q-kG_Pvm)Q?VJ+z~p4B2%wU7dps@vCtY?T7_o2nuO z($jpj_EA&PmOP^z{ErJftzNsnhS^9UP4wNjjP&e6hF@4Yj3!L#&3P91V-PX=iXN0T c8yEa*{7FfK6N?ZaLDr$&K$}ME&Go4LAJPi~a{vGU literal 0 HcmV?d00001 diff --git a/users/admin.py b/users/admin.py new file mode 100644 index 0000000..e0406cb --- /dev/null +++ b/users/admin.py @@ -0,0 +1,7 @@ +from django.contrib import admin +from .models import Profile + +admin.site.register(Profile) + + +# Register your models here. diff --git a/users/apps.py b/users/apps.py new file mode 100644 index 0000000..4ce1fab --- /dev/null +++ b/users/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class UsersConfig(AppConfig): + name = 'users' diff --git a/users/forms.py b/users/forms.py new file mode 100644 index 0000000..7e3efa5 --- /dev/null +++ b/users/forms.py @@ -0,0 +1,39 @@ +from django import forms +from django.contrib.auth.models import User +from django.contrib.auth.forms import UserCreationForm +from .models import Profile +from allauth.socialaccount.forms import SignupForm +from allauth.account.forms import LoginForm +from django.core import validators + +class RegForm(UserCreationForm): + email = forms.EmailField() + botcatcher = forms.CharField(required = False, widget = forms.HiddenInput, + validators = [validators.MaxLengthValidator(0)]) + + class Meta: + model = User + fields = ['username', 'email', 'password1', 'password2', 'botcatcher'] + + +class StaffUpdateForm(forms.ModelForm): + botcatcher = forms.CharField(required = False, widget = forms.HiddenInput, + validators = [validators.MaxLengthValidator(0)]) + + class Meta: + model = Profile + fields = ['uid', 'name', 'dob', 'gender', 'state', 'city', 'botcatcher'] + +class DberUpdateForm(forms.ModelForm): + botcatcher = forms.CharField(required = False, widget = forms.HiddenInput, + validators = [validators.MaxLengthValidator(0)]) + + class Meta: + model = Profile + fields = ['name', 'dob', 'gender', 'state', 'city', 'botcatcher'] + +class EmailChangeForm(forms.ModelForm): + + class Meta: + model = User + fields = ['email'] diff --git a/users/migrations/0001_initial.py b/users/migrations/0001_initial.py new file mode 100644 index 0000000..9a0b3e4 --- /dev/null +++ b/users/migrations/0001_initial.py @@ -0,0 +1,33 @@ +# Generated by Django 2.2.4 on 2019-12-30 06:54 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Profile', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('uid', models.CharField(max_length=12)), + ('name', models.CharField(max_length=20)), + ('dob', models.DateField(default=django.utils.timezone.now)), + ('gender', models.CharField(choices=[('MALE', 'Male'), ('FEMALE', 'Female'), ('OTHERS', 'Rather Not Say')], default=1, max_length=6)), + ('city', models.CharField(max_length=20)), + ('state', models.CharField(max_length=20)), + ('city_circle', models.IntegerField(default=0)), + ('qualifier', models.IntegerField(default=0)), + ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/users/migrations/__pycache__/0001_initial.cpython-37.pyc b/users/migrations/__pycache__/0001_initial.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2b50d719cceab53dba6d32655a1b62330ec965cd GIT binary patch literal 1243 zcmY*Z&2rl|5aypKQlexhmSd+)JGts2x!1PSiDJo3W@5Wz*%uzlfw(IfG=EfpYARpb ztDd3lv9E;bttY)gPhC({ItB-;{T91e?6-j4b~-JC#>wygkEad8_(y~Na7cMWQ@$ku z2AHXlnW1TF-Ab*@4(-edoeJA&BXr4br_Ip)-T((0zZuX#JMn(CLl5k!(Ra7BkI^@k zC$TJfzL0%OwKBdCtmH*5m75iSsl1A{-+mmD@`k4Tn*9bP^`pAkBu9KEEK949aInc?$|HMbTmc(t+U^e6BI z@$;qfFZX2Js^$-(nDZ2s#oXjT5(Q@|e?%4h zjAB+ujB=KtvR53o0dYsfw=(uilw!Up@0Fuhw>?@=HWV{jZ352ODlL_}z#LFecbv=7 zhY3lRA|dx;QepQ3v)Xcf`)+bGeeB+_@*c(OtD<~8W$Ud;+iqQ*)K<;-zTh!RaYR@g z=!8zp%e89AlIl=x4WgKfI7OiYmH*R%2`oel-e)yi0%fGzf~4}OXzE%T=Gdl zUiD9v7ggm(k!nQ|-J?~Cqz6%?_tK>jYVw?yM3S&|a8G_@%O#tUBj8e3oX2Zn>7|3w z-R-;RZaTS%F0aRv4=VWN!BMLAdDVeSeOrZoCCVRBV=nYzlz)EDM6HggzMbkq!tzC- z8mp40Qh6oM@Uh6LJ$dm_1@H3`7g&dNu5-LCNbEu_m?^KSogRs5o{y&Iqwz$wiY3+$ z=PyHiO{b{DzvJN@Q6`5O%lSjfQebj8M)^<{%OT8`g(z7%)U1-r{jlEvsjC>Fb%N)vwko&%UqPy8;Jsk6S{5L|`78p6S{D0se4jp8x;= literal 0 HcmV?d00001 diff --git a/users/migrations/__pycache__/__init__.cpython-37.pyc b/users/migrations/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0090db3b5724d1abe7a7e0d943bac7afb4b6b674 GIT binary patch literal 151 zcmZ?b<>g`kg0q)d;z0Cc5CH>>K!yVl7qb9~6oz01O-8?!3`HPe1o6v3KeRZts8~NY zF)uSaCov}_u~^?FwK%&Zzd%1FsUW|oBr!+76rv<{9 literal 0 HcmV?d00001 diff --git a/users/models.py b/users/models.py new file mode 100644 index 0000000..1e2d1b0 --- /dev/null +++ b/users/models.py @@ -0,0 +1,33 @@ +from django.db import models +from django.contrib.auth.models import User +from PIL import Image +from django.dispatch import receiver +from django.db.models.signals import post_save +from django.utils import timezone +from django.urls import reverse + +sex_choices = [('MALE', 'Male'), ('FEMALE', 'Female'), ('OTHERS', 'Rather Not Say'),] + +class Profile(models.Model): + user = models.OneToOneField(User, on_delete=models.CASCADE) + uid = models.CharField(max_length=12) + name = models.CharField(max_length = 20) + dob = models.DateField(default = timezone.now) + gender = models.CharField(max_length = 6, choices = sex_choices, default = 1) + city = models.CharField(max_length = 20) + state = models.CharField(max_length = 20) + + city_circle = models.IntegerField(default=0) + qualifier = models.IntegerField(default = 0) # 1 - Staff 0 - DBer + + def profile_create_url(self): + return reverse('create_profile', kwargs={'pk': self.pk}) + + def __str__(self): + return f'{self.user.username} Profile' + + def save(self, *args, **kwargs): + super().save(*args, **kwargs) + + if self.qualifier == 0: + self.city_circle = ord(upper(self.city[0])) - 64 diff --git a/users/templates/users/change_email.html b/users/templates/users/change_email.html new file mode 100644 index 0000000..cea4777 --- /dev/null +++ b/users/templates/users/change_email.html @@ -0,0 +1,36 @@ +{% extends "files/base.html" %} +{% load crispy_forms_tags %} +{% block content %} +
+
+
+
+

Reset Email

+

Change Your Email Account Linked to DBPortal

+
+
+
+
+ + +
+
+
+
+ {% csrf_token %} +
+ Change Email + {{ form|crispy }} +
+
+ +
+
+
+ +
+
+ + + +{%endblock content%} diff --git a/users/templates/users/change_password.html b/users/templates/users/change_password.html new file mode 100644 index 0000000..df383e5 --- /dev/null +++ b/users/templates/users/change_password.html @@ -0,0 +1,36 @@ +{% extends "files/base.html" %} +{% load crispy_forms_tags %} +{% block content %} +
+
+
+
+

Reset Password

+

Change Your Account Password Linked to DBPortal

+
+
+
+
+ + +
+
+
+
+ {% csrf_token %} +
+ Change Password + {{ form|crispy }} +
+
+ +
+
+
+ +
+
+ + + +{%endblock content%} diff --git a/users/templates/users/login.html b/users/templates/users/login.html new file mode 100644 index 0000000..d8c2637 --- /dev/null +++ b/users/templates/users/login.html @@ -0,0 +1,42 @@ +{% extends "files/base.html" %} +{% load crispy_forms_tags %} +{% block content %} +
+
+
+
+

User Login

+

Login to Your DBPortal Account

+
+
+
+
+ + +
+
+
+
+ {% csrf_token %} +
+ Log In + {{ form|crispy }} +
+
+ +
+
+
+
+ + Don't have an account ? + Sign Up + + +
+
+
+ + + +{%endblock content%} diff --git a/users/templates/users/logout.html b/users/templates/users/logout.html new file mode 100644 index 0000000..cfdd360 --- /dev/null +++ b/users/templates/users/logout.html @@ -0,0 +1,38 @@ +{% extends "files/base.html" %} +{% block content %} + +
+
+
+
+

Logged Out

+

+ You Have been successfully logged out +

+
+
+
+
+ +
+
+
+ +
+
+
+
+

You have been successfully logged out

+ + Log In Again + +
+
+
+
+ +
+
+
+ +{% endblock content %} diff --git a/users/templates/users/register.html b/users/templates/users/register.html new file mode 100644 index 0000000..6c34a17 --- /dev/null +++ b/users/templates/users/register.html @@ -0,0 +1,45 @@ +{% extends "files/base.html" %} +{% load crispy_forms_tags %} +{% block content %} + + +
+
+
+
+

Register

+

+ Register a New User +

+
+
+
+
+ +
+
+
+
+
+ {% csrf_token %} +
+ Join Today + {{ form|crispy }} +
+
+ +
+
+
+ + Already have an Account? Sign In +    Register an organization? + Register + +
+
+
+
+
+ +{% endblock content %} diff --git a/users/templates/users/update_staff.html b/users/templates/users/update_staff.html new file mode 100644 index 0000000..e6b8af7 --- /dev/null +++ b/users/templates/users/update_staff.html @@ -0,0 +1,40 @@ +{% extends "files/base.html" %} +{% load crispy_forms_tags %} +{% block content %} + +
+
+
+
+

User Profile

+

+ Update the User Profile of the Staff +

+
+
+
+
+ +
+
+
+ +
+ {% csrf_token %} +
+ Profile Info +
+ + {{ p_form|crispy }} +
+
+
+ +
+
+
+
+
+ + +{% endblock content %} diff --git a/users/tests.py b/users/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/users/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/users/urls.py b/users/urls.py new file mode 100644 index 0000000..09e8b1a --- /dev/null +++ b/users/urls.py @@ -0,0 +1,13 @@ +from django.contrib import admin +from django.urls import path +from .views import register, update_staff, change_email, change_password +from django.contrib.auth import views as auth_views + +urlpatterns = [ + path('register/', register, name='register'), + path('update_staff/', update_staff, name='update_staff'), + path('login/', auth_views.LoginView.as_view(template_name='users/login.html'), name='login'), + path('logout/', auth_views.LogoutView.as_view(template_name='users/logout.html'), name='logout'), + path('change_email/', change_email, name='change_email'), + path('change_password/', change_password, name='change_password'), +] diff --git a/users/views.py b/users/views.py new file mode 100644 index 0000000..bbf4792 --- /dev/null +++ b/users/views.py @@ -0,0 +1,85 @@ +from django.shortcuts import render +from django.contrib.auth.decorators import login_required +from django.contrib import messages +import requests +from django.shortcuts import render, get_object_or_404, redirect +from django.contrib.auth.decorators import login_required +from .forms import RegForm, StaffUpdateForm, DberUpdateForm, EmailChangeForm +from django.contrib.auth import update_session_auth_hash +from django.contrib.auth.forms import PasswordChangeForm + +def register(request): + if request.method == 'POST': + form = RegForm(request.POST) + if form.is_valid(): + form.save() + username = form.cleaned_data.get('username') + pwd = form.cleaned_data.get('password1') + messages.success(request, f'Account created successfully for {username}') + + Profile.objects.get_or_create(user = request.user) + + user = authenticate(username = username, password = pwd) + login(request, user) + + return redirect('home') + else : + form = RegForm() + + return render(request, 'users/register.html', {'form' : form}) + +@login_required +def update_staff(request): + + if request.method == 'POST': + p_form = StaffUpdateForm(request.POST, + instance=request.user.profile) + + if p_form.is_valid(): + request.user.profile.save() + p_form.save() + + else: + p_form = StaffUpdateForm(instance=request.user.profile) + + context = { + 'p_form' : p_form + } + return render(request, 'users/update_staff.html', context) + + +def change_password(request): + if request.method == 'POST': + form = PasswordChangeForm(request.user, request.POST) + if form.is_valid(): + user = form.save() + update_session_auth_hash(request, user) + return redirect('home') + + else: + form = PasswordChangeForm(request.user) + return render(request, 'users/change_password.html', { + 'form': form + }) + +@login_required +def change_email(request): + + user = request.user + if request.method == 'POST': + form = EmailChangeForm(request.POST) + if form.is_valid(): + form.save() + + user.email = form.cleaned_data['email'] + user.save() + + return redirect('change_email') + + else: + form = EmailChangeForm() + + return render(request, 'users/change_email.html', { + 'form': form + }) +# Create your views here. From bc6684f37571aef4b565c1709c8ca062c967178a Mon Sep 17 00:00:00 2001 From: Sankha Das <54751139+sankha555@users.noreply.github.com> Date: Mon, 30 Dec 2019 19:35:35 +0530 Subject: [PATCH 3/4] backend bugs --- __pycache__/__init__.cpython-37.pyc | Bin 0 -> 140 bytes __pycache__/admin.cpython-37.pyc | Bin 0 -> 251 bytes __pycache__/apps.cpython-37.pyc | Bin 0 -> 354 bytes __pycache__/forms.cpython-37.pyc | Bin 0 -> 2100 bytes __pycache__/models.cpython-37.pyc | Bin 0 -> 1190 bytes __pycache__/urls.cpython-37.pyc | Bin 0 -> 962 bytes __pycache__/views.cpython-37.pyc | Bin 0 -> 7562 bytes admin.py | 6 + apps.py | 5 + forms.py | 39 ++ migrations/0001_initial.py | 27 ++ .../__pycache__/0001_initial.cpython-37.pyc | Bin 0 -> 981 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 151 bytes models.py | 21 + templates/files/add_dber.html | 39 ++ templates/files/base.html | 184 +++++++++ templates/files/failed_search.html | 32 ++ templates/files/home.html | 44 +++ templates/files/mail_content.html | 36 ++ templates/files/search_city_staff.html | 36 ++ templates/files/search_dber.html | 36 ++ templates/files/search_results.html | 100 +++++ templates/files/update_dber.html | 39 ++ templates/files/upload_file.html | 36 ++ tests.py | 3 + urls.py | 19 + views.py | 370 ++++++++++++++++++ 27 files changed, 1072 insertions(+) create mode 100644 __pycache__/__init__.cpython-37.pyc create mode 100644 __pycache__/admin.cpython-37.pyc create mode 100644 __pycache__/apps.cpython-37.pyc create mode 100644 __pycache__/forms.cpython-37.pyc create mode 100644 __pycache__/models.cpython-37.pyc create mode 100644 __pycache__/urls.cpython-37.pyc create mode 100644 __pycache__/views.cpython-37.pyc create mode 100644 admin.py create mode 100644 apps.py create mode 100644 forms.py create mode 100644 migrations/0001_initial.py create mode 100644 migrations/__pycache__/0001_initial.cpython-37.pyc create mode 100644 migrations/__pycache__/__init__.cpython-37.pyc create mode 100644 models.py create mode 100644 templates/files/add_dber.html create mode 100644 templates/files/base.html create mode 100644 templates/files/failed_search.html create mode 100644 templates/files/home.html create mode 100644 templates/files/mail_content.html create mode 100644 templates/files/search_city_staff.html create mode 100644 templates/files/search_dber.html create mode 100644 templates/files/search_results.html create mode 100644 templates/files/update_dber.html create mode 100644 templates/files/upload_file.html create mode 100644 tests.py create mode 100644 urls.py create mode 100644 views.py diff --git a/__pycache__/__init__.cpython-37.pyc b/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d7658de106e27ee1f7dfc8fb02c76e4f0853c9e7 GIT binary patch literal 140 zcmZ?b<>g`kf)p*bI1v39M8E(ekl_Ht#VkM~g&~+hlhJP_LlH_j>V#UpgIgMj86kuaBMV}=0hD4>rA;oUI1Ky^jQrBAO#J{BCY&NH z`PuK;^7Hj-b)qD`pSnku`c=t)Xlbq_`Ah&6LQoL~0EG?e&_q3GPy{>k-je>Py17?< zdys9_!`wQIemuY*Gq*m_UB4Jkap%TuT0f_;WWULc%;!Z+NP)Ad#IP?kcbT@H3*}Fh zJCTp@b8a7)GTZ1zzYi{;V|zoqFKM#4nNlt;*cY*4d$eCqZ*zAc*Ixr&)>pV%EMeLF E0(w_JCIA2c literal 0 HcmV?d00001 diff --git a/__pycache__/apps.cpython-37.pyc b/__pycache__/apps.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..974e55d092eddb2b9c2d0520689f5585247a34c1 GIT binary patch literal 354 zcmYLFy-ve05I)B#N=qy82&`eK#g0(<5o}#hmkd~jbE{A%F?KsJ!^`kWUYU3WChig{ zPP*^D^ZomJHk$wmo*g}|$bPYNketYZG@cS5pm5NLN(i_I%us#+N-N%Fm0|t><>;HT zpcH9*<^4_9uItS+zZ^smS&+sP0t=Nuph{6m%&1zXM_j6)OEt&Q7V=M_HrF6@j`{S0Ni vk8}SPBo*_;F(W8M?=N{Td@=2&n{!^^SReVHH8B3gR9p-TUh=JdpQ-!>^@ULD literal 0 HcmV?d00001 diff --git a/__pycache__/forms.cpython-37.pyc b/__pycache__/forms.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9e2b9f3c5140026ce1e423fba9d63e59a89def4a GIT binary patch literal 2100 zcmZ`)&2HO95a#kmS@~ z9@txBSn6*e%wj}X8Hou&-WGP|#E#(|;bva!0q-(T_*oDKM(&F+Ys3x12O`Rvantaj zXl3oVZTN=R%Q|s~SU*@SV$I(y*5u@}`__r~LDFJvkhDS414$nwd#nSJ&RTK+k}lf^ z$^QDQLy+`XA0+*?&I5LEZVe8v0E0Ck+M5?LQ^2?vic5HR@qH{gEz=@Dg~KaSYr3bY z;GhuvB#U{?M(61wuU4o92aRXNA~m1DCi;bnl+m(~DnVD9#|LH%OML}|TQOl)Y;)(* zWdx|l{oey-|3ManIq#e}gzzDW5We@;jvLH}&;z}PkzA}qK^eL}l_o+*hmyanQpuV2 ze@)qfmlBJ)<=zIt7?yeu$c_6L+%tP&#~yRQh5M$z?P7SwOA5KlX~wm~iexhIbvT{k zemd3Bbea{c63Dlv)0Y($^@&8d+Ji$bv_DU|VCqjx9)i@6|Gpeyy45J7dHO<7!KfOY zaP^`rRwFiB6|$sagxOXjQ>fwUwRSO>Jp_Rr84{Pshrmn*k?f-3eIz|3h*mcc$|<_m z%^y?7c>XkBRdsH3?~J~B#`8tF{CQI^9nFd|p=Gk<(ipx8x8@$8=_U}&u0n(%iAdKr zvaM`i7yD~ay26OqLfA0jzGa$T)k@ZX06OtA`q82F?`Bucju z;DBHZOML-kI|0lFn4W>`7~aQDhZYRhUEVpPsW>k3lIJDDzQSMzM1BCTG=!GdfvRSg zJSlaM)M}GKxC^R0f=}cpNIpe!FRG8=6bEBn)D~&k5@owFVXiiqU`}CxU`}nAQ>Pvx z-TaQRlNpy7{g#RAzBsyNf;;sTG6xd@_4i>KP5s|=Zy7S9XsV;#%{b1qzu-CJQoBi7 zzSf>9X~|(m?`9(af3lC{-W=d49l^RgT<%?4sJOE?K7#`+lEU!|ZHfCW_znohuoP-- zGFab%byqM4njiWBn%~p?y7`X**m+6kbIhjv7`|Nhf*b%p83cFZL+^FvQQ>~TpTjA( zMGe@7Hb%*0@KF2glIDw|zD6F`n<2KEOlLz{mCK>I*px&-`q3_hIRvXD-c#CNE1N5^ zRpGU_`5wy>KcPYxqpCp(Zo@YXfi!plm# mhQ$#zJ#ETjpzbQ74!?nL;YR-!2Ce?LfN8k>vwLCB$KU_>Y`U`m literal 0 HcmV?d00001 diff --git a/__pycache__/models.cpython-37.pyc b/__pycache__/models.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9aaec89a7fc0ae30e1f712ad48a147a8d3a5d331 GIT binary patch literal 1190 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 W+jK5DbKY0H3*MK!n)f>H#s33HN0Ar+ literal 0 HcmV?d00001 diff --git a/admin.py b/admin.py new file mode 100644 index 0000000..7587366 --- /dev/null +++ b/admin.py @@ -0,0 +1,6 @@ +from django.contrib import admin +from .models import File + +admin.site.register(File) + +# Register your models here. diff --git a/apps.py b/apps.py new file mode 100644 index 0000000..c86f272 --- /dev/null +++ b/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class FilesConfig(AppConfig): + name = 'files' diff --git a/forms.py b/forms.py new file mode 100644 index 0000000..1f7ef79 --- /dev/null +++ b/forms.py @@ -0,0 +1,39 @@ +from django import forms +from django.contrib.auth.models import User +from django.contrib.auth.forms import UserCreationForm +from .models import File +from users.models import Profile +from allauth.socialaccount.forms import SignupForm +from allauth.account.forms import LoginForm +from django.core import validators + +class FileUploadForm(forms.ModelForm): + botcatcher = forms.FileField(required = False, widget = forms.HiddenInput, + validators = [validators.MaxLengthValidator(0)]) + + class Meta: + model = File + fields = ['fname', 'doc'] + +class SearchUIDForm(forms.Form): + botcatcher = forms.CharField(required = False, widget = forms.HiddenInput, + validators = [validators.MaxLengthValidator(0)]) + uid = forms.CharField(max_length=12) + fields = ['uid'] + +class MailContentForm(forms.Form): + subject = forms.CharField(max_length = 20) + content = forms.CharField(max_length = 264) + + fields = ['subject', 'content'] + +class AddDberForm(forms.ModelForm): + + class Meta: + model = Profile + fields = ['uid', 'name', 'dob', 'gender', 'city', 'state'] + +class SearchCityStaffForm(forms.Form): + + city = forms.CharField(max_length = 20) + fields = ['city'] diff --git a/migrations/0001_initial.py b/migrations/0001_initial.py new file mode 100644 index 0000000..d9e0f2c --- /dev/null +++ b/migrations/0001_initial.py @@ -0,0 +1,27 @@ +# Generated by Django 2.2.4 on 2019-12-30 06:54 + +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('users', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='File', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('fname', models.CharField(max_length=20)), + ('doc', models.FileField(blank=True, upload_to='files_dir/')), + ('up_date', models.DateField(default=django.utils.timezone.now)), + ('staff', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.Profile')), + ], + ), + ] diff --git a/migrations/__pycache__/0001_initial.cpython-37.pyc b/migrations/__pycache__/0001_initial.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5cf8ac0d3f71319dcd362ade043e0a7badcaf61f GIT binary patch literal 981 zcmYjQ&2rN)5VrhpCu!3*9fk+skV{-HoEWAhAq>N`!%XSL2Q*4n336@A$PUn4={3*5 znOD-4Q(u7-D<`4IqxJ4etKIKg>2nx?xnw{a zse@HT0n=e@0DQq#d856$VT;AO*Va7xprkniqa#^TB%e1}bR*H>wiWmb!E>mu5Ohe} zqA1ldrP!%e&Qb4D`ens(vl*>m55Eh%;wA8ME_khM1fVF5F}nVJMT z8h>VLryAyV>IAFbsy<|_TuLOn5qYh{MihK4ORk+#e$(+(DlV4gdt}pwnGRbhc&T(S zzPKJ=Oy1~NR(yBSepzaS`CIX4lH8c~B?T+RZO(FFbu!`gZ6m7$W|dS8%afMqFI90MLyaCZ;yP$vDFgXufvzy?z}Q2*FK6q2}$Vu1-%*~=>Px# literal 0 HcmV?d00001 diff --git a/migrations/__pycache__/__init__.cpython-37.pyc b/migrations/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8174320a190fd58e35e48720a404ebcb0749d373 GIT binary patch literal 151 zcmZ?b<>g`kf)p*bI1v39M8E(ekl_Ht#VkM~g&~+hlhJP_LlH +
+
+
+

Add DBER

+

+ Add a New Record to the Database +

+
+
+
+ + +
+
+
+ +
+ {% csrf_token %} +
+ Profile Info +
+ {{ form }} +
+
+
+ +
+
+
+
+
+ + +{% endblock content %} diff --git a/templates/files/base.html b/templates/files/base.html new file mode 100644 index 0000000..f780e67 --- /dev/null +++ b/templates/files/base.html @@ -0,0 +1,184 @@ +{% load static %} + + + + + DBPortal - The Database Management System + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + {%block content%} + + + {%endblock content%} + + +
+
+
+ BITS Pilani + Vidya Vihar, Pilani, Rajasthan 333031 +
+ +
+
+ + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + diff --git a/templates/files/failed_search.html b/templates/files/failed_search.html new file mode 100644 index 0000000..7b0ed0b --- /dev/null +++ b/templates/files/failed_search.html @@ -0,0 +1,32 @@ +{%extends "files/base.html"%} +{% block content %} +
+
+
+
+

Sorry, No Search Results !

+

+ Your search returned no results. Please check the UID once again or make a new search. +

+
+
+
+
+ + +
+
+
+ +
+

Make a new Search

+ + + Search Students + + +
+
+
+
+{%endblock content%} diff --git a/templates/files/home.html b/templates/files/home.html new file mode 100644 index 0000000..a3fc897 --- /dev/null +++ b/templates/files/home.html @@ -0,0 +1,44 @@ +{% extends "files/base.html" %} +{% block content %} + +
+
+
+
+

DBPortal

+

+ The Database Management System +

+
+
+
+
+ +
+
+
+ +
+
+
+
+

Home

+

+ Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem + Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown + printer took a galley of type and scrambled it to make a type specimen book. It has survived + not only five centuries, but also the leap into electronic typesetting, remaining essentially + unchanged. It was popularised in the 1960s with the release of Letraset sheets containing + Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker + including versions of Lorem Ipsum. +

+
+
+
+
+ +
+
+
+ +{% endblock content %} diff --git a/templates/files/mail_content.html b/templates/files/mail_content.html new file mode 100644 index 0000000..07d7a18 --- /dev/null +++ b/templates/files/mail_content.html @@ -0,0 +1,36 @@ +{% extends "files/base.html" %} +{% load crispy_forms_tags %} +{% block content %} +
+
+
+
+

Send Mail

+

Send Mail to the Concerned User

+
+
+
+
+ + +
+
+
+
+ {% csrf_token %} +
+ Write Mail + {{ form|crispy }} +
+
+ +
+
+
+ +
+
+ + + +{%endblock content%} diff --git a/templates/files/search_city_staff.html b/templates/files/search_city_staff.html new file mode 100644 index 0000000..11f757b --- /dev/null +++ b/templates/files/search_city_staff.html @@ -0,0 +1,36 @@ +{% extends "files/base.html" %} +{% load crispy_forms_tags %} +{% block content %} +
+
+
+
+

Search City Staff

+

Search for City Staff in the Database

+
+
+
+
+ + +
+
+
+
+ {% csrf_token %} +
+ Search Staff + {{ form }} +
+
+ +
+
+
+ +
+
+ + + +{%endblock content%} diff --git a/templates/files/search_dber.html b/templates/files/search_dber.html new file mode 100644 index 0000000..364a3eb --- /dev/null +++ b/templates/files/search_dber.html @@ -0,0 +1,36 @@ +{% extends "files/base.html" %} +{% load crispy_forms_tags %} +{% block content %} +
+
+
+
+

Search Users

+

Search for Users in the Database

+
+
+
+
+ + +
+
+
+
+ {% csrf_token %} +
+ Search Users + {{ form }} +
+
+ +
+
+
+ +
+
+ + + +{%endblock content%} diff --git a/templates/files/search_results.html b/templates/files/search_results.html new file mode 100644 index 0000000..a9d53b2 --- /dev/null +++ b/templates/files/search_results.html @@ -0,0 +1,100 @@ +{%extends "files/base.html"%} +{% load crispy_forms_tags %} +{% block content %} +
+
+
+
+

Search Results

+

+ Your search returned the following results. +

+
+
+
+
+ + +
+
+
+ {% if dber %} + +
+ + + + + + {% if user.profile.qualifier == 1%} + + + + + {% elif user != dber.user %} + + + + {% endif %} + +
+

{{ dber.name }}

+

{{ dber.uid }}

+

DOB : {{ dber.dob }}

+

Sex : {{ dber.gender }}

+

City: {{ dber.city }}, {{ dber.state }}

+
+
+

+ + Update + +     + + Delete + +     + + Mail + +     +

+
+

+ + Mail + +     + {% if user.profile %} + + {% elif dber.user %} + + {% else %} + + Link Account + + {% endif %} +

+
+
+
+ + {% else %} +

Sorry, No Users Related to Your Search were Found

+ {% endif %} + +
+ + {% if user.profile %} + + {% else %} +
+

Didn't Find Your Profile ?

+ Report the issue to your city's staff in-charge. + +
+ {% endif %} +
+
+ +{%endblock content%} diff --git a/templates/files/update_dber.html b/templates/files/update_dber.html new file mode 100644 index 0000000..4f3d8c2 --- /dev/null +++ b/templates/files/update_dber.html @@ -0,0 +1,39 @@ +{% extends "files/base.html" %} +{% load crispy_forms_tags %} +{% block content %} + +
+
+
+
+

Update DBER

+

+ Update the User Profile of the Dber +

+
+
+
+
+ +
+
+
+ +
+ {% csrf_token %} +
+ Profile Info +
+ {{ p_form|crispy }} +
+
+
+ +
+
+
+
+
+ + +{% endblock content %} diff --git a/templates/files/upload_file.html b/templates/files/upload_file.html new file mode 100644 index 0000000..7505aab --- /dev/null +++ b/templates/files/upload_file.html @@ -0,0 +1,36 @@ +{% extends "files/base.html" %} +{% load crispy_forms_tags %} +{% block content %} +
+
+
+
+

Upload Files

+

Upload Fiels to Populate the Database

+
+
+
+
+ + +
+
+
+
+ {% csrf_token %} +
+ Upload File + {{ form|crispy }} +
+
+ +
+
+
+ +
+
+ + + +{%endblock content%} diff --git a/tests.py b/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/urls.py b/urls.py new file mode 100644 index 0000000..f221019 --- /dev/null +++ b/urls.py @@ -0,0 +1,19 @@ +from django.contrib import admin +from django.urls import path +from .views import upload_file, search_dber, search_uid_normal, update_dber, search_city_staff, delete_dber, add_dber, send_mail, send_mass_mails, home, link_account +from django.contrib.auth import views as auth_views + +urlpatterns = [ + + path('', home, name='home'), + path('upload_file/', upload_file, name='upload_file'), + path('search_dber/', search_dber, name='search_dber'), + path('search_uid/', search_uid_normal, name='search_uid_normal'), + path('search_city_staff/', search_city_staff, name='search_city_staff'), + path('link_account//', link_account, name='link_account'), + path('update_dber//', update_dber, name='update_dber'), + path('delete_dber//', delete_dber, name='delete_dber'), + path('add_dber/', add_dber, name='add_dber'), + path('send_mail//', send_mail, name='send_mail'), + path('send_mass_mails/', send_mass_mails, name='send_mass_mails'), +] diff --git a/views.py b/views.py new file mode 100644 index 0000000..db87188 --- /dev/null +++ b/views.py @@ -0,0 +1,370 @@ +from django.shortcuts import render +from django.contrib.auth.decorators import login_required +from django.contrib import messages +import requests +from django.shortcuts import render, get_object_or_404, redirect, HttpResponseRedirect +from django.contrib.auth.decorators import login_required +from .forms import FileUploadForm, SearchUIDForm, MailContentForm, AddDberForm, SearchCityStaffForm +import xlrd, xlsxwriter +import openpyxl +from django.conf import settings +from .models import File +from users.models import Profile + + +def home(request): + return render(request, 'files/home.html') + +@login_required +def upload_file(request): + + if File.objects.filter(staff = request.user.profile).exists(): + return HttpResponse("You have already uploaded your file, Update the previous file.") + if request.method == 'POST': + form = FileUploadForm(request.POST, request.FILES) + if form.is_valid(): + file = form.save(commit=False) + file.save() + + #file = request.FILES['filename'].temporary_file_path + document = file.doc + wb = xlrd.open_workbook(document.path) + sheet = wb.sheet_by_index(0) + sheet.cell_value(0, 0) + + rows = sheet.nrows + cols = sheet.ncols + + for i in range(2,rows): + dber_uid = sheet.cell_value(i, 0) + dber_name = sheet.cell_value(i, 1) + dber_dob = sheet.cell_value(i, 2) + dber_gender = sheet.cell_value(i, 3) + dber_city = sheet.cell_value(i, 4) + dber_state = sheet.cell_value(i, 5) + + new_dber = Profile.objects.get_or_create(uid = dber_uid) + new_dber.name = dber_name + new_dber.dob = dber_dob + new_dber.gender = dber_gender + new_dber.city = dber_city + new_dber.state = dber_state + new_dber.city_circle = file.staff.city_circle + + new_dber.save() + + return redirect('home') + else: + form = FileUploadForm() + + return render(request, 'files/upload_file.html', { + 'form': form + }) + +def search_dber(request): + + if request.method == 'POST': + form = SearchUIDForm(request.POST) + if form.is_valid(): + search_uid = form.cleaned_data['uid'] + + file = get_object_or_404(File, staff = request.user.profile) + document = file.doc + wb = xlrd.open_workbook(document.path) + sheet = wb.sheet_by_index(0) + + rows = sheet.nrows + cols = sheet.ncols + + flag = 0 + + for i in range(2,rows): + + if search_uid == sheet.cell_value(i, 0): + flag = 1 + dber = get_object_or_404(Profile, uid = search_uid) + return render(request, "files/search_results.html", {'dber':dber}) + + if flag == 0: + return render(request, "files/failed_search.html") + else: + form = SearchUIDForm() + + return render(request, 'files/search_dber.html', { + 'form': form + }) + +def search_uid_normal(request): + + if request.method == 'POST': + form = SearchUIDForm(request.POST) + if form.is_valid(): + search_uid = form.cleaned_data['uid'] + + dber = get_object_or_404(Profile, uid = search_uid) + return render(request, "files/search_results.html", {'dber':dber}) + + else: + form = SearchUIDForm() + + return render(request, 'files/search_dber.html', { + 'form': form + }) + +@login_required +def update_dber(request, pk): + + dber = get_object_or_404(Profile, pk = pk) + if request.method == 'POST': + p_form = DberUpdateForm(request.POST, + instance=dber) + + if p_form.is_valid(): + dber.save() + p_form.save() + + # File updation begins + + file = get_object_or_404(File, staff = request.user.profile) + document = file.doc + wb = openpyxl.load_workbook(document.path) + sheet = wb.get_sheet(0) + + rows = sheet.max_row + + flag = 0 + for i in range(3,rows+1): + + cell_name = f'A{i}' + if dber.uid == sheet[cell_name].value: + flag = 1 + + list = [dber.uid, dber.name, dber.dob, dber.gender, dber.city, dber.state] + for j in range(2, 7): + cell = sheet.cell(row = i, column = j) + cell.value = list[j-1] + + break + + if flag == 0: + return render(request, "files/failed_search.html") + + wb.save(document.path) + file.save() + #File Updation Ends + + return redirect('home') + + else: + p_form = DberUpdateForm(instance=dber) + + + context = { + 'p_form' : p_form + } + return render(request, 'files/update_dber.html', context) + +@login_required +def delete_dber(request, pk): + + dber = get_object_or_404(Profile, pk = pk) + + # File updation begins + file = get_object_or_404(File, staff = request.user.profile) + document = file.doc + wb = openpyxl.load_workbook(document.path) + sheet = wb.get_sheet(0) + + rows = sheet.max_row + + flag = 0 + for i in range(3,rows+1): + cell_name = f'A{i}' + if dber.uid == sheet[cell_name].value: + flag = 1 + sheet.delete_rows(i, 1) + break + + Profile.objects.remove(dber) + + wb.save(document.path) + file.save() + #File Updation Ends + + return redirect('home') + +@login_required +def add_dber(request): + + if request.method == 'POST': + form = AddDberForm(request.POST) + + if form.is_valid(): + form.save() + dber_uid = form.cleaned_data['uid'] + + #new dber created in database + new_dber = Profile.objects.get_or_create(uid = dber_uid) + new_dber.name = form.cleaned_data['name'] + new_dber.dob = form.cleaned_data['dob'] + new_dber.gender = form.cleaned_data['gender'] + new_dber.city = form.cleaned_data['city'] + new_dber.state = form.cleaned_data['state'] + new_dber.city_circle = request.user.profile.city_circle + + new_dber.save() + + # File updation begins + file = get_object_or_404(File, staff = request.user.profile) + document = file.doc + wb = openpyxl.load_workbook(document.path) + sheet = wb.get_sheet(0) + + rows = sheet.max_row + cols = sheet.max_column + + sheet.insert_rows(3) #new dber insterted at top of sheet + + list = [new_dber.uid, new_dber.name, new_dber.dob, new_dber.gender, new_dber.city, new_dber.state] + for j in range(1, 7): + cell = sheet.cell(row = 3, column = j) + cell.value = list[j-1] + + + wb.save(document.path) + file.save() + #File Updation Ends + + return redirect('home') + + else: + form = AddDberForm() + + return render(request, 'files/add_dber.html', {'form':form}) + +@login_required +def send_mail(request, pk): + + dber = get_object_or_404(Profile, pk = pk) + if request.method == 'POST': + form = MailContentForm(request.POST) + + if form.is_valid(): + + subject = form.cleaned_data['subject'] + content = form.cleaned_data['content'] + + mail = smtplib.SMTP(settings.EMAIL_HOST, settings.EMAIL_PORT) + mail.ehlo() + mail.starttls() + mail.login(settings.EMAIL_HOST_USER, settings.EMAIL_HOST_PASSWORD) + + message = f'**** SUBJECT : {subject} **** \n{content}\n\nRegards,\n{request.user.profile.name}' + + email = dber.user.email + try: + mail.sendmail(settings.EMAIL_HOST_USER, email, message) + except: + pass + + mail.close() + + else: + form = MailContentForm() + + return render(request, 'files/mail_content.html', {'form':form}) + +@login_required +def send_mass_mails(request): + + if request.method == 'POST': + form = MailContentForm(request.POST) + + if form.is_valid(): + + subject = form.cleaned_data['subject'] + content = form.cleaned_data['content'] + + mail = smtplib.SMTP(settings.EMAIL_HOST, settings.EMAIL_PORT) + mail.ehlo() + mail.starttls() + mail.login(settings.EMAIL_HOST_USER, settings.EMAIL_HOST_PASSWORD) + + message = f'**** SUBJECT : {subject} **** \n{content}\n\nRegards,\n{request.user.profile.name}' + + users = User.objects.all(profile) + for user in users: + if (user.profile.city_circle == request.user.profile.city_circle) and (user.profile.qualifier == 0): + + email = user.email + try: + mail.sendmail(settings.EMAIL_HOST_USER, email, message) + except: + pass + + mail.close() + + else: + form = MailContentForm() + + return render(request, 'files/mail_content.html', {'form':form}) + +@login_required +def send_city_staff_mail(request): + + if request.method == 'POST': + form = SearchCityStaffForm(request.POST) + + if form.is_valid(): + + city = form.cleaned_data['city'] + + flag = 0 + staff_pool = Profile.objects.exclude(qualifier=0) + + for staff_user in staff_pool: + if staff_user.city == city: + flag = 1 + return redirect('send_mail', staff_user.id) + break + + if flag == 0: + return render(request, 'templates/failed_search.html') + + else: + + + form = SearchCityStaffForm() + + return render(request, 'files/search_results.html', {'form':form}) + +@login_required +def link_account(request, pk): + profile = get_object_or_404(Profile, pk = pk) + user = request.user + + profile.user = user + profile.save() + user.save() + + return redirect('home') + +@login_required +def search_city_staff(request): + + if request.method == "POST": + form = SearchCityStaffForm(request.POST) + + if form.is_valid(): + search_city = form.cleaned_data['city'] + + if Profile.objects.filter(qualifier = 1, city = search_city).exists(): + staff = Profile.objects.get(qualifier = 1, city = search_city) + return redirect('send_mail', staff.id) + else: + return redirect('search_city_staff') + + else: + form = SearchCityStaffForm() + + return render(request, 'files/search_city_staff.html', {'form':form}) From de281924ddac077feccfbab604ea5ce8494274e8 Mon Sep 17 00:00:00 2001 From: Sankha Das <54751139+sankha555@users.noreply.github.com> Date: Mon, 30 Dec 2019 20:23:03 +0530 Subject: [PATCH 4/4] Delete forms.py --- forms.py | 39 --------------------------------------- 1 file changed, 39 deletions(-) delete mode 100644 forms.py diff --git a/forms.py b/forms.py deleted file mode 100644 index 1f7ef79..0000000 --- a/forms.py +++ /dev/null @@ -1,39 +0,0 @@ -from django import forms -from django.contrib.auth.models import User -from django.contrib.auth.forms import UserCreationForm -from .models import File -from users.models import Profile -from allauth.socialaccount.forms import SignupForm -from allauth.account.forms import LoginForm -from django.core import validators - -class FileUploadForm(forms.ModelForm): - botcatcher = forms.FileField(required = False, widget = forms.HiddenInput, - validators = [validators.MaxLengthValidator(0)]) - - class Meta: - model = File - fields = ['fname', 'doc'] - -class SearchUIDForm(forms.Form): - botcatcher = forms.CharField(required = False, widget = forms.HiddenInput, - validators = [validators.MaxLengthValidator(0)]) - uid = forms.CharField(max_length=12) - fields = ['uid'] - -class MailContentForm(forms.Form): - subject = forms.CharField(max_length = 20) - content = forms.CharField(max_length = 264) - - fields = ['subject', 'content'] - -class AddDberForm(forms.ModelForm): - - class Meta: - model = Profile - fields = ['uid', 'name', 'dob', 'gender', 'city', 'state'] - -class SearchCityStaffForm(forms.Form): - - city = forms.CharField(max_length = 20) - fields = ['city']