merge with default

This commit is contained in:
Yann Leboulanger 2010-03-19 08:23:24 +01:00
commit 9dedf990bd
14 changed files with 107 additions and 79 deletions

View File

@ -1,4 +1,4 @@
# Copyright (C) 2009 Alexander Cherniuk <ts33kr@gmail.com> # Copyright (C) 2009-2010 Alexander Cherniuk <ts33kr@gmail.com>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by

View File

@ -1,4 +1,4 @@
# Copyright (C) 2009 Alexander Cherniuk <ts33kr@gmail.com> # Copyright (C) 2009-2010 Alexander Cherniuk <ts33kr@gmail.com>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by

View File

@ -1,4 +1,4 @@
# Copyright (C) 2009 Alexander Cherniuk <ts33kr@gmail.com> # Copyright (C) 2009-2010 Alexander Cherniuk <ts33kr@gmail.com>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -45,3 +45,9 @@ class CommandError(BaseError):
Used to indicate errors occured during command execution. Used to indicate errors occured during command execution.
""" """
pass pass
class NoCommandError(BaseError):
"""
Used to indicate an inability to find the specified command.
"""
pass

View File

@ -1,4 +1,4 @@
# Copyright (C) 2009 Alexander Cherniuk <ts33kr@gmail.com> # Copyright (C) 2009-2010 Alexander Cherniuk <ts33kr@gmail.com>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -25,7 +25,7 @@ from inspect import getargspec
from dispatching import Dispatcher, HostDispatcher, ContainerDispatcher from dispatching import Dispatcher, HostDispatcher, ContainerDispatcher
from mapping import parse_arguments, adapt_arguments from mapping import parse_arguments, adapt_arguments
from errors import DefinitionError, CommandError from errors import DefinitionError, CommandError, NoCommandError
class CommandHost(object): class CommandHost(object):
""" """
@ -128,7 +128,7 @@ class CommandProcessor(object):
def get_command(self, name): def get_command(self, name):
command = Dispatcher.get_command(self.COMMAND_HOST, name) command = Dispatcher.get_command(self.COMMAND_HOST, name)
if not command: if not command:
raise CommandError("Command does not exist", name=name) raise NoCommandError("Command does not exist", name=name)
return command return command
def list_commands(self): def list_commands(self):
@ -330,7 +330,7 @@ def command(*names, **properties):
return decorator return decorator
def documentation(text): def doc(text):
""" """
This decorator is used to bind a documentation (a help) to a This decorator is used to bind a documentation (a help) to a
command. command.

View File

@ -1,4 +1,4 @@
# Copyright (C) 2009 Alexander Cherniuk <ts33kr@gmail.com> # Copyright (C) 2009-2010 Alexander Cherniuk <ts33kr@gmail.com>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by

View File

@ -1,4 +1,4 @@
# Copyright (C) 2009 Alexander Cherniuk <ts33kr@gmail.com> # Copyright (C) 2009-2010 Alexander Cherniuk <ts33kr@gmail.com>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -21,7 +21,7 @@ Keep in mind that this module is not being loaded, so the code will not
be executed and commands defined here will not be detected. be executed and commands defined here will not be detected.
""" """
from ..framework import CommandContainer, command, documentation from ..framework import CommandContainer, command, doc
from hosts import ChatCommands, PrivateChatCommands, GroupChatCommands from hosts import ChatCommands, PrivateChatCommands, GroupChatCommands
class CustomCommonCommands(CommandContainer): class CustomCommonCommands(CommandContainer):
@ -58,7 +58,7 @@ class CustomChatCommands(CommandContainer):
HOSTS = (ChatCommands,) HOSTS = (ChatCommands,)
@documentation(_("The same as using a doc-string, except it supports translation")) @doc(_("The same as using a doc-string, except it supports translation"))
@command @command
def sing(self): def sing(self):
return "Are you phreaking kidding me? Buy yourself a damn stereo..." return "Are you phreaking kidding me? Buy yourself a damn stereo..."

View File

@ -1,4 +1,4 @@
# Copyright (C) 2009 Alexander Cherniuk <ts33kr@gmail.com> # Copyright (C) 2009-2010 Alexander Cherniuk <ts33kr@gmail.com>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by

View File

