view frontends/src/jp/cmd_profile.py @ 1596:b7ee113183fc

jp: better profile commands: - new "profile/default" command - info doesn't show password anymore by default, need to be explicitly requested - info and modify don't need to connect anymore - modify can now set default profile. As use_profile is set, at least a profile session need to be started when it would not be mandatory technicaly (if just setting the profile as default is needed). But this option should not be used often, and it's not a big side effect, so I don't feel the need to create a new dedicated command, or to do complicated checks to avoid the session start.
author Goffi <goffi@goffi.org>
date Sat, 14 Nov 2015 19:18:10 +0100
parents e4e960d285b0
children 91a605feed8c
line wrap: on
line source

#! /usr/bin/python
# -*- coding: utf-8 -*-

# jp: a SAT command line tool
# Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014, 2015 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/>.

"""This module permits to manage profiles. It can list, create, delete
and retrieve information about a profile."""

import logging as log
from sat.core.i18n import _
from sat_frontends.jp import base

__commands__ = ["Profile"]

PROFILE_HELP = _('The name of the profile')


class ProfileDefault(base.CommandBase):
    def __init__(self, host):
        super(ProfileDefault, self).__init__(host, 'default', use_profile=False, help=_('print default profile'))

    def add_parser_options(self):
        pass

    def run(self):
        print self.host.bridge.getProfileName('@DEFAULT@')


class ProfileDelete(base.CommandBase):
    def __init__(self, host):
        super(ProfileDelete, self).__init__(host, 'delete', use_profile=False, help=_('delete a profile'))

    def add_parser_options(self):
        self.parser.add_argument('profile', type=str, help=PROFILE_HELP)

    def run(self):
        super(ProfileDelete, self).run()
        if self.args.profile not in self.host.bridge.getProfilesList():
            log.error("Profile %s doesn't exist." % self.args.profile)
            self.host.quit(1)
        self.host.bridge.asyncDeleteProfile(self.args.profile, callback=lambda dummy: None)


class ProfileInfo(base.CommandBase):
    def __init__(self, host):
        super(ProfileInfo, self).__init__(host, 'info', need_connect=False, help=_('get information about a profile'))
        self.to_show = [(_(u"jid"), "Connection", "JabberID"),]
        self.largest = max([len(item[0]) for item in self.to_show])


    def add_parser_options(self):
        self.parser.add_argument('--show-password', action='store_true', help=_(u'show the XMPP password IN CLEAR TEXT'))

    def showNextValue(self, label=None, category=None, value=None):
        """Show next value from self.to_show and quit on last one"""
        if label is not None:
            print((u"{label:<"+unicode(self.largest+2)+"}{value}").format(label=label+": ", value=value))
        try:
            label, category, name = self.to_show.pop(0)
        except IndexError:
            self.host.quit()
        else:
            self.host.bridge.asyncGetParamA(name, category, profile_key=self.host.profile,
                                            callback=lambda value: self.showNextValue(label, category, value))

    def connected(self):
        self.need_loop = True
        super(ProfileInfo, self).connected()
        if self.args.show_password:
            self.to_show.append((_(u"XMPP password"), "Connection", "Password"))
        self.showNextValue()


class ProfileList(base.CommandBase):
    def __init__(self, host):
        super(ProfileList, self).__init__(host, 'list', use_profile=False, help=_('list profiles'))

    def add_parser_options(self):
        pass

    def run(self):
        super(ProfileList, self).run()
        for profile in self.host.bridge.getProfilesList():
            print profile


class ProfileCreate(base.CommandBase):
    def __init__(self, host):
        super(ProfileCreate, self).__init__(host, 'create', use_profile=False, help=_('Create a new profile'))

    def add_parser_options(self):
        self.parser.add_argument('profile', type=str, help=_('the name of the profile'))
        self.parser.add_argument('-p', '--password', type=str, default='', help=_('the password of the profile'))
        self.parser.add_argument('-j', '--jid', type=str, help=_('the jid of the profile'))
        self.parser.add_argument('-x', '--xmpp-password', type=str, help=_('the password of the XMPP account (use profile password if not specified)'),
                                 metavar='PASSWORD')

    def _profile_created(self):
        if self.args.jid:
            self.host.bridge.setParam("JabberID", self.args.jid, "Connection" ,profile_key=self.args.profile)
        xmpp_pwd = self.args.password or self.args.xmpp_password
        if xmpp_pwd:
            self.host.bridge.setParam("Password", xmpp_pwd, "Connection", profile_key=self.args.profile)
        self.host.quit()

    def run(self):
        """Create a new profile"""
        self.need_loop = True
        if self.args.profile in self.host.bridge.getProfilesList():
            log.error("Profile %s already exists." % self.args.profile)
            self.host.quit(1)
        self.host.bridge.asyncCreateProfile(self.args.profile, self.args.password, callback=self._profile_created, errback=None)


class ProfileModify(base.CommandBase):
    def __init__(self, host):
        super(ProfileModify, self).__init__(host, 'modify', need_connect=False, help=_('Modify an existing profile'))

    def add_parser_options(self):
        self.parser.add_argument('-w', '--password', type=str, default='', help=_('the password of the profile'))
        self.parser.add_argument('-j', '--jid', type=str, help=_('the jid of the profile'))
        self.parser.add_argument('-x', '--xmpp-password', type=str, help=_('the password of the XMPP account'),
                                 metavar='PASSWORD')
        self.parser.add_argument('-D', '--default', action='store_true', help=_(u'set as default profile'))

    def _profile_created(self):
        if self.args.jid:
            self.host.bridge.setParam("JabberID", self.args.jid, "Connection" ,profile_key=self.args.profile)
        xmpp_pwd = self.args.password or self.args.xmpp_password
        if xmpp_pwd:
            self.host.bridge.setParam("Password", xmpp_pwd, "Connection", profile_key=self.args.profile)
        self.host.quit()

    def connected(self):
        super(ProfileModify, self).connected()
        if self.args.password is not None:
            self.host.bridge.setParam("Password", self.args.password, "General", profile_key=self.host.profile)
        if self.args.jid is not None:
            self.host.bridge.setParam("JabberID", self.args.jid, "Connection", profile_key=self.host.profile)
        if self.args.xmpp_password is not None:
            self.host.bridge.setParam("Password", self.args.xmpp_password, "Connection", profile_key=self.host.profile)
        if self.args.default:
            self.host.bridge.profileSetDefault(self.host.profile)


class Profile(base.CommandBase):
    subcommands = (ProfileCreate, ProfileDefault, ProfileDelete, ProfileInfo, ProfileList, ProfileModify)

    def __init__(self, host):
        super(Profile, self).__init__(host, 'profile', use_profile=False, help=_('Profile commands'))