Exemple #1
0
    def grep(self, text, limit=None):
        results = app.logger.search_log(self.account, self.contact.jid, text)

        if not results:
            raise CommandError(_("%s: Nothing found") % text)

        if limit:
            try:
                results = results[len(results) - int(limit):]
            except ValueError:
                raise CommandError(_("Limit must be an integer"))

        for row in results:
            contact = row.contact_name
            if not contact:
                if row.kind == KindConstant.CHAT_MSG_SENT:
                    contact = app.nicks[self.account]
                else:
                    contact = self.contact.name

            time_obj = localtime(row.time)
            date_obj = date.fromtimestamp(row.time)
            date_ = strftime('%Y-%m-%d', time_obj)
            time_ = strftime('%H:%M:%S', time_obj)

            if date_obj == date.today():
                formatted = "[%s] %s: %s" % (time_, contact, row.message)
            else:
                formatted = "[%s, %s] %s: %s" % (date_, time_, contact,
                                                 row.message)

            self.echo(formatted)
Exemple #2
0
 def affiliate(self, who, affiliation):
     if affiliation not in ('owner', 'admin', 'member', 'outcast', 'none'):
         raise CommandError(_("Invalid affiliation given"))
     if not who in app.contacts.get_nick_list(self.account, self.room_jid):
         raise CommandError(_("Nickname not found"))
     contact = app.contacts.get_gc_contact(self.account, self.room_jid, who)
     self.connection.gc_set_affiliation(self.room_jid, contact.jid,
                                        affiliation)
Exemple #3
0
 def ping(self, nick):
     if self.account == app.ZEROCONF_ACC_NAME:
         raise CommandError(
             _('Command is not supported for zeroconf accounts'))
     gc_c = app.contacts.get_gc_contact(self.account, self.room_jid, nick)
     if gc_c is None:
         raise CommandError(_("Unknown nickname"))
     app.connections[self.account].get_module('Ping').send_ping(gc_c)
Exemple #4
0
 def dtmf(self, sequence):
     if not self.audio_sid:
         raise CommandError(_("No open audio sessions with the contact"))
     for tone in sequence:
         if not (tone in ("*", "#") or tone.isdigit()):
             raise CommandError(_("%s is not a valid tone") % tone)
     gjs = self.connection.get_jingle_session
     session = gjs(self.full_jid, self.audio_sid)
     content = session.get_content("audio")
     content.batch_dtmf(sequence)
Exemple #5
0
 def video(self):
     if not self.video_available:
         raise CommandError(_("Video sessions are not available"))
     # A video session is toggled by inverting the state of the
     # appropriate button.
     state = self._video_button.get_active()
     self._video_button.set_active(not state)
Exemple #6
0
 def audio(self):
     if not self.audio_available:
         raise CommandError(_("Voice chats are not available"))
     # An audio session is toggled by inverting the state of the
     # appropriate button.
     state = self._audio_button.get_active()
     self._audio_button.set_active(not state)
Exemple #7
0
 def nick(self, new_nick):
     try:
         new_nick = helpers.parse_resource(new_nick)
     except Exception:
         raise CommandError(_("Invalid nickname"))
     # FIXME: Check state of MUC
     self.connection.get_module('MUC').change_nick(self.room_jid, new_nick)
     self.new_nick = new_nick
Exemple #8
0
 def status(self, status, message):
     if status not in ('online', 'away', 'chat', 'xa', 'dnd'):
         raise CommandError("Invalid status given")
     for connection in app.connections.values():
         if not app.settings.get_account_setting(connection.name,
                                                 'sync_with_global_status'):
             continue
         if not connection.state.is_available:
             continue
         connection.change_status(status, message)
Exemple #9
0
 def status(self, status, message):
     if status not in ('online', 'away', 'chat', 'xa', 'dnd'):
         raise CommandError("Invalid status given")
     for connection in app.connections.values():
         if not app.config.get_per('accounts', connection.name,
                                   'sync_with_global_status'):
             continue
         if connection.connected < 2:
             continue
         connection.change_status(status, message)
Exemple #10
0
 def nick(self, new_nick):
     try:
         new_nick = helpers.parse_resource(new_nick)
     except Exception:
         raise CommandError(_("Invalid nickname"))
     self.connection.join_gc(new_nick,
                             self.room_jid,
                             None,
                             change_nick=True)
     self.new_nick = new_nick
