raymondEDS commited on
Commit
9cc64fb
Β·
1 Parent(s): 7dcd182
Files changed (6) hide show
  1. .streamlit/config.toml +18 -0
  2. README.md +109 -8
  3. data/users/users.yaml +14 -0
  4. requirements.txt +5 -1
  5. run_app.py +96 -0
  6. src/streamlit_app.py +427 -38
.streamlit/config.toml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [global]
2
+ developmentMode = false
3
+
4
+ [server]
5
+ headless = true
6
+ port = 8501
7
+ enableCORS = false
8
+ enableXsrfProtection = false
9
+
10
+ [browser]
11
+ gatherUsageStats = false
12
+
13
+ [theme]
14
+ primaryColor = "#1f77b4"
15
+ backgroundColor = "#ffffff"
16
+ secondaryBackgroundColor = "#f0f2f6"
17
+ textColor = "#262730"
18
+ font = "sans serif"
README.md CHANGED
@@ -1,19 +1,120 @@
1
  ---
2
  title: Dev LMS
3
- emoji: πŸš€
4
- colorFrom: red
5
- colorTo: red
6
  sdk: docker
7
  app_port: 8501
8
  tags:
9
  - streamlit
 
 
 
10
  pinned: false
11
- short_description: Streamlit template space
12
  ---
13
 
14
- # Welcome to Streamlit!
15
 
16
- Edit `/src/streamlit_app.py` to customize this app to your heart's desire. :heart:
17
 
