ToletiSri commited on
Commit
322ae63
·
verified ·
1 Parent(s): b37e76f

Upload UtilityFunctions.py

Browse files
Files changed (1) hide show
  1. UtilityFunctions.py +250 -0
UtilityFunctions.py ADDED
@@ -0,0 +1,250 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import shutil
3
+
4
+ def email_decorator(func):
5
+ """
6
+ A decorator to handle common email sending setup and error handling.
7
+ It retrieves email credentials from environment variables, sets up the SMTP server,
8
+ and sends the email. It also includes error handling for common email-related issues.
9
+
10
+ Requires environment variables:
11
+ SENDER_EMAIL: Email account for sending
12
+ SENDER_PASSWORD: App password for email account
13
+ """
14
+ import os
15
+ import smtplib
16
+ from functools import wraps
17
+
18
+ @wraps(func)
19
+ def wrapper(*args, **kwargs):
20
+ sender_email = os.environ.get('SENDER_EMAIL')
21
+ sender_password = os.environ.get('SENDER_PASSWORD')
22
+
23
+ if not all([sender_email, sender_password]):
24
+ raise ValueError("Missing email credentials in environment variables")
25
+
26
+ try:
27
+ msg = func(*args, **kwargs) # Execute the decorated function to get the EmailMessage object
28
+ msg['From'] = sender_email # Ensure 'From' is set here
29
+ with smtplib.SMTP('smtp.gmail.com', 587) as server:
30
+ server.starttls()
31
+ server.login(sender_email, sender_password)
32
+ server.send_message(msg)
33
+ return True
34
+ except smtplib.SMTPAuthenticationError:
35
+ print("Authentication failed. Check your email credentials.")
36
+ return False
37
+ except Exception as e:
38
+ print(f"Error sending email: {str(e)}")
39
+ return False
40
+
41
+ return wrapper
42
+
43
+
44
+ def get_files_in_folder(root_dir):
45
+ """Recursively scan a folder and return list of files with full paths
46
+ Args:
47
+ root_dir - Directory to scan
48
+ Reutnrs:
49
+ List of file names with absolute path
50
+ """
51
+ file_list = []
52
+ for dirpath, _, filenames in os.walk(root_dir):
53
+ for filename in filenames:
54
+ full_path = os.path.join(dirpath, filename)
55
+ file_list.append(full_path)
56
+ return file_list
57
+
58
+ def get_file_types(file_list):
59
+ """Return dictionary mapping filenames to their file extensions.
60
+ Args:
61
+ List of file names with absolute path
62
+ Returns:
63
+ Dictionary with file name as key and file type as value
64
+ """
65
+ type_dict = {}
66
+ for file_path in file_list:
67
+ # Split the file extension from the path
68
+ _, ext = os.path.splitext(file_path)
69
+ # Remove leading dot and convert to lowercase for consistency
70
+ clean_ext = ext.lower().lstrip('.') if ext else 'no_extension'
71
+ type_dict[file_path] = clean_ext
72
+ return type_dict
73
+
74
+ def organize_files(type_dict):
75
+ """Organize files into folders based on their type in their respective directories.
76
+ Args:
77
+ Dictionary with file name as key and file type as value
78
+ """
79
+
80
+ for file_path, file_type in type_dict.items():
81
+ # Get parent directory and filename
82
+ parent_dir = os.path.dirname(file_path)
83
+ filename = os.path.basename(file_path)
84
+
85
+ # Create target directory name (pluralize for readability)
86
+ target_dir_name = f"{file_type}s" # Example: 'pdf' becomes 'pdfs'
87
+ target_dir = os.path.join(parent_dir, target_dir_name)
88
+
89
+ # Create target directory if it doesn't exist
90
+ os.makedirs(target_dir, exist_ok=True)
91
+
92
+ # Construct full target path
93
+ target_path = os.path.join(target_dir, filename)
94
+
95
+ # Only move if source and target paths are different
96
+ if file_path != target_path:
97
+ try:
98
+ shutil.move(file_path, target_path)
99
+ print(f"Moved: {filename} -> {target_dir_name}/")
100
+ except Exception as e:
101
+ print(f"Error moving {filename}: {str(e)}")
102
+
103
+ def zip_folder(folder_path):
104
+ """Create a zip archive of the specified folder in its parent directory.
105
+ Args:
106
+ Folder name along with the absolute path
107
+ """
108
+ import os
109
+ import shutil
110
+ try:
111
+ parent_dir = os.path.dirname(folder_path)
112
+ folder_name = os.path.basename(folder_path)
113
+ # Check if the path is a file or a folder
114
+ if os.path.isfile(folder_path):
115
+ # If it's a file, create a zip archive of the file
116
+ shutil.make_archive(os.path.splitext(folder_path)[0], 'zip', root_dir=parent_dir, base_dir=os.path.basename(parent_dir))
117
+ print(f"Created {folder_name}.zip in {parent_dir}")
118
+ else:
119
+ # If it's a folder, create a zip archive of the folder
120
+ shutil.make_archive(folder_path, 'zip', parent_dir, folder_name)
121
+ print(f"Created {folder_name}.zip in {parent_dir}")
122
+ return True
123
+ except FileExistsError as e:
124
+ print(f"FileExistsError: {str(e)}")
125
+ return False
126
+ except Exception as e:
127
+ print(f"Error zipping folder: {str(e)}")
128
+ return False
129
+
130
+
131
+ @email_decorator
132
+ def send_reminder_email(email_id, task):
133
+ """Send a reminder email for a task
134
+ Args:
135
+ email_id: this is a positional argument. Recipient email address should be passed here
136
+ task: this is a positional argument, indicates the task description to include in the reminder.
137
+
138
+ """
139
+ from email.message import EmailMessage
140
+ # Create email message
141
+ msg = EmailMessage()
142
+ msg['Subject'] = 'Task Reminder'
143
+ msg['To'] = email_id
144
+ msg.set_content(f'Reminder for your task:\n\n{task}')
145
+
146
+ return msg
147
+
148
+ @email_decorator
149
+ def add_calendar_invite(task, date, email):
150
+ """Create and send a calendar invite for a task on specified date/time to given email.
151
+
152
+ Args:
153
+ task: Task description for the calendar event
154
+ date: datetime object for the event start time
155
+ email: Recipient email address
156
+
157
+ """
158
+ import smtplib
159
+ import os
160
+ from email.message import EmailMessage
161
+ import datetime
162
+ import uuid
163
+
164
+ sender_email = os.environ.get('SENDER_EMAIL')
165
+
166
+ # Generate unique ID for the event
167
+ uid = uuid.uuid4()
168
+
169
+ # Calculate end time (1 hour after start)
170
+ start_time = date
171
+ end_time = start_time + datetime.timedelta(hours=1)
172
+
173
+ # Format times in UTC
174
+ dtstamp = datetime.datetime.now(datetime.timezone.utc).strftime("%Y%m%dT%H%M%SZ")
175
+ dtstart = start_time.astimezone(datetime.timezone.utc).strftime("%Y%m%dT%H%M%SZ")
176
+ dtend = end_time.astimezone(datetime.timezone.utc).strftime("%Y%m%dT%H%M%SZ")
177
+
178
+ # Create ICS content
179
+ ics_content = f"""BEGIN:VCALENDAR
180
+ VERSION:2.0
181
+ PRODID:-//Task Manager//Calendar Invite//EN
182
+ BEGIN:VEVENT
183
+ UID:{uid}
184
+ DTSTAMP:{dtstamp}
185
+ DTSTART:{dtstart}
186
+ DTEND:{dtend}
187
+ SUMMARY:{task}
188
+ ORGANIZER:mailto:{sender_email}
189
+ ATTENDEE:mailto:{email}
190
+ END:VEVENT
191
+ END:VCALENDAR
192
+ """.replace('\n', '\r\n') # Convert to CRLF line endings
193
+
194
+ # Create email message
195
+ msg = EmailMessage()
196
+ msg['Subject'] = f'Calendar Invite: {task}'
197
+ msg['To'] = email
198
+ msg.set_content('Please find the calendar invite attached.')
199
+ # Attach ICS file
200
+ msg.add_attachment(ics_content, subtype='calendar', filename='invite.ics')
201
+ return msg
202
+
203
+ import yfinance as yf
204
+ import time
205
+ import os
206
+ import smtplib
207
+ from datetime import datetime, timedelta
208
+ from email.message import EmailMessage
209
+ from apscheduler.schedulers.background import BackgroundScheduler
210
+
211
+ def get_stock_price(stock_name):
212
+ """Gets the stock price of a given stock
213
+ Args:
214
+ stock_name: Name of stock as listed in stock market
215
+ """
216
+ stock = yf.Ticker(stock_name)
217
+ data = stock.history(period='1d')
218
+ return data['Close'].iloc[-1]
219
+
220
+ @email_decorator
221
+ def send_stock_email(email, stock_name):
222
+ """sends the price of the given stock to the given email.
223
+ Args:
224
+ stock_name: Name of stock as listed in stock market
225
+ email: Recipient email address
226
+ """
227
+ price = get_stock_price(stock_name)
228
+
229
+ msg = EmailMessage()
230
+ msg['Subject'] = f'NVIDIA Stock Price Update: ${price:.2f}'
231
+ msg['To'] = email
232
+ msg.set_content(f'Current NVIDIA stock price: ${price:.2f}')
233
+ return msg
234
+
235
+
236
+ def schedule_daily_stock_email(email, stock_name="NVDA"):
237
+ """Schedules and sends the price of the given stock to the given email everyday at 5 pm.
238
+ Args:
239
+ stock_name: Name of stock as listed in stock market, Defaut value being Nvidia - NVDA
240
+ email: Recipient email address
241
+ """
242
+ scheduler = BackgroundScheduler()
243
+ scheduler.add_job(
244
+ send_stock_email,
245
+ 'cron',
246
+ hour=17,
247
+ minute=0,
248
+ args=[email, stock_name]
249
+ )
250
+ scheduler.start()