@ -1,4 +1,4 @@
# Copyright (C) 2009 Alexander Cherniuk <ts33kr@gmail.com> # Copyright (C) 2009-2010 Alexander Cherniuk <ts33kr@gmail.com>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -26,7 +26,7 @@ from traceback import print_exc
from common import gajim from common import gajim
from ..framework import CommandProcessor from ..framework import CommandProcessor
from ..errors import CommandError from ..errors import CommandError, NoCommandError
class ChatCommandProcessor(CommandProcessor): class ChatCommandProcessor(CommandProcessor):
""" """
@ -44,6 +44,12 @@ class ChatCommandProcessor(CommandProcessor):
def execute_command(self, name, arguments): def execute_command(self, name, arguments):
try: try:
super(ChatCommandProcessor, self).execute_command(name, arguments) super(ChatCommandProcessor, self).execute_command(name, arguments)
except NoCommandError, error:
details = dict(name=error.name, message=error.message)
message = "%(name)s: %(message)s\n" % details
message += "Try using the //%(name)s or /say /%(name)s " % details
message += "construct if you intended to send it as a text."
self.echo(message, 'error')
except CommandError, error: except CommandError, error:
self.echo("%s: %s" % (error.name, error.message), 'error') self.echo("%s: %s" % (error.name, error.message), 'error')
except Exception: except Exception:
@ -51,26 +57,27 @@ class ChatCommandProcessor(CommandProcessor):
print_exc() print_exc()
def looks_like_command(self, text, body, name, arguments): def looks_like_command(self, text, body, name, arguments):
# Command escape stuff ggoes here. If text was prepended by the command # Command escape stuff ggoes here. If text was prepended by the
# prefix twice, like //not_a_command (if prefix is set to /) then it # command prefix twice, like //not_a_command (if prefix is set
# will be escaped, that is sent just as a regular message with one (only # to /) then it will be escaped, that is sent just as a regular
# one) prefix removed, so message will be /not_a_command. # message with one (only one) prefix removed, so message will be
# /not_a_command.
if body.startswith(self.COMMAND_PREFIX): if body.startswith(self.COMMAND_PREFIX):
self.send(body) self.send(body)
return True return True
def command_preprocessor(self, command, name, arguments, args, kwargs): def command_preprocessor(self, command, name, arguments, args, kwargs):
# If command argument contain h or help option - forward it to the /help # If command argument contain h or help option - forward it to
# command. Dont forget to pass self, as all commands are unbound. And # the /help command. Dont forget to pass self, as all commands
# also don't forget to print output. # are unbound. And also don't forget to print output.
if 'h' in kwargs or 'help' in kwargs: if 'h' in kwargs or 'help' in kwargs:
help = self.get_command('help') help = self.get_command('help')
self.echo(help(self, name)) self.echo(help(self, name))
return True return True
def command_postprocessor(self, command, name, arguments, args, kwargs, value): def command_postprocessor(self, command, name, arguments, args, kwargs, value):
# If command returns a string - print it to a user. A convenient and # If command returns a string - print it to a user. A convenient
# sufficient in most simple cases shortcut to a using echo. # and sufficient in most simple cases shortcut to a using echo.
if value and isinstance(value, StringTypes): if value and isinstance(value, StringTypes):
self.echo(value) self.echo(value)

View File

