add pages
This commit is contained in:
7
app.py
7
app.py
@@ -39,11 +39,16 @@ elif page_label == "Lesson2":
|
||||
pg.pythonx_lesson2()
|
||||
elif page_label == "Lesson3":
|
||||
pg.pythonx_lesson3()
|
||||
|
||||
elif page_label == "Lesson4":
|
||||
pg.pythonx_lesson4()
|
||||
|
||||
# block of CIS Tech Challenge Event
|
||||
elif page_label == "CIS Tech Challenge":
|
||||
pg.cis_tech_challenge_homepage()
|
||||
|
||||
# block of CoreTeks
|
||||
elif page_label == "CoreTeks":
|
||||
pg.coreteks_homepage()
|
||||
# block for testing page
|
||||
elif page_label == "Testing":
|
||||
pg.testing()
|
||||
|
||||
BIN
files/student_locations.db
Normal file
BIN
files/student_locations.db
Normal file
Binary file not shown.
BIN
images/11-05-2024-Streamlit.jpg
Normal file
BIN
images/11-05-2024-Streamlit.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 187 KiB |
BIN
images/11-19-2024-CaddyAndLinux.jpg
Normal file
BIN
images/11-19-2024-CaddyAndLinux.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 515 KiB |
BIN
images/CoreTeksPicture.png
Normal file
BIN
images/CoreTeksPicture.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 MiB |
115
webpages/SendEmail.py
Normal file
115
webpages/SendEmail.py
Normal file
@@ -0,0 +1,115 @@
|
||||
import smtplib
|
||||
from email.mime.text import MIMEText
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
|
||||
|
||||
# Function to send an email notification
|
||||
def send_email(sender_email, password, to_email, subject):
|
||||
# Create a MIMEMultipart email object to support multiple parts (e.g., HTML content)
|
||||
message = MIMEMultipart('alternative')
|
||||
message['Subject'] = subject # Set the email subject
|
||||
message['From'] = sender_email # Set the sender's email address
|
||||
message['To'] = to_email # Set the recipient's email address
|
||||
|
||||
# HTML content for the email body
|
||||
html_content = """
|
||||
<html>
|
||||
<head>
|
||||
<title>Welcome to BuffTeks!</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
.container {
|
||||
max-width: 600px;
|
||||
margin: 20px auto;
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
}
|
||||
.header {
|
||||
background-color: #450012;
|
||||
color: white;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.content {
|
||||
padding: 20px;
|
||||
}
|
||||
.content a {
|
||||
color: #4CAF50;
|
||||
text-decoration: none;
|
||||
}
|
||||
.content a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.footer {
|
||||
background-color: #f1f1f1;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
Welcome to BuffTeks!
|
||||
</div>
|
||||
<div class="content">
|
||||
<p>Dear New Member,</p>
|
||||
|
||||
<p>Thank you for your interest in the <a href="https://buffteks.org" target="_blank">BuffTeks</a> student organization! We're excited to have you with us. To further enrich your experience and connect with fellow members, we have set up a Discord server for BuffTeks. This platform will allow you to engage in discussions, seek help, share insights, and participate in various club activities.</p>
|
||||
|
||||
<p>Please join the BuffTeks Discord via the invitation link: <a href="https://discord.gg/dU8vKfAjxv" target="_blank">https://discord.gg/dU8vKfAjxv</a></p>
|
||||
|
||||
<p>Once you're in, take a moment to review our server rules and introduce yourself in the "Introductions" channel. If you have any questions, don't hesitate to reach out.</p>
|
||||
|
||||
<p>We look forward to seeing you there!</p>
|
||||
|
||||
<p>Sincerely,</p>
|
||||
|
||||
<p>BuffTeks Faculty Advisor</p>
|
||||
<p>Cheng (Carl) Zhang, Ph.D.<br>
|
||||
Paul Engler Professor of Business Innovation<br>
|
||||
Assistant Professor of Computer Information Systems<br>
|
||||
Paul and Virginia Engler College of Business<br>
|
||||
West Texas A&M University, Canyon, TX<br>
|
||||
Email: czhang@wtamu.edu<br>
|
||||
</p>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© 2024 BuffTeks Student Organization
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
# Convert the HTML content to a MIMEText object for HTML format
|
||||
html_part = MIMEText(html_content, 'html')
|
||||
|
||||
# Attach the HTML part to the MIMEMultipart message
|
||||
message.attach(html_part)
|
||||
|
||||
try:
|
||||
# Connect to the SMTP server and send the email
|
||||
with smtplib.SMTP('mail.privateemail.com', 587) as server:
|
||||
server.starttls() # Enable TLS encryption for secure connection
|
||||
server.login(sender_email, password) # Log in with the sender's email and password
|
||||
server.send_message(message) # Send the email message
|
||||
print("Email sent successfully!")
|
||||
except Exception as e:
|
||||
# Catch and display any exceptions that occur during the sending process
|
||||
print(f"Failed to send email: {str(e)}")
|
||||
|
||||
|
||||
|
||||
@@ -9,5 +9,8 @@ from .pythonx_lessons_pages.pythonx_homepage import pythonx_homepage
|
||||
from .pythonx_lessons_pages.pythonx_lesson1 import pythonx_lesson1
|
||||
from .pythonx_lessons_pages.pythonx_lesson2 import pythonx_lesson2
|
||||
from .pythonx_lessons_pages.pythonx_lesson3 import pythonx_lesson3
|
||||
from .pythonx_lessons_pages.pythonx_lesson4 import pythonx_lesson4
|
||||
from .outstanding_members import outstanding_members
|
||||
from .cis_tech_challenge_pages.cis_tech_challenge_homepage import cis_tech_challenge_homepage
|
||||
from .cis_tech_challenge_pages.cis_tech_challenge_homepage import cis_tech_challenge_homepage
|
||||
from .coreteks_pages.coreteks_homepage import coreteks_homepage
|
||||
from .SendEmail import send_email
|
||||
BIN
webpages/__pycache__/SendEmail.cpython-312.pyc
Normal file
BIN
webpages/__pycache__/SendEmail.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -2,6 +2,12 @@ import streamlit as st
|
||||
|
||||
def classroom():
|
||||
st.title("BuffTeks Classroom")
|
||||
st.divider()
|
||||
|
||||
st.divider()
|
||||
|
||||
st.title("PythonX")
|
||||
st.image("./images/PythonXPicture.png")
|
||||
st.image("./images/PythonXPicture.png", caption = "Learn coding in Python")
|
||||
|
||||
st.divider()
|
||||
st.title("CoreTeks")
|
||||
st.image("./images/CoreTeksPicture.png", caption="Sharing and learning new tech skills")
|
||||
Binary file not shown.
35
webpages/coreteks_pages/coreteks_homepage.py
Normal file
35
webpages/coreteks_pages/coreteks_homepage.py
Normal file
@@ -0,0 +1,35 @@
|
||||
import streamlit as st
|
||||
|
||||
def coreteks_homepage():
|
||||
# load pythonx logo
|
||||
st.image("./images/CoreTeksPicture.png")
|
||||
|
||||
st.header(" :clap: Welcome to CoreTeks")
|
||||
|
||||
st.markdown(
|
||||
"""
|
||||
CoreTeks is an engaging and dynamic course designed to explore the ever-evolving world of IT technologies. Our mission is to connect learners with industry professionals and passionate individuals who are eager to share their expertise.
|
||||
|
||||
Through a series of guest speaker sessions, CoreTeks introduces members to popular and cutting-edge IT tools, techniques, and innovations. Whether you're a seasoned expert or someone with unique IT skills to share, we welcome you to inspire and educate our community.
|
||||
|
||||
Join us at CoreTeks, where knowledge meets collaboration, and technology shapes the future!
|
||||
"""
|
||||
)
|
||||
|
||||
st.divider()
|
||||
|
||||
st.header(" :paperclip: CoreTeks Presentations")
|
||||
# for streamlit talk
|
||||
st.subheader(" :one: Introduction to Streamlit")
|
||||
st.image("./images/11-05-2024-Streamlit.jpg", width= 700)
|
||||
st.link_button(label="Watch Video Recording", use_container_width=True, type="primary", url="https://wtamu0-my.sharepoint.com/:v:/g/personal/czhang_wtamu_edu/EZBXalcLWaxHquMkZxOWXz8BV2yBo_A1OURZin0ZM0XliQ?nav=eyJyZWZlcnJhbEluZm8iOnsicmVmZXJyYWxBcHAiOiJPbmVEcml2ZUZvckJ1c2luZXNzIiwicmVmZXJyYWxBcHBQbGF0Zm9ybSI6IldlYiIsInJlZmVycmFsTW9kZSI6InZpZXciLCJyZWZlcnJhbFZpZXciOiJNeUZpbGVzTGlua0NvcHkifX0&e=SJD0A4", )
|
||||
st.divider()
|
||||
|
||||
# for linux talk
|
||||
st.subheader(" :two: Linux Security and Web Server Setup")
|
||||
st.image("./images/11-19-2024-CaddyAndLinux.jpg", width= 500)
|
||||
st.link_button(label="Watch Video Recording", use_container_width=True, type="primary", url="https://wtamu0-my.sharepoint.com/:v:/g/personal/czhang_wtamu_edu/EdgZHrnkqihNrOZGYAT6O2MBSRBOBMv3czD_uIE21KgsWw?nav=eyJyZWZlcnJhbEluZm8iOnsicmVmZXJyYWxBcHAiOiJPbmVEcml2ZUZvckJ1c2luZXNzIiwicmVmZXJyYWxBcHBQbGF0Zm9ybSI6IldlYiIsInJlZmVycmFsTW9kZSI6InZpZXciLCJyZWZlcnJhbFZpZXciOiJNeUZpbGVzTGlua0NvcHkifX0&e=obIoyY", )
|
||||
st.link_button(label="Download PDF Instruction", use_container_width=True, type="primary", url="https://wtamu0-my.sharepoint.com/:b:/g/personal/czhang_wtamu_edu/Eaygqoc_FqxNgYj3BlEOXhsBzOj-BWTbNKwkpJEYSDBwgA?e=K7qxSU", )
|
||||
st.divider()
|
||||
|
||||
|
||||
@@ -1,4 +1,51 @@
|
||||
import streamlit as st
|
||||
from .SendEmail import send_email
|
||||
import time
|
||||
|
||||
|
||||
def join_us():
|
||||
st.html("https://wtamuuw.az1.qualtrics.com/jfe/form/SV_2boQtKLCptO33HE")
|
||||
st.title("Join Us")
|
||||
st.write("Thank you for your interest in the BuffTeks student organization! Please share your information below, \
|
||||
and our Faculty Advisor will send you an invitation to join our Discord channel. \
|
||||
If you have any questions, feel free to contact our Faculty Advisor, Dr. Carl Zhang, at czhang@wtamu.edu.")
|
||||
|
||||
full_name = st.text_input("**Full Name**")
|
||||
wt_email = st.text_input("**WT Email**")
|
||||
major_list = ["Accounting", "Computer Infromation Systems", "Economics", "Finance", "General Business", "Management", "Marketing", "Other"]
|
||||
stu_major = st.radio("**Major/Field of Study**",major_list)
|
||||
if stu_major == "Other":
|
||||
other_major = st.text_input("Please specify the other major")
|
||||
stu_major = other_major
|
||||
|
||||
year_of_study_list = ["Freshman", "Sophomore", "Junior", "Senior", "Graduate"]
|
||||
stu_year = st.radio("**Year of Study**", year_of_study_list)
|
||||
|
||||
skills_options = ["Programming", "Cybersecurity", "Web Development", "Mobile App Development", "machine Learning/AI", "Data Analysis", "Other"]
|
||||
skills_selection = st.multiselect(
|
||||
label= "**Technical Skills You Are Interested In (Please check all that apply)**",
|
||||
options = skills_options,
|
||||
placeholder = "Choose all that apply")
|
||||
if "Other" in skills_selection:
|
||||
other_skill = st.text_input("**Please specify the other skills**")
|
||||
skills_selection.remove("Other")
|
||||
skills_selection.append(f"Other ({other_skill})")
|
||||
|
||||
next_btn = st.button("Next")
|
||||
|
||||
if next_btn:
|
||||
if "wtamu.edu" not in wt_email:
|
||||
st.warning("Please input your WT Email address to receive invitation")
|
||||
with st.spinner('Sending Email...'):
|
||||
send_email(sender_email="noreply@buffteks.org", password="cidm4360fall2024@*", to_email=wt_email, subject=f"Welcome to join ButtTeks, {full_name}!")
|
||||
st.balloons()
|
||||
st.success("Thanks for submitting your information, you will receive an invitation email shortly. \n Please contact Dr.Zhang (czhang@wtamu.edu) if you need any help.")
|
||||
|
||||
# @st.dialog("Check Email")
|
||||
# def confirm_email(wt_email, full_name):
|
||||
# st.write(f"Please double-check your **WT Email** in order to receive our invitation: \n {wt_email}")
|
||||
# if st.button("Confirm & Submit"):
|
||||
# send_email(sender_email="noreply@buffteks.org", password="cidm4360fall2024@*", to_email=wt_email, subject=f"Welcome to join ButtTeks, {full_name}!")
|
||||
# st.rerun()
|
||||
# return True
|
||||
|
||||
|
||||
@@ -25,13 +25,16 @@ def navigation_bar():
|
||||
sac.MenuItem('Lesson1', icon='1-square'),
|
||||
sac.MenuItem('Lesson2', icon='2-square'),
|
||||
sac.MenuItem('Lesson3', icon='3-square'),
|
||||
]),
|
||||
]),
|
||||
sac.MenuItem("Testing", icon='fingerprint'),
|
||||
sac.MenuItem(type='divider'),
|
||||
sac.MenuItem('Link', type='group', children=[
|
||||
sac.MenuItem('Join Us', icon='person-plus', href='https://wtamuuw.az1.qualtrics.com/jfe/form/SV_2boQtKLCptO33HE'),
|
||||
sac.MenuItem('Lesson4', icon='4-square'),
|
||||
]),
|
||||
sac.MenuItem('CoreTeks', icon='bi bi-tools'),
|
||||
]),
|
||||
sac.MenuItem("Join Us", icon='person-add'),
|
||||
# sac.MenuItem("Testing", icon='fingerprint'),
|
||||
# sac.MenuItem(type='divider'),
|
||||
# sac.MenuItem('Link', type='group', children=[
|
||||
# sac.MenuItem('Join Us', icon='person-plus', href='https://wtamuuw.az1.qualtrics.com/jfe/form/SV_2boQtKLCptO33HE'),
|
||||
# ]),
|
||||
|
||||
sac.MenuItem(type='divider'),
|
||||
sac.MenuItem("Reference", icon='paperclip'),
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
123
webpages/pythonx_lessons_pages/pythonx_lesson4.py
Normal file
123
webpages/pythonx_lessons_pages/pythonx_lesson4.py
Normal file
@@ -0,0 +1,123 @@
|
||||
|
||||
import streamlit as st
|
||||
import pandas as pd
|
||||
import folium
|
||||
from streamlit_folium import folium_static
|
||||
from geopy.geocoders import Nominatim
|
||||
import sqlite3
|
||||
from datetime import datetime
|
||||
from folium.features import CustomIcon
|
||||
|
||||
|
||||
def pythonx_lesson4():
|
||||
# Initialize the database
|
||||
conn = sqlite3.connect('./files/student_locations.db')
|
||||
c = conn.cursor()
|
||||
c.execute('''CREATE TABLE IF NOT EXISTS students
|
||||
(id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
city TEXT,
|
||||
state TEXT,
|
||||
country TEXT,
|
||||
latitude REAL,
|
||||
longitude REAL,
|
||||
timestamp DATETIME)''')
|
||||
conn.commit()
|
||||
|
||||
|
||||
st.title('Where are Members From')
|
||||
|
||||
# Input form for student location
|
||||
with st.form("student_form"):
|
||||
input_city = st.text_input("Enter your City, State (e.g.: Amarillo,TX), or City, Country (Toronto, Canada):")
|
||||
|
||||
submitted = st.form_submit_button("Submit")
|
||||
|
||||
if submitted:
|
||||
lat, lon, city, state, country = get_location(input_city)
|
||||
if lat and lon:
|
||||
save_student(conn, city, state, country, lat, lon)
|
||||
st.success(f"Location saved: {city}, {country}")
|
||||
else:
|
||||
st.error("Unable to find the location. Please try a different city name.")
|
||||
|
||||
# Display all students on a map
|
||||
st.subheader('All Student Locations')
|
||||
df = get_all_students(conn)
|
||||
if not df.empty:
|
||||
m = create_map(df)
|
||||
folium_static(m)
|
||||
else:
|
||||
st.write("No student data available yet.")
|
||||
|
||||
# Display student statistics
|
||||
st.subheader('Student Statistics')
|
||||
if not df.empty:
|
||||
st.write(f"Total students: {len(df)}")
|
||||
st.write(f"Total cities: {df['city'].nunique()}")
|
||||
st.write(f"Total countries: {df['country'].nunique()}")
|
||||
st.write("Top 5 cities:")
|
||||
st.write(df['city'].value_counts().head())
|
||||
st.write("Top 5 countries:")
|
||||
st.write(df['country'].value_counts().head())
|
||||
else:
|
||||
st.write("No student data available yet.")
|
||||
|
||||
# Close the database connection
|
||||
conn.close()
|
||||
|
||||
|
||||
|
||||
def get_location(city):
|
||||
geolocator = Nominatim(user_agent="student_location_app")
|
||||
try:
|
||||
location = geolocator.geocode(city, language="en")
|
||||
st.write(location)
|
||||
if location:
|
||||
location_str = str(location).split(",")
|
||||
state, country = location_str[2], location_str[-1]
|
||||
return location.latitude, location.longitude, location.raw.get('name'), state, country
|
||||
else:
|
||||
return None, None, None, None, None
|
||||
except Exception as e:
|
||||
st.write(e)
|
||||
return None, None, None, None, None
|
||||
|
||||
|
||||
def save_student(conn, city, state, country, lat, lon):
|
||||
c = conn.cursor()
|
||||
timestamp = datetime.now()
|
||||
c.execute("INSERT INTO students (city, state, country, latitude, longitude, timestamp) VALUES (?, ?, ?, ?, ?, ?)",
|
||||
(city, state, country, lat, lon, timestamp))
|
||||
conn.commit()
|
||||
|
||||
def get_all_students(conn):
|
||||
df = pd.read_sql_query("SELECT * from students", conn)
|
||||
return df
|
||||
|
||||
def create_map(df):
|
||||
m = folium.Map(location=[41.2706, -97.1749], zoom_start=4)
|
||||
|
||||
# Group by city and count occurrences
|
||||
city_counts = df.groupby(['city', 'state', 'latitude', 'longitude', 'country']).size().reset_index(name='count')
|
||||
|
||||
# Normalize marker sizes
|
||||
max_count = city_counts['count'].max()
|
||||
min_size, max_size = 5, 20 # min and max marker sizes
|
||||
|
||||
for _, row in city_counts.iterrows():
|
||||
# Create a custom icon
|
||||
icon = CustomIcon(
|
||||
icon_image='./images/BuffaloMarker.png', # Replace with the path to your icon file
|
||||
icon_size=(30, 30), # Adjust the size as needed
|
||||
icon_anchor=(15, 30), # Adjust anchor point if needed
|
||||
popup_anchor=(0, -30) # Adjust popup anchor if needed
|
||||
)
|
||||
|
||||
folium.Marker(
|
||||
location=[row['latitude'], row['longitude']],
|
||||
popup=f"{row['city']} <br> {row['count']}",
|
||||
tooltip=f"{row['city']}, {row['country']}",
|
||||
icon=icon
|
||||
).add_to(m)
|
||||
|
||||
return m
|
||||
@@ -1,8 +1,14 @@
|
||||
import streamlit as st
|
||||
from webpages.SendEmail import send_email
|
||||
|
||||
|
||||
# # Example usage of the send_email function
|
||||
# if __name__ == "__main__":
|
||||
# send_email(
|
||||
# sender_email="noreply@buffteks.org", # Sender's email address
|
||||
# password="cidm4360fall2024@*", # Sender's email password
|
||||
# to_email="REPLACE_WITH_RESIDENT_EMAIL", # Recipient's email address
|
||||
# subject="Package Pickup Notification", # Subject of the email
|
||||
# )
|
||||
|
||||
def testing():
|
||||
st.title("Testing Page")
|
||||
|
||||
|
||||
st.write("Testing Page")
|
||||
|
||||
Reference in New Issue
Block a user