diff --git a/src/jcl/jabber/__init__.py b/src/jcl/jabber/__init__.py index 100e47d..15b9ea1 100644 --- a/src/jcl/jabber/__init__.py +++ b/src/jcl/jabber/__init__.py @@ -1,11 +1,16 @@ """Jabber related classes""" __revision__ = "" +import jcl.model.account as account from jcl.model.account import Account class Handler(object): """handling class""" + def __init__(self, component): + """Default Handler constructor""" + self.component = component + def filter(self, stanza, lang_class): """ Filter account to be processed by the handler @@ -21,13 +26,41 @@ class Handler(object): """ return [] -class DiscoHandler(object): - """Handle disco get items requests""" - - def filter(self, node, info_query): - """Filter requests to be handled""" - return False - - def handle(self, node, info_query, lang_class, disco_items, data): - """Handle disco get items request""" +def root_filter(self, stanza, lang_class, node=None): + """Filter stanza sent to root node""" + to_jid = stanza.get_to() + if to_jid.resource is None and to_jid.node is None and node is None: + return True + else: + return None + +def account_type_filter(self, stanza, lang_class, node=None): + """Filter stanzas sent to account type node""" + to_jid = stanza.get_to() + account_type = to_jid.resource + if account_type is not None and to_jid.node is None: + return account_type + else: + return None + +def account_filter(self, stanza, lang_class, node=None): + """Filter stanzas sent to account jid""" + name = stanza.get_to().node + return name + +def get_account_filter(self, stanza, lang_class, node=None): + """Filter stanzas sent to account jid, only if account exists""" + name = stanza.get_to().node + if name is not None: + return account.get_account(name, + stanza.get_from().bare()) + else: + return None + +def get_accounts_root_filter(self, stanza, lang_class, node=None): + """Filter stanza sent to root node""" + to_jid = stanza.get_to() + if to_jid.resource is None and to_jid.node is None and node is None: + return account.get_accounts(stanza.get_from().bare()) + else: return None diff --git a/src/jcl/jabber/command.py b/src/jcl/jabber/command.py index 50c4dd2..2ceb2fe 100644 --- a/src/jcl/jabber/command.py +++ b/src/jcl/jabber/command.py @@ -27,7 +27,8 @@ from pyxmpp.jabber.dataforms import Form, Field import jcl from jcl.lang import Lang -from jcl.jabber import DiscoHandler +from jcl.jabber.disco import DiscoHandler, RootDiscoGetInfoHandler +import jcl.model as model from jcl.model.account import Account COMMAND_NS = "http://jabber.org/protocol/commands" @@ -146,47 +147,60 @@ class JCLCommandManager(CommandManager): field_type="fixed", label="Account name")) # TODO: add to Lang bare_from_jid = unicode(info_query.get_from().bare()) - self.account_manager.db_connect() + model.db_connect() accounts = Account.select(Account.q.user_jid == bare_from_jid) for _account in accounts: fields = [Field(name="name", field_type="fixed", value=_account.name)] result_form.add_item(fields) - self.account_manager.db_disconnect() + model.db_disconnect() result_form.as_xml(command_node) return [response] +class CommandRootDiscoGetInfoHandler(RootDiscoGetInfoHandler): + + def handle(self, info_query, lang_class, node, disco_obj, data): + """Add command feature to DiscoInfo""" + disco_infos = RootDiscoGetInfoHandler.handle(self, info_query, + lang_class, node, + disco_obj, data) + disco_infos[0].add_feature(COMMAND_NS) + return disco_infos + class CommandDiscoGetInfoHandler(DiscoHandler): """Handle Ad-Hoc command disco get info requests""" - def filter(self, node, info_query): + def filter(self, info_query, lang_class, node): """ Filter requests to be handled. Only known commands """ return (node in command_manager.commands) - def handle(self, disco_info, node, info_query, data, lang_class): + def handle(self, info_query, lang_class, node, disco_obj, data): """ Return infos for given command """ - if not disco_info: - disco_info = DiscoInfo() - return command_manager.get_command_info(disco_info, node, lang_class) + if not disco_obj: + disco_obj = DiscoInfo() + return [command_manager.get_command_info(disco_info=disco_obj, + command_name=node, + lang_class=lang_class)] class CommandDiscoGetItemsHandler(DiscoHandler): """Handle Ad-Hoc command disco get items requests""" - def filter(self, node, info_query): + def filter(self, info_query, lang_class, node): """ Filter requests to be handled. """ return (node == 'http://jabber.org/protocol/commands') - def handle(self, disco_items, node, info_query, data, lang_class): + def handle(self, info_query, lang_class, node, disco_obj, data): """ """ - if not disco_items: - disco_items = DiscoItems() - return command_manager.list_commands(disco_items, lang_class) + if not disco_obj: + disco_obj = DiscoItems() + return [command_manager.list_commands(disco_items=disco_obj, + lang_class=lang_class)] diff --git a/src/jcl/jabber/component.py b/src/jcl/jabber/component.py index 3597166..b558eda 100644 --- a/src/jcl/jabber/component.py +++ b/src/jcl/jabber/component.py @@ -40,7 +40,6 @@ from Queue import Queue from sqlobject.inheritance import InheritableSQLObject from sqlobject.sqlbuilder import AND -from sqlobject.dbconnection import connectionForURI import pyxmpp.error as error from pyxmpp.jid import JID @@ -53,10 +52,19 @@ from pyxmpp.jabber.dataforms import Form, Field, Option import jcl from jcl.error import FieldError from jcl.jabber import Handler +from jcl.jabber.disco import AccountDiscoGetInfoHandler, \ + AccountTypeDiscoGetInfoHandler, RootDiscoGetItemsHandler, \ + AccountTypeDiscoGetItemsHandler from jcl.jabber.message import PasswordMessageHandler import jcl.jabber.command as command from jcl.jabber.command import CommandDiscoGetItemsHandler, \ - CommandDiscoGetInfoHandler, CommandManager, JCLCommandManager + CommandDiscoGetInfoHandler, CommandManager, JCLCommandManager, \ + CommandRootDiscoGetInfoHandler +from jcl.jabber.presence import AccountPresenceAvailableHandler, \ + RootPresenceAvailableHandler, AccountPresenceUnavailableHandler, \ + RootPresenceUnavailableHandler, AccountPresenceSubscribeHandler, \ + RootPresenceSubscribeHandler, AccountPresenceUnsubscribeHandler +import jcl.model as model from jcl.model import account from jcl.model.account import Account, LegacyJID from jcl.lang import Lang @@ -67,10 +75,12 @@ VERSION = "0.1" # JCL implementation ############################################################################### class JCLComponent(Component, object): - """Implement default JCL component behavior: + """ + Implement default JCL component behavior: - Jabber register process (add, delete, update accounts) - Jabber presence handling - passwork request at login + - Service Administration (XEP-0133) """ timeout = 1 @@ -80,7 +90,6 @@ class JCLComponent(Component, object): secret, server, port, - db_connection_str, disco_category="headline", disco_type="x-unknown", lang=Lang()): @@ -94,21 +103,28 @@ class JCLComponent(Component, object): # default values self.name = lang.get_default_lang_class().component_name self.spool_dir = "." - self.db_connection_str = db_connection_str self.version = VERSION self.time_unit = 60 self.queue = Queue(100) self.account_manager = AccountManager(self) self.msg_handlers = [] - self.subscribe_handlers = [] - self.unsubscribe_handlers = [] - self.available_handlers = [] - self.unavailable_handlers = [] + self.presence_subscribe_handlers = [[AccountPresenceSubscribeHandler(self), + RootPresenceSubscribeHandler(self)]] + self.presence_unsubscribe_handlers = [[AccountPresenceUnsubscribeHandler(self)]] + self.presence_available_handlers = [[AccountPresenceAvailableHandler(self), + RootPresenceAvailableHandler(self)]] + self.presence_unavailable_handlers = [[AccountPresenceUnavailableHandler(self), + RootPresenceUnavailableHandler(self)]] command.command_manager = JCLCommandManager() command.command_manager.component = self command.command_manager.account_manager = self.account_manager - self.disco_get_items_handlers = [CommandDiscoGetItemsHandler()] - self.disco_get_info_handlers = [CommandDiscoGetInfoHandler()] + self.disco_get_items_handlers = [[RootDiscoGetItemsHandler(self), + AccountTypeDiscoGetItemsHandler(self)], + [CommandDiscoGetItemsHandler(self)]] + self.disco_get_info_handlers = [[CommandRootDiscoGetInfoHandler(self), + AccountDiscoGetInfoHandler(self), + AccountTypeDiscoGetInfoHandler(self)], + [CommandDiscoGetInfoHandler(self)]] self.__logger = logging.getLogger("jcl.jabber.JCLComponent") self.lang = lang @@ -119,7 +135,8 @@ class JCLComponent(Component, object): signal.signal(signal.SIGTERM, self.signal_handler) def run(self): - """Main loop + """ + Main loop Connect to Jabber server Start timer thread Call Component main loop @@ -149,27 +166,12 @@ class JCLComponent(Component, object): self.disconnect() self.__logger.debug("Exitting normally") - ################# - # SQlite connections are not multi-threaded - # Utils workaround methods - ################# - def db_connect(self): - """Create a new connection to the DataBase (SQLObject use connection - pool) associated to the current thread""" - account.hub.threadConnection = \ - connectionForURI(self.db_connection_str) -# account.hub.threadConnection.debug = True - - def db_disconnect(self): - """Delete connection associated to the current thread""" - del account.hub.threadConnection - - ########################################################################### # Handlers ########################################################################### def time_handler(self): - """Timer thread handler + """ + Timer thread handler """ self.__logger.info("Timer thread started...") try: @@ -179,13 +181,17 @@ class JCLComponent(Component, object): self.wait_event.wait(self.time_unit) self.handle_tick() self.__logger.debug("Resetting alarm signal") - ##time.sleep(self.time_unit) except Exception, exception: + type, value, stack = sys.exc_info() + self.__logger.error("Error in timer thread\n%s\n%s" + % (exception, "".join(traceback.format_exception + (type, value, stack, 5)))) self.queue.put(exception) self.__logger.info("Timer thread terminated...") def authenticated(self): - """Override authenticated Component event handler + """ + Override authenticated Component event handler Register event handlers Probe for every accounts registered """ @@ -227,7 +233,7 @@ class JCLComponent(Component, object): self.handle_message) self.send_stanzas(self.account_manager.probe_all_accounts_presence()) - self.msg_handlers += [PasswordMessageHandler()] + self.msg_handlers += [[PasswordMessageHandler(self)]] def signal_handler(self, signum, frame): """Stop method handler @@ -277,32 +283,45 @@ class JCLComponent(Component, object): self.send_stanzas(result) return result - def apply_registered_behavior(self, handlers, stanza, apply_all=True): + def apply_registered_behavior(self, handlers, stanza, + apply_filter_func=None, + apply_handle_func=None): """Execute handler if their filter method does not return None""" result = [] - self.db_connect() - lang = self.lang.get_lang_class_from_node(stanza.get_node()) - for handler in handlers: - try: - self.__logger.debug("Applying filter " + repr(handler)) - data = handler.filter(stanza, lang) - if data: - self.__logger.debug("Applying handler " + repr(handler)) - result += handler.handle(stanza, lang, data) - if not apply_all: - break - except Exception, e: - type, value, stack = sys.exc_info() - self.__logger.error("Error with handler " + str(handler) + - " with " + str(stanza) + "\n%s\n%s" - % (e, "".join(traceback.format_exception - (type, value, stack, 5)))) - result += [Message(from_jid=stanza.get_to(), - to_jid=stanza.get_from(), - stanza_type="error", - subject=lang.error_subject, - body=lang.error_body % (e.message))] - self.db_disconnect() + lang_class = self.lang.get_lang_class_from_node(stanza.get_node()) + for handler_group in handlers: + for handler in handler_group: + try: + self.__logger.debug("Applying filter " + repr(handler)) + if apply_filter_func is not None: + data = apply_filter_func(handler.filter, stanza, lang_class) + else: + data = handler.filter(stanza, lang_class) + if data is not None and data != False: + self.__logger.debug("Applying handler " + repr(handler)) + if apply_handle_func is not None: + handler_result = apply_handle_func(handler.handle, + stanza, + lang_class, + data, + result) + else: + handler_result = handler.handle(stanza, lang_class, + data) + if handler_result is not None: + result += handler_result + break + except Exception, e: + type, value, stack = sys.exc_info() + self.__logger.error("Error with handler " + str(handler) + + " with " + str(stanza) + "\n%s\n%s" + % (e, "".join(traceback.format_exception + (type, value, stack, 5)))) + result += [Message(from_jid=stanza.get_to(), + to_jid=stanza.get_from(), + stanza_type="error", + subject=lang_class.error_subject, + body=lang_class.error_body % (e.message))] self.send_stanzas(result) return result @@ -337,50 +356,29 @@ class JCLComponent(Component, object): return 1 def disco_get_info(self, node, info_query): - """Discovery get info handler """ - result = self.apply_behavior(\ - info_query, - lambda name, from_jid, account_type, lang_class: \ - self.account_manager.account_disco_get_info(), - lambda name, from_jid, account_type, lang_class: \ - self.account_manager.account_type_disco_get_info(), - lambda name, from_jid, account_type, lang_class: \ - self.account_manager.root_disco_get_info(\ - node, - self.name, - self.disco_identity.category, - self.disco_identity.type)) - if result is None: - lang_class = self.lang.get_lang_class_from_node(info_query.get_node()) - for disco_filter in self.disco_get_info_handlers: - data = disco_filter.filter(node, info_query) - if data: - result = disco_filter.handle(result, node, info_query, - data, lang_class) + Discovery get info handler + """ + result = self.apply_registered_behavior(\ + self.disco_get_info_handlers, + info_query, + lambda filter_func, stanza, lang_class: \ + filter_func(stanza, lang_class, node), + lambda handle_func, stanza, lang_class, data, result: \ + handle_func(stanza, lang_class, node, result, data)) return result def disco_get_items(self, node, info_query): - """Discovery get nested nodes handler """ - result = self.apply_behavior(\ + Discovery get nested nodes handler + """ + result = self.apply_registered_behavior(\ + self.disco_get_items_handlers, info_query, - lambda name, from_jid, account_type, lang_class: \ - None, - lambda name, from_jid, account_type, lang_class: \ - self.account_manager.account_type_disco_get_items(from_jid, - account_type), - lambda name, from_jid, account_type, lang_class: \ - self.account_manager.root_disco_get_items(node, - from_jid, - lang_class)) - if result is None: - lang_class = self.lang.get_lang_class_from_node(info_query.get_node()) - for disco_filter in self.disco_get_items_handlers: - data = disco_filter.filter(node, info_query) - if data: - result = disco_filter.handle(result, node, info_query, - data, lang_class) + lambda filter_func, stanza, lang_class: \ + filter_func(stanza, lang_class, node), + lambda handle_func, stanza, lang_class, data, result: \ + handle_func(stanza, lang_class, node, result, data)) return result def handle_get_version(self, info_query): @@ -474,22 +472,7 @@ class JCLComponent(Component, object): if presence sent to the component ('if not name'), presence is sent to all accounts for current user. Otherwise, send presence from current account. """ - result = self.apply_registered_behavior(self.available_handlers, stanza) - if result == []: - result = self.apply_behavior(\ - stanza, - lambda name, from_jid, account_type, lang_class: \ - self.account_manager.account_handle_presence_available(name, - from_jid, - lang_class, - stanza.get_show()), - lambda name, from_jid, account_type, lang_class: \ - [], - lambda name, from_jid, account_type, lang_class: \ - self.account_manager.root_handle_presence_available(from_jid, - lang_class, - stanza.get_show()), - send_result=True) + result = self.apply_registered_behavior(self.presence_available_handlers, stanza) return result @@ -497,38 +480,16 @@ class JCLComponent(Component, object): """Handle presence unavailability """ self.__logger.debug("PRESENCE_UNAVAILABLE") - result = self.apply_registered_behavior(self.unavailable_handlers, stanza) - if result == []: - result = self.apply_behavior(\ - stanza, - lambda name, from_jid, account_type, lang_class: \ - self.account_manager.account_handle_presence_unavailable(name, - from_jid), - lambda name, from_jid, account_type, lang_class: \ - [], - lambda name, from_jid, account_type, lang_class: \ - self.account_manager.root_handle_presence_unavailable(from_jid), - send_result=True) + result = self.apply_registered_behavior(self.presence_unavailable_handlers, + stanza) return result def handle_presence_subscribe(self, stanza): """Handle subscribe presence from user """ self.__logger.debug("PRESENCE_SUBSCRIBE") - result = self.apply_registered_behavior(self.subscribe_handlers, stanza) - if result == []: - result = self.apply_behavior(\ - stanza, - lambda name, from_jid, account_type, lang_class: \ - self.account_manager.account_handle_presence_subscribe(name, - from_jid, - stanza), - lambda name, from_jid, account_type, lang_class: \ - [], - lambda name, from_jid, account_type, lang_class: \ - self.account_manager.root_handle_presence_subscribe(from_jid, - stanza), - send_result=True) + result = self.apply_registered_behavior(self.presence_subscribe_handlers, + stanza) return result def handle_presence_subscribed(self, stanza): @@ -541,18 +502,8 @@ class JCLComponent(Component, object): """Handle unsubscribe presence from user """ self.__logger.debug("PRESENCE_UNSUBSCRIBE") - result = self.apply_registered_behavior(self.unsubscribe_handlers, stanza) - if result == []: - result = self.apply_behavior(\ - stanza, - lambda name, from_jid, account_type, lang_class: \ - self.account_manager.account_handle_presence_unsubscribe(name, - from_jid), - lambda name, from_jid, account_type, lang_class: \ - [], - lambda name, from_jid, account_type, lang_class: \ - [], - send_result=True) + result = self.apply_registered_behavior(self.presence_unsubscribe_handlers, + stanza) return result def handle_presence_unsubscribed(self, stanza): @@ -570,7 +521,7 @@ class JCLComponent(Component, object): Handle password response message """ self.__logger.debug("MESSAGE: " + message.get_body()) - self.apply_registered_behavior(self.msg_handlers, message, False) + self.apply_registered_behavior(self.msg_handlers, message) return 1 def handle_command(self, info_query): @@ -593,7 +544,7 @@ class JCLComponent(Component, object): ########################################################################### # Utils ########################################################################### - def send_error_to_account(self, _account, exception): + def send_error(self, _account, exception): """ """ self.send_stanzas(self.account_manager.send_error_from_account(_account, exception)) type, value, stack = sys.exc_info() @@ -643,72 +594,6 @@ class AccountManager(object): account_classes = property(_get_account_classes, _set_account_classes) - ###### disco_get_info handlers ###### - def account_disco_get_info(self): - """Implement discovery get_info on an account node""" - self.__logger.debug("account_disco_get_info") - disco_info = DiscoInfo() - disco_info.add_feature("jabber:iq:register") - return disco_info - - def account_type_disco_get_info(self): - """Implement discovery get_info on an account type node""" - self.__logger.debug("account_type_disco_get_info") - return self.account_disco_get_info() - - def root_disco_get_info(self, node, name, category, type): - """Implement discovery get_info on main component JID""" - self.__logger.debug("root_disco_get_info") - if not node: - disco_info = DiscoInfo() - disco_info.add_feature("jabber:iq:version") - disco_info.add_feature(command.COMMAND_NS) - if not self.has_multiple_account_type: - disco_info.add_feature("jabber:iq:register") - DiscoIdentity(disco_info, name, - category, - type) - return disco_info - else: - return None - - ###### disco_get_items handlers ###### - def account_type_disco_get_items(self, from_jid, account_type): - """Discovery get_items on an account type node""" - self.__logger.debug("Listing account for " + account_type) - account_class = self._get_account_class(account_type + "Account") - if account_class is not None: - return self._list_accounts(account_class, - from_jid.bare(), - account_type=account_type) - else: - self.__logger.error("Error: " + account_class.__name__ - + " class not in account_classes") - return None - - def root_disco_get_items(self, node, from_jid, lang_class): - """Discovery get_items on root node""" - if node is not None: - return None - disco_items = None - if self.has_multiple_account_type: # list accounts with only one type declared - disco_items = DiscoItems() - for account_type in self.account_types: - type_label_attr = "type_" + account_type.lower() + "_name" - if hasattr(lang_class, type_label_attr): - type_label = getattr(lang_class, type_label_attr) - else: - type_label = account_type - DiscoItem(disco_items, - JID(unicode(self.component.jid) + "/" + - account_type), - account_type, - type_label) - else: - disco_items = self._list_accounts(self.account_classes[0], - from_jid.bare()) - return disco_items - ###### get_register handlers ###### def account_get_register(self, info_query, name, @@ -718,19 +603,19 @@ class AccountManager(object): """Handle get_register on an account. Return a preinitialized form""" info_query = info_query.make_result_response() - account_class = self._get_account_class(account_type + "Account") - self.db_connect() + account_class = self.get_account_class(account_type + "Account") + model.db_connect() accounts = account_class.select(\ AND(account_class.q.name == name, account_class.q.user_jid == unicode(from_jid.bare()))) if accounts is not None: query = info_query.new_query("jabber:iq:register") _account = accounts[0] - self.db_disconnect() + model.db_disconnect() self.get_reg_form_init(lang_class, _account).as_xml(query) else: - self.db_disconnect() + model.db_disconnect() return [info_query] def _account_type_get_register(self, info_query, account_class, lang_class): @@ -748,7 +633,7 @@ class AccountManager(object): """Handle get_register on an account_type node""" return self._account_type_get_register(\ info_query, - self._get_account_class(account_type + "Account"), + self.get_account_class(account_type + "Account"), lang_class) def root_get_register(self, info_query, lang_class): @@ -762,7 +647,7 @@ class AccountManager(object): def remove_all_accounts(self, user_jid): """Unsubscribe all accounts associated to 'user_jid' then delete those accounts from the DataBase""" - self.db_connect() + model.db_connect() result = [] for _account in Account.select(Account.q.user_jid == unicode(user_jid)): self.__logger.debug("Deleting " + _account.name @@ -781,7 +666,7 @@ class AccountManager(object): result.append(Presence(from_jid=self.component.jid, to_jid=user_jid, stanza_type="unsubscribed")) - self.db_disconnect() + model.db_disconnect() return result def _populate_account(self, _account, lang_class, x_data, @@ -791,7 +676,7 @@ class AccountManager(object): result = [] from_jid = info_query.get_from() bare_from_jid = unicode(from_jid.bare()) - self.db_connect() + model.db_connect() try: for (field, field_type, field_options, field_post_func, field_default_func) in _account.get_register_fields(): @@ -816,7 +701,7 @@ class AccountManager(object): lang_class.mandatory_field % (field)) text.setNs(text.newNs(error.STANZA_ERROR_NS, None)) result.append(iq_error) - self.db_disconnect() + model.db_disconnect() return result result.append(info_query.make_result_response()) @@ -840,7 +725,7 @@ class AccountManager(object): to_jid=_account.user_jid, subject=_account.get_update_message_subject(lang_class), body=_account.get_update_message_body(lang_class))) - self.db_disconnect() + model.db_disconnect() return result def account_set_register(self, name, from_jid, lang_class, @@ -848,13 +733,13 @@ class AccountManager(object): """Update account""" self.__logger.debug("Updating account " + name) bare_from_jid = from_jid.bare() - self.db_connect() + model.db_connect() accounts = Account.select(\ AND(Account.q.name == name, Account.q.user_jid == unicode(bare_from_jid))) accounts_count = accounts.count() _account = list(accounts)[0] - self.db_disconnect() + model.db_disconnect() if accounts_count > 1: # Just print a warning, only the first account will be use self.__logger.error("There might not exist 2 accounts for " + @@ -874,7 +759,7 @@ class AccountManager(object): x_data, info_query): """Create new account from account_class""" - self.db_connect() + model.db_connect() bare_from_jid = from_jid.bare() _account = account_class(user_jid=unicode(bare_from_jid), name=name, @@ -882,7 +767,7 @@ class AccountManager(object): all_accounts = Account.select(\ Account.q.user_jid == unicode(bare_from_jid)) first_account = (all_accounts.count() > 0) - self.db_disconnect() + model.db_disconnect() return self._populate_account(_account, lang_class, x_data, info_query, True, first_account) @@ -895,7 +780,7 @@ class AccountManager(object): """Create new typed account""" return self._account_type_set_register(\ name, from_jid, - self._get_account_class(account_type + "Account"), lang_class, + self.get_account_class(account_type + "Account"), lang_class, x_data, info_query) def root_set_register(self, name, from_jid, lang_class, @@ -911,39 +796,12 @@ class AccountManager(object): ###### presence generic handlers ###### - def account_handle_presence(self, name, from_jid, presence_func): - """Handle presence sent to an account JID""" - result = [] - self.db_connect() - accounts = Account.select(\ - AND(Account.q.name == name, - Account.q.user_jid == unicode(from_jid.bare()))) - if accounts.count() > 0: - result.extend(presence_func(accounts[0])) - self.db_disconnect() - return result - - def root_handle_presence(self, from_jid, presence_func, root_presence_func): - """handle presence sent to component JID""" - result = [] - self.db_connect() - accounts = Account.select(\ - Account.q.user_jid == unicode(from_jid.bare())) - accounts_length = 0 - for _account in accounts: - accounts_length += 1 - result.extend(presence_func(_account)) - self.db_disconnect() - if (accounts_length > 0): - result.extend(root_presence_func(accounts_length)) - return result - def send_presence_all(self, presence): """Send presence to all account. Optimized to use only one sql request""" current_user_jid = None result = [] - self.db_connect() + model.db_connect() # Explicit reference to account table (clauseTables) to use # "user_jid" column with Account subclasses for _account in \ @@ -951,146 +809,50 @@ class AccountManager(object): orderBy="user_jid"): if current_user_jid != _account.user_jid: current_user_jid = _account.user_jid - result.extend(self._send_presence(self.component.jid, - _account.user_jid, - presence)) - result.extend(getattr(self, "_send_presence_" + + result.extend(self.send_presence(self.component.jid, + _account.user_jid, + presence)) + result.extend(getattr(self, "send_presence_" + presence)(_account)) - self.db_disconnect() + model.db_disconnect() return result - ###### presence_available handlers ###### - def account_handle_presence_available(self, name, from_jid, lang_class, show): - """Handle presence \"available\" sent to an account JID""" - self.__logger.debug("Account handle presence available") - return self.account_handle_presence(\ - name, from_jid, - lambda _account: \ - self._send_presence_available(_account, - show, - lang_class)) - - def root_handle_presence_available(self, from_jid, lang_class, show): - """Handle presence \"available\" sent to component JID""" - self.__logger.debug("Root handle presence available") - return self.root_handle_presence(\ - from_jid, - lambda _account: \ - self._send_presence_available(_account, - show, - lang_class), - lambda nb_accounts: \ - self._send_root_presence(from_jid, "available", show, - str(nb_accounts) + - lang_class.message_status)) - - ###### presence_unavailable handlers ###### - def account_handle_presence_unavailable(self, name, from_jid): - """Handle presence \"unavailable\" sent to an account JID""" - self.__logger.debug("Account handle presence available") - return self.account_handle_presence(\ - name, from_jid, - lambda _account: \ - self._send_presence_unavailable(_account)) - - def root_handle_presence_unavailable(self, from_jid): - """Handle presence \"unavailable\" sent to component JID""" - self.__logger.debug("Root handle presence available") - return self.root_handle_presence(\ - from_jid, - lambda _account: \ - self._send_presence_unavailable(_account), - lambda nb_accounts: \ - self._send_root_presence(from_jid, "unavailable")) - - ###### presence_subscribe handlers ###### - def account_handle_presence_subscribe(self, name, from_jid, stanza): - """Handle \"subscribe\" iq sent to an account JID""" - if self._has_account(from_jid, name): - return [stanza.make_accept_response()] - else: - self.__logger.debug("Account '" + str(name) + "' for user '" + - unicode(from_jid.bare()) + "' was not found. " + - "Refusing subscription") - return [] - - def root_handle_presence_subscribe(self, from_jid, stanza): - """Handle \"subscribe\" iq sent to component JID""" - if self._has_account(from_jid): - return [stanza.make_accept_response()] - else: - self.__logger.debug("User '" + - unicode(from_jid.bare()) + - "' doesn't have any account. " + - "Refusing subscription") - return [] - - ###### presence_unsubscribe handler (only apply to account) ###### - def account_handle_presence_unsubscribe(self, name, from_jid): - """Handle \"unsubscribe\" iq sent to account JID""" - result = [] - self.db_connect() - accounts = Account.select(\ - AND(Account.q.name == name, - Account.q.user_jid == unicode(from_jid.bare()))) - for _account in accounts: - result.append(Presence(from_jid=_account.jid, - to_jid=from_jid, - stanza_type="unsubscribe")) - result.append(Presence(from_jid=_account.jid, - to_jid=from_jid, - stanza_type="unsubscribed")) - _account.destroySelf() - self.db_disconnect() - return result - def probe_all_accounts_presence(self): """Send presence probe to all registered accounts""" return self.send_presence_all("probe") ###### Utils methods ###### - def _has_account(self, from_jid, name=None): - """Check if user with \"from_jid\" JID has an account. - Check if an account named \"name\" exist if \"name\" given.""" - self.db_connect() - if name is None: - accounts = Account.select(\ - Account.q.user_jid == unicode(from_jid.bare())) - else: - accounts = Account.select(\ - AND(Account.q.name == name, - Account.q.user_jid == unicode(from_jid.bare()))) - result = (accounts is not None \ - and accounts.count() > 0) - self.db_disconnect() - return result - - - def _list_accounts(self, _account_class, bare_from_jid, - account_type=""): + def list_accounts(self, bare_from_jid, account_class=None, + account_type=""): """List accounts in disco_items for given _account_class and user jid""" + if account_class is None: + account_class = self.account_classes[0] if account_type is not None and account_type != "": resource = "/" + account_type account_type = account_type + "/" else: resource = "" - self.db_connect() - accounts = _account_class.select(_account_class.q.user_jid == \ - unicode(bare_from_jid)) + model.db_connect() + accounts = account_class.select(account_class.q.user_jid == \ + unicode(bare_from_jid)) if accounts.count() == 0: - return None - disco_items = DiscoItems() + return for _account in accounts: - self.__logger.debug(str(_account)) - DiscoItem(disco_items, - JID(unicode(_account.jid) + resource), - account_type + _account.name, - _account.long_name) - self.db_disconnect() - return disco_items + yield (_account, resource, account_type) + model.db_disconnect() - def _get_account_class(self, account_class_name): + def list_account_types(self, lang_class): + """List account supported types""" + for account_type in self.account_types: + type_label_attr = "type_" + account_type.lower() + "_name" + if hasattr(lang_class, type_label_attr): + type_label = getattr(lang_class, type_label_attr) + else: + type_label = account_type + yield (account_type, type_label) + + def get_account_class(self, account_class_name): """Return account class definition from declared classes in account_classes from its class name""" self.__logger.debug("Looking for " + account_class_name) @@ -1101,19 +863,9 @@ class AccountManager(object): self.__logger.debug(account_class_name + " not found") return None - def db_connect(self): - """Create a new connection to the DataBase (SQLObject use connection - pool) associated to the current thread""" - account.hub.threadConnection = \ - connectionForURI(self.component.db_connection_str) # TODO : move db_connection_str to AccountManager -# account.hub.threadConnection.debug = True - - def db_disconnect(self): - """Delete connection associated to the current thread""" - del account.hub.threadConnection - def get_reg_form(self, lang_class, _account_class, bare_from_jid): - """Return register form based on language and account class + """ + Return register form based on language and account class """ reg_form = Form(title=lang_class.register_title, instructions=lang_class.register_instructions) @@ -1123,7 +875,7 @@ class AccountManager(object): name="name", required=True) - self.db_connect() + model.db_connect() for (field_name, field_type, field_options, @@ -1158,11 +910,12 @@ class AccountManager(object): except: self.__logger.debug("Setting field " + field_name + " required") field.required = True - self.db_disconnect() + model.db_disconnect() return reg_form def get_reg_form_init(self, lang_class, _account): - """Return register form for an existing account (update) + """ + Return register form for an existing account (update) """ reg_form = self.get_reg_form(lang_class, _account.__class__, _account.user_jid) @@ -1177,31 +930,34 @@ class AccountManager(object): """Compose account jid from account name""" return name + u"@" + unicode(self.component.jid) - def _send_presence_probe(self, _account): + def send_presence_probe(self, _account): """Send presence probe to account's user""" return [Presence(from_jid=_account.jid, to_jid=_account.user_jid, stanza_type="probe")] - def _send_presence_unavailable(self, _account): + def send_presence_unavailable(self, _account): """Send unavailable presence to account's user""" + model.db_connect() _account.status = account.OFFLINE - return [Presence(from_jid=_account.jid, - to_jid=_account.user_jid, - stanza_type="unavailable")] - - def _send_root_presence(self, to_jid, presence_type, - show=None, status=None): - result = self._send_presence(self.component.jid, to_jid, - presence_type, show=show, - status=status) - result.extend(self._send_root_presence_legacy(to_jid, - presence_type, - show=show, - status=status)) + result = [Presence(from_jid=_account.jid, + to_jid=_account.user_jid, + stanza_type="unavailable")] + model.db_disconnect() return result - def _send_presence(self, from_jid, to_jid, presence_type, status=None, show=None): + def send_root_presence(self, to_jid, presence_type, + show=None, status=None): + result = self.send_presence(self.component.jid, to_jid, + presence_type, show=show, + status=status) + result.extend(self.send_root_presence_legacy(to_jid, + presence_type, + show=show, + status=status)) + return result + + def send_presence(self, from_jid, to_jid, presence_type, status=None, show=None): """Send presence stanza""" return [Presence(from_jid=from_jid, to_jid=to_jid, @@ -1209,10 +965,11 @@ class AccountManager(object): show=show, stanza_type=presence_type)] - def _send_presence_available(self, _account, show, lang_class): + def send_presence_available(self, _account, show, lang_class): """Send available presence to account's user and ask for password if necessary""" result = [] + model.db_connect() _account.default_lang_class = lang_class old_status = _account.status if show is None: @@ -1225,28 +982,24 @@ class AccountManager(object): show=show, stanza_type="available")) if hasattr(_account, 'store_password') \ - and hasattr(_account, 'password') \ - and _account.store_password == False \ - and old_status == account.OFFLINE \ - and _account.password == None : + and hasattr(_account, 'password') \ + and _account.store_password == False \ + and old_status == account.OFFLINE \ + and _account.password == None : result.extend(self.ask_password(_account, lang_class)) + model.db_disconnect() return result - def _send_root_presence_legacy(self, to_jid, presence_type, + def send_root_presence_legacy(self, to_jid, presence_type, status=None, show=None): """Send presence from legacy JID""" result = [] - self.db_connect() - legacy_jids = LegacyJID.select(\ - AND(LegacyJID.q.accountID == Account.q.id, - Account.q.user_jid == unicode(to_jid.bare()))) - for legacy_jid in legacy_jids: + for legacy_jid in account.get_legacy_jids(unicode(to_jid.bare())): result.append(Presence(from_jid=legacy_jid.jid, to_jid=to_jid, show=show, status=status, stanza_type=presence_type)) - self.db_disconnect() return result def ask_password(self, _account, lang_class): @@ -1254,8 +1007,8 @@ class AccountManager(object): """ result = [] if hasattr(_account, 'waiting_password_reply') \ - and not _account.waiting_password_reply \ - and _account.status != account.OFFLINE: + and not _account.waiting_password_reply \ + and _account.status != account.OFFLINE: _account.waiting_password_reply = True result.append(Message(from_jid=_account.jid, to_jid=_account.user_jid, @@ -1265,6 +1018,20 @@ class AccountManager(object): (_account.name))) return result + def set_password(self, _account, from_jid, password, lang_class): + """ + Set password to given account + """ + model.db_connect() + _account.password = password + _account.waiting_password_reply = False + result = [Message(from_jid=_account.jid, + to_jid=from_jid, + subject=lang_class.password_saved_for_session, + body=lang_class.password_saved_for_session)] + model.db_disconnect() + return result + def send_error_from_account(self, _account, exception): """Send an error message only one time until _account.in_error has been reset to False""" diff --git a/src/jcl/jabber/disco.py b/src/jcl/jabber/disco.py new file mode 100644 index 0000000..fbde289 --- /dev/null +++ b/src/jcl/jabber/disco.py @@ -0,0 +1,149 @@ +## +## disco.py +## Login : David Rousselie +## Started on Wed Jun 27 22:27:25 2007 David Rousselie +## $Id$ +## +## Copyright (C) 2007 David Rousselie +## 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 USA +## + +import logging + +from pyxmpp.jid import JID +from pyxmpp.jabber.disco import DiscoInfo, DiscoItems, DiscoItem, DiscoIdentity + +import jcl.jabber as jabber + +class DiscoHandler(object): + """Handle disco get items requests""" + + def __init__(self, component): + self.component = component + + def filter(self, stanza, lang_class, node): + """Filter requests to be handled""" + return False + + def handle(self, stanza, lang_class, node, disco_obj, data): + """Handle disco get items request""" + return None + +class RootDiscoGetInfoHandler(DiscoHandler): + + filter = jabber.root_filter + + def __init__(self, component): + DiscoHandler.__init__(self, component) + self.__logger = logging.getLogger("jcl.jabber.RootDiscoGetInfoHandler") + + def handle(self, stanza, lang_class, node, disco_obj, data): + """Implement discovery get_info on main component JID""" + self.__logger.debug("root_disco_get_info") + disco_info = DiscoInfo() + disco_info.add_feature("jabber:iq:version") + if not self.component.account_manager.has_multiple_account_type: + disco_info.add_feature("jabber:iq:register") + DiscoIdentity(disco_info, self.component.name, + self.component.disco_identity.category, + self.component.disco_identity.type) + return [disco_info] + +class AccountDiscoGetInfoHandler(DiscoHandler): + + filter = jabber.account_filter + + def __init__(self, component): + DiscoHandler.__init__(self, component) + self.__logger = logging.getLogger("jcl.jabber.AccountDiscoGetInfoHandler") + + def handle(self, stanza, lang_class, node, disco_obj, data): + """Implement discovery get_info on an account node""" + self.__logger.debug("account_disco_get_info") + disco_info = DiscoInfo() + disco_info.add_feature("jabber:iq:register") + return [disco_info] + +class AccountTypeDiscoGetInfoHandler(AccountDiscoGetInfoHandler): + + filter = jabber.account_type_filter + + def __init__(self, component): + AccountDiscoGetInfoHandler.__init__(self, component) + self.__logger = logging.getLogger("jcl.jabber.AccountTypeDiscoGetInfoHandler") + +class RootDiscoGetItemsHandler(DiscoHandler): + + filter = jabber.root_filter + + def __init__(self, component): + DiscoHandler.__init__(self, component) + self.__logger = logging.getLogger("jcl.jabber.RootDiscoGetItemsHandler") + + def handle(self, stanza, lang_class, node, disco_obj, data): + """Discovery get_items on root node""" + from_jid = stanza.get_from() + if node is not None: + return None + disco_items = None + if self.component.account_manager.has_multiple_account_type: # list accounts with only one type declared + disco_items = DiscoItems() + for (account_type, type_label) in \ + self.component.account_manager.list_account_types(lang_class): + DiscoItem(disco_items, + JID(unicode(self.component.jid) + "/" + + account_type), + account_type, + type_label) + + else: + disco_items = DiscoItems() + for (_account, resource, account_type) in \ + self.component.account_manager.list_accounts(from_jid.bare()): + DiscoItem(disco_items, + JID(unicode(_account.jid) + resource), + account_type + _account.name, + _account.long_name) + return [disco_items] + +class AccountTypeDiscoGetItemsHandler(DiscoHandler): + + filter = jabber.account_type_filter + + def __init__(self, component): + DiscoHandler.__init__(self, component) + self.__logger = logging.getLogger("jcl.jabber.AccountTypeDiscoGetItemsHandler") + + def handle(self, stanza, lang_class, node, disco_obj, data): + """Discovery get_items on an account type node""" + account_type = data + from_jid = stanza.get_from() + self.__logger.debug("Listing account for " + account_type) + account_class = self.component.account_manager.get_account_class(account_type + "Account") + if account_class is not None: + disco_items = DiscoItems() + for (_account, resource, account_type) in \ + self.component.account_manager.list_accounts(from_jid.bare(), + account_class, + account_type=account_type): + DiscoItem(disco_items, + JID(unicode(_account.jid) + resource), + account_type + _account.name, + _account.long_name) + return [disco_items] + else: + self.__logger.error("Error: " + account_class.__name__ + + " class not in account_classes") + return [] diff --git a/src/jcl/jabber/feeder.py b/src/jcl/jabber/feeder.py index 7455543..5c73ae3 100644 --- a/src/jcl/jabber/feeder.py +++ b/src/jcl/jabber/feeder.py @@ -31,6 +31,7 @@ import logging from jcl.jabber import Handler from jcl.jabber.component import JCLComponent from jcl.lang import Lang +import jcl.model as model from jcl.model.account import Account from pyxmpp.message import Message @@ -48,14 +49,12 @@ class FeederComponent(JCLComponent): secret, server, port, - db_connection_str, lang = Lang()): JCLComponent.__init__(self, jid, secret, server, port, - db_connection_str, lang=lang) # Define default feeder and sender, can be override self.handler = FeederHandler(Feeder(self), Sender(self)) @@ -65,12 +64,12 @@ class FeederComponent(JCLComponent): def handle_tick(self): """Implement main feed/send behavior""" - self.db_connect() + model.db_connect() self.handler.handle(\ None, self.lang.get_default_lang_class(), self.handler.filter(None, self.lang.get_default_lang_class())) - self.db_disconnect() + model.db_disconnect() diff --git a/src/jcl/jabber/message.py b/src/jcl/jabber/message.py index 5d60c4c..73b07fb 100644 --- a/src/jcl/jabber/message.py +++ b/src/jcl/jabber/message.py @@ -22,16 +22,19 @@ import re +from sqlobject.sqlbuilder import AND from pyxmpp.message import Message from jcl.jabber import Handler +import jcl.model.account as account from jcl.model.account import Account class PasswordMessageHandler(Handler): """Handle password message""" - def __init__(self): + def __init__(self, component): """handler constructor""" + Handler.__init__(self, component) self.password_regexp = re.compile("\[PASSWORD\]") def filter(self, stanza, lang_class): @@ -39,23 +42,14 @@ class PasswordMessageHandler(Handler): Return the uniq account associated with a name and user JID. DB connection might already be opened. """ - name = stanza.get_to().node - bare_from_jid = unicode(stanza.get_from().bare()) - accounts = Account.select(\ - AND(Account.q.name == name, - Account.q.user_jid == bare_from_jid)) - if accounts.count() > 1: - print >>sys.stderr, "Account " + name + " for user " + \ - bare_from_jid + " must be uniq" - elif accounts.count() == 0: - return None - _account = accounts[0] + _account = account.get_account(stanza.get_to().node, + stanza.get_from().bare()) if hasattr(_account, 'password') \ - and hasattr(_account, 'waiting_password_reply') \ - and (getattr(_account, 'waiting_password_reply') == True) \ - and self.password_regexp.search(stanza.get_subject()) \ - is not None: - return accounts + and hasattr(_account, 'waiting_password_reply') \ + and (getattr(_account, 'waiting_password_reply') == True) \ + and self.password_regexp.search(stanza.get_subject()) \ + is not None: + return _account else: return None @@ -63,10 +57,6 @@ class PasswordMessageHandler(Handler): """ Receive password in stanza (must be a Message) for given account. """ - _account = data[0] - _account.password = stanza.get_body() - _account.waiting_password_reply = False - return [Message(from_jid=_account.jid, - to_jid=stanza.get_from(), - subject=lang_class.password_saved_for_session, - body=lang_class.password_saved_for_session)] + return self.component.account_manager.set_password(data, stanza.get_from(), + stanza.get_body(), + lang_class) diff --git a/src/jcl/jabber/presence.py b/src/jcl/jabber/presence.py index c498485..87d7d3d 100644 --- a/src/jcl/jabber/presence.py +++ b/src/jcl/jabber/presence.py @@ -24,17 +24,19 @@ from pyxmpp.presence import Presence from jcl.jabber import Handler +import jcl.jabber as jabber +import jcl.model as model class DefaultPresenceHandler(Handler): """Handle presence""" - def handle(self, presence, lang_class, data): + def handle(self, stanza, lang_class, data): """Return same presence as receive one""" - to_jid = presence.get_to() - from_jid = presence.get_from() - presence.set_to(from_jid) - presence.set_from(to_jid) - return [presence] + to_jid = stanza.get_to() + from_jid = stanza.get_from() + stanza.set_to(from_jid) + stanza.set_from(to_jid) + return [stanza] class DefaultSubscribeHandler(Handler): """Return default response to subscribe queries""" @@ -64,3 +66,94 @@ class DefaultUnsubscribeHandler(Handler): stanza_type="unsubscribed")) return result +class AccountPresenceHandler(Handler): + filter = jabber.get_account_filter + + def handle(self, stanza, lang_class, data): + """Handle presence sent to an account JID""" + result = [] + _account = data + result.extend(self.get_account_presence(stanza, lang_class, _account)) + return result + +class AccountPresenceAvailableHandler(AccountPresenceHandler): + def get_account_presence(self, stanza, lang_class, _account): + return self.component.account_manager.send_presence_available(_account, + stanza.get_show(), + lang_class) + +class RootPresenceHandler(Handler): + filter = jabber.get_accounts_root_filter + + def handle(self, stanza, lang_class, data): + """handle presence sent to component JID""" + result = [] + accounts_length = 0 + accounts = data + for _account in accounts: + accounts_length += 1 + result.extend(self.get_account_presence(stanza, lang_class, _account)) + if accounts_length > 0: + result.extend(self.get_root_presence(stanza, lang_class, accounts_length)) + return result + +class RootPresenceAvailableHandler(RootPresenceHandler, AccountPresenceAvailableHandler): + def get_root_presence(self, stanza, lang_class, nb_accounts): + return self.component.account_manager.send_root_presence(stanza.get_from(), + "available", + stanza.get_show(), + str(nb_accounts) + + lang_class.message_status) + + +class AccountPresenceUnavailableHandler(AccountPresenceHandler): + def get_account_presence(self, stanza, lang_class, _account): + return self.component.account_manager.send_presence_unavailable(_account) + +class RootPresenceUnavailableHandler(RootPresenceHandler, AccountPresenceUnavailableHandler): + def get_root_presence(self, stanza, lang_class, nb_accounts): + return self.component.account_manager.send_root_presence(stanza.get_from(), + "unavailable") + +class AccountPresenceSubscribeHandler(Handler): + """""" + + filter = jabber.get_account_filter + + def handle(self, stanza, lang_class, data): + """Handle \"subscribe\" iq sent to an account JID""" + return [stanza.make_accept_response()] + +class RootPresenceSubscribeHandler(AccountPresenceSubscribeHandler): + """""" + + filter = jabber.get_accounts_root_filter + + def handle(self, stanza, lang_class, data): + """Handle \"subscribe\" iq sent to component JID""" + if list(data) != []: + return AccountPresenceSubscribeHandler.handle(self, stanza, + lang_class, None) + else: + return None + +class AccountPresenceUnsubscribeHandler(Handler): + """""" + + filter = jabber.get_account_filter + + def handle(self, stanza, lang_class, data): + """Handle \"unsubscribe\" iq sent to account JID""" + result = [] + from_jid = stanza.get_from() + _account = data + model.db_connect() + result.append(Presence(from_jid=_account.jid, + to_jid=from_jid, + stanza_type="unsubscribe")) + result.append(Presence(from_jid=_account.jid, + to_jid=from_jid, + stanza_type="unsubscribed")) + _account.destroySelf() + model.db_disconnect() + return result diff --git a/src/jcl/jabber/tests/__init__.py b/src/jcl/jabber/tests/__init__.py index 1ffde7a..550e5fd 100644 --- a/src/jcl/jabber/tests/__init__.py +++ b/src/jcl/jabber/tests/__init__.py @@ -3,13 +3,15 @@ __revision__ = "" import unittest -from jcl.jabber.tests import component, feeder, command +from jcl.jabber.tests import component, feeder, command, message, presence def suite(): suite = unittest.TestSuite() suite.addTest(component.suite()) suite.addTest(feeder.suite()) suite.addTest(command.suite()) + suite.addTest(message.suite()) + suite.addTest(presence.suite()) return suite if __name__ == '__main__': diff --git a/src/jcl/jabber/tests/component.py b/src/jcl/jabber/tests/component.py index 1872f84..62cf165 100644 --- a/src/jcl/jabber/tests/component.py +++ b/src/jcl/jabber/tests/component.py @@ -45,6 +45,7 @@ from jcl.jabber.component import JCLComponent, Handler from jcl.jabber.message import PasswordMessageHandler from jcl.jabber.presence import DefaultSubscribeHandler, \ DefaultUnsubscribeHandler, DefaultPresenceHandler +import jcl.model as model from jcl.model import account from jcl.model.account import Account, LegacyJID from jcl.lang import Lang @@ -156,7 +157,7 @@ class HandlerMock(object): self.handled = [] def filter(self, stanza, lang_class): - return [] + return True def handle(self, stanza, lang_class, data): self.handled.append((stanza, lang_class, data)) @@ -172,26 +173,26 @@ class JCLComponent_TestCase(unittest.TestCase): self.comp = JCLComponent("jcl.test.com", "password", "localhost", - "5347", - 'sqlite://' + DB_URL) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + "5347") + model.db_connection_str = 'sqlite://' + DB_URL + model.db_connect() Account.createTable(ifNotExists = True) LegacyJID.createTable(ifNotExists=True) ExampleAccount.createTable(ifNotExists = True) Example2Account.createTable(ifNotExists = True) - del account.hub.threadConnection + model.db_disconnect() self.max_tick_count = 1 self.saved_time_handler = None def tearDown(self): - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() Example2Account.dropTable(ifExists = True) ExampleAccount.dropTable(ifExists = True) LegacyJID.dropTable(ifExists=True) Account.dropTable(ifExists = True) del TheURIOpener.cachedURIs['sqlite://' + DB_URL] - account.hub.threadConnection.close() - del account.hub.threadConnection + model.hub.threadConnection.close() + model.db_disconnect() if os.path.exists(DB_PATH): os.unlink(DB_PATH) @@ -199,9 +200,9 @@ class JCLComponent_TestCase(unittest.TestCase): # Constructor tests ########################################################################### def test_constructor(self): - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() self.assertTrue(Account._connection.tableExists("account")) - del account.hub.threadConnection + model.db_disconnect() ########################################################################### # apply_registered_behavior tests @@ -211,7 +212,7 @@ class JCLComponent_TestCase(unittest.TestCase): self.comp.stream_class = MockStreamNoConnect message = Message(from_jid="user1@test.com", to_jid="account11@jcl.test.com") - result = self.comp.apply_registered_behavior([ErrorHandler()], message) + result = self.comp.apply_registered_behavior([[ErrorHandler(None)]], message) self.assertEquals(len(result), 1) self.assertEquals(result[0].get_type(), "error") self.assertEquals(len(self.comp.stream.sent), 1) @@ -224,7 +225,7 @@ class JCLComponent_TestCase(unittest.TestCase): to_jid="account11@jcl.test.com") handler1 = HandlerMock() handler2 = HandlerMock() - result = self.comp.apply_registered_behavior([handler1, handler2], + result = self.comp.apply_registered_behavior([[handler1], [handler2]], message) self.assertEquals(len(result), 2) self.assertEquals(result[0][0], message) @@ -237,9 +238,8 @@ class JCLComponent_TestCase(unittest.TestCase): to_jid="account11@jcl.test.com") handler1 = HandlerMock() handler2 = HandlerMock() - result = self.comp.apply_registered_behavior([handler1, handler2], - message, - apply_all=False) + result = self.comp.apply_registered_behavior([[handler1, handler2]], + message) self.assertEquals(len(result), 1) self.assertEquals(result[0][0], message) self.assertEquals(len(handler1.handled), 1) @@ -316,7 +316,7 @@ class JCLComponent_TestCase(unittest.TestCase): self.comp.time_unit = 1 self.max_tick_count = 1 self.comp.handle_tick = self.__handle_tick_test_time_handler - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid = "test1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -326,7 +326,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid = "test2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.run() self.assertTrue(self.comp.stream.connection_started) threads = threading.enumerate() @@ -404,7 +404,7 @@ class JCLComponent_TestCase(unittest.TestCase): self.assertTrue(True) def test_authenticated_send_probe(self): - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid = "test1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -414,7 +414,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid = "test2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.stream = MockStream() self.comp.authenticated() self.assertEqual(len(self.comp.stream.sent), 5) @@ -500,39 +500,55 @@ class JCLComponent_TestCase(unittest.TestCase): # 'disco_get_info' tests ########################################################################### def test_disco_get_info(self): + self.comp.stream = MockStream() + self.comp.stream_class = MockStream info_query = Iq(stanza_type="get", from_jid="user1@test.com", to_jid="jcl.test.com") - disco_info = self.comp.disco_get_info(None, info_query) + disco_infos = self.comp.disco_get_info(None, info_query) + self.assertEquals(len(disco_infos), 1) + disco_info = disco_infos[0] self.assertEquals(disco_info.get_identities()[0].get_name(), self.comp.name) self.assertTrue(disco_info.has_feature("jabber:iq:version")) self.assertTrue(disco_info.has_feature("jabber:iq:register")) def test_disco_get_info_multiple_account_type(self): self.comp.account_manager.account_classes = (ExampleAccount, Example2Account) + self.comp.stream = MockStream() + self.comp.stream_class = MockStream info_query = Iq(stanza_type="get", from_jid="user1@test.com", to_jid="jcl.test.com") - disco_info = self.comp.disco_get_info(None, info_query) + disco_infos = self.comp.disco_get_info(None, info_query) + self.assertEquals(len(disco_infos), 1) + disco_info = disco_infos[0] self.assertEquals(disco_info.get_identities()[0].get_name(), self.comp.name) self.assertTrue(disco_info.has_feature("jabber:iq:version")) self.assertFalse(disco_info.has_feature("jabber:iq:register")) def test_disco_get_info_node(self): + self.comp.stream = MockStream() + self.comp.stream_class = MockStream info_query = Iq(stanza_type="get", from_jid="user1@test.com", to_jid="node_test@jcl.test.com") - disco_info = self.comp.disco_get_info("node_test", info_query) + disco_infos = self.comp.disco_get_info("node_test", info_query) + self.assertEquals(len(disco_infos), 1) + disco_info = disco_infos[0] self.assertTrue(disco_info.has_feature("jabber:iq:register")) def test_disco_get_info_long_node(self): self.comp.account_manager.account_classes = (ExampleAccount, Example2Account) + self.comp.stream = MockStream() + self.comp.stream_class = MockStream info_query = Iq(stanza_type="get", from_jid="user1@test.com", to_jid="node_test@jcl.test.com/node_type") - disco_info = self.comp.disco_get_info("node_type/node_test", - info_query) + disco_infos = self.comp.disco_get_info("node_type/node_test", + info_query) + self.assertEquals(len(disco_infos), 1) + disco_info = disco_infos[0] self.assertTrue(disco_info.has_feature("jabber:iq:register")) def test_disco_get_info_root_unknown_node(self): @@ -540,14 +556,17 @@ class JCLComponent_TestCase(unittest.TestCase): from_jid="user1@test.com", to_jid="jcl.test.com") disco_info = self.comp.disco_get_info("unknown", info_query) - self.assertEquals(disco_info, None) + self.assertEquals(disco_info, []) def test_disco_get_info_command_list(self): + self.comp.stream = MockStream() + self.comp.stream_class = MockStream info_query = Iq(stanza_type="get", from_jid="user1@test.com", to_jid="jcl.test.com") - disco_info = self.comp.disco_get_info("list", info_query) - self.assertNotEquals(disco_info, None) + disco_infos = self.comp.disco_get_info("list", info_query) + self.assertEquals(len(disco_infos), 1) + disco_info = disco_infos[0] self.assertTrue(disco_info.has_feature("http://jabber.org/protocol/commands")) self.assertEquals(len(disco_info.get_identities()), 1) self.assertEquals(disco_info.get_identities()[0].get_category(), @@ -562,88 +581,92 @@ class JCLComponent_TestCase(unittest.TestCase): ########################################################################### def test_disco_get_items_1type_no_node(self): """get_items on main entity. Must list accounts""" - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() + self.comp.stream = MockStream() + self.comp.stream_class = MockStream account1 = Account(user_jid = "user1@test.com", \ name = "account1", \ jid = "account1@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() info_query = Iq(stanza_type = "get", \ from_jid = "user1@test.com", \ to_jid = "jcl.test.com") disco_items = self.comp.disco_get_items(None, info_query) - self.assertEquals(len(disco_items.get_items()), 1) - disco_item = disco_items.get_items()[0] + self.assertEquals(len(disco_items[0].get_items()), 1) + disco_item = disco_items[0].get_items()[0] self.assertEquals(disco_item.get_jid(), account1.jid) self.assertEquals(disco_item.get_node(), account1.name) self.assertEquals(disco_item.get_name(), account1.long_name) def test_disco_get_items_unknown_node(self): self.comp.account_manager.account_classes = (ExampleAccount, ) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = ExampleAccount(user_jid="user1@test.com", name="account11", jid="account11@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() info_query = Iq(stanza_type="get", from_jid="user1@test.com", to_jid="jcl.test.com") disco_items = self.comp.disco_get_items("unknown", info_query) - self.assertEquals(disco_items, None) + self.assertEquals(disco_items, []) def test_disco_get_items_unknown_node_multiple_account_types(self): self.comp.account_manager.account_classes = (ExampleAccount, Example2Account) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = ExampleAccount(user_jid="user1@test.com", name="account11", jid="account11@jcl.test.com") account21 = Example2Account(user_jid="user1@test.com", name="account21", jid="account21@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() info_query = Iq(stanza_type="get", from_jid="user1@test.com", to_jid="jcl.test.com") self.comp.account_manager.has_multiple_account_type = True disco_items = self.comp.disco_get_items("unknown", info_query) - self.assertEquals(disco_items, None) + self.assertEquals(disco_items, []) def test_disco_get_items_1type_with_node(self): """get_items on an account. Must return nothing""" - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account1 = Account(user_jid="user1@test.com", name="account1", jid="account1@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() info_query = Iq(stanza_type="get", from_jid="user1@test.com", to_jid="account1@jcl.test.com") disco_items = self.comp.disco_get_items("account1", info_query) - self.assertEquals(disco_items, None) + self.assertEquals(disco_items, []) def test_disco_get_items_2types_no_node(self): """get_items on main entity. Must account types""" self.comp.lang = LangExample() self.comp.account_manager.account_classes = (ExampleAccount, Example2Account) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + self.comp.stream = MockStream() + self.comp.stream_class = MockStream + model.db_connect() account11 = ExampleAccount(user_jid="user1@test.com", name="account11", jid="account11@jcl.test.com") account21 = Example2Account(user_jid="user1@test.com", name="account21", jid="account21@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() info_query = Iq(stanza_type="get", from_jid="user1@test.com", to_jid="jcl.test.com") disco_items = self.comp.disco_get_items(None, info_query) - self.assertEquals(len(disco_items.get_items()), 2) - disco_item = disco_items.get_items()[0] + self.assertEquals(len(disco_items[0].get_items()), 2) + disco_item = disco_items[0].get_items()[0] self.assertEquals(unicode(disco_item.get_jid()), unicode(self.comp.jid) + "/Example") self.assertEquals(disco_item.get_node(), "Example") self.assertEquals(disco_item.get_name(), LangExample.en.type_example_name) - disco_item = disco_items.get_items()[1] + disco_item = disco_items[0].get_items()[1] self.assertEquals(unicode(disco_item.get_jid()), unicode(self.comp.jid) + "/Example2") self.assertEquals(disco_item.get_node(), "Example2") @@ -656,26 +679,28 @@ class JCLComponent_TestCase(unittest.TestCase): """get_items on the first account type node. Must return account list of that type for the current user""" self.comp.account_manager.account_classes = (ExampleAccount, Example2Account) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) - account11 = ExampleAccount(user_jid = "user1@test.com", \ - name = "account11", \ - jid = "account11@jcl.test.com") - account12 = ExampleAccount(user_jid = "user2@test.com", \ - name = "account12", \ - jid = "account12@jcl.test.com") - account21 = Example2Account(user_jid = "user1@test.com", \ - name = "account21", \ - jid = "account21@jcl.test.com") - account22 = Example2Account(user_jid = "user2@test.com", \ - name = "account22", \ - jid = "account22@jcl.test.com") - del account.hub.threadConnection - info_query = Iq(stanza_type = "get", \ - from_jid = "user1@test.com", \ - to_jid = "jcl.test.com/Example") + self.comp.stream = MockStream() + self.comp.stream_class = MockStream + model.db_connect() + account11 = ExampleAccount(user_jid="user1@test.com", + name="account11", + jid="account11@jcl.test.com") + account12 = ExampleAccount(user_jid="user2@test.com", + name="account12", + jid="account12@jcl.test.com") + account21 = Example2Account(user_jid="user1@test.com", + name="account21", + jid="account21@jcl.test.com") + account22 = Example2Account(user_jid="user2@test.com", + name="account22", + jid="account22@jcl.test.com") + model.db_disconnect() + info_query = Iq(stanza_type="get", + from_jid="user1@test.com", + to_jid="jcl.test.com/Example") disco_items = self.comp.disco_get_items("Example", info_query) - self.assertEquals(len(disco_items.get_items()), 1) - disco_item = disco_items.get_items()[0] + self.assertEquals(len(disco_items[0].get_items()), 1) + disco_item = disco_items[0].get_items()[0] self.assertEquals(unicode(disco_item.get_jid()), unicode(account11.jid) + "/Example") self.assertEquals(disco_item.get_node(), "Example/" + account11.name) self.assertEquals(disco_item.get_name(), account11.long_name) @@ -684,26 +709,28 @@ class JCLComponent_TestCase(unittest.TestCase): """get_items on the second account type node. Must return account list of that type for the current user""" self.comp.account_manager.account_classes = (ExampleAccount, Example2Account) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) - account11 = ExampleAccount(user_jid = "user1@test.com", \ - name = "account11", \ - jid = "account11@jcl.test.com") - account12 = ExampleAccount(user_jid = "user2@test.com", \ - name = "account12", \ - jid = "account12@jcl.test.com") - account21 = Example2Account(user_jid = "user1@test.com", \ - name = "account21", \ - jid = "account21@jcl.test.com") - account22 = Example2Account(user_jid = "user2@test.com", \ - name = "account22", \ - jid = "account22@jcl.test.com") - del account.hub.threadConnection - info_query = Iq(stanza_type = "get", \ - from_jid = "user2@test.com", \ - to_jid = "jcl.test.com/Example2") + self.comp.stream = MockStream() + self.comp.stream_class = MockStream + model.db_connect() + account11 = ExampleAccount(user_jid="user1@test.com", + name="account11", + jid="account11@jcl.test.com") + account12 = ExampleAccount(user_jid="user2@test.com", + name="account12", + jid="account12@jcl.test.com") + account21 = Example2Account(user_jid="user1@test.com", + name="account21", + jid="account21@jcl.test.com") + account22 = Example2Account(user_jid="user2@test.com", + name="account22", + jid="account22@jcl.test.com") + model.db_disconnect() + info_query = Iq(stanza_type="get", + from_jid="user2@test.com", + to_jid="jcl.test.com/Example2") disco_items = self.comp.disco_get_items("Example2", info_query) - self.assertEquals(len(disco_items.get_items()), 1) - disco_item = disco_items.get_items()[0] + self.assertEquals(len(disco_items[0].get_items()), 1) + disco_item = disco_items[0].get_items()[0] self.assertEquals(unicode(disco_item.get_jid()), unicode(account22.jid) + "/Example2") self.assertEquals(disco_item.get_node(), "Example2/" + account22.name) self.assertEquals(disco_item.get_name(), account22.long_name) @@ -711,39 +738,41 @@ class JCLComponent_TestCase(unittest.TestCase): def test_disco_get_items_2types_with_long_node(self): """get_items on a first type account. Must return nothing""" self.comp.account_manager.account_classes = (ExampleAccount, Example2Account) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) - account1 = ExampleAccount(user_jid = "user1@test.com", \ - name = "account1", \ - jid = "account1@jcl.test.com") - del account.hub.threadConnection - info_query = Iq(stanza_type = "get", \ - from_jid = "user1@test.com", \ - to_jid = "account1@jcl.test.com/Example") + model.db_connect() + account1 = ExampleAccount(user_jid="user1@test.com", + name="account1", + jid="account1@jcl.test.com") + model.db_disconnect() + info_query = Iq(stanza_type="get", + from_jid="user1@test.com", + to_jid="account1@jcl.test.com/Example") disco_items = self.comp.disco_get_items("Example/account1", info_query) - self.assertEquals(disco_items, None) + self.assertEquals(disco_items, []) def test_disco_get_items_2types_with_long_node2(self): """get_items on a second type account. Must return nothing""" self.comp.account_manager.account_classes = (ExampleAccount, Example2Account) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) - account1 = Example2Account(user_jid = "user1@test.com", \ - name = "account1", \ - jid = "account1@jcl.test.com") - del account.hub.threadConnection - info_query = Iq(stanza_type = "get", \ - from_jid = "user1@test.com", \ - to_jid = "account1@jcl.test.com/Example2") + model.db_connect() + account1 = Example2Account(user_jid="user1@test.com", + name="account1", + jid="account1@jcl.test.com") + model.db_disconnect() + info_query = Iq(stanza_type="get", + from_jid="user1@test.com", + to_jid="account1@jcl.test.com/Example2") disco_items = self.comp.disco_get_items("Example2/account1", info_query) - self.assertEquals(disco_items, None) + self.assertEquals(disco_items, []) def test_disco_get_items_list_commands(self): + self.comp.stream = MockStream() + self.comp.stream_class = MockStream info_query = Iq(stanza_type="get", from_jid="user1@test.com", to_jid="jcl.test.com") disco_items = self.comp.disco_get_items("http://jabber.org/protocol/commands", info_query) - self.assertEquals(len(disco_items.get_items()), 35) - item = disco_items.get_items()[0] + self.assertEquals(len(disco_items[0].get_items()), 35) + item = disco_items[0].get_items()[0] self.assertEquals(item.get_node(), "list") self.assertEquals(item.get_name(), Lang.en.command_list) @@ -873,7 +902,7 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_get_register_exist(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid="user1@test.com", name="account11", jid="account11@jcl.test.com") @@ -883,7 +912,7 @@ class JCLComponent_TestCase(unittest.TestCase): account21 = Account(user_jid="user1@test.com", name="account21", jid="account21@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_get_register(Iq(stanza_type="get", from_jid="user1@test.com", to_jid="account11@jcl.test.com")) @@ -917,7 +946,7 @@ class JCLComponent_TestCase(unittest.TestCase): self.assertEquals(value[0].content, "account11") def test_handle_get_register_exist_complex(self): - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() self.comp.stream = MockStream() self.comp.stream_class = MockStream account1 = ExampleAccount(user_jid = "user1@test.com", \ @@ -944,7 +973,7 @@ class JCLComponent_TestCase(unittest.TestCase): store_password = False, \ test_enum = "choice1", \ test_int = 21) - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_get_register(Iq(stanza_type = "get", \ from_jid = "user1@test.com", \ to_jid = "account1@jcl.test.com")) @@ -1082,7 +1111,7 @@ class JCLComponent_TestCase(unittest.TestCase): x_data.as_xml(query, None) self.comp.handle_set_register(iq_set) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() accounts = Account.select(\ Account.q.user_jid == "user1@test.com" \ and Account.q.name == "account1") @@ -1091,7 +1120,7 @@ class JCLComponent_TestCase(unittest.TestCase): self.assertEquals(_account.user_jid, "user1@test.com") self.assertEquals(_account.name, "account1") self.assertEquals(_account.jid, "account1@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() stanza_sent = self.comp.stream.sent self.assertEquals(len(stanza_sent), 4) @@ -1139,7 +1168,7 @@ class JCLComponent_TestCase(unittest.TestCase): x_data.as_xml(query, None) self.comp.handle_set_register(iq_set) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() accounts = Account.select(\ Account.q.user_jid == "user1@test.com" \ and Account.q.name == "account1") @@ -1148,7 +1177,7 @@ class JCLComponent_TestCase(unittest.TestCase): self.assertEquals(_account.user_jid, "user1@test.com") self.assertEquals(_account.name, "account1") self.assertEquals(_account.jid, "account1@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() stanza_sent = self.comp.stream.sent self.assertEquals(len(stanza_sent), 4) @@ -1211,7 +1240,7 @@ class JCLComponent_TestCase(unittest.TestCase): x_data.as_xml(query, None) self.comp.handle_set_register(iq_set) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() accounts = Account.select(\ Account.q.user_jid == "user1@test.com" \ and Account.q.name == "account1") @@ -1225,7 +1254,7 @@ class JCLComponent_TestCase(unittest.TestCase): self.assertFalse(_account.store_password) self.assertEquals(_account.test_enum, "choice3") self.assertEquals(_account.test_int, 43) - del account.hub.threadConnection + model.db_disconnect() stanza_sent = self.comp.stream.sent self.assertEquals(len(stanza_sent), 4) @@ -1276,7 +1305,7 @@ class JCLComponent_TestCase(unittest.TestCase): x_data.as_xml(query) self.comp.handle_set_register(iq_set) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() accounts = Account.select(\ Account.q.user_jid == "user1@test.com" \ and Account.q.name == "account1") @@ -1290,7 +1319,7 @@ class JCLComponent_TestCase(unittest.TestCase): self.assertTrue(_account.store_password) self.assertEquals(_account.test_enum, "choice2") self.assertEquals(_account.test_int, 44) - del account.hub.threadConnection + model.db_disconnect() def test_handle_set_register_new_name_mandatory(self): self.comp.stream = MockStream() @@ -1303,12 +1332,12 @@ class JCLComponent_TestCase(unittest.TestCase): x_data.as_xml(query) self.comp.handle_set_register(iq_set) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() accounts = Account.select(\ Account.q.user_jid == "user1@test.com" \ and Account.q.name == "account1") self.assertEquals(accounts.count(), 0) - del account.hub.threadConnection + model.db_disconnect() stanza_sent = self.comp.stream.sent self.assertEquals(len(stanza_sent), 1) @@ -1335,12 +1364,12 @@ class JCLComponent_TestCase(unittest.TestCase): x_data.as_xml(query) self.comp.handle_set_register(iq_set) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() accounts = Account.select(\ Account.q.user_jid == "user1@test.com" \ and Account.q.name == "account1") self.assertEquals(accounts.count(), 0) - del account.hub.threadConnection + model.db_disconnect() stanza_sent = self.comp.stream.sent self.assertEquals(len(stanza_sent), 1) @@ -1353,7 +1382,7 @@ class JCLComponent_TestCase(unittest.TestCase): Lang.en.mandatory_field % ("login")) def test_handle_set_register_update_complex(self): - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() self.comp.stream = MockStream() self.comp.stream_class = MockStream self.comp.account_manager.account_classes = (Example2Account, ExampleAccount) @@ -1373,7 +1402,7 @@ class JCLComponent_TestCase(unittest.TestCase): store_password = True, \ test_enum = "choice1", \ test_int = 21) - del account.hub.threadConnection + model.db_disconnect() x_data = Form("submit") x_data.add_field(name = "name", \ value = "account1", \ @@ -1400,7 +1429,7 @@ class JCLComponent_TestCase(unittest.TestCase): x_data.as_xml(query) self.comp.handle_set_register(iq_set) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() accounts = Account.select(\ Account.q.user_jid == "user1@test.com" \ and Account.q.name == "account1") @@ -1415,7 +1444,7 @@ class JCLComponent_TestCase(unittest.TestCase): self.assertFalse(_account.store_password) self.assertEquals(_account.test_enum, "choice3") self.assertEquals(_account.test_int, 43) - del account.hub.threadConnection + model.db_disconnect() stanza_sent = self.comp.stream.sent self.assertEquals(len(stanza_sent), 2) @@ -1437,7 +1466,7 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_set_register_remove(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account1", \ jid = "account1@jcl.test.com") @@ -1447,7 +1476,7 @@ class JCLComponent_TestCase(unittest.TestCase): account21 = Account(user_jid = "user2@test.com", \ name = "account1", \ jid = "account1@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() iq_set = Iq(stanza_type = "set", \ from_jid = "user1@test.com", \ to_jid = "jcl.test.com") @@ -1455,7 +1484,7 @@ class JCLComponent_TestCase(unittest.TestCase): query.newChild(None, "remove", None) self.comp.handle_set_register(iq_set) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() accounts = Account.select(\ Account.q.user_jid == "user1@test.com") self.assertEquals(accounts.count(), 0) @@ -1466,7 +1495,7 @@ class JCLComponent_TestCase(unittest.TestCase): self.assertEquals(_account.user_jid, "user2@test.com") self.assertEquals(_account.name, "account1") self.assertEquals(_account.jid, "account1@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() stanza_sent = self.comp.stream.sent self.assertEquals(len(stanza_sent), 6) @@ -1504,7 +1533,7 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_presence_available_to_component(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -1514,7 +1543,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid = "user2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_presence_available(Presence(\ stanza_type = "available", \ from_jid = "user1@test.com",\ @@ -1551,7 +1580,7 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_presence_available_to_component_legacy_users(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid="user1@test.com", name="account11", jid="account11@jcl.test.com") @@ -1576,7 +1605,7 @@ class JCLComponent_TestCase(unittest.TestCase): legacy_jid21 = LegacyJID(legacy_address="u21@test.com", jid="u21%test.com@jcl.test.com", account=account2) - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_presence_available(Presence(\ stanza_type="available", from_jid="user1@test.com", @@ -1641,7 +1670,7 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_presence_available_to_component_unknown_user(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -1651,7 +1680,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid = "user2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_presence_available(Presence(\ stanza_type = "available", \ from_jid = "unknown@test.com",\ @@ -1662,7 +1691,7 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_presence_available_to_account(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -1672,7 +1701,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid = "user2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_presence_available(Presence(\ stanza_type = "available", \ from_jid = "user1@test.com",\ @@ -1687,8 +1716,8 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_presence_available_to_registered_handlers(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - self.comp.available_handlers += [DefaultPresenceHandler()] - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + self.comp.presence_available_handlers += [(DefaultPresenceHandler(self.comp),)] + model.db_connect() account11 = Account(user_jid="user1@test.com", name="account11", jid="account11@jcl.test.com") @@ -1698,7 +1727,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid="user2@test.com", name="account2", jid="account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_presence_available(Presence(\ stanza_type="available", from_jid="user1@test.com", @@ -1714,7 +1743,7 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_presence_available_to_account_unknown_user(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -1724,7 +1753,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid = "user2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_presence_available(Presence(\ stanza_type = "available", \ from_jid = "unknown@test.com",\ @@ -1735,7 +1764,7 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_presence_available_to_unknown_account(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -1745,7 +1774,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid = "user2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_presence_available(Presence(\ stanza_type = "available", \ from_jid = "user1@test.com",\ @@ -1756,7 +1785,7 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_presence_available_to_account_live_password(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -1767,7 +1796,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid = "user2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_presence_available(Presence(\ stanza_type = "available", \ from_jid = "user1@test.com",\ @@ -1782,7 +1811,7 @@ class JCLComponent_TestCase(unittest.TestCase): self.assertEqual(presence.get_type(), None) def test_handle_presence_available_to_account_live_password_complex(self): - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() self.comp.stream = MockStream() self.comp.stream_class = MockStream account11 = ExampleAccount(user_jid = "user1@test.com", \ @@ -1795,7 +1824,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = ExampleAccount(user_jid = "user2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_presence_available(Presence(\ stanza_type = "available", \ from_jid = "user1@test.com",\ @@ -1828,7 +1857,7 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_presence_unavailable_to_component(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -1838,7 +1867,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid = "user2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_presence_unavailable(Presence(\ stanza_type = "unavailable", \ from_jid = "user1@test.com",\ @@ -1878,7 +1907,7 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_presence_unavailable_to_component_legacy_users(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid="user1@test.com", name="account11", jid="account11@jcl.test.com") @@ -1903,7 +1932,7 @@ class JCLComponent_TestCase(unittest.TestCase): legacy_jid21 = LegacyJID(legacy_address="u21@test.com", jid="u21%test.com@jcl.test.com", account=account2) - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_presence_unavailable(Presence(\ stanza_type="unavailable", from_jid="user1@test.com", @@ -1968,7 +1997,7 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_presence_unavailable_to_component_unknown_user(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -1978,7 +2007,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid = "user2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_presence_unavailable(Presence(\ stanza_type = "unavailable", \ from_jid = "unknown@test.com",\ @@ -1989,34 +2018,34 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_presence_unavailable_to_account(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) - account11 = Account(user_jid = "user1@test.com", \ - name = "account11", \ - jid = "account11@jcl.test.com") - account12 = Account(user_jid = "user1@test.com", \ - name = "account12", \ - jid = "account12@jcl.test.com") - account2 = Account(user_jid = "user2@test.com", \ - name = "account2", \ - jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_connect() + account11 = Account(user_jid="user1@test.com", + name="account11", + jid="account11@jcl.test.com") + account12 = Account(user_jid="user1@test.com", + name="account12", + jid="account12@jcl.test.com") + account2 = Account(user_jid="user2@test.com", + name="account2", + jid="account2@jcl.test.com") + model.db_disconnect() self.comp.handle_presence_unavailable(Presence(\ - stanza_type = "unavailable", \ - from_jid = "user1@test.com",\ - to_jid = "account11@jcl.test.com")) + stanza_type="unavailable", + from_jid="user1@test.com", + to_jid="account11@jcl.test.com")) presence_sent = self.comp.stream.sent self.assertEqual(len(presence_sent), 1) self.assertEqual(presence_sent[0].get_to(), "user1@test.com") self.assertEqual(presence_sent[0].get_from(), "account11@jcl.test.com") self.assertEqual(\ - presence_sent[0].xpath_eval("@type")[0].get_content(), \ + presence_sent[0].xpath_eval("@type")[0].get_content(), "unavailable") def test_handle_presence_unavailable_to_registered_handlers(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - self.comp.unavailable_handlers += [DefaultPresenceHandler()] - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + self.comp.presence_unavailable_handlers += [(DefaultPresenceHandler(self.comp),)] + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -2026,7 +2055,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid = "user2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_presence_unavailable(Presence(\ stanza_type = "unavailable", \ from_jid = "user1@test.com",\ @@ -2042,7 +2071,7 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_presence_unavailable_to_account_unknown_user(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -2052,7 +2081,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid = "user2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_presence_unavailable(Presence(\ stanza_type = "unavailable", \ from_jid = "unknown@test.com",\ @@ -2063,7 +2092,7 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_presence_unavailable_to_unknown_account(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -2073,7 +2102,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid = "user2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_presence_unavailable(Presence(\ stanza_type = "unavailable", \ from_jid = "user1@test.com",\ @@ -2084,7 +2113,7 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_presence_subscribe_to_component(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -2094,7 +2123,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid = "user2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_presence_subscribe(Presence(\ stanza_type = "subscribe", \ from_jid = "user1@test.com",\ @@ -2110,28 +2139,28 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_presence_subscribe_to_component_unknown_user(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) - account11 = Account(user_jid = "user1@test.com", \ - name = "account11", \ - jid = "account11@jcl.test.com") - account12 = Account(user_jid = "user1@test.com", \ - name = "account12", \ - jid = "account12@jcl.test.com") - account2 = Account(user_jid = "user2@test.com", \ - name = "account2", \ - jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_connect() + account11 = Account(user_jid="user1@test.com", + name="account11", + jid="account11@jcl.test.com") + account12 = Account(user_jid="user1@test.com", + name="account12", + jid="account12@jcl.test.com") + account2 = Account(user_jid="user2@test.com", + name="account2", + jid="account2@jcl.test.com") + model.db_disconnect() self.comp.handle_presence_subscribe(Presence(\ - stanza_type = "subscribe", \ - from_jid = "unknown@test.com",\ - to_jid = "jcl.test.com")) + stanza_type="subscribe", + from_jid="unknown@test.com", + to_jid="jcl.test.com")) presence_sent = self.comp.stream.sent self.assertEqual(len(presence_sent), 0) def test_handle_presence_subscribe_to_account(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -2141,7 +2170,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid = "user2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_presence_subscribe(Presence(\ stanza_type = "subscribe", \ from_jid = "user1@test.com",\ @@ -2157,28 +2186,28 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_presence_subscribe_to_account_unknown_user(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) - account11 = Account(user_jid = "user1@test.com", \ - name = "account11", \ - jid = "account11@jcl.test.com") - account12 = Account(user_jid = "user1@test.com", \ - name = "account12", \ - jid = "account12@jcl.test.com") - account2 = Account(user_jid = "user2@test.com", \ - name = "account2", \ - jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_connect() + account11 = Account(user_jid="user1@test.com", + name="account11", + jid="account11@jcl.test.com") + account12 = Account(user_jid="user1@test.com", + name="account12", + jid="account12@jcl.test.com") + account2 = Account(user_jid="user2@test.com", + name="account2", + jid="account2@jcl.test.com") + model.db_disconnect() self.comp.handle_presence_subscribe(Presence(\ - stanza_type = "subscribe", \ - from_jid = "unknown@test.com",\ - to_jid = "account11@jcl.test.com")) + stanza_type="subscribe", + from_jid="unknown@test.com", + to_jid="account11@jcl.test.com")) presence_sent = self.comp.stream.sent self.assertEqual(len(presence_sent), 0) def test_handle_presence_subscribe_to_unknown_account(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -2188,7 +2217,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid = "user2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_presence_subscribe(Presence(\ stanza_type = "subscribe", \ from_jid = "user1@test.com",\ @@ -2199,8 +2228,8 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_presence_subscribe_to_registered_handlers(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - self.comp.subscribe_handlers += [DefaultSubscribeHandler()] - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + self.comp.presence_subscribe_handlers += [(DefaultSubscribeHandler(self.comp),)] + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -2210,7 +2239,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid = "user2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() result = self.comp.handle_presence_subscribe(Presence(\ stanza_type = "subscribe", \ from_jid = "user1@test.com",\ @@ -2231,7 +2260,7 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_presence_unsubscribe_to_account(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -2241,7 +2270,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid = "user2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_presence_unsubscribe(Presence(\ stanza_type = "unsubscribe", \ from_jid = "user1@test.com",\ @@ -2258,7 +2287,7 @@ class JCLComponent_TestCase(unittest.TestCase): self.assertEqual(presence.get_to(), "user1@test.com") self.assertEqual(presence.xpath_eval("@type")[0].get_content(), \ "unsubscribed") - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() self.assertEquals(Account.select(\ Account.q.user_jid == "user1@test.com" \ and Account.q.name == "account11").count(), \ @@ -2268,13 +2297,13 @@ class JCLComponent_TestCase(unittest.TestCase): 1) self.assertEquals(Account.select().count(), \ 2) - del account.hub.threadConnection + model.db_disconnect() def test_handle_presence_unsubscribe_to_registered_handlers(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - self.comp.unsubscribe_handlers += [DefaultUnsubscribeHandler()] - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + self.comp.presence_unsubscribe_handlers += [(DefaultUnsubscribeHandler(self.comp),)] + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -2284,7 +2313,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid = "user2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_presence_unsubscribe(Presence(\ stanza_type = "unsubscribe", \ from_jid = "user1@test.com",\ @@ -2305,7 +2334,7 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_presence_unsubscribe_to_account_unknown_user(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -2315,22 +2344,22 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid = "user2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_presence_unsubscribe(Presence(\ stanza_type = "unsubscribe", \ from_jid = "unknown@test.com",\ to_jid = "account11@jcl.test.com")) presence_sent = self.comp.stream.sent self.assertEqual(len(presence_sent), 0) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() self.assertEquals(Account.select().count(), \ 3) - del account.hub.threadConnection + model.db_disconnect() def test_handle_presence_unsubscribe_to_unknown_account(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -2340,17 +2369,17 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid = "user2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_presence_unsubscribe(Presence(\ stanza_type = "unsubscribe", \ from_jid = "user1@test.com",\ to_jid = "unknown@jcl.test.com")) presence_sent = self.comp.stream.sent self.assertEqual(len(presence_sent), 0) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() self.assertEquals(Account.select().count(), \ 3) - del account.hub.threadConnection + model.db_disconnect() def test_handle_presence_unsubscribed(self): self.comp.stream = MockStream() @@ -2386,7 +2415,7 @@ class JCLComponent_TestCase(unittest.TestCase): self.comp.stream = MockStream() self.comp.stream_class = MockStream self.comp.authenticated() - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -2397,7 +2426,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = Account(user_jid = "user2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_message(Message(\ from_jid = "user1@test.com", \ to_jid = "account11@jcl.test.com", \ @@ -2410,7 +2439,7 @@ class JCLComponent_TestCase(unittest.TestCase): self.comp.stream = MockStream() self.comp.stream_class = MockStream self.comp.authenticated() - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = ExampleAccount(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -2421,7 +2450,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = ExampleAccount(user_jid = "user2@test.com", \ name = "account2", \ jid = "account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() self.comp.handle_message(Message(\ from_jid = "user1@test.com", \ to_jid = "account11@jcl.test.com", \ @@ -2444,12 +2473,12 @@ class JCLComponent_TestCase(unittest.TestCase): def test_send_error_first(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() _account = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") exception = Exception("test exception") - self.comp.send_error_to_account(_account, exception) + self.comp.send_error(_account, exception) self.assertEqual(len(self.comp.stream.sent), 1) error_sent = self.comp.stream.sent[0] self.assertEqual(error_sent.get_to(), _account.user_jid) @@ -2458,18 +2487,18 @@ class JCLComponent_TestCase(unittest.TestCase): self.assertEqual(error_sent.get_subject(), _account.default_lang_class.error_subject) self.assertEqual(error_sent.get_body(), _account.default_lang_class.error_body \ % (exception)) - del account.hub.threadConnection + model.db_disconnect() def test_send_error_second(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() _account = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") _account.in_error = True exception = Exception("test exception") - self.comp.send_error_to_account(_account, exception) + self.comp.send_error(_account, exception) self.assertEqual(len(self.comp.stream.sent), 0) def test_send_stanzas(self): @@ -2495,7 +2524,7 @@ class JCLComponent_TestCase(unittest.TestCase): def test_handle_command_execute_list(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = ExampleAccount(user_jid="user1@test.com", name="account11", jid="account11@jcl.test.com") @@ -2505,7 +2534,7 @@ class JCLComponent_TestCase(unittest.TestCase): account2 = ExampleAccount(user_jid="user2@test.com", name="account2", jid="account2@jcl.test.com") - del account.hub.threadConnection + model.db_disconnect() info_query = Iq(stanza_type="set", from_jid="user1@test.com", to_jid="jcl.test.com") @@ -3159,24 +3188,25 @@ class JCLComponent_TestCase(unittest.TestCase): class Handler_TestCase(unittest.TestCase): def setUp(self): - self.handler = Handler() + self.handler = Handler(None) if os.path.exists(DB_PATH): os.unlink(DB_PATH) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connection_str = 'sqlite://' + DB_URL + model.db_connect() Account.createTable(ifNotExists = True) - del account.hub.threadConnection + model.db_disconnect() def tearDown(self): - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() Account.dropTable(ifExists = True) del TheURIOpener.cachedURIs['sqlite://' + DB_URL] - account.hub.threadConnection.close() - del account.hub.threadConnection + model.hub.threadConnection.close() + model.db_disconnect() if os.path.exists(DB_PATH): os.unlink(DB_PATH) def test_filter(self): - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -3185,184 +3215,16 @@ class Handler_TestCase(unittest.TestCase): jid = "account12@jcl.test.com") accounts = self.handler.filter(None, None) self.assertEquals(accounts.count(), 2) - del account.hub.threadConnection + model.db_disconnect() def test_handle(self): self.assertEquals(self.handler.handle(None, None, None), []) -class DefaultSubscribeHandler_TestCase(unittest.TestCase): - def setUp(self): - self.handler = DefaultSubscribeHandler() - - def test_handle(self): - presence = Presence(from_jid="user1@test.com", - to_jid="user1%test.com@jcl.test.com", - stanza_type="subscribe") - result = self.handler.handle(presence, None, []) - self.assertEquals(len(result), 2) - self.assertEquals(result[0].get_to(), "user1@test.com") - self.assertEquals(result[0].get_from(), "user1%test.com@jcl.test.com") - self.assertEquals(result[0].get_type(), "subscribe") - self.assertEquals(result[1].get_to(), "user1@test.com") - self.assertEquals(result[1].get_from(), "user1%test.com@jcl.test.com") - self.assertEquals(result[1].get_type(), "subscribed") - -class DefaultUnsubscribeHandler_TestCase(unittest.TestCase): - def setUp(self): - self.handler = DefaultUnsubscribeHandler() - - def test_handle(self): - presence = Presence(from_jid = "user1@test.com", \ - to_jid = "user1%test.com@jcl.test.com", \ - stanza_type = "unsubscribe") - result = self.handler.handle(presence, None, []) - self.assertEquals(len(result), 2) - self.assertEquals(result[0].get_to(), "user1@test.com") - self.assertEquals(result[0].get_from(), "user1%test.com@jcl.test.com") - self.assertEquals(result[0].get_type(), "unsubscribe") - self.assertEquals(result[1].get_to(), "user1@test.com") - self.assertEquals(result[1].get_from(), "user1%test.com@jcl.test.com") - self.assertEquals(result[1].get_type(), "unsubscribed") - -class DefaultPresenceHandler_TestCase(unittest.TestCase): - def setUp(self): - self.handler = DefaultPresenceHandler() - - def test_handle_away(self): - presence = Presence(from_jid = "user1@test.com", \ - to_jid = "user1%test.com@jcl.test.com", \ - stanza_type = "available", \ - show = "away") - result = self.handler.handle(presence, None, []) - self.assertEquals(len(result), 1) - self.assertEquals(result[0].get_to(), "user1@test.com") - self.assertEquals(result[0].get_from(), "user1%test.com@jcl.test.com") - self.assertEquals(result[0].get_type(), None) - self.assertEquals(result[0].get_show(), "away") - - def test_handle_offline(self): - presence = Presence(from_jid = "user1@test.com", \ - to_jid = "user1%test.com@jcl.test.com", \ - stanza_type = "unavailable") - result = self.handler.handle(presence, None, []) - self.assertEquals(len(result), 1) - self.assertEquals(result[0].get_to(), "user1@test.com") - self.assertEquals(result[0].get_from(), "user1%test.com@jcl.test.com") - self.assertEquals(result[0].get_type(), "unavailable") - -class PasswordMessageHandler_TestCase(unittest.TestCase): - def setUp(self): - self.handler = PasswordMessageHandler() - if os.path.exists(DB_PATH): - os.unlink(DB_PATH) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) - Account.createTable(ifNotExists = True) - ExampleAccount.createTable(ifNotExists = True) - del account.hub.threadConnection - - def tearDown(self): - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) - ExampleAccount.dropTable(ifExists = True) - Account.dropTable(ifExists = True) - del TheURIOpener.cachedURIs['sqlite://' + DB_URL] - account.hub.threadConnection.close() - del account.hub.threadConnection - if os.path.exists(DB_PATH): - os.unlink(DB_PATH) - - def test_filter_waiting_password(self): - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) - account11 = ExampleAccount(user_jid = "user1@test.com", \ - name = "account11", \ - jid = "account11@jcl.test.com") - account11.waiting_password_reply = True - account12 = ExampleAccount(user_jid = "user1@test.com", \ - name = "account12", \ - jid = "account12@jcl.test.com") - message = Message(from_jid = "user1@test.com", \ - to_jid = "account11@jcl.test.com", \ - subject = "[PASSWORD]", \ - body = "secret") - accounts = self.handler.filter(message, None) - self.assertEquals(accounts.count(), 1) - self.assertEquals(accounts[0].name, "account11") - del account.hub.threadConnection - - def test_filter_not_waiting_password(self): - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) - account11 = ExampleAccount(user_jid = "user1@test.com", \ - name = "account11", \ - jid = "account11@jcl.test.com") - account11.waiting_password_reply = False - account12 = ExampleAccount(user_jid = "user1@test.com", \ - name = "account12", \ - jid = "account12@jcl.test.com") - message = Message(from_jid = "user1@test.com", \ - to_jid = "account11@jcl.test.com", \ - subject = "[PASSWORD]", \ - body = "secret") - accounts = self.handler.filter(message, None) - self.assertEquals(accounts, None) - del account.hub.threadConnection - - def test_filter_not_good_message(self): - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) - account11 = ExampleAccount(user_jid = "user1@test.com", \ - name = "account11", \ - jid = "account11@jcl.test.com") - account11.waiting_password_reply = True - account12 = ExampleAccount(user_jid = "user1@test.com", \ - name = "account12", \ - jid = "account12@jcl.test.com") - message = Message(from_jid = "user1@test.com", \ - to_jid = "account11@jcl.test.com", \ - subject = "[NOT GOOD MESSAGE]", \ - body = "secret") - accounts = self.handler.filter(message, None) - self.assertEquals(accounts, None) - del account.hub.threadConnection - - def test_filter_not_password_account(self): - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) - account11 = Account(user_jid="user1@test.com", - name="account11", - jid="account11@jcl.test.com") - account12 = Account(user_jid="user1@test.com", - name="account12", - jid="account12@jcl.test.com") - message = Message(from_jid="user1@test.com", - to_jid="account11@jcl.test.com", - subject="[PASSWORD]", - body="secret") - accounts = self.handler.filter(message, None) - self.assertEquals(accounts, None) - del account.hub.threadConnection - - def test_handle(self): - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) - account11 = ExampleAccount(user_jid="user1@test.com", - name="account11", - jid="account11@jcl.test.com") - account12 = ExampleAccount(user_jid="user1@test.com", - name="account12", - jid="account12@jcl.test.com") - message = Message(from_jid="user1@test.com", - to_jid="account11@jcl.test.com", - subject="[PASSWORD]", - body="secret") - messages = self.handler.handle(message, Lang.en, [account11]) - self.assertEquals(len(messages), 1) - self.assertEquals(account11.password, "secret") - del account.hub.threadConnection def suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(JCLComponent_TestCase, 'test')) suite.addTest(unittest.makeSuite(Handler_TestCase, 'test')) - suite.addTest(unittest.makeSuite(DefaultSubscribeHandler_TestCase, 'test')) - suite.addTest(unittest.makeSuite(DefaultUnsubscribeHandler_TestCase, 'test')) - suite.addTest(unittest.makeSuite(DefaultPresenceHandler_TestCase, 'test')) - suite.addTest(unittest.makeSuite(PasswordMessageHandler_TestCase, 'test')) return suite if __name__ == '__main__': diff --git a/src/jcl/jabber/tests/feeder.py b/src/jcl/jabber/tests/feeder.py index 5c31640..8868c65 100644 --- a/src/jcl/jabber/tests/feeder.py +++ b/src/jcl/jabber/tests/feeder.py @@ -36,6 +36,7 @@ from jcl.jabber.component import JCLComponent from jcl.jabber.feeder import FeederComponent, Feeder, Sender, MessageSender, \ HeadlineSender, FeederHandler from jcl.model.account import Account, LegacyJID +import jcl.model as model from jcl.model import account from jcl.model.tests.account import ExampleAccount, Example2Account @@ -65,24 +66,24 @@ class FeederComponent_TestCase(JCLComponent_TestCase): self.comp = FeederComponent("jcl.test.com", "password", "localhost", - "5347", - 'sqlite://' + DB_URL) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + "5347") + model.db_connection_str = 'sqlite://' + DB_URL + model.db_connect() Account.createTable(ifNotExists = True) LegacyJID.createTable(ifNotExists=True) ExampleAccount.createTable(ifNotExists = True) Example2Account.createTable(ifNotExists = True) - del account.hub.threadConnection + model.db_disconnect() def tearDown(self): - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() Account.dropTable(ifExists = True) LegacyJID.dropTable(ifExists=True) ExampleAccount.dropTable(ifExists = True) Example2Account.dropTable(ifExists = True) del TheURIOpener.cachedURIs['sqlite://' + DB_URL] - account.hub.threadConnection.close() - del account.hub.threadConnection + model.hub.threadConnection.close() + model.db_disconnect() if os.path.exists(DB_PATH): os.unlink(DB_PATH) @@ -90,8 +91,8 @@ class FeederComponent_TestCase(JCLComponent_TestCase): self.comp.time_unit = 1 self.comp.stream = MockStream() self.comp.stream_class = MockStream - run_thread = threading.Thread(target = self.comp.run, \ - name = "run_thread") + run_thread = threading.Thread(target=self.comp.run, + name="run_thread") run_thread.start() time.sleep(1) self.comp.running = False @@ -118,7 +119,7 @@ class FeederComponent_TestCase(JCLComponent_TestCase): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = Account(user_jid = "user1@test.com", \ name = "account11", \ jid = "account11@jcl.test.com") @@ -190,30 +191,30 @@ class MessageSender_TestCase(unittest.TestCase): self.comp = FeederComponent("jcl.test.com", "password", "localhost", - "5347", - 'sqlite://' + DB_URL) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + "5347") + model.db_connection_str = 'sqlite://' + DB_URL + model.db_connect() Account.createTable(ifNotExists = True) - del account.hub.threadConnection + model.db_disconnect() self.sender = MessageSender(self.comp) self.message_type = None def tearDown(self): - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() Account.dropTable(ifExists = True) del TheURIOpener.cachedURIs['sqlite://' + DB_URL] - account.hub.threadConnection.close() - del account.hub.threadConnection + model.hub.threadConnection.close() + model.db_disconnect() if os.path.exists(DB_PATH): os.unlink(DB_PATH) def test_send(self): self.comp.stream = MockStream() self.comp.stream_class = MockStream - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) - account11 = Account(user_jid = "user1@test.com", \ - name = "account11", \ - jid = "account11@jcl.test.com") + model.db_connect() + account11 = Account(user_jid="user1@test.com", + name="account11", + jid="account11@jcl.test.com") self.sender.send(account11, ("subject", "Body message")) self.assertEquals(len(self.comp.stream.sent), 1) message = self.comp.stream.sent[0] @@ -222,7 +223,7 @@ class MessageSender_TestCase(unittest.TestCase): self.assertEquals(message.get_subject(), "subject") self.assertEquals(message.get_body(), "Body message") self.assertEquals(message.get_type(), self.message_type) - del account.hub.threadConnection + model.db_disconnect() class HeadlineSender_TestCase(MessageSender_TestCase): def setUp(self): @@ -235,24 +236,25 @@ class FeederHandler_TestCase(unittest.TestCase): self.handler = FeederHandler(FeederMock(), SenderMock()) if os.path.exists(DB_PATH): os.unlink(DB_PATH) - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connection_str = 'sqlite://' + DB_URL + model.db_connect() Account.createTable(ifNotExists = True) ExampleAccount.createTable(ifNotExists = True) - del account.hub.threadConnection + model.db_disconnect() def tearDown(self): self.handler = None - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() ExampleAccount.dropTable(ifExists = True) Account.dropTable(ifExists = True) del TheURIOpener.cachedURIs['sqlite://' + DB_URL] - account.hub.threadConnection.close() - del account.hub.threadConnection + model.hub.threadConnection.close() + model.db_disconnect() if os.path.exists(DB_PATH): os.unlink(DB_PATH) def test_filter(self): - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account12 = ExampleAccount(user_jid="user2@test.com", name="account12", jid="account12@jcl.test.com") @@ -264,10 +266,10 @@ class FeederHandler_TestCase(unittest.TestCase): # accounts must be ordered by user_jid self.assertEquals(accounts[0].name, "account11") self.assertEquals(accounts[1].name, "account12") - del account.hub.threadConnection + model.db_disconnect() def test_handle(self): - account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL) + model.db_connect() account11 = ExampleAccount(user_jid="user1@test.com", name="account11", jid="account11@jcl.test.com") @@ -279,7 +281,7 @@ class FeederHandler_TestCase(unittest.TestCase): self.assertEquals(len(sent), 2) self.assertEquals(sent[0], (account11, ("subject", "body"))) self.assertEquals(sent[1], (account12, ("subject", "body"))) - del account.hub.threadConnection + model.db_disconnect() def suite(): suite = unittest.TestSuite() diff --git a/src/jcl/jabber/tests/message.py b/src/jcl/jabber/tests/message.py new file mode 100644 index 0000000..aae8caf --- /dev/null +++ b/src/jcl/jabber/tests/message.py @@ -0,0 +1,161 @@ +## +## message.py +## Login : David Rousselie +## Started on Fri Jul 6 21:40:55 2007 David Rousselie +## $Id$ +## +## Copyright (C) 2007 David Rousselie +## 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 USA +## + +import unittest +import sys +import os + +from pyxmpp.message import Message +from sqlobject.dbconnection import TheURIOpener + +from jcl.lang import Lang +from jcl.jabber.component import JCLComponent +from jcl.jabber.message import PasswordMessageHandler +import jcl.model.account as account +import jcl.model as model +from jcl.model.account import Account + +from jcl.model.tests.account import ExampleAccount + +if sys.platform == "win32": + DB_PATH = "/c|/temp/jcl_test.db" +else: + DB_PATH = "/tmp/jcl_test.db" +DB_URL = DB_PATH# + "?debug=1&debugThreading=1" + +class PasswordMessageHandler_TestCase(unittest.TestCase): + def setUp(self): + self.comp = JCLComponent("jcl.test.com", + "password", + "localhost", + "5347", + 'sqlite://' + DB_URL) + self.handler = PasswordMessageHandler(self.comp) + if os.path.exists(DB_PATH): + os.unlink(DB_PATH) + model.db_connection_str = 'sqlite://' + DB_URL + model.db_connect() + Account.createTable(ifNotExists = True) + ExampleAccount.createTable(ifNotExists = True) + model.db_disconnect() + + def tearDown(self): + model.db_connect() + ExampleAccount.dropTable(ifExists = True) + Account.dropTable(ifExists = True) + del TheURIOpener.cachedURIs['sqlite://' + DB_URL] + model.hub.threadConnection.close() + model.db_disconnect() + if os.path.exists(DB_PATH): + os.unlink(DB_PATH) + + def test_filter_waiting_password(self): + model.db_connect() + account11 = ExampleAccount(user_jid="user1@test.com", + name="account11", + jid="account11@jcl.test.com") + account11.waiting_password_reply = True + account12 = ExampleAccount(user_jid="user1@test.com", + name="account12", + jid="account12@jcl.test.com") + message = Message(from_jid="user1@test.com", + to_jid="account11@jcl.test.com", + subject="[PASSWORD]", + body="secret") + _account = self.handler.filter(message, None) + self.assertEquals(_account.name, "account11") + model.db_disconnect() + + def test_filter_not_waiting_password(self): + model.db_connect() + account11 = ExampleAccount(user_jid="user1@test.com", + name="account11", + jid="account11@jcl.test.com") + account11.waiting_password_reply = False + account12 = ExampleAccount(user_jid="user1@test.com", + name="account12", + jid="account12@jcl.test.com") + message = Message(from_jid="user1@test.com", + to_jid="account11@jcl.test.com", + subject="[PASSWORD]", + body="secret") + _account = self.handler.filter(message, None) + self.assertEquals(_account, None) + model.db_disconnect() + + def test_filter_not_good_message(self): + model.db_connect() + account11 = ExampleAccount(user_jid="user1@test.com", + name="account11", + jid="account11@jcl.test.com") + account11.waiting_password_reply = True + account12 = ExampleAccount(user_jid="user1@test.com", + name="account12", + jid="account12@jcl.test.com") + message = Message(from_jid="user1@test.com", + to_jid="account11@jcl.test.com", + subject="[WRONG MESSAGE]", + body="secret") + _account = self.handler.filter(message, None) + self.assertEquals(_account, None) + model.db_disconnect() + + def test_filter_not_password_account(self): + model.db_connect() + account11 = Account(user_jid="user1@test.com", + name="account11", + jid="account11@jcl.test.com") + account12 = Account(user_jid="user1@test.com", + name="account12", + jid="account12@jcl.test.com") + message = Message(from_jid="user1@test.com", + to_jid="account11@jcl.test.com", + subject="[PASSWORD]", + body="secret") + _account = self.handler.filter(message, None) + self.assertEquals(_account, None) + model.db_disconnect() + + def test_handle(self): + model.db_connect() + account11 = ExampleAccount(user_jid="user1@test.com", + name="account11", + jid="account11@jcl.test.com") + account12 = ExampleAccount(user_jid="user1@test.com", + name="account12", + jid="account12@jcl.test.com") + message = Message(from_jid="user1@test.com", + to_jid="account11@jcl.test.com", + subject="[PASSWORD]", + body="secret") + messages = self.handler.handle(message, Lang.en, account11) + self.assertEquals(len(messages), 1) + self.assertEquals(account11.password, "secret") + model.db_disconnect() + +def suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(PasswordMessageHandler_TestCase, 'test')) + return suite + +if __name__ == '__main__': + unittest.main(defaultTest='suite') diff --git a/src/jcl/jabber/tests/presence.py b/src/jcl/jabber/tests/presence.py new file mode 100644 index 0000000..60fb835 --- /dev/null +++ b/src/jcl/jabber/tests/presence.py @@ -0,0 +1,98 @@ +## +## presence.py +## Login : David Rousselie +## Started on Fri Jul 6 21:45:43 2007 David Rousselie +## $Id$ +## +## Copyright (C) 2007 David Rousselie +## 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 USA +## + +import unittest + +from pyxmpp.presence import Presence + +from jcl.jabber.presence import DefaultSubscribeHandler, \ + DefaultUnsubscribeHandler, DefaultPresenceHandler + +class DefaultSubscribeHandler_TestCase(unittest.TestCase): + def setUp(self): + self.handler = DefaultSubscribeHandler(None) + + def test_handle(self): + presence = Presence(from_jid="user1@test.com", + to_jid="user1%test.com@jcl.test.com", + stanza_type="subscribe") + result = self.handler.handle(presence, None, []) + self.assertEquals(len(result), 2) + self.assertEquals(result[0].get_to(), "user1@test.com") + self.assertEquals(result[0].get_from(), "user1%test.com@jcl.test.com") + self.assertEquals(result[0].get_type(), "subscribe") + self.assertEquals(result[1].get_to(), "user1@test.com") + self.assertEquals(result[1].get_from(), "user1%test.com@jcl.test.com") + self.assertEquals(result[1].get_type(), "subscribed") + +class DefaultUnsubscribeHandler_TestCase(unittest.TestCase): + def setUp(self): + self.handler = DefaultUnsubscribeHandler(None) + + def test_handle(self): + presence = Presence(from_jid="user1@test.com", + to_jid="user1%test.com@jcl.test.com", + stanza_type="unsubscribe") + result = self.handler.handle(presence, None, []) + self.assertEquals(len(result), 2) + self.assertEquals(result[0].get_to(), "user1@test.com") + self.assertEquals(result[0].get_from(), "user1%test.com@jcl.test.com") + self.assertEquals(result[0].get_type(), "unsubscribe") + self.assertEquals(result[1].get_to(), "user1@test.com") + self.assertEquals(result[1].get_from(), "user1%test.com@jcl.test.com") + self.assertEquals(result[1].get_type(), "unsubscribed") + +class DefaultPresenceHandler_TestCase(unittest.TestCase): + def setUp(self): + self.handler = DefaultPresenceHandler(None) + + def test_handle_away(self): + presence = Presence(from_jid="user1@test.com", + to_jid="user1%test.com@jcl.test.com", + stanza_type="available", + show="away") + result = self.handler.handle(presence, None, []) + self.assertEquals(len(result), 1) + self.assertEquals(result[0].get_to(), "user1@test.com") + self.assertEquals(result[0].get_from(), "user1%test.com@jcl.test.com") + self.assertEquals(result[0].get_type(), None) + self.assertEquals(result[0].get_show(), "away") + + def test_handle_offline(self): + presence = Presence(from_jid="user1@test.com", + to_jid="user1%test.com@jcl.test.com", + stanza_type="unavailable") + result = self.handler.handle(presence, None, []) + self.assertEquals(len(result), 1) + self.assertEquals(result[0].get_to(), "user1@test.com") + self.assertEquals(result[0].get_from(), "user1%test.com@jcl.test.com") + self.assertEquals(result[0].get_type(), "unavailable") + +def suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(DefaultSubscribeHandler_TestCase, 'test')) + suite.addTest(unittest.makeSuite(DefaultUnsubscribeHandler_TestCase, 'test')) + suite.addTest(unittest.makeSuite(DefaultPresenceHandler_TestCase, 'test')) + return suite + +if __name__ == '__main__': + unittest.main(defaultTest='suite') diff --git a/src/jcl/model/__init__.py b/src/jcl/model/__init__.py index 97f885b..e121431 100644 --- a/src/jcl/model/__init__.py +++ b/src/jcl/model/__init__.py @@ -1,3 +1,32 @@ """Contains data model classes""" __revision__ = "" +from sqlobject.dbconnection import ConnectionHub +from sqlobject.dbconnection import connectionForURI + +import jcl.model + +db_connected = False +db_connection_str = "" + +# create a hub to attach a per thread connection +hub = ConnectionHub() + +def db_connect(): + """ + Create a new connection to the DataBase (SQLObject use connection + pool) associated to the current thread. + """ + if not jcl.model.db_connected: + jcl.model.hub.threadConnection = \ + connectionForURI(db_connection_str) + # account.hub.threadConnection.debug = True + jcl.model.db_connected = True + +def db_disconnect(): + """ + Delete connection associated to the current thread. + """ + if jcl.model.db_connected: + del jcl.model.hub.threadConnection + jcl.model.db_connected = False diff --git a/src/jcl/model/account.py b/src/jcl/model/account.py index a468f2a..e660a95 100644 --- a/src/jcl/model/account.py +++ b/src/jcl/model/account.py @@ -28,16 +28,16 @@ __revision__ = "$Id: account.py,v 1.3 2005/09/18 20:24:07 dax Exp $" from sqlobject.inheritance import InheritableSQLObject from sqlobject.col import StringCol, EnumCol, IntCol, BoolCol, ForeignKey -from sqlobject.dbconnection import ConnectionHub from sqlobject.joins import MultipleJoin +from sqlobject.sqlbuilder import AND from jcl.lang import Lang from jcl.error import FieldError +import jcl.model as model OFFLINE = "offline" ONLINE = "online" - def default_post_func(field_value, default_func, bare_from_jid): """Default post process function: do nothing""" if field_value is None or str(field_value) == "": @@ -57,13 +57,32 @@ def mandatory_field(field_value): raise FieldError # TODO : add translated message return field_value -# create a hub to attach a per thread connection -hub = ConnectionHub() +def get_account(name, bare_user_jid): + result = None + model.db_connect() + accounts = Account.select(\ + AND(Account.q.name == name, + Account.q.user_jid == unicode(bare_user_jid))) + if accounts.count() > 0: + result = accounts[0] + model.db_disconnect() + return result + +def get_accounts(bare_user_jid): + model.db_connect() + accounts = Account.select(\ + Account.q.user_jid == unicode(bare_user_jid)) + if accounts.count() == 0: + model.db_disconnect() + return + for _account in accounts: + yield _account + model.db_disconnect() class Account(InheritableSQLObject): """Base Account class""" _cacheValue = False - _connection = hub + _connection = model.hub user_jid = StringCol() name = StringCol() jid = StringCol() @@ -268,8 +287,17 @@ class PresenceAccount(Account): action = property(get_action) +def get_legacy_jids(bare_to_jid): + model.db_connect() + legacy_jids = LegacyJID.select(\ + AND(LegacyJID.q.accountID == Account.q.id, + Account.q.user_jid == bare_to_jid)) + for legacy_jid in legacy_jids: + yield legacy_jid + model.db_disconnect() + class LegacyJID(InheritableSQLObject): - _connection = hub + _connection = model.hub legacy_address = StringCol() jid = StringCol() diff --git a/src/jcl/model/tests/account.py b/src/jcl/model/tests/account.py index f9dad25..9b20056 100644 --- a/src/jcl/model/tests/account.py +++ b/src/jcl/model/tests/account.py @@ -28,6 +28,7 @@ from sqlobject import * from sqlobject.dbconnection import TheURIOpener from jcl.error import FieldError +import jcl.model as model from jcl.model import account from jcl.model.account import Account, PresenceAccount @@ -165,13 +166,15 @@ class AccountModule_TestCase(unittest.TestCase): class InheritableAccount_TestCase(unittest.TestCase): def setUp(self): self.db_url = DB_URL + model.db_connection_str = 'sqlite://' + self.db_url def test_get_register_fields(self): - """Check if post functions and default functions execute correctly. + """ + Check if post functions and default functions execute correctly. To be validated this test only need to be executed without any exception. """ - account.hub.threadConnection = connectionForURI('sqlite://' + self.db_url) + model.db_connect() for (field_name, field_type, field_options, @@ -184,41 +187,42 @@ class InheritableAccount_TestCase(unittest.TestCase): except FieldError, error: # this type of error is OK pass - del account.hub.threadConnection + model.db_disconnect() class Account_TestCase(InheritableAccount_TestCase): def setUp(self): if os.path.exists(DB_PATH): os.unlink(DB_PATH) self.db_url = DB_URL - account.hub.threadConnection = connectionForURI('sqlite://' + self.db_url) + model.db_connection_str = 'sqlite://' + self.db_url + model.db_connect() Account.createTable(ifNotExists = True) ExampleAccount.createTable(ifNotExists = True) - del account.hub.threadConnection + model.db_disconnect() self.account_class = Account def tearDown(self): - account.hub.threadConnection = connectionForURI('sqlite://' + self.db_url) + model.db_connect() ExampleAccount.dropTable(ifExists = True) Account.dropTable(ifExists = True) del TheURIOpener.cachedURIs['sqlite://' + self.db_url] - account.hub.threadConnection.close() - del account.hub.threadConnection + model.hub.threadConnection.close() + model.db_disconnect() if os.path.exists(DB_PATH): os.unlink(DB_PATH) def test_set_status(self): - account.hub.threadConnection = connectionForURI('sqlite://' + self.db_url) + model.db_connect() account11 = Account(user_jid="test1@test.com", name="account11", jid="account11@jcl.test.com") account11.status = account.OFFLINE self.assertEquals(account11.status, account.OFFLINE) # TODO : test first_check attribute - del account.hub.threadConnection + model.db_disconnect() def test_set_status_live_password(self): - account.hub.threadConnection = connectionForURI('sqlite://' + self.db_url) + model.db_connect() account11 = ExampleAccount(user_jid="test1@test.com", name="account11", jid="account11@jcl.test.com", @@ -232,32 +236,33 @@ class Account_TestCase(InheritableAccount_TestCase): self.assertEquals(account11.status, account.OFFLINE) self.assertEquals(account11.waiting_password_reply, False) self.assertEquals(account11.password, None) - del account.hub.threadConnection + model.db_disconnect() class PresenceAccount_TestCase(InheritableAccount_TestCase): def setUp(self): if os.path.exists(DB_PATH): os.unlink(DB_PATH) self.db_url = DB_URL - account.hub.threadConnection = connectionForURI('sqlite://' + self.db_url) + model.db_connection_str = 'sqlite://' + self.db_url + model.db_connect() Account.createTable(ifNotExists = True) PresenceAccount.createTable(ifNotExists = True) PresenceAccountExample.createTable(ifNotExists = True) self.account = PresenceAccountExample(\ - user_jid = "test1@test.com", \ - name = "account11", \ - jid = "account11@jcl.test.com") - del account.hub.threadConnection + user_jid="test1@test.com", + name="account11", + jid="account11@jcl.test.com") + model.db_disconnect() self.account_class = PresenceAccount def tearDown(self): - account.hub.threadConnection = connectionForURI('sqlite://' + self.db_url) + model.db_connect() PresenceAccountExample.dropTable(ifExists = True) PresenceAccount.dropTable(ifExists = True) Account.dropTable(ifExists = True) del TheURIOpener.cachedURIs['sqlite://' + self.db_url] - account.hub.threadConnection.close() - del account.hub.threadConnection + model.hub.threadConnection.close() + model.db_disconnect() if os.path.exists(DB_PATH): os.unlink(DB_PATH) diff --git a/src/jcl/runner.py b/src/jcl/runner.py index 1ee0dc7..3dabd31 100644 --- a/src/jcl/runner.py +++ b/src/jcl/runner.py @@ -28,6 +28,7 @@ from getopt import gnu_getopt from sqlobject import * +import jcl.model as model from jcl.model import account from jcl.model.account import Account, PresenceAccount @@ -48,35 +49,35 @@ class JCLRunner(object): self.language = "en" self.db_url = "sqlite:///var/spool/jabber/jcl.db" self.pid_file = "/var/run/jabber/jcl.pid" - self.options = [("c:", "config-file=", None, \ - " FILE\t\t\t\tConfiguration file to use", \ - lambda arg: self.set_attr("config_file", arg)), \ - ("S:", "server=", "jabber", \ - " SERVER_ADDRESS\t\t\tAddress of the Jabber server", \ - lambda arg: self.set_attr("server", arg)), \ - ("P:", "port=", "jabber", \ - " PORT\t\t\t\t\tPort of the Jabber server to connect the component", \ - lambda arg: self.set_attr("port", int(arg))), \ - ("s:", "secret=", "jabber", \ - " SECRET\t\t\t\tComponent password to connect to the Jabber server", \ - lambda arg: self.set_attr("secret", arg)), \ - ("j:", "service-jid=", "jabber", \ - " JID\t\t\t\tJID of the component", \ - lambda arg: self.set_attr("service_jid", arg)), \ - ("l:", "language=", "jabber", \ - " LANG\t\t\t\tDefault Language of the component", \ - lambda arg: self.set_attr("language", arg)), \ - ("u:", "db-url=", "db", \ - " URL\t\t\t\tDatabase URL", \ - lambda arg: self.set_attr("db_url", arg)), \ - ("p:", "pid-file=", "component", \ - " FILE\t\t\t\tPath of the PID file", \ - lambda arg: self.set_attr("pid_file", arg)), \ - ("d", "debug", None, \ - "\t\t\t\t\tEnable debug traces", \ - lambda arg: self.set_attr("debug", True)), \ - ("h", "help", None, \ - "\t\t\t\t\tThis help", \ + self.options = [("c:", "config-file=", None, + " FILE\t\t\t\tConfiguration file to use", + lambda arg: self.set_attr("config_file", arg)), + ("S:", "server=", "jabber", + " SERVER_ADDRESS\t\t\tAddress of the Jabber server", + lambda arg: self.set_attr("server", arg)), + ("P:", "port=", "jabber", + " PORT\t\t\t\t\tPort of the Jabber server to connect the component", + lambda arg: self.set_attr("port", int(arg))), + ("s:", "secret=", "jabber", + " SECRET\t\t\t\tComponent password to connect to the Jabber server", + lambda arg: self.set_attr("secret", arg)), + ("j:", "service-jid=", "jabber", + " JID\t\t\t\tJID of the component", + lambda arg: self.set_attr("service_jid", arg)), + ("l:", "language=", "jabber", + " LANG\t\t\t\tDefault Language of the component", + lambda arg: self.set_attr("language", arg)), + ("u:", "db-url=", "db", + " URL\t\t\t\tDatabase URL", + lambda arg: self.set_attr("db_url", arg)), + ("p:", "pid-file=", "component", + " FILE\t\t\t\tPath of the PID file", + lambda arg: self.set_attr("pid_file", arg)), + ("d", "debug", None, + "\t\t\t\t\tEnable debug traces", + lambda arg: self.set_attr("debug", True)), + ("h", "help", None, + "\t\t\t\t\tThis help", lambda arg: self.print_help())] self.logger = logging.getLogger() self.logger.addHandler(logging.StreamHandler()) @@ -97,7 +98,7 @@ class JCLRunner(object): def __apply_commandline_args(self, commandline_args, cleanopts): for arg in commandline_args: value = commandline_args[arg] - self.logger.debug("Applying argument " + arg + " = " + \ + self.logger.debug("Applying argument " + arg + " = " + value) cleanopts[arg][1](value) @@ -118,9 +119,9 @@ class JCLRunner(object): if section is not None: attr = opt.replace("-", "_") config_property = self.config.get(section, attr) - self.logger.debug("Setting " + attr + " = " + \ - config_property + \ - " from configuration file " + \ + self.logger.debug("Setting " + attr + " = " + + config_property + + " from configuration file " + self.config_file) set_func(config_property) @@ -175,8 +176,8 @@ class JCLRunner(object): def setup_db(self): - Account.createTable(ifNotExists = True) - PresenceAccount.createTable(ifNotExists = True) + Account.createTable(ifNotExists=True) + PresenceAccount.createTable(ifNotExists=True) def setup_pidfile(self): pidfile = open(self.pid_file, "w") @@ -186,10 +187,11 @@ class JCLRunner(object): def _run(self, run_func): try: self.setup_pidfile() - account.hub.threadConnection = connectionForURI(self.db_url) + model.db_connection_str = self.db_url + model.db_connect() self.setup_db() - del account.hub.threadConnection - self.logger.debug(self.component_name + " v" + \ + model.db_disconnect() + self.logger.debug(self.component_name + " v" + self.component_version + " is starting ...") run_func() self.logger.debug(self.component_name + " is exiting") @@ -199,12 +201,11 @@ class JCLRunner(object): def run(self): def run_func(): - component = JCLComponent(jid = self.service_jid, \ - secret = self.secret, \ - server = self.server, \ - port = self.port, \ - db_connection_str = self.db_url, \ - lang = Lang(self.language)) + component = JCLComponent(jid=self.service_jid, + secret=self.secret, + server=self.server, + port=self.port, + lang=Lang(self.language)) component.run() self._run(run_func) diff --git a/src/jcl/tests/runner.py b/src/jcl/tests/runner.py index 58a0c5b..b9b7fd1 100644 --- a/src/jcl/tests/runner.py +++ b/src/jcl/tests/runner.py @@ -29,6 +29,7 @@ from sqlobject import * import jcl from jcl.runner import JCLRunner +import jcl.model as model from jcl.model import account from jcl.model.account import Account, PresenceAccount @@ -125,11 +126,11 @@ class JCLRunner_TestCase(unittest.TestCase): def do_nothing(): pass self.runner._run(do_nothing) - account.hub.threadConnection = connectionForURI(self.runner.db_url) + model.db_connect() # dropTable should succeed because tables should exist Account.dropTable() PresenceAccount.dropTable() - del account.hub.threadConnection + model.db_disconnect() os.unlink(DB_PATH) self.assertFalse(os.access("/tmp/jcl.pid", os.F_OK))