Merge pull request #172 from WebEngineering2/bot

Bot correction markdown and logic mistake in updater
This commit is contained in:
NormalParameter 2022-05-10 22:45:53 +02:00 committed by GitHub
commit 40e4aab4d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 281 additions and 47 deletions

View File

@ -2,8 +2,8 @@
script for communicating with webservice to get data from database
"""
__author__ = "Florian Kellermann, Linus Eickhoff"
__date__ = "26.04.2022"
__version__ = "1.0.1"
__date__ = "10.05.2022"
__version__ = "1.0.2"
__license__ = "None"
#side-dependencies: none
@ -70,6 +70,12 @@ class API_Handler:
Args:
email (string): email of the user
password (string): password of the user
Returns:
token (string): new token or None if not 200
Raises:
None
"""
payload = {'email': email, 'password': password}
with r.Session() as s:
@ -91,6 +97,9 @@ class API_Handler:
Returns:
json: json of user infos
Raises:
None
"""
if max_retries <= 0:
return None
@ -113,6 +122,9 @@ class API_Handler:
Returns:
list: list of users
Raises:
None
"""
if max_retries <= 0:
return None
@ -136,6 +148,9 @@ class API_Handler:
Returns:
list: list of keywords
Raises:
None
"""
if max_retries <= 0:
return None
@ -165,6 +180,9 @@ class API_Handler:
Returns:
int: status code
Raises:
None
"""
with r.Session() as s:
headers = {'Authorization': 'Bearer ' + self.token + ":" + str(user_id)}
@ -182,6 +200,9 @@ class API_Handler:
Returns:
int: status code
Raises:
None
"""
with r.Session() as s:
headers = {'Authorization': 'Bearer ' + self.token + ":" + str(user_id)}
@ -199,6 +220,9 @@ class API_Handler:
Returns:
list: list of shares
Raises:
None
"""
if max_retries <= 0:
return None
@ -223,11 +247,14 @@ class API_Handler:
Args:
user_id (int): id of the user
isin (string): isin of the share
isin (string): identifier of the share (standard is isin)
comment (string): comment of the share
Returns:
int: status code
Raises:
None
"""
with r.Session() as s:
headers = {'Authorization': 'Bearer ' + self.token + ":" + str(user_id)}
@ -240,14 +267,17 @@ class API_Handler:
Args:
user_id (int): id of the user
symbol (string): symbol of the share
isin (string): identifier of the share (standard is isin)
Returns:
int: status code
Raises:
None
"""
with r.Session() as s:
headers = {'Authorization': 'Bearer ' + self.token + ":" + str(user_id)}
req = s.delete(self.db_adress + "/share", json={"isin": isin}, headers=headers) # to delete a share only the isin is needed because it is unique, shares are not transactions!
req = s.delete(self.db_adress + "/share", json={"isin": str(isin)}, headers=headers) # to delete a share only the isin is needed because it is unique, shares are not transactions!
return req.status_code
@ -260,6 +290,9 @@ class API_Handler:
Returns:
dict: dictionary of transactions
Raises:
None
"""
if max_retries <= 0:
return None
@ -288,6 +321,9 @@ class API_Handler:
Returns:
int: status code
Raises:
None
"""
with r.Session() as s:
time = time[:-3] + "Z" # remove last character and add Z to make it a valid date for db
@ -306,6 +342,9 @@ class API_Handler:
Returns:
dict: dictionary of portfolio
Raises:
None
"""
if max_retries <= 0:
return None
@ -328,6 +367,9 @@ class API_Handler:
Returns:
int: status code
Raises:
None
"""
if not croniter.is_valid(cron_interval): # check if cron_interval is in valid format
print("Error: Invalid cron format")
@ -348,6 +390,9 @@ class API_Handler:
Returns:
int: status code
Raises:
None
"""
with r.Session() as s:
headers = {'Authorization': 'Bearer ' + self.token} # only bot token is needed, user is chosen by email

View File

@ -3,8 +3,8 @@
script for telegram bot and its functions
"""
__author__ = "Florian Kellermann, Linus Eickhoff"
__date__ = "26.04.2022"
__version__ = "1.2.2"
__date__ = "10.05.2022"
__version__ = "1.2.3"
__license__ = "None"
# side-dependencies: none
@ -23,6 +23,7 @@ import re
import news.news_fetcher as news
import shares.share_fetcher as share_fetcher
import helper_functions as hf
import datetime as dt
from telebot import types
@ -83,7 +84,7 @@ def send_help(message):
:rtype: none
"""
bot.reply_to(message, "/id or /auth get your user id\n/update get updates on your shares.\n/setAdmin set admin rights of user (ADMIN)\n/users see all users. (ADMIN)\n/me get my user info\n/news get top article for each keyword.\n/allnews get all news (last 7 days)\n/keywords get all your keywords\n/addkeyword add a keyword\n/removekeyword remove a keyword\n/share get price of specific share\n/portfolio see own portfolio\n/newtransaction add new transaction\n/interval get update interval\n/setinterval set update interval\n_For further details see https://gruppe1.testsites.info _", parse_mode='MARKDOWN')
bot.reply_to(message, "/id or /auth get your user id\n/update get updates on your shares.\n/shares get update on interesting shares\n/setAdmin set admin rights of user (ADMIN)\n/users see all users. (ADMIN)\n/me get my user info\n/news get top article for each keyword.\n/allnews get all news (last 7 days)\n/keywords get all your keywords\n/addkeyword add a keyword\n/removekeyword remove a keyword\n/transactions get all transactions\n/newtransaction create new transaction\n/share get price of specific share\n/portfolio see own portfolio\n/removeshare removes share from portfolio\n/interval get update interval\n/setinterval set update interval\n For further details see https://gruppe1.testsites.info")
@bot.message_handler(commands=['users', 'Users']) # /users -> sending all users
@ -225,7 +226,6 @@ def update_for_user(message):
share_symbols = []
share_amounts = []
share_courses = []
my_portfolio = p_my_handler.get_user_portfolio(p_user_id)
@ -234,15 +234,15 @@ def update_for_user(message):
print(element["count"], element["isin"])
share_symbols.append(element["isin"])
share_amounts.append(element["count"])
share_courses.append(element["current_price"])
my_user = p_my_handler.get_user(p_user_id)
send_to_user("Hello %s this is your share update:"%str(my_user["username"]), pUser_id=p_user_id)
if len(share_symbols) != 0:
for i in range(len(share_symbols)):
my_update_message = f'Symbol: {share_symbols[i]}\nCurrent Price per Share: {share_courses[i]}\nAmount owned: {share_amounts[i]}\nTotal Investment: {float(share_courses[i]) * float(share_amounts[i])}'
send_to_user(my_update_message, pUser_id=p_user_id)
my_price = share_fetcher.get_share_price_no_currency(share_symbols[i])
my_update_message = f'{share_fetcher.get_share_information_markdown(share_symbols[i])}\ncount: {share_amounts[i]}\nTotal: {hf.make_markdown_proof(round(float(my_price) * float(share_amounts[i]), 2))} EUR'
bot.send_message(chat_id=p_user_id, text=my_update_message, parse_mode="MARKDOWNV2")
else:
send_to_user("No shares found for your account. Check https://gruppe1.testsites.info to change your settings and add shares.", pUser_id=p_user_id)
@ -280,8 +280,8 @@ def send_share_update(message):
bot.register_next_step_handler(message, send_share_price)
def send_share_price(message):
str_share_price = share_fetcher.get_share_information(str(message.text))
bot.reply_to(message, str_share_price)
str_share_price = share_fetcher.get_share_information_markdown(str(message.text))
bot.reply_to(message, str_share_price, parse_mode="MARKDOWNV2")
@bot.message_handler(commands=['allnews', 'Allnews']) # /allnews -> get all news
@ -304,7 +304,7 @@ def send_all_news(message):
return
if not keywords: # true if user is registered but does not have any keywords
bot.send_message(chat_id=user_id, text='You have no keywords. Please add some keywords with /news')
bot.send_message(chat_id=user_id, text='You have no keywords. Please add some keywords with /addkeyword')
return
keywords_search = ' OR '.join(keywords) # concat all keywords with OR -> NewsAPI can understand OR, AND, NOT etc.
@ -316,7 +316,7 @@ def send_all_news(message):
if news_list: # true if news_list is not empty
for article in news_list:
formatted_article = news.format_article(article)
bot.send_message(chat_id=user_id, text=formatted_article, parse_mode="MARKDOWN") # Markdown allows to write bold text with * etc.
bot.send_message(chat_id=user_id, text=formatted_article, parse_mode="MARKDOWNV2") # Markdown allows to write bold text with * etc.
else:
bot.send_message(chat_id=user_id, text='No news found for your keywords.')
@ -350,11 +350,13 @@ def send_news(message):
bot.send_message(chat_id=user_id, text='News Server did not respond correctly. Try again later.')
if not top_news: # true if no news found for keyword (empty list)
bot.send_message(chat_id=user_id, text=f'No news found for keyword: *{keyword}*', parse_mode="MARKDOWN")
keyword = hf.make_markdown_proof(keyword)
bot.send_message(chat_id=user_id, text=f'No news found for keyword: *{keyword}*', parse_mode="MARKDOWNV2")
else:
keyword = hf.make_markdown_proof(keyword)
formatted_article = news.format_article(top_news[0]) # only format and send most popular news
bot.send_message(chat_id=user_id, text=f"_keyword: {keyword}_\n\n" + formatted_article, parse_mode="MARKDOWN")
bot.send_message(chat_id=user_id, text=f"_keyword: {keyword}_\n\n" + formatted_article, parse_mode="MARKDOWNV2") # do not use v2 because of bugs related t "." in links
@bot.message_handler(commands=['addkeyword', 'Addkeyword']) # /addkeyword -> add keyword to user
@ -417,15 +419,21 @@ def send_keywords(message):
"""
user_id = int(message.from_user.id)
keywords = api_handler.get_user_keywords(user_id) # get keywords of user
if keywords == None: # true if user is not registered
bot.send_message(chat_id=user_id, text='This didn\'t work. Make sure to connect your telegram id (/id) on https://gruppe1.testsites.info')
return
if not keywords: # true if user is registered but does not have any keywords
bot.send_message(chat_id=user_id, text='No keywords set for this account. Add keywords by using /addkeyword')
return
else: # send keyword list
keywords_str = ', '.join(keywords)
bot.send_message(chat_id=user_id, text=f'Your keywords are: _{keywords_str}_', parse_mode="MARKDOWN")
keywords_str = hf.make_markdown_proof(keywords_str)
text = f'Your keywords are: _{keywords_str}_'
bot.send_message(chat_id=user_id, text=text, parse_mode="MARKDOWNV2")
@bot.message_handler(commands=['portfolio', 'Portfolio'])
@ -448,11 +456,40 @@ def send_portfolio(message):
return
else: # send portfolio
for stock in portfolio:
comment = str(stock["comment"]) # comment may be written name of stock, comment is made by user when adding an stock to portfolio
count = "{:.2f}".format(float(stock["count"])) # round count to 2 decimal places
isin = str(stock["isin"])
worth = "{:.2f}".format(float(stock["current_price"]) * float(stock["count"])) # round current_price to 2 decimal places
bot.send_message(chat_id=user_id, text=f'*{comment}*\n_{isin}_\namount: {count}\nworth: ${worth}', parse_mode="MARKDOWN") # formatted message in markdown
comment = hf.make_markdown_proof(str(stock["comment"])) # comment may be written name of stock, comment is made by user when adding an stock to portfolio
count = hf.make_markdown_proof("{:.2f}".format(float(stock["count"]))) # round count to 2 decimal places
isin = hf.make_markdown_proof(str(stock["isin"]))
worth = hf.make_markdown_proof("{:.2f}".format(float(stock["current_price"]) * float(stock["count"]))) # round current_price to 2 decimal places
bot.send_message(chat_id=user_id, text=f'*{comment}*\n_{isin}_\namount: {count}\nworth: ${worth}', parse_mode="MARKDOWNV2") # formatted message in markdown
@bot.message_handler(commands=['removeshare', 'Removeshare'])
def remove_share(message):
""" Remove share from portfolio
:type message: message object bot
:param message: message that was reacted to, in this case always '/removeshare'
:raises: none
:rtype: none
"""
user_id = int(message.from_user.id)
bot.send_message(chat_id=user_id, text='Type ISIN/Symbol/CompanyName of share to remove (if you are unsure do /portfolio, find your share and insert the value above amount):')
bot.register_next_step_handler(message, remove_share_step) # wait for user to send ISIN, then call remove_share_step function
def remove_share_step(message):
user_id = int(message.from_user.id)
isin = str(message.text)
status = api_handler.delete_share(int(user_id), str(isin)) # remove share from portfolio
if status == 200: # statuscode 200 means share was removed successfully without errors
bot.send_message(chat_id=user_id, text=f'Share "{isin}" removed.') # checking if share to remove is in database are handled in database, not here
else:
bot.send_message(chat_id=user_id, text=f'Failed deleting share "{isin}". (statuscode {status})\nMake sure that the share is in your portfolio and written exactly like there.')
@bot.message_handler(commands=['newtransaction', 'Newtransaction']) #tbd not working rn may be deleted in future
@ -469,10 +506,11 @@ def set_new_transaction(message):
bot.send_message(chat_id=user_id, text='Type "<name of stock>,<isin/name/symbol>,<amount>,<price_per_stock_usd>" (time of transaction will be set to now, negative amount is selling, positive is buying):')
bot.register_next_step_handler(message, set_new_transaction_step)
def set_new_transaction_step(message):
user_id = int(message.from_user.id)
if not re.match(r"[A-Za-z0-9]+,[A-Za-z0-9]+,(-)?[0-9]+(.[0-9]+)?,[0-9]+(.[0-9]+)?", message.text):
if not re.match(r"[A-Za-z0-9 ]+,[A-Za-z0-9]+,(-)?[0-9]+(.[0-9]+)?,[0-9]+(.[0-9]+)?", message.text):
bot.send_message(chat_id=user_id, text='Invalid format \n(e.g. Apple,US0378331005,53.2,120.4).\n Try again with /newtransaction.')
return
@ -514,7 +552,63 @@ def send_interval(message):
return
formatted_interval = str(interval).replace(' ', '_') # replace spaces with underscores to add to url of crontab.guru
bot.send_message(chat_id=user_id, text=f'Your update interval: {interval} (https://crontab.guru/#{formatted_interval})')
@bot.message_handler(commands=['transactions', 'Transactions'])
def send_transactions(message):
""" send transactions for user
:type message: message object bot
:param message: message that was reacted to, in this case always '/transactions'
:raises: none
:rtype: none
"""
user_id = int(message.from_user.id)
transactions = api_handler.get_user_transactions(user_id) # get transactions of user
if transactions == None: # true if user does not exist
bot.send_message(chat_id=user_id, text='This didn\'t work. Make sure to connect your telegram id (/id) on https://gruppe1.testsites.info')
return
if not transactions: # true if user has no transactions
bot.send_message(chat_id=user_id, text='You do not have any transactions.')
return
else:
for transaction in transactions:
comment = hf.make_markdown_proof(transaction['comment']) or "\(no desc\)" # if comment is empty, make it "no desc"
isin = hf.make_markdown_proof(transaction['isin'])
amount = hf.make_markdown_proof(transaction['count'])
price = hf.make_markdown_proof(transaction['price'])
time = hf.make_markdown_proof(transaction['time'])
bot.send_message(chat_id=user_id, text=f'_{comment}_\n{isin}\namount: {amount}\nprice: {price}\ntime: {time}', parse_mode="MARKDOWNV2")
@bot.message_handler(commands=['shares', 'Shares'])
def send_shares(message):
""" send shares for user
:type message: message object bot
:param message: message that was reacted to, in this case always '/shares'
:raises: none
:rtype: none
"""
user_id = int(message.from_user.id)
shares = api_handler.get_user_shares(user_id) # get shares of user
if shares == None: # true if user does not exist
bot.send_message(chat_id=user_id, text='This didn\'t work. Make sure to connect your telegram id (/id) on https://gruppe1.testsites.info')
elif not shares: # true if user has no shares
bot.send_message(chat_id=user_id, text='You do not have any shares. Add shares on https://gruppe1.testsites.info')
else:
for element in shares:
bot.send_message(chat_id=user_id, text=share_fetcher.get_share_information_markdown(element), parse_mode="MARKDOWNV2")
@bot.message_handler(commands=['setinterval', 'Setinterval'])
def set_new_interval(message):

