Skip to content

Commit a7ac47a

Browse files
authored
Add files via upload
1 parent 0876cf5 commit a7ac47a

File tree

1 file changed

+127
-56
lines changed

1 file changed

+127
-56
lines changed

streamlit_app.py

Lines changed: 127 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import streamlit as st
22
import pandas as pd
3-
import tempfile
3+
import tempfile
44
import os
55
from googleapiclient.discovery import build
66
from googleapiclient.http import MediaFileUpload
@@ -12,138 +12,201 @@
1212
FOLDER_ID = st.secrets["FOLDER_ID"]
1313
SHEET_ID = SPREADSHEET_ID
1414

15+
1516
def get_gdrive_service():
1617
"""Authenticates using the OAuth Refresh Token from st.secrets"""
1718
creds_info = st.secrets["google_oauth"]
1819
creds = Credentials(
19-
token=None,
20+
token=None,
2021
refresh_token=creds_info["refresh_token"],
2122
client_id=creds_info["client_id"],
2223
client_secret=creds_info["client_secret"],
2324
token_uri="https://oauth2.googleapis.com/token"
2425
)
2526
if not creds.valid:
2627
creds.refresh(Request())
27-
drive_service = build('drive', 'v3', credentials=creds)
28-
sheets_service = build('sheets', 'v4', credentials=creds)
28+
drive_service = build("drive", "v3", credentials=creds)
29+
sheets_service = build("sheets", "v4", credentials=creds)
2930
return drive_service, sheets_service
3031

32+
3133
# Initialize the services
3234
try:
3335
drive_service, sheets_service = get_gdrive_service()
3436
except Exception as e:
3537
st.error(f"Authentication Failed: {e}")
3638
st.stop()
3739

40+
3841
# --- 2. APP INTERFACE CONFIG ---
39-
st.set_page_config(page_title="Scientific Slide Library", layout="wide", page_icon="🔬")
42+
st.set_page_config(
43+
page_title="Scientific Slide Library",
44+
layout="wide",
45+
page_icon="🔬"
46+
)
4047

41-
# 5) BACKGROUND COLOR - Tag: BACKGROUND_STYLE
48+
# --- 3. GLOBAL STYLES ---
4249
st.markdown(
4350
"""
4451
<style>
4552
.stApp {
46-
background-color: #f0f0f0;
53+
background-color: #e6e6e6;
4754
}
48-
.stDataFrame {
55+
56+
div[data-testid="stDataFrame"] {
4957
background-color: white;
50-
border-radius: 5px;
58+
border-radius: 8px;
59+
padding: 6px;
60+
box-shadow: 0 2px 6px rgba(0,0,0,0.08);
61+
}
62+
63+
div[data-testid="stDataFrame"] td {
64+
white-space: normal !important;
65+
word-wrap: break-word;
66+
}
67+
68+
div[data-testid="stDataFrame"] tr:hover {
69+
background-color: #f5f7fa;
70+
}
71+
72+
h1, h2, h3 {
73+
color: #2c2c2c;
5174
}
5275
</style>
5376
""",
5477
unsafe_allow_html=True
5578
)
5679

57-
# 4) HEADER TEXT - Tag: HEADER_SECTION
58-
# Feel free to edit the text inside these quotes
80+
# --- 4. HEADER ---
5981
st.title("🔬 Scientific Slide Library")
60-
st.markdown("""
61-
Welcome to the central resource repository. Use this dashboard to browse through
62-
curated scientific presentations, search for specific topics, and access files directly.
63-
""")
64-
# --- END HEADER SECTION ---
82+
st.markdown(
83+
"""
84+
Welcome to the central resource repository.
85+
Browse curated scientific presentations, search for specific topics,
86+
and access downloadable files directly.
87+
"""
88+
)
6589

66-
# 1) SWAP TABS - Browse Library is now first (Default)
90+
# --- 5. TABS ---
6791
tab1, tab2 = st.tabs(["📚 Browse Library", "📤 Upload New Slides"])
6892

93+
94+
# =========================
95+
# 📚 TAB 1: BROWSE LIBRARY
96+
# =========================
6997
with tab1:
7098
st.header("Library Database")
71-
st.write("Search, filter, and access all stored presentations.")
72-
99+
100+
st.subheader("🔍 Search Library")
101+
search_query = st.text_input(
102+
"",
103+
placeholder="Search by title, description, keyword, or contact…"
104+
)
105+
73106
try:
74-
# Fetch all data from the Google Sheet
75107
result = sheets_service.spreadsheets().values().get(
76-
spreadsheetId=SHEET_ID, range="Sheet1!A:Z"
108+
spreadsheetId=SHEET_ID,
109+
range="Sheet1!A:Z"
77110
).execute()
78-
79-
values = result.get('values', [])
111+
112+
values = result.get("values", [])
80113

81114
if not values:
82115
st.info("The library is currently empty. Start by uploading a file!")
83116
else:
84-
# Create a DataFrame (assumes headers: Name, Description, Keywords, Link, Person)
85117
df = pd.DataFrame(values[1:], columns=values[0])
86-
87-
# --- 3) TWO LINK COLUMNS LOGIC ---
88-
# We create a "Download" link by modifying the Google Drive "View" link
89-
# Converting 'file/d/ID/view' to 'uc?export=download&id=ID'
118+
119+
# --- CREATE DOWNLOAD LINK ---
90120
def make_download_url(view_url):
91121
try:
92122
if "drive.google.com" in view_url:
93123
file_id = view_url.split("/d/")[1].split("/")[0]
94124
return f"https://drive.google.com/uc?export=download&id={file_id}"
95125
return view_url
96-
except:
126+
except Exception:
97127
return view_url
98128

