Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Binary file added backend/__pycache__/adminmenu.cpython-313.pyc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added backend/__pycache__/mentor_menu.cpython-313.pyc
Binary file not shown.
Binary file not shown.
Binary file added backend/__pycache__/utils.cpython-313.pyc
Binary file not shown.
45 changes: 45 additions & 0 deletions backend/admin_preference_menu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from PyQt6 import QtWidgets, uic
from applications_menu import ApplicationsWindow
from interviews_menu import InterviewsMenuWindow
from mentor_menu import MentorMeetingWindow
from adminmenu import AdminMenuWindow

class AdminPreferenceMenuWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
uic.loadUi("ui/admin_preference_menu.ui", self)
self.pushButton_mentorinterview.clicked.connect(self.open_mentor_interviews_window)
self.pushButton_applications.clicked.connect(self.open_applications_window)
self.pushButton_interviews.clicked.connect(self.open_interviews_window)
self.pushButton_adminmenu.clicked.connect(self.open_admin_menu_window)
self.pushButton_exit.clicked.connect(self.close)

def open_mentor_interviews_window(self):
self.interviews_window = MentorMeetingWindow(parent=self)
self.interviews_window.show()
self.hide()

def open_applications_window(self):
self.applications_window = ApplicationsWindow(parent=self)
self.applications_window.show()
self.hide()

def open_interviews_window(self):
self.interviews_window = InterviewsMenuWindow(parent=self)
self.interviews_window.show()
self.hide()

def open_admin_menu_window(self):
self.admin_menu_window = AdminMenuWindow(parent=self)
self.admin_menu_window.show()
self.hide()



# Test amaçlı çalıştırmak için:
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
window = AdminPreferenceMenuWindow()
window.show()
sys.exit(app.exec())
126 changes: 126 additions & 0 deletions backend/adminmenu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
from PyQt6 import QtWidgets, uic
from googleapiclient.discovery import build
from google.oauth2.credentials import Credentials
from google.auth.transport.requests import Request
from dotenv import load_dotenv # .env dosyasını okumak için
import os
import datetime
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

# .env dosyasını yükle
load_dotenv()

SCOPES = [
'https://www.googleapis.com/auth/calendar.readonly',
'https://www.googleapis.com/auth/drive.readonly'
]
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
CREDENTIALS_PATH = os.path.join(BASE_DIR, "../credentials.json")
TOKEN_PATH = os.path.join(BASE_DIR, "../token.json")

class AdminMenuWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__()
self.parent_menu = parent
uic.loadUi("ui/admin_menu.ui", self)
self.pushButton_preference_admin_menu.clicked.connect(self.back_to_admin_preference_menu)
self.pushButton_activity_control.clicked.connect(self.load_activities_to_table)
self.pushButton_sendmail.clicked.connect(self.send_emails_to_participants)
self.pushButton_exit.clicked.connect(QtWidgets.QApplication.quit)

def back_to_admin_preference_menu(self):
if self.parent_menu is not None:
self.parent_menu.show()
self.close()

def get_calendar_service(self):
creds = None
if os.path.exists(TOKEN_PATH):
creds = Credentials.from_authorized_user_file(TOKEN_PATH, SCOPES)
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
from google_auth_oauthlib.flow import InstalledAppFlow
flow = InstalledAppFlow.from_client_secrets_file(CREDENTIALS_PATH, SCOPES)
creds = flow.run_local_server(port=0)
with open(TOKEN_PATH, "w") as token:
token.write(creds.to_json())
return build('calendar', 'v3', credentials=creds)

def load_activities_to_table(self):
service = self.get_calendar_service()
now = datetime.datetime.utcnow().isoformat() + 'Z'
events_result = service.events().list(
calendarId='primary', timeMin=now,
maxResults=20, singleEvents=True,
orderBy='startTime').execute()
events = events_result.get('items', [])

table = self.tableWidget_admin_menu_dashboard
table.setRowCount(len(events))
table.setColumnCount(4)
table.setHorizontalHeaderLabels(["Event Name", "Start Time", "Organizer Email", "Participants"])

