diff --git a/CHANGELOG.org b/CHANGELOG.org index 7f77b1c..8bf46c0 100644 --- a/CHANGELOG.org +++ b/CHANGELOG.org @@ -12,3 +12,5 @@ Added fzf function for using all_labels_except. ** 0.4.1 <2023-03-02 Thu> Added *source update args* function. +** 0.5.0 <2023-03-03 Fri> + Added *groups add* function. diff --git a/pyproject.toml b/pyproject.toml index e32f854..5302fc1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "tui-rsync" -version = "0.4.1" +version = "0.5.0" description = "" authors = ["Kostiantyn Klochko "] readme = "README.rst" diff --git a/tui_rsync/cli/cli.py b/tui_rsync/cli/cli.py index c972f60..d55c06f 100644 --- a/tui_rsync/cli/cli.py +++ b/tui_rsync/cli/cli.py @@ -21,9 +21,11 @@ from rich.console import Console import typer from cli.source import source from cli.sync import sync +from cli.groups import groups console = Console() cli_app = typer.Typer(rich_markup_mode="rich") cli_app.add_typer(source, name="source", help="Manage sources") +cli_app.add_typer(groups, name="groups", help="Manage groups") cli_app.add_typer(sync, name="sync", help="Sync sources") diff --git a/tui_rsync/cli/groups.py b/tui_rsync/cli/groups.py new file mode 100644 index 0000000..9d8289f --- /dev/null +++ b/tui_rsync/cli/groups.py @@ -0,0 +1,60 @@ +################################################################################ +# Copyright (C) 2023 Kostiantyn Klochko # +# # +# This file is part of tui-rsync. # +# # +# tui-rsync is free software: you can redistribute it and/or modify it under # +# uthe terms of the GNU General Public License as published by the Free # +# Software Foundation, either version 3 of the License, or (at your option) # +# any later version. # +# # +# tui-rsync is distributed in the hope that it will be useful, but WITHOUT ANY # +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # +# details. # +# # +# You should have received a copy of the GNU General Public License along with # +# tui-rsync. If not, see . # +################################################################################ + +from rich.console import Console +from rich.prompt import Confirm, Prompt +from typing import List, Optional +import typer + +from cli.label_prompt import LabelPrompt +from cli.rsync import Rsync +from models.models import Group, count_all_labels_except + +console = Console() +groups = typer.Typer() + +@groups.command() +def add( + group_label: str = typer.Option( + None, "--group-label", "-g", + help="[b]The label[/] is a uniq identification of a [b]group[/].", + show_default=False + ), +): + """ + [green b]Create[/] a [yellow]new group[/] with a [bold]uniq[/] label. + [b]The chosen sources[/] will be united into [b]the group[/]. + """ + if group_label is None: + question = "Would you like to change [yellow b]the group label[/]?" + group_label = LabelPrompt.ask_uuid(question) + + labels = [] + while True: + is_empty = count_all_labels_except(labels) == 0 + if is_empty: + break + is_fzf = Confirm.ask("Would you like to add a source to the group? ", + default=True) + if not is_fzf: + break + option = LabelPrompt.get_label_except_fzf(labels) + labels.append(option) + Group.create_save(group_label, labels) + diff --git a/tui_rsync/models/models.py b/tui_rsync/models/models.py index c708799..c8e996f 100644 --- a/tui_rsync/models/models.py +++ b/tui_rsync/models/models.py @@ -93,9 +93,43 @@ class Destination(BaseModel): def __str__(self) -> str: return f"{self.path}" +class Group(BaseModel): + label = CharField(unique=True) + + @staticmethod + def create_save(label:str, source_labels:list[str]): + group = Group.create( + label=label, + sources=[], + ) + for source_label in source_labels: + # continue: + src = Source.get(label=source_label) + group_src, _ = GroupSource.get_or_create(group=group, source=src) + group.save() + return group + + def __str__(self) -> str: + return f"{self.label}" + + def __repl__(self) -> str: + return f"{self.label}" + +class GroupSource(BaseModel): + group = ForeignKeyField(Group, backref='sources') + source = ForeignKeyField(Source) + def create_tables(): with db: - db.create_tables([Source, Path, Destination, SyncCommand], safe=True) + tables = [ + Source, + Path, + Destination, + SyncCommand, + Group, + GroupSource + ] + db.create_tables(tables, safe=True) def all_labels(): with db: @@ -104,3 +138,6 @@ def all_labels(): def all_labels_except(labels): with db: return Source.select(Source.label).where(Source.label.not_in(labels)) + +def count_all_labels_except(labels): + return len(all_labels_except(labels))