|
|
|
@ -1,32 +1,61 @@
|
|
|
|
|
#!/usr/local/bin/python3.8 |
|
|
|
|
import argparse |
|
|
|
|
import os |
|
|
|
|
from dataclasses import dataclass |
|
|
|
|
from datetime import datetime |
|
|
|
|
import yaml |
|
|
|
|
import argparse |
|
|
|
|
from typing import List |
|
|
|
|
from rich import print |
|
|
|
|
from rich.prompt import Prompt |
|
|
|
|
|
|
|
|
|
import yaml |
|
|
|
|
from loguru import logger |
|
|
|
|
from rich import box, print |
|
|
|
|
from rich.console import Console |
|
|
|
|
from rich.padding import Padding |
|
|
|
|
from rich.panel import Panel |
|
|
|
|
from rich.text import Text |
|
|
|
|
from rich.prompt import Prompt |
|
|
|
|
from rich.table import Table |
|
|
|
|
from rich.console import Console |
|
|
|
|
from rich import box |
|
|
|
|
from rich.text import Text |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True) |
|
|
|
|
class Action: |
|
|
|
|
message: str |
|
|
|
|
cmd: str |
|
|
|
|
|
|
|
|
|
@property |
|
|
|
|
def pretty_message(self) -> str: |
|
|
|
|
_m = self.message |
|
|
|
|
_m = _m.replace("{warn}", "[bold yellow]\[!][/bold yellow]") |
|
|
|
|
_m = _m.replace("{process}", "[bold orange3]\[..][/bold orange3]") |
|
|
|
|
|
|
|
|
|
return _m |
|
|
|
|
|
|
|
|
|
@property |
|
|
|
|
def pretty_cmd(self) -> str: |
|
|
|
|
_date: str = datetime.today().strftime("%Y-%m-%d") |
|
|
|
|
_time: str = datetime.now().strftime("%H%M") |
|
|
|
|
return self.cmd.replace("{date}", _date).replace("{time}", _time) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass |
|
|
|
|
@dataclass() |
|
|
|
|
class Job: |
|
|
|
|
name: str |
|
|
|
|
dst_dir: str |
|
|
|
|
action: str |
|
|
|
|
actions: List[Action] |
|
|
|
|
active: bool = False |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Добавить обозначения {warn} {good} {error} {nice}, менять их на |
|
|
|
|
# символы и красить вывод консоли |
|
|
|
|
def run_job(job: Job, console: Console) -> None: |
|
|
|
|
"""Запусить задачу бэкапа.""" |
|
|
|
|
"""Запусить задачу бэкапа. |
|
|
|
|
|
|
|
|
|
Проходит по всем вложенным `actions` и, выводя сообщение |
|
|
|
|
`pretty_message`, выполняет задачу из `pretyy_cmd`. |
|
|
|
|
|
|
|
|
|
Notes |
|
|
|
|
----- |
|
|
|
|
Для удобства использования даты и времени, все это пишется с |
|
|
|
|
помощью плейсхолдеров в скрипте, и преобразуется при вызове |
|
|
|
|
`pretty_cmd`. |
|
|
|
|
""" |
|
|
|
|
|
|
|
|
|
date = datetime.today().strftime("%Y-%m-%d") |
|
|
|
|
time = datetime.now().strftime("%H%M") |
|
|
|
@ -35,18 +64,12 @@ def run_job(job: Job, console: Console) -> None:
|
|
|
|
|
|
|
|
|
|
if not os.path.isdir(path): |
|
|
|
|
os.makedirs(path) |
|
|
|
|
# BOLDYELLOW="\e[1;33m[!]\e[0m" |
|
|
|
|
# ENDCOLOR="\e[0m" |
|
|
|
|
cmd = ( |
|
|
|
|
job.action.replace("{name}", job.name) |
|
|
|
|
.replace("{date}", date) |
|
|
|
|
.replace("{time}", time) |
|
|
|
|
.replace("{warn}", "\033[33m[!]\033[0m") |
|
|
|
|
) |
|
|
|
|
with console.status( |
|
|
|
|
f"[bold yellow]\[..][/bold yellow] [bold]{job.name}[/bold] начинаю ..." |
|
|
|
|
): |
|
|
|
|
os.system(cmd) |
|
|
|
|
|
|
|
|
|
print(f"[bold yellow]\[..][/bold yellow] [bold]{job.name}[/bold] начинаю ...") |
|
|
|
|
|
|
|
|
|
for action in job.actions: |
|
|
|
|
with console.status(action.pretty_message): |
|
|
|
|
os.system(action.pretty_cmd) |
|
|
|
|
|
|
|
|
|
print(f"[bold green]\[OK][/bold green] [bold]{job.name}[/bold] выполнено") |
|
|
|
|
|
|
|
|
@ -95,22 +118,35 @@ def ask_about_backups(jobs: List[Job], force_all: bool) -> List[Job]:
|
|
|
|
|
return jobs |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def create_actions_from_list(actions: list) -> List[Action]: |
|
|
|
|
a: List[Action] = [] |
|
|
|
|
|
|
|
|
|
for com in actions: |
|
|
|
|
a.append(Action(com["com"]["message"], com["com"]["cmd"])) |
|
|
|
|
|
|
|
|
|
return a |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def yaml_loader(file: str) -> List[Job]: |
|
|
|
|
"""Парсинг yaml файла с задачами бэкапа. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
See Also |
|
|
|
|
-------- |
|
|
|
|
yamlchecker.com - сервис проверки yaml |
|
|
|
|
""" |
|
|
|
|
jobs: list = [] |
|
|
|
|
with open(file, "r") as conf: |
|
|
|
|
for task in yaml.safe_load_all(conf): |
|
|
|
|
try: |
|
|
|
|
if task: |
|
|
|
|
jobs.append( |
|
|
|
|
Job( |
|
|
|
|
name=task["name"], |
|
|
|
|
dst_dir=task["dst_dir"], |
|
|
|
|
action=task["action"], |
|
|
|
|
actions=create_actions_from_list(task["actions"]), |
|
|
|
|
) |
|
|
|
|
) |
|
|
|
|
except AttributeError: |
|
|
|
|
print( |
|
|
|
|
"Ваш список задач говно, попробуйте не ставить --- после последнего элемента" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
return jobs |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -130,6 +166,7 @@ def main() -> None:
|
|
|
|
|
console = Console() |
|
|
|
|
jobs = yaml_loader(os.path.abspath(args.file)) |
|
|
|
|
|
|
|
|
|
# logger.debug(jobs) |
|
|
|
|
jobs = ask_about_backups(jobs, args.forceall) |
|
|
|
|
|
|
|
|
|
for j in jobs: |
|
|
|
|