for row, event in enumerate(events):
event_name = event.get('summary', 'No Title')
start_time = event['start'].get('dateTime', event['start'].get('date', ''))
organizer_email = event.get('organizer', {}).get('email', '')
participants = [att.get('email', '') for att in event.get('attendees', [])] if 'attendees' in event else []
participants_str = ", ".join(participants)

table.setItem(row, 0, QtWidgets.QTableWidgetItem(event_name))
table.setItem(row, 1, QtWidgets.QTableWidgetItem(start_time))
table.setItem(row, 2, QtWidgets.QTableWidgetItem(organizer_email))
table.setItem(row, 3, QtWidgets.QTableWidgetItem(participants_str))

def send_emails_to_participants(self):
service = self.get_calendar_service()
now = datetime.datetime.utcnow().isoformat() + 'Z'
events_result = service.events().list(
calendarId='primary', timeMin=now,
maxResults=20, singleEvents=True,
orderBy='startTime').execute()
events = events_result.get('items', [])

sender_email = "vit7team2crmproject@gmail.com"
# .env dosyasından şifreyi oku
sender_password = os.environ.get("CRM_GMAIL_APP_PASSWORD")

if not sender_password:
QtWidgets.QMessageBox.critical(self, "Hata", "Mail gönderimi için uygulama şifresi bulunamadı!")
return

for event in events:
event_name = event.get('summary', 'No Title')
start_time = event['start'].get('dateTime', event['start'].get('date', ''))
participants = [att.get('email', '') for att in event.get('attendees', [])] if 'attendees' in event else []

for recipient in participants:
msg = MIMEMultipart()
msg['From'] = sender_email
msg['To'] = recipient
msg['Subject'] = f"Etkinlik Daveti: {event_name}"

body = f"Merhaba,\n\n{event_name} etkinliğine davetlisiniz.\nBaşlangıç Zamanı: {start_time}\n\nİyi günler!"
msg.attach(MIMEText(body, 'plain'))

try:
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as server:
server.login(sender_email, sender_password)
server.sendmail(sender_email, recipient, msg.as_string())
print(f"Mail gönderildi: {recipient}")
except Exception as e:
print(f"Mail gönderilemedi: {recipient}, Hata: {e}")

QtWidgets.QMessageBox.information(self, "Bilgi", "Tüm katılımcılara mail gönderimi tamamlandı.")

# Test amaçlı çalıştırmak için:
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
window = AdminMenuWindow()
window.show()
sys.exit(app.exec())
111 changes: 111 additions & 0 deletions backend/applications_menu.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
from PyQt6 import QtWidgets, uic
import pandas as pd
from utils import get_engine

class ApplicationsWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.parent_menu = parent
uic.loadUi("ui/applications_menu.ui", self)
self.df = None
self.load_table_data()
self.lineEdit_search.textChanged.connect(self.filter_table)
self.pushButton_all_applications.clicked.connect(self.load_table_data)
self.pushButton_planned_mentor_meetings.clicked.connect(self.planned_mentor_meetings)
self.pushButton_unscheduled_mentor_meetings.clicked.connect(self.unscheduled_mentor_meetings)
self.pushButton_repeted_registeration.clicked.connect(self.repeated_registration)
self.pushButton_dif_registeration.clicked.connect(self.different_registration)
self.pushButton_filter_application.clicked.connect(self.filter_applications)
self.pushButton_BackMenu.clicked.connect(self.back_to_menu)
self.pushButton_exit.clicked.connect(self.close)

def get_base_query(self):
return """
SELECT
b."ZamanDamgasi" AS "Date",
k."AdSoyad" AS "Name Surname",
k."MailAdresi" AS "Mail",
k."TelefonNumarasi" AS "Telephone",
k."PostaKodu" AS "Post Code",
k."YasadiginizEyalet" AS "State",
b."EkonomikDurum" AS "Economical Situation"
FROM basvurular b
LEFT JOIN kursiyerler k
ON b."KursiyerID" = k."KursiyerID"
"""

