| | import streamlit as st |
| | import pandas as pd |
| | import smtplib |
| | from email.mime.text import MIMEText |
| | from email.mime.multipart import MIMEMultipart |
| | import gspread |
| | from oauth2client.service_account import ServiceAccountCredentials |
| | from streamlit_option_menu import option_menu |
| | from io import BytesIO |
| | import requests |
| | from email.mime.application import MIMEApplication |
| | import os |
| |
|
| | |
| | def read_file(path): |
| | try: |
| | with open(path, 'rb') as file: |
| | return file.read() |
| | except Exception as e: |
| | st.error(f"Failed to read file from {path}: {str(e)}") |
| | return None |
| |
|
| | |
| | def get_content_type(file_path): |
| | if file_path.lower().endswith('.pdf'): |
| | return 'application/pdf' |
| | elif file_path.lower().endswith('.csv'): |
| | return 'text/csv' |
| | elif file_path.lower().endswith('.xlsx'): |
| | return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' |
| | else: |
| | return 'application/octet-stream' |
| |
|
| | |
| | EMAIL_HOST = 'smtp.gmail.com' |
| | EMAIL_PORT = 587 |
| | EMAIL_HOST_USER = 'ninadmandavkar@gofynd.com' |
| | EMAIL_HOST_PASSWORD = 'vxay jiss cctw lsdo' |
| |
|
| |
|
| | st.set_page_config(page_title="Alerter",page_icon="",layout="centered") |
| |
|
| |
|
| | html_title = """ |
| | <style> |
| | .fixed-title { |
| | font-size: 60px; |
| | color: #ffffff; |
| | background-image: linear-gradient(to right, #ff0000, #ffdab9); |
| | background-clip: text; |
| | -webkit-background-clip: text; |
| | text-fill-color: transparent; |
| | -webkit-text-fill-color: transparent; |
| | text-shadow: 2px 2px 4px rgba(0,0,0,0.4); |
| | } |
| | </style> |
| | <h1 class="fixed-title">Alerter</h1> |
| | """ |
| | st.markdown(html_title, unsafe_allow_html=True) |
| |
|
| | menu_options = [ |
| | {"label": "Internal users", "icon": "π", "description": "Upload a document and schedule it for email"}, |
| | {"label": "External users", "icon": "π", "description": "Schedule an email with BigQuery data"}, |
| | {"label": "Recon checking", "icon": "π", "description": "Schedule an email with BigQuery data"}, |
| | {"label": "Manual BQ upload", "icon": "π", "description": "Schedule an email with BigQuery data"}, |
| | {"label": "Invoice splitter", "icon": "π", "description": "Schedule an email with BigQuery data"}, |
| | {"label": "Seller sale validation", "icon": "π", "description": "Schedule an email with BigQuery data"}, |
| | |
| | {"label": "Payment working", "icon": "π", "description": "Schedule an email with BigQuery data"} |
| | ] |
| |
|
| | |
| | selected_option = option_menu( |
| | menu_title="Select Integration", |
| | options=[option["label"] for option in menu_options], |
| | icons=[option["icon"] for option in menu_options], |
| | menu_icon="cast", |
| | default_index=0, |
| | orientation="horizontal" |
| | ) |
| |
|
| | if selected_option == "External users": |
| |
|
| | html_subject = """ |
| | <html> |
| | <head> |
| | <style> |
| | .button { |
| | display: inline-block; |
| | padding: 10px 20px; |
| | border-radius: 12px; |
| | background: linear-gradient(to bottom, #f8f9fa, #e0e0e0); |
| | box-shadow: |
| | 0 6px 12px rgba(0, 0, 0, 0.3), |
| | 0 8px 16px rgba(0, 0, 0, 0.2), |
| | inset 0 -2px 4px rgba(255, 255, 255, 0.6); |
| | text-align: center; |
| | position: relative; |
| | transform: translateY(4px); |
| | transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out; |
| | cursor: pointer; |
| | user-select: none; |
| | } |
| | .button:hover { |
| | box-shadow: |
| | 0 8px 16px rgba(0, 0, 0, 0.3), |
| | 0 12px 24px rgba(0, 0, 0, 0.2); |
| | transform: translateY(2px); |
| | } |
| | .button:active { |
| | box-shadow: |
| | 0 4px 8px rgba(0, 0, 0, 0.3), |
| | 0 6px 12px rgba(0, 0, 0, 0.2); |
| | transform: translateY(0); |
| | } |
| | </style> |
| | </head> |
| | <body> |
| | <div class="button"> |
| | <h3 style=" |
| | font-size: 20px; |
| | color: #ffffff; |
| | background-image: linear-gradient(to right, #800000, #ff0000, #ffdab9); |
| | background-clip: text; |
| | -webkit-background-clip: text; |
| | text-fill-color: transparent; |
| | -webkit-text-fill-color: transparent; |
| | margin: 0; |
| | text-shadow: 0 2px 5px rgba(0, 0, 0, 0.4); |
| | ">Select an option</h3> |
| | </div> |
| | </body> |
| | </html> |
| | """ |
| |
|
| | st.markdown(html_subject, unsafe_allow_html=True) |
| |
|
| | |
| | upload_option = st.radio("", ["Upload Spreadsheet (CSV or Excel)", "Google Sheets URL"]) |
| |
|
| |
|
| | |
| | if upload_option == "Upload Spreadsheet (CSV or Excel)": |
| | html_subject = """ |
| | <html> |
| | <head> |
| | <style> |
| | .button { |
| | display: inline-block; |
| | padding: 10px 20px; |
| | border-radius: 12px; |
| | background: linear-gradient(to bottom, #f8f9fa, #e0e0e0); |
| | box-shadow: |
| | 0 6px 12px rgba(0, 0, 0, 0.3), |
| | 0 8px 16px rgba(0, 0, 0, 0.2), |
| | inset 0 -2px 4px rgba(255, 255, 255, 0.6); |
| | text-align: center; |
| | position: relative; |
| | transform: translateY(4px); |
| | transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out; |
| | cursor: pointer; |
| | user-select: none; |
| | } |
| | .button:hover { |
| | box-shadow: |
| | 0 8px 16px rgba(0, 0, 0, 0.3), |
| | 0 12px 24px rgba(0, 0, 0, 0.2); |
| | transform: translateY(2px); |
| | } |
| | .button:active { |
| | box-shadow: |
| | 0 4px 8px rgba(0, 0, 0, 0.3), |
| | 0 6px 12px rgba(0, 0, 0, 0.2); |
| | transform: translateY(0); |
| | } |
| | </style> |
| | </head> |
| | <body> |
| | <div class="button"> |
| | <h3 style=" |
| | font-size: 20px; |
| | color: #ffffff; |
| | background-image: linear-gradient(to right, #800000, #ff0000, #ffdab9); |
| | background-clip: text; |
| | -webkit-background-clip: text; |
| | text-fill-color: transparent; |
| | -webkit-text-fill-color: transparent; |
| | margin: 0; |
| | text-shadow: 0 2px 5px rgba(0, 0, 0, 0.4); |
| | ">Upload documents</h3> |
| | </div> |
| | </body> |
| | </html> |
| | """ |
| |
|
| | st.markdown(html_subject, unsafe_allow_html=True) |
| | uploaded_file = st.file_uploader("", type=["csv", "xlsx"]) |
| | if uploaded_file: |
| | |
| | if uploaded_file.name.endswith(".csv"): |
| | df = pd.read_csv(uploaded_file) |
| | else: |
| | df = pd.read_excel(uploaded_file) |
| |
|
| | st.write("") |
| | st.write("") |
| |
|
| | elif upload_option == "Google Sheets URL": |
| | html_subject = """ |
| | <html> |
| | <head> |
| | <style> |
| | .button { |
| | display: inline-block; |
| | padding: 10px 20px; |
| | border-radius: 12px; |
| | background: linear-gradient(to bottom, #f8f9fa, #e0e0e0); |
| | box-shadow: |
| | 0 6px 12px rgba(0, 0, 0, 0.3), |
| | 0 8px 16px rgba(0, 0, 0, 0.2), |
| | inset 0 -2px 4px rgba(255, 255, 255, 0.6); |
| | text-align: center; |
| | position: relative; |
| | transform: translateY(4px); |
| | transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out; |
| | cursor: pointer; |
| | user-select: none; |
| | } |
| | .button:hover { |
| | box-shadow: |
| | 0 8px 16px rgba(0, 0, 0, 0.3), |
| | 0 12px 24px rgba(0, 0, 0, 0.2); |
| | transform: translateY(2px); |
| | } |
| | .button:active { |
| | box-shadow: |
| | 0 4px 8px rgba(0, 0, 0, 0.3), |
| | 0 6px 12px rgba(0, 0, 0, 0.2); |
| | transform: translateY(0); |
| | } |
| | </style> |
| | </head> |
| | <body> |
| | <div class="button"> |
| | <h3 style=" |
| | font-size: 20px; |
| | color: #ffffff; |
| | background-image: linear-gradient(to right, #800000, #ff0000, #ffdab9); |
| | background-clip: text; |
| | -webkit-background-clip: text; |
| | text-fill-color: transparent; |
| | -webkit-text-fill-color: transparent; |
| | margin: 0; |
| | text-shadow: 0 2px 5px rgba(0, 0, 0, 0.4); |
| | ">Enter Google sheets url</h3> |
| | </div> |
| | </body> |
| | </html> |
| | """ |
| |
|
| | st.markdown(html_subject, unsafe_allow_html=True) |
| | sheet_url = st.text_input("") |
| | if sheet_url: |
| | try: |
| | |
| | scope = ["https://spreadsheets.google.com/feeds", 'https://www.googleapis.com/auth/drive'] |
| |
|
| | |
| | creds = ServiceAccountCredentials.from_json_keyfile_name('fynd-db-48954327ef17.json', scope) |
| | client = gspread.authorize(creds) |
| |
|
| | |
| | sheet = client.open_by_url(sheet_url).sheet1 |
| | data = sheet.get_all_records() |
| | df = pd.DataFrame(data) |
| |
|
| | except Exception as e: |
| | st.error(f"Failed to load Google Sheets: {str(e)}") |
| |
|
| | if 'df' in locals(): |
| | |
| | df = df.drop(columns=['status'], errors='ignore') |
| | st.dataframe(df) |
| |
|
| | button_styles = """ |
| | <style> |
| | div.stButton > button { |
| | color: #ffffff; /* Text color */ |
| | font-size: 30px; |
| | background-image: linear-gradient(to right, #800000, #ff0000); /* Maroon to light red gradient */ |
| | border: none; |
| | padding: 10px 20px; |
| | cursor: pointer; |
| | border-radius: 15px; |
| | display: inline-block; |
| | box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1), 0 8px 15px rgba(0, 0, 0, 0.1); /* Box shadow */ |
| | transition: all 0.3s ease; /* Smooth transition on hover */ |
| | } |
| | div.stButton > button:hover { |
| | background-color: #00ff00; /* Hover background color */ |
| | color: #ff0000; /* Hover text color */ |
| | box-shadow: 0 6px 10px rgba(0, 0, 0, 0.2), 0 12px 20px rgba(0, 0, 0, 0.2); /* Box shadow on hover */ |
| | } |
| | </style> |
| | """ |
| | st.markdown(button_styles, unsafe_allow_html=True) |
| |
|
| | if st.button("Send Emails"): |
| | |
| | for index, row in df.iterrows(): |
| | email = row['Email Addresses'] |
| | subject = row['Subject'] |
| | message = row['Message'] |
| | cc_addresses = row['CC Addresses'].split(',') if 'CC Addresses' in row else [] |
| | Folder_IDs = row['Folder IDs'].split(',') |
| | |
| | |
| |
|
| | |
| | msg = MIMEMultipart() |
| | msg['From'] = EMAIL_HOST_USER |
| | msg['To'] = email |
| | msg['Subject'] = subject |
| |
|
| | if cc_addresses: |
| | msg['Cc'] = ','.join(cc_addresses) |
| |
|
| | body = f"""{message}""" |
| | msg.attach(MIMEText(body, 'plain')) |
| |
|
| |
|
| | |
| | for folder_id in Folder_IDs: |
| | pdf_path = folder_id.strip() |
| | if pdf_path.endswith('.pdf'): |
| | pdf_content = read_file(pdf_path) |
| | if pdf_content: |
| | part = MIMEApplication(pdf_content, Name=os.path.basename(pdf_path)) |
| | part['Content-Disposition'] = f'attachment; filename="{os.path.basename(pdf_path)}"' |
| | msg.attach(part) |
| |
|
| | |
| | |
| | for folder_id in Folder_IDs: |
| | csv_path = folder_id.strip() |
| | if csv_path.endswith('.csv'): |
| | csv_content = read_file(csv_path) |
| | if csv_content: |
| | part = MIMEApplication(csv_content, Name=os.path.basename(csv_path)) |
| | part['Content-Disposition'] = f'attachment; filename="{os.path.basename(csv_path)}"' |
| | msg.attach(part) |
| |
|
| | |
| | for folder_id in Folder_IDs: |
| | xlsx_path = folder_id.strip() |
| | if xlsx_path.endswith('.xlsx'): |
| | xlsx_content = read_file(xlsx_path) |
| | if xlsx_content: |
| | part = MIMEApplication(xlsx_content, Name=os.path.basename(xlsx_path)) |
| | part['Content-Disposition'] = f'attachment; filename="{os.path.basename(xlsx_path)}"' |
| | msg.attach(part) |
| |
|
| |
|
| |
|
| | |
| | for folder_id in Folder_IDs: |
| | zip_path = folder_id.strip() |
| | if zip_path.endswith('.zip'): |
| | zip_content = read_file(zip_path) |
| | if zip_content: |
| | part = MIMEApplication(zip_content, Name=os.path.basename(zip_path)) |
| | part['Content-Disposition'] = f'attachment; filename="{os.path.basename(zip_path)}"' |
| | msg.attach(part) |
| |
|
| |
|
| | |
| | try: |
| | with smtplib.SMTP(EMAIL_HOST, EMAIL_PORT) as server: |
| | server.starttls() |
| | server.login(EMAIL_HOST_USER, EMAIL_HOST_PASSWORD) |
| | server.sendmail(msg['From'], [email] + cc_addresses, msg.as_string()) |
| | st.success(f"Email sent to {email}") |
| | except Exception as e: |
| | st.error(f"Failed to send email to {email}: {str(e)}") |
| |
|
| | |
| |
|
| | elif selected_option == "Internal users": |
| | with open('ap.py') as file: |
| | exec(file.read()) |
| |
|
| | elif selected_option == "Recon checking": |
| | with open('recon.py') as file: |
| | exec(file.read()) |
| |
|
| | elif selected_option == "Manual BQ upload": |
| | with open('bq.py') as file: |
| | exec(file.read()) |
| |
|
| | elif selected_option == "Invoice splitter": |
| | with open('splitter.py') as file: |
| | exec(file.read()) |
| |
|
| | elif selected_option == "Seller sale validation": |
| | with open('seller.py') as file: |
| | exec(file.read()) |
| |
|
| | elif selected_option == "Payment working": |
| | with open('payments.py') as file: |
| | exec(file.read()) |
| |
|
| |
|
| |
|