- Создал(а) Aleksandr Savkin, редактировал(а) Vasily Selivantsev янв. 26, 2023
resources/archive/shot_saver.py
This module provides a high-level interface for saving screenshots asynchronously in the form of the ShotSaver class.
Class arguments
pool_size (int, optional)
: Maximum number of simultaneously saved screenshots. 10 by default.callback (callable[str, str], optional)
: Callback function that is called after the screenshots are saved. The guid of the task to save and the current status of the task are passed to this function.
Class public attributes
timeout_sec (int)
: Screenshot waiting time, sec. 10 by default.buffer_ts(int)
: Waiting time for creating a screenshot with figures. 0 by default.max_tries (int)
: Number of attempts to save a screenshot. 2 by default.callback (callable[str, str])
: Same as the callback argument.pool_size (int)
: Same as the pool_size argument.screenshots_folder (str)
: Screenshots folder by default, if no other is specified when calling the method. Server screenshot folder by default.
Class methods
save
- Saves a screenshot to a file. Returns task's guid and a path, where the screenshot will be saved.
Method's arguments:- channel_full_guid (str): Channel guid in a form of ChannelGuid_ServerGuid .
dt (datetime.datetime, optional)
: Date and time of a screenshot saving. Current date and time by default.figures (bool, optional):
If True - saves a screenshot with figures. False by default.file_name (str, optional)
: Screenshot name. By default, it is generated according to the template{channel.name} (%Y.%m.%d %H-%M-%S.%f).jpg
In the screenshot name, date and time formatting is supported (available arguments are at https://strftime.org/) as well as channel and server objects.file_path (str, optional)
: Full name for screenshot saving. By default, screenshot will be saved in the directory, defined in screenshots_folder attribute.callback (callable[str, str], optional)
: Callback function that is called after screenshots are saved. The guid of the task to save and the current status of the task are passed to this function. If not defined - callback of class is used.task_guid (str, optional)
: Task's guid. host.random_guid() function define it by default.
get
- Returns image in callback, bytes
Method arguments:channel_full_guid (str)
: Channel guid in a form of ChannelGuid_ServerGuid .dt (datetime.datetime, optional)
: Date and time of a screenshot saving. Current date and time by default.figures (bool, optional)
: If True - saves a screenshot with figures. False by default.callback (callable[str, str])
: Callback function that is called after screenshots are saved. The guid of the task to save and the current status of the task are passed to this function. If not defined - callback of class is used. Raises EnvironmentError if callback of class is also not defined.
Possible states of screenshot saving are contained in the status object:
status.saving
- Screenshot is being saved.status.error
- Error of screenshot saving.status.success
- Screenshot is successfully saved.status.in_queue
- Screenshot is added to a saving queue.
During the initialization, the ShotSaver class creates a thread pool from several separate threads (worker), the number of threads is equal to the pool_size parameter.
Saving screenshots in thread pool is necessary to limit the number of screenshots requested at the same time, for a large number of requests of the host.screenshot_v2 or host.screenshot_v2_figures method can lead to the Trassir crash.
Each call of the save method adds a save task to the task queue. Which later pick up the workers in turn. Also status.in_queue is passed to the callback.
Worker calls the host.screenshot_v2 or host.screenshot_v2_figures method depending on the figures parameter and passes status.saving to the callback. Then it waits for the file to appear in the specified folder during the time specified in the timeout_sec parameter.
If the screenshot does not appear within the specified time in the folder and max_tries > 1, then the worker will call the method for saving the screenshot again. Then the logic of waiting and re-saving is repeated as many times as specified in the max_tries parameter.
If the screenshot has been successfully saved, then status.success is passed to the callback.
If the screenshot does not appear in the folder after all attempts, status.error is passed to the callback.
The get method works the same way as the save method, except that after successfully saving the screenshot, it gets the image and passes the result to the callback, after which it deletes the screenshot file.
Code examples
Simple example
Saving the current screenshot from the channel with a standard name to the screenshots folder.
from shot_saver import ShotSaver CHANNEL_GUID = "uR76TlcA_O4Yazs8u" # Must be replaced with the guid of your channel ss = ShotSaver() ss.save(CHANNEL_GUID)
Changing the folder of screenshots saving
If you want all screenshots of this script to be saved in a separate folder, you can change it globally for the entire class.
from shot_saver import ShotSaver CHANNEL_GUID = "uR76TlcA_O4Yazs8u" # Must be replaced with the guid of your channel ss = ShotSaver() ss.screenshots_folder = r"D:\DSSL\shots" ss.save(CHANNEL_GUID)
Or assign directly when saving a screenshot
from shot_saver import ShotSaver CHANNEL_GUID = "uR76TlcA_O4Yazs8u" # Must be replaced with the guid of your channel ss = ShotSaver() ss.save(CHANNEL_GUID, file_path=r"D:\DSSL\shots")
Screenshot request for a specific date / time
We can also change the name of the screenshot, and / or add the date / time for which we want to save the screenshot.
For example, let's save a screenshot for the current date, and change the time to 00:00:00 .
import datetime from shot_saver import ShotSaver CHANNEL_GUID = "uR76TlcA_O4Yazs8u" # Must be replaced with the guid of your channel ss = ShotSaver() dt = datetime.datetime.combine( datetime.datetime.now().date(), # Current date datetime.time() # Время 00:00:00 ) ss.save(CHANNEL_GUID, dt=dt, file_name="midnight_shot.jpg")
Tracking of the screenshot saving status
Upon successful saving, the resulting image is opened.
We use the tasks variable to store the current tasks and the paths for the screenshot saves for each task.
import os import host from shot_saver import ShotSaver, status CHANNEL_GUID = "uR76TlcA_O4Yazs8u" ss = ShotSaver() tasks = {} def callback(guid, state): host.message("[%s] %s" % (guid, state)) # Displaying the current task status if state == status.success: # Opening the image if the screenshot was successfully saved fpath = tasks.pop(guid) os.startfile(fpath) elif state == status.error: # Removing the task from the list if an error occurs fpath = tasks.pop(guid) host.message("Can't save shot: %s" % fpath) task_guid, file_path = ss.save(CHANNEL_GUID, callback=callback) tasks[task_guid] = file_path
Getting an image in bytes
For example, to display in a window host.question
import base64 import host from shot_saver import ShotSaver CHANNEL_GUID = "uR76TlcA_O4Yazs8u" ss = ShotSaver() __image_html = """<img src="data:image/png;base64,{img}" width="800">""" def show_image(image_bytes): host.question( __image_html.format(img=base64.b64encode(image_bytes)), "OK", lambda: 0 ) ss.get(CHANNEL_GUID, callback=show_image)
- Нет меток