Exemple #11
0
    def __call__(self, *args, **kwargs):
        try:
            return self.handler(*args, **kwargs)

        # This allows to use a shortcut way of raising an exception
        # inside a handler. That is to raise a CommandError without
        # command or name attributes set. They will be set to a
        # corresponding values right here in case if they was not set by
        # the one who raised an exception.
        except CommandError as error:
            if not error.command and not error.name:
                raise CommandError(error.message, self)
            raise

        # This one is a little bit too wide, but as Python does not have
        # anything more constrained - there is no other choice. Take a
        # look here if command complains about invalid arguments while
        # they are ok.
        except TypeError:
            raise CommandError("Command received invalid arguments", self)
Exemple #12
0
 def role(self, who, role):
     if role not in ('moderator', 'participant', 'visitor', 'none'):
         raise CommandError(_("Invalid role given"))
     if not who in app.contacts.get_nick_list(self.account, self.room_jid):
         raise CommandError(_("Nickname not found"))
     self.connection.get_module('MUC').set_role(self.room_jid, who, role)
Exemple #13
0
 def kick(self, who, reason):
     if not who in app.contacts.get_nick_list(self.account, self.room_jid):
         raise CommandError(_("Nickname not found"))
     self.connection.get_module('MUC').set_role(self.room_jid, who, 'none',
                                                reason or str())
Exemple #14
0
 def message(self, nick, a_message):
     nicks = app.contacts.get_nick_list(self.account, self.room_jid)
     if nick in nicks:
         self.on_send_pm(nick=nick, msg=a_message)
     else:
         raise CommandError(_("Nickname not found"))
Exemple #15
0
 def chat(self, nick):
     nicks = app.contacts.get_nick_list(self.account, self.room_jid)
     if nick in nicks:
         self.send_pm(nick)
     else:
         raise CommandError(_("Nickname not found"))
Exemple #16
0
 def ping(self, nick):
     if self.account == app.ZEROCONF_ACC_NAME:
         raise CommandError(
             _('Command is not supported for zeroconf accounts'))
     gc_c = app.contacts.get_gc_contact(self.account, self.room_jid, nick)
     app.connections[self.account].sendPing(gc_c, self)
Exemple #17
0
 def ping(self):
     if self.account == app.ZEROCONF_ACC_NAME:
         raise CommandError(
             _('Command is not supported for zeroconf accounts'))
     app.connections[self.account].get_module('Ping').send_ping(
         self.contact)