18
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
19
- forums](https://discuss.streamlit.io).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
  title: Dev LMS
3
+ emoji: πŸ“š
4
+ colorFrom: blue
5
+ colorTo: purple
6
  sdk: docker
7
  app_port: 8501
8
  tags:
9
  - streamlit
10
+ - lms
11
+ - education
12
+ - pdf
13
  pinned: false
14
+ short_description: A Learning Management System with user authentication and PDF document management
15
  ---
16
 
17
+ # Dev LMS - Learning Management System
18
 
19
+ A comprehensive Learning Management System built with Streamlit that provides user authentication and PDF document management capabilities.
20
 
21
+ ## πŸš€ Features
22
+
23
+ ### πŸ” Authentication
24
+ - Secure user login system
25
+ - Multiple user roles (Admin, Teacher, Student)
26
+ - Session management with cookies
27
+ - Password hashing for security
28
+
29
+ ### πŸ“„ Document Management
30
+ - PDF document upload and storage
31
+ - Text extraction from PDF files
32
+ - Document preview and search functionality
33
+ - Document library with user ownership tracking
34
+
35
+ ### πŸ“Š Dashboard
36
+ - User activity metrics
37
+ - Document statistics
38
+ - Recent activity tracking
39
+ - System overview
40
+
41
+ ### πŸ” Search & Navigation
42
+ - Search documents by filename, content, or owner
43
+ - Filter documents by various criteria
44
+ - Easy navigation between different sections
45
+ - Document categorization
46
+
47
+ ## πŸ‘₯ Default Users
48
+
49
+ The system comes with three default user accounts:
50
+
51
+ | Role | Username | Password |
52
+ |------|----------|----------|
53
+ | Administrator | `admin` | `admin123` |
54
+ | Teacher | `teacher` | `teacher123` |
55
+ | Student | `student` | `student123` |
56
+
57
+ ## πŸ› οΈ Installation & Usage
58
+
59
+ 1. **Install Dependencies:**
60
+ ```bash
61
+ pip install -r requirements.txt
62
+ ```
63
+
64
+ 2. **Run the Application:**
65
+ ```bash
66
+ streamlit run src/streamlit_app.py
67
+ ```
68
+
69
+ 3. **Access the Application:**
70
+ - Open your browser and go to `http://localhost:8501`
71
+ - Login with one of the default credentials
72
+ - Start uploading and managing PDF documents!
73
+
74
+ ## πŸ“ Application Structure
75
+
76
+ ```
77
+ β”œβ”€β”€ src/
78
+ β”‚ └── streamlit_app.py # Main application file
79
+ β”œβ”€β”€ data/ # Data storage (created automatically)
80
+ β”‚ β”œβ”€β”€ documents/ # Document storage
81
+ β”‚ └── users/ # User configuration
82
+ β”œβ”€β”€ requirements.txt # Python dependencies
83
+ └── README.md # This file
84
+ ```
85
+
86
+ ## πŸ”§ Technical Details
87
+
88
+ - **Framework:** Streamlit
89
+ - **Authentication:** streamlit-authenticator
90
+ - **PDF Processing:** PyPDF2
91
+ - **Data Storage:** Session state + YAML configuration
92
+ - **Security:** bcrypt password hashing
93
+
94
+ ## 🎯 Use Cases
95
+
96
+ - **Educational Institutions:** Manage course materials and assignments
97
+ - **Corporate Training:** Organize training documents and resources
98
+ - **Research Teams:** Share and collaborate on research papers
99
+ - **Document Management:** Centralized PDF storage and retrieval
100
+
101
+ ## πŸ”’ Security Features
102
+
103
+ - Secure password hashing using bcrypt
104
+ - Session-based authentication
105
+ - User role management
106
+ - Document ownership tracking
107
+ - Secure file upload handling
108
+
109
+ ## πŸ“ˆ Future Enhancements
110
+
111
+ - Database integration for persistent storage
112
+ - Advanced document annotation features
113
+ - User permission management
114
+ - Document versioning
115
+ - Real-time collaboration tools
116
+ - Mobile-responsive design
117
+
118
+ ---
119
+
120
+ **Built with ❀️ using Streamlit**
data/users/users.yaml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ credentials:
2
+ usernames:
3
+ admin:
4
+ email: admin@example.com
5
+ name: admin
6
+ password: admin
7
+ student:
8
+ email: student@example.com
9
+ name: Student
10
+ password: $2b$12$/aG0V/TytqnA1/eDjKfxbOC6KcBZgNng4ugaUDz6Y7TUmgkQV98ci
11
+ teacher:
12
+ email: teacher@example.com
13
+ name: Teacher
14
+ password: $2b$12$uFiJhI1IMGLnd9b/8anHRek.2vnkt0YAiH6q8G5FvciFZXsk.I442
requirements.txt CHANGED
@@ -1,3 +1,7 @@
1
  altair
2
  pandas
3
- streamlit
 
 
 
 
 
1
  altair
2
  pandas
3
+ streamlit
4
+ streamlit-authenticator
5
+ PyPDF2
6
+ python-multipart
7
+ bcrypt
run_app.py ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Dev LMS Startup Script
4
+ ======================
5
+
6
+ This script provides an easy way to start the Dev LMS application.
7
+ It handles dependency checking and provides helpful information.
8
+ """
9
+
10
+ import subprocess
11
+ import sys
12
+ import os
13
+
14
+ def check_dependencies():
15
+ """Check if required dependencies are installed"""
16
+ required_packages = [
17
+ 'streamlit',
18
+ 'streamlit_authenticator',
19
+ 'PyPDF2',
20
+ 'yaml',
21
+ 'bcrypt'
22
+ ]
23
+
24
+ missing_packages = []
25
+
26
+ for package in required_packages:
27
+ try:
28
+ __import__(package.replace('-', '_'))
29
+ except ImportError:
30
+ missing_packages.append(package)
31
+
32
+ return missing_packages
33
+
34
+ def install_dependencies():
35
+ """Install missing dependencies"""
36
+ print("Installing missing dependencies...")
37
+ try:
38
+ subprocess.check_call([sys.executable, '-m', 'pip', 'install', '-r', 'requirements.txt'])
39
+ print("βœ… Dependencies installed successfully!")
40
+ return True
41
+ except subprocess.CalledProcessError:
42
+ print("❌ Failed to install dependencies. Please install them manually:")
43
+ print(" pip install -r requirements.txt")
44
+ return False
45
+
46
+ def main():
47
+ print("πŸš€ Dev LMS - Learning Management System")
48
+ print("=" * 50)
49
+
50
+ # Check if we're in the right directory
51
+ if not os.path.exists('src/streamlit_app.py'):
52
+ print("❌ Error: Please run this script from the project root directory")
53
+ print(" (where src/streamlit_app.py is located)")
54
+ sys.exit(1)
55
+
56
+ # Check dependencies
57
+ print("πŸ” Checking dependencies...")
58
+ missing = check_dependencies()
59
+
60
+ if missing:
61
+ print(f"❌ Missing dependencies: {', '.join(missing)}")
62
+ response = input("Would you like to install them now? (y/n): ")
63
+ if response.lower() in ['y', 'yes']:
64
+ if not install_dependencies():
65
+ sys.exit(1)
66
+ else:
67
+ print("Please install dependencies manually and try again.")
68
+ sys.exit(1)
69
+ else:
70
+ print("βœ… All dependencies are installed!")
71
+
72
+ print("\n🎯 Starting Dev LMS...")
73
+ print("πŸ“– Default login credentials:")
74
+ print(" - Admin: admin / admin123")
75
+ print(" - Teacher: teacher / teacher123")
76
+ print(" - Student: student / student123")
77
+ print("\n🌐 The application will open in your browser at: http://localhost:8501")
78
+ print("⏹️ Press Ctrl+C to stop the application")
79
+ print("=" * 50)
80
+
81
+ try:
82
+ # Start the Streamlit app
83
+ subprocess.run([
84
+ sys.executable, '-m', 'streamlit', 'run',
85
+ 'src/streamlit_app.py',
86
+ '--server.port=8501',
87
+ '--server.headless=true'
88
+ ])
89
+ except KeyboardInterrupt:
90
+ print("\nπŸ‘‹ Dev LMS stopped. Goodbye!")
91
+ except Exception as e:
92
+ print(f"❌ Error starting application: {e}")
93
+ sys.exit(1)
94
+
95
+ if __name__ == "__main__":
96
+ main()
src/streamlit_app.py CHANGED
@@ -1,40 +1,429 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
  import streamlit as st
 
 
 
 
 
 
 
 
 
5
 
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
+ import streamlit_authenticator as stauth
3
+ import yaml
4
+ from yaml.loader import SafeLoader
5
+ import os
6
+ import PyPDF2
7
+ import io
8
+ import base64
9
+ from datetime import datetime
10
+ import json
11
 
12
+ # Page configuration
13
+ st.set_page_config(
14
+ page_title="Dev LMS",
15
+ page_icon="πŸ“š",
16
+ layout="wide",
17
+ initial_sidebar_state="expanded"
18
+ )
19
+
20
+ # Initialize session state
21
+ if 'authenticated' not in st.session_state:
22
+ st.session_state.authenticated = False
23
+ if 'username' not in st.session_state:
24
+ st.session_state.username = None
25
+ if 'uploaded_documents' not in st.session_state:
26
+ st.session_state.uploaded_documents = {}
27
+
28
+ # Create data directory if it doesn't exist
29
+ os.makedirs('data', exist_ok=True)
30
+ os.makedirs('data/documents', exist_ok=True)
31
+ os.makedirs('data/users', exist_ok=True)
32
+
33
+ # User configuration file
34
+ USERS_FILE = 'data/users/users.yaml'
35
+
36
+ def create_default_users():
37
+ """Create default users if the users file doesn't exist"""
38
+ if not os.path.exists(USERS_FILE):
39
+ default_users = {
40
+ 'credentials': {
41
+ 'usernames': {
42
+ 'admin': {
43
+ 'email': 'admin@example.com',
44
+ 'name': 'Administrator',
45
+ 'password': stauth.Hasher(['admin123']).generate()[0]
46
+ },
47
+ 'teacher': {
48
+ 'email': 'teacher@example.com',
49
+ 'name': 'Teacher',
50
+ 'password': stauth.Hasher(['teacher123']).generate()[0]
51
+ },
52
+ 'student': {
53
+ 'email': 'student@example.com',
54
+ 'name': 'Student',
55
+ 'password': stauth.Hasher(['student123']).generate()[0]
56
+ }
57
+ }
58
+ }
59
+ }
60
+
61
+ os.makedirs(os.path.dirname(USERS_FILE), exist_ok=True)
62
+ with open(USERS_FILE, 'w') as file:
63
+ yaml.dump(default_users, file, default_flow_style=False)
64
+
65
+ def load_users():
66
+ """Load users from YAML file"""
67
+ create_default_users()
68
+ with open(USERS_FILE) as file:
69
+ config = yaml.load(file, Loader=SafeLoader)
70
+ return config
71
+
72
+ def save_document_info(username, filename, file_content, file_type):
73
+ """Save document information to session state"""
74
+ if username not in st.session_state.uploaded_documents:
75
+ st.session_state.uploaded_documents[username] = []
76
+
77
+ document_info = {
78
+ 'filename': filename,
79
+ 'upload_time': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
80
+ 'file_type': file_type,
81
+ 'size': len(file_content),
82
+ 'content': file_content.decode('latin-1') if isinstance(file_content, bytes) else str(file_content)
83
+ }
84
+
85
+ st.session_state.uploaded_documents[username].append(document_info)
86
+
87
+ def extract_pdf_text(pdf_file):
88
+ """Extract text from PDF file"""
89
+ try:
90
+ pdf_reader = PyPDF2.PdfReader(pdf_file)
91
+ text = ""
92
+ for page in pdf_reader.pages:
93
+ text += page.extract_text() + "\n"
94
+ return text
95
+ except Exception as e:
96
+ st.error(f"Error reading PDF: {str(e)}")
97
+ return ""
98
+
99
+ def main():
100
+ # Load users
101
+ config = load_users()
102
+
103
+ # Create authenticator
104
+ authenticator = stauth.Authenticate(
105
+ config['credentials'],
106
+ 'dev_lms',
107
+ 'auth_key',
108
+ cookie_expiry_days=30
109
+ )
110
+
111
+ # Sidebar for navigation
112
+ with st.sidebar:
113
+ st.title("πŸ“š Dev LMS")
114
+ st.markdown("---")
115
+
116
+ if not st.session_state.authenticated:
117
+ st.info("Please login to access the LMS")
118
+ else:
119
+ st.success(f"Welcome, {st.session_state.username}!")
120
+ st.markdown("---")
121
+
122
+ # Navigation
123
+ page = st.selectbox(
124
+ "Navigation",
125
+ ["Dashboard", "Upload Documents", "My Documents", "Document Library", "Settings"]
126
+ )
127
+
128
+ # Main content area
129
+ if not st.session_state.authenticated:
130
+ # Login page
131
+ st.title("πŸ” Login to Dev LMS")
132
+ st.markdown("---")
133
+
134
+ col1, col2, col3 = st.columns([1, 2, 1])
135
+ with col2:
136
+ name, authentication_status, username = authenticator.login('Login', 'main')
137
+
138
+ if authentication_status == False:
139
+ st.error('Username/password is incorrect')
140
+ elif authentication_status == None:
141
+ st.warning('Please enter your username and password')
142
+ elif authentication_status:
143
+ st.session_state.authenticated = True
144
+ st.session_state.username = username
145
+ st.success(f'Welcome {name}')
146
+ st.rerun()
147
+
148
+ # Show default credentials
149
+ with st.expander("Default Login Credentials"):
150
+ st.markdown("""
151
+ **Default Users:**
152
+ - **Admin**: username: `admin`, password: `admin123`
153
+ - **Teacher**: username: `teacher`, password: `teacher123`
154
+ - **Student**: username: `student`, password: `student123`
155
+ """)
156
+
157
+ else:
158
+ # Authenticated user content
159
+ if 'page' not in locals():
160
+ page = "Dashboard"
161
+
162
+ if page == "Dashboard":
163
+ show_dashboard()
164
+ elif page == "Upload Documents":
165
+ show_upload_documents()
166
+ elif page == "My Documents":
167
+ show_my_documents()
168
+ elif page == "Document Library":
169
+ show_document_library()
170
+ elif page == "Settings":
171
+ show_settings()
172
+
173
+ # Logout button
174
+ st.sidebar.markdown("---")
175
+ if st.sidebar.button("Logout"):
176
+ st.session_state.authenticated = False
177
+ st.session_state.username = None
178
+ st.rerun()
179
+
180
+ def show_dashboard():
181
+ """Show the main dashboard"""
182
+ st.title("πŸ“Š Dashboard")
183
+ st.markdown("---")
184
+
185
+ col1, col2, col3 = st.columns(3)
186
+
187
+ with col1:
188
+ st.metric(
189
+ label="My Documents",
190
+ value=len(st.session_state.uploaded_documents.get(st.session_state.username, [])),
191
+ delta="0"
192
+ )
193
+
194
+ with col2:
195
+ total_docs = sum(len(docs) for docs in st.session_state.uploaded_documents.values())
196
+ st.metric(
197
+ label="Total Documents",
198
+ value=total_docs,
199
+ delta="0"
200
+ )
201
+
202
+ with col3:
203
+ st.metric(
204
+ label="Active Users",
205
+ value=len(st.session_state.uploaded_documents.keys()),
206
+ delta="0"
207
+ )
208
+
209
+ st.markdown("---")
210
+
211
+ # Recent activity
212
+ st.subheader("πŸ“ˆ Recent Activity")
213
+ if st.session_state.uploaded_documents.get(st.session_state.username):
214
+ recent_docs = st.session_state.uploaded_documents[st.session_state.username][-5:]
215
+ for doc in recent_docs:
216
+ with st.container():
217
+ col1, col2, col3 = st.columns([3, 2, 1])
218
+ with col1:
219
+ st.write(f"**{doc['filename']}**")
220
+ with col2:
221
+ st.write(doc['upload_time'])
222
+ with col3:
223
+ st.write(f"{doc['file_type']}")
224
+ st.markdown("---")
225
+
226
+ def show_upload_documents():
227
+ """Show document upload interface"""
228
+ st.title("πŸ“€ Upload Documents")
229
+ st.markdown("---")
230
+
231
+ uploaded_file = st.file_uploader(
232
+ "Choose a PDF file",
233
+ type=['pdf'],
234
+ help="Upload PDF documents to the LMS"
235
+ )
236
+
237
+ if uploaded_file is not None:
238
+ # Display file info
239
+ file_details = {
240
+ "Filename": uploaded_file.name,
241
+ "File size": f"{uploaded_file.size / 1024:.2f} KB",
242
+ "File type": uploaded_file.type
243
+ }
244
+
245
+ st.write("**File Details:**")
246
+ for key, value in file_details.items():
247
+ st.write(f"- {key}: {value}")
248
+
249
+ # Extract and display PDF content
250
+ pdf_text = extract_pdf_text(uploaded_file)
251
+
252
+ if pdf_text.strip():
253
+ st.subheader("πŸ“„ Document Preview")
254
+ with st.expander("View extracted text"):
255
+ st.text_area("PDF Content", pdf_text, height=300)
256
+
257
+ # Upload button
258
+ if st.button("Upload Document"):
259
+ # Save document info
260
+ save_document_info(
261
+ st.session_state.username,
262
+ uploaded_file.name,
263
+ uploaded_file.read(),
264
+ "PDF"
265
+ )
266
+
267
+ st.success(f"βœ… Document '{uploaded_file.name}' uploaded successfully!")
268
+ st.balloons()
269
+
270
+ def show_my_documents():
271
+ """Show user's uploaded documents"""
272
+ st.title("πŸ“ My Documents")
273
+ st.markdown("---")
274
+
275
+ user_docs = st.session_state.uploaded_documents.get(st.session_state.username, [])
276
+
277
+ if not user_docs:
278
+ st.info("You haven't uploaded any documents yet.")
279
+ return
280
+
281
+ # Search functionality
282
+ search_term = st.text_input("πŸ” Search documents", placeholder="Enter filename or content...")
283
+
284
+ # Filter documents based on search
285
+ filtered_docs = user_docs
286
+ if search_term:
287
+ filtered_docs = [
288
+ doc for doc in user_docs
289
+ if search_term.lower() in doc['filename'].lower() or
290
+ search_term.lower() in doc.get('content', '').lower()
291
+ ]
292
+
293
+ if not filtered_docs:
294
+ st.warning("No documents match your search criteria.")
295
+ return
296
+
297
+ # Display documents
298
+ for i, doc in enumerate(filtered_docs):
299
+ with st.container():
300
+ col1, col2, col3, col4 = st.columns([3, 2, 1, 1])
301
+
302
+ with col1:
303
+ st.write(f"**{doc['filename']}**")
304
+
305
+ with col2:
306
+ st.write(doc['upload_time'])
307
+
308
+ with col3:
309
+ st.write(f"{doc['file_type']}")
310
+
311
+ with col4:
312
+ if st.button(f"View {i}", key=f"view_{i}"):
313
+ st.subheader(f"πŸ“„ {doc['filename']}")
314
+ st.write(f"**Uploaded:** {doc['upload_time']}")
315
+ st.write(f"**Size:** {doc['size']} bytes")
316
+
317
+ # Display content if available
318
+ if 'content' in doc and doc['content']:
319
+ st.text_area("Document Content", doc['content'], height=400, key=f"content_{i}")
320
+
321
+ st.markdown("---")
322
+
323
+ def show_document_library():
324
+ """Show all documents in the system"""
325
+ st.title("πŸ“š Document Library")
326
+ st.markdown("---")
327
+
328
+ if not st.session_state.uploaded_documents:
329
+ st.info("No documents have been uploaded to the system yet.")
330
+ return
331
+
332
+ # Search functionality
333
+ search_term = st.text_input("πŸ” Search all documents", placeholder="Enter filename, content, or username...")
334
+
335
+ # Collect all documents
336
+ all_docs = []
337
+ for username, docs in st.session_state.uploaded_documents.items():
338
+ for doc in docs:
339
+ doc_copy = doc.copy()
340
+ doc_copy['owner'] = username
341
+ all_docs.append(doc_copy)
342
+
343
+ # Filter documents based on search
344
+ filtered_docs = all_docs
345
+ if search_term:
346
+ filtered_docs = [
347
+ doc for doc in all_docs
348
+ if search_term.lower() in doc['filename'].lower() or
349
+ search_term.lower() in doc.get('content', '').lower() or
350
+ search_term.lower() in doc['owner'].lower()
351
+ ]
352
+
353
+ if not filtered_docs:
354
+ st.warning("No documents match your search criteria.")
355
+ return
356
+
357
+ # Display documents
358
+ for i, doc in enumerate(filtered_docs):
359
+ with st.container():
360
+ col1, col2, col3, col4, col5 = st.columns([3, 2, 1, 1, 1])
361
+
362
+ with col1:
363
+ st.write(f"**{doc['filename']}**")
364
+
365
+ with col2:
366
+ st.write(doc['upload_time'])
367
+
368
+ with col3:
369
+ st.write(f"{doc['file_type']}")
370
+
371
+ with col4:
372
+ st.write(f"By: {doc['owner']}")
373
+
374
+ with col5:
375
+ if st.button(f"View {i}", key=f"lib_view_{i}"):
376
+ st.subheader(f"πŸ“„ {doc['filename']}")
377
+ st.write(f"**Uploaded by:** {doc['owner']}")
378
+ st.write(f"**Uploaded:** {doc['upload_time']}")
379
+ st.write(f"**Size:** {doc['size']} bytes")
380
+
381
+ # Display content if available
382
+ if 'content' in doc and doc['content']:
383
+ st.text_area("Document Content", doc['content'], height=400, key=f"lib_content_{i}")
384
+
385
+ st.markdown("---")
386
+
387
+ def show_settings():
388
+ """Show user settings"""
389
+ st.title("βš™οΈ Settings")
390
+ st.markdown("---")
391
+
392
+ st.subheader("πŸ‘€ User Information")
393
+ st.write(f"**Username:** {st.session_state.username}")
394
+ st.write(f"**Session ID:** {id(st.session_state)}")
395
+
396
+ st.markdown("---")
397
+
398
+ st.subheader("πŸ”§ System Information")
399
+ st.write("**Version:** Dev LMS v1.0")
400
+ st.write("**Features:**")
401
+ st.write("- User authentication")
402
+ st.write("- PDF document upload")
403
+ st.write("- Document search and preview")
404
+ st.write("- Document library")
405
+
406
+ st.markdown("---")
407
+
408
+ # Export data option
409
+ if st.button("πŸ“₯ Export My Data"):
410
+ user_docs = st.session_state.uploaded_documents.get(st.session_state.username, [])
411
+ if user_docs:
412
+ # Create JSON export
413
+ export_data = {
414
+ 'username': st.session_state.username,
415
+ 'export_date': datetime.now().isoformat(),
416
+ 'documents': user_docs
417
+ }
418
+
419
+ st.download_button(
420
+ label="Download JSON Export",
421
+ data=json.dumps(export_data, indent=2),
422
+ file_name=f"{st.session_state.username}_data_export.json",
423
+ mime="application/json"
424
+ )
425
+ else:
426
+ st.info("No data to export.")
427
+
428
+ if __name__ == "__main__":
429
+ main()