From b7f191c99462111d25089b9b0aef18451f0f3802 Mon Sep 17 00:00:00 2001 From: HappyCthulhu Date: Fri, 8 Oct 2021 19:34:39 +0300 Subject: [PATCH] Move all launch funcs to launch.py --- card0_manager.py | 12 +- launch.py | 166 +++++++++++++++++++++++++ moncontrol.py | 170 ++------------------------ monitors_manager.py | 12 +- xrandr_manager.py => xrandrmanager.py | 2 +- 5 files changed, 188 insertions(+), 174 deletions(-) create mode 100644 launch.py rename xrandr_manager.py => xrandrmanager.py (99%) diff --git a/card0_manager.py b/card0_manager.py index 6a167c6..37afbad 100644 --- a/card0_manager.py +++ b/card0_manager.py @@ -5,7 +5,7 @@ from logging_settings import set_logger -class CARD0: +class Card0: @staticmethod def check_cable_status(fp): @@ -36,7 +36,7 @@ def check_if_cable_was_disconnected(past_cables_conditions, cables_conditions_fi # проходимся по списку из старых кабелей, отдельно получаем текущую информацию для кабеля, сравниваем for port_path, port_past_condition in past_cables_conditions.copy().items(): - current_cable_status = CARD0.check_cable_status(f'{port_path}/status').replace('\n', '') + current_cable_status = Card0.check_cable_status(f'{port_path}/status').replace('\n', '') if current_cable_status != port_past_condition: removed_cables.append(port_path.split("/")[-1]) @@ -76,19 +76,19 @@ def check_cable_conditions_until_it_change(cabels_conditions_file_path): logger.debug(f'Файл конфигов был пуст или не существовал') with open(cabels_conditions_file_path, 'w') as file: - json.dump(CARD0.get_cables_path_condition_from_card0(), file, indent=4) + json.dump(Card0.get_cables_path_condition_from_card0(), file, indent=4) return True else: with open(cabels_conditions_file_path, 'r') as file: past_cables_conditions = json.load(file) - current_cables_conditions_from_card0 = CARD0.get_cables_path_condition_from_card0() + current_cables_conditions_from_card0 = Card0.get_cables_path_condition_from_card0() cables_changes = { - 'new_cables': CARD0.check_if_cable_was_connected(past_cables_conditions, + 'new_cables': Card0.check_if_cable_was_connected(past_cables_conditions, current_cables_conditions_from_card0), - 'removed_cables': CARD0.check_if_cable_was_disconnected(past_cables_conditions, + 'removed_cables': Card0.check_if_cable_was_disconnected(past_cables_conditions, cabels_conditions_file_path) } diff --git a/launch.py b/launch.py new file mode 100644 index 0000000..43aeb15 --- /dev/null +++ b/launch.py @@ -0,0 +1,166 @@ +import json +import os +import time +from pathlib import Path + +from card0_manager import Card0 +from logging_settings import set_logger +from monitors_manager import Monitors +from xrandrmanager import XrandrManager +class Launch: + + + + @staticmethod + def monitoring_activity(): + while True: + Card0.check_cable_conditions_until_it_change(CABLES_CONDITIONS_FILE_PATH) + xrandr = XrandrManager() + + if len(xrandr.monitors_data) == 1: + execute_command = 'xrandr --auto' + logger.info(execute_command) + + # при пустом файлу st_size возвращает 1, а не 0... + if not Path(MONITORS_LAYOUTS_FILE_PATH).is_file() or Path(MONITORS_LAYOUTS_FILE_PATH).stat().st_size < 2: + position_manually() + + else: + with open(MONITORS_LAYOUTS_FILE_PATH, 'r') as file: + previously_saved_mons_pos = json.load(file) + + location_of_monitors = xrandr.get_needed_monitors_layout_config_automatically(xrandr.monitors_data, + previously_saved_mons_pos) + + if location_of_monitors: + execute_command = xrandr.create_string_for_execute(xrandr.monitors_data, location_of_monitors) + logger.debug(f'Позиционируем мониторы согласно сохраненным ранее настройкам: {location_of_monitors}') + + logger.info(execute_command) + + else: + logger.info( + 'Config with previous monitor layouts doesnt contains current connected cables. Connecting monitors with sorting by monitors size. If you want to set monitors by yout self, use command: "moncotrol -s"') + monitors_sorted_by_size = Monitors.connect_monitors_automatically(xrandr.monitors_data) + + with open(MONITORS_LAYOUTS_FILE_PATH, 'w') as file: + json.dump(monitors_sorted_by_size, file, indent=4) + + execute_command = xrandr.create_string_for_execute(xrandr.monitors_data, monitors_sorted_by_size) + + logger.info(execute_command) + + time.sleep(3) + + # os.system(execute_command) + + + @staticmethod + def position_manually(): + monitors = Monitors() + xrandr = XrandrManager() + + my_monitors_position = monitors.set_monitors_position_manually() + + # TODO: сделать проверку на существование и пустоту файла + + if not Path(MONITORS_LAYOUTS_FILE_PATH).is_file() or Path(MONITORS_LAYOUTS_FILE_PATH).stat().st_size < 2: + + with open(MONITORS_LAYOUTS_FILE_PATH, 'w') as file: + json.dump([my_monitors_position], file) + + execute_command = xrandr.create_string_for_execute(xrandr.monitors_data, my_monitors_position) + + else: + with open(MONITORS_LAYOUTS_FILE_PATH, 'r') as file: + previously_saved_mons_pos = json.load(file) + + new_collection_of_monitors_positions = xrandr.create_new_collections_of_mon_positions(my_monitors_position, + previously_saved_mons_pos) + + with open(MONITORS_LAYOUTS_FILE_PATH, 'w') as file: + json.dump(new_collection_of_monitors_positions, file, indent=4) + + execute_command = xrandr.create_string_for_execute(xrandr.monitors_data, + new_collection_of_monitors_positions[0]) + + logger.info('Settings was saved successfully') + logger.info(execute_command) + + + def wrong_input(mode, settings): + line_break = '\n' + logger.critical(f'\nСкрипт не имеет настройки: {mode}\n\n' + f'\nЗапустите скрит с одной из следующих настроек:{line_break}{line_break}\n' + f'{f"{line_break}".join(settings)}') + + + @staticmethod + def choose_one_of_saved_positions_of_monitors(): + if not Path(MONITORS_LAYOUTS_FILE_PATH).is_file() or Path(MONITORS_LAYOUTS_FILE_PATH).stat().st_size == 0: + logger.info('Config file empty or doesnt exist') + + else: + with open(MONITORS_LAYOUTS_FILE_PATH, 'r') as file: + previously_saved_mons_pos = json.load(file) + + # TODO: возможно, стоит сделать отдельную функцию для принта конфигов + if not previously_saved_mons_pos: + logger.info('You did not save any monitors layouts yet') + logger.info('Next strings will show monitors_positions in format: {config_id: [cable_1, cable_2, etc]}\n') + + saved_cable_position_with_id = XrandrManager.create_layout_id_layout_name_dict(previously_saved_mons_pos) + + # TODO: здесь должен быть logger + for id, monitors_names in saved_cable_position_with_id.items(): + print(f'\n{id}: {monitors_names}') + + print('\n') + + logger.info('Write number of config, that u need rn and press Enter button') + input_id = int(input()) + + xrandr = XrandrManager() + execute_command = xrandr.create_string_for_execute(xrandr.monitors_data, saved_cable_position_with_id[input_id]) + logger.info(execute_command) + + + @staticmethod + def show_saved_monitors_positions(): + if not Path(MONITORS_LAYOUTS_FILE_PATH).is_file() or Path(MONITORS_LAYOUTS_FILE_PATH).stat().st_size == 0: + logger.info('Config file empty or doesnt exist') + + else: + with open(MONITORS_LAYOUTS_FILE_PATH, 'r') as file: + saved_positions = json.load(file) + + saved_positions_with_position_id = XrandrManager.create_layout_id_layout_name_dict(saved_positions) + + logger.info( + 'Next strings will show monitors_positions in format: {monitors_position_id: [cabel_1, cabel_2, etc]}') + + for id, monitors_names in saved_positions_with_position_id.items(): + print(f'\n{id}: {monitors_names}') + print('\n') + + + @staticmethod + def delete_config(): + if not Path(MONITORS_LAYOUTS_FILE_PATH).is_file() or Path(MONITORS_LAYOUTS_FILE_PATH).stat().st_size == 0: + logger.info('Config file empty or doesnt exist: saved layouts doesnt exits') + + else: + with open(MONITORS_LAYOUTS_FILE_PATH, 'r') as file: + previously_saved_mons_pos = json.load(file) + + new_configs = Monitors.delete_saved_config(previously_saved_mons_pos) + + with open(MONITORS_LAYOUTS_FILE_PATH, 'w') as file: + json.dump(new_configs, file) + + logger.info( + f'This configs was deleted successfully: {[config for config in previously_saved_mons_pos if config not in new_configs]}') + +logger = set_logger() +MONITORS_LAYOUTS_FILE_PATH = 'my_monitor_layout.json' +CABLES_CONDITIONS_FILE_PATH = 'cables_conditions_from_card0.json' diff --git a/moncontrol.py b/moncontrol.py index 4077e1f..98bb46a 100755 --- a/moncontrol.py +++ b/moncontrol.py @@ -1,13 +1,9 @@ import argparse -import json import os -import time -from pathlib import Path -from card0_manager import CARD0 +from launch import Launch from logging_settings import set_logger -from monitors_manager import MONITORS -from xrandr_manager import XRANDR_MANAGER +from monitors_manager import Monitors # XRANDR_MANAGER, MONITOR_MANAGER, CARD0_MANAGER, LAUNCH @@ -28,6 +24,7 @@ # TODO: autorandr каким-то маническим образом позиционирует мои мониторы... Как?! # TODO: точно ли мне нужна дополнительная информация о мониторах в конфигах? выглядит так, будто это просто слишком сильно усложняет скрипт... можно просто получить из xrandr инфу о соответствующем мониторе + def get_and_write_virtual_env(): logger.info('Please install direnv!') @@ -40,152 +37,6 @@ def get_and_write_virtual_env(): os.environ['CABLES_DIR'] = '/sys/class/drm/card0/' -def monitoring_activity(): - while True: - CARD0.check_cable_conditions_until_it_change(CABLES_CONDITIONS_FILE_PATH) - xrandr = XRANDR_MANAGER() - - # TODO: при пустом файлу st_size возвращает 1, а не 0... wtf - print(Path(MONITORS_LAYOUTS_FILE_PATH).stat().st_size) - - if len(xrandr.monitors_data) == 1: - execute_command = 'xrandr --auto' - logger.info(execute_command) - - if not Path(MONITORS_LAYOUTS_FILE_PATH).is_file() or Path(MONITORS_LAYOUTS_FILE_PATH).stat().st_size < 2: - position_manually() - - else: - with open(MONITORS_LAYOUTS_FILE_PATH, 'r') as file: - previously_saved_mons_pos = json.load(file) - - location_of_monitors = XRANDR_MANAGER.get_needed_monitors_layout_config_automatically(xrandr.monitors_data, - previously_saved_mons_pos) - - if location_of_monitors: - execute_command = xrandr.create_string_for_execute(xrandr.monitors_data, location_of_monitors) - logger.debug(f'Позиционируем мониторы согласно сохраненным ранее настройкам: {location_of_monitors}') - - logger.info(execute_command) - - else: - logger.info( - 'Config with previous monitor layouts doesnt contains current connected cables. Connecting monitors with sorting by monitors size. If you want to set monitors by yout self, use command: "moncotrol -s"') - monitors_sorted_by_size = MONITORS.connect_monitors_automatically(xrandr.monitors_data) - - with open(MONITORS_LAYOUTS_FILE_PATH, 'w') as file: - json.dump(monitors_sorted_by_size, file, indent=4) - - execute_command = xrandr.create_string_for_execute(xrandr.monitors_data, monitors_sorted_by_size) - - logger.info(execute_command) - - time.sleep(3) - - # os.system(execute_command) - - -def position_manually(): - monitors = MONITORS() - xrandr = XRANDR_MANAGER() - - my_monitors_position = monitors.set_monitors_position_manually() - - # TODO: сделать проверку на существование и пустоту файла - - if not Path(MONITORS_LAYOUTS_FILE_PATH).is_file() or Path(MONITORS_LAYOUTS_FILE_PATH).stat().st_size < 2: - - with open(MONITORS_LAYOUTS_FILE_PATH, 'w') as file: - json.dump([my_monitors_position], file) - - execute_command = XRANDR_MANAGER.create_string_for_execute(xrandr.monitors_data, my_monitors_position) - - else: - with open(MONITORS_LAYOUTS_FILE_PATH, 'r') as file: - previously_saved_mons_pos = json.load(file) - - new_collection_of_monitors_positions = xrandr.create_new_collections_of_mon_positions(my_monitors_position, - previously_saved_mons_pos) - - with open(MONITORS_LAYOUTS_FILE_PATH, 'w') as file: - json.dump(new_collection_of_monitors_positions, file, indent=4) - - execute_command = XRANDR_MANAGER.create_string_for_execute(xrandr.monitors_data, new_collection_of_monitors_positions[0]) - - logger.info('Settings was saved successfully') - logger.info(execute_command) - - -def wrong_input(mode, settings): - line_break = '\n' - logger.critical(f'\nСкрипт не имеет настройки: {mode}\n\n' - f'\nЗапустите скрит с одной из следующих настроек:{line_break}{line_break}\n' - f'{f"{line_break}".join(settings)}') - - -def choose_one_of_saved_positions_of_monitors(): - if not Path(MONITORS_LAYOUTS_FILE_PATH).is_file() or Path(MONITORS_LAYOUTS_FILE_PATH).stat().st_size == 0: - logger.info('Config file empty or doesnt exist') - - else: - with open(MONITORS_LAYOUTS_FILE_PATH, 'r') as file: - previously_saved_mons_pos = json.load(file) - - # TODO: возможно, стоит сделать отдельную функцию для принта конфигов - if not previously_saved_mons_pos: - logger.info('You did not save any monitors layouts yet') - logger.info('Next strings will show monitors_positions in format: {config_id: [cable_1, cable_2, etc]}\n') - - saved_cable_position_with_id = XRANDR_MANAGER.create_layout_id_layout_name_dict(previously_saved_mons_pos) - - for id, monitors_names in saved_cable_position_with_id.items(): - print(f'\n{id}: {monitors_names}') - - print('\n') - - logger.info('Write number of config, that u need rn and press Enter button') - input_id = int(input()) - - xrandr = XRANDR_MANAGER() - execute_command = xrandr.create_string_for_execute(xrandr.monitors_data, saved_cable_position_with_id[input_id]) - logger.info(execute_command) - - -def show_saved_monitors_positions(): - if not Path(MONITORS_LAYOUTS_FILE_PATH).is_file() or Path(MONITORS_LAYOUTS_FILE_PATH).stat().st_size == 0: - logger.info('Config file empty or doesnt exist') - - else: - with open(MONITORS_LAYOUTS_FILE_PATH, 'r') as file: - saved_positions = json.load(file) - - saved_positions_with_position_id = XRANDR_MANAGER.create_layout_id_layout_name_dict(saved_positions) - - logger.info( - 'Next strings will show monitors_positions in format: {monitors_position_id: [cabel_1, cabel_2, etc]}') - - for id, monitors_names in saved_positions_with_position_id.items(): - print(f'\n{id}: {monitors_names}') - print('\n') - - -def delete_config(): - if not Path(MONITORS_LAYOUTS_FILE_PATH).is_file() or Path(MONITORS_LAYOUTS_FILE_PATH).stat().st_size == 0: - logger.info('Config file empty or doesnt exist: saved layouts doesnt exits') - - else: - with open(MONITORS_LAYOUTS_FILE_PATH, 'r') as file: - previously_saved_mons_pos = json.load(file) - - new_configs = MONITORS.delete_saved_config(previously_saved_mons_pos) - - with open(MONITORS_LAYOUTS_FILE_PATH, 'w') as file: - json.dump(new_configs, file) - - logger.info( - f'This configs was deleted successfully: {[config for config in previously_saved_mons_pos if config not in new_configs]}') - - def make_parser(): parser = argparse.ArgumentParser(description="Arguments:") parser.add_argument("-a", "--auto-monitoring-connectivity", default=False, action="store_true", @@ -207,12 +58,12 @@ def start_app(mode): options = ['auto_monitoring_connectivity', 'set_monitors_positions_manually', 'match_monitor_with_cable', 'watch_saved_positions', 'delete_saved_config', 'choose_one_of_saved_positions_of_monitors'] start = { - options[0]: monitoring_activity, - options[1]: position_manually, - options[2]: MONITORS.match_monitor_with_cable, - options[3]: show_saved_monitors_positions, - options[4]: delete_config, - options[5]: choose_one_of_saved_positions_of_monitors + options[0]: Launch.monitoring_activity, + options[1]: Launch.position_manually, + options[2]: Monitors.match_monitor_with_cable, + options[3]: Launch.show_saved_monitors_positions, + options[4]: Launch.delete_config, + options[5]: Launch.choose_one_of_saved_positions_of_monitors } start[mode]() @@ -224,9 +75,6 @@ def start_app(mode): if not os.environ.get('CABLES_DIR'): get_and_write_virtual_env() - MONITORS_LAYOUTS_FILE_PATH = 'my_monitor_layout.json' - CABLES_CONDITIONS_FILE_PATH = 'cables_conditions_from_card0.json' - args = make_parser().parse_args() my_gorgeous_dic = vars(args) mode = list(filter(lambda item: item[1], my_gorgeous_dic.items()))[0][0] diff --git a/monitors_manager.py b/monitors_manager.py index 2f6be9b..3933daf 100644 --- a/monitors_manager.py +++ b/monitors_manager.py @@ -4,15 +4,15 @@ from collections import OrderedDict from logging_settings import set_logger -from xrandr_manager import XRANDR_MANAGER +from xrandrmanager import XrandrManager -class MONITORS(XRANDR_MANAGER): +class Monitors(XrandrManager): def set_monitors_position_manually(self): monitors_data_from_xrandr = self.monitors_data - cables_ids_names = XRANDR_MANAGER.create_cable_id_cable_name_dict([*monitors_data_from_xrandr]) + cables_ids_names = XrandrManager.create_cable_id_cable_name_dict([*monitors_data_from_xrandr]) logger.info( f"\n\nВот список подключенных мониторов в формате 'monitor_id --- monitor_name':\n" @@ -35,7 +35,7 @@ def match_monitor_with_cable(): # TODO: вот это у меня во многих местах встречается, нужно в отдельную функцию вынести - xrandr = XRANDR_MANAGER() + xrandr = XrandrManager() cables_ids_names = xrandr.create_cable_id_cable_name_dict(xrandr.monitors_data.keys()) # TODO: вот это в отдельную функцию вынести, ибо используется в разных местах? @@ -64,7 +64,7 @@ def match_monitor_with_cable(): @staticmethod def delete_saved_config(saved_cables_positions): - saved_cable_position_with_id = XRANDR_MANAGER.create_layout_id_layout_name_dict(saved_cables_positions) + saved_cable_position_with_id = XrandrManager.create_layout_id_layout_name_dict(saved_cables_positions) logger.info('Next strings will show monitors_positions in format: {config: [cable_1, cable_2, etc]}\n') for id, monitors_names in saved_cable_position_with_id.items(): @@ -89,7 +89,7 @@ def connect_monitors_automatically(data_from_xrandr): if len(data_from_xrandr) > 1: monitors_sorted_by_size = list(OrderedDict(sorted(list(data_from_xrandr.items()), - key=lambda value: XRANDR_MANAGER.get_monitor_dimensions( + key=lambda value: XrandrManager.get_monitor_dimensions( value[1]['monitor_size']))).keys()) # TODO: нужно описать кейсы, когда в этой функции вообще есть смысл # например, если скрипт начал работу на заднем плане. Чтоб хоть как-то моники подрубились... Удобнее работать? diff --git a/xrandr_manager.py b/xrandrmanager.py similarity index 99% rename from xrandr_manager.py rename to xrandrmanager.py index bdd7f9f..0443299 100644 --- a/xrandr_manager.py +++ b/xrandrmanager.py @@ -2,7 +2,7 @@ import subprocess -class XRANDR_MANAGER: +class XrandrManager: def __init__(self): self.monitors_data = self.get_monitors_data()