def load_table_data(self):
try:
engine = get_engine()
query = self.get_base_query()
self.df = pd.read_sql(query, engine)
self.show_table(self.df)
except Exception as e:
QtWidgets.QMessageBox.critical(self, "Hata", f"Veri yüklenemedi: {e}")

def show_table(self, df):
self.tableWidget_application_dashboard.setRowCount(len(df))
self.tableWidget_application_dashboard.setColumnCount(len(df.columns) - 2) # Son iki sütun filtre için
self.tableWidget_application_dashboard.setHorizontalHeaderLabels(
["Date", "Name Surname", "Mail", "Telephone", "Post Code", "State", "Economical Situation"]
)
for row in range(len(df)):
for col in range(7): # Sadece ilk 7 sütunu göster
value = str(df.iloc[row, col])
self.tableWidget_application_dashboard.setItem(row, col, QtWidgets.QTableWidgetItem(value))

def filter_table(self):
if self.df is None:
return
search_text = self.lineEdit_search.text().lower()
if search_text == "":
filtered_df = self.df
else:
filtered_df = self.df[self.df['Name Surname'].str.lower().str.contains(search_text)]
self.show_table(filtered_df)

def planned_mentor_meetings(self):
if self.df is None:
self.load_table_data()
filtered = self.df[self.df["MentorGorusmesi"] == "OK"]
self.show_table(filtered)

def unscheduled_mentor_meetings(self):
if self.df is None:
self.load_table_data()
filtered = self.df[self.df["MentorGorusmesi"] != "OK"]
self.show_table(filtered)

def repeated_registration(self):
if self.df is None:
self.load_table_data()
filtered = self.df[self.df.duplicated(subset=["Name Surname", "Mail"], keep=False)]
self.show_table(filtered)

def different_registration(self):
if self.df is None:
self.load_table_data()
# Farklı kayıtlar: Aynı isim ve mail başka bir yerde yoksa
merged = self.df.groupby(["Name Surname", "Mail"]).size().reset_index(name='counts')
unique = merged[merged['counts'] == 1]
filtered = self.df.set_index(["Name Surname", "Mail"]).loc[unique.set_index(["Name Surname", "Mail"]).index].reset_index()
self.show_table(filtered)

def filter_applications(self):
if self.df is None:
self.load_table_data()
filtered = self.df.drop_duplicates(subset=["Name Surname", "Mail"])
self.show_table(filtered)

def back_to_menu(self):
if self.parent_menu is not None:
self.parent_menu.show()
self.close()

# Test amaçlı çalıştırmak için:
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
window = ApplicationsWindow()
window.show()
sys.exit(app.exec())
63 changes: 63 additions & 0 deletions backend/auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import os.path

from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError

# If modifying these scopes, delete the file token.json.
SCOPES = [
'https://www.googleapis.com/auth/calendar.readonly',
'https://www.googleapis.com/auth/drive.readonly'
]
CREDENTIALS_PATH = "../credentials.json"
TOKEN_PATH = "../token.json"

def main():
"""Shows basic usage of the Drive v3 API.
Prints the names and ids of the first 10 files the user has access to.
"""
creds = None
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists(TOKEN_PATH):
creds = Credentials.from_authorized_user_file(TOKEN_PATH, SCOPES)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
CREDENTIALS_PATH, SCOPES
)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open(TOKEN_PATH, "w") as token:
token.write(creds.to_json())

try:
service = build("drive", "v3", credentials=creds)

# Call the Drive v3 API
results = (
service.files()
.list(pageSize=10, fields="nextPageToken, files(id, name)")
.execute()
)
items = results.get("files", [])

if not items:
print("No files found.")
return
print("Files:")
for item in items:
print(f"{item['name']} ({item['id']})")
except HttpError as error:
# TODO(developer) - Handle errors from drive API.
print(f"An error occurred: {error}")


if __name__ == "__main__":
main()
Loading