View File

@ -2,7 +2,7 @@
script for regularly sending updates on shares and news based on user interval
"""
__author__ = "Florian Kellermann, Linus Eickhoff"
__date__ = "26.04.2022"
__date__ = "10.05.2022"
__version__ = "1.0.2"
__license__ = "None"
@ -14,6 +14,8 @@ from bot import bot
import sys
from apscheduler.schedulers.background import BackgroundScheduler
from api_handling.api_handler import API_Handler
import shares.share_fetcher as share_fetcher
import helper_functions as hf
'''
@ -72,7 +74,8 @@ def update_crontab(p_my_handler):
user_ids.append(int(element["telegram_user_id"]))
try:
user_crontab.append(str(element["cron"]))
except: continue
except:
user_ids.pop()
except: continue
@ -136,29 +139,39 @@ def update_for_user(p_user_id, p_my_handler):
print(element["count"], element["isin"])
share_symbols.append(element["isin"])
share_amounts.append(element["count"])
share_courses.append(element["current_price"])
my_user = p_my_handler.get_user(p_user_id)
send_to_user("Hello %s this is your share update for today:"%str(my_user["username"]), pUser_id=p_user_id)
shares = p_my_handler.get_user_shares(p_user_id)
if len(share_symbols) != 0:
for i in range(len(share_symbols)):
my_update_message = f'Symbol: {share_symbols[i]}\nCurrent Price per Share: {share_courses[i]}\nAmount owned: {share_amounts[i]}\nTotal Investment: {float(share_courses[i]) * float(share_amounts[i])}'
send_to_user(my_update_message, pUser_id=p_user_id)
my_price = share_fetcher.get_share_price_no_currency(share_symbols[i])
my_update_message = f'{share_fetcher.get_share_information_markdown(share_symbols[i])}\ncount: {share_amounts[i]}\nTotal: {hf.make_markdown_proof(round(float(my_price) * float(share_amounts[i]), 2))} EUR'
bot.send_message(chat_id=p_user_id, text=my_update_message, parse_mode="MARKDOWNV2")
else:
send_to_user("No shares found for your account. Check https://gruppe1.testsites.info to change your settings and add shares.", pUser_id=p_user_id)
if len(shares)!=0: # Send updates on watchlist shares if existing
send_to_user("Your watchlist shares:", pUser_id=p_user_id)
for element in shares:
send_to_user(share_fetcher.get_share_information_markdown(element), pUser_id=p_user_id, md_mode=True)
keywords = p_my_handler.get_user_keywords(p_user_id) # get keywords as array
if(keywords): # if keywords exist and array is not empty
send_to_user("If you haven't read yet: \nHere are some interesting news according to your keywords:", pUser_id=p_user_id)
for keyword in keywords:
news = news_fetcher.get_top_news_by_keyword(keyword)["articles"]
keyword = hf.make_markdown_proof(keyword)
if not news: # if empty news array
send_to_user(f"No news found for keyword _{keyword}_.", pUser_id=p_user_id, md_mode=True)
if news == None: # if news is none
elif news == None: # if news is none
send_to_user(f"Server error for keyword _{keyword}_.", pUser_id=p_user_id, md_mode=True)
else:
news_formatted = news_fetcher.format_article(news[0]) # format for message, only use the most popular article
@ -183,7 +196,7 @@ def send_to_user(pText, pUser_id , md_mode = False):
:rtype: none
"""
if md_mode:
bot.send_message(chat_id=pUser_id, text=pText, parse_mode="MARKDOWN")
bot.send_message(chat_id=pUser_id, text=pText, parse_mode="MARKDOWNV2")
else:
bot.send_message(chat_id=pUser_id, text=pText)

