diff options
-rw-r--r-- | protocols/skype/HACKING | 44 | ||||
-rw-r--r-- | protocols/skype/skype.c | 49 | ||||
-rw-r--r-- | protocols/skype/skyped.py | 210 | ||||
-rw-r--r-- | protocols/skype/skyped.txt | 3 | ||||
-rw-r--r-- | protocols/skype/t/add-yes-bitlbee.mock | 3 | ||||
-rw-r--r-- | protocols/skype/t/add-yes-skyped.mock | 12 | ||||
-rw-r--r-- | protocols/skype/t/added-no-bitlbee.mock (renamed from protocols/skype/t/add-no-bitlbee.mock) | 0 | ||||
-rw-r--r-- | protocols/skype/t/added-no-skyped.mock (renamed from protocols/skype/t/add-no-skyped.mock) | 0 | ||||
-rw-r--r-- | protocols/skype/t/added-yes-bitlbee.mock | 9 | ||||
-rw-r--r-- | protocols/skype/t/added-yes-skyped.mock | 23 | ||||
-rw-r--r-- | protocols/skype/t/ctcp-help-bitlbee.mock | 9 | ||||
-rw-r--r-- | protocols/skype/t/ctcp-help-skyped.mock | 12 | ||||
-rw-r--r-- | protocols/skype/t/set-mood-text-bitlbee.mock | 9 | ||||
-rw-r--r-- | protocols/skype/t/set-mood-text-skyped.mock | 12 | ||||
-rwxr-xr-x | protocols/skype/test.py | 126 | ||||
-rw-r--r-- | protocols/twitter/twitter.c | 8 |
16 files changed, 321 insertions, 208 deletions
diff --git a/protocols/skype/HACKING b/protocols/skype/HACKING index a6ff8290..935856a7 100644 --- a/protocols/skype/HACKING +++ b/protocols/skype/HACKING @@ -17,10 +17,50 @@ python skyped.py -n -d 4) irssi + == Tests -The plugin is tested with a mocked IRC client and a mocked skyped. To add a new -test, the following steps are necessary: +The plugin is tested with a mocked IRC client and a mocked skyped. + +=== Requirements + +Python pexpect module is required to run the tests. + +To run tests with bitlbee built in a development tree and not (the one) +installed in the system (e.g. /usr), make sure to specify --plugindir= option to +./configure script during the build process: + +bitlbee% ./configure --skype=1 --plugindir="$(realpath .)" + +Otherwise bitlbee will try to load skype.so (among other things) from /usr/lib, +which is probably not what you want to test, or produce "Unknown protocol" +error. + +=== Running + +Tests can be run by running test.py script in this ("protocols/skype") +directory. + +For more control over how/which tests are being run from there, use "python -m +unittest" command: + +bitlbee/protocols/skype% python -m unittest test +bitlbee/protocols/skype% python -m unittest -f test +bitlbee/protocols/skype% python -m unittest test.Test.testMsg + +If bitlbee crashes during tests with SIGSEGV (segmentation fault), it's likely +that there is some problem with skype.c plugin. +To get a backtrace of such crash, use: + +bitlbee/protocols/skype% ATTACH_GDB=true python -m unittest test.Test.testMsg + +Example shows running "testMsg" test with gdb attached to bitlbee, which will +produce full backtrace in "t/gdb-<pid>.log" files (see pid in pexpect error +output of the test). + +=== Adding new tests + +To add a new test, the following steps are necessary: 1) Add a new -skyped.mock file: just do the test manually, copy&paste the skyped output and clean it up, so Alice talks to Bob. You can test the created diff --git a/protocols/skype/skype.c b/protocols/skype/skype.c index b3d29dab..4ae34668 100644 --- a/protocols/skype/skype.c +++ b/protocols/skype/skype.c @@ -28,7 +28,7 @@ #define SKYPE_DEFAULT_SERVER "localhost" #define SKYPE_DEFAULT_PORT "2727" -#define IRC_LINE_SIZE 1024 +#define IRC_LINE_SIZE 16384 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) /* @@ -193,7 +193,7 @@ int skype_printf(struct im_connection *ic, char *fmt, ...) static void skype_buddy_ask_yes(void *data) { struct skype_buddy_ask_data *bla = data; - skype_printf(bla->ic, "SET USER %s ISAUTHORIZED TRUE", + skype_printf(bla->ic, "SET USER %s ISAUTHORIZED TRUE\n", bla->handle); g_free(bla->handle); g_free(bla); @@ -202,7 +202,7 @@ static void skype_buddy_ask_yes(void *data) static void skype_buddy_ask_no(void *data) { struct skype_buddy_ask_data *bla = data; - skype_printf(bla->ic, "SET USER %s ISAUTHORIZED FALSE", + skype_printf(bla->ic, "SET USER %s ISAUTHORIZED FALSE\n", bla->handle); g_free(bla->handle); g_free(bla); @@ -225,7 +225,7 @@ void skype_buddy_ask(struct im_connection *ic, char *handle, char *message) static void skype_call_ask_yes(void *data) { struct skype_buddy_ask_data *bla = data; - skype_printf(bla->ic, "SET CALL %s STATUS INPROGRESS", + skype_printf(bla->ic, "SET CALL %s STATUS INPROGRESS\n", bla->handle); g_free(bla->handle); g_free(bla); @@ -234,7 +234,7 @@ static void skype_call_ask_yes(void *data) static void skype_call_ask_no(void *data) { struct skype_buddy_ask_data *bla = data; - skype_printf(bla->ic, "SET CALL %s STATUS FINISHED", + skype_printf(bla->ic, "SET CALL %s STATUS FINISHED\n", bla->handle); g_free(bla->handle); g_free(bla); @@ -917,7 +917,7 @@ static void skype_parse_group(struct im_connection *ic, char *line) if (!sd->pending_user) { /* Number of users changed in this group, query its type to see * if it's a custom one we should care about. */ - skype_printf(ic, "GET GROUP %s TYPE", id); + skype_printf(ic, "GET GROUP %s TYPE\n", id); return; } @@ -926,7 +926,7 @@ static void skype_parse_group(struct im_connection *ic, char *line) struct skype_group *sg = skype_group_by_id(ic, atoi(id)); if (sg) { - skype_printf(ic, "ALTER GROUP %d ADDUSER %s", sg->id, sd->pending_user); + skype_printf(ic, "ALTER GROUP %d ADDUSER %s\n", sg->id, sd->pending_user); g_free(sd->pending_user); sd->pending_user = NULL; } else @@ -934,7 +934,7 @@ static void skype_parse_group(struct im_connection *ic, char *line) "No skype group with id %s. That's probably a bug.", id); } else if (!strcmp(info, "TYPE CUSTOM_GROUP")) /* This one is interesting, query its users. */ - skype_printf(ic, "GET GROUP %s USERS", id); + skype_printf(ic, "GET GROUP %s USERS\n", id); } static void skype_parse_chat(struct im_connection *ic, char *line) @@ -1146,6 +1146,13 @@ static gboolean skype_read_callback(gpointer data, gint fd, return FALSE; /* Read the whole data. */ st = ssl_read(sd->ssl, buf, sizeof(buf)); + if (st >= IRC_LINE_SIZE-1) { + /* As we don't buffer incoming data, if IRC_LINE_SIZE amount of bytes + * were received, there's a good chance last message was truncated + * and the next recv() will yield garbage. */ + imcb_error(ic, "Unable to handle incoming data from skyped"); + st = 0; + } if (st > 0) { buf[st] = '\0'; /* Then split it up to lines. */ @@ -1337,7 +1344,7 @@ static char *skype_set_display_name(set_t *set, char *value) account_t *acc = set->data; struct im_connection *ic = acc->ic; - skype_printf(ic, "SET PROFILE FULLNAME %s", value); + skype_printf(ic, "SET PROFILE FULLNAME %s\n", value); return value; } @@ -1346,7 +1353,7 @@ static char *skype_set_mood_text(set_t *set, char *value) account_t *acc = set->data; struct im_connection *ic = acc->ic; - skype_printf(ic, "SET PROFILE MOOD_TEXT %s", value); + skype_printf(ic, "SET PROFILE MOOD_TEXT %s\n", value); return value; } @@ -1355,7 +1362,7 @@ static char *skype_set_balance(set_t *set, char *value) account_t *acc = set->data; struct im_connection *ic = acc->ic; - skype_printf(ic, "GET PROFILE PSTN_BALANCE"); + skype_printf(ic, "GET PROFILE PSTN_BALANCE\n"); return value; } @@ -1366,7 +1373,7 @@ static void skype_call(struct im_connection *ic, char *value) if (ptr) *ptr = '\0'; - skype_printf(ic, "CALL %s", nick); + skype_printf(ic, "CALL %s\n", nick); g_free(nick); } @@ -1375,7 +1382,7 @@ static void skype_hangup(struct im_connection *ic) struct skype_data *sd = ic->proto_data; if (sd->call_id) { - skype_printf(ic, "SET CALL %s STATUS FINISHED", + skype_printf(ic, "SET CALL %s STATUS FINISHED\n", sd->call_id); g_free(sd->call_id); sd->call_id = 0; @@ -1415,10 +1422,10 @@ static void skype_add_buddy(struct im_connection *ic, char *who, char *group) if (!sg) { /* No such group, we need to create it, then have to * add the user once it's created. */ - skype_printf(ic, "CREATE GROUP %s", group); + skype_printf(ic, "CREATE GROUP %s\n", group); sd->pending_user = g_strdup(nick); } else { - skype_printf(ic, "ALTER GROUP %d ADDUSER %s", sg->id, nick); + skype_printf(ic, "ALTER GROUP %d ADDUSER %s\n", sg->id, nick); } } } @@ -1522,11 +1529,6 @@ static void skype_get_info(struct im_connection *ic, char *who) skype_printf(ic, "GET USER %s BIRTHDAY\n", nick); } -static void skype_set_my_name(struct im_connection *ic, char *info) -{ - skype_set_display_name(set_find(&ic->acc->set, "display_name"), info); -} - static void skype_init(account_t *acc) { set_t *s; @@ -1583,12 +1585,14 @@ GList *skype_buddy_action_list(bee_user_t *bu) bu = bu; if (ret == NULL) { - static const struct buddy_action ba[3] = { + static const struct buddy_action ba[2] = { {"CALL", "Initiate a call" }, {"HANGUP", "Hang up a call" }, }; + int i; - ret = g_list_prepend(ret, (void *) ba + 0); + for (i = 0; i < ARRAY_SIZE(ba); i++) + ret = g_list_prepend(ret, (void *)(ba + i)); } return ret; @@ -1619,7 +1623,6 @@ void init_plugin(void) ret->logout = skype_logout; ret->buddy_msg = skype_buddy_msg; ret->get_info = skype_get_info; - ret->set_my_name = skype_set_my_name; ret->away_states = skype_away_states; ret->set_away = skype_set_away; ret->add_buddy = skype_add_buddy; diff --git a/protocols/skype/skyped.py b/protocols/skype/skyped.py index f1777d0b..cb57b7ec 100644 --- a/protocols/skype/skyped.py +++ b/protocols/skype/skyped.py @@ -1,32 +1,30 @@ #!/usr/bin/env python2.7 -# +# # skyped.py -# +# # Copyright (c) 2007-2013 by Miklos Vajna <vmiklos@vmiklos.hu> # # 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 # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. -# +# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -# +# # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, # USA. # import sys import os import signal -import locale import time import socket -import getopt import Skype4Py import hashlib from ConfigParser import ConfigParser, NoOptionError @@ -53,11 +51,12 @@ def eh(type, value, tb): gobject.MainLoop().quit() if options.conn: options.conn.close() - # shut down client if it's running - try: - skype.skype.Client.Shutdown() - except NameError: - pass + if not options.dont_start_skype: + # shut down client if it's running + try: + skype.skype.Client.Shutdown() + except NameError: + pass sys.exit("Exiting.") sys.excepthook = eh @@ -124,35 +123,30 @@ def skype_idle_handler(skype): time.sleep(1) return True -def send(sock, txt): +def send(sock, txt, tries=10): global options - from time import sleep - count = 1 - done = False if hasgobject: - while (not done) and (count < 10): - try: - sock.send(txt) - done = True - except Exception, s: - count += 1 - dprint("Warning, sending '%s' failed (%s). count=%d" % (txt, s, count)) - sleep(1) - if not done: + if not options.conn: return + try: + sock.sendall(txt) + except socket.error as s: + dprint("Warning, sending '%s' failed (%s)." % (txt, s)) options.conn.close() + options.conn = False else: - while (not done) and (count < 10) and options.conn: + for attempt in xrange(1, tries+1): + if not options.conn: break if wait_for_lock(options.lock, 3, 10, "socket send"): try: - if options.conn: sock.send(txt) + if options.conn: sock.sendall(txt) options.lock.release() - done = True - except Exception, s: + except socket.error as s: options.lock.release() - count += 1 dprint("Warning, sending '%s' failed (%s). count=%d" % (txt, s, count)) - sleep(1) - if not done: + time.sleep(1) + else: + break + else: if options.conn: options.conn.close() options.conn = False @@ -207,9 +201,13 @@ def listener(sock, skype): certfile=options.config.sslcert, keyfile=options.config.sslkey, ssl_version=ssl.PROTOCOL_TLSv1) - except ssl.SSLError: - dprint("Warning, SSL init failed, did you create your certificate?") - return False + except (ssl.SSLError, socket.error) as err: + if isinstance(err, ssl.SSLError): + dprint("Warning, SSL init failed, did you create your certificate?") + return False + else: + dprint('Warning, SSL init failed') + return True if hasattr(options.conn, 'handshake'): try: options.conn.handshake() @@ -280,7 +278,7 @@ class MockedSkype: def __init__(self, mock): sock = open(mock) self.lines = sock.readlines() - + def SendCommand(self, c): pass @@ -309,10 +307,12 @@ class MockedSkype: class SkypeApi: def __init__(self, mock): + global options if not mock: self.skype = Skype4Py.Skype() self.skype.OnNotify = self.recv - self.skype.Client.Start() + if not options.dont_start_skype: + self.skype.Client.Start() else: self.skype = MockedSkype(mock) @@ -379,43 +379,6 @@ class SkypeApi: except Skype4Py.SkypeAPIError, s: dprint("Warning, sending '%s' failed (%s)." % (e, s)) -class Options: - def __init__(self): - self.cfgpath = os.path.join(os.environ['HOME'], ".skyped", "skyped.conf") - # fall back to system-wide settings - self.syscfgpath = "/usr/local/etc/skyped/skyped.conf" - if os.path.exists(self.syscfgpath) and not os.path.exists(self.cfgpath): - self.cfgpath = self.syscfgpath - self.daemon = True - self.debug = False - self.help = False - self.host = "0.0.0.0" - self.log = None - self.port = None - self.version = False - # well, this is a bit hackish. we store the socket of the last connected client - # here and notify it. maybe later notify all connected clients? - self.conn = None - # this will be read first by the input handler - self.buf = None - self.mock = None - - - def usage(self, ret): - print """Usage: skyped [OPTION]... - -skyped is a daemon that acts as a tcp server on top of a Skype instance. - -Options: - -c --config path to configuration file (default: %s) - -d --debug enable debug messages - -h --help this help - -H --host set the tcp host, supports IPv4 and IPv6 (default: %s) - -l --log set the log file in background mode (default: none) - -n --nofork don't run as daemon in the background - -p --port set the tcp port (default: %s) - -v --version display version information""" % (self.cfgpath, self.host, self.port) - sys.exit(ret) def serverloop(options, skype): timeout = 1; # in seconds @@ -458,60 +421,72 @@ def serverloop(options, skype): else: options.last_bitlbee_pong = now -if __name__=='__main__': - options = Options() - try: - opts, args = getopt.getopt(sys.argv[1:], "c:dhH:l:m:np:v", ["config=", "debug", "help", "host=", "log=", "mock=", "nofork", "port=", "version"]) - except getopt.GetoptError: - options.usage(1) - for opt, arg in opts: - if opt in ("-c", "--config"): - options.cfgpath = arg - elif opt in ("-d", "--debug"): - options.debug = True - elif opt in ("-h", "--help"): - options.help = True - elif opt in ("-H", "--host"): - options.host = arg - elif opt in ("-l", "--log"): - options.log = arg - elif opt in ("-m", "--mock"): - options.mock = arg - elif opt in ("-n", "--nofork"): - options.daemon = False - elif opt in ("-p", "--port"): - options.port = int(arg) - elif opt in ("-v", "--version"): - options.version = True - if options.help: - options.usage(0) - elif options.version: + +def main(args=None): + global options + global skype + + cfgpath = os.path.join(os.environ['HOME'], ".skyped", "skyped.conf") + syscfgpath = "/usr/local/etc/skyped/skyped.conf" + if not os.path.exists(cfgpath) and os.path.exists(syscfgpath): + cfgpath = syscfgpath # fall back to system-wide settings + port = 2727 + + import argparse + parser = argparse.ArgumentParser() + parser.add_argument('-c', '--config', + metavar='path', default=cfgpath, + help='path to configuration file (default: %(default)s)') + parser.add_argument('-H', '--host', default='0.0.0.0', + help='set the tcp host, supports IPv4 and IPv6 (default: %(default)s)') + parser.add_argument('-p', '--port', type=int, + help='set the tcp port (default: %(default)s)') + parser.add_argument('-l', '--log', metavar='path', + help='set the log file in background mode (default: none)') + parser.add_argument('-v', '--version', action='store_true', help='display version information') + parser.add_argument('-n', '--nofork', + action='store_true', help="don't run as daemon in the background") + parser.add_argument('-s', '--dont-start-skype', action='store_true', + help="assume that skype is running independently, don't try to start/stop it") + parser.add_argument('-m', '--mock', help='fake interactions with skype (only useful for tests)') + parser.add_argument('-d', '--debug', action='store_true', help='enable debug messages') + options = parser.parse_args(sys.argv[1:] if args is None else args) + + if options.version: print "skyped %s" % __version__ sys.exit(0) - # parse our config - if not os.path.exists(options.cfgpath): - print "Can't find configuration file at '%s'." % options.cfgpath - print "Use the -c option to specify an alternate one." - sys.exit(1) + + # well, this is a bit hackish. we store the socket of the last connected client + # here and notify it. maybe later notify all connected clients? + options.conn = None + # this will be read first by the input handler + options.buf = None + + if not os.path.exists(options.config): + parser.error(( "Can't find configuration file at '%s'." + "Use the -c option to specify an alternate one." )% options.config) + + cfgpath = options.config options.config = ConfigParser() - options.config.read(options.cfgpath) - options.config.username = options.config.get('skyped', 'username').split('#')[0] - options.config.password = options.config.get('skyped', 'password').split('#')[0] - options.config.sslkey = os.path.expanduser(options.config.get('skyped', 'key').split('#')[0]) - options.config.sslcert = os.path.expanduser(options.config.get('skyped', 'cert').split('#')[0]) + options.config.read(cfgpath) + options.config.username = options.config.get('skyped', 'username').split('#', 1)[0] + options.config.password = options.config.get('skyped', 'password').split('#', 1)[0] + options.config.sslkey = os.path.expanduser(options.config.get('skyped', 'key').split('#', 1)[0]) + options.config.sslcert = os.path.expanduser(options.config.get('skyped', 'cert').split('#', 1)[0]) + # hack: we have to parse the parameters first to locate the # config file but the -p option should overwrite the value from # the config file try: - options.config.port = int(options.config.get('skyped', 'port').split('#')[0]) + options.config.port = int(options.config.get('skyped', 'port').split('#', 1)[0]) if not options.port: options.port = options.config.port except NoOptionError: pass if not options.port: - options.port = 2727 - dprint("Parsing config file '%s' done, username is '%s'." % (options.cfgpath, options.config.username)) - if options.daemon: + options.port = port + dprint("Parsing config file '%s' done, username is '%s'." % (cfgpath, options.config.username)) + if not options.nofork: pid = os.fork() if pid == 0: nullin = file(os.devnull, 'r') @@ -539,3 +514,6 @@ if __name__=='__main__': options.conn = False options.lock = threading.Lock() server(options.host, options.port, skype) + + +if __name__ == '__main__': main() diff --git a/protocols/skype/skyped.txt b/protocols/skype/skyped.txt index 0f11f093..c5f9abb9 100644 --- a/protocols/skype/skyped.txt +++ b/protocols/skype/skyped.txt @@ -74,6 +74,9 @@ in `skyped.conf`. -n, --nofork:: Don't run as daemon in the background +-s, --dont-start-skype:: + Assume that skype is running independently, don't try to start/stop it. + -p, --port:: Set the tcp port (default: 2727) diff --git a/protocols/skype/t/add-yes-bitlbee.mock b/protocols/skype/t/add-yes-bitlbee.mock index df068f89..5f17fd33 100644 --- a/protocols/skype/t/add-yes-bitlbee.mock +++ b/protocols/skype/t/add-yes-bitlbee.mock @@ -4,6 +4,5 @@ >> PRIVMSG &bitlbee << PRIVMSG &bitlbee :account add skype alice foo << PRIVMSG &bitlbee :account skype on ->> PRIVMSG &bitlbee :skype - New request: The user bob wants to add you -<< PRIVMSG &bitlbee :yes +<< PRIVMSG &bitlbee :add skype bob >> :bob!bob@skype.com JOIN :&bitlbee diff --git a/protocols/skype/t/add-yes-skyped.mock b/protocols/skype/t/add-yes-skyped.mock index e22beb97..eed257e5 100644 --- a/protocols/skype/t/add-yes-skyped.mock +++ b/protocols/skype/t/add-yes-skyped.mock @@ -8,16 +8,14 @@ << USERSTATUS ONLINE >> GET USER echo123 ONLINESTATUS << USER echo123 ONLINESTATUS ONLINE -<< USER bob RECEIVEDAUTHREQUEST Please allow me to see when you are online ->> SET USER bob ISAUTHORIZED TRUE -<< USER bob ISAUTHORIZED TRUE -<< USER bob RECEIVEDAUTHREQUEST +>> SET USER bob BUDDYSTATUS 2 Please authorize me +<< USER bob BUDDYSTATUS 2 << USER bob ISAUTHORIZED TRUE << USER bob ISBLOCKED FALSE +<< USER bob BUDDYSTATUS 2 +<< USER bob ONLINESTATUS OFFLINE +<< USER bob FULLNAME skype test203 << USER bob BUDDYSTATUS 3 << USER bob ONLINESTATUS OFFLINE << USER bob ONLINESTATUS ONLINE << USER bob TIMEZONE 90000 -<< USER bob FULLNAME Miklos V -<< USER bob LANGUAGE hu Hungarian -<< USER bob COUNTRY hu Hungary diff --git a/protocols/skype/t/add-no-bitlbee.mock b/protocols/skype/t/added-no-bitlbee.mock index d7a70c66..d7a70c66 100644 --- a/protocols/skype/t/add-no-bitlbee.mock +++ b/protocols/skype/t/added-no-bitlbee.mock diff --git a/protocols/skype/t/add-no-skyped.mock b/protocols/skype/t/added-no-skyped.mock index f7283cbc..f7283cbc 100644 --- a/protocols/skype/t/add-no-skyped.mock +++ b/protocols/skype/t/added-no-skyped.mock diff --git a/protocols/skype/t/added-yes-bitlbee.mock b/protocols/skype/t/added-yes-bitlbee.mock new file mode 100644 index 00000000..df068f89 --- /dev/null +++ b/protocols/skype/t/added-yes-bitlbee.mock @@ -0,0 +1,9 @@ +>> NOTICE AUTH +<< NICK alice +<< USER alice alice localhost :Alice +>> PRIVMSG &bitlbee +<< PRIVMSG &bitlbee :account add skype alice foo +<< PRIVMSG &bitlbee :account skype on +>> PRIVMSG &bitlbee :skype - New request: The user bob wants to add you +<< PRIVMSG &bitlbee :yes +>> :bob!bob@skype.com JOIN :&bitlbee diff --git a/protocols/skype/t/added-yes-skyped.mock b/protocols/skype/t/added-yes-skyped.mock new file mode 100644 index 00000000..e22beb97 --- /dev/null +++ b/protocols/skype/t/added-yes-skyped.mock @@ -0,0 +1,23 @@ +>> SEARCH GROUPS CUSTOM +<< GROUPS 48, 49 +>> SEARCH FRIENDS +<< USERS echo123 +>> SET USERSTATUS ONLINE +<< USERSTATUS ONLINE +>> SET USERSTATUS ONLINE +<< USERSTATUS ONLINE +>> GET USER echo123 ONLINESTATUS +<< USER echo123 ONLINESTATUS ONLINE +<< USER bob RECEIVEDAUTHREQUEST Please allow me to see when you are online +>> SET USER bob ISAUTHORIZED TRUE +<< USER bob ISAUTHORIZED TRUE +<< USER bob RECEIVEDAUTHREQUEST +<< USER bob ISAUTHORIZED TRUE +<< USER bob ISBLOCKED FALSE +<< USER bob BUDDYSTATUS 3 +<< USER bob ONLINESTATUS OFFLINE +<< USER bob ONLINESTATUS ONLINE +<< USER bob TIMEZONE 90000 +<< USER bob FULLNAME Miklos V +<< USER bob LANGUAGE hu Hungarian +<< USER bob COUNTRY hu Hungary diff --git a/protocols/skype/t/ctcp-help-bitlbee.mock b/protocols/skype/t/ctcp-help-bitlbee.mock new file mode 100644 index 00000000..98522ec1 --- /dev/null +++ b/protocols/skype/t/ctcp-help-bitlbee.mock @@ -0,0 +1,9 @@ +>> NOTICE AUTH +<< NICK alice +<< USER alice alice localhost :Alice +>> PRIVMSG &bitlbee +<< PRIVMSG &bitlbee :account add skype alice foo +<< PRIVMSG &bitlbee :account skype on +>> :bob!bob@skype.com JOIN :&bitlbee +<< PRIVMSG bob :HELP +>> :bob!bob@skype.com NOTICE alice :HELP Supported CTCPs: HANGUP (Hang up a call), CALL (Initiate a call) diff --git a/protocols/skype/t/ctcp-help-skyped.mock b/protocols/skype/t/ctcp-help-skyped.mock new file mode 100644 index 00000000..322c7c6b --- /dev/null +++ b/protocols/skype/t/ctcp-help-skyped.mock @@ -0,0 +1,12 @@ +>> SEARCH GROUPS CUSTOM +<< GROUPS 48, 49 +>> SEARCH FRIENDS +<< USERS echo123, bob +>> SET USERSTATUS ONLINE +<< USERSTATUS ONLINE +>> SET USERSTATUS ONLINE +<< USERSTATUS ONLINE +>> GET USER echo123 ONLINESTATUS +<< USER echo123 ONLINESTATUS ONLINE +>> GET USER bob ONLINESTATUS +<< USER bob ONLINESTATUS ONLINE diff --git a/protocols/skype/t/set-mood-text-bitlbee.mock b/protocols/skype/t/set-mood-text-bitlbee.mock new file mode 100644 index 00000000..f017f8bd --- /dev/null +++ b/protocols/skype/t/set-mood-text-bitlbee.mock @@ -0,0 +1,9 @@ +>> NOTICE AUTH +<< NICK alice +<< USER alice alice localhost :Alice +>> PRIVMSG &bitlbee +<< PRIVMSG &bitlbee :account add skype alice foo +<< PRIVMSG &bitlbee :account skype set skypeconsole_receive true +<< PRIVMSG &bitlbee :account skype on +<< PRIVMSG &bitlbee :account skype set mood_text "foo bar" +>> PRIVMSG &bitlbee :alice: PROFILE MOOD_TEXT foo bar diff --git a/protocols/skype/t/set-mood-text-skyped.mock b/protocols/skype/t/set-mood-text-skyped.mock new file mode 100644 index 00000000..f2814248 --- /dev/null +++ b/protocols/skype/t/set-mood-text-skyped.mock @@ -0,0 +1,12 @@ +>> SEARCH GROUPS CUSTOM +<< GROUPS 48, 49 +>> SEARCH FRIENDS +<< USERS echo123 +>> SET USERSTATUS ONLINE +<< USERSTATUS ONLINE +>> SET USERSTATUS ONLINE +<< USERSTATUS ONLINE +>> GET USER echo123 ONLINESTATUS +<< USER echo123 ONLINESTATUS ONLINE +>> SET PROFILE MOOD_TEXT foo bar +<< PROFILE MOOD_TEXT foo bar diff --git a/protocols/skype/test.py b/protocols/skype/test.py index 9f4c13ce..632ae124 100755 --- a/protocols/skype/test.py +++ b/protocols/skype/test.py @@ -8,51 +8,24 @@ import shutil import os import hashlib -class Test(unittest.TestCase): - def openssl(self, args): - with open(os.devnull, "w") as devnull: - proc = subprocess.Popen(['openssl'] + args, stdin=subprocess.PIPE, stderr=devnull) - for i in range(6): - proc.stdin.write("\n") - proc.stdin.close() - proc.communicate() - def mock(self, name): - skyped_log = open("t/skyped.log", "w") - skyped = subprocess.Popen([sys.executable, "skyped.py", "-c", "t/skyped/skyped.conf", "-n", "-d", "-m", "t/%s-skyped.mock" % name], - stdout=skyped_log, stderr=subprocess.STDOUT) - - try: - bitlbee = pexpect.spawn('../../bitlbee', ['-d', 't/bitlbee']) - bitlbee_mock = open("t/%s-bitlbee.mock" % name) - for i in bitlbee_mock.readlines(): - line = i.strip() - if line.startswith(">> "): - bitlbee.expect_exact(line[3:], timeout=10) - elif line.startswith("<< "): - bitlbee.sendline(line[3:]) - bitlbee_mock.close() - bitlbee.close() - finally: - skyped.terminate() - skyped.communicate() - skyped_log.close() - - def setUp(self): - try: - shutil.rmtree("t/bitlbee") - except OSError: - pass - os.makedirs("t/bitlbee") - - try: - shutil.rmtree("t/skyped") - except OSError: - pass - os.makedirs("t/skyped") - cwd = os.getcwd() - os.chdir("t/skyped") +def openssl(args): + with open(os.devnull, "w") as devnull: + proc = subprocess.Popen(['openssl'] + args, stdin=subprocess.PIPE, stderr=devnull) + for i in range(6): + proc.stdin.write("\n") + proc.stdin.close() + proc.communicate() +def setupSkyped(): + try: + shutil.rmtree("t/skyped") + except OSError: + pass + os.makedirs("t/skyped") + cwd = os.getcwd() + os.chdir("t/skyped") + try: shutil.copyfile("../../skyped.cnf", "skyped.cnf") - self.openssl(['req', '-new', '-x509', '-days', '365', '-nodes', '-config', 'skyped.cnf', '-out', 'skyped.cert.pem', '-keyout', 'skyped.key.pem']) + openssl(['req', '-new', '-x509', '-days', '365', '-nodes', '-config', 'skyped.cnf', '-out', 'skyped.cert.pem', '-keyout', 'skyped.key.pem']) with open("skyped.conf", "w") as sock: sock.write("[skyped]\n") sock.write("username = alice\n") @@ -60,8 +33,51 @@ class Test(unittest.TestCase): sock.write("cert = %s/skyped.cert.pem\n" % os.getcwd()) sock.write("key = %s/skyped.key.pem\n" % os.getcwd()) sock.write("port = 2727\n") + finally: os.chdir(cwd) +class Test(unittest.TestCase): + def mock(self, name): + with open("t/skyped.log", "w") as skyped_log,\ + open("t/pexpect.log", "w") as pexpect_log: + skyped = subprocess.Popen([sys.executable, "skyped.py", + "-c", "t/skyped/skyped.conf", "-n", "-d", "-m", "t/%s-skyped.mock" % name], + stdout=skyped_log, stderr=subprocess.STDOUT) + try: + bitlbee = pexpect.spawn('../../bitlbee', ['-d', 't/bitlbee'], logfile=pexpect_log) + if os.environ.get('ATTACH_GDB'): + subprocess.Popen(['gdb', '-batch-silent', + '-ex', 'set logging overwrite on', + '-ex', 'set logging file t/gdb-%s.log' % bitlbee.pid, + '-ex', 'set logging on', + '-ex', 'handle all pass nostop noprint', + '-ex', 'handle SIGSEGV pass stop print', + '-ex', 'set pagination 0', + '-ex', 'continue', + '-ex', 'backtrace full', + '-ex', 'info registers', + '-ex', 'thread apply all backtrace', + '-ex', 'quit', + '../../bitlbee', str(bitlbee.pid) ]) + bitlbee_mock = open("t/%s-bitlbee.mock" % name) + for i in bitlbee_mock.readlines(): + line = i.strip() + if line.startswith(">> "): + bitlbee.expect_exact(line[3:], timeout=10) + elif line.startswith("<< "): + bitlbee.sendline(line[3:]) + bitlbee_mock.close() + bitlbee.close() + finally: + skyped.terminate() + skyped.communicate() + + def setUp(self): + try: + shutil.rmtree("t/bitlbee") + except OSError: + pass + os.makedirs("t/bitlbee") def testMsg(self): self.mock("msg") @@ -71,25 +87,28 @@ class Test(unittest.TestCase): def testInfo(self): self.mock("info") - + def testCall(self): self.mock("call") - + def testCallFailed(self): self.mock("call-failed") - + def testAddYes(self): self.mock("add-yes") - def testAddNo(self): - self.mock("add-no") + def testAddedYes(self): + self.mock("added-yes") + + def testAddedNo(self): + self.mock("added-no") def testGroupchatInvited(self): self.mock("groupchat-invited") def testGroupchatInvite(self): self.mock("groupchat-invite") - + def testCalledYes(self): self.mock("called-yes") @@ -102,5 +121,12 @@ class Test(unittest.TestCase): def testGroupRead(self): self.mock("group-read") + def testCtcpHelp(self): + self.mock("ctcp-help") + + def testSetMoodText(self): + self.mock("set-mood-text") + if __name__ == '__main__': + setupSkyped() unittest.main() diff --git a/protocols/twitter/twitter.c b/protocols/twitter/twitter.c index 8d437ed1..e48df2ed 100644 --- a/protocols/twitter/twitter.c +++ b/protocols/twitter/twitter.c @@ -469,13 +469,6 @@ static int twitter_buddy_msg(struct im_connection *ic, char *who, char *message, return (0); } -/** - * - */ -static void twitter_set_my_name(struct im_connection *ic, char *info) -{ -} - static void twitter_get_info(struct im_connection *ic, char *who) { } @@ -733,7 +726,6 @@ void twitter_initmodule() ret->logout = twitter_logout; ret->buddy_msg = twitter_buddy_msg; ret->get_info = twitter_get_info; - ret->set_my_name = twitter_set_my_name; ret->add_buddy = twitter_add_buddy; ret->remove_buddy = twitter_remove_buddy; ret->chat_msg = twitter_chat_msg; |