def set_new_password_function(confirm_email_token_url_variable): """Returns: confirms email token link""" # Need to create a css unique key so that cache busting can be done css_cache_busting_variable = create_uuid_function('css_') # Check if user session data is already present/signed in if session and session.get('logged_in_user_email') != 'none': return redirect('https://symbolnews.com/dashboard', code=301) # Setup token serializer serializer_instance = URLSafeTimedSerializer( os.environ.get('URL_SAFE_SERIALIZER_SECRET_KEY_EMAIL')) string_to_salt = os.environ.get( 'URL_SAFE_SERIALIZER_SECRET_SALT_EMAIL').encode("utf-8") # See if token matches the one sent out try: user_email_confirming = serializer_instance.loads( confirm_email_token_url_variable, salt=string_to_salt, max_age=3600) session['user_email_to_change_password'] = user_email_confirming return render_template( 'templates_login_and_create_account/new_password_page.html', css_cache_busting_variable_to_html=css_cache_busting_variable) # If token does not match the one sent out except: session['output_message_landing_page_session'] = 'Token has expired!' return redirect("https://symbolnews.com/", code=301) return redirect("https://symbolnews.com/", code=301)
def landing_page_render_function(): """Returns: The login page""" # Need to create a css unique key so that cache busting can be done css_cache_busting_variable = create_uuid_function('css_') # Check if user session data is already present/signed in if session and session.get('logged_in_user_email') != 'none': return redirect('https://symbolnews.com/dashboard', code=301) # When redirected to this page, first check if there is an session error message associated with this redirect if session and session.get('output_message_landing_page_session') != None: # Set the variables based on session inputs output_message_landing_page = session[ 'output_message_landing_page_session'] try: return render_template( 'templates_login_and_create_account/landing_page.html', output_message_from_python_to_html=output_message_landing_page, css_cache_busting_variable_to_html=css_cache_busting_variable) except: return 'failed' finally: session['output_message_landing_page_session'] = None # If no error message than just render as per usual else: return render_template( 'templates_login_and_create_account/landing_page.html', css_cache_busting_variable_to_html=css_cache_busting_variable)
def job_remind_verify_email_text_reminder_function(): """Return: Send reminder text to users to verify their emails/check spam folder""" # First check the day num_day_of_week = datetime.datetime.today().weekday() if num_day_of_week == 0 or num_day_of_week == 1 or num_day_of_week == 2 or num_day_of_week == 3 or num_day_of_week == 4 or num_day_of_week == 5: return True # Connect to database connection_postgres, cursor = connect_to_postgres_function() # Pull data - all phone needed data users_not_confirmed_arr = select_user_email_not_confirmed_status_but_phone_yes_confirmed_function(connection_postgres, cursor) if len(users_not_confirmed_arr) > 0: for i in users_not_confirmed_arr: try: # Message the confirmation link to user twilio_message_sid = send_reminder_phone_to_confirm_email_account_function(i[0], i[1], i[2]) # Add the UUID and timestamp for datetime that the reminder was created/sent uuid_reminder_phone = create_uuid_function("rdpe_") reminder_phone_timestamp = create_timestamp_function() confirm_phone_number_token = '' # Insert data into database table attempt_insert_reminder_phone = insert_reminder_phone_table_function(connection_postgres, cursor, uuid_reminder_phone, reminder_phone_timestamp, i[3], confirm_phone_number_token, twilio_message_sid) print(attempt_insert_reminder_phone) except: pass # Close connection close_connection_cursor_to_database_function(connection_postgres, cursor)
def about_page_render_function(): """Returns: Renders the create account page""" # Need to create a css unique key so that cache busting can be done css_cache_busting_variable = create_uuid_function('css_') return render_template( 'templates_login_and_create_account/about_page.html', css_cache_busting_variable_to_html=css_cache_busting_variable)
def delete_account_page_render_function(): # Need to create a css unique key so that cache busting can be done css_cache_busting_variable = create_uuid_function('css_') if session and 'logged_in_user_email' in session and session.get('logged_in_user_email') != 'none': return render_template('templates_user_logged_in/account_delete.html', css_cache_busting_variable_to_html = css_cache_busting_variable) else: set_session_variables_to_none_logout_function() return redirect("https://symbolnews.com/", code=301)
def job_remind_verify_phone_function(): """Return: Send reminder text to users to verify their phone number""" # First check the day num_day_of_week = datetime.datetime.today().weekday() if num_day_of_week == 0 or num_day_of_week == 1 or num_day_of_week == 2 or num_day_of_week == 3 or num_day_of_week == 4 or num_day_of_week == 5: return True # Connect to database connection_postgres, cursor = connect_to_postgres_function() # Pull data - all phone needed data users_not_confirmed_arr = select_user_phone_not_confirmed_status_function( connection_postgres, cursor) if len(users_not_confirmed_arr) > 0: for i in users_not_confirmed_arr: try: # Create token for verification confirm_phone_number_token = create_confirm_token_function( i[0], os.environ.get('URL_SAFE_SERIALIZER_SECRET_KEY_PHONE'), os.environ.get('URL_SAFE_SERIALIZER_SECRET_SALT_PHONE')) # Create the URL link for verification try: url_for( 'confirm_phone_number_page.confirm_phone_number_page_function', confirm_phone_number_token_url_variable= confirm_phone_number_token) except: pass # Message the confirmation link to user twilio_message_sid = send_reminder_phone_confirm_account_function( i[0], i[1], confirm_phone_number_token) # Add the UUID and timestamp for datetime that the reminder was created/sent uuid_reminder_phone = create_uuid_function("rmdp_") reminder_phone_timestamp = create_timestamp_function() # Insert data into database table attempt_insert_reminder_phone = insert_reminder_phone_table_function( connection_postgres, cursor, uuid_reminder_phone, reminder_phone_timestamp, i[2], confirm_phone_number_token, twilio_message_sid) print(attempt_insert_reminder_phone) except: pass # Close connection close_connection_cursor_to_database_function(connection_postgres, cursor)
def account_page_edit_information_function(): """Returns: Renders the user's account page""" # Need to create a css unique key so that cache busting can be done css_cache_busting_variable = create_uuid_function('css_') if session['logged_in_user_email'] != 'none': return render_template( 'templates_user_logged_in/account_edit_information.html', user_email_from_session_to_html=session['logged_in_user_email'], user_first_name_from_session_to_html=session[ 'logged_in_user_first_name'], user_last_name_from_session_to_html=session[ 'logged_in_user_last_name'], user_phone_number_from_session_to_html=session[ 'logged_in_user_phone_number'], css_cache_busting_variable_to_html=css_cache_busting_variable) else: set_session_variables_to_none_logout_function() return redirect("https://symbolnews.com/", code=301)
def send_sms_function(connection_postgres, cursor, input_arr): """ Returns: Send update text to user """ phone_number = '1' + str(input_arr[0]) symbol = input_arr[1] percent_change = input_arr[2] google_link = input_arr[3] account_sid = os.environ.get('TWILIO_ACCOUNT_SID') auth_token = os.environ.get('TWILIO_AUTH_TOKEN') client = Client(account_sid, auth_token) message = client.messages.create( body=symbol + ' ' + percent_change + ' from previous close.\nLatest news articles for ' + symbol + ' here:\n' + google_link + '\n\nAdd symbols to news watchlist:\nSymbolNews.com', from_=os.environ.get('TWILIO_PHONE_NUMBER'), to=phone_number) print(message.sid) # Information that will go into the stock texts sent out table fk_uuid_user = input_arr[4] fk_uuid_symbol_track = input_arr[5] twilio_message_side = message.sid # Add the UUID and timestamp for datetime that the account was created user_uuid_text_sent = create_uuid_function("sndt_") user_timestamp_text_sent = create_timestamp_function() # Insert text message sent info into database sent_text_status = insert_sent_texts_table_function( connection_postgres, cursor, user_uuid_text_sent, user_timestamp_text_sent, fk_uuid_user, fk_uuid_symbol_track, twilio_message_side) print(sent_text_status)
def send_email_weekly_recap_sym_thresholds_function( to_email_address_outgoing, weekly_sym_thresholds_value_dict, master_string, email_send_date, connection_postgres, cursor, symbols_sent_arr): sg = sendgrid.SendGridAPIClient(api_key=os.environ.get('SENDGRID_API_KEY')) from_email = Email(email="*****@*****.**", name="Symbol News") # Change to your verified sender to_email = To(to_email_address_outgoing) # Change to your recipient subject = "Weekly Recap - " + email_send_date content = Content("text/plain", \ "Hi " + weekly_sym_thresholds_value_dict['first_name'] + ",\n\n" + \ "Total texts sent to you this week: " + str(weekly_sym_thresholds_value_dict['total_texts_this_week']) + \ "\n\nSummary this week (% price change from Monday open to Friday close):\n\n" + \ master_string + "\n\nBest,\nRob from Symbol News") mail = Mail(from_email, to_email, subject, content) # Get a JSON-ready representation of the Mail object mail_json = mail.get() # Send an HTTP POST request to /mail/send #response = sg.client.mail.send.post(request_body=mail_json) sg.client.mail.send.post(request_body=mail_json) # After email sent, insert tracking row into database user_uuid = weekly_sym_thresholds_value_dict['uuid'] # Add the UUID and timestamp for datetime that the account was created user_uuid_sent_email_recap = create_uuid_function("snde_") user_sent_email_recap_timestamp = create_timestamp_function() insert_email_recap_status = insert_sent_recap_email_table_function( connection_postgres, cursor, user_uuid_sent_email_recap, user_sent_email_recap_timestamp, user_uuid, mail_json, weekly_sym_thresholds_value_dict['total_texts_this_week'], symbols_sent_arr) print(insert_email_recap_status)
def creating_account_to_postgres_function(): """Returns: Uploads new account info to Postgres database, if it does not already exist.""" # Check if user session data is already present/signed in if session and session.get('logged_in_user_email') != 'none': return redirect('https://symbolnews.com/dashboard', code=301) # Get and sanitize the user inputs from html form user_first_name_from_html_form_sanitized = sanitize_name_input_create_account_function( request.form.get('user_first_name')) user_last_name_from_html_form_sanitized = sanitize_name_input_create_account_function( request.form.get('user_last_name')) user_phone_number_from_html_form_sanitized = sanitize_phone_number_input_create_account_function( request.form.get('phone_number')) user_email_from_html_form_sanitized = sanitize_email_input_create_account_function( request.form.get('email')) user_password_from_html_form_sanitized = sanitize_password_input_create_account_function( request.form.get('psw')) # If postman invalid inputs used if user_first_name_from_html_form_sanitized == 'none' or user_last_name_from_html_form_sanitized == 'none' or user_phone_number_from_html_form_sanitized == 'none' or user_email_from_html_form_sanitized == 'none' or user_password_from_html_form_sanitized == 'none': print('FAILED TO CREATE ACCOUNT!') return 'FAILED TO CREATE ACCOUNT!' # Hash the user password from html form hashed_user_password_from_html_form = bcrypt.hashpw( user_password_from_html_form_sanitized.encode('utf-8'), bcrypt.gensalt()) hashed_user_password_from_html_form_decoded_for_database_insert = hashed_user_password_from_html_form.decode( 'ascii') # Connect to postgres connection_postgres, cursor = connect_to_postgres_function() # Search query if email is already in database email_exists = select_login_information_table_query_function( connection_postgres, cursor, user_email_from_html_form_sanitized) phone_exists = select_login_information_table_query_phone_number_function( connection_postgres, cursor, user_phone_number_from_html_form_sanitized) # If email account already exists in database if email_exists == 'Account already exists' or phone_exists == 'Account already exists': # Close connection to database close_connection_cursor_to_database_function(connection_postgres, cursor) # Set outgoing session messages session[ 'output_message_create_account_page_session'] = 'Account already exists' # Redirect to page return redirect("https://symbolnews.com/create_account", code=301) # Add the UUID and timestamp for datetime that the account was created user_uuid_create_account = create_uuid_function("user_") user_create_account_timestamp = create_timestamp_function() # Insert query function to insert new user created data into postgres success_message, error_message = insert_login_information_table_query_function( connection_postgres, cursor, user_uuid_create_account, user_create_account_timestamp, user_first_name_from_html_form_sanitized, user_last_name_from_html_form_sanitized, user_phone_number_from_html_form_sanitized, user_email_from_html_form_sanitized, hashed_user_password_from_html_form_decoded_for_database_insert) # Close database connection and cursor close_connection_cursor_to_database_function(connection_postgres, cursor) # Continue based on query insert results if success_message == 'success' and error_message == 'none': # Create tokens for email and phone number verification confirm_email_token = create_confirm_token_function( user_email_from_html_form_sanitized, os.environ.get('URL_SAFE_SERIALIZER_SECRET_KEY_EMAIL'), os.environ.get('URL_SAFE_SERIALIZER_SECRET_SALT_EMAIL')) confirm_phone_number_token = create_confirm_token_function( user_phone_number_from_html_form_sanitized, os.environ.get('URL_SAFE_SERIALIZER_SECRET_KEY_PHONE'), os.environ.get('URL_SAFE_SERIALIZER_SECRET_SALT_PHONE')) # Create the URL links for email and phone number verification url_for('confirm_email_page.confirm_email_page_function', confirm_email_token_url_variable=confirm_email_token) url_for( 'confirm_phone_number_page.confirm_phone_number_page_function', confirm_phone_number_token_url_variable=confirm_phone_number_token) # Send the confirmation email and text links to user try: send_phone_number_confirm_account_function( user_phone_number_from_html_form_sanitized, user_first_name_from_html_form_sanitized, confirm_phone_number_token) send_email_confirm_account_function( user_email_from_html_form_sanitized, user_first_name_from_html_form_sanitized, confirm_email_token) except: # If user inputs wrong format # Delete user that was just input to database connection_postgres, cursor = connect_to_postgres_function() delete_all_user_login_information_table_data_function( connection_postgres, cursor, user_uuid_create_account) close_connection_cursor_to_database_function( connection_postgres, cursor) set_session_variables_to_none_logout_function() session[ 'output_message_create_account_page_session'] = 'Unable to create account with the phone number provided!' return redirect("https://symbolnews.com/create_account", code=301) # Send admin email that account was created try: send_admin_email_account_created_function( user_first_name_from_html_form_sanitized, user_last_name_from_html_form_sanitized, user_email_from_html_form_sanitized, user_create_account_timestamp) except: print('did not send email to admin') # Flask set session variables and redirect to dashboard session['logged_in_user_uuid'] = user_uuid_create_account session['logged_in_user_email'] = user_email_from_html_form_sanitized session[ 'logged_in_user_first_name'] = user_first_name_from_html_form_sanitized session[ 'logged_in_user_last_name'] = user_last_name_from_html_form_sanitized session[ 'logged_in_user_phone_number'] = user_phone_number_from_html_form_sanitized session.permanent = True return redirect("https://symbolnews.com/dashboard", code=301) # If above fails at any point redirect back to create account page else: set_session_variables_to_none_logout_function() return redirect("https://symbolnews.com/create_account", code=301) return redirect("https://symbolnews.com/create_account", code=301)
def dashboard_page_render_function(): """Returns: User dashboard with user symbol tracking list""" # Need to create a css unique key so that cache busting can be done css_cache_busting_variable = create_uuid_function('css_') if session and session.get( 'logged_in_user_email') != 'none' and session.get( 'logged_in_user_email') != None: # Get info for the page render # Connect to database connection_postgres, cursor = connect_to_postgres_function() # Pull tracking list from databse symbol_tracking_list = select_user_tracking_list_function( connection_postgres, cursor, session['logged_in_user_uuid']) # Check if email and phone number are verified display_output_message_email, display_output_message_phone_number = select_user_confirmed_account_status_function( connection_postgres, cursor, session['logged_in_user_uuid']) # If not verified yet, unhide the resend link text resend_email_confirm_link = '' resend_phone_number_confirm_link = '' # Add the resend link text words to html file if they are not blank/None if display_output_message_email != None and len( display_output_message_email) >= 2: resend_email_confirm_link = 'Click to resend email confirmation link.' if display_output_message_phone_number != None and len( display_output_message_phone_number) >= 2: resend_phone_number_confirm_link = 'Click to resend phone number confirmation link.' # Close the connnection to database close_connection_cursor_to_database_function(connection_postgres, cursor) # When redirected to this page, first check if there is an session error message associated with this redirect if session and session.get( 'output_message_dashboard_page_session') != None: try: return render_template( 'templates_user_logged_in/loggedin_dashboard_page.html', user_email_from_session_to_html=session[ 'logged_in_user_email'], user_first_name_from_session_to_html=session[ 'logged_in_user_first_name'], user_last_name_from_session_to_html=session[ 'logged_in_user_last_name'], user_phone_number_from_session_to_html=session[ 'logged_in_user_phone_number'], symbol_tracking_list_from_python_to_html= symbol_tracking_list, output_message_from_python_to_html=session[ 'output_message_dashboard_page_session'], resend_email_confirm_link_to_html=resend_email_confirm_link, resend_phone_number_confirm_link_to_html= resend_phone_number_confirm_link, css_cache_busting_variable_to_html= css_cache_busting_variable) except: return 'failed' finally: session['output_message_dashboard_page_session'] = None # Render the page return render_template( 'templates_user_logged_in/loggedin_dashboard_page.html', user_email_from_session_to_html=session['logged_in_user_email'], user_first_name_from_session_to_html=session[ 'logged_in_user_first_name'], user_last_name_from_session_to_html=session[ 'logged_in_user_last_name'], user_phone_number_from_session_to_html=session[ 'logged_in_user_phone_number'], symbol_tracking_list_from_python_to_html=symbol_tracking_list, resend_email_confirm_link_to_html=resend_email_confirm_link, resend_phone_number_confirm_link_to_html= resend_phone_number_confirm_link, css_cache_busting_variable_to_html=css_cache_busting_variable) # If no session info found else: set_session_variables_to_none_logout_function() return redirect("https://symbolnews.com/", code=301)
def upload_symbol_percent_change_input_function(): """Returns: sanatizes the user input, then uploads it into the database and data table""" if session and session.get('logged_in_user_email') != 'none': # Sanitize/confirm user inputs user_symbol_from_html_form_sanitized = sanitize_symbol_input_function( request.form.get('track_symbol')) does_symbol_exist = yfinance_check_if_symbol_exists_function( user_symbol_from_html_form_sanitized) user_symbol_percent_change_from_html_form_sanitized = sanitize_symbol_percent_change_input_function( request.form.get('track_percent_change')) # If user inputs were invalid if user_symbol_from_html_form_sanitized == 'none' or does_symbol_exist == 'none' or user_symbol_percent_change_from_html_form_sanitized == 'none': session[ 'output_message_dashboard_page_session'] = 'Stock Symbol must exist and be 1-5 letters long. Minimum % Change must be 7.' return redirect("https://symbolnews.com/dashboard", code=301) # If user inputs were valid else: # Create uuid and timestamp for insertion user_table_insert_uuid = create_uuid_function("symt_") user_track_symbol_timestamp = create_timestamp_function() # Database insert connection_postgres, cursor = connect_to_postgres_function() # Check if user is already tracking this symbol error_message_check_if_exist = select_stock_tracking_table_duplicates_function( connection_postgres, cursor, session['logged_in_user_uuid'], user_symbol_from_html_form_sanitized) # If user is not already tracking this symbol if error_message_check_if_exist == 'none': # Insert stock tracking information into the stock_tracking_table session[ 'output_message_dashboard_page_session'] = insert_stock_tracking_table_function( connection_postgres, cursor, user_table_insert_uuid, user_track_symbol_timestamp, user_symbol_from_html_form_sanitized, user_symbol_percent_change_from_html_form_sanitized, session['logged_in_user_uuid']) # Get google news link for the symbol not company short name yet, a job will get the short name in order to save wait time for user temporary_google_search_input = user_symbol_from_html_form_sanitized + '_stock' google_news_url_link = get_google_news_page_function( temporary_google_search_input) # Insert into the new stock_news_links_table the 1.symbol and 2.google_link(symbol search) try: output_message_news_link_upload = insert_stock_news_links_table_function( connection_postgres, cursor, user_symbol_from_html_form_sanitized, google_news_url_link) except: pass # Insert into job/queue table so that the job can get the company short name every 10 min in the background try: job_queue_name = 'get_company_short_name' output_message_job_upload = insert_jobs_queues_table_function( connection_postgres, cursor, job_queue_name, user_symbol_from_html_form_sanitized) except: pass return redirect("/dashboard", code=301) #return redirect("https://symbolnews.com/dashboard", code=301) # If user is already tracking this symbol else: session[ 'output_message_dashboard_page_session'] = error_message_check_if_exist return redirect("/dashboard", code=301) #return redirect("https://symbolnews.com/dashboard", code=301) # If no session info found else: set_session_variables_to_none_logout_function() return redirect("https://symbolnews.com/", code=301)