Exemple #18
0
def adapt_arguments(command, arguments, args, opts):
    """
    Adapt args and opts got from the parser to a specific handler by
    means of arguments specified on command definition. That is
    transform them to *args and **kwargs suitable for passing to a
    command handler.

    Dashes (-) in the option names will be converted to underscores. So
    you can map --one-more-option to a one_more_option=None.

    If the initial value of a keyword argument is a boolean (False in
    most cases) - then this option will be treated as a switch, that is
    an option which does not take an argument. If a switch is followed
    by an argument - then this argument will be treated just like a
    normal positional argument.
    """
    spec_args, spec_kwargs, var_args, _var_kwargs = command.extract_specification(
    )
    norm_kwargs = dict(spec_kwargs)

    # Quite complex piece of neck-breaking logic to extract raw
    # arguments if there is more, then one positional argument specified
    # by the command.  In case if it's just one argument which is the
    # collector - this is fairly easy. But when it's more then one
    # argument - the neck-breaking logic of how to retrieve residual
    # arguments as a raw, all in one piece string, kicks in.
    if command.raw:
        if arguments:
            spec_fix = 1 if command.source else 0
            spec_len = len(spec_args) - spec_fix
            arguments_end = len(arguments) - 1

            # If there are any optional arguments given they should be
            # either an unquoted positional argument or part of the raw
            # argument. So we find all optional arguments that can
            # possibly be unquoted argument and append them as is to the
            # args.
            for key, value, (start, end) in opts[:spec_len]:
                if value:
                    end -= len(value) + 1
                    args.append((arguments[start:end], (start, end)))
                    args.append((value, (end, end + len(value) + 1)))
                else:
                    args.append((arguments[start:end], (start, end)))

            # We need in-place sort here because after manipulations
            # with options order of arguments might be wrong and we just
            # can't have more complex logic to not let that happen.
            args.sort(key=itemgetter(1))

            if spec_len > 1:
                try:
                    _stopper, (start, end) = args[spec_len - 2]
                except IndexError:
                    raise CommandError(_("Missing arguments"), command)

                # The essential point of the whole play. After
                # boundaries are being determined (supposedly correct)
                # we separate raw part from the rest of arguments, which
                # should be normally processed.
                raw = arguments[end:]
                raw = raw.strip() or None

                if not raw and not command.empty:
                    raise CommandError(_("Missing arguments"), command)

                # Discard residual arguments and all of the options as
                # raw command does not support options and if an option
                # is given it is rather a part of a raw argument.
                args = args[:spec_len - 1]
                opts = []

                args.append((raw, (end, arguments_end)))
            else:
                # Substitute all of the arguments with only one, which
                # contain raw and unprocessed arguments as a string. And
                # discard all the options, as raw command does not
                # support them.
                args = [(arguments, (0, arguments_end))]
                opts = []
        else:
            if command.empty:
                args.append((None, (0, 0)))
            else:
                raise CommandError(_("Missing arguments"), command)

    # The first stage of transforming options we have got to a format
    # that can be used to associate them with declared keyword
    # arguments.  Substituting dashes (-) in their names with
    # underscores (_).
    for index, (key, value, position) in enumerate(opts):
        if '-' in key:
            opts[index] = (key.replace('-', '_'), value, position)

    # The second stage of transforming options to an associable state.
    # Expanding short, one-letter options to a verbose ones, if
    # corresponding opt-in has been given.
    if command.expand:
        expanded = []
        for spec_key in norm_kwargs.keys():
            letter = spec_key[0] if len(spec_key) > 1 else None
            if letter and letter not in expanded:
                for index, (key, value, position) in enumerate(opts):
                    if key == letter:
                        expanded.append(letter)
                        opts[index] = (spec_key, value, position)
                        break

    # Detect switches and set their values accordingly. If any of them
    # carries a value - append it to args.
    for index, (key, value, position) in enumerate(opts):
        if isinstance(norm_kwargs.get(key), bool):
            opts[index] = (key, True, position)
            if value:
                args.append((value, position))

    # Sorting arguments and options (just to be sure) in regarding to
    # their positions in the string.
    args.sort(key=itemgetter(1))
    opts.sort(key=itemgetter(2))

    # Stripping down position information supplied with arguments and
    # options as it won't be needed again.
    args = list(map(lambda t: t[0], args))
    opts = list(map(lambda t: (t[0], t[1]), opts))

    # If command has extra option enabled - collect all extra arguments
    # and pass them to a last positional argument command defines as a
    # list.
    if command.extra:
        if not var_args:
            spec_fix = 1 if not command.source else 2
            spec_len = len(spec_args) - spec_fix
            extra = args[spec_len:]
            args = args[:spec_len]
            args.append(extra)
        else:
            raise DefinitionError("Can not have both, extra and *args")

    # Detect if positional arguments overlap keyword arguments. If so
    # and this is allowed by command options - then map them directly to
    # their options, so they can get proper further processing.
    spec_fix = 1 if command.source else 0
    spec_len = len(spec_args) - spec_fix
    if len(args) > spec_len:
        if command.overlap:
            overlapped = args[spec_len:]
            args = args[:spec_len]
            for arg, spec_key, _spec_value in zip(overlapped, spec_kwargs):
                opts.append((spec_key, arg))
        else:
            raise CommandError(_("Too many arguments"), command)

    # Detect every switch and ensure it will not receive any arguments.
    # Normally this does not happen unless overlapping is enabled.
    for key, value in opts:
        initial = norm_kwargs.get(key)
        if isinstance(initial, bool):
            if not isinstance(value, bool):
                raise CommandError("%s: Switch can not take an argument" % key,
                                   command)

    # Inject the source arguments as a string as a first argument, if
    # command has enabled the corresponding option.
    if command.source:
        args.insert(0, arguments)

    # Return *args and **kwargs in the form suitable for passing to a
    # command handler and being expanded.
    return tuple(args), dict(opts)