view libervia/cli/cmd_bookmarks.py @ 4351:6a0a081485b8

plugin autocrypt: Autocrypt protocol implementation: Implementation of autocrypt: `autocrypt` header is checked, and if present and no public key is known for the peer, the key is imported. `autocrypt` header is also added to outgoing message (only if an email gateway is detected). For the moment, the JID is use as identifier, but the real email used by gateway should be used in the future. rel 456
author Goffi <goffi@goffi.org>
date Fri, 28 Feb 2025 09:23:35 +0100
parents 554a87ae17a6
children
line wrap: on
line source

#!/usr/bin/env python3


# Libervia CLI
# Copyright (C) 2009-2021 JΓ©rΓ΄me Poisson (goffi@goffi.org)

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program 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 Affero General Public License for more details.

# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from rich.table import Table

from libervia.backend.core.i18n import _
from libervia.backend.tools.common import data_format
from libervia.cli.constants import Const as C

from . import base
from .bookmarks_legacy import BookmarksLegacy

__commands__ = ["Bookmarks"]


class BookmarksList(base.CommandBase):
    def __init__(self, host):
        extra_outputs = {"default": self.default_output}
        super().__init__(
            host, "list", help=_("list bookmarks"),
            use_output=C.OUTPUT_COMPLEX,
            extra_outputs=extra_outputs
        )

    def add_parser_options(self):
        pass

    def default_output(self, data: dict) -> None:
        table = Table(title="πŸ“š " + _("Group Chat Bookmarks"))
        table.add_column("🌐 JID")
        table.add_column("πŸ“ " + _("Name"))
        table.add_column("πŸ‘€ " + _("Nick"))
        table.add_column("πŸ”’ " + _("Password"))
        table.add_column("πŸšͺ " + _("Joined"))

        for jid, conference_data in data.items():
            table.add_row(
                str(jid),
                conference_data.get("name", ""),
                conference_data.get("nick", ""),
                conference_data.get("password", ""),
                "βœ…" if conference_data.get("autojoin", False) else "❌"
            )

        self.console.print(table)

    async def start(self):
        try:
            data = data_format.deserialise(await self.host.bridge.bookmarks_list(
                "", self.host.profile
            ))
        except Exception as e:
            self.disp(f"can't get bookmarks list: {e}", error=True)
            self.host.quit(C.EXIT_BRIDGE_ERRBACK)
            return

        await self.output(data)
        self.host.quit()


class BookmarksRemove(base.CommandBase):
    def __init__(self, host):
        super().__init__(host, "remove", help=_("remove a bookmark"))

    def add_parser_options(self):
        self.parser.add_argument(
            "bookmark", help=_("jid of the bookmark to remove")
        )
        self.parser.add_argument(
            "-f",
            "--force",
            action="store_true",
            help=_("delete bookmark without confirmation"),
        )

    async def start(self):
        if not self.args.force:
            await self.host.confirm_or_quit(
                _("Are you sure to delete the bookmark {bookmark_id!r}?")
                .format(bookmark_id=self.args.bookmark)
            )

        try:
            await self.host.bridge.bookmark_remove(
                self.args.bookmark, self.host.profile
            )
        except Exception as e:
            self.disp(_("can't delete bookmark: {e}").format(e=e), error=True)
            self.host.quit(C.EXIT_BRIDGE_ERRBACK)
        else:
            self.disp(_("bookmark deleted"))
            self.host.quit()


class BookmarksSet(base.CommandBase):
    def __init__(self, host):
        super().__init__(
            host, "set", help=_("add or update a bookmark")
        )

    def add_parser_options(self):
        self.parser.add_argument("bookmark", help=_("jid of the chat room"))
        self.parser.add_argument("-n", "--name", help=_("bookmark name"), dest="name")
        self.parser.add_argument(
            "-j",
            "--join",
            nargs="?",
            # Value use when option is missing.
            default=None,
            # Value use when option is used, but value is not specified.
            const=True,
            type=base.optional_bool_decoder,
            # The bookmark attribute is called "autojoin" for historical reason, but it's
            # now used a "join" flag, so we use ``join`` here for the option.
            dest="autojoin",
            metavar="BOOL",
            help=_("join the conference room"),
        )
        self.parser.add_argument(
            "-N",
            "--nick", help=_("preferred roomnick for the chatroom")
        )
        self.parser.add_argument(
            "-P",
            "--password", help=_("password used to access the chatroom")
        )
        self.parser.add_argument(
            "-u",
            "--update",
            action="store_true",
            help=_("update bookmark data instead of replacing")
        )

    async def start(self):
        conference_data = {
            "autojoin": self.args.autojoin,
            "name": self.args.name,
            "nick": self.args.nick,
            "password": self.args.password,
        }

        conference_data = {k: v for k, v in conference_data.items() if v is not None}
        if self.args.update:
            try:
                old_conference_data = data_format.deserialise(
                    await self.host.bridge.bookmark_get(
                        self.args.bookmark, self.host.profile
                    )
                )
            except Exception as e:
                self.disp(
                    f"Can't find existing bookmark {self.args.bookmark!r}: {e}. We "
                    "create it.",
                    error=True
                )
            else:
                old_conference_data.update(conference_data)
                conference_data = old_conference_data

        try:
            await self.host.bridge.bookmarks_set(
                data_format.serialise({self.args.bookmark: conference_data}),
                self.host.profile,
            )
        except Exception as e:
            self.disp(f"can't add bookmark: {e}", error=True)
            self.host.quit(C.EXIT_BRIDGE_ERRBACK)
        else:
            self.disp(_("bookmark successfully set"))
            self.host.quit()


class Bookmarks(base.CommandBase):
    subcommands = (BookmarksList, BookmarksSet, BookmarksRemove, BookmarksLegacy)

    def __init__(self, host):
        super().__init__(
            host, "bookmarks", use_profile=False, help=_("manage bookmarks")
        )