View File

@ -0,0 +1,68 @@
"""
script for helper functions for bot related stuff
"""
__author__ = "Florian Kellermann, Linus Eickhoff"
__date__ = "10.05.2022"
__version__ = "1.0.0"
__license__ = "None"
def contains_markdownv1_symbols(text):
""" checks if text contains markdown symbols
:type text: string
:param text: text to check
:return: true if text contains markdown symbols
:rtype: bool
"""
if text.find("_") != -1 or text.find("*") != -1 or text.find("`") != -1: # check if text contains relevant markdown symbols
return True
return False
def make_markdown_proof(text): # used to avoid errors related to markdown parsemode for telegram messaging
""" makes text markdown proof
:type text: string
:param text: text to make markdown proof
:return: markdown proof text
:rtype: string
"""
text = str(text)
text = text.replace("_", "\\_") # replace _ with \_ because \ is used as escape character in markdown, double escape is needed because \ is also a escape character in strings
text = text.replace("*", "\\*")
text = text.replace("`", "\\`")
text = text.replace("[", "\\[")
text = text.replace("]", "\\]")
text = text.replace("(", "\\(")
text = text.replace(")", "\\)")
text = text.replace("#", "\\#")
text = text.replace("+", "\\+")
text = text.replace("-", "\\-")
text = text.replace("!", "\\!")
text = text.replace(".", "\\.")
text = text.replace("?", "\\?")
text = text.replace("/", "\\/")
text = text.replace("~", "\\~")
text = text.replace("|", "\\|")
text = text.replace("<", "\\<")
text = text.replace(">", "\\>")
text = text.replace("&", "\\&")
text = text.replace("^", "\\^")
text = text.replace("$", "\\$")
text = text.replace("%", "\\%")
return text
if __name__ == '__main__':
print("this is a module for helper functions for the bot and should not be run directly")
print(make_markdown_proof("_test_"))
text = make_markdown_proof("_test_")
print(f"{text}")