@ -1,4 +1,4 @@
# Copyright (C) 2009 Alexander Cherniuk <ts33kr@gmail.com> # Copyright (C) 2009-2010 Alexander Cherniuk <ts33kr@gmail.com>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -27,7 +27,7 @@ from common.exceptions import GajimGeneralException
from common.logger import Constants from common.logger import Constants
from ..errors import CommandError from ..errors import CommandError
from ..framework import CommandContainer, command, documentation from ..framework import CommandContainer, command, doc
from ..mapping import generate_usage from ..mapping import generate_usage
from hosts import ChatCommands, PrivateChatCommands, GroupChatCommands from hosts import ChatCommands, PrivateChatCommands, GroupChatCommands
@ -45,18 +45,18 @@ class StandardCommonCommands(CommandContainer):
HOSTS = (ChatCommands, PrivateChatCommands, GroupChatCommands) HOSTS = (ChatCommands, PrivateChatCommands, GroupChatCommands)
@command @command
@documentation(_("Clear the text window")) @doc(_("Clear the text window"))
def clear(self): def clear(self):
self.conv_textview.clear() self.conv_textview.clear()
@command @command
@documentation(_("Hide the chat buttons")) @doc(_("Hide the chat buttons"))
def compact(self): def compact(self):
new_status = not self.hide_chat_buttons new_status = not self.hide_chat_buttons
self.chat_buttons_set_visible(new_status) self.chat_buttons_set_visible(new_status)
@command(overlap=True) @command(overlap=True)
@documentation(_("Show help on a given command or a list of available commands if -(-a)ll is given")) @doc(_("Show help on a given command or a list of available commands if -(-a)ll is given"))
def help(self, command=None, all=False): def help(self, command=None, all=False):
if command: if command:
command = self.get_command(command) command = self.get_command(command)
@ -83,17 +83,17 @@ class StandardCommonCommands(CommandContainer):
self.echo(help(self, 'help')) self.echo(help(self, 'help'))
@command(raw=True) @command(raw=True)
@documentation(_("Send a message to the contact")) @doc(_("Send a message to the contact"))
def say(self, message): def say(self, message):
self.send(message) self.send(message)
@command(raw=True) @command(raw=True)
@documentation(_("Send action (in the third person) to the current chat")) @doc(_("Send action (in the third person) to the current chat"))
def me(self, action): def me(self, action):
self.send("/me %s" % action) self.send("/me %s" % action)
@command('lastlog', overlap=True) @command('lastlog', overlap=True)
@documentation(_("Show logged messages which mention given text")) @doc(_("Show logged messages which mention given text"))
def grep(self, text, limit=None): def grep(self, text, limit=None):
results = gajim.logger.get_search_results_for_query(self.contact.jid, results = gajim.logger.get_search_results_for_query(self.contact.jid,
text, self.account) text, self.account)
@ -129,7 +129,7 @@ class StandardCommonCommands(CommandContainer):
self.echo(formatted) self.echo(formatted)
@command(raw=True, empty=True) @command(raw=True, empty=True)
@documentation(_(""" @doc(_("""
Set current the status Set current the status
Status can be given as one of the following values: online, away, Status can be given as one of the following values: online, away,
@ -142,7 +142,7 @@ class StandardCommonCommands(CommandContainer):
connection.change_status(status, message) connection.change_status(status, message)
@command(raw=True, empty=True) @command(raw=True, empty=True)
@documentation(_("Set the current status to away")) @doc(_("Set the current status to away"))
def away(self, message): def away(self, message):
if not message: if not message:
message = _("Away") message = _("Away")
@ -150,36 +150,40 @@ class StandardCommonCommands(CommandContainer):
connection.change_status('away', message) connection.change_status('away', message)
@command('back', raw=True, empty=True) @command('back', raw=True, empty=True)
@documentation(_("Set the current status to online")) @doc(_("Set the current status to online"))
def online(self, message): def online(self, message):
if not message: if not message:
message = _("Available") message = _("Available")
for connection in gajim.connections.itervalues(): for connection in gajim.connections.itervalues():
connection.change_status('online', message) connection.change_status('online', message)
class StandardChatCommands(CommandContainer): class StandardCommonChatCommands(CommandContainer):
""" """
This command container contains standard command which are unique to This command container contans standard commands, which are common
a chat. to a chat and a private chat only.
""" """
HOSTS = (ChatCommands,) HOSTS = (ChatCommands, PrivateChatCommands)
@command @command
@documentation(_("Send a ping to the contact")) @doc(_("Toggle the GPG encryption"))
def gpg(self):
self._toggle_gpg()
@command
@doc(_("Send a ping to the contact"))
def ping(self): def ping(self):
if self.account == gajim.ZEROCONF_ACC_NAME: if self.account == gajim.ZEROCONF_ACC_NAME:
raise CommandError(_('Command is not supported for zeroconf accounts')) raise CommandError(_('Command is not supported for zeroconf accounts'))
gajim.connections[self.account].sendPing(self.contact) gajim.connections[self.account].sendPing(self.contact)
@command @command
@documentation(_("Sends DTMF events through an open audio session")) @doc(_("Send DTMF events through an open audio session"))
def dtmf(self, events): def dtmf(self, events):
if not self.audio_sid: if not self.audio_sid:
raise CommandError(_("There is no open audio session with this contact")) raise CommandError(_("There is no open audio session with this contact"))
# Valid values for DTMF tones are *, # or a number # Valid values for DTMF tones are *, # or a number
events = [event for event in events events = filter(lambda e: e in ('*', '#') or e.isdigit (), events)
if event in ('*', '#') or event.isdigit()]
if events: if events:
session = gajim.connections[self.account].get_jingle_session( session = gajim.connections[self.account].get_jingle_session(
self.contact.get_full_jid(), self.audio_sid) self.contact.get_full_jid(), self.audio_sid)
@ -189,7 +193,7 @@ class StandardChatCommands(CommandContainer):
raise CommandError(_("No valid DTMF event specified")) raise CommandError(_("No valid DTMF event specified"))
@command @command
@documentation(_("Toggle audio session")) @doc(_("Toggle audio session"))
def audio(self): def audio(self):
if self.audio_state == self.JINGLE_STATE_NOT_AVAILABLE: if self.audio_state == self.JINGLE_STATE_NOT_AVAILABLE:
raise CommandError(_("Video sessions are not available")) raise CommandError(_("Video sessions are not available"))
@ -200,7 +204,7 @@ class StandardChatCommands(CommandContainer):
self._audio_button.set_active(not state) self._audio_button.set_active(not state)
@command @command
@documentation(_("Toggle video session")) @doc(_("Toggle video session"))
def video(self): def video(self):
if self.video_state == self.JINGLE_STATE_NOT_AVAILABLE: if self.video_state == self.JINGLE_STATE_NOT_AVAILABLE:
raise CommandError(_("Video sessions are not available")) raise CommandError(_("Video sessions are not available"))
@ -210,24 +214,32 @@ class StandardChatCommands(CommandContainer):
state = self._video_button.get_active() state = self._video_button.get_active()
self._video_button.set_active(not state) self._video_button.set_active(not state)
class StandardChatCommands(CommandContainer):
"""
This command container contains standard commands which are unique
to a chat.
"""
HOSTS = (ChatCommands,)
class StandardPrivateChatCommands(CommandContainer): class StandardPrivateChatCommands(CommandContainer):
""" """
This command container contains standard command which are unique to This command container contains standard commands which are unique
a private chat. to a private chat.
""" """
HOSTS = (PrivateChatCommands,) HOSTS = (PrivateChatCommands,)
class StandardGroupchatCommands(CommandContainer): class StandardGroupChatCommands(CommandContainer):
""" """
This command container contains standard command which are unique to This command container contains standard commands which are unique
a group chat. to a group chat.
""" """
HOSTS = (GroupChatCommands,) HOSTS = (GroupChatCommands,)
@command(raw=True) @command(raw=True)
@documentation(_("Change your nickname in a group chat")) @doc(_("Change your nickname in a group chat"))
def nick(self, new_nick): def nick(self, new_nick):
try: try:
new_nick = helpers.parse_resource(new_nick) new_nick = helpers.parse_resource(new_nick)
@ -237,7 +249,7 @@ class StandardGroupchatCommands(CommandContainer):
self.new_nick = new_nick self.new_nick = new_nick
@command('query', raw=True) @command('query', raw=True)
@documentation(_("Open a private chat window with a specified occupant")) @doc(_("Open a private chat window with a specified occupant"))
def chat(self, nick): def chat(self, nick):
nicks = gajim.contacts.get_nick_list(self.account, self.room_jid) nicks = gajim.contacts.get_nick_list(self.account, self.room_jid)
if nick in nicks: if nick in nicks:
@ -246,7 +258,7 @@ class StandardGroupchatCommands(CommandContainer):
raise CommandError(_("Nickname not found")) raise CommandError(_("Nickname not found"))
@command('msg', raw=True) @command('msg', raw=True)
@documentation(_("Open a private chat window with a specified occupant and send him a message")) @doc(_("Open a private chat window with a specified occupant and send him a message"))
def message(self, nick, a_message): def message(self, nick, a_message):
nicks = gajim.contacts.get_nick_list(self.account, self.room_jid) nicks = gajim.contacts.get_nick_list(self.account, self.room_jid)
if nick in nicks: if nick in nicks:
@ -255,7 +267,7 @@ class StandardGroupchatCommands(CommandContainer):
raise CommandError(_("Nickname not found")) raise CommandError(_("Nickname not found"))
@command(raw=True, empty=True) @command(raw=True, empty=True)
@documentation(_("Display or change a group chat topic")) @doc(_("Display or change a group chat topic"))
def topic(self, new_topic): def topic(self, new_topic):
if new_topic: if new_topic:
self.connection.send_gc_subject(self.room_jid, new_topic) self.connection.send_gc_subject(self.room_jid, new_topic)
@ -263,13 +275,13 @@ class StandardGroupchatCommands(CommandContainer):
return self.subject return self.subject
@command(raw=True, empty=True) @command(raw=True, empty=True)
@documentation(_("Invite a user to a room for a reason")) @doc(_("Invite a user to a room for a reason"))
def invite(self, jid, reason): def invite(self, jid, reason):
self.connection.send_invite(self.room_jid, jid, reason) self.connection.send_invite(self.room_jid, jid, reason)
return _("Invited %s to %s") % (jid, self.room_jid) return _("Invited %s to %s") % (jid, self.room_jid)
@command(raw=True, empty=True) @command(raw=True, empty=True)
@documentation(_("Join a group chat given by a jid, optionally using given nickname")) @doc(_("Join a group chat given by a jid, optionally using given nickname"))
def join(self, jid, nick): def join(self, jid, nick):
if not nick: if not nick:
nick = self.nick nick = self.nick
@ -286,12 +298,12 @@ class StandardGroupchatCommands(CommandContainer):
pass pass
@command('part', 'close', raw=True, empty=True) @command('part', 'close', raw=True, empty=True)
@documentation(_("Leave the groupchat, optionally giving a reason, and close tab or window")) @doc(_("Leave the groupchat, optionally giving a reason, and close tab or window"))
def leave(self, reason): def leave(self, reason):
self.parent_win.remove_tab(self, self.parent_win.CLOSE_COMMAND, reason) self.parent_win.remove_tab(self, self.parent_win.CLOSE_COMMAND, reason)
@command(raw=True, empty=True) @command(raw=True, empty=True)
@documentation(_(""" @doc(_("""
Ban user by a nick or a jid from a groupchat Ban user by a nick or a jid from a groupchat
If given nickname is not found it will be treated as a jid. If given nickname is not found it will be treated as a jid.
@ -303,14 +315,14 @@ class StandardGroupchatCommands(CommandContainer):
self.connection.gc_set_affiliation(self.room_jid, who, 'outcast', reason or str()) self.connection.gc_set_affiliation(self.room_jid, who, 'outcast', reason or str())
@command(raw=True, empty=True) @command(raw=True, empty=True)
@documentation(_("Kick user by a nick from a groupchat")) @doc(_("Kick user by a nick from a groupchat"))
def kick(self, who, reason): def kick(self, who, reason):
if not who in gajim.contacts.get_nick_list(self.account, self.room_jid): if not who in gajim.contacts.get_nick_list(self.account, self.room_jid):
raise CommandError(_("Nickname not found")) raise CommandError(_("Nickname not found"))
self.connection.gc_set_role(self.room_jid, who, 'none', reason or str()) self.connection.gc_set_role(self.room_jid, who, 'none', reason or str())
@command @command
@documentation(_("Display names of all group chat occupants")) @doc(_("Display names of all group chat occupants"))
def names(self, verbose=False): def names(self, verbose=False):
get_contact = lambda nick: gajim.contacts.get_gc_contact(self.account, self.room_jid, nick) get_contact = lambda nick: gajim.contacts.get_gc_contact(self.account, self.room_jid, nick)
nicks = gajim.contacts.get_nick_list(self.account, self.room_jid) nicks = gajim.contacts.get_nick_list(self.account, self.room_jid)
@ -331,11 +343,11 @@ class StandardGroupchatCommands(CommandContainer):
return ', '.join(nicks) return ', '.join(nicks)
@command('ignore', raw=True) @command('ignore', raw=True)
@documentation(_("Forbid an occupant to send you public or private messages")) @doc(_("Forbid an occupant to send you public or private messages"))
def block(self, who): def block(self, who):
self.on_block(None, who) self.on_block(None, who)
@command('unignore', raw=True) @command('unignore', raw=True)
@documentation(_("Allow an occupant to send you public or private messages")) @doc(_("Allow an occupant to send you public or private messages"))
def unblock(self, who): def unblock(self, who):
self.on_unblock(None, who) self.on_unblock(None, who)

View File

@ -1,4 +1,4 @@
# Copyright (C) 2009 Alexander Cherniuk <ts33kr@gmail.com> # Copyright (C) 2009-2010 Alexander Cherniuk <ts33kr@gmail.com>
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by

View File

@ -31,6 +31,7 @@ class DeviceManager(object):
element = gst.element_factory_make(name, '%spresencetest' % name) element = gst.element_factory_make(name, '%spresencetest' % name)
if isinstance(element, gst.interfaces.PropertyProbe): if isinstance(element, gst.interfaces.PropertyProbe):
element.set_state(gst.STATE_READY) element.set_state(gst.STATE_READY)
element.probe_property_name('device')
devices = element.probe_get_values_name('device') devices = element.probe_get_values_name('device')
if devices: if devices:
self.devices[text % _(' Default device')] = pipe % name self.devices[text % _(' Default device')] = pipe % name
@ -79,7 +80,7 @@ class VideoInputManager(DeviceManager):
'%s is-live=true') '%s is-live=true')
# Auto src # Auto src
self.detect_element('autovideosrc', _('Autodetect')) self.detect_element('autovideosrc', _('Autodetect'))
# V4L2 src ; TODO: Figure out why it doesn't work # V4L2 src
self.detect_element('v4l2src', _('V4L2: %s')) self.detect_element('v4l2src', _('V4L2: %s'))
# Funny things, just to test... # Funny things, just to test...
# self.devices['GOOM'] = 'audiotestsrc ! goom' # self.devices['GOOM'] = 'audiotestsrc ! goom'
@ -96,3 +97,4 @@ class VideoOutputManager(DeviceManager):
# ximagesink # ximagesink
self.detect_element('ximagesink', _('X Window System (without Xv)')) self.detect_element('ximagesink', _('X Window System (without Xv)'))
self.detect_element('autovideosink', _('Autodetect')) self.detect_element('autovideosink', _('Autodetect'))

View File

@ -422,11 +422,16 @@ class SASL(PlugIn):
self.on_sasl() self.on_sasl()
raise NodeProcessed raise NodeProcessed
@staticmethod
def _convert_to_iso88591(string):
try:
string = string.decode('utf-8').encode('iso-8859-1')
except UnicodeEncodeError:
pass
return string
def set_password(self, password): def set_password(self, password):
if password is None: self.password = '' if password is None else password
self.password = ''
else:
self.password = password
if self.mechanism == 'SCRAM-SHA-1': if self.mechanism == 'SCRAM-SHA-1':
nonce = ''.join('%x' % randint(0, 2 ** 28) for randint in \ nonce = ''.join('%x' % randint(0, 2 ** 28) for randint in \
itertools.repeat(random.randint, 7)) itertools.repeat(random.randint, 7))
@ -437,15 +442,9 @@ class SASL(PlugIn):
node = Node('auth', attrs={'xmlns': NS_SASL, node = Node('auth', attrs={'xmlns': NS_SASL,
'mechanism': self.mechanism}, payload=[sasl_data]) 'mechanism': self.mechanism}, payload=[sasl_data])
elif self.mechanism == 'DIGEST-MD5': elif self.mechanism == 'DIGEST-MD5':
def convert_to_iso88591(string): hash_username = self._convert_to_iso88591(self.resp['username'])
try: hash_realm = self._convert_to_iso88591(self.resp['realm'])
string = string.decode('utf-8').encode('iso-8859-1') hash_password = self._convert_to_iso88591(self.password)
except UnicodeEncodeError:
pass
return string
hash_username = convert_to_iso88591(self.resp['username'])
hash_realm = convert_to_iso88591(self.resp['realm'])
hash_password = convert_to_iso88591(self.password)
A1 = C([H(C([hash_username, hash_realm, hash_password])), A1 = C([H(C([hash_username, hash_realm, hash_password])),
self.resp['nonce'], self.resp['cnonce']]) self.resp['nonce'], self.resp['cnonce']])
A2 = C(['AUTHENTICATE', self.resp['digest-uri']]) A2 = C(['AUTHENTICATE', self.resp['digest-uri']])

View File

@ -534,6 +534,8 @@ class GajimRemote:
self.arguments += ['']*(len(args)-i) self.arguments += ['']*(len(args)-i)
def handle_uri(self): def handle_uri(self):
if len(sys.argv) < 3:
send_error(_('No uri given'))
if not sys.argv[2].startswith('xmpp:'): if not sys.argv[2].startswith('xmpp:'):
send_error(_('Wrong uri')) send_error(_('Wrong uri'))
sys.argv[2] = sys.argv[2][5:] sys.argv[2] = sys.argv[2][5:]