mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-27 04:31:13 +00:00
Autogenerated screenshots and plotshots (#2558)
* add screenshot and plotshot * handle 0 plots * black * change logo * change path spec * get window name automatically * create screenshot frame * merge commands * fix parser help * minor refactors * rewrite parser help * save img * small improvs (#2562) * prevent non windows users to use screenshot now * minor msg change * refine frames * update dependencies * black * flake8 * flake8 * change pyautogui import * update dependencies to avoid mouseinfo * update poetry and requirements * remove pygetwindow * revert dependency files to main * remove terminal ref * black * minor image change * black * move images to timages folder * move images to timages folder * remove unused var Co-authored-by: DidierRLopes <dro.lopes@campus.fct.unl.pt> Co-authored-by: hjoaquim <h.joaquim@campus.fct.unl.pt> Co-authored-by: minhhoang1023 <40023817+minhhoang1023@users.noreply.github.com> Co-authored-by: Colin Delahunty <72827203+colin99d@users.noreply.github.com>
This commit is contained in:
BIN
images/background.png
vendored
Normal file
BIN
images/background.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 324 KiB |
BIN
images/openbb_horizontal_logo.png
vendored
Normal file
BIN
images/openbb_horizontal_logo.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 897 B |
@@ -2,6 +2,7 @@
|
|||||||
__docformat__ = "numpy"
|
__docformat__ = "numpy"
|
||||||
# pylint: disable=too-many-lines
|
# pylint: disable=too-many-lines
|
||||||
import argparse
|
import argparse
|
||||||
|
import io
|
||||||
import logging
|
import logging
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Union, Optional, Dict
|
from typing import List, Union, Optional, Dict
|
||||||
@@ -35,6 +36,8 @@ from screeninfo import get_monitors
|
|||||||
import yfinance as yf
|
import yfinance as yf
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
from PIL import Image, ImageDraw
|
||||||
|
|
||||||
from openbb_terminal.rich_config import console
|
from openbb_terminal.rich_config import console
|
||||||
from openbb_terminal import feature_flags as obbff
|
from openbb_terminal import feature_flags as obbff
|
||||||
from openbb_terminal import config_plot as cfgPlot
|
from openbb_terminal import config_plot as cfgPlot
|
||||||
@@ -1671,6 +1674,109 @@ def search_wikipedia(expression: str) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def screenshot() -> None:
|
||||||
|
"""
|
||||||
|
Screenshot the terminal window or the plot window
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
terminal_window_target: bool
|
||||||
|
Target the terminal window
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
if plt.get_fignums():
|
||||||
|
img_buf = io.BytesIO()
|
||||||
|
plt.savefig(img_buf, format="png")
|
||||||
|
shot = Image.open(img_buf)
|
||||||
|
screenshot_to_canvas(shot, plot_exists=True)
|
||||||
|
console.print("")
|
||||||
|
|
||||||
|
else:
|
||||||
|
console.print("No plots found.\n")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
console.print(f"Cannot reach window - {e}\n")
|
||||||
|
|
||||||
|
|
||||||
|
def screenshot_to_canvas(shot, plot_exists: bool = False):
|
||||||
|
"""
|
||||||
|
Frame image to OpenBB canvas.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
shot
|
||||||
|
Image to frame with OpenBB Canvas
|
||||||
|
plot_exists: bool
|
||||||
|
Variable to say whether the image is a plot or screenshot of terminal
|
||||||
|
"""
|
||||||
|
|
||||||
|
WHITE_LINE_WIDTH = 3
|
||||||
|
OUTSIDE_CANVAS_WIDTH = shot.width + 4 * WHITE_LINE_WIDTH + 5
|
||||||
|
OUTSIDE_CANVAS_HEIGHT = shot.height + 4 * WHITE_LINE_WIDTH + 5
|
||||||
|
UPPER_SPACE = 40
|
||||||
|
BACKGROUND_WIDTH_SLACK = 150
|
||||||
|
BACKGROUND_HEIGHT_SLACK = 150
|
||||||
|
|
||||||
|
background = Image.open(Path("images/background.png"))
|
||||||
|
logo = Image.open(Path("images/openbb_horizontal_logo.png"))
|
||||||
|
|
||||||
|
try:
|
||||||
|
if plot_exists:
|
||||||
|
HEADER_HEIGHT = 0
|
||||||
|
RADIUS = 8
|
||||||
|
|
||||||
|
background = background.resize(
|
||||||
|
(
|
||||||
|
shot.width + BACKGROUND_WIDTH_SLACK,
|
||||||
|
shot.height + BACKGROUND_HEIGHT_SLACK,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
x = int((background.width - OUTSIDE_CANVAS_WIDTH) / 2)
|
||||||
|
y = UPPER_SPACE
|
||||||
|
|
||||||
|
white_shape = [
|
||||||
|
(x, y),
|
||||||
|
(x + OUTSIDE_CANVAS_WIDTH, y + OUTSIDE_CANVAS_HEIGHT),
|
||||||
|
]
|
||||||
|
img = ImageDraw.Draw(background)
|
||||||
|
img.rounded_rectangle(
|
||||||
|
white_shape,
|
||||||
|
fill="black",
|
||||||
|
outline="white",
|
||||||
|
width=WHITE_LINE_WIDTH,
|
||||||
|
radius=RADIUS,
|
||||||
|
)
|
||||||
|
background.paste(shot, (x + WHITE_LINE_WIDTH + 5, y + WHITE_LINE_WIDTH + 5))
|
||||||
|
|
||||||
|
# Logo
|
||||||
|
background.paste(
|
||||||
|
logo,
|
||||||
|
(
|
||||||
|
int((background.width - logo.width) / 2),
|
||||||
|
UPPER_SPACE
|
||||||
|
+ OUTSIDE_CANVAS_HEIGHT
|
||||||
|
+ HEADER_HEIGHT
|
||||||
|
+ int(
|
||||||
|
(
|
||||||
|
background.height
|
||||||
|
- UPPER_SPACE
|
||||||
|
- OUTSIDE_CANVAS_HEIGHT
|
||||||
|
- HEADER_HEIGHT
|
||||||
|
- logo.height
|
||||||
|
)
|
||||||
|
/ 2
|
||||||
|
),
|
||||||
|
),
|
||||||
|
logo,
|
||||||
|
)
|
||||||
|
|
||||||
|
background.show(title="screenshot")
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
console.print("Shot failed.")
|
||||||
|
|
||||||
|
|
||||||
@lru_cache
|
@lru_cache
|
||||||
def load_json(path: str) -> Dict[str, str]:
|
def load_json(path: str) -> Dict[str, str]:
|
||||||
"""Loads a dictionary from a json file path
|
"""Loads a dictionary from a json file path
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ from openbb_terminal.helper_funcs import (
|
|||||||
load_json,
|
load_json,
|
||||||
parse_and_split_input,
|
parse_and_split_input,
|
||||||
search_wikipedia,
|
search_wikipedia,
|
||||||
|
screenshot,
|
||||||
)
|
)
|
||||||
from openbb_terminal.config_terminal import theme
|
from openbb_terminal.config_terminal import theme
|
||||||
from openbb_terminal.rich_config import console, get_ordered_list_sources
|
from openbb_terminal.rich_config import console, get_ordered_list_sources
|
||||||
@@ -92,6 +93,7 @@ class BaseController(metaclass=ABCMeta):
|
|||||||
"wiki",
|
"wiki",
|
||||||
"record",
|
"record",
|
||||||
"stop",
|
"stop",
|
||||||
|
"screenshot",
|
||||||
]
|
]
|
||||||
|
|
||||||
CHOICES_COMMANDS: List[str] = []
|
CHOICES_COMMANDS: List[str] = []
|
||||||
@@ -623,6 +625,22 @@ class BaseController(metaclass=ABCMeta):
|
|||||||
RECORD_SESSION = False
|
RECORD_SESSION = False
|
||||||
SESSION_RECORDED = list()
|
SESSION_RECORDED = list()
|
||||||
|
|
||||||
|
@log_start_end(log=logger)
|
||||||
|
def call_screenshot(self, other_args: List[str]) -> None:
|
||||||
|
"""Process screenshot command"""
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
add_help=False,
|
||||||
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||||
|
prog="screenshot",
|
||||||
|
description="Screenshot terminal window or plot figure open into an OpenBB frame. "
|
||||||
|
"Default target is plot if there is one open, otherwise it's terminal window. "
|
||||||
|
" In case the user wants the terminal window, it can be forced with '-t` or '--terminal' flag passed.",
|
||||||
|
)
|
||||||
|
ns_parser = parse_simple_args(parser, other_args)
|
||||||
|
|
||||||
|
if ns_parser:
|
||||||
|
screenshot()
|
||||||
|
|
||||||
def parse_known_args_and_warn(
|
def parse_known_args_and_warn(
|
||||||
self,
|
self,
|
||||||
parser: argparse.ArgumentParser,
|
parser: argparse.ArgumentParser,
|
||||||
|
|||||||
Reference in New Issue
Block a user