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:
montezdesousa
2022-10-09 10:52:07 +02:00
committed by GitHub
parent cb5e610bcb
commit bc2816c609
4 changed files with 124 additions and 0 deletions

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 897 B

View File

@@ -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

View File

@@ -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,