import re
from datetime import datetime, timedelta
from pathlib import Path
from typing import Dict, List, Match, Optional, Tuple, Union
from dateutil.relativedelta import relativedelta
from openbb_terminal.core.plots.backend import plots_backend
from openbb_terminal.rich_config import console
# pylint: disable=too-many-statements,eval-used,consider-iterating-dictionary
# pylint: disable=too-many-branches,too-many-return-statements
# Necessary for OpenBB keywords
MONTHS_VALUE = {
"JANUARY": 1,
"FEBRUARY": 2,
"MARCH": 3,
"APRIL": 4,
"MAY": 5,
"JUNE": 6,
"JULY": 7,
"AUGUST": 8,
"SEPTEMBER": 9,
"OCTOBER": 10,
"NOVEMBER": 11,
"DECEMBER": 12,
}
WEEKDAY_VALUE = {
"MONDAY": 0,
"TUESDAY": 1,
"WEDNESDAY": 2,
"THURSDAY": 3,
"FRIDAY": 4,
"SATURDAY": 5,
"SUNDAY": 6,
}
def is_reset(command: str) -> bool:
"""Test whether a command is a reset command
Parameters
----------
command : str
The command to test
Returns
-------
answer : bool
Whether the command is a reset command
"""
if "reset" in command:
return True
if command == "r":
return True
if command == "r\n":
return True
return False
def match_and_return_openbb_keyword_date(keyword: str) -> str:
"""Return OpenBB keyword into date
Parameters
----------
keyword : str
String with potential OpenBB keyword (e.g. 1MONTHAGO,LASTFRIDAY,3YEARSFROMNOW,NEXTTUESDAY)
Returns
----------
str: Date with format YYYY-MM-DD
"""
match = re.match(r"^\$(\d+)([A-Z]+)AGO$", keyword)
now = datetime.now()
if match:
integer_value = int(match.group(1))
time_unit = match.group(2)
if time_unit == "DAYS":
return (now - timedelta(days=integer_value)).strftime("%Y-%m-%d")
if time_unit == "MONTHS":
return (now - relativedelta(months=integer_value)).strftime("%Y-%m-%d")
if time_unit == "YEARS":
return (now - relativedelta(years=integer_value)).strftime("%Y-%m-%d")
match = re.match(r"^\$(\d+)([A-Z]+)FROMNOW$", keyword)
if match:
integer_value = int(match.group(1))
time_unit = match.group(2)
if time_unit == "DAYS":
return (now + timedelta(days=integer_value)).strftime("%Y-%m-%d")
if time_unit == "MONTHS":
return (now + relativedelta(months=integer_value)).strftime("%Y-%m-%d")
if time_unit == "YEARS":
return (now + relativedelta(years=integer_value)).strftime("%Y-%m-%d")
match = re.search(r"\$LAST(\w+)", keyword)
if match:
time_unit = match.group(1)
# Check if it corresponds to a month
if time_unit in list(MONTHS_VALUE.keys()):
# Calculate the year and month for last month date
if now.month > MONTHS_VALUE[time_unit]:
# If the current month is greater than the last date month, it means it is this year
return datetime(now.year, MONTHS_VALUE[time_unit], 1).strftime(
"%Y-%m-%d"
)
return datetime(now.year - 1, MONTHS_VALUE[time_unit], 1).strftime(
"%Y-%m-%d"
)
# Check if it corresponds to a week day
if time_unit in list(WEEKDAY_VALUE.keys()):
if datetime.weekday(now) > WEEKDAY_VALUE[time_unit]:
return (
now
- timedelta(datetime.weekday(now))
+ timedelta(WEEKDAY_VALUE[time_unit])
).strftime("%Y-%m-%d")
return (
now
- timedelta(7)
- timedelta(datetime.weekday(now))
+ timedelta(WEEKDAY_VALUE[time_unit])
).strftime("%Y-%m-%d")<