99129
if "Link" in df.columns:
100130
df["Download"] = df["Link"].apply(make_download_url)
101131

102-
# Interactive Search
103-
search_query = st.text_input("Quick Filter", placeholder="Search by name, topic, or keyword...")
132+
# --- SEARCH FILTER ---
104133
if search_query:
105-
df = df[df.apply(lambda row: row.astype(str).str.contains(search_query, case=False).any(), axis=1)]
134+
df = df[df.apply(
135+
lambda row: row.astype(str).str.contains(search_query, case=False).any(),
136+
axis=1
137+
)]
138+
139+
# --- COLUMN ORDERING ---
140+
desired_order = [
141+
"Presentation Title",
142+
"Description",
143+
"Keywords",
144+
"Person", # Contact
145+
"Link", # View
146+
"Download" # Download
147+
]
148+
df = df[[c for c in desired_order if c in df.columns]]
106149

107-
# 2) NARROWER TABLE & WORD WRAP
150+
# --- DISPLAY TABLE ---
108151
st.dataframe(
109-
df,
110-
use_container_width=True,
152+
df,
153+
use_container_width=True,
111154
hide_index=True,
155+
height=600,
112156
column_config={
113-
"Presentation Title": st.column_config.TextColumn("Title", width="medium"),
114-
"Description": st.column_config.TextColumn("Topic/Description", width="large"),
115-
"Keywords": st.column_config.TextColumn("Keywords", width="small"),
116-
"Link": st.column_config.LinkColumn("View File", display_text="👁️ Open Sheets"),
117-
"Download": st.column_config.LinkColumn("Download", display_text="📥 Download")
157+
"Presentation Title": st.column_config.TextColumn(
158+
"Title", width="medium"
159+
),
160+
"Description": st.column_config.TextColumn(
161+
"Description", width="large"
162+
),
163+
"Keywords": st.column_config.TextColumn(
164+
"Keywords", width="small"
165+
),
166+
"Person": st.column_config.TextColumn(
167+
"Contact", width="small"
168+
),
169+
"Link": st.column_config.LinkColumn(
170+
"View", display_text="👁️ Open"
171+
),
172+
"Download": st.column_config.LinkColumn(
173+
"Download", display_text="📥 Download"
174+
)
118175
}
119176
)
120-
121-
if st.button("Refresh Database"):
177+
178+
if st.button("🔄 Refresh Database"):
122179
st.rerun()
123180

124181
except Exception as e:
125182
st.error(f"Could not load the database: {e}")
126183

184+
185+
# =========================
186+
# 📤 TAB 2: UPLOAD NEW FILE
187+
# =========================
127188
with tab2:
128189
st.header("Contribute to the Library")
129-
st.write("Upload your slides and fill out the details below.")
130-
190+
st.write("Upload your slides and provide the associated metadata.")
191+
131192
with st.form("upload_form", clear_on_submit=True):
132193
person = st.text_input("Your Name")
133194
name = st.text_input("Presentation Title")
134-
description = st.text_area("Topic/Description")
195+
description = st.text_area("Topic / Description")
135196
keywords = st.text_input("Keywords (comma separated)")
136-
uploaded_file = st.file_uploader("Choose Presentation File (PDF, PPTX, etc.)")
137-
197+
uploaded_file = st.file_uploader(
198+
"Choose Presentation File (PDF, PPTX, etc.)"
199+
)
200+
138201
submit_button = st.form_submit_button("Submit Entry")
139202

140203
if submit_button:
141204
if not name or not description:
142205
st.warning("Please provide at least a title and a description.")
143206
else:
144-
with st.spinner("Processing upload... please wait."):
207+
with st.spinner("Processing upload..."):
145208
file_link = "No file uploaded"
146-
209+
147210
if uploaded_file is not None:
148211
with tempfile.NamedTemporaryFile(delete=False) as tmp:
149212
tmp.write(uploaded_file.getvalue())
@@ -155,33 +218,41 @@ def make_download_url(view_url):
155218
"parents": [FOLDER_ID]
156219
}
157220
media = MediaFileUpload(tmp_path, resumable=True)
158-
221+
159222
uploaded_drive_file = drive_service.files().create(
160223
body=file_metadata,
161224
media_body=media,
162225
fields="id, webViewLink"
163226
).execute()
164-
227+
165228
file_link = uploaded_drive_file.get("webViewLink")
229+
166230
except Exception as e:
167231
st.error(f"Drive Error: {e}")
232+
168233
finally:
169234
if os.path.exists(tmp_path):
170235
os.remove(tmp_path)
171236

172237
try:
173-
# Prepare row data (ensure this matches the order of your sheet columns)
174-
row_data = [[name, description, keywords, file_link, person]]
175-
238+
row_data = [[
239+
name,
240+
description,
241+
keywords,
242+
file_link,
243+
person
244+
]]
245+
176246
sheets_service.spreadsheets().values().append(
177247
spreadsheetId=SHEET_ID,
178248
range="Sheet1!A1",
179249
valueInputOption="USER_ENTERED",
180250
body={"values": row_data}
181251
).execute()
182-
252+
183253
st.success("✅ Entry recorded successfully!")
184254
st.balloons()
185255
st.rerun()
256+
186257
except Exception as e:
187-
st.error(f"Sheets Error: {e}")
258+
st.error(f"Sheets Error: {e}")

0 commit comments

Comments
 (0)