Spaces:
Running
Running
import streamlit as st | |
import requests | |
from pymongo.mongo_client import MongoClient | |
from pymongo.server_api import ServerApi | |
from datetime import datetime | |
import random | |
st.set_page_config( | |
page_title="Climate Action", | |
page_icon="π", | |
initial_sidebar_state="expanded", | |
layout="wide" | |
) | |
st.markdown( | |
""" <style> | |
div[role="radiogroup"] > :first-child{ | |
display: none !important; | |
} | |
</style> | |
""", | |
unsafe_allow_html=True | |
) | |
### Setting up the session state | |
if 'inserted' not in st.session_state: | |
st.session_state["model"] = "google" | |
# web app state | |
st.session_state.gotit = False | |
st.session_state.submitted = False | |
st.session_state.inserted = 0 | |
st.session_state.max_messages = 50 | |
st.session_state.clicked_links = [] | |
st.session_state.messages = [{"query": "", "results": {}, "page": 1, "time": datetime.now()}] | |
st.session_state.user_data = {} | |
# user info state | |
st.session_state.fields = [ | |
'climate_actions', 'age', 'gender', 'education', 'residence', 'property', 'car', | |
'politics', 'impact_open', 'ev', | |
'fossil', 'aerosol', 'diet', 'recycling', | |
'user_id' | |
] | |
for field in st.session_state.fields: | |
st.session_state[field] = '' | |
st.session_state.user_id = str(random.randint(100000, 999999)) | |
st.session_state.recycling = 0 | |
st.session_state.start_time = datetime.now() | |
st.session_state.convo_start_time = '' | |
RESULTS_PER_PAGE = 10 | |
if "page" not in st.session_state: | |
st.session_state.page = 1 | |
if 'p' not in st.query_params: | |
st.query_params['p'] = 'g' | |
### App interface | |
with st.sidebar: | |
st.markdown("# Let's talk climate action!") | |
st.markdown(f""" | |
{"β" if st.session_state.submitted else "β"} **Step 1. Complete a form** | |
{"β" if len(st.session_state.messages) > 1 else "β"} **Step 2. Type in the search box to search Google** | |
π± You should ask a climate change related question like: | |
- *What are the most effective actions to reduce my carbon emissions?* | |
- *What's better for the environment: a year of vegetarianism or skipping one transatlantic flight?* | |
- *How do the emissions saved by switching to an EV compare to recycling for a year in terms of trees planted?* | |
β Do not share any personal information (e.g., name or address). | |
β οΈ You must click on **at least 5 links** before you will see a *Finish* button. You can continue before submitting, but **you must finish and enter your completion code into the survey to recieve compensation**. | |
β If you encounter any technical issues, please let us know. | |
{"β" if st.session_state.inserted > 1 else "β"} **Step 3. Use the *Finish* button to get your completion code** | |
β οΈ Do not forget to copy & paste your completion code! | |
βΊ You can always return to this panel by clicking the arrow on the top left. | |
{"π **All done! Please enter your code in the survye and press *Next*.**" if st.session_state.inserted > 1 else ""} | |
""") | |
if st.session_state.gotit == False or st.session_state.submitted == False: | |
st.session_state.gotit = st.button("Let's start!", key=None, help=None, use_container_width=True) | |
def google_search(query, page): | |
start_index = (page - 1) * RESULTS_PER_PAGE + 1 | |
url = f"https://www.googleapis.com/customsearch/v1?q={query}&key={st.secrets['GOOGLE_API_KEY']}&cx={st.secrets['GOOGLE_CX']}&start={start_index}" | |
response = requests.get(url) | |
return response.json() | |
def display_results(results): | |
for item in results.get('items', []): | |
col1, col2 = st.columns([1, 5], vertical_alignment='center') | |
image_url = None | |
if "pagemap" in item and "cse_thumbnail" in item["pagemap"]: | |
image_url = item["pagemap"]["cse_thumbnail"][0]["src"] | |
with col1: | |
if image_url: | |
st.image(image_url, width=160) | |
with col2: | |
if st.button(f"π **{item['title']}**", item['link'], type='tertiary'): | |
st.session_state.clicked_links.append({"link": item['link'], "time": datetime.now()}) | |
#webbrowser.open(item['link']) | |
st.markdown(f"[Click to view: {item['link']}]({item['link']})") | |
st.markdown(item['snippet']) | |
st.divider() | |
def form(): | |
st.markdown("**Please answer every question to proceed.**") | |
st.session_state.age = st.text_input("How old are you in years?") | |
st.session_state.gender = st.radio("Do you describe yourself as a man, a woman, or in some other way?", | |
['','Man', 'Woman', 'Other']) | |
st.session_state.education = st.radio("What is the highest level of education you completed?", | |
['', | |
'Did not graduate high school', | |
'High school graduate, GED, or alternative', | |
'Some college, or associates degree', | |
"Bachelor's (college) degree or equivalent", | |
"Graduate degree (e.g., Master's degree, MBA)", | |
'Doctorate degree (e.g., PhD, MD)']) | |
st.session_state.politics = st.radio('What is your political orientation?', ['', 'Extremely liberal', 'Liberal', 'Slightly liberal', 'Moderate', 'Slightly conservative', 'Conservative', 'Extremely conservative']) | |
st.session_state.residence = st.radio("What type of a community do you live in?", | |
['', 'Urban','Suburban','Rural','Other']) | |
st.session_state.property = st.radio("Do you own or rent the home in which you live?", | |
['', 'Own', 'Rent', 'Neither (I live rent-free)', 'Other' ]) | |
st.session_state.car = st.radio("Do you own or lease a car?", | |
['', 'Own', 'Lease', 'Neither (I do not own or lease a car)']) | |
st.session_state.climate_actions = st.text_area('Please describe any actions you are taking to address climate change? Write *None* if you are not taking any.') | |
st.session_state.impact_open = st.text_area('What do you believe is the single most effective action you can take to reduce carbon emissions that contribute to climate change?') | |
st.session_state.recycling = st.slider('What percentage of plastic produced gets recycled?', 0, 100, value=0) | |
st.markdown("**Do you agree or disagree with the following statements?**") | |
st.session_state.ev = st.radio("Electric vehicles don't have enough range to handle daily travel demands.", ["", "Strongly Disagree", "Disagree", "Neutral", "Agree", "Strongly Agree"]) | |
st.session_state.fossil = st.radio('The fossil fuel industry is trying to shift the blame away from themselves by emphasizing the importance of individual climate action.', ["", "Strongly Disagree", "Disagree", "Neutral", "Agree", "Strongly Agree"]) | |
st.session_state.aerosol = st.radio('The use of aerosol spray cans is a major cause of climate change.', ["", "Strongly Disagree", "Disagree", "Neutral", "Agree", "Strongly Agree"]) | |
st.session_state.diet = st.radio('Lab-grown meat produces up to 25 times more CO2 than real meat.', ["", "Strongly Disagree", "Disagree", "Neutral", "Agree", "Strongly Agree"]) | |
columns_form = st.columns((1,1,1)) | |
with columns_form[2]: | |
submitted = st.button("Proceed",use_container_width=True, | |
help = 'Make sure you answer every question', | |
disabled = not (all(st.session_state[field] != '' for field in st.session_state.fields) and st.session_state.recycling != 0)) | |
if submitted: | |
st.session_state.user_data = {key: st.session_state[key] for key in st.session_state.fields} | |
st.session_state.user_data["model"] = st.session_state["model"] | |
st.session_state.user_data["condition"] = st.query_params['p'] | |
st.session_state.user_data["start_time"] = st.session_state.start_time | |
st.session_state.user_data["inserted"] = st.session_state.inserted | |
st.session_state.user_data["submission_time"] = datetime.now() | |
#with MongoClient(st.secrets["mongo"],server_api=ServerApi('1')) as client: | |
#db = client.chat | |
#collection = db.app | |
#user_data = st.session_state.user_data | |
#collection.insert_one(user_data) | |
st.session_state.inserted += 1 | |
st.session_state.submitted = True | |
st.rerun() | |
if st.session_state.gotit and st.session_state.submitted == False: | |
form() | |
if len(st.session_state.messages) >= st.session_state.max_messages: | |
st.info( | |
"You have reached the limit of searches for this search. Please end and submit the search." | |
) | |
elif st.session_state.submitted == False: | |
pass | |
elif st.session_state.inserted > 1: | |
st.markdown("## Copy your code!") | |
st.markdown('**Your completion code is:**') | |
st.markdown(f'## {st.session_state.user_id}') | |
st.markdown('**Please copy the code and enter it into the survey field below.**') | |
elif query := st.text_input("Enter search query and press Enter", placeholder="Search Google..."): | |
if query != st.session_state.messages[-1]["query"] or st.session_state.page != st.session_state.messages[-1]["page"]: | |
results = google_search(query, st.session_state.page) | |
st.session_state.messages.append({"query": query, "results": results, "page": st.session_state.page, "time": datetime.now()}) | |
display_results(st.session_state.messages[-1]["results"]) | |
col1, _, col2 = st.columns([.2, .6, .2]) | |
with col1: | |
if st.session_state.page > 1: | |
if st.button("β¬ οΈ Previous Page",use_container_width=True): | |
st.session_state.page -= 1 | |
st.rerun() | |
with col2: | |
if "nextPage" in st.session_state.messages[-1]["results"].get("queries", {}): | |
if st.button("Next Page β‘οΈ",use_container_width=True): | |
st.session_state.page += 1 | |
st.rerun() | |
if (len(st.session_state.clicked_links) > 4 or st.session_state.max_messages == len(st.session_state.messages)) and not st.session_state.inserted > 1: | |
columns = st.columns((1,1,1)) | |
with columns[2]: | |
if st.button("Finish",use_container_width=True): | |
keys = ["inserted", "messages", "convo_start_time", 'clicked_links'] | |
st.session_state.user_data.update({key: st.session_state[key] for key in keys}) | |
st.session_state.user_data["convo_end_time"] = datetime.now() | |
with MongoClient(st.secrets["mongo"],server_api=ServerApi('1')) as client: | |
db = client.chat | |
collection = db.app | |
user_data = st.session_state.user_data | |
#del user_data['_id'] | |
collection.insert_one(user_data) | |
st.session_state.inserted += 1 | |
st.rerun() | |