Merge changes from default to refacotring branch
23
ChangeLog
|
@ -1,3 +1,26 @@
|
||||||
|
Gajim 0.13 (XX November 2009)
|
||||||
|
|
||||||
|
* Improve gtkspell (fix memleak)
|
||||||
|
* BOSH connection
|
||||||
|
* Roster versioning
|
||||||
|
* Ability to send contacts
|
||||||
|
* GUI to send XHTML messages
|
||||||
|
* Improve sessions handling
|
||||||
|
* pubsub storage (for bookmarks)
|
||||||
|
* Ability to select account when joining a groupchat
|
||||||
|
* Better Gnome keyring support
|
||||||
|
* Ability to ignore occupants in groupchats
|
||||||
|
* Ability to show / hide self contact row
|
||||||
|
* Automatically go away when screensaver is enabled under windows
|
||||||
|
* Ability to enable / disable accounts
|
||||||
|
* better URL recognition
|
||||||
|
* groupchat autoreconnect
|
||||||
|
* Store passwords in KDE wallet if available
|
||||||
|
* Better MUC errors handling
|
||||||
|
* Fix sound player launch (don't create zombies anymore)
|
||||||
|
* Optional shell like completion
|
||||||
|
* New color theme
|
||||||
|
|
||||||
Gajim 0.12.5 (08 August 2009)
|
Gajim 0.12.5 (08 August 2009)
|
||||||
|
|
||||||
* Don't depend on GTK 2.14
|
* Don't depend on GTK 2.14
|
||||||
|
|
|
@ -2,7 +2,9 @@ Anders Ström
|
||||||
Christophe Got
|
Christophe Got
|
||||||
Dennis Craven
|
Dennis Craven
|
||||||
Guillaume Morin
|
Guillaume Morin
|
||||||
|
Gvorcek Spajreh
|
||||||
Josef Vybíral
|
Josef Vybíral
|
||||||
Membris Khan
|
Membris Khan
|
||||||
Rederick Asher
|
Rederick Asher
|
||||||
Jakub Szypulka
|
Jakub Szypulka
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
AC_INIT([Gajim - A Jabber Instant Messager],
|
AC_INIT([Gajim - A Jabber Instant Messager],
|
||||||
[0.12.5.7-dev],[http://trac.gajim.org/],[gajim])
|
[0.12.5.8-dev],[http://trac.gajim.org/],[gajim])
|
||||||
AC_PREREQ([2.59])
|
AC_PREREQ([2.59])
|
||||||
|
|
||||||
AC_CONFIG_HEADER(config.h)
|
AC_CONFIG_HEADER(config.h)
|
||||||
|
|
After Width: | Height: | Size: 929 B |
After Width: | Height: | Size: 938 B |
After Width: | Height: | Size: 210 B |
After Width: | Height: | Size: 286 B |
After Width: | Height: | Size: 941 B |
After Width: | Height: | Size: 466 B |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 901 B |
After Width: | Height: | Size: 949 B |
After Width: | Height: | Size: 895 B |
After Width: | Height: | Size: 924 B |
After Width: | Height: | Size: 939 B |
After Width: | Height: | Size: 937 B |
After Width: | Height: | Size: 204 B |
After Width: | Height: | Size: 929 B |
After Width: | Height: | Size: 929 B |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 739 B |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 4.2 KiB |
|
@ -174,7 +174,6 @@ Section "Gajim" SecGajim
|
||||||
File "bin\pywintypes25.dll"
|
File "bin\pywintypes25.dll"
|
||||||
File "bin\OpenSSL.rand.pyd"
|
File "bin\OpenSSL.rand.pyd"
|
||||||
File "bin\select.pyd"
|
File "bin\select.pyd"
|
||||||
File "bin\Crypto.Hash.SHA256.pyd"
|
|
||||||
File "bin\sqlite3.dll"
|
File "bin\sqlite3.dll"
|
||||||
File "bin\ssleay32.dll"
|
File "bin\ssleay32.dll"
|
||||||
File "bin\OpenSSL.SSL.pyd"
|
File "bin\OpenSSL.SSL.pyd"
|
||||||
|
@ -286,6 +285,11 @@ Section "sun" SecIconsetsSun
|
||||||
File /r "data\iconsets\sun"
|
File /r "data\iconsets\sun"
|
||||||
SectionEnd
|
SectionEnd
|
||||||
|
|
||||||
|
Section "wroop" SecIconsetsWroop
|
||||||
|
SetOutPath "$INSTDIR\data\iconsets"
|
||||||
|
File /r "data\iconsets\wroop"
|
||||||
|
SectionEnd
|
||||||
|
|
||||||
Section "transports" SecIconsetsTransports
|
Section "transports" SecIconsetsTransports
|
||||||
SetOutPath "$INSTDIR\data\iconsets"
|
SetOutPath "$INSTDIR\data\iconsets"
|
||||||
File /r "data\iconsets\transports"
|
File /r "data\iconsets\transports"
|
||||||
|
@ -646,7 +650,6 @@ Section "Uninstall"
|
||||||
Delete "$INSTDIR\bin\bz2.pyd"
|
Delete "$INSTDIR\bin\bz2.pyd"
|
||||||
Delete "$INSTDIR\bin\cairo._cairo.pyd"
|
Delete "$INSTDIR\bin\cairo._cairo.pyd"
|
||||||
Delete "$INSTDIR\bin\Crypto.Cipher.AES.pyd"
|
Delete "$INSTDIR\bin\Crypto.Cipher.AES.pyd"
|
||||||
Delete "$INSTDIR\bin\Crypto.Hash.SHA256.pyd"
|
|
||||||
Delete "$INSTDIR\bin\gajim.exe"
|
Delete "$INSTDIR\bin\gajim.exe"
|
||||||
Delete "$INSTDIR\bin\gobject._gobject.pyd"
|
Delete "$INSTDIR\bin\gobject._gobject.pyd"
|
||||||
Delete "$INSTDIR\bin\gtk._gtk.pyd"
|
Delete "$INSTDIR\bin\gtk._gtk.pyd"
|
||||||
|
@ -692,6 +695,7 @@ Section "Uninstall"
|
||||||
RMDir /r "$INSTDIR\data\iconsets\gota"
|
RMDir /r "$INSTDIR\data\iconsets\gota"
|
||||||
RMDir /r "$INSTDIR\data\iconsets\jabberbulb"
|
RMDir /r "$INSTDIR\data\iconsets\jabberbulb"
|
||||||
RMDir /r "$INSTDIR\data\iconsets\sun"
|
RMDir /r "$INSTDIR\data\iconsets\sun"
|
||||||
|
RMDir /r "$INSTDIR\data\iconsets\wroop"
|
||||||
RMDir /r "$INSTDIR\data\iconsets\transports"
|
RMDir /r "$INSTDIR\data\iconsets\transports"
|
||||||
RMDir "$INSTDIR\data\iconsets"
|
RMDir "$INSTDIR\data\iconsets"
|
||||||
RMDir "$INSTDIR\data"
|
RMDir "$INSTDIR\data"
|
||||||
|
|
|
@ -65,7 +65,9 @@ class CommandProcessor(object):
|
||||||
Try to process text as a command. Returns True if it has been processed
|
Try to process text as a command. Returns True if it has been processed
|
||||||
as a command and False otherwise.
|
as a command and False otherwise.
|
||||||
"""
|
"""
|
||||||
if not text.startswith(self.COMMAND_PREFIX):
|
prefix = text.startswith(self.COMMAND_PREFIX)
|
||||||
|
length = len(text) > len(self.COMMAND_PREFIX)
|
||||||
|
if not (prefix and length):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
body = text[len(self.COMMAND_PREFIX):]
|
body = text[len(self.COMMAND_PREFIX):]
|
||||||
|
@ -158,7 +160,7 @@ class Command(object):
|
||||||
# in case if they was not set by the one who raised an exception.
|
# in case if they was not set by the one who raised an exception.
|
||||||
except CommandError, error:
|
except CommandError, error:
|
||||||
if not error.command and not error.name:
|
if not error.command and not error.name:
|
||||||
raise CommandError(exception.message, self)
|
raise CommandError(error.message, self)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
# This one is a little bit too wide, but as Python does not have
|
# This one is a little bit too wide, but as Python does not have
|
||||||
|
|
|
@ -22,6 +22,7 @@ from common import gajim
|
||||||
from common import helpers
|
from common import helpers
|
||||||
from common.exceptions import GajimGeneralException
|
from common.exceptions import GajimGeneralException
|
||||||
|
|
||||||
|
from ..errors import CommandError
|
||||||
from ..framework import CommandContainer, command, documentation
|
from ..framework import CommandContainer, command, documentation
|
||||||
from ..mapping import generate_usage
|
from ..mapping import generate_usage
|
||||||
|
|
||||||
|
|
|
@ -198,7 +198,7 @@ class NullClientCaps(AbstractClientCaps):
|
||||||
|
|
||||||
def _lookup_in_cache(self, caps_cache):
|
def _lookup_in_cache(self, caps_cache):
|
||||||
# lookup something which does not exist to get a new CacheItem created
|
# lookup something which does not exist to get a new CacheItem created
|
||||||
cache_item = caps_cache[('old', '')]
|
cache_item = caps_cache[('dummy', '')]
|
||||||
assert cache_item.queried == 0
|
assert cache_item.queried == 0
|
||||||
return cache_item
|
return cache_item
|
||||||
|
|
||||||
|
@ -359,10 +359,10 @@ class ConnectionCaps(object):
|
||||||
else:
|
else:
|
||||||
hash_method, node, caps_hash = caps_tag['hash'], caps_tag['node'], caps_tag['ver']
|
hash_method, node, caps_hash = caps_tag['hash'], caps_tag['node'], caps_tag['ver']
|
||||||
|
|
||||||
if node is None or caps_hash is None:
|
if not node or not caps_hash:
|
||||||
# improper caps in stanza, ignore client capabilities.
|
# improper caps in stanza, ignore client capabilities.
|
||||||
client_caps = NullClientCaps()
|
client_caps = NullClientCaps()
|
||||||
elif hash_method is None:
|
elif not hash_method:
|
||||||
client_caps = OldClientCaps(caps_hash, node)
|
client_caps = OldClientCaps(caps_hash, node)
|
||||||
else:
|
else:
|
||||||
client_caps = ClientCaps(caps_hash, node, hash_method)
|
client_caps = ClientCaps(caps_hash, node, hash_method)
|
||||||
|
|
|
@ -326,8 +326,7 @@ class Config:
|
||||||
'http_auth': [opt_str, 'ask'], # yes, no, ask
|
'http_auth': [opt_str, 'ask'], # yes, no, ask
|
||||||
'dont_ack_subscription': [opt_bool, False, _('Jabberd2 workaround')],
|
'dont_ack_subscription': [opt_bool, False, _('Jabberd2 workaround')],
|
||||||
# proxy65 for FT
|
# proxy65 for FT
|
||||||
'file_transfer_proxies': [opt_str,
|
'file_transfer_proxies': [opt_str, 'proxy.eu.jabber.org, proxy.jabber.ru, proxy.jabbim.cz'],
|
||||||
'proxy65.talkonaut.com, proxy.jabber.org, proxy.netlab.cz, transfer.jabber.freenet.de, proxy.jabber.cd.chalmers.se'],
|
|
||||||
'use_ft_proxies': [opt_bool, True, _('If checked, Gajim will use your IP and proxies defined in file_transfer_proxies option for file transfer.'), True],
|
'use_ft_proxies': [opt_bool, True, _('If checked, Gajim will use your IP and proxies defined in file_transfer_proxies option for file transfer.'), True],
|
||||||
'msgwin-x-position': [opt_int, -1], # Default is to let the wm decide
|
'msgwin-x-position': [opt_int, -1], # Default is to let the wm decide
|
||||||
'msgwin-y-position': [opt_int, -1], # Default is to let the wm decide
|
'msgwin-y-position': [opt_int, -1], # Default is to let the wm decide
|
||||||
|
|
|
@ -2259,7 +2259,7 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
||||||
is_gc = True
|
is_gc = True
|
||||||
status = prs.getStatus() or ''
|
status = prs.getStatus() or ''
|
||||||
show = prs.getShow()
|
show = prs.getShow()
|
||||||
if not show in gajim.SHOW_LIST:
|
if show not in ('chat', 'away', 'xa', 'dnd'):
|
||||||
show = '' # We ignore unknown show
|
show = '' # We ignore unknown show
|
||||||
if not ptype and not show:
|
if not ptype and not show:
|
||||||
show = 'online'
|
show = 'online'
|
||||||
|
|
|
@ -27,7 +27,7 @@ docdir = '../'
|
||||||
datadir = '../'
|
datadir = '../'
|
||||||
localedir = '../po'
|
localedir = '../po'
|
||||||
|
|
||||||
version = '0.12.5.7-dev'
|
version = '0.12.5.8-dev'
|
||||||
|
|
||||||
import sys, os.path
|
import sys, os.path
|
||||||
for base in ('.', 'common'):
|
for base in ('.', 'common'):
|
||||||
|
|
|
@ -216,12 +216,51 @@ class OptionsParser:
|
||||||
self.update_config_to_01256()
|
self.update_config_to_01256()
|
||||||
if old < [0, 12, 5, 7] and new >= [0, 12, 5, 7]:
|
if old < [0, 12, 5, 7] and new >= [0, 12, 5, 7]:
|
||||||
self.update_config_to_01257()
|
self.update_config_to_01257()
|
||||||
|
if old < [0, 12, 5, 8] and new >= [0, 12, 5, 8]:
|
||||||
|
self.update_config_to_01258()
|
||||||
|
|
||||||
gajim.logger.init_vars()
|
gajim.logger.init_vars()
|
||||||
gajim.config.set('version', new_version)
|
gajim.config.set('version', new_version)
|
||||||
|
|
||||||
caps.capscache.initialize_from_db()
|
caps.capscache.initialize_from_db()
|
||||||
|
|
||||||
|
def assert_unread_msgs_table_exists(self):
|
||||||
|
'''create table unread_messages if there is no such table'''
|
||||||
|
back = os.getcwd()
|
||||||
|
os.chdir(logger.LOG_DB_FOLDER)
|
||||||
|
con = sqlite.connect(logger.LOG_DB_FILE)
|
||||||
|
os.chdir(back)
|
||||||
|
cur = con.cursor()
|
||||||
|
try:
|
||||||
|
cur.executescript(
|
||||||
|
'''
|
||||||
|
CREATE TABLE unread_messages (
|
||||||
|
message_id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
|
||||||
|
jid_id INTEGER
|
||||||
|
);
|
||||||
|
'''
|
||||||
|
)
|
||||||
|
con.commit()
|
||||||
|
gajim.logger.init_vars()
|
||||||
|
except sqlite.OperationalError:
|
||||||
|
pass
|
||||||
|
con.close()
|
||||||
|
|
||||||
|
def update_ft_proxies(self, to_remove=[], to_add=[]):
|
||||||
|
for account in gajim.config.get_per('accounts'):
|
||||||
|
proxies_str = gajim.config.get_per('accounts', account,
|
||||||
|
'file_transfer_proxies')
|
||||||
|
proxies = [p.strip() for p in proxies_str.split(',')]
|
||||||
|
for wrong_proxy in to_remove:
|
||||||
|
if wrong_proxy in proxies:
|
||||||
|
proxies.remove(wrong_proxy)
|
||||||
|
for new_proxy in to_add:
|
||||||
|
if new_proxy not in proxies:
|
||||||
|
proxies.append(new_proxy)
|
||||||
|
proxies_str = ', '.join(proxies)
|
||||||
|
gajim.config.set_per('accounts', account, 'file_transfer_proxies',
|
||||||
|
proxies_str)
|
||||||
|
|
||||||
def update_config_x_to_09(self):
|
def update_config_x_to_09(self):
|
||||||
# Var name that changed:
|
# Var name that changed:
|
||||||
# avatar_width /height -> chat_avatar_width / height
|
# avatar_width /height -> chat_avatar_width / height
|
||||||
|
@ -262,38 +301,10 @@ class OptionsParser:
|
||||||
theme = gajim.config.get_per('themes')[0]
|
theme = gajim.config.get_per('themes')[0]
|
||||||
gajim.config.set('roster_theme', theme)
|
gajim.config.set('roster_theme', theme)
|
||||||
# new proxies in accounts.name.file_transfer_proxies
|
# new proxies in accounts.name.file_transfer_proxies
|
||||||
for account in gajim.config.get_per('accounts'):
|
self.update_ft_proxies(to_add=['proxy.netlab.cz'])
|
||||||
proxies = gajim.config.get_per('accounts', account,
|
|
||||||
'file_transfer_proxies')
|
|
||||||
if proxies.find('proxy.netlab.cz') < 0:
|
|
||||||
proxies += ', ' + 'proxy.netlab.cz'
|
|
||||||
gajim.config.set_per('accounts', account, 'file_transfer_proxies',
|
|
||||||
proxies)
|
|
||||||
|
|
||||||
gajim.config.set('version', '0.9')
|
gajim.config.set('version', '0.9')
|
||||||
|
|
||||||
def assert_unread_msgs_table_exists(self):
|
|
||||||
'''create table unread_messages if there is no such table'''
|
|
||||||
back = os.getcwd()
|
|
||||||
os.chdir(logger.LOG_DB_FOLDER)
|
|
||||||
con = sqlite.connect(logger.LOG_DB_FILE)
|
|
||||||
os.chdir(back)
|
|
||||||
cur = con.cursor()
|
|
||||||
try:
|
|
||||||
cur.executescript(
|
|
||||||
'''
|
|
||||||
CREATE TABLE unread_messages (
|
|
||||||
message_id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
|
|
||||||
jid_id INTEGER
|
|
||||||
);
|
|
||||||
'''
|
|
||||||
)
|
|
||||||
con.commit()
|
|
||||||
gajim.logger.init_vars()
|
|
||||||
except sqlite.OperationalError:
|
|
||||||
pass
|
|
||||||
con.close()
|
|
||||||
|
|
||||||
def update_config_09_to_010(self):
|
def update_config_09_to_010(self):
|
||||||
if 'usetabbedchat' in self.old_values and not \
|
if 'usetabbedchat' in self.old_values and not \
|
||||||
self.old_values['usetabbedchat']:
|
self.old_values['usetabbedchat']:
|
||||||
|
@ -311,21 +322,8 @@ class OptionsParser:
|
||||||
self.old_values['always_compact_view_gc'] != 'False':
|
self.old_values['always_compact_view_gc'] != 'False':
|
||||||
gajim.config.set('always_hide_groupchat_buttons', True)
|
gajim.config.set('always_hide_groupchat_buttons', True)
|
||||||
|
|
||||||
for account in gajim.config.get_per('accounts'):
|
self.update_ft_proxies(to_remove=['proxy65.jabber.autocom.pl',
|
||||||
proxies_str = gajim.config.get_per('accounts', account,
|
'proxy65.jabber.ccc.de'], to_add=['transfer.jabber.freenet.de'])
|
||||||
'file_transfer_proxies')
|
|
||||||
proxies = proxies_str.split(',')
|
|
||||||
for i in range(0, len(proxies)):
|
|
||||||
proxies[i] = proxies[i].strip()
|
|
||||||
for wrong_proxy in ('proxy65.jabber.autocom.pl',
|
|
||||||
'proxy65.jabber.ccc.de'):
|
|
||||||
if wrong_proxy in proxies:
|
|
||||||
proxies.remove(wrong_proxy)
|
|
||||||
if not 'transfer.jabber.freenet.de' in proxies:
|
|
||||||
proxies.append('transfer.jabber.freenet.de')
|
|
||||||
proxies_str = ', '.join(proxies)
|
|
||||||
gajim.config.set_per('accounts', account, 'file_transfer_proxies',
|
|
||||||
proxies_str)
|
|
||||||
# create unread_messages table if needed
|
# create unread_messages table if needed
|
||||||
self.assert_unread_msgs_table_exists()
|
self.assert_unread_msgs_table_exists()
|
||||||
|
|
||||||
|
@ -811,4 +809,12 @@ class OptionsParser:
|
||||||
'simplebulb', 'stellar'):
|
'simplebulb', 'stellar'):
|
||||||
gajim.config.set('iconset', gajim.config.DEFAULT_ICONSET)
|
gajim.config.set('iconset', gajim.config.DEFAULT_ICONSET)
|
||||||
gajim.config.set('version', '0.12.5.7')
|
gajim.config.set('version', '0.12.5.7')
|
||||||
|
|
||||||
|
def update_config_to_01258(self):
|
||||||
|
self.update_ft_proxies(to_remove=['proxy65.talkonaut.com',
|
||||||
|
'proxy.jabber.org', 'proxy.netlab.cz', 'transfer.jabber.freenet.de',
|
||||||
|
'proxy.jabber.cd.chalmers.se'], to_add=['proxy.eu.jabber.org',
|
||||||
|
'proxy.jabber.ru', 'proxy.jabbim.cz'])
|
||||||
|
gajim.config.set('version', '0.12.5.8')
|
||||||
|
|
||||||
# vim: se ts=3:
|
# vim: se ts=3:
|
||||||
|
|
|
@ -84,8 +84,8 @@ class NonBlockingBOSH(NonBlockingTransport):
|
||||||
self.proxy_dict['type'] = 'http'
|
self.proxy_dict['type'] = 'http'
|
||||||
# with SSL over proxy, we do HTTP CONNECT to proxy to open a channel to
|
# with SSL over proxy, we do HTTP CONNECT to proxy to open a channel to
|
||||||
# BOSH Connection Manager
|
# BOSH Connection Manager
|
||||||
host, port = urisplit(self.bosh_uri)[1].split(':', 1)
|
host, port = urisplit(self.bosh_uri)[1:3]
|
||||||
self.proxy_dict['xmpp_server'] = (host, int(port))
|
self.proxy_dict['xmpp_server'] = (host, port)
|
||||||
self.proxy_dict['credentials'] = self.proxy_creds
|
self.proxy_dict['credentials'] = self.proxy_creds
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,30 +35,39 @@ import errno
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
import base64
|
import base64
|
||||||
|
import urlparse
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
log = logging.getLogger('gajim.c.x.transports_nb')
|
log = logging.getLogger('gajim.c.x.transports_nb')
|
||||||
|
|
||||||
def urisplit(uri):
|
def urisplit(uri):
|
||||||
'''
|
'''
|
||||||
Function for splitting URI string to tuple (protocol, host, path).
|
Function for splitting URI string to tuple (protocol, host, port, path).
|
||||||
e.g. urisplit('http://httpcm.jabber.org/webclient') returns
|
e.g. urisplit('http://httpcm.jabber.org:123/webclient') returns
|
||||||
('http', 'httpcm.jabber.org', '/webclient')
|
('http', 'httpcm.jabber.org', 123, '/webclient')
|
||||||
|
return 443 as default port if proto is https else 80
|
||||||
'''
|
'''
|
||||||
import re
|
splitted = urlparse.urlsplit(uri)
|
||||||
regex = '(([^:/]+)(://))?([^/]*)(/?.*)'
|
proto, host, path = splitted.scheme, splitted.hostname, splitted.path
|
||||||
grouped = re.match(regex, uri).groups()
|
try:
|
||||||
proto, host, path = grouped[1], grouped[3], grouped[4]
|
port = splitted.port
|
||||||
return proto, host, path
|
except ValueError:
|
||||||
|
log.warn('port cannot be extracted from BOSH URL %s, using default port' \
|
||||||
|
% uri)
|
||||||
|
port = ''
|
||||||
|
if not port:
|
||||||
|
if proto == 'https':
|
||||||
|
port = 443
|
||||||
|
else:
|
||||||
|
port = 80
|
||||||
|
return proto, host, port, path
|
||||||
|
|
||||||
def get_proxy_data_from_dict(proxy):
|
def get_proxy_data_from_dict(proxy):
|
||||||
tcp_host, tcp_port, proxy_user, proxy_pass = None, None, None, None
|
tcp_host, tcp_port, proxy_user, proxy_pass = None, None, None, None
|
||||||
proxy_type = proxy['type']
|
proxy_type = proxy['type']
|
||||||
if proxy_type == 'bosh' and not proxy['bosh_useproxy']:
|
if proxy_type == 'bosh' and not proxy['bosh_useproxy']:
|
||||||
# with BOSH not over proxy we have to parse the hostname from BOSH URI
|
# with BOSH not over proxy we have to parse the hostname from BOSH URI
|
||||||
tcp_host = urisplit(proxy['bosh_uri'])[1]
|
proto, tcp_host, tcp_port, path = urisplit(proxy['bosh_uri'])
|
||||||
tcp_host, tcp_port = tcp_host.split(':', 1)
|
|
||||||
tcp_port = int(tcp_port)
|
|
||||||
else:
|
else:
|
||||||
# with proxy!=bosh or with bosh over HTTP proxy we're connecting to proxy
|
# with proxy!=bosh or with bosh over HTTP proxy we're connecting to proxy
|
||||||
# machine
|
# machine
|
||||||
|
@ -602,10 +611,8 @@ class NonBlockingHTTP(NonBlockingTCP):
|
||||||
NonBlockingTCP.__init__(self, raise_event, on_disconnect, idlequeue,
|
NonBlockingTCP.__init__(self, raise_event, on_disconnect, idlequeue,
|
||||||
estabilish_tls, certs, proxy_dict)
|
estabilish_tls, certs, proxy_dict)
|
||||||
|
|
||||||
self.http_protocol, self.http_host, self.http_path = urisplit(
|
self.http_protocol, self.http_host, self.http_port, self.http_path = \
|
||||||
http_dict['http_uri'])
|
urisplit(http_dict['http_uri'])
|
||||||
self.http_host, self.http_port = self.http_host.split(':', 1)
|
|
||||||
self.http_port = int(self.http_port)
|
|
||||||
self.http_protocol = self.http_protocol or 'http'
|
self.http_protocol = self.http_protocol or 'http'
|
||||||
self.http_path = self.http_path or '/'
|
self.http_path = self.http_path or '/'
|
||||||
self.http_version = http_dict['http_version']
|
self.http_version = http_dict['http_version']
|
||||||
|
|
102
src/config.py
|
@ -228,25 +228,8 @@ class PreferencesWindow:
|
||||||
st = gajim.config.get('use_transports_iconsets')
|
st = gajim.config.get('use_transports_iconsets')
|
||||||
self.xml.get_widget('transports_iconsets_checkbutton').set_active(st)
|
self.xml.get_widget('transports_iconsets_checkbutton').set_active(st)
|
||||||
|
|
||||||
# Color for incoming messages
|
# Color widgets
|
||||||
colSt = gajim.config.get('inmsgcolor')
|
self.draw_color_widgets()
|
||||||
self.xml.get_widget('incoming_msg_colorbutton').set_color(
|
|
||||||
gtk.gdk.color_parse(colSt))
|
|
||||||
|
|
||||||
# Color for outgoing messages
|
|
||||||
colSt = gajim.config.get('outmsgcolor')
|
|
||||||
self.xml.get_widget('outgoing_msg_colorbutton').set_color(
|
|
||||||
gtk.gdk.color_parse(colSt))
|
|
||||||
|
|
||||||
# Color for status messages
|
|
||||||
colSt = gajim.config.get('statusmsgcolor')
|
|
||||||
self.xml.get_widget('status_msg_colorbutton').set_color(
|
|
||||||
gtk.gdk.color_parse(colSt))
|
|
||||||
|
|
||||||
# Color for hyperlinks
|
|
||||||
colSt = gajim.config.get('urlmsgcolor')
|
|
||||||
self.xml.get_widget('url_msg_colorbutton').set_color(
|
|
||||||
gtk.gdk.color_parse(colSt))
|
|
||||||
|
|
||||||
# Font for messages
|
# Font for messages
|
||||||
font = gajim.config.get('conversation_font')
|
font = gajim.config.get('conversation_font')
|
||||||
|
@ -823,12 +806,18 @@ class PreferencesWindow:
|
||||||
for win in gajim.interface.msg_win_mgr.windows():
|
for win in gajim.interface.msg_win_mgr.windows():
|
||||||
win.update_font()
|
win.update_font()
|
||||||
|
|
||||||
def on_incoming_msg_colorbutton_color_set(self, widget):
|
def on_incoming_nick_colorbutton_color_set(self, widget):
|
||||||
self.on_preference_widget_color_set(widget, 'inmsgcolor')
|
self.on_preference_widget_color_set(widget, 'inmsgcolor')
|
||||||
|
|
||||||
def on_outgoing_msg_colorbutton_color_set(self, widget):
|
def on_outgoing_nick_colorbutton_color_set(self, widget):
|
||||||
self.on_preference_widget_color_set(widget, 'outmsgcolor')
|
self.on_preference_widget_color_set(widget, 'outmsgcolor')
|
||||||
|
|
||||||
|
def on_incoming_msg_colorbutton_color_set(self, widget):
|
||||||
|
self.on_preference_widget_color_set(widget, 'inmsgtxtcolor')
|
||||||
|
|
||||||
|
def on_outgoing_msg_colorbutton_color_set(self, widget):
|
||||||
|
self.on_preference_widget_color_set(widget, 'outmsgtxtcolor')
|
||||||
|
|
||||||
def on_url_msg_colorbutton_color_set(self, widget):
|
def on_url_msg_colorbutton_color_set(self, widget):
|
||||||
self.on_preference_widget_color_set(widget, 'urlmsgcolor')
|
self.on_preference_widget_color_set(widget, 'urlmsgcolor')
|
||||||
|
|
||||||
|
@ -847,21 +836,70 @@ class PreferencesWindow:
|
||||||
font_widget.set_sensitive(True)
|
font_widget.set_sensitive(True)
|
||||||
self.on_preference_widget_font_set(font_widget, 'conversation_font')
|
self.on_preference_widget_font_set(font_widget, 'conversation_font')
|
||||||
|
|
||||||
def on_reset_colors_button_clicked(self, widget):
|
def draw_color_widgets(self):
|
||||||
for i in ('inmsgcolor', 'outmsgcolor', 'statusmsgcolor', 'urlmsgcolor'):
|
col_to_widget = {'inmsgcolor': 'incoming_nick_colorbutton',
|
||||||
gajim.config.set(i, gajim.interface.default_colors[i])
|
'outmsgcolor': 'outgoing_nick_colorbutton',
|
||||||
|
'inmsgtxtcolor': ['incoming_msg_colorbutton',
|
||||||
|
'incoming_msg_checkbutton'],
|
||||||
|
'outmsgtxtcolor': ['outgoing_msg_colorbutton',
|
||||||
|
'outgoing_msg_checkbutton'],
|
||||||
|
'statusmsgcolor': 'status_msg_colorbutton',
|
||||||
|
'urlmsgcolor': 'url_msg_colorbutton'}
|
||||||
|
for c in col_to_widget:
|
||||||
|
col = gajim.config.get(c)
|
||||||
|
if col:
|
||||||
|
if isinstance(col_to_widget[c], list):
|
||||||
|
self.xml.get_widget(col_to_widget[c][0]).set_color(
|
||||||
|
gtk.gdk.color_parse(col))
|
||||||
|
self.xml.get_widget(col_to_widget[c][0]).set_sensitive(True)
|
||||||
|
self.xml.get_widget(col_to_widget[c][1]).set_active(True)
|
||||||
|
else:
|
||||||
|
self.xml.get_widget(col_to_widget[c]).set_color(
|
||||||
|
gtk.gdk.color_parse(col))
|
||||||
|
else:
|
||||||
|
if isinstance(col_to_widget[c], list):
|
||||||
|
self.xml.get_widget(col_to_widget[c][0]).set_color(
|
||||||
|
gtk.gdk.color_parse('#000000'))
|
||||||
|
self.xml.get_widget(col_to_widget[c][0]).set_sensitive(False)
|
||||||
|
self.xml.get_widget(col_to_widget[c][1]).set_active(False)
|
||||||
|
else:
|
||||||
|
self.xml.get_widget(col_to_widget[c]).set_color(
|
||||||
|
gtk.gdk.color_parse('#000000'))
|
||||||
|
|
||||||
|
def on_reset_colors_button_clicked(self, widget):
|
||||||
|
col_to_widget = {'inmsgcolor': 'incoming_nick_colorbutton',
|
||||||
|
'outmsgcolor': 'outgoing_nick_colorbutton',
|
||||||
|
'inmsgtxtcolor': 'incoming_msg_colorbutton',
|
||||||
|
'outmsgtxtcolor': 'outgoing_msg_colorbutton',
|
||||||
|
'statusmsgcolor': 'status_msg_colorbutton',
|
||||||
|
'urlmsgcolor': 'url_msg_colorbutton'}
|
||||||
|
for c in col_to_widget:
|
||||||
|
gajim.config.set(c, gajim.interface.default_colors[c])
|
||||||
|
self.draw_color_widgets()
|
||||||
|
|
||||||
self.xml.get_widget('incoming_msg_colorbutton').set_color(\
|
|
||||||
gtk.gdk.color_parse(gajim.config.get('inmsgcolor')))
|
|
||||||
self.xml.get_widget('outgoing_msg_colorbutton').set_color(\
|
|
||||||
gtk.gdk.color_parse(gajim.config.get('outmsgcolor')))
|
|
||||||
self.xml.get_widget('status_msg_colorbutton').set_color(\
|
|
||||||
gtk.gdk.color_parse(gajim.config.get('statusmsgcolor')))
|
|
||||||
self.xml.get_widget('url_msg_colorbutton').set_color(\
|
|
||||||
gtk.gdk.color_parse(gajim.config.get('urlmsgcolor')))
|
|
||||||
self.update_text_tags()
|
self.update_text_tags()
|
||||||
gajim.interface.save_config()
|
gajim.interface.save_config()
|
||||||
|
|
||||||
|
def _set_color(self, state, widget_name, option):
|
||||||
|
''' set color value in prefs and update the UI '''
|
||||||
|
if state:
|
||||||
|
color = self.xml.get_widget(widget_name).get_color()
|
||||||
|
color_string = gtkgui_helpers.make_color_string(color)
|
||||||
|
else:
|
||||||
|
color_string = ''
|
||||||
|
gajim.config.set(option, color_string)
|
||||||
|
gajim.interface.save_config()
|
||||||
|
|
||||||
|
def on_incoming_msg_checkbutton_toggled(self, widget):
|
||||||
|
state = widget.get_active()
|
||||||
|
self.xml.get_widget('incoming_msg_colorbutton').set_sensitive(state)
|
||||||
|
self._set_color(state, 'incoming_msg_colorbutton', 'inmsgtxtcolor')
|
||||||
|
|
||||||
|
def on_outgoing_msg_checkbutton_toggled(self, widget):
|
||||||
|
state = widget.get_active()
|
||||||
|
self.xml.get_widget('outgoing_msg_colorbutton').set_sensitive(state)
|
||||||
|
self._set_color(state, 'outgoing_msg_colorbutton', 'outmsgtxtcolor')
|
||||||
|
|
||||||
def on_auto_away_checkbutton_toggled(self, widget):
|
def on_auto_away_checkbutton_toggled(self, widget):
|
||||||
self.on_checkbutton_toggled(widget, 'autoaway',
|
self.on_checkbutton_toggled(widget, 'autoaway',
|
||||||
[self.auto_away_time_spinbutton, self.auto_away_message_entry])
|
[self.auto_away_time_spinbutton, self.auto_away_message_entry])
|
||||||
|
|
|
@ -853,7 +853,7 @@ class ConversationTextview(gobject.GObject):
|
||||||
gajim.interface.instances[self.account]['join_gc'].window.present()
|
gajim.interface.instances[self.account]['join_gc'].window.present()
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
dialogs.JoinGroupchatWindow(account=None, room_jid=room_jid)
|
dialogs.JoinGroupchatWindow(account=self.account, room_jid=room_jid)
|
||||||
except GajimGeneralException:
|
except GajimGeneralException:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -1922,7 +1922,7 @@ class JoinGroupchatWindow:
|
||||||
'''automatic is a dict like {'invities': []}
|
'''automatic is a dict like {'invities': []}
|
||||||
If automatic is not empty, this means room must be automaticaly configured
|
If automatic is not empty, this means room must be automaticaly configured
|
||||||
and when done, invities must be automatically invited'''
|
and when done, invities must be automatically invited'''
|
||||||
self.xml = gtkgui_helpers.get_glade('join_groupchat_window.glade')
|
|
||||||
if account:
|
if account:
|
||||||
if room_jid != '' and room_jid in gajim.gc_connected[account] and\
|
if room_jid != '' and room_jid in gajim.gc_connected[account] and\
|
||||||
gajim.gc_connected[account][room_jid]:
|
gajim.gc_connected[account][room_jid]:
|
||||||
|
@ -1934,20 +1934,26 @@ class JoinGroupchatWindow:
|
||||||
ErrorDialog(_('You are not connected to the server'),
|
ErrorDialog(_('You are not connected to the server'),
|
||||||
_('You can not join a group chat unless you are connected.'))
|
_('You can not join a group chat unless you are connected.'))
|
||||||
raise GajimGeneralException, 'You must be connected to join a groupchat'
|
raise GajimGeneralException, 'You must be connected to join a groupchat'
|
||||||
else:
|
|
||||||
account_label = self.xml.get_widget('account_label')
|
self.xml = gtkgui_helpers.get_glade('join_groupchat_window.glade')
|
||||||
account_combobox = self.xml.get_widget('account_combobox')
|
|
||||||
account_label.set_no_show_all(False)
|
account_label = self.xml.get_widget('account_label')
|
||||||
account_combobox.set_no_show_all(False)
|
account_combobox = self.xml.get_widget('account_combobox')
|
||||||
liststore = gtk.ListStore(str)
|
account_label.set_no_show_all(False)
|
||||||
account_combobox.set_model(liststore)
|
account_combobox.set_no_show_all(False)
|
||||||
cell = gtk.CellRendererText()
|
liststore = gtk.ListStore(str)
|
||||||
account_combobox.pack_start(cell, True)
|
account_combobox.set_model(liststore)
|
||||||
account_combobox.add_attribute(cell, 'text', 0)
|
cell = gtk.CellRendererText()
|
||||||
for acct in [a for a in gajim.connections if \
|
account_combobox.pack_start(cell, True)
|
||||||
gajim.account_is_connected(a)]:
|
account_combobox.add_attribute(cell, 'text', 0)
|
||||||
account_combobox.append_text(acct)
|
account_combobox.set_active(-1)
|
||||||
account_combobox.set_active(-1)
|
|
||||||
|
# Add accounts, set current as active if it matches 'account'
|
||||||
|
for acct in [a for a in gajim.connections if \
|
||||||
|
gajim.account_is_connected(a)]:
|
||||||
|
account_combobox.append_text(acct)
|
||||||
|
if account and account == acct:
|
||||||
|
account_combobox.set_active(liststore.iter_n_children(None)-1)
|
||||||
|
|
||||||
self.account = account
|
self.account = account
|
||||||
self.automatic = automatic
|
self.automatic = automatic
|
||||||
|
@ -2064,7 +2070,7 @@ class JoinGroupchatWindow:
|
||||||
user, server, resource = helpers.decompose_jid(room_jid)
|
user, server, resource = helpers.decompose_jid(room_jid)
|
||||||
if not user or not server or resource:
|
if not user or not server or resource:
|
||||||
ErrorDialog(_('Invalid group chat Jabber ID'),
|
ErrorDialog(_('Invalid group chat Jabber ID'),
|
||||||
_('The group chat Jabber ID has not allowed characters.'))
|
_('Please enter the group chat Jabber ID as room@server.'))
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
room_jid = helpers.parse_jid(room_jid)
|
room_jid = helpers.parse_jid(room_jid)
|
||||||
|
@ -4346,7 +4352,7 @@ class TransformChatToMUC:
|
||||||
gajim.automatic_rooms[self.account][room_jid]['invities'] = guest_list
|
gajim.automatic_rooms[self.account][room_jid]['invities'] = guest_list
|
||||||
gajim.automatic_rooms[self.account][room_jid]['continue_tag'] = True
|
gajim.automatic_rooms[self.account][room_jid]['continue_tag'] = True
|
||||||
gajim.interface.join_gc_room(self.account, room_jid,
|
gajim.interface.join_gc_room(self.account, room_jid,
|
||||||
gajim.nicks[self.account], None, is_continued=True)
|
gajim.nicks[self.account], None, is_continued=True)
|
||||||
self.window.destroy()
|
self.window.destroy()
|
||||||
|
|
||||||
def on_cancel_button_clicked(self, widget):
|
def on_cancel_button_clicked(self, widget):
|
||||||
|
@ -4354,8 +4360,8 @@ class TransformChatToMUC:
|
||||||
|
|
||||||
def unique_room_id_error(self, server):
|
def unique_room_id_error(self, server):
|
||||||
self.unique_room_id_supported(server,
|
self.unique_room_id_supported(server,
|
||||||
gajim.nicks[self.account].lower().replace(' ','') + str(randrange(
|
gajim.nicks[self.account].lower().replace(' ','') + str(randrange(
|
||||||
9999999)))
|
9999999)))
|
||||||
|
|
||||||
class DataFormWindow(Dialog):
|
class DataFormWindow(Dialog):
|
||||||
def __init__(self, form, on_response_ok):
|
def __init__(self, form, on_response_ok):
|
||||||
|
|
3397
src/gajim.py
|
@ -647,7 +647,7 @@ class GroupchatControl(ChatControlBase):
|
||||||
bookmark_separator = xml.get_widget('bookmark_separator')
|
bookmark_separator = xml.get_widget('bookmark_separator')
|
||||||
separatormenuitem2 = xml.get_widget('separatormenuitem2')
|
separatormenuitem2 = xml.get_widget('separatormenuitem2')
|
||||||
|
|
||||||
if hide_buttonbar_entries:
|
if hide_buttonbar_items:
|
||||||
change_nick_menuitem.hide()
|
change_nick_menuitem.hide()
|
||||||
change_subject_menuitem.hide()
|
change_subject_menuitem.hide()
|
||||||
bookmark_room_menuitem.hide()
|
bookmark_room_menuitem.hide()
|
||||||
|
|
|
@ -83,15 +83,15 @@ common.configpaths.gajimpaths.init(config_path)
|
||||||
del config_path
|
del config_path
|
||||||
common.configpaths.gajimpaths.init_profile()
|
common.configpaths.gajimpaths.init_profile()
|
||||||
from common import exceptions
|
from common import exceptions
|
||||||
import dialogs
|
from common import gajim
|
||||||
import gtkgui_helpers
|
import gtkgui_helpers
|
||||||
from common.logger import LOG_DB_PATH, constants
|
from common.logger import LOG_DB_PATH, constants
|
||||||
|
|
||||||
#FIXME: constants should implement 2 way mappings
|
#FIXME: constants should implement 2 way mappings
|
||||||
status = dict((constants.__dict__[i], i[5:].lower()) for i in \
|
status = dict((constants.__dict__[i], i[5:].lower()) for i in \
|
||||||
constants.__dict__.keys() if i.startswith('SHOW_'))
|
constants.__dict__.keys() if i.startswith('SHOW_'))
|
||||||
from common import gajim
|
|
||||||
from common import helpers
|
from common import helpers
|
||||||
|
import dialogs
|
||||||
|
|
||||||
# time, message, subject
|
# time, message, subject
|
||||||
(
|
(
|
||||||
|
|
|
@ -1234,6 +1234,9 @@ class RosterWindow:
|
||||||
child_path = self.model.get_path(child_iter)
|
child_path = self.model.get_path(child_iter)
|
||||||
path = self.modelfilter.convert_child_path_to_path(child_path)
|
path = self.modelfilter.convert_child_path_to_path(child_path)
|
||||||
|
|
||||||
|
if not path:
|
||||||
|
continue
|
||||||
|
|
||||||
if not self.tree.row_expanded(path) and icon_name != 'event':
|
if not self.tree.row_expanded(path) and icon_name != 'event':
|
||||||
iterC = self.model.iter_children(child_iter)
|
iterC = self.model.iter_children(child_iter)
|
||||||
while iterC:
|
while iterC:
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
'''
|
||||||
|
|
||||||
|
This package contains integration tests. Integration tests are tests
|
||||||
|
which require or include UI, network or both.
|
||||||
|
|
||||||
|
'''
|
|
@ -14,34 +14,6 @@ gajim.logger = MockLogger()
|
||||||
|
|
||||||
Interface()
|
Interface()
|
||||||
|
|
||||||
class TestMiscInterface(unittest.TestCase):
|
|
||||||
|
|
||||||
def test_links_regexp_entire(self):
|
|
||||||
def assert_matches_all(str_):
|
|
||||||
m = gajim.interface.basic_pattern_re.match(str_)
|
|
||||||
|
|
||||||
# the match should equal the string
|
|
||||||
str_span = (0, len(str_))
|
|
||||||
self.assertEqual(m.span(), str_span)
|
|
||||||
|
|
||||||
# these entire strings should be parsed as links
|
|
||||||
assert_matches_all('http://google.com/')
|
|
||||||
assert_matches_all('http://google.com')
|
|
||||||
assert_matches_all('http://www.google.ca/search?q=xmpp')
|
|
||||||
|
|
||||||
assert_matches_all('http://tools.ietf.org/html/draft-saintandre-rfc3920bis-05#section-12.3')
|
|
||||||
|
|
||||||
assert_matches_all('http://en.wikipedia.org/wiki/Protocol_(computing)')
|
|
||||||
assert_matches_all(
|
|
||||||
'http://en.wikipedia.org/wiki/Protocol_%28computing%29')
|
|
||||||
|
|
||||||
assert_matches_all('mailto:test@example.org')
|
|
||||||
|
|
||||||
assert_matches_all('xmpp:example-node@example.com')
|
|
||||||
assert_matches_all('xmpp:example-node@example.com/some-resource')
|
|
||||||
assert_matches_all('xmpp:example-node@example.com?message')
|
|
||||||
assert_matches_all('xmpp://guest@example.com/support@example.com?message')
|
|
||||||
|
|
||||||
import time
|
import time
|
||||||
from data import *
|
from data import *
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
'''
|
'''
|
||||||
Unit test for tranports classes.
|
Integration test for tranports classes. See unit for the ordinary
|
||||||
|
unit tests of this module.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
@ -12,62 +13,6 @@ from xmpp_mocks import IdleQueueThread, IdleMock
|
||||||
from common.xmpp import transports_nb
|
from common.xmpp import transports_nb
|
||||||
|
|
||||||
|
|
||||||
class TestModuleLevelFunctions(unittest.TestCase):
|
|
||||||
'''
|
|
||||||
Test class for functions defined at module level
|
|
||||||
'''
|
|
||||||
def test_urisplit(self):
|
|
||||||
def check_uri(uri, proto, host, path):
|
|
||||||
_proto, _host, _path = transports_nb.urisplit(uri)
|
|
||||||
self.assertEqual(proto, _proto)
|
|
||||||
self.assertEqual(host, _host)
|
|
||||||
self.assertEqual(path, _path)
|
|
||||||
check_uri('http://httpcm.jabber.org/webclient',
|
|
||||||
proto='http', host='httpcm.jabber.org', path='/webclient')
|
|
||||||
|
|
||||||
def test_get_proxy_data_from_dict(self):
|
|
||||||
def check_dict(proxy_dict, host, port, user, passwd):
|
|
||||||
_host, _port, _user, _passwd = transports_nb.get_proxy_data_from_dict(
|
|
||||||
proxy_dict)
|
|
||||||
self.assertEqual(_host, host)
|
|
||||||
self.assertEqual(_port, port)
|
|
||||||
self.assertEqual(_user, user)
|
|
||||||
self.assertEqual(_passwd, passwd)
|
|
||||||
|
|
||||||
bosh_dict = {'bosh_content': u'text/xml; charset=utf-8',
|
|
||||||
'bosh_hold': 2,
|
|
||||||
'bosh_http_pipelining': False,
|
|
||||||
'bosh_uri': u'http://gajim.org:5280/http-bind',
|
|
||||||
'bosh_useproxy': False,
|
|
||||||
'bosh_wait': 30,
|
|
||||||
'bosh_wait_for_restart_response': False,
|
|
||||||
'host': u'172.16.99.11',
|
|
||||||
'pass': u'pass',
|
|
||||||
'port': 3128,
|
|
||||||
'type': u'bosh',
|
|
||||||
'useauth': True,
|
|
||||||
'user': u'user'}
|
|
||||||
check_dict(bosh_dict, host=u'gajim.org', port=5280, user=u'user',
|
|
||||||
passwd=u'pass')
|
|
||||||
|
|
||||||
proxy_dict = {'bosh_content': u'text/xml; charset=utf-8',
|
|
||||||
'bosh_hold': 2,
|
|
||||||
'bosh_http_pipelining': False,
|
|
||||||
'bosh_port': 5280,
|
|
||||||
'bosh_uri': u'',
|
|
||||||
'bosh_useproxy': True,
|
|
||||||
'bosh_wait': 30,
|
|
||||||
'bosh_wait_for_restart_response': False,
|
|
||||||
'host': u'172.16.99.11',
|
|
||||||
'pass': u'pass',
|
|
||||||
'port': 3128,
|
|
||||||
'type': 'socks5',
|
|
||||||
'useauth': True,
|
|
||||||
'user': u'user'}
|
|
||||||
check_dict(proxy_dict, host=u'172.16.99.11', port=3128, user=u'user',
|
|
||||||
passwd=u'pass')
|
|
||||||
|
|
||||||
|
|
||||||
class AbstractTransportTest(unittest.TestCase):
|
class AbstractTransportTest(unittest.TestCase):
|
||||||
''' Encapsulates Idlequeue instantiation for transports and more...'''
|
''' Encapsulates Idlequeue instantiation for transports and more...'''
|
||||||
|
|
|
@ -91,6 +91,7 @@ class MockChatControl(Mock):
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return self is other
|
return self is other
|
||||||
|
|
||||||
|
|
||||||
class MockInterface(Mock):
|
class MockInterface(Mock):
|
||||||
def __init__(self, *args):
|
def __init__(self, *args):
|
||||||
Mock.__init__(self, *args)
|
Mock.__init__(self, *args)
|
||||||
|
@ -113,14 +114,17 @@ class MockInterface(Mock):
|
||||||
self.jabber_state_images = {'16': Mock(), '32': Mock(),
|
self.jabber_state_images = {'16': Mock(), '32': Mock(),
|
||||||
'opened': Mock(), 'closed': Mock()}
|
'opened': Mock(), 'closed': Mock()}
|
||||||
|
|
||||||
|
|
||||||
class MockLogger(Mock):
|
class MockLogger(Mock):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Mock.__init__(self, {'write': None, 'get_transports_type': {}})
|
Mock.__init__(self, {'write': None, 'get_transports_type': {}})
|
||||||
|
|
||||||
|
|
||||||
class MockContact(Mock):
|
class MockContact(Mock):
|
||||||
def __nonzero__(self):
|
def __nonzero__(self):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
import random
|
import random
|
||||||
|
|
||||||
class MockSession(Mock):
|
class MockSession(Mock):
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
'''
|
'''
|
||||||
Runs Gajim's Test Suite
|
Runs Gajim's Test Suite
|
||||||
|
|
||||||
Non GUI related tests will be run on each commit.
|
Unit tests tests will be run on each commit.
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
@ -35,19 +35,21 @@ for o, a in opts:
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
# new test modules need to be added manually
|
# new test modules need to be added manually
|
||||||
modules = ( 'test_xmpp_dispatcher_nb',
|
modules = ( 'unit.test_xmpp_dispatcher_nb',
|
||||||
'test_xmpp_client_nb',
|
'unit.test_xmpp_transports_nb',
|
||||||
'test_xmpp_transports_nb',
|
'unit.test_caps',
|
||||||
'test_resolver',
|
'unit.test_contacts',
|
||||||
'test_caps',
|
'unit.test_gui_interface',
|
||||||
'test_contacts',
|
'unit.test_sessions',
|
||||||
)
|
)
|
||||||
#modules = ()
|
#modules = ()
|
||||||
|
|
||||||
if use_x:
|
if use_x:
|
||||||
modules += ('test_misc_interface',
|
modules += ('integration.test_gui_event_integration',
|
||||||
'test_roster',
|
'integration.test_roster',
|
||||||
'test_sessions',
|
'integration.test_resolver',
|
||||||
|
'integration.test_xmpp_client_nb',
|
||||||
|
'integration.test_xmpp_transports_nb'
|
||||||
)
|
)
|
||||||
|
|
||||||
nb_errors = 0
|
nb_errors = 0
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
'''
|
||||||
|
|
||||||
|
This package just contains plain unit tests
|
||||||
|
|
||||||
|
'''
|
|
@ -0,0 +1,112 @@
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
import lib
|
||||||
|
lib.setup_env()
|
||||||
|
|
||||||
|
from common import logging_helpers
|
||||||
|
logging_helpers.set_quiet()
|
||||||
|
|
||||||
|
from common import gajim
|
||||||
|
|
||||||
|
from gajim_mocks import MockLogger
|
||||||
|
gajim.logger = MockLogger()
|
||||||
|
|
||||||
|
from gui_interface import Interface
|
||||||
|
|
||||||
|
class Test(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_instantiation(self):
|
||||||
|
''' Test that we can proper initialize and do not fail on globals '''
|
||||||
|
interface = Interface()
|
||||||
|
interface.run()
|
||||||
|
|
||||||
|
def test_dispatch(self):
|
||||||
|
''' Test dispatcher forwarding network events to handler_* methods '''
|
||||||
|
sut = Interface()
|
||||||
|
|
||||||
|
success = sut.dispatch('No Such Event', None, None)
|
||||||
|
self.assertFalse(success, msg="Unexisting event handled")
|
||||||
|
|
||||||
|
success = sut.dispatch('STANZA_ARRIVED', None, None)
|
||||||
|
self.assertTrue(success, msg="Existing event must be handled")
|
||||||
|
|
||||||
|
def test_register_unregister_single_handler(self):
|
||||||
|
''' Register / Unregister a custom event handler '''
|
||||||
|
sut = Interface()
|
||||||
|
event = 'TESTS_ARE_COOL_EVENT'
|
||||||
|
|
||||||
|
self.called = False
|
||||||
|
def handler(account, data):
|
||||||
|
self.assertEqual(account, 'account')
|
||||||
|
self.assertEqual(data, 'data')
|
||||||
|
self.called = True
|
||||||
|
|
||||||
|
self.assertFalse(self.called)
|
||||||
|
sut.register_handler('TESTS_ARE_COOL_EVENT', handler)
|
||||||
|
sut.dispatch(event, 'account', 'data')
|
||||||
|
self.assertTrue(self.called, msg="Handler should have been called")
|
||||||
|
|
||||||
|
self.called = False
|
||||||
|
sut.unregister_handler('TESTS_ARE_COOL_EVENT', handler)
|
||||||
|
sut.dispatch(event, 'account', 'data')
|
||||||
|
self.assertFalse(self.called, msg="Handler should no longer be called")
|
||||||
|
|
||||||
|
|
||||||
|
def test_dispatch_to_multiple_handlers(self):
|
||||||
|
''' Register and dispatch a single event to multiple handlers '''
|
||||||
|
sut = Interface()
|
||||||
|
event = 'SINGLE_EVENT'
|
||||||
|
|
||||||
|
self.called_a = False
|
||||||
|
self.called_b = False
|
||||||
|
|
||||||
|
def handler_a(account, data):
|
||||||
|
self.assertFalse(self.called_a, msg="One must only be notified once")
|
||||||
|
self.called_a = True
|
||||||
|
|
||||||
|
def handler_b(account, data):
|
||||||
|
self.assertFalse(self.called_b, msg="One must only be notified once")
|
||||||
|
self.called_b = True
|
||||||
|
|
||||||
|
sut.register_handler(event, handler_a)
|
||||||
|
sut.register_handler(event, handler_b)
|
||||||
|
|
||||||
|
# register again
|
||||||
|
sut.register_handler('SOME_OTHER_EVENT', handler_b)
|
||||||
|
sut.register_handler(event, handler_a)
|
||||||
|
|
||||||
|
sut.dispatch(event, 'account', 'data')
|
||||||
|
self.assertTrue(self.called_a and self.called_b,
|
||||||
|
msg="Both handlers should have been called")
|
||||||
|
|
||||||
|
def test_links_regexp_entire(self):
|
||||||
|
sut = Interface()
|
||||||
|
def assert_matches_all(str_):
|
||||||
|
m = sut.basic_pattern_re.match(str_)
|
||||||
|
|
||||||
|
# the match should equal the string
|
||||||
|
str_span = (0, len(str_))
|
||||||
|
self.assertEqual(m.span(), str_span)
|
||||||
|
|
||||||
|
# these entire strings should be parsed as links
|
||||||
|
assert_matches_all('http://google.com/')
|
||||||
|
assert_matches_all('http://google.com')
|
||||||
|
assert_matches_all('http://www.google.ca/search?q=xmpp')
|
||||||
|
|
||||||
|
assert_matches_all('http://tools.ietf.org/html/draft-saintandre-rfc3920bis-05#section-12.3')
|
||||||
|
|
||||||
|
assert_matches_all('http://en.wikipedia.org/wiki/Protocol_(computing)')
|
||||||
|
assert_matches_all(
|
||||||
|
'http://en.wikipedia.org/wiki/Protocol_%28computing%29')
|
||||||
|
|
||||||
|
assert_matches_all('mailto:test@example.org')
|
||||||
|
|
||||||
|
assert_matches_all('xmpp:example-node@example.com')
|
||||||
|
assert_matches_all('xmpp:example-node@example.com/some-resource')
|
||||||
|
assert_matches_all('xmpp:example-node@example.com?message')
|
||||||
|
assert_matches_all('xmpp://guest@example.com/support@example.com?message')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
#import sys;sys.argv = ['', 'Test.test']
|
||||||
|
unittest.main()
|
|
@ -5,19 +5,27 @@ import time
|
||||||
import lib
|
import lib
|
||||||
lib.setup_env()
|
lib.setup_env()
|
||||||
|
|
||||||
|
|
||||||
|
import notify
|
||||||
|
|
||||||
from common import gajim
|
from common import gajim
|
||||||
from common import xmpp
|
from common import xmpp
|
||||||
|
|
||||||
|
from common.stanza_session import StanzaSession
|
||||||
|
from session import ChatControlSession
|
||||||
|
|
||||||
from mock import Mock, expectParams
|
from mock import Mock, expectParams
|
||||||
from gajim_mocks import *
|
from gajim_mocks import *
|
||||||
|
|
||||||
from common.stanza_session import StanzaSession
|
gajim.interface = MockInterface()
|
||||||
|
|
||||||
|
|
||||||
# name to use for the test account
|
# name to use for the test account
|
||||||
account_name = 'test'
|
account_name = 'test'
|
||||||
|
|
||||||
class TestStanzaSession(unittest.TestCase):
|
class TestStanzaSession(unittest.TestCase):
|
||||||
''' Testclass for common/stanzasession.py '''
|
''' Testclass for common/stanzasession.py '''
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.jid = 'test@example.org/Gajim'
|
self.jid = 'test@example.org/Gajim'
|
||||||
self.conn = MockConnection(account_name, {'send_stanza': None})
|
self.conn = MockConnection(account_name, {'send_stanza': None})
|
||||||
|
@ -68,14 +76,10 @@ class TestStanzaSession(unittest.TestCase):
|
||||||
calls = self.conn.mockGetNamedCalls('send_stanza')
|
calls = self.conn.mockGetNamedCalls('send_stanza')
|
||||||
self.assertEqual(0, len(calls))
|
self.assertEqual(0, len(calls))
|
||||||
|
|
||||||
from session import ChatControlSession
|
|
||||||
|
|
||||||
gajim.interface = MockInterface()
|
|
||||||
|
|
||||||
import notify
|
|
||||||
|
|
||||||
class TestChatControlSession(unittest.TestCase):
|
class TestChatControlSession(unittest.TestCase):
|
||||||
''' Testclass for session.py '''
|
''' Testclass for session.py '''
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.jid = 'test@example.org/Gajim'
|
self.jid = 'test@example.org/Gajim'
|
||||||
self.conn = MockConnection(account_name, {'send_stanza': None})
|
self.conn = MockConnection(account_name, {'send_stanza': None})
|
|
@ -0,0 +1,80 @@
|
||||||
|
'''
|
||||||
|
Unit test for tranports classes.
|
||||||
|
'''
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
import lib
|
||||||
|
lib.setup_env()
|
||||||
|
|
||||||
|
from common.xmpp import transports_nb
|
||||||
|
|
||||||
|
|
||||||
|
class TestModuleLevelFunctions(unittest.TestCase):
|
||||||
|
'''
|
||||||
|
Test class for functions defined at module level
|
||||||
|
'''
|
||||||
|
def test_urisplit(self):
|
||||||
|
def check_uri(uri, proto, host, port, path):
|
||||||
|
_proto, _host, _port, _path = transports_nb.urisplit(uri)
|
||||||
|
self.assertEqual(proto, _proto)
|
||||||
|
self.assertEqual(host, _host)
|
||||||
|
self.assertEqual(path, _path)
|
||||||
|
self.assertEqual(port, _port)
|
||||||
|
|
||||||
|
check_uri('http://httpcm.jabber.org:5280/webclient', proto='http',
|
||||||
|
host='httpcm.jabber.org', port=5280, path='/webclient')
|
||||||
|
|
||||||
|
check_uri('http://httpcm.jabber.org/webclient', proto='http',
|
||||||
|
host='httpcm.jabber.org', port=80, path='/webclient')
|
||||||
|
|
||||||
|
check_uri('https://httpcm.jabber.org/webclient', proto='https',
|
||||||
|
host='httpcm.jabber.org', port=443, path='/webclient')
|
||||||
|
|
||||||
|
def test_get_proxy_data_from_dict(self):
|
||||||
|
def check_dict(proxy_dict, host, port, user, passwd):
|
||||||
|
_host, _port, _user, _passwd = transports_nb.get_proxy_data_from_dict(
|
||||||
|
proxy_dict)
|
||||||
|
self.assertEqual(_host, host)
|
||||||
|
self.assertEqual(_port, port)
|
||||||
|
self.assertEqual(_user, user)
|
||||||
|
self.assertEqual(_passwd, passwd)
|
||||||
|
|
||||||
|
bosh_dict = {'bosh_content': u'text/xml; charset=utf-8',
|
||||||
|
'bosh_hold': 2,
|
||||||
|
'bosh_http_pipelining': False,
|
||||||
|
'bosh_uri': u'http://gajim.org:5280/http-bind',
|
||||||
|
'bosh_useproxy': False,
|
||||||
|
'bosh_wait': 30,
|
||||||
|
'bosh_wait_for_restart_response': False,
|
||||||
|
'host': u'172.16.99.11',
|
||||||
|
'pass': u'pass',
|
||||||
|
'port': 3128,
|
||||||
|
'type': u'bosh',
|
||||||
|
'useauth': True,
|
||||||
|
'user': u'user'}
|
||||||
|
check_dict(bosh_dict, host=u'gajim.org', port=5280, user=u'user',
|
||||||
|
passwd=u'pass')
|
||||||
|
|
||||||
|
proxy_dict = {'bosh_content': u'text/xml; charset=utf-8',
|
||||||
|
'bosh_hold': 2,
|
||||||
|
'bosh_http_pipelining': False,
|
||||||
|
'bosh_port': 5280,
|
||||||
|
'bosh_uri': u'',
|
||||||
|
'bosh_useproxy': True,
|
||||||
|
'bosh_wait': 30,
|
||||||
|
'bosh_wait_for_restart_response': False,
|
||||||
|
'host': u'172.16.99.11',
|
||||||
|
'pass': u'pass',
|
||||||
|
'port': 3128,
|
||||||
|
'type': 'socks5',
|
||||||
|
'useauth': True,
|
||||||
|
'user': u'user'}
|
||||||
|
check_dict(proxy_dict, host=u'172.16.99.11', port=3128, user=u'user',
|
||||||
|
passwd=u'pass')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
|
|
||||||
|
# vim: se ts=3:
|