View File

@ -10,6 +10,8 @@ import sys
import os
import requests
import helper_functions as hf
from newsapi import NewsApiClient
from dotenv import load_dotenv
@ -18,14 +20,16 @@ load_dotenv() # loads environment vars
# Init
api_key = os.getenv('NEWS_API_KEY') # get API Key from .env file
newsapi = NewsApiClient(api_key=api_key) # news api from https://newsapi.org/
try:
# get all available news sources (e.g BBC, New York Times, etc.)
source_json = requests.get(f"https://newsapi.org/v2/top-headlines/sources?apiKey={api_key}&language=en").json()
sources = source_json["sources"]
str_sources = ",".join([source["id"] for source in sources])
except KeyError:
print("Error: Could not get sources")
sys.exit(1)
print("Error: Could not get sources, may be blocked because of too many requests (free newsapi is limited to 100 reqs per day)")
str_sources = str("Reuters, bbc, cnn, fox-news, google-news, hacker-news, nytimes, the-huffington-post, the-new-york-times, business-insider, bbc-news, cbc-news, ESPN, fox-sports, google-news-uk, independent, the-wall-street-journal, the-washington-times, time, usa-today")
def get_all_news_by_keyword(keyword, from_date="2000-01-01"):
@ -68,13 +72,14 @@ def format_article(article):
Returns:
String: formatted article
"""
sourcename = article["source"]["name"]
headline = article["title"]
url = article["url"]
sourcename = hf.make_markdown_proof(article["source"]["name"]) # make attributes markdownv2 proof
headline = hf.make_markdown_proof(article["title"])
url = hf.make_markdown_proof(article["url"])
formatted_article = f"_{sourcename}_\n*{headline}*\n\n{url}" # formatting in Markdown syntax
return formatted_article
if __name__ == '__main__': # only execute if script is called directly -> for simple testing
print("this is a module and should not be run directly")

View File

@ -2,13 +2,14 @@
script for share fetching (by symbols (e.g. AAPL, TSLA etc.))
"""
__author__ = "Florian Kellermann, Linus Eickhoff"
__date__ = "15.03.2022"
__version__ = "1.0.0"
__date__ = "10.05.2022"
__version__ = "1.0.1"
__license__ = "None"
import investpy
import pandas
from currency_converter import CurrencyConverter
import helper_functions as hf
def get_share_price(str_search_for):
"""get stock price per share for company name or isin or symbol
@ -55,13 +56,11 @@ def get_share_price(str_search_for):
except RuntimeError:
return "None"
def get_share_price_no_currency(str_search_for):
"""get stock price per share for company name or isin or symbol no currency
Args:
str_search_for (string): search for this string/isin
Returns: none
"""
try:
@ -96,7 +95,6 @@ def get_share_price_no_currency(str_search_for):
return str_return
def get_share_information(str_search_for):
search_result = investpy.search_quotes(text=str_search_for, products=['stocks'],
countries=['germany'], n_results=1)
@ -105,8 +103,19 @@ def get_share_information(str_search_for):
return str_return
def get_share_information_markdown(str_search_for):
search_result = investpy.search_quotes(text=str_search_for, products=['stocks'],
countries=['germany'], n_results=1)
str_return = f'*{hf.make_markdown_proof(search_result.name)}*\n_{hf.make_markdown_proof(search_result.symbol)}_\nworth: {hf.make_markdown_proof(get_share_price(str_search_for))}'
return str_return
def get_share_information_simple(str_search_for):
search_result = investpy.search_quotes(text=str_search_for, products=['stocks'],
countries=['germany'], n_results=1)
str_return = search_result.name + "\n" +search_result.symbol + "\nworth: " + get_share_price(str_search_for)
return str_return
if __name__ == "__main__":
print(get_share_price("US2515661054"))
print(get_share_price("DE0005557508"))
print(get_share_price_no_currency("US2515661054"))
print(get_share_price_no_currency("DE0005557508"))
print("None")