core: use of the new core.log module:
/!\ this is a massive refactoring and was largely automated, it probably did bring some bugs /!\
This commit is contained in:
parent
dc5c042fe7
commit
501bc92528
57 changed files with 707 additions and 941 deletions
|
|
@ -20,7 +20,8 @@
|
|||
from sat.core.i18n import _
|
||||
from bridge_frontend import BridgeFrontend
|
||||
import dbus
|
||||
from logging import debug, error
|
||||
from sat.core.log import getLogger
|
||||
log = getLogger(__name__)
|
||||
from sat.core.exceptions import BridgeExceptionNoService, BridgeInitError
|
||||
|
||||
from dbus.mainloop.glib import DBusGMainLoop
|
||||
|
|
@ -47,7 +48,7 @@ class DBusBridgeFrontend(BridgeFrontend):
|
|||
if e._dbus_error_name == 'org.freedesktop.DBus.Error.ServiceUnknown':
|
||||
raise BridgeExceptionNoService
|
||||
elif e._dbus_error_name == 'org.freedesktop.DBus.Error.NotSupported':
|
||||
print u"D-Bus is not launched, please see README to see instructions on how to launch it"
|
||||
log.error(_(u"D-Bus is not launched, please see README to see instructions on how to launch it"))
|
||||
raise BridgeInitError
|
||||
else:
|
||||
raise e
|
||||
|
|
@ -59,7 +60,7 @@ class DBusBridgeFrontend(BridgeFrontend):
|
|||
elif iface == "plugin":
|
||||
self.db_plugin_iface.connect_to_signal(functionName, handler)
|
||||
else:
|
||||
error(_('Unknown interface'))
|
||||
log.error(_('Unknown interface'))
|
||||
|
||||
def __getattribute__(self, name):
|
||||
""" usual __getattribute__ if the method exists, else try to find a plugin method """
|
||||
|
|
|
|||
|
|
@ -17,12 +17,14 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from sat.core.i18n import _
|
||||
from bridge import Bridge
|
||||
import dbus
|
||||
import dbus.service
|
||||
import dbus.mainloop.glib
|
||||
import inspect
|
||||
from logging import debug, info, error
|
||||
from sat.core.log import getLogger
|
||||
log = getLogger(__name__)
|
||||
from twisted.internet.defer import Deferred
|
||||
from sat.core.exceptions import BridgeInitError
|
||||
|
||||
|
|
@ -69,7 +71,7 @@ class DbusObject(dbus.service.Object):
|
|||
|
||||
def __init__(self, bus, path):
|
||||
dbus.service.Object.__init__(self, bus, path)
|
||||
debug("Init DbusObject...")
|
||||
log.debug("Init DbusObject...")
|
||||
self.cb = {}
|
||||
|
||||
def register(self, name, cb):
|
||||
|
|
@ -84,7 +86,7 @@ class DbusObject(dbus.service.Object):
|
|||
if "callback" in kwargs:
|
||||
#we must have errback too
|
||||
if not "errback" in kwargs:
|
||||
error("errback is missing in method call [%s]" % name)
|
||||
log.error("errback is missing in method call [%s]" % name)
|
||||
raise InternalError
|
||||
callback = kwargs.pop("callback")
|
||||
errback = kwargs.pop("errback")
|
||||
|
|
@ -94,13 +96,13 @@ class DbusObject(dbus.service.Object):
|
|||
result = self.cb[name](*args, **kwargs)
|
||||
if async:
|
||||
if not isinstance(result, Deferred):
|
||||
error("Asynchronous method [%s] does not return a Deferred." % name)
|
||||
log.error("Asynchronous method [%s] does not return a Deferred." % name)
|
||||
raise AsyncNotDeferred
|
||||
result.addCallback(lambda result: callback() if result is None else callback(result))
|
||||
result.addErrback(lambda err: errback(GenericException(err)))
|
||||
else:
|
||||
if isinstance(result, Deferred):
|
||||
error("Synchronous method [%s] return a Deferred." % name)
|
||||
log.error("Synchronous method [%s] return a Deferred." % name)
|
||||
raise DeferredNotAsync
|
||||
return result
|
||||
### signals ###
|
||||
|
|
@ -502,7 +504,7 @@ class DbusObject(dbus.service.Object):
|
|||
attributes = ', '.join(self.__attributes(signature))
|
||||
#TODO: use doc parameter to name attributes
|
||||
|
||||
#code = compile ('def '+name+' (self,'+attributes+'): debug ("'+name+' signal")', '<DBus bridge>','exec') #XXX: the debug is too annoying with xmllog
|
||||
#code = compile ('def '+name+' (self,'+attributes+'): log.debug ("'+name+' signal")', '<DBus bridge>','exec') #XXX: the log.debug is too annoying with xmllog
|
||||
code = compile('def ' + name + ' (self,' + attributes + '): pass', '<DBus bridge>', 'exec')
|
||||
exec (code)
|
||||
signal = locals()[name]
|
||||
|
|
@ -517,12 +519,12 @@ class DBusBridge(Bridge):
|
|||
def __init__(self):
|
||||
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
|
||||
Bridge.__init__(self)
|
||||
info("Init DBus...")
|
||||
log.info("Init DBus...")
|
||||
try:
|
||||
self.session_bus = dbus.SessionBus()
|
||||
except dbus.DBusException as e:
|
||||
if e._dbus_error_name == 'org.freedesktop.DBus.Error.NotSupported':
|
||||
print u"D-Bus is not launched, please see README to see instructions on how to launch it"
|
||||
log.error(_(u"D-Bus is not launched, please see README to see instructions on how to launch it"))
|
||||
raise BridgeInitError
|
||||
self.dbus_name = dbus.service.BusName(const_INT_PREFIX, self.session_bus)
|
||||
self.dbus_bridge = DbusObject(self.session_bus, const_OBJ_PATH)
|
||||
|
|
@ -570,13 +572,13 @@ class DBusBridge(Bridge):
|
|||
self.dbus_bridge.subscribe(sub_type, entity_jid, profile)
|
||||
|
||||
def register(self, name, callback):
|
||||
debug("registering DBus bridge method [%s]", name)
|
||||
log.debug("registering DBus bridge method [%s]" % name)
|
||||
self.dbus_bridge.register(name, callback)
|
||||
|
||||
def addMethod(self, name, int_suffix, in_sign, out_sign, method, async=False, doc={}):
|
||||
"""Dynamically add a method to Dbus Bridge"""
|
||||
#FIXME: doc parameter is kept only temporary, the time to remove it from calls
|
||||
print ("Adding method [%s] to DBus bridge" % name)
|
||||
log.debug("Adding method [%s] to DBus bridge" % name)
|
||||
self.dbus_bridge.addMethod(name, int_suffix, in_sign, out_sign, method, async)
|
||||
self.register(name, method)
|
||||
|
||||
|
|
|
|||
|
|
@ -17,9 +17,10 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from logging import debug, info, error
|
||||
from sat.core.log import getLogger
|
||||
log = getLogger(__name__)
|
||||
|
||||
|
||||
class Bridge(object):
|
||||
def __init__(self):
|
||||
info("Bridge initialization")
|
||||
log.info("Bridge initialization")
|
||||
|
|
|
|||
|
|
@ -17,12 +17,14 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from sat.core.i18n import _
|
||||
from bridge import Bridge
|
||||
import dbus
|
||||
import dbus.service
|
||||
import dbus.mainloop.glib
|
||||
import inspect
|
||||
from logging import debug, info, error
|
||||
from sat.core.log import getLogger
|
||||
log = getLogger(__name__)
|
||||
from twisted.internet.defer import Deferred
|
||||
from sat.core.exceptions import BridgeInitError
|
||||
|
||||
|
|
@ -69,7 +71,7 @@ class DbusObject(dbus.service.Object):
|
|||
|
||||
def __init__(self, bus, path):
|
||||
dbus.service.Object.__init__(self, bus, path)
|
||||
debug("Init DbusObject...")
|
||||
log.debug("Init DbusObject...")
|
||||
self.cb = {}
|
||||
|
||||
def register(self, name, cb):
|
||||
|
|
@ -84,7 +86,7 @@ class DbusObject(dbus.service.Object):
|
|||
if "callback" in kwargs:
|
||||
#we must have errback too
|
||||
if not "errback" in kwargs:
|
||||
error("errback is missing in method call [%s]" % name)
|
||||
log.error("errback is missing in method call [%s]" % name)
|
||||
raise InternalError
|
||||
callback = kwargs.pop("callback")
|
||||
errback = kwargs.pop("errback")
|
||||
|
|
@ -94,13 +96,13 @@ class DbusObject(dbus.service.Object):
|
|||
result = self.cb[name](*args, **kwargs)
|
||||
if async:
|
||||
if not isinstance(result, Deferred):
|
||||
error("Asynchronous method [%s] does not return a Deferred." % name)
|
||||
log.error("Asynchronous method [%s] does not return a Deferred." % name)
|
||||
raise AsyncNotDeferred
|
||||
result.addCallback(lambda result: callback() if result is None else callback(result))
|
||||
result.addErrback(lambda err: errback(GenericException(err)))
|
||||
else:
|
||||
if isinstance(result, Deferred):
|
||||
error("Synchronous method [%s] return a Deferred." % name)
|
||||
log.error("Synchronous method [%s] return a Deferred." % name)
|
||||
raise DeferredNotAsync
|
||||
return result
|
||||
### signals ###
|
||||
|
|
@ -194,7 +196,7 @@ class DbusObject(dbus.service.Object):
|
|||
attributes = ', '.join(self.__attributes(signature))
|
||||
#TODO: use doc parameter to name attributes
|
||||
|
||||
#code = compile ('def '+name+' (self,'+attributes+'): debug ("'+name+' signal")', '<DBus bridge>','exec') #XXX: the debug is too annoying with xmllog
|
||||
#code = compile ('def '+name+' (self,'+attributes+'): log.debug ("'+name+' signal")', '<DBus bridge>','exec') #XXX: the log.debug is too annoying with xmllog
|
||||
code = compile('def ' + name + ' (self,' + attributes + '): pass', '<DBus bridge>', 'exec')
|
||||
exec (code)
|
||||
signal = locals()[name]
|
||||
|
|
@ -209,25 +211,25 @@ class DBusBridge(Bridge):
|
|||
def __init__(self):
|
||||
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
|
||||
Bridge.__init__(self)
|
||||
info("Init DBus...")
|
||||
log.info("Init DBus...")
|
||||
try:
|
||||
self.session_bus = dbus.SessionBus()
|
||||
except dbus.DBusException as e:
|
||||
if e._dbus_error_name == 'org.freedesktop.DBus.Error.NotSupported':
|
||||
print u"D-Bus is not launched, please see README to see instructions on how to launch it"
|
||||
log.error(_(u"D-Bus is not launched, please see README to see instructions on how to launch it"))
|
||||
raise BridgeInitError
|
||||
self.dbus_name = dbus.service.BusName(const_INT_PREFIX, self.session_bus)
|
||||
self.dbus_bridge = DbusObject(self.session_bus, const_OBJ_PATH)
|
||||
|
||||
##DIRECT_CALLS##
|
||||
def register(self, name, callback):
|
||||
debug("registering DBus bridge method [%s]", name)
|
||||
log.debug("registering DBus bridge method [%s]" % name)
|
||||
self.dbus_bridge.register(name, callback)
|
||||
|
||||
def addMethod(self, name, int_suffix, in_sign, out_sign, method, async=False, doc={}):
|
||||
"""Dynamically add a method to Dbus Bridge"""
|
||||
#FIXME: doc parameter is kept only temporary, the time to remove it from calls
|
||||
print ("Adding method [%s] to DBus bridge" % name)
|
||||
log.debug("Adding method [%s] to DBus bridge" % name)
|
||||
self.dbus_bridge.addMethod(name, int_suffix, in_sign, out_sign, method, async)
|
||||
self.register(name, method)
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@
|
|||
from sat.core.i18n import _
|
||||
from bridge_frontend import BridgeFrontend
|
||||
import dbus
|
||||
from logging import debug, error
|
||||
from sat.core.log import getLogger
|
||||
log = getLogger(__name__)
|
||||
from sat.core.exceptions import BridgeExceptionNoService, BridgeInitError
|
||||
|
||||
from dbus.mainloop.glib import DBusGMainLoop
|
||||
|
|
@ -47,7 +48,7 @@ class DBusBridgeFrontend(BridgeFrontend):
|
|||
if e._dbus_error_name == 'org.freedesktop.DBus.Error.ServiceUnknown':
|
||||
raise BridgeExceptionNoService
|
||||
elif e._dbus_error_name == 'org.freedesktop.DBus.Error.NotSupported':
|
||||
print u"D-Bus is not launched, please see README to see instructions on how to launch it"
|
||||
log.error(_(u"D-Bus is not launched, please see README to see instructions on how to launch it"))
|
||||
raise BridgeInitError
|
||||
else:
|
||||
raise e
|
||||
|
|
@ -59,7 +60,7 @@ class DBusBridgeFrontend(BridgeFrontend):
|
|||
elif iface == "plugin":
|
||||
self.db_plugin_iface.connect_to_signal(functionName, handler)
|
||||
else:
|
||||
error(_('Unknown interface'))
|
||||
log.error(_('Unknown interface'))
|
||||
|
||||
def __getattribute__(self, name):
|
||||
""" usual __getattribute__ if the method exists, else try to find a plugin method """
|
||||
|
|
|
|||
|
|
@ -25,20 +25,18 @@ from twisted.words.xish import domish
|
|||
from twisted.internet import reactor
|
||||
from wokkel.xmppim import RosterItem
|
||||
from sat.bridge.DBus import DBusBridge
|
||||
import logging
|
||||
from logging import debug, info, warning, error
|
||||
|
||||
import sys
|
||||
import os.path
|
||||
|
||||
from sat.core import xmpp
|
||||
from sat.core import exceptions
|
||||
from sat.core.log import getLogger
|
||||
log = getLogger(__name__)
|
||||
from sat.core.constants import Const as C
|
||||
from sat.memory.memory import Memory
|
||||
from sat.tools.misc import TriggerManager
|
||||
from sat.stdui import ui_contact_list
|
||||
from glob import glob
|
||||
from uuid import uuid4
|
||||
import sys
|
||||
import os.path
|
||||
|
||||
try:
|
||||
from collections import OrderedDict # only available from python 2.7
|
||||
|
|
@ -93,7 +91,7 @@ class SAT(service.Service):
|
|||
try:
|
||||
self.bridge = DBusBridge()
|
||||
except exceptions.BridgeInitError:
|
||||
print (u"Bridge can't be initialised, can't start SàT core") # reactor is not launched yet, so we can't use error log
|
||||
log.error(u"Bridge can't be initialised, can't start SàT core")
|
||||
sys.exit(1)
|
||||
self.bridge.register("getVersion", lambda: C.APP_VERSION)
|
||||
self.bridge.register("getProfileName", self.memory.getProfileName)
|
||||
|
|
@ -140,7 +138,7 @@ class SAT(service.Service):
|
|||
|
||||
def _postMemoryInit(self, ignore):
|
||||
"""Method called after memory initialization is done"""
|
||||
info(_("Memory initialised"))
|
||||
log.info(_("Memory initialised"))
|
||||
self._import_plugins()
|
||||
ui_contact_list.ContactList(self)
|
||||
|
||||
|
|
@ -169,25 +167,25 @@ class SAT(service.Service):
|
|||
|
||||
"""
|
||||
if import_name in self.plugins:
|
||||
debug('Plugin [%s] already imported, passing' % import_name)
|
||||
log.debug('Plugin [%s] already imported, passing' % import_name)
|
||||
return
|
||||
if not import_name:
|
||||
import_name, (plugin_path, mod, plugin_info) = plugins_to_import.popitem()
|
||||
else:
|
||||
if not import_name in plugins_to_import:
|
||||
if optional:
|
||||
warning(_("Recommended plugin not found: %s") % import_name)
|
||||
log.warning(_("Recommended plugin not found: %s") % import_name)
|
||||
return
|
||||
error(_("Dependency not found: %s") % import_name)
|
||||
log.error(_("Dependency not found: %s") % import_name)
|
||||
raise ImportError(_('Dependency plugin not found: [%s]') % import_name)
|
||||
plugin_path, mod, plugin_info = plugins_to_import.pop(import_name)
|
||||
dependencies = plugin_info.setdefault("dependencies", [])
|
||||
recommendations = plugin_info.setdefault("recommendations", [])
|
||||
for to_import in dependencies + recommendations:
|
||||
if to_import not in self.plugins:
|
||||
debug('Recursively import dependency of [%s]: [%s]' % (import_name, to_import))
|
||||
log.debug('Recursively import dependency of [%s]: [%s]' % (import_name, to_import))
|
||||
self._import_plugins_from_dict(plugins_to_import, to_import, to_import not in dependencies)
|
||||
info(_("importing plugin: %s"), plugin_info['name'])
|
||||
log.info(_("importing plugin: %s") % plugin_info['name'])
|
||||
self.plugins[import_name] = getattr(mod, plugin_info['main'])(self)
|
||||
if 'handler' in plugin_info and plugin_info['handler'] == 'yes':
|
||||
self.plugins[import_name].is_handler = True
|
||||
|
|
@ -205,11 +203,11 @@ class SAT(service.Service):
|
|||
"""
|
||||
profile = self.memory.getProfileName(profile_key)
|
||||
if not profile:
|
||||
error(_('Trying to connect a non-exsitant profile'))
|
||||
log.error(_('Trying to connect a non-exsitant profile'))
|
||||
raise exceptions.ProfileUnknownError(profile_key)
|
||||
|
||||
if self.isConnected(profile):
|
||||
info(_("already connected !"))
|
||||
log.info(_("already connected !"))
|
||||
return defer.succeed("None")
|
||||
|
||||
def afterMemoryInit(ignore):
|
||||
|
|
@ -217,7 +215,7 @@ class SAT(service.Service):
|
|||
try:
|
||||
port = int(self.memory.getParamA("Port", "Connection", profile_key=profile))
|
||||
except ValueError:
|
||||
error(_("Can't parse port value, using default value"))
|
||||
log.error(_("Can't parse port value, using default value"))
|
||||
port = 5222
|
||||
current = self.profiles[profile] = xmpp.SatXMPPClient(
|
||||
self, profile,
|
||||
|
|
@ -245,7 +243,7 @@ class SAT(service.Service):
|
|||
current.identityHandler = xmpp.SatIdentityHandler()
|
||||
current.identityHandler.setHandlerParent(current)
|
||||
|
||||
debug(_("setting plugins parents"))
|
||||
log.debug(_("setting plugins parents"))
|
||||
|
||||
plugin_conn_cb = []
|
||||
for plugin in self.plugins.iteritems():
|
||||
|
|
@ -270,10 +268,10 @@ class SAT(service.Service):
|
|||
def logPluginResults(results):
|
||||
all_succeed = all([success for success, result in results])
|
||||
if not all_succeed:
|
||||
error(_("Plugins initialisation error"))
|
||||
log.error(_("Plugins initialisation error"))
|
||||
for idx, (success, result) in enumerate(results):
|
||||
if not success:
|
||||
error("Error (plugin %(name)s): %(failure)s" % {'name': plugin_conn_cb[idx][0],
|
||||
log.error("error (plugin %(name)s): %(failure)s" % {'name': plugin_conn_cb[idx][0],
|
||||
'failure': result})
|
||||
|
||||
list_d.addCallback(logPluginResults)
|
||||
|
|
@ -289,10 +287,10 @@ class SAT(service.Service):
|
|||
def disconnect(self, profile_key):
|
||||
"""disconnect from jabber server"""
|
||||
if not self.isConnected(profile_key):
|
||||
info(_("not connected !"))
|
||||
log.info(_("not connected !"))
|
||||
return
|
||||
profile = self.memory.getProfileName(profile_key)
|
||||
info(_("Disconnecting..."))
|
||||
log.info(_("Disconnecting..."))
|
||||
self.profiles[profile].stopService()
|
||||
for plugin in self.plugins.iteritems():
|
||||
disconnected_cb = getattr(plugin[1], "profileDisconnected", None)
|
||||
|
|
@ -318,23 +316,23 @@ class SAT(service.Service):
|
|||
try:
|
||||
del self.profiles[profile]
|
||||
except KeyError:
|
||||
error(_("Trying to remove reference to a client not referenced"))
|
||||
log.error(_("Trying to remove reference to a client not referenced"))
|
||||
self.memory.purgeProfileSession(profile)
|
||||
|
||||
def startService(self):
|
||||
info("Salut à toi ô mon frère !")
|
||||
log.info(u"Salut à toi ô mon frère !")
|
||||
#TODO: manage autoconnect
|
||||
#self.connect()
|
||||
|
||||
def stopService(self):
|
||||
info("Salut aussi à Rantanplan")
|
||||
log.info("Salut aussi à Rantanplan")
|
||||
|
||||
def run(self):
|
||||
debug(_("running app"))
|
||||
log.debug(_("running app"))
|
||||
reactor.run()
|
||||
|
||||
def stop(self):
|
||||
debug(_("stopping app"))
|
||||
log.debug(_("stopping app"))
|
||||
reactor.stop()
|
||||
|
||||
## Misc methods ##
|
||||
|
|
@ -415,7 +413,7 @@ class SAT(service.Service):
|
|||
|
||||
def setParam(self, name, value, category, security_limit, profile_key):
|
||||
"""set wanted paramater and notice observers"""
|
||||
info(_("setting param: %(name)s=%(value)s in category %(category)s") % {'name': name, 'value': value, 'category': category})
|
||||
log.info(_("setting param: %(name)s=%(value)s in category %(category)s") % {'name': name, 'value': value, 'category': category})
|
||||
self.memory.setParam(name, value, category, security_limit, profile_key)
|
||||
|
||||
def isConnected(self, profile_key):
|
||||
|
|
@ -425,7 +423,7 @@ class SAT(service.Service):
|
|||
"""
|
||||
profile = self.memory.getProfileName(profile_key)
|
||||
if not profile:
|
||||
error(_('asking connection status for a non-existant profile'))
|
||||
log.error(_('asking connection status for a non-existant profile'))
|
||||
return
|
||||
if profile not in self.profiles:
|
||||
return False
|
||||
|
|
@ -490,7 +488,7 @@ class SAT(service.Service):
|
|||
if not self.trigger.point("sendMessage", mess_data, pre_xml_treatments, post_xml_treatments, profile):
|
||||
return defer.succeed(None)
|
||||
|
||||
debug(_("Sending jabber message of type [%(type)s] to %(to)s...") % {"type": mess_data["type"], "to": to_jid.full()})
|
||||
log.debug(_("Sending jabber message of type [%(type)s] to %(to)s...") % {"type": mess_data["type"], "to": to_jid.full()})
|
||||
|
||||
def generateXML(mess_data):
|
||||
mess_data['xml'] = domish.Element((None, 'message'))
|
||||
|
|
@ -507,12 +505,12 @@ class SAT(service.Service):
|
|||
def sendErrback(e):
|
||||
text = '%s: %s' % (e.value.__class__.__name__, e.getErrorMessage())
|
||||
if e.check(MessageSentAndStored):
|
||||
debug(text)
|
||||
log.debug(text)
|
||||
elif e.check(AbortSendMessage):
|
||||
warning(text)
|
||||
log.warning(text)
|
||||
return e
|
||||
else:
|
||||
error("Unmanaged exception: %s" % text)
|
||||
log.error("Unmanaged exception: %s" % text)
|
||||
return e
|
||||
pre_xml_treatments.addCallback(generateXML)
|
||||
pre_xml_treatments.chainDeferred(post_xml_treatments)
|
||||
|
|
@ -532,7 +530,7 @@ class SAT(service.Service):
|
|||
try:
|
||||
client = self.profiles[profile]
|
||||
except KeyError:
|
||||
error(_("Trying to send a message with no profile"))
|
||||
log.error(_("Trying to send a message with no profile"))
|
||||
return
|
||||
current_jid = client.jid
|
||||
if not skip_send:
|
||||
|
|
@ -580,7 +578,7 @@ class SAT(service.Service):
|
|||
profile = self.memory.getProfileName(profile_key)
|
||||
assert(profile)
|
||||
to_jid = jid.JID(raw_jid)
|
||||
debug(_('subsciption request [%(subs_type)s] for %(jid)s') % {'subs_type': subs_type, 'jid': to_jid.full()})
|
||||
log.debug(_('subsciption request [%(subs_type)s] for %(jid)s') % {'subs_type': subs_type, 'jid': to_jid.full()})
|
||||
if subs_type == "subscribe":
|
||||
self.profiles[profile].presence.subscribe(to_jid)
|
||||
elif subs_type == "subscribed":
|
||||
|
|
@ -664,7 +662,7 @@ class SAT(service.Service):
|
|||
@param data: dictionary of dictionaries
|
||||
"""
|
||||
if action_type != "DICT_DICT":
|
||||
error(_("action_type for actionResultExt must be DICT_DICT, fixing it"))
|
||||
log.error(_("action_type for actionResultExt must be DICT_DICT, fixing it"))
|
||||
action_type = "DICT_DICT"
|
||||
self.bridge.actionResultExt(action_type, action_id, data, profile)
|
||||
|
||||
|
|
@ -678,7 +676,7 @@ class SAT(service.Service):
|
|||
# FIXME: use XMLUI and *callback methods for dialog
|
||||
client = self.getClient(profile)
|
||||
if conf_id in client._waiting_conf:
|
||||
error(_("Attempt to register two callbacks for the same confirmation"))
|
||||
log.error(_("Attempt to register two callbacks for the same confirmation"))
|
||||
else:
|
||||
client._waiting_conf[conf_id] = (conf_type, data, cb)
|
||||
self.bridge.askConfirmation(conf_id, conf_type, data, profile)
|
||||
|
|
@ -686,9 +684,9 @@ class SAT(service.Service):
|
|||
def confirmationAnswer(self, conf_id, accepted, data, profile):
|
||||
"""Called by frontends to answer confirmation requests"""
|
||||
client = self.getClient(profile)
|
||||
debug(_("Received confirmation answer for conf_id [%(conf_id)s]: %(success)s") % {'conf_id': conf_id, 'success': _("accepted") if accepted else _("refused")})
|
||||
log.debug(_("Received confirmation answer for conf_id [%(conf_id)s]: %(success)s") % {'conf_id': conf_id, 'success': _("accepted") if accepted else _("refused")})
|
||||
if conf_id not in client._waiting_conf:
|
||||
error(_("Received an unknown confirmation (%(id)s for %(profile)s)") % {'id': conf_id, 'profile': profile})
|
||||
log.error(_("Received an unknown confirmation (%(id)s for %(profile)s)") % {'id': conf_id, 'profile': profile})
|
||||
else:
|
||||
cb = client._waiting_conf[conf_id][-1]
|
||||
del client._waiting_conf[conf_id]
|
||||
|
|
@ -703,7 +701,7 @@ class SAT(service.Service):
|
|||
"""Remove a progress callback"""
|
||||
client = self.getClient(profile)
|
||||
if progress_id not in client._progress_cb_map:
|
||||
error(_("Trying to remove an unknow progress callback"))
|
||||
log.error(_("Trying to remove an unknow progress callback"))
|
||||
else:
|
||||
del client._progress_cb_map[progress_id]
|
||||
|
||||
|
|
@ -718,7 +716,7 @@ class SAT(service.Service):
|
|||
client._progress_cb_map[progress_id](progress_id, data, profile)
|
||||
except KeyError:
|
||||
pass
|
||||
#debug("Requested progress for unknown progress_id")
|
||||
#log.debug("Requested progress for unknown progress_id")
|
||||
return data
|
||||
|
||||
def registerCallback(self, callback, *args, **kwargs):
|
||||
|
|
@ -750,7 +748,7 @@ class SAT(service.Service):
|
|||
def removeCallback(self, callback_id):
|
||||
""" Remove a previously registered callback
|
||||
@param callback_id: id returned by [registerCallback] """
|
||||
debug("Removing callback [%s]" % callback_id)
|
||||
log.debug("Removing callback [%s]" % callback_id)
|
||||
del self._cb_map[callback_id]
|
||||
|
||||
def launchCallback(self, callback_id, data=None, profile_key=C.PROF_KEY_NONE):
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ from sat.core.constants import Const as C
|
|||
from twisted.internet import task, defer
|
||||
from twisted.words.protocols.jabber import jid, xmlstream
|
||||
from wokkel import client, disco, xmppim, generic, compat, delay, iwokkel
|
||||
from logging import debug, info, warning, error
|
||||
from sat.core.log import getLogger
|
||||
log = getLogger(__name__)
|
||||
from sat.core import exceptions
|
||||
from calendar import timegm
|
||||
from zope.interface import implements
|
||||
|
|
@ -54,13 +55,13 @@ class SatXMPPClient(client.XMPPClient):
|
|||
return
|
||||
client.XMPPClient._authd(self, xmlstream)
|
||||
self.__connected = True
|
||||
info(_("********** [%s] CONNECTED **********") % self.profile)
|
||||
log.info(_("********** [%s] CONNECTED **********") % self.profile)
|
||||
self.streamInitialized()
|
||||
self.host_app.bridge.connected(self.profile) # we send the signal to the clients
|
||||
|
||||
def streamInitialized(self):
|
||||
"""Called after _authd"""
|
||||
debug(_("XML stream is initialized"))
|
||||
log.debug(_("XML stream is initialized"))
|
||||
self.keep_alife = task.LoopingCall(self.xmlstream.send, " ") # Needed to avoid disconnection (specially with openfire)
|
||||
self.keep_alife.start(180)
|
||||
|
||||
|
|
@ -81,7 +82,7 @@ class SatXMPPClient(client.XMPPClient):
|
|||
disco_d.addCallback(finish_connection)
|
||||
|
||||
def initializationFailed(self, reason):
|
||||
error(_("ERROR: XMPP connection failed for profile '%(profile)s': %(reason)s" % {'profile': self.profile, 'reason': reason}))
|
||||
log.error(_("ERROR: XMPP connection failed for profile '%(profile)s': %(reason)s" % {'profile': self.profile, 'reason': reason}))
|
||||
self.host_app.bridge.connectionError("AUTH_ERROR", self.profile)
|
||||
try:
|
||||
client.XMPPClient.initializationFailed(self, reason)
|
||||
|
|
@ -95,11 +96,11 @@ class SatXMPPClient(client.XMPPClient):
|
|||
|
||||
def connectionLost(self, connector, unused_reason):
|
||||
self.__connected = False
|
||||
info(_("********** [%s] DISCONNECTED **********") % self.profile)
|
||||
log.info(_("********** [%s] DISCONNECTED **********") % self.profile)
|
||||
try:
|
||||
self.keep_alife.stop()
|
||||
except AttributeError:
|
||||
debug(_("No keep_alife"))
|
||||
log.debug(_("No keep_alife"))
|
||||
self.host_app.bridge.disconnected(self.profile) # we send the signal to the clients
|
||||
self.host_app.purgeClient(self.profile) # and we remove references to this client
|
||||
|
||||
|
|
@ -111,7 +112,7 @@ class SatMessageProtocol(xmppim.MessageProtocol):
|
|||
self.host = host
|
||||
|
||||
def onMessage(self, message):
|
||||
debug(_(u"got message from: %s"), message["from"])
|
||||
log.debug(_(u"got message from: %s") % message["from"])
|
||||
post_treat = defer.Deferred() # XXX: plugin can add their treatments to this deferred
|
||||
|
||||
if not self.host.trigger.point("MessageReceived", message, post_treat, profile=self.parent.profile):
|
||||
|
|
@ -163,7 +164,7 @@ class SatRosterProtocol(xmppim.RosterClientProtocol):
|
|||
|
||||
def requestRoster(self):
|
||||
""" ask the server for Roster list """
|
||||
debug("requestRoster")
|
||||
log.debug("requestRoster")
|
||||
d = self.getRoster().addCallback(self.rosterCb)
|
||||
d.chainDeferred(self.got_roster)
|
||||
|
||||
|
|
@ -217,11 +218,11 @@ class SatRosterProtocol(xmppim.RosterClientProtocol):
|
|||
# may change in the future
|
||||
self.removeItem(item.jid)
|
||||
return
|
||||
info(_("new contact in roster list: %s"), item.jid.full())
|
||||
log.info(_("new contact in roster list: %s") % item.jid.full())
|
||||
if not item.subscriptionTo:
|
||||
warning(_("You are not subscribed to this contact !"))
|
||||
log.warning(_("You are not subscribed to this contact !"))
|
||||
if not item.subscriptionFrom:
|
||||
warning(_("This contact is not subscribed to you !"))
|
||||
log.warning(_("This contact is not subscribed to you !"))
|
||||
#self.host.memory.addContact(item.jid, item_attr, item.groups, self.parent.profile)
|
||||
|
||||
bare_jid = item.jid.userhostJID()
|
||||
|
|
@ -239,7 +240,7 @@ class SatRosterProtocol(xmppim.RosterClientProtocol):
|
|||
try:
|
||||
item = self._jids.pop(bare_jid)
|
||||
except KeyError:
|
||||
warning("Received a roster remove event for an item not in cache")
|
||||
log.warning("Received a roster remove event for an item not in cache")
|
||||
return
|
||||
for group in item.groups:
|
||||
try:
|
||||
|
|
@ -248,7 +249,7 @@ class SatRosterProtocol(xmppim.RosterClientProtocol):
|
|||
if not jids_set:
|
||||
del self._groups[group]
|
||||
except KeyError:
|
||||
warning("there is not cache for the group [%(groups)s] of the removed roster item [%(jid)s]" %
|
||||
log.warning("there is not cache for the group [%(groups)s] of the removed roster item [%(jid)s]" %
|
||||
{"group": group, "jid": bare_jid})
|
||||
|
||||
# then we send the bridge signal
|
||||
|
|
@ -295,7 +296,7 @@ class SatPresenceProtocol(xmppim.PresenceClientProtocol):
|
|||
super(SatPresenceProtocol, self).send(obj)
|
||||
|
||||
def availableReceived(self, entity, show=None, statuses=None, priority=0):
|
||||
debug(_("presence update for [%(entity)s] (available, show=%(show)s statuses=%(statuses)s priority=%(priority)d)") % {'entity': entity, 'show': show, 'statuses': statuses, 'priority': priority})
|
||||
log.debug(_("presence update for [%(entity)s] (available, show=%(show)s statuses=%(statuses)s priority=%(priority)d)") % {'entity': entity, 'show': show, 'statuses': statuses, 'priority': priority})
|
||||
|
||||
if not statuses:
|
||||
statuses = {}
|
||||
|
|
@ -314,7 +315,7 @@ class SatPresenceProtocol(xmppim.PresenceClientProtocol):
|
|||
self.parent.profile)
|
||||
|
||||
def unavailableReceived(self, entity, statuses=None):
|
||||
debug(_("presence update for [%(entity)s] (unavailable, statuses=%(statuses)s)") % {'entity': entity, 'statuses': statuses})
|
||||
log.debug(_("presence update for [%(entity)s] (unavailable, statuses=%(statuses)s)") % {'entity': entity, 'statuses': statuses})
|
||||
|
||||
if not statuses:
|
||||
statuses = {}
|
||||
|
|
@ -358,7 +359,7 @@ class SatPresenceProtocol(xmppim.PresenceClientProtocol):
|
|||
self.host.memory.delWaitingSub(entity.userhost(), self.parent.profile)
|
||||
item = self.parent.roster.getItem(entity)
|
||||
if not item or not item.subscriptionTo: # we automatically subscribe to 'to' presence
|
||||
debug(_('sending automatic "from" subscription request'))
|
||||
log.debug(_('sending automatic "from" subscription request'))
|
||||
self.subscribe(entity)
|
||||
|
||||
def unsubscribed(self, entity):
|
||||
|
|
@ -366,29 +367,29 @@ class SatPresenceProtocol(xmppim.PresenceClientProtocol):
|
|||
self.host.memory.delWaitingSub(entity.userhost(), self.parent.profile)
|
||||
|
||||
def subscribedReceived(self, entity):
|
||||
debug(_("subscription approved for [%s]") % entity.userhost())
|
||||
log.debug(_("subscription approved for [%s]") % entity.userhost())
|
||||
self.host.bridge.subscribe('subscribed', entity.userhost(), self.parent.profile)
|
||||
|
||||
def unsubscribedReceived(self, entity):
|
||||
debug(_("unsubscription confirmed for [%s]") % entity.userhost())
|
||||
log.debug(_("unsubscription confirmed for [%s]") % entity.userhost())
|
||||
self.host.bridge.subscribe('unsubscribed', entity.userhost(), self.parent.profile)
|
||||
|
||||
def subscribeReceived(self, entity):
|
||||
debug(_("subscription request from [%s]") % entity.userhost())
|
||||
log.debug(_("subscription request from [%s]") % entity.userhost())
|
||||
item = self.parent.roster.getItem(entity)
|
||||
if item and item.subscriptionTo:
|
||||
# We automatically accept subscription if we are already subscribed to contact presence
|
||||
debug(_('sending automatic subscription acceptance'))
|
||||
log.debug(_('sending automatic subscription acceptance'))
|
||||
self.subscribed(entity)
|
||||
else:
|
||||
self.host.memory.addWaitingSub('subscribe', entity.userhost(), self.parent.profile)
|
||||
self.host.bridge.subscribe('subscribe', entity.userhost(), self.parent.profile)
|
||||
|
||||
def unsubscribeReceived(self, entity):
|
||||
debug(_("unsubscription asked for [%s]") % entity.userhost())
|
||||
log.debug(_("unsubscription asked for [%s]") % entity.userhost())
|
||||
item = self.parent.roster.getItem(entity)
|
||||
if item and item.subscriptionFrom: # we automatically remove contact
|
||||
debug(_('automatic contact deletion'))
|
||||
log.debug(_('automatic contact deletion'))
|
||||
self.host.delContact(entity, self.parent.profile)
|
||||
self.host.bridge.subscribe('unsubscribe', entity.userhost(), self.parent.profile)
|
||||
|
||||
|
|
@ -405,7 +406,7 @@ class SatFallbackHandler(generic.FallbackHandler):
|
|||
def iqFallback(self, iq):
|
||||
if iq.handled is True:
|
||||
return
|
||||
debug(u"iqFallback: xml = [%s]" % (iq.toXml()))
|
||||
log.debug(u"iqFallback: xml = [%s]" % (iq.toXml()))
|
||||
generic.FallbackHandler.iqFallback(self, iq)
|
||||
|
||||
|
||||
|
|
@ -441,14 +442,14 @@ class RegisteringAuthenticator(xmlstream.ConnectAuthenticator):
|
|||
iq.send(self.jabber_host).addCallbacks(self.registrationAnswer, self.registrationFailure)
|
||||
|
||||
def registrationAnswer(self, answer):
|
||||
debug(_("registration answer: %s") % answer.toXml())
|
||||
log.debug(_("registration answer: %s") % answer.toXml())
|
||||
answer_type = "SUCCESS"
|
||||
answer_data = {"message": _("Registration successfull")}
|
||||
self.host.bridge.actionResult(answer_type, self.answer_id, answer_data, self.profile)
|
||||
self.xmlstream.sendFooter()
|
||||
|
||||
def registrationFailure(self, failure):
|
||||
info(_("Registration failure: %s") % str(failure.value))
|
||||
log.info(_("Registration failure: %s") % str(failure.value))
|
||||
answer_type = "ERROR"
|
||||
answer_data = {}
|
||||
if failure.value.condition == 'conflict':
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@
|
|||
|
||||
from sat.core.i18n import _
|
||||
from sat.core import exceptions
|
||||
from logging import debug, info, warning, error
|
||||
from sat.core.log import getLogger
|
||||
log = getLogger(__name__)
|
||||
from twisted.words.protocols.jabber import jid
|
||||
from twisted.words.protocols.jabber.error import StanzaError
|
||||
from twisted.internet import defer
|
||||
|
|
@ -126,9 +127,9 @@ class Discovery(object):
|
|||
# we cache items only for our own server
|
||||
try:
|
||||
items = self.host.memory.getEntityData(jid_, ["DISCO_ITEMS"], client.profile)["DISCO_ITEMS"]
|
||||
debug("[%s] disco items are in cache" % jid_.full())
|
||||
log.debug("[%s] disco items are in cache" % jid_.full())
|
||||
except KeyError:
|
||||
debug("Caching [%s] disco items" % jid_.full())
|
||||
log.debug("Caching [%s] disco items" % jid_.full())
|
||||
items = yield client.disco.requestItems(jid_)
|
||||
self.host.memory.updateEntityData(jid_, "DISCO_ITEMS", items, client.profile)
|
||||
else:
|
||||
|
|
@ -139,7 +140,7 @@ class Discovery(object):
|
|||
|
||||
def _infosEb(self, failure, entity_jid):
|
||||
failure.trap(StanzaError)
|
||||
warning(_("Error while requesting [%(jid)s]: %(error)s") % {'jid': entity_jid.full(),
|
||||
log.warning(_("Error while requesting [%(jid)s]: %(error)s") % {'jid': entity_jid.full(),
|
||||
'error': failure.getErrorMessage()})
|
||||
|
||||
def findServiceEntities(self, category, type_, jid_=None, profile_key=C.PROF_KEY_NONE):
|
||||
|
|
@ -236,7 +237,7 @@ class Discovery(object):
|
|||
s.append('<')
|
||||
#TODO: manage XEP-0128 data form here
|
||||
cap_hash = b64encode(sha1(''.join(s)).digest())
|
||||
debug(_('Capability hash generated: [%s]') % cap_hash)
|
||||
log.debug(_('Capability hash generated: [%s]') % cap_hash)
|
||||
return cap_hash
|
||||
|
||||
@defer.inlineCallbacks
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@ import csv
|
|||
from xdg import BaseDirectory
|
||||
from ConfigParser import SafeConfigParser, NoOptionError, NoSectionError
|
||||
from uuid import uuid4
|
||||
from logging import debug, info, warning, error
|
||||
from sat.core.log import getLogger
|
||||
log = getLogger(__name__)
|
||||
from twisted.internet import defer, reactor
|
||||
from twisted.words.protocols.jabber import jid
|
||||
from sat.core import exceptions
|
||||
|
|
@ -61,7 +62,7 @@ class Sessions(object):
|
|||
|
||||
def _purgeSession(self, session_id):
|
||||
del self._sessions[session_id]
|
||||
debug("Session [%s] purged" % session_id)
|
||||
log.debug("Session [%s] purged" % session_id)
|
||||
|
||||
def __len__(self):
|
||||
return len(self._sessions)
|
||||
|
|
@ -97,7 +98,7 @@ class Sessions(object):
|
|||
timer.cancel()
|
||||
self._purgeSession(session_id)
|
||||
except KeyError:
|
||||
debug ("Session [%s] doesn't exists, timeout expired ?" % session_id)
|
||||
log.debug ("Session [%s] doesn't exists, timeout expired ?" % session_id)
|
||||
|
||||
def keys(self):
|
||||
return self._sessions.keys()
|
||||
|
|
@ -110,7 +111,7 @@ class Memory(object):
|
|||
"""This class manage all persistent informations"""
|
||||
|
||||
def __init__(self, host):
|
||||
info(_("Memory manager init"))
|
||||
log.info(_("Memory manager init"))
|
||||
self.initialized = defer.Deferred()
|
||||
self.host = host
|
||||
self._entities_cache = {} # XXX: keep presence/last resource/other data in cache
|
||||
|
|
@ -123,7 +124,7 @@ class Memory(object):
|
|||
self.storage = SqliteStorage(database_file, host.__version__)
|
||||
PersistentDict.storage = self.storage
|
||||
self.params = Params(host, self.storage)
|
||||
info(_("Loading default params template"))
|
||||
log.info(_("Loading default params template"))
|
||||
self.params.load_default_params()
|
||||
d = self.storage.initialized.addCallback(lambda ignore: self.load())
|
||||
self.memory_data = PersistentDict("memory")
|
||||
|
|
@ -136,7 +137,7 @@ class Memory(object):
|
|||
try:
|
||||
config.read(C.CONFIG_FILES)
|
||||
except:
|
||||
error(_("Can't read main config !"))
|
||||
log.error(_("Can't read main config !"))
|
||||
return config
|
||||
|
||||
# XXX: tmp update code, will be removed in the future
|
||||
|
|
@ -148,7 +149,7 @@ class Memory(object):
|
|||
return # nothing to do
|
||||
old_default = '~/.sat'
|
||||
if os.path.isfile(os.path.expanduser(old_default) + '/' + C.SAVEFILE_DATABASE):
|
||||
warning(_("A database has been found in the default local_dir for previous versions (< 0.5)"))
|
||||
log.warning(_("A database has been found in the default local_dir for previous versions (< 0.5)"))
|
||||
config = SafeConfigParser()
|
||||
target_file = None
|
||||
for file_ in C.CONFIG_FILES[::-1]:
|
||||
|
|
@ -164,7 +165,7 @@ class Memory(object):
|
|||
config.set('', 'local_dir', old_default)
|
||||
with open(target_file, 'wb') as configfile:
|
||||
config.write(configfile) # for the next time that user launches sat
|
||||
warning(_("Auto-update: local_dir set to %(path)s in the file %(config_file)s") % {'path': old_default, 'config_file': file_})
|
||||
log.warning(_("Auto-update: local_dir set to %(path)s in the file %(config_file)s") % {'path': old_default, 'config_file': file_})
|
||||
default = old_default
|
||||
else: # use the new default local_dir
|
||||
default = C.DEFAULT_LOCAL_DIR
|
||||
|
|
@ -200,10 +201,10 @@ class Memory(object):
|
|||
if os.path.exists(filename):
|
||||
try:
|
||||
self.params.load_xml(filename)
|
||||
debug(_("Parameters loaded from file: %s") % filename)
|
||||
log.debug(_("Parameters loaded from file: %s") % filename)
|
||||
return True
|
||||
except Exception as e:
|
||||
error(_("Can't load parameters from file: %s") % e)
|
||||
log.error(_("Can't load parameters from file: %s") % e)
|
||||
return False
|
||||
|
||||
def load(self):
|
||||
|
|
@ -219,18 +220,18 @@ class Memory(object):
|
|||
def startProfileSession(self, profile):
|
||||
""""Iniatialise session for a profile
|
||||
@param profile: %(doc_profile)s"""
|
||||
info(_("[%s] Profile session started" % profile))
|
||||
log.info(_("[%s] Profile session started" % profile))
|
||||
self._entities_cache[profile] = {}
|
||||
|
||||
def purgeProfileSession(self, profile):
|
||||
"""Delete cache of data of profile
|
||||
@param profile: %(doc_profile)s"""
|
||||
info(_("[%s] Profile session purge" % profile))
|
||||
log.info(_("[%s] Profile session purge" % profile))
|
||||
self.params.purgeProfile(profile)
|
||||
try:
|
||||
del self._entities_cache[profile]
|
||||
except KeyError:
|
||||
error(_("Trying to purge roster status cache for a profile not in memory: [%s]") % profile)
|
||||
log.error(_("Trying to purge roster status cache for a profile not in memory: [%s]") % profile)
|
||||
|
||||
def save_xml(self, filename=None):
|
||||
"""Save parameters template to xml file"""
|
||||
|
|
@ -240,10 +241,10 @@ class Memory(object):
|
|||
filename = os.path.expanduser(filename)
|
||||
try:
|
||||
self.params.save_xml(filename)
|
||||
debug(_("Parameters saved to file: %s") % filename)
|
||||
log.debug(_("Parameters saved to file: %s") % filename)
|
||||
return True
|
||||
except Exception as e:
|
||||
error(_("Can't save parameters to file: %s") % e)
|
||||
log.error(_("Can't save parameters to file: %s") % e)
|
||||
return False
|
||||
|
||||
def getProfilesList(self):
|
||||
|
|
@ -312,7 +313,7 @@ class Memory(object):
|
|||
if "presence" in self._entities_cache[profile][entity]:
|
||||
entities_presence[entity] = self._entities_cache[profile][entity]["presence"]
|
||||
|
||||
debug("Memory getPresenceStatus (%s)", entities_presence)
|
||||
log.debug("Memory getPresenceStatus (%s)", entities_presence)
|
||||
return entities_presence
|
||||
|
||||
def setPresenceStatus(self, entity_jid, show, priority, statuses, profile_key):
|
||||
|
|
@ -393,7 +394,7 @@ class Memory(object):
|
|||
try:
|
||||
del entity_data[key]
|
||||
except KeyError:
|
||||
debug("Key [%s] doesn't exist for [%s] in entities_cache" % (key, entity_jid.full()))
|
||||
log.debug("Key [%s] doesn't exist for [%s] in entities_cache" % (key, entity_jid.full()))
|
||||
|
||||
def getEntityData(self, entity_jid, keys_list, profile_key):
|
||||
"""Get a list of cached values for entity
|
||||
|
|
@ -454,7 +455,7 @@ class Memory(object):
|
|||
try:
|
||||
del self._entities_cache[profile][entity]
|
||||
except KeyError:
|
||||
debug("Can't delete entity [%s]: not in cache" % entity.full())
|
||||
log.debug("Can't delete entity [%s]: not in cache" % entity.full())
|
||||
|
||||
def addWaitingSub(self, type_, entity_jid, profile_key):
|
||||
"""Called when a subcription request is received"""
|
||||
|
|
@ -475,7 +476,7 @@ class Memory(object):
|
|||
"""Called to get a list of currently waiting subscription requests"""
|
||||
profile = self.getProfileName(profile_key)
|
||||
if not profile:
|
||||
error(_('Asking waiting subscriptions for a non-existant profile'))
|
||||
log.error(_('Asking waiting subscriptions for a non-existant profile'))
|
||||
return {}
|
||||
if profile not in self.subscriptions:
|
||||
return {}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ from sat.core.i18n import _
|
|||
from sat.core import exceptions
|
||||
from sat.core.constants import Const as C
|
||||
from xml.dom import minidom, NotFoundErr
|
||||
from logging import debug, info, warning, error
|
||||
from sat.core.log import getLogger
|
||||
log = getLogger(__name__)
|
||||
from twisted.internet import defer
|
||||
from twisted.python.failure import Failure
|
||||
from sat.tools.xml_tools import paramsXML2XMLUI
|
||||
|
|
@ -115,7 +116,7 @@ class Params(object):
|
|||
try:
|
||||
del self.params[profile]
|
||||
except KeyError:
|
||||
error(_("Trying to purge cache of a profile not in memory: [%s]") % profile)
|
||||
log.error(_("Trying to purge cache of a profile not in memory: [%s]") % profile)
|
||||
|
||||
def save_xml(self, filename):
|
||||
"""Save parameters template to xml file"""
|
||||
|
|
@ -123,7 +124,7 @@ class Params(object):
|
|||
xml_file.write(self.dom.toxml('utf-8'))
|
||||
|
||||
def __init__(self, host, storage):
|
||||
debug("Parameters init")
|
||||
log.debug("Parameters init")
|
||||
self.host = host
|
||||
self.storage = storage
|
||||
self.default_profile = None
|
||||
|
|
@ -138,7 +139,7 @@ class Params(object):
|
|||
@return: a Deferred instance
|
||||
"""
|
||||
if self.storage.hasProfile(profile):
|
||||
info(_('The profile name already exists'))
|
||||
log.info(_('The profile name already exists'))
|
||||
return defer.fail(Failure(exceptions.ConflictError))
|
||||
if not self.host.trigger.point("ProfileCreation", profile):
|
||||
return defer.fail(Failure(exceptions.CancelError))
|
||||
|
|
@ -153,13 +154,13 @@ class Params(object):
|
|||
@return: a Deferred instance
|
||||
"""
|
||||
if not self.storage.hasProfile(profile):
|
||||
info(_('Trying to delete an unknown profile'))
|
||||
log.info(_('Trying to delete an unknown profile'))
|
||||
return defer.fail(Failure(exceptions.ProfileUnknownError))
|
||||
if self.host.isConnected(profile):
|
||||
if force:
|
||||
self.host.disconnect(profile)
|
||||
else:
|
||||
info(_("Trying to delete a connected profile"))
|
||||
log.info(_("Trying to delete a connected profile"))
|
||||
return defer.fail(Failure(exceptions.ConnectedProfileError))
|
||||
return self.storage.deleteProfile(profile)
|
||||
|
||||
|
|
@ -174,11 +175,11 @@ class Params(object):
|
|||
if profile_key == '@DEFAULT@':
|
||||
default = self.host.memory.memory_data.get('Profile_default')
|
||||
if not default:
|
||||
info(_('No default profile, returning first one')) # TODO: manage real default profile
|
||||
log.info(_('No default profile, returning first one')) # TODO: manage real default profile
|
||||
try:
|
||||
default = self.host.memory.memory_data['Profile_default'] = self.storage.getProfilesList()[0]
|
||||
except IndexError:
|
||||
info(_('No profile exist yet'))
|
||||
log.info(_('No profile exist yet'))
|
||||
return ""
|
||||
return default # FIXME: temporary, must use real default value, and fallback to first one if it doesn't exists
|
||||
elif profile_key == C.PROF_KEY_NONE:
|
||||
|
|
@ -186,7 +187,7 @@ class Params(object):
|
|||
elif return_profile_keys and profile_key in ["@ALL@"]:
|
||||
return profile_key # this value must be managed by the caller
|
||||
if not self.storage.hasProfile(profile_key):
|
||||
info(_('Trying to access an unknown profile'))
|
||||
log.info(_('Trying to access an unknown profile'))
|
||||
return "" # FIXME: raise exceptions.ProfileUnknownError here (must be well checked, this method is used in lot of places)
|
||||
return profile_key
|
||||
|
||||
|
|
@ -267,23 +268,23 @@ class Params(object):
|
|||
@param app: name of the frontend registering the parameters
|
||||
"""
|
||||
if not app:
|
||||
warning(_("Trying to register frontends parameters with no specified app: aborted"))
|
||||
log.warning(_("Trying to register frontends parameters with no specified app: aborted"))
|
||||
return
|
||||
if not hasattr(self, "frontends_cache"):
|
||||
self.frontends_cache = []
|
||||
if app in self.frontends_cache:
|
||||
debug(_("Trying to register twice frontends parameters for %(app)s: aborted" % {"app": app}))
|
||||
log.debug(_("Trying to register twice frontends parameters for %(app)s: aborted" % {"app": app}))
|
||||
return
|
||||
self.frontends_cache.append(app)
|
||||
self.updateParams(xml, security_limit, app)
|
||||
debug("Frontends parameters registered for %(app)s" % {'app': app})
|
||||
log.debug("Frontends parameters registered for %(app)s" % {'app': app})
|
||||
|
||||
def __default_ok(self, value, name, category):
|
||||
#FIXME: will not work with individual parameters
|
||||
self.setParam(name, value, category)
|
||||
|
||||
def __default_ko(self, failure, name, category):
|
||||
error(_("Can't determine default value for [%(category)s/%(name)s]: %(reason)s") % {'category': category, 'name': name, 'reason': str(failure.value)})
|
||||
log.error(_("Can't determine default value for [%(category)s/%(name)s]: %(reason)s") % {'category': category, 'name': name, 'reason': str(failure.value)})
|
||||
|
||||
def setDefault(self, name, category, callback, errback=None):
|
||||
"""Set default value of parameter
|
||||
|
|
@ -295,17 +296,17 @@ class Params(object):
|
|||
"""
|
||||
#TODO: send signal param update if value changed
|
||||
#TODO: manage individual paramaters
|
||||
debug ("setDefault called for %(category)s/%(name)s" % {"category": category, "name": name})
|
||||
log.debug ("setDefault called for %(category)s/%(name)s" % {"category": category, "name": name})
|
||||
node = self._getParamNode(name, category, '@ALL@')
|
||||
if not node:
|
||||
error(_("Requested param [%(name)s] in category [%(category)s] doesn't exist !") % {'name': name, 'category': category})
|
||||
log.error(_("Requested param [%(name)s] in category [%(category)s] doesn't exist !") % {'name': name, 'category': category})
|
||||
return
|
||||
if node[1].getAttribute('default_cb') == 'yes':
|
||||
# del node[1].attributes['default_cb'] # default_cb is not used anymore as a flag to know if we have to set the default value,
|
||||
# and we can still use it later e.g. to call a generic setDefault method
|
||||
value = self._getParam(category, name, C.GENERAL)
|
||||
if value is None: # no value set by the user: we have the default value
|
||||
debug ("Default value to set, using callback")
|
||||
log.debug ("Default value to set, using callback")
|
||||
d = defer.maybeDeferred(callback)
|
||||
d.addCallback(self.__default_ok, name, category)
|
||||
d.addErrback(errback or self.__default_ko, name, category)
|
||||
|
|
@ -343,7 +344,7 @@ class Params(object):
|
|||
#FIXME: looks really dirty and buggy, need to be reviewed/refactored
|
||||
node = self._getParamNode(name, category)
|
||||
if not node:
|
||||
error(_("Requested param [%(name)s] in category [%(category)s] doesn't exist !") % {'name': name, 'category': category})
|
||||
log.error(_("Requested param [%(name)s] in category [%(category)s] doesn't exist !") % {'name': name, 'category': category})
|
||||
raise exceptions.NotFound
|
||||
|
||||
if node[0] == C.GENERAL:
|
||||
|
|
@ -354,11 +355,11 @@ class Params(object):
|
|||
|
||||
profile = self.getProfileName(profile_key)
|
||||
if not profile:
|
||||
error(_('Requesting a param for an non-existant profile'))
|
||||
log.error(_('Requesting a param for an non-existant profile'))
|
||||
raise exceptions.ProfileUnknownError
|
||||
|
||||
if profile not in self.params:
|
||||
error(_('Requesting synchronous param for not connected profile'))
|
||||
log.error(_('Requesting synchronous param for not connected profile'))
|
||||
raise exceptions.NotConnectedProfileError(profile)
|
||||
|
||||
if attr == "value":
|
||||
|
|
@ -378,11 +379,11 @@ class Params(object):
|
|||
@param profile: owner of the param (@ALL@ for everyone)"""
|
||||
node = self._getParamNode(name, category)
|
||||
if not node:
|
||||
error(_("Requested param [%(name)s] in category [%(category)s] doesn't exist !") % {'name': name, 'category': category})
|
||||
log.error(_("Requested param [%(name)s] in category [%(category)s] doesn't exist !") % {'name': name, 'category': category})
|
||||
return None
|
||||
|
||||
if not self.checkSecurityLimit(node[1], security_limit):
|
||||
warning(_("Trying to get parameter '%(param)s' in category '%(cat)s' without authorization!!!"
|
||||
log.warning(_("Trying to get parameter '%(param)s' in category '%(cat)s' without authorization!!!"
|
||||
% {'param': name, 'cat': category}))
|
||||
return None
|
||||
|
||||
|
|
@ -394,7 +395,7 @@ class Params(object):
|
|||
|
||||
profile = self.getProfileName(profile_key)
|
||||
if not profile:
|
||||
error(_('Requesting a param for a non-existant profile'))
|
||||
log.error(_('Requesting a param for a non-existant profile'))
|
||||
return defer.fail()
|
||||
|
||||
if attr != "value":
|
||||
|
|
@ -538,7 +539,7 @@ class Params(object):
|
|||
"""
|
||||
profile = self.getProfileName(profile_key)
|
||||
if not profile:
|
||||
error(_("Asking params for inexistant profile"))
|
||||
log.error(_("Asking params for inexistant profile"))
|
||||
return ""
|
||||
d = self.getParams(security_limit, app, profile)
|
||||
return d.addCallback(lambda param_xml: paramsXML2XMLUI(param_xml))
|
||||
|
|
@ -554,7 +555,7 @@ class Params(object):
|
|||
"""
|
||||
profile = self.getProfileName(profile_key)
|
||||
if not profile:
|
||||
error(_("Asking params for inexistant profile"))
|
||||
log.error(_("Asking params for inexistant profile"))
|
||||
return defer.succeed("")
|
||||
|
||||
def returnXML(prof_xml):
|
||||
|
|
@ -577,7 +578,7 @@ class Params(object):
|
|||
#TODO: manage category of general type (without existant profile)
|
||||
profile = self.getProfileName(profile_key)
|
||||
if not profile:
|
||||
error(_("Asking params for inexistant profile"))
|
||||
log.error(_("Asking params for inexistant profile"))
|
||||
return ""
|
||||
|
||||
def returnCategoryXml(prof_xml):
|
||||
|
|
@ -629,17 +630,17 @@ class Params(object):
|
|||
if profile_key != C.PROF_KEY_NONE:
|
||||
profile = self.getProfileName(profile_key)
|
||||
if not profile:
|
||||
error(_('Trying to set parameter for an unknown profile'))
|
||||
log.error(_('Trying to set parameter for an unknown profile'))
|
||||
return # TODO: throw an error
|
||||
|
||||
node = self._getParamNode(name, category, '@ALL@')
|
||||
if not node:
|
||||
error(_('Requesting an unknown parameter (%(category)s/%(name)s)')
|
||||
log.error(_('Requesting an unknown parameter (%(category)s/%(name)s)')
|
||||
% {'category': category, 'name': name})
|
||||
return
|
||||
|
||||
if not self.checkSecurityLimit(node[1], security_limit):
|
||||
warning(_("Trying to set parameter '%(param)s' in category '%(cat)s' without authorization!!!"
|
||||
log.warning(_("Trying to set parameter '%(param)s' in category '%(cat)s' without authorization!!!"
|
||||
% {'param': name, 'cat': category}))
|
||||
return
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from sat.core.i18n import _
|
||||
from logging import debug, info, warning, error
|
||||
from sat.core.log import getLogger
|
||||
log = getLogger(__name__)
|
||||
|
||||
|
||||
class MemoryNotInitializedError(Exception):
|
||||
|
|
@ -35,7 +36,7 @@ class PersistentDict(object):
|
|||
"""@param namespace: unique namespace for this dictionary
|
||||
@param profile: profile which *MUST* exists, or None for general values"""
|
||||
if not self.storage:
|
||||
error(_("PersistentDict can't be used before memory initialisation"))
|
||||
log.error(_("PersistentDict can't be used before memory initialisation"))
|
||||
raise MemoryNotInitializedError
|
||||
self._cache = {}
|
||||
self.namespace = namespace
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@
|
|||
|
||||
from sat.core.i18n import _
|
||||
from sat.core import exceptions
|
||||
from logging import debug, info, warning, error
|
||||
from sat.core.log import getLogger
|
||||
log = getLogger(__name__)
|
||||
from twisted.enterprise import adbapi
|
||||
from twisted.internet import defer
|
||||
from collections import OrderedDict
|
||||
|
|
@ -80,7 +81,7 @@ class SqliteStorage(object):
|
|||
self.initialized = defer.Deferred() # triggered when memory is fully initialised and ready
|
||||
self.profiles = {} # we keep cache for the profiles (key: profile name, value: profile id)
|
||||
|
||||
info(_("Connecting database"))
|
||||
log.info(_("Connecting database"))
|
||||
new_base = not os.path.exists(db_filename) # do we have to create the database ?
|
||||
if new_base: # the dir may not exist if it's not the XDG recommended one
|
||||
dir_ = os.path.dirname(db_filename)
|
||||
|
|
@ -92,10 +93,10 @@ class SqliteStorage(object):
|
|||
# XXX: foreign_keys activation doesn't seem to work, probably because of the multi-threading
|
||||
# All the requests that need to use this feature should be run with runInteraction instead,
|
||||
# so you can set the PRAGMA as it is done in self.deleteProfile
|
||||
init_defer = self.dbpool.runOperation("PRAGMA foreign_keys = ON").addErrback(lambda x: error(_("Can't activate foreign keys")))
|
||||
init_defer = self.dbpool.runOperation("PRAGMA foreign_keys = ON").addErrback(lambda x: log.error(_("Can't activate foreign keys")))
|
||||
|
||||
def getNewBaseSql():
|
||||
info(_("The database is new, creating the tables"))
|
||||
log.info(_("The database is new, creating the tables"))
|
||||
database_creation = ["PRAGMA user_version=%d" % CURRENT_DB_VERSION]
|
||||
database_creation.extend(Updater.createData2Raw(DATABASE_SCHEMAS['current']['CREATE']))
|
||||
database_creation.extend(Updater.insertData2Raw(DATABASE_SCHEMAS['current']['INSERT']))
|
||||
|
|
@ -109,7 +110,7 @@ class SqliteStorage(object):
|
|||
|
||||
if statements is None:
|
||||
return defer.succeed(None)
|
||||
debug("===== COMMITING STATEMENTS =====\n%s\n============\n\n" % '\n'.join(statements))
|
||||
log.debug("===== COMMITING STATEMENTS =====\n%s\n============\n\n" % '\n'.join(statements))
|
||||
d = self.dbpool.runInteraction(self._updateDb, tuple(statements))
|
||||
return d
|
||||
|
||||
|
|
@ -166,7 +167,7 @@ class SqliteStorage(object):
|
|||
@param name: name of the profile
|
||||
@return: deferred triggered once profile is actually deleted"""
|
||||
def deletionError(failure):
|
||||
error(_("Can't delete profile [%s]") % name)
|
||||
log.error(_("Can't delete profile [%s]") % name)
|
||||
return failure
|
||||
|
||||
def delete(txn):
|
||||
|
|
@ -176,7 +177,7 @@ class SqliteStorage(object):
|
|||
return None
|
||||
|
||||
d = self.dbpool.runInteraction(delete)
|
||||
d.addCallback(lambda ignore: info(_("Profile [%s] deleted") % name))
|
||||
d.addCallback(lambda ignore: log.info(_("Profile [%s] deleted") % name))
|
||||
d.addErrback(deletionError)
|
||||
return d
|
||||
|
||||
|
|
@ -190,7 +191,7 @@ class SqliteStorage(object):
|
|||
for param in result:
|
||||
category, name, value = param
|
||||
params_gen[(category, name)] = value
|
||||
debug(_("loading general parameters from database"))
|
||||
log.debug(_("loading general parameters from database"))
|
||||
return self.dbpool.runQuery("SELECT category,name,value FROM param_gen").addCallback(fillParams)
|
||||
|
||||
def loadIndParams(self, params_ind, profile):
|
||||
|
|
@ -203,7 +204,7 @@ class SqliteStorage(object):
|
|||
for param in result:
|
||||
category, name, value = param
|
||||
params_ind[(category, name)] = value
|
||||
debug(_("loading individual parameters from database"))
|
||||
log.debug(_("loading individual parameters from database"))
|
||||
d = self.dbpool.runQuery("SELECT category,name,value FROM param_ind WHERE profile_id=?", (self.profiles[profile], ))
|
||||
d.addCallback(fillParams)
|
||||
return d
|
||||
|
|
@ -225,7 +226,7 @@ class SqliteStorage(object):
|
|||
@param value: value to set
|
||||
@return: deferred"""
|
||||
d = self.dbpool.runQuery("REPLACE INTO param_gen(category,name,value) VALUES (?,?,?)", (category, name, value))
|
||||
d.addErrback(lambda ignore: error(_("Can't set general parameter (%(category)s/%(name)s) in database" % {"category": category, "name": name})))
|
||||
d.addErrback(lambda ignore: log.error(_("Can't set general parameter (%(category)s/%(name)s) in database" % {"category": category, "name": name})))
|
||||
return d
|
||||
|
||||
def setIndParam(self, category, name, value, profile):
|
||||
|
|
@ -236,7 +237,7 @@ class SqliteStorage(object):
|
|||
@param profile: a profile which *must* exist
|
||||
@return: deferred"""
|
||||
d = self.dbpool.runQuery("REPLACE INTO param_ind(category,name,profile_id,value) VALUES (?,?,?,?)", (category, name, self.profiles[profile], value))
|
||||
d.addErrback(lambda ignore: error(_("Can't set individual parameter (%(category)s/%(name)s) for [%(profile)s] in database" % {"category": category, "name": name, "profile": profile})))
|
||||
d.addErrback(lambda ignore: log.error(_("Can't set individual parameter (%(category)s/%(name)s) for [%(profile)s] in database" % {"category": category, "name": name, "profile": profile})))
|
||||
return d
|
||||
|
||||
#History
|
||||
|
|
@ -256,7 +257,7 @@ class SqliteStorage(object):
|
|||
d = self.dbpool.runQuery("INSERT INTO history(source, source_res, dest, dest_res, timestamp, message, type, extra, profile_id) VALUES (?,?,?,?,?,?,?,?,?)",
|
||||
(from_jid.userhost(), from_jid.resource, to_jid.userhost(), to_jid.resource, timestamp or time(),
|
||||
message, _type, extra_, self.profiles[profile]))
|
||||
d.addErrback(lambda ignore: error(_("Can't save following message in history: from [%(from_jid)s] to [%(to_jid)s] ==> [%(message)s]" %
|
||||
d.addErrback(lambda ignore: log.error(_("Can't save following message in history: from [%(from_jid)s] to [%(to_jid)s] ==> [%(message)s]" %
|
||||
{"from_jid": from_jid.full(), "to_jid": to_jid.full(), "message": message})))
|
||||
return d
|
||||
|
||||
|
|
@ -321,9 +322,9 @@ class SqliteStorage(object):
|
|||
for private in result:
|
||||
key, value = private
|
||||
private_gen[key] = value
|
||||
debug(_("loading general private values [namespace: %s] from database") % (namespace, ))
|
||||
log.debug(_("loading general private values [namespace: %s] from database") % (namespace, ))
|
||||
d = self.dbpool.runQuery("SELECT key,value FROM private_gen WHERE namespace=?", (namespace, )).addCallback(fillPrivates)
|
||||
return d.addErrback(lambda x: debug(_("No data present in database for namespace %s") % namespace))
|
||||
return d.addErrback(lambda x: log.debug(_("No data present in database for namespace %s") % namespace))
|
||||
|
||||
def loadIndPrivates(self, private_ind, namespace, profile):
|
||||
"""Load individual private values
|
||||
|
|
@ -336,10 +337,10 @@ class SqliteStorage(object):
|
|||
for private in result:
|
||||
key, value = private
|
||||
private_ind[key] = value
|
||||
debug(_("loading individual private values [namespace: %s] from database") % (namespace, ))
|
||||
log.debug(_("loading individual private values [namespace: %s] from database") % (namespace, ))
|
||||
d = self.dbpool.runQuery("SELECT key,value FROM private_ind WHERE namespace=? AND profile_id=?", (namespace, self.profiles[profile]))
|
||||
d.addCallback(fillPrivates)
|
||||
return d.addErrback(lambda x: debug(_("No data present in database for namespace %s") % namespace))
|
||||
return d.addErrback(lambda x: log.debug(_("No data present in database for namespace %s") % namespace))
|
||||
|
||||
def setGenPrivate(self, namespace, key, value):
|
||||
"""Save the general private value in database
|
||||
|
|
@ -348,7 +349,7 @@ class SqliteStorage(object):
|
|||
@param value: value to set
|
||||
@return: deferred"""
|
||||
d = self.dbpool.runQuery("REPLACE INTO private_gen(namespace,key,value) VALUES (?,?,?)", (namespace, key, value))
|
||||
d.addErrback(lambda ignore: error(_("Can't set general private value (%(key)s) [namespace:%(namespace)s] in database" %
|
||||
d.addErrback(lambda ignore: log.error(_("Can't set general private value (%(key)s) [namespace:%(namespace)s] in database" %
|
||||
{"namespace": namespace, "key": key})))
|
||||
return d
|
||||
|
||||
|
|
@ -360,7 +361,7 @@ class SqliteStorage(object):
|
|||
@param profile: a profile which *must* exist
|
||||
@return: deferred"""
|
||||
d = self.dbpool.runQuery("REPLACE INTO private_ind(namespace,key,profile_id,value) VALUES (?,?,?,?)", (namespace, key, self.profiles[profile], value))
|
||||
d.addErrback(lambda ignore: error(_("Can't set individual private value (%(key)s) [namespace: %(namespace)s] for [%(profile)s] in database" %
|
||||
d.addErrback(lambda ignore: log.error(_("Can't set individual private value (%(key)s) [namespace: %(namespace)s] for [%(profile)s] in database" %
|
||||
{"namespace": namespace, "key": key, "profile": profile})))
|
||||
return d
|
||||
|
||||
|
|
@ -370,7 +371,7 @@ class SqliteStorage(object):
|
|||
@param key: key of the private value
|
||||
@return: deferred"""
|
||||
d = self.dbpool.runQuery("DELETE FROM private_gen WHERE namespace=? AND key=?", (namespace, key))
|
||||
d.addErrback(lambda ignore: error(_("Can't delete general private value (%(key)s) [namespace:%(namespace)s] in database" %
|
||||
d.addErrback(lambda ignore: log.error(_("Can't delete general private value (%(key)s) [namespace:%(namespace)s] in database" %
|
||||
{"namespace": namespace, "key": key})))
|
||||
return d
|
||||
|
||||
|
|
@ -381,7 +382,7 @@ class SqliteStorage(object):
|
|||
@param profile: a profile which *must* exist
|
||||
@return: deferred"""
|
||||
d = self.dbpool.runQuery("DELETE FROM private_ind WHERE namespace=? AND key=? AND profile=?)", (namespace, key, self.profiles[profile]))
|
||||
d.addErrback(lambda ignore: error(_("Can't delete individual private value (%(key)s) [namespace: %(namespace)s] for [%(profile)s] in database" %
|
||||
d.addErrback(lambda ignore: log.error(_("Can't delete individual private value (%(key)s) [namespace: %(namespace)s] for [%(profile)s] in database" %
|
||||
{"namespace": namespace, "key": key, "profile": profile})))
|
||||
return d
|
||||
|
||||
|
|
@ -395,9 +396,9 @@ class SqliteStorage(object):
|
|||
for private in result:
|
||||
key, value = private
|
||||
private_gen[key] = pickle.loads(str(value))
|
||||
debug(_("loading general private binary values [namespace: %s] from database") % (namespace, ))
|
||||
log.debug(_("loading general private binary values [namespace: %s] from database") % (namespace, ))
|
||||
d = self.dbpool.runQuery("SELECT key,value FROM private_gen_bin WHERE namespace=?", (namespace, )).addCallback(fillPrivates)
|
||||
return d.addErrback(lambda x: debug(_("No binary data present in database for namespace %s") % namespace))
|
||||
return d.addErrback(lambda x: log.debug(_("No binary data present in database for namespace %s") % namespace))
|
||||
|
||||
def loadIndPrivatesBinary(self, private_ind, namespace, profile):
|
||||
"""Load individual private binary values
|
||||
|
|
@ -410,10 +411,10 @@ class SqliteStorage(object):
|
|||
for private in result:
|
||||
key, value = private
|
||||
private_ind[key] = pickle.loads(str(value))
|
||||
debug(_("loading individual private binary values [namespace: %s] from database") % (namespace, ))
|
||||
log.debug(_("loading individual private binary values [namespace: %s] from database") % (namespace, ))
|
||||
d = self.dbpool.runQuery("SELECT key,value FROM private_ind_bin WHERE namespace=? AND profile_id=?", (namespace, self.profiles[profile]))
|
||||
d.addCallback(fillPrivates)
|
||||
return d.addErrback(lambda x: debug(_("No binary data present in database for namespace %s") % namespace))
|
||||
return d.addErrback(lambda x: log.debug(_("No binary data present in database for namespace %s") % namespace))
|
||||
|
||||
def setGenPrivateBinary(self, namespace, key, value):
|
||||
"""Save the general private binary value in database
|
||||
|
|
@ -422,7 +423,7 @@ class SqliteStorage(object):
|
|||
@param value: value to set
|
||||
@return: deferred"""
|
||||
d = self.dbpool.runQuery("REPLACE INTO private_gen_bin(namespace,key,value) VALUES (?,?,?)", (namespace, key, pickle.dumps(value, 0)))
|
||||
d.addErrback(lambda ignore: error(_("Can't set general private binary value (%(key)s) [namespace:%(namespace)s] in database" %
|
||||
d.addErrback(lambda ignore: log.error(_("Can't set general private binary value (%(key)s) [namespace:%(namespace)s] in database" %
|
||||
{"namespace": namespace, "key": key})))
|
||||
return d
|
||||
|
||||
|
|
@ -434,7 +435,7 @@ class SqliteStorage(object):
|
|||
@param profile: a profile which *must* exist
|
||||
@return: deferred"""
|
||||
d = self.dbpool.runQuery("REPLACE INTO private_ind_bin(namespace,key,profile_id,value) VALUES (?,?,?,?)", (namespace, key, self.profiles[profile], pickle.dumps(value, 0)))
|
||||
d.addErrback(lambda ignore: error(_("Can't set individual binary private value (%(key)s) [namespace: %(namespace)s] for [%(profile)s] in database" %
|
||||
d.addErrback(lambda ignore: log.error(_("Can't set individual binary private value (%(key)s) [namespace: %(namespace)s] for [%(profile)s] in database" %
|
||||
{"namespace": namespace, "key": key, "profile": profile})))
|
||||
return d
|
||||
|
||||
|
|
@ -444,7 +445,7 @@ class SqliteStorage(object):
|
|||
@param key: key of the private value
|
||||
@return: deferred"""
|
||||
d = self.dbpool.runQuery("DELETE FROM private_gen_bin WHERE namespace=? AND key=?", (namespace, key))
|
||||
d.addErrback(lambda ignore: error(_("Can't delete general private binary value (%(key)s) [namespace:%(namespace)s] in database" %
|
||||
d.addErrback(lambda ignore: log.error(_("Can't delete general private binary value (%(key)s) [namespace:%(namespace)s] in database" %
|
||||
{"namespace": namespace, "key": key})))
|
||||
return d
|
||||
|
||||
|
|
@ -455,7 +456,7 @@ class SqliteStorage(object):
|
|||
@param profile: a profile which *must* exist
|
||||
@return: deferred"""
|
||||
d = self.dbpool.runQuery("DELETE FROM private_ind_bin WHERE namespace=? AND key=? AND profile=?)", (namespace, key, self.profiles[profile]))
|
||||
d.addErrback(lambda ignore: error(_("Can't delete individual private binary value (%(key)s) [namespace: %(namespace)s] for [%(profile)s] in database" %
|
||||
d.addErrback(lambda ignore: log.error(_("Can't delete individual private binary value (%(key)s) [namespace: %(namespace)s] for [%(profile)s] in database" %
|
||||
{"namespace": namespace, "key": key, "profile": profile})))
|
||||
return d
|
||||
##Helper methods##
|
||||
|
|
@ -521,7 +522,7 @@ class Updater(object):
|
|||
|
||||
if local_hash == current_hash:
|
||||
if local_version != CURRENT_DB_VERSION:
|
||||
warning(_("Your local schema is up-to-date, but database versions mismatch, fixing it..."))
|
||||
log.warning(_("Your local schema is up-to-date, but database versions mismatch, fixing it..."))
|
||||
yield self._setLocalVersion(CURRENT_DB_VERSION)
|
||||
else:
|
||||
# an update is needed
|
||||
|
|
@ -531,17 +532,17 @@ class Updater(object):
|
|||
if self._sat_version.endswith('D'):
|
||||
# we are in a development version
|
||||
update_data = self.generateUpdateData(local_sch, current_sch, False)
|
||||
warning(_("There is a schema mismatch, but as we are on a dev version, database will be updated"))
|
||||
log.warning(_("There is a schema mismatch, but as we are on a dev version, database will be updated"))
|
||||
update_raw = self.update2raw(update_data, True)
|
||||
defer.returnValue(update_raw)
|
||||
else:
|
||||
error(_(u"schema version is up-to-date, but local schema differ from expected current schema"))
|
||||
log.error(_(u"schema version is up-to-date, but local schema differ from expected current schema"))
|
||||
update_data = self.generateUpdateData(local_sch, current_sch, True)
|
||||
warning(_(u"Here are the commands that should fix the situation, use at your own risk (do a backup before modifying database), you can go to SàT's MUC room at sat@chat.jabberfr.org for help\n### SQL###\n%s\n### END SQL ###\n") % u'\n'.join(("%s;" % statement for statement in self.update2raw(update_data))))
|
||||
log.warning(_(u"Here are the commands that should fix the situation, use at your own risk (do a backup before modifying database), you can go to SàT's MUC room at sat@chat.jabberfr.org for help\n### SQL###\n%s\n### END SQL ###\n") % u'\n'.join(("%s;" % statement for statement in self.update2raw(update_data))))
|
||||
raise exceptions.DatabaseError("Database mismatch")
|
||||
else:
|
||||
# Database is not up-to-date, we'll do the update
|
||||
info(_("Database schema has changed, local database will be updated"))
|
||||
log.info(_("Database schema has changed, local database will be updated"))
|
||||
update_raw = []
|
||||
for version in xrange(local_version+1, CURRENT_DB_VERSION+1):
|
||||
try:
|
||||
|
|
@ -612,12 +613,12 @@ class Updater(object):
|
|||
schema_dict = {}
|
||||
for create_statement in raw_statements:
|
||||
if not create_statement.startswith("CREATE TABLE "):
|
||||
warning("Unexpected statement, ignoring it")
|
||||
log.warning("Unexpected statement, ignoring it")
|
||||
continue
|
||||
_create_statement = create_statement[13:]
|
||||
table, raw_col_stats = _create_statement.split(' ',1)
|
||||
if raw_col_stats[0] != '(' or raw_col_stats[-1] != ')':
|
||||
warning("Unexpected statement structure, ignoring it")
|
||||
log.warning("Unexpected statement structure, ignoring it")
|
||||
continue
|
||||
col_stats = [stmt.strip() for stmt in self.stmnt_regex.findall(raw_col_stats[1:-1])]
|
||||
col_defs = []
|
||||
|
|
@ -668,7 +669,7 @@ class Updater(object):
|
|||
new_col_defs, new_constraints = new_data[table]
|
||||
for obj in old_col_defs, old_constraints, new_col_defs, new_constraints:
|
||||
if not isinstance(obj, tuple):
|
||||
raise InternalError("Columns definitions must be tuples")
|
||||
raise exceptions.InternalError("Columns definitions must be tuples")
|
||||
defs_create, defs_delete, ignore = getChanges(set(old_col_defs), set(new_col_defs))
|
||||
constraints_create, constraints_delete, ignore = getChanges(set(old_constraints), set(new_constraints))
|
||||
created_col_names = set([name.split(' ',1)[0] for name in defs_create])
|
||||
|
|
@ -706,7 +707,7 @@ class Updater(object):
|
|||
drop.append(self.DROP_SQL % table)
|
||||
if dev_version:
|
||||
if drop:
|
||||
info("Dev version, SQL NOT EXECUTED:\n--\n%s\n--\n" % "\n".join(drop))
|
||||
log.info("Dev version, SQL NOT EXECUTED:\n--\n%s\n--\n" % "\n".join(drop))
|
||||
else:
|
||||
ret.extend(drop)
|
||||
|
||||
|
|
@ -717,7 +718,7 @@ class Updater(object):
|
|||
|
||||
cols_delete = update.get('cols delete', {})
|
||||
for table in cols_delete:
|
||||
info("Following columns in table [%s] are not needed anymore, but are kept for dev version: %s" % (table, ", ".join(cols_delete[table])))
|
||||
log.info("Following columns in table [%s] are not needed anymore, but are kept for dev version: %s" % (table, ", ".join(cols_delete[table])))
|
||||
|
||||
cols_modify = update.get('cols modify', {})
|
||||
for table in cols_modify:
|
||||
|
|
|
|||
|
|
@ -1,271 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# SAT plugin for managing xep-0045
|
||||
# Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Jérôme Poisson (goffi@goffi.org)
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
# the Free Software Foundation, either version 3 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 Affero General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from sat.core.i18n import _
|
||||
from logging import debug, info, warning, error
|
||||
from twisted.words.xish import domish
|
||||
from twisted.internet import protocol, defer, threads, reactor
|
||||
from twisted.words.protocols.jabber import client, jid, xmlstream
|
||||
from twisted.words.protocols.jabber import error as jab_error
|
||||
from twisted.words.protocols.jabber.xmlstream import IQ
|
||||
from twisted.web.client import getPage
|
||||
from sat.memory.persistent import PersistentBinaryDict
|
||||
import os.path
|
||||
import pdb
|
||||
|
||||
from zope.interface import implements
|
||||
|
||||
from wokkel import disco, iwokkel, data_form
|
||||
from sat.tools.xml_tools import XMLUI
|
||||
import urllib
|
||||
import webbrowser
|
||||
|
||||
from BeautifulSoup import BeautifulSoup
|
||||
import re
|
||||
|
||||
PLUGIN_INFO = {
|
||||
"name": "CouchSurfing plugin",
|
||||
"import_name": "CS",
|
||||
"type": "Misc",
|
||||
"protocols": [],
|
||||
"dependencies": [],
|
||||
"main": "CS_Plugin",
|
||||
"handler": "no",
|
||||
"description": _(u"""This plugin allow to manage your CouchSurfing account throught your SàT frontend""")
|
||||
}
|
||||
|
||||
AGENT = 'Salut à Toi XMPP/CS Plugin'
|
||||
|
||||
|
||||
class CS_Plugin(object):
|
||||
|
||||
params = """
|
||||
<params>
|
||||
<individual>
|
||||
<category name="CouchSurfing">
|
||||
<param name="Login" type="string" />
|
||||
<param name="Password" type="password" />
|
||||
</category>
|
||||
</individual>
|
||||
</params>
|
||||
"""
|
||||
|
||||
def __init__(self, host):
|
||||
info(_("Plugin CS initialization"))
|
||||
self.host = host
|
||||
#parameters
|
||||
host.memory.updateParams(CS_Plugin.params)
|
||||
#menu
|
||||
host.importMenu(_("Plugin"), "CouchSurfing", self.menuSelected, help_string=_("Launch CoushSurfing management interface"))
|
||||
self.data = {} # TODO: delete cookies/data after a while
|
||||
self.host.registerGeneralCB("plugin_CS_sendMessage", self.sendMessage)
|
||||
self.host.registerGeneralCB("plugin_CS_showUnreadMessages", self.showUnreadMessages)
|
||||
|
||||
def profileConnected(self, profile):
|
||||
self.data[profile] = PersistentBinaryDict("plugin_CS", profile)
|
||||
|
||||
def dataLoaded(ignore):
|
||||
if not self.data[profile]:
|
||||
self.data[profile] = {'cookies': {}}
|
||||
|
||||
self.data[profile].load().addCallback(dataLoaded)
|
||||
|
||||
def profileDisconnected(self, profile):
|
||||
del self.data[profile]
|
||||
|
||||
def erroCB(self, e, id):
|
||||
"""Called when something is going wrong when contacting CS website"""
|
||||
#pdb.set_trace()
|
||||
message_data = {"reason": "connection error", "message": _(u"Impossible to contact CS website, please check your login/password, connection or try again later")}
|
||||
self.host.bridge.actionResult("ERROR", id, message_data)
|
||||
|
||||
def menuSelected(self, id, profile):
|
||||
"""Called when the couchsurfing menu item is selected"""
|
||||
login = self.host.memory.getParamA("Login", "CouchSurfing", profile_key=profile)
|
||||
password = self.host.memory.getParamA("Password", "CouchSurfing", profile_key=profile)
|
||||
if not login or not password:
|
||||
message_data = {"reason": "uncomplete", "message": _(u"You have to fill your CouchSurfing login & password in parameters before using this interface")}
|
||||
self.host.bridge.actionResult("ERROR", id, message_data)
|
||||
return
|
||||
|
||||
post_data = urllib.urlencode({'auth_login[un]': login, 'auth_login[pw]': password, 'auth_login[action]': 'Login...'})
|
||||
|
||||
self.data[profile]['cookies'] = {}
|
||||
|
||||
d = getPage('http://www.couchsurfing.org/login.html', method='POST', postdata=post_data, headers={'Content-Type': 'application/x-www-form-urlencoded'}, agent=AGENT, cookies=self.data[profile]['cookies'])
|
||||
d.addCallback(self.__connectionCB, id, profile)
|
||||
d.addErrback(self.erroCB, id)
|
||||
|
||||
#self.host.bridge.actionResult("SUPPRESS", id, {})
|
||||
|
||||
#pages parsing callbacks
|
||||
|
||||
def savePage(self, name, html):
|
||||
f = open('/tmp/CS_' + name + '.html', 'w')
|
||||
f.write(html)
|
||||
f.close()
|
||||
print "page [%s] sauvee" % name
|
||||
#pdb.set_trace()
|
||||
|
||||
def __connectionCB(self, html, id, profile):
|
||||
print 'Response received'
|
||||
#self.savePage('principale',html)
|
||||
soup = BeautifulSoup(html)
|
||||
self.data[profile]['user_nick'] = soup.find('a', 'item_link', href='/home.html').contents[0]
|
||||
self.data[profile]['user_name'] = soup.html.head.title.string.split(' - ')[1]
|
||||
#unread messages
|
||||
try:
|
||||
self.data[profile]['unread_messages'] = int(soup.find(lambda tag: tag.name == 'div' and ('class', 'item_bubble') in tag.attrs and tag.find('a', href="/messages.html?message_status=inbox")).find(text=True))
|
||||
except:
|
||||
self.data[profile]['unread_messages'] = 0
|
||||
#unread couchrequest messages
|
||||
try:
|
||||
self.data[profile]['unread_CR_messages'] = int(soup.find(lambda tag: tag.name == 'div' and ('class', 'item_bubble') in tag.attrs and tag.find('a', href="/couchmanager")).find(text=True))
|
||||
except:
|
||||
self.data[profile]['unread_CR_messages'] = 0
|
||||
|
||||
#if we have already the list of friend, no need to make new requests
|
||||
if 'friends' not in self.data[profile]:
|
||||
self.data[profile]['friends'] = {}
|
||||
d = getPage('http://www.couchsurfing.org/connections.html?type=myfriends&show=10000', agent=AGENT, cookies=self.data[profile]['cookies'])
|
||||
d.addCallback(self.__friendsPageCB, id=id, profile=profile)
|
||||
d.addErrback(self.erroCB, id)
|
||||
else:
|
||||
self.host.bridge.actionResult("XMLUI", id, {"type": "window", "xml": self.__buildUI(self.data[profile])})
|
||||
|
||||
def __buildUI(self, data):
|
||||
"""Build the XML UI of the plugin
|
||||
@param data: data store for the profile"""
|
||||
user_nick = data['user_nick']
|
||||
user_name = data['user_name']
|
||||
unread_mess = data['unread_messages']
|
||||
unread_CR_mess = data['unread_CR_messages']
|
||||
friends_list = data['friends'].keys()
|
||||
friends_list.sort()
|
||||
interface = XMLUI('window', 'tabs', title='CouchSurfing management')
|
||||
interface.addCategory(_("Messages"), "vertical")
|
||||
interface.addText(_("G'day %(name)s, you have %(nb_message)i unread message%(plural_mess)s and %(unread_CR_mess)s unread couch request message%(plural_CR)s\nIf you want to send a message, select the recipient(s) in the list below") % {'name': user_name, 'nb_message': unread_mess, 'plural_mess': 's' if unread_mess > 1 else '', 'unread_CR_mess': unread_CR_mess, 'plural_CR': 's' if unread_CR_mess > 1 else ''})
|
||||
if unread_mess:
|
||||
interface.addButton('plugin_CS_showUnreadMessages', 'showUnreadMessages', _('Show unread message%(plural)s in external web browser') % {'plural': 's' if unread_mess > 1 else ''})
|
||||
interface.addList(friends_list, 'friends', None, style=['multi'])
|
||||
interface.changeLayout('pairs')
|
||||
interface.addLabel(_("Subject"))
|
||||
interface.addString('subject')
|
||||
interface.changeLayout('vertical')
|
||||
interface.addLabel(_("Message"))
|
||||
interface.addText("(use %name% for contact name and %firstname% for guessed first name)")
|
||||
interface.addTextBox('message')
|
||||
interface.addButton('plugin_CS_sendMessage', 'sendMessage', _('send'), fields_back=['friends', 'subject', 'message'])
|
||||
#interface.addCategory(_("Events"), "vertical") #TODO: coming soon, hopefuly :)
|
||||
#interface.addCategory(_("Couch search"), "vertical")
|
||||
return interface.toXml()
|
||||
|
||||
def __meetingPageCB(self, html):
|
||||
"""Called when the meeting page has been received"""
|
||||
|
||||
def __friendsPageCB(self, html, id, profile):
|
||||
"""Called when the friends list page has been received"""
|
||||
self.savePage('friends', html)
|
||||
soup = BeautifulSoup(html.replace('"formtable width="400', '"formtable" width="400"')) # CS html fix #TODO: report the bug to CS dev team
|
||||
friends = self.data[profile]['friends']
|
||||
for _tr in soup.findAll('tr', {'class': re.compile("^msgRow*")}): # we parse the row with friends infos
|
||||
_nobr = _tr.find('nobr') # contain the friend name
|
||||
friend_name = unicode(_nobr.string)
|
||||
friend_link = u'http://www.couchsurfing.org' + _nobr.parent['href']
|
||||
regex_href = re.compile(r'/connections\.html\?id=([^&]+)')
|
||||
a_tag = _tr.find('a', href=regex_href)
|
||||
friend_id = regex_href.search(unicode(a_tag)).groups()[0]
|
||||
|
||||
debug(_("CS friend found: %(friend_name)s (id: %(friend_id)s, link: %(friend_link)s)") % {'friend_name': friend_name, 'friend_id': friend_id, 'friend_link': friend_link})
|
||||
friends[friend_name] = {'link': friend_link, 'id': friend_id}
|
||||
a = soup.find('td', 'barmiddle next').a # is there several pages ?
|
||||
if a:
|
||||
#yes, we parse the next page
|
||||
d = getPage('http://www.couchsurfing.org/' + str(a['href']), agent=AGENT, cookies=self.data[profile]['cookies'])
|
||||
d.addCallback(self.__friendsPageCB, id=id, profile=profile)
|
||||
d.addErrback(self.erroCB, id)
|
||||
else:
|
||||
#no, we show the result
|
||||
self.host.bridge.actionResult("XMLUI", id, {"type": "window", "xml": self.__buildUI(self.data[profile])})
|
||||
|
||||
def __sendMessage(self, answer, subject, message, data, recipient_list, id, profile):
|
||||
"""Send actually the message
|
||||
@param subject: subject of the message
|
||||
@param message: body of the message
|
||||
@param data: data of the profile
|
||||
@param recipient_list: list of friends names, names are removed once message is sent
|
||||
@param id: id of the action
|
||||
@param profile: profile who launched the action
|
||||
"""
|
||||
if answer:
|
||||
if not 'Here is a copy of the email that was sent' in answer:
|
||||
error(_("INTERNAL ERROR: no confirmation of message sent by CS, maybe the site has been modified ?"))
|
||||
#TODO: throw a warning to the frontend, saying that maybe the message has not been sent and to contact dev of this plugin
|
||||
#debug(_('HTML answer: %s') % answer)
|
||||
if recipient_list:
|
||||
recipient = recipient_list.pop()
|
||||
try:
|
||||
friend_id = data['friends'][recipient]['id']
|
||||
except KeyError:
|
||||
error('INTERNAL ERROR: unknown friend')
|
||||
return # send an error to the frontend
|
||||
mess = message.replace('%name%', recipient).replace('%firstname%', recipient.split(' ')[0])
|
||||
info(_('Sending message to %s') % recipient)
|
||||
debug(_("\nsubject: %(subject)s\nmessage: \n---\n%(message)s\n---\n\n") % {'subject': subject, 'message': mess})
|
||||
post_data = urllib.urlencode({'email[subject]': subject.encode('utf-8'), 'email[body]': mess.encode('utf-8'), 'email[id]': friend_id, 'email[action]': 'Send Message', 'email[replied_id]': '', 'email[couchsurf]': '', 'email[directions_to_add]': ''})
|
||||
d = getPage("http://www.couchsurfing.org/send_message.html", method='POST', postdata=post_data, headers={'Content-Type': 'application/x-www-form-urlencoded'}, agent=AGENT, cookies=data['cookies'])
|
||||
d.addCallback(self.__sendMessage, subject, message, data, recipient_list, id, profile)
|
||||
d.addErrback(self.erroCB, id)
|
||||
else:
|
||||
interface = XMLUI('window', title=_('Message sent')) # TODO: create particular actionResult for alerts ?
|
||||
interface.addText(_('The message has been sent to every recipients'))
|
||||
self.host.bridge.actionResult("XMLUI", id, {"type": "window", "xml": interface.toXml()})
|
||||
|
||||
def sendMessage(self, id, data, profile):
|
||||
"""Called to send a message to a friend
|
||||
@param data: dict with the following keys:
|
||||
friend: name of the recipient
|
||||
subject: subject of the message
|
||||
message: body of the message, with the following special keywords:
|
||||
- %name%: name of the friend
|
||||
- %firstname%: guessed first name of the friend (currently the first part of the name)
|
||||
"""
|
||||
if not data['friends']:
|
||||
message_data = {"reason": "bad data", "message": _(u"There is not recipient selected for this message !")}
|
||||
self.host.bridge.actionResult("ERROR", id, message_data)
|
||||
return
|
||||
friends = data['friends'].split('\t')
|
||||
subject = data['subject']
|
||||
message = data['message']
|
||||
info(_("sending message to %(friends)s with subject [%(subject)s]" % {'friends': friends, 'subject': subject}))
|
||||
self.__sendMessage(None, subject, message, self.data[profile], friends, id, profile)
|
||||
|
||||
def __showUnreadMessages2(self, html, id, profile):
|
||||
"""Called when the inbox page has been received"""
|
||||
#FIXME: that's really too fragile, only works if the unread messages are in the first page, and it would be too resources consuming for the website to DL each time all pages. In addition, the show attribute doesn't work as expected.
|
||||
soup = BeautifulSoup(html)
|
||||
for tag in soup.findAll(lambda tag: tag.name == 'strong' and tag.a and tag.a['href'].startswith('messages.html?message_status=inbox')):
|
||||
link = "http://www.couchsurfing.org/" + str(tag.a['href'])
|
||||
webbrowser.open_new_tab(link) # TODO: the web browser need to already have CS cookies (i.e. already be opened & logged on CS, or be permanently loggued), a warning to the user should be sent/or a balloon-tip
|
||||
|
||||
def showUnreadMessages(self, id, data, profile):
|
||||
"""Called when user want to see all unread messages in the external browser"""
|
||||
d = getPage("http://www.couchsurfing.org/messages.html?message_status=inbox&show=10000", agent=AGENT, cookies=self.data[profile]['cookies'])
|
||||
d.addCallback(self.__showUnreadMessages2, id, profile)
|
||||
d.addErrback(self.erroCB, id)
|
||||
|
|
@ -19,7 +19,8 @@
|
|||
|
||||
from sat.core.i18n import _, D_
|
||||
from sat.core.constants import Const as C
|
||||
from logging import debug, info, warning, error
|
||||
from sat.core.log import getLogger
|
||||
log = getLogger(__name__)
|
||||
from twisted.words.protocols.jabber import jid
|
||||
from twisted.internet import defer, reactor
|
||||
from wokkel import data_form
|
||||
|
|
@ -53,7 +54,7 @@ PLUGIN_INFO = {
|
|||
class AdHocDBus(object):
|
||||
|
||||
def __init__(self, host):
|
||||
info(_("plugin Ad-Hoc D-Bus initialization"))
|
||||
log.info(_("plugin Ad-Hoc D-Bus initialization"))
|
||||
self.host = host
|
||||
host.bridge.addMethod("adHocDBusAddAuto", ".plugin", in_sign='sasasasasasass', out_sign='(sa(sss))',
|
||||
method=self._adHocDBusAddAuto,
|
||||
|
|
@ -97,7 +98,7 @@ class AdHocDBus(object):
|
|||
|
||||
@defer.inlineCallbacks
|
||||
def _introspect(self, methods, bus_name, proxy):
|
||||
debug("introspecting path [%s]" % proxy.object_path)
|
||||
log.debug("introspecting path [%s]" % proxy.object_path)
|
||||
introspect_xml = yield self._DBusIntrospect(proxy)
|
||||
el = etree.fromstring(introspect_xml)
|
||||
for node in el.iterchildren('node', 'interface'):
|
||||
|
|
@ -108,13 +109,13 @@ class AdHocDBus(object):
|
|||
elif node.tag == 'interface':
|
||||
name = node.get('name')
|
||||
if any(name.startswith(ignored) for ignored in IGNORED_IFACES_START):
|
||||
debug('interface [%s] is ignored' % name)
|
||||
log.debug('interface [%s] is ignored' % name)
|
||||
continue
|
||||
debug("introspecting interface [%s]" % name)
|
||||
log.debug("introspecting interface [%s]" % name)
|
||||
for method in node.iterchildren('method'):
|
||||
if self._acceptMethod(method):
|
||||
method_name = method.get('name')
|
||||
debug("method accepted: [%s]" % method_name)
|
||||
log.debug("method accepted: [%s]" % method_name)
|
||||
methods.add((proxy.object_path, name, method_name))
|
||||
|
||||
def _adHocDBusAddAuto(self, prog_name, allowed_jids, allowed_groups, allowed_magics, forbidden_jids, forbidden_groups, flags, profile_key):
|
||||
|
|
@ -125,13 +126,13 @@ class AdHocDBus(object):
|
|||
bus_names = yield self._DBusListNames()
|
||||
bus_names = [bus_name for bus_name in bus_names if '.' + prog_name in bus_name]
|
||||
if not bus_names:
|
||||
info("Can't find any bus for [%s]" % prog_name)
|
||||
log.info("Can't find any bus for [%s]" % prog_name)
|
||||
return
|
||||
bus_names.sort()
|
||||
for bus_name in bus_names:
|
||||
if bus_name.endswith(prog_name):
|
||||
break
|
||||
info("bus name found: [%s]" % bus_name)
|
||||
log.info("bus name found: [%s]" % bus_name)
|
||||
proxy = self.session_bus.get_object(bus_name, '/', introspect=False)
|
||||
methods = set()
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from sat.core.i18n import _
|
||||
from logging import debug, info, warning, error
|
||||
from sat.core.log import getLogger
|
||||
log = getLogger(__name__)
|
||||
from twisted.words.protocols.jabber import jid
|
||||
from twisted.internet import reactor, protocol
|
||||
|
||||
|
|
@ -47,13 +48,13 @@ class ExportCommandProtocol(protocol.ProcessProtocol):
|
|||
|
||||
def _clean(self, data):
|
||||
if not data:
|
||||
error ("data should not be empty !")
|
||||
log.error ("data should not be empty !")
|
||||
return u""
|
||||
decoded = data.decode('utf-8', 'ignore')[:-1 if data[-1] == '\n' else None]
|
||||
return clean_ustr(decoded)
|
||||
|
||||
def connectionMade(self):
|
||||
info("connectionMade :)")
|
||||
log.info("connectionMade :)")
|
||||
|
||||
def outReceived(self, data):
|
||||
self.parent.host.sendMessage(self.target, self._clean(data), no_trigger=True, profile_key=self.profile)
|
||||
|
|
@ -62,7 +63,7 @@ class ExportCommandProtocol(protocol.ProcessProtocol):
|
|||
self.parent.host.sendMessage(self.target, self._clean(data), no_trigger=True, profile_key=self.profile)
|
||||
|
||||
def processEnded(self, reason):
|
||||
info (u"process finished: %d" % (reason.value.exitCode,))
|
||||
log.info (u"process finished: %d" % (reason.value.exitCode,))
|
||||
self.parent.removeProcess(self.target, self)
|
||||
|
||||
def write(self, message):
|
||||
|
|
@ -83,7 +84,7 @@ class CommandExport(object):
|
|||
# this is specially true if we have other triggers.
|
||||
|
||||
def __init__(self, host):
|
||||
info(_("Plugin command export initialization"))
|
||||
log.info(_("Plugin command export initialization"))
|
||||
self.host = host
|
||||
self.spawned = {} # key = entity
|
||||
host.trigger.add("MessageReceived", self.MessageReceivedTrigger, priority=10000)
|
||||
|
|
@ -109,7 +110,7 @@ class CommandExport(object):
|
|||
body = [e for e in message.elements() if e.name == 'body'][0]
|
||||
except IndexError:
|
||||
# do not block message without body (chat state notification...)
|
||||
warning("No body element found in message, following normal behaviour")
|
||||
log.warning("No body element found in message, following normal behaviour")
|
||||
return True
|
||||
|
||||
mess_data = unicode(body) + '\n'
|
||||
|
|
@ -141,7 +142,7 @@ class CommandExport(object):
|
|||
"""
|
||||
profile = self.host.memory.getProfileName(profile_key)
|
||||
if not profile:
|
||||
warning("Unknown profile [%s]" % (profile,))
|
||||
log.warning("Unknown profile [%s]" % (profile,))
|
||||
return
|
||||
|
||||
for target in targets:
|
||||
|
|
@ -151,7 +152,7 @@ class CommandExport(object):
|
|||
raise jid.InvalidFormat
|
||||
_jid = _jid.userhostJID()
|
||||
except (jid.InvalidFormat, RuntimeError):
|
||||
info(u"invalid target ignored: %s" % (target,))
|
||||
log.info(u"invalid target ignored: %s" % (target,))
|
||||
continue
|
||||
process_prot = ExportCommandProtocol(self, _jid, options, profile)
|
||||
self.spawned.setdefault((_jid, profile),set()).add(process_prot)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@
|
|||
|
||||
from sat.core.i18n import _
|
||||
from sat.core.constants import Const as C
|
||||
from logging import debug, info, warning, error
|
||||
from sat.core.log import getLogger
|
||||
log = getLogger(__name__)
|
||||
from twisted.words.protocols.jabber import jid
|
||||
|
||||
from sat.core.exceptions import UnknownEntityError
|
||||
|
|
@ -46,14 +47,14 @@ class Exp_Parrot(object):
|
|||
# /unparrot command in text commands plugin.
|
||||
|
||||
def __init__(self, host):
|
||||
info(_("Plugin Parrot initialization"))
|
||||
log.info(_("Plugin Parrot initialization"))
|
||||
self.host = host
|
||||
host.trigger.add("MessageReceived", self.MessageReceivedTrigger, priority=100)
|
||||
#host.trigger.add("sendMessage", self.sendMessageTrigger, priority=100)
|
||||
try:
|
||||
self.host.plugins[C.TEXT_CMDS].registerTextCommands(self)
|
||||
except KeyError:
|
||||
info(_("Text commands not available"))
|
||||
log.info(_("Text commands not available"))
|
||||
|
||||
#def sendMessageTrigger(self, mess_data, treatments, profile):
|
||||
# """ Deactivate other triggers if recipient is in parrot links """
|
||||
|
|
@ -64,7 +65,7 @@ class Exp_Parrot(object):
|
|||
# return True
|
||||
#
|
||||
# if mess_data['to'].userhostJID() in _links.values():
|
||||
# debug("Parrot link detected, skipping other triggers")
|
||||
# log.debug("Parrot link detected, skipping other triggers")
|
||||
# raise SkipOtherTriggers
|
||||
|
||||
def MessageReceivedTrigger(self, message, post_treat, profile):
|
||||
|
|
@ -101,7 +102,7 @@ class Exp_Parrot(object):
|
|||
|
||||
self.host.sendMessage(jid.JID(unicode(linked)), msg, None, "auto", no_trigger=True, profile_key=profile)
|
||||
else:
|
||||
warning("No body element found in message, following normal behaviour")
|
||||
log.warning("No body element found in message, following normal behaviour")
|
||||
|
||||
return True
|
||||
|
||||
|
|
@ -117,7 +118,7 @@ class Exp_Parrot(object):
|
|||
_links = client.parrot_links = {}
|
||||
|
||||
_links[source_jid.userhostJID()] = dest_jid
|
||||
info("Parrot mode: %s will be repeated to %s" % (source_jid.userhost(), unicode(dest_jid)))
|
||||
log.info("Parrot mode: %s will be repeated to %s" % (source_jid.userhost(), unicode(dest_jid)))
|
||||
|
||||
def removeParrot(self, source_jid, profile):
|
||||
"""Remove parrot link
|
||||
|
|
@ -131,7 +132,7 @@ class Exp_Parrot(object):
|
|||
|
||||
def cmd_parrot(self, mess_data, profile):
|
||||
"""activate Parrot mode between 2 entities, in both directions."""
|
||||
debug("Catched parrot command")
|
||||
log.debug("Catched parrot command")
|
||||
txt_cmd = self.host.plugins[C.TEXT_CMDS]
|
||||
|
||||
try:
|
||||
|
|
@ -153,7 +154,7 @@ class Exp_Parrot(object):
|
|||
|
||||
def cmd_unparrot(self, mess_data, profile):
|
||||
"""remove Parrot mode between 2 entities, in both directions."""
|
||||
debug("Catched unparrot command")
|
||||
log.debug("Catched unparrot command")
|
||||
txt_cmd = self.host.plugins[C.TEXT_CMDS]
|
||||
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -19,10 +19,11 @@
|
|||
|
||||
from sat.core.i18n import _
|
||||
from sat.core.constants import Const as C
|
||||
from logging import debug, info, warning, error
|
||||
from sat.core.log import getLogger
|
||||
log = getLogger(__name__)
|
||||
from twisted.words.xish import domish
|
||||
from twisted.words.protocols.jabber import jid
|
||||
from twisted.words.protocols.jabber import error as jab_error
|
||||
from twisted.words.protocols import jabber
|
||||
from twisted.internet import reactor
|
||||
|
||||
from wokkel import data_form
|
||||
|
|
@ -47,7 +48,7 @@ class Exp_Pipe(object):
|
|||
"""This is a modified version of XEP-0096 to work with named pipes instead of files"""
|
||||
|
||||
def __init__(self, host):
|
||||
info(_("Plugin Pipe initialization"))
|
||||
log.info(_("Plugin Pipe initialization"))
|
||||
self.host = host
|
||||
self.managed_stream_m = [self.host.plugins["XEP-0065"].NAMESPACE,
|
||||
self.host.plugins["XEP-0047"].NAMESPACE] # Stream methods managed
|
||||
|
|
@ -62,12 +63,12 @@ class Exp_Pipe(object):
|
|||
def _kill_id(self, approval_id, profile):
|
||||
"""Delete a waiting_for_approval id, called after timeout
|
||||
@param approval_id: id of _pipe_waiting_for_approval"""
|
||||
info(_("SI Pipe Transfer: TimeOut reached for id %s") % approval_id)
|
||||
log.info(_("SI Pipe Transfer: TimeOut reached for id %s") % approval_id)
|
||||
try:
|
||||
client = self.host.getClient(profile)
|
||||
del client._pipe_waiting_for_approval[approval_id]
|
||||
except KeyError:
|
||||
warning(_("kill id called on a non existant approval id"))
|
||||
log.warning(_("kill id called on a non existant approval id"))
|
||||
|
||||
def transferRequest(self, iq_id, from_jid, si_id, si_mime_type, si_el, profile):
|
||||
"""Called when a pipe transfer is requested
|
||||
|
|
@ -77,14 +78,14 @@ class Exp_Pipe(object):
|
|||
@param si_mime_type: Mime type of the pipe (or default "application/octet-stream" if unknown)
|
||||
@param si_el: domish.Element of the request
|
||||
@param profile: %(doc_profile)s"""
|
||||
info(_("EXP-PIPE file transfer requested"))
|
||||
debug(si_el.toXml())
|
||||
log.info(_("EXP-PIPE file transfer requested"))
|
||||
log.debug(si_el.toXml())
|
||||
client = self.host.getClient(profile)
|
||||
pipe_elts = filter(lambda elt: elt.name == 'pipe', si_el.elements())
|
||||
feature_elts = self.host.plugins["XEP-0020"].getFeatureElt(si_el)
|
||||
|
||||
if not pipe_elts:
|
||||
warning(_("No pipe element found"))
|
||||
log.warning(_("No pipe element found"))
|
||||
self.host.plugins["XEP-0095"].sendBadRequestError(iq_id, from_jid, profile)
|
||||
return
|
||||
|
||||
|
|
@ -94,15 +95,15 @@ class Exp_Pipe(object):
|
|||
try:
|
||||
stream_method = self.host.plugins["XEP-0020"].negociate(feature_el, 'stream-method', self.managed_stream_m)
|
||||
except KeyError:
|
||||
warning(_("No stream method found"))
|
||||
log.warning(_("No stream method found"))
|
||||
self.host.plugins["XEP-0095"].sendBadRequestError(iq_id, from_jid, profile)
|
||||
return
|
||||
if not stream_method:
|
||||
warning(_("Can't find a valid stream method"))
|
||||
log.warning(_("Can't find a valid stream method"))
|
||||
self.host.plugins["XEP-0095"].sendFailedError(iq_id, from_jid, profile)
|
||||
return
|
||||
else:
|
||||
warning(_("No feature element found"))
|
||||
log.warning(_("No feature element found"))
|
||||
self.host.plugins["XEP-0095"].sendBadRequestError(iq_id, from_jid, profile)
|
||||
return
|
||||
|
||||
|
|
@ -125,7 +126,7 @@ class Exp_Pipe(object):
|
|||
try:
|
||||
dest_path = frontend_data['dest_path']
|
||||
except KeyError:
|
||||
error(_('dest path not found in frontend_data'))
|
||||
log.error(_('dest path not found in frontend_data'))
|
||||
del(client._pipe_waiting_for_approval[sid])
|
||||
return
|
||||
if stream_method == self.host.plugins["XEP-0065"].NAMESPACE:
|
||||
|
|
@ -135,7 +136,7 @@ class Exp_Pipe(object):
|
|||
file_obj = open(dest_path, 'w+')
|
||||
self.host.plugins["XEP-0047"].prepareToReceive(jid.JID(data['from']), sid, file_obj, None, self._transferSucceeded, self._transferFailed, profile)
|
||||
else:
|
||||
error(_("Unknown stream method, this should not happen at this stage, cancelling transfer"))
|
||||
log.error(_("Unknown stream method, this should not happen at this stage, cancelling transfer"))
|
||||
del(client._pipe_waiting_for_approval[sid])
|
||||
return
|
||||
|
||||
|
|
@ -145,7 +146,7 @@ class Exp_Pipe(object):
|
|||
misc_elts.append(domish.Element((PROFILE, "file")))
|
||||
self.host.plugins["XEP-0095"].acceptStream(data["id"], data['from'], feature_elt, misc_elts, profile)
|
||||
else:
|
||||
debug(_("Transfer [%s] refused"), sid)
|
||||
log.debug(_("Transfer [%s] refused"), sid)
|
||||
self.host.plugins["XEP-0095"].sendRejectedError(data["id"], data['from'], profile=profile)
|
||||
del(client._pipe_waiting_for_approval[sid])
|
||||
|
||||
|
|
@ -154,7 +155,7 @@ class Exp_Pipe(object):
|
|||
@param id: stream id"""
|
||||
client = self.host.getClient(profile)
|
||||
file_obj.close()
|
||||
info(_('Transfer %s successfuly finished') % sid)
|
||||
log.info(_('Transfer %s successfuly finished') % sid)
|
||||
del(client._pipe_waiting_for_approval[sid])
|
||||
|
||||
def _transferFailed(self, sid, file_obj, stream_method, reason, profile):
|
||||
|
|
@ -163,41 +164,41 @@ class Exp_Pipe(object):
|
|||
@param reason: can be TIMEOUT, IO_ERROR, PROTOCOL_ERROR"""
|
||||
client = self.host.getClient(profile)
|
||||
data, timeout, stream_method, failed_methods, profile = client._pipe_waiting_for_approval[sid]
|
||||
warning(_('Transfer %(id)s failed with stream method %(s_method)s') % {'id': sid,
|
||||
log.warning(_('Transfer %(id)s failed with stream method %(s_method)s') % {'id': sid,
|
||||
's_method': stream_method})
|
||||
# filepath = file_obj.name
|
||||
file_obj.close()
|
||||
#TODO: session remenber (within a time limit) when a stream method fail, and avoid that stream method with full jid for the rest of the session
|
||||
warning(_("All stream methods failed, can't transfer the file"))
|
||||
log.warning(_("All stream methods failed, can't transfer the file"))
|
||||
del(client._pipe_waiting_for_approval[sid])
|
||||
|
||||
def pipeCb(self, filepath, sid, profile, IQ):
|
||||
if IQ['type'] == "error":
|
||||
stanza_err = jab_error.exceptionFromStanza(IQ)
|
||||
stanza_err = jabber.error.exceptionFromStanza(IQ)
|
||||
if stanza_err.code == '403' and stanza_err.condition == 'forbidden':
|
||||
debug(_("Pipe transfer refused by %s") % IQ['from'])
|
||||
log.debug(_("Pipe transfer refused by %s") % IQ['from'])
|
||||
self.host.bridge.newAlert(_("The contact %s refused your pipe stream") % IQ['from'], _("Pipe stream refused"), "INFO", profile)
|
||||
else:
|
||||
warning(_("Error during pipe stream transfer with %s") % IQ['from'])
|
||||
log.warning(_("Error during pipe stream transfer with %s") % IQ['from'])
|
||||
self.host.bridge.newAlert(_("Something went wrong during the pipe stream session intialisation with %s") % IQ['from'], _("Pipe stream error"), "ERROR", profile)
|
||||
return
|
||||
|
||||
si_elt = IQ.firstChildElement()
|
||||
|
||||
if IQ['type'] != "result" or not si_elt or si_elt.name != "si":
|
||||
error(_("Protocol error during file transfer"))
|
||||
log.error(_("Protocol error during file transfer"))
|
||||
return
|
||||
|
||||
feature_elts = self.host.plugins["XEP-0020"].getFeatureElt(si_elt)
|
||||
if not feature_elts:
|
||||
warning(_("No feature element"))
|
||||
log.warning(_("No feature element"))
|
||||
return
|
||||
|
||||
choosed_options = self.host.plugins["XEP-0020"].getChoosedOptions(feature_elts[0])
|
||||
try:
|
||||
stream_method = choosed_options["stream-method"]
|
||||
except KeyError:
|
||||
warning(_("No stream method choosed"))
|
||||
log.warning(_("No stream method choosed"))
|
||||
return
|
||||
|
||||
if stream_method == self.host.plugins["XEP-0065"].NAMESPACE:
|
||||
|
|
@ -211,7 +212,7 @@ class Exp_Pipe(object):
|
|||
file_obj = open(filepath, 'r') # XXX: we have to be sure that filepath is well opened, as reading can block it
|
||||
self.host.plugins["XEP-0047"].startStream(file_obj, jid.JID(IQ['from']), sid, None, self.sendSuccessCb, self.sendFailureCb, None, profile)
|
||||
else:
|
||||
warning(_("Invalid stream method received"))
|
||||
log.warning(_("Invalid stream method received"))
|
||||
|
||||
def pipeOut(self, to_jid, filepath, data={}, profile_key=C.PROF_KEY_NONE):
|
||||
"""send a file using EXP-PIPE
|
||||
|
|
@ -223,7 +224,7 @@ class Exp_Pipe(object):
|
|||
"""
|
||||
profile = self.host.memory.getProfileName(profile_key)
|
||||
if not profile:
|
||||
warning(_("Trying to send a file from an unknown profile"))
|
||||
log.warning(_("Trying to send a file from an unknown profile"))
|
||||
return ""
|
||||
feature_elt = self.host.plugins["XEP-0020"].proposeFeatures({'stream-method': self.managed_stream_m})
|
||||
|
||||
|
|
@ -237,9 +238,9 @@ class Exp_Pipe(object):
|
|||
return sid
|
||||
|
||||
def sendSuccessCb(self, sid, file_obj, stream_method, profile):
|
||||
info(_('Transfer %s successfuly finished') % sid)
|
||||
log.info(_('Transfer %s successfuly finished') % sid)
|
||||
file_obj.close()
|
||||
|
||||
def sendFailureCb(self, sid, file_obj, stream_method, reason, profile):
|
||||
file_obj.close()
|
||||
warning(_('Transfer %(id)s failed with stream method %(s_method)s %(profile)s') % {'id': sid, "s_method": stream_method, "profile": profile})
|
||||
log.warning(_('Transfer %(id)s failed with stream method %(s_method)s %(profile)s') % {'id': sid, "s_method": stream_method, "profile": profile})
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from sat.core.i18n import _, D_
|
||||
from logging import debug, info, warning, error
|
||||
from sat.core.log import getLogger
|
||||
log = getLogger(__name__)
|
||||
from sat.core import exceptions
|
||||
from twisted.internet import reactor, defer, protocol
|
||||
from os.path import join, dirname
|
||||
|
|
@ -88,10 +89,10 @@ class ProsodyRegisterProtocol(protocol.ProcessProtocol):
|
|||
|
||||
def processEnded(self, reason):
|
||||
if (reason.value.exitCode == 0):
|
||||
info(_('Prosody command succeed'))
|
||||
log.info(_('Prosody command succeed'))
|
||||
self.deferred.callback(None)
|
||||
else:
|
||||
error(_(u"Can't complete Prosody command (error code: %(code)d): %(message)s") % {'code': reason.value.exitCode, 'message': self.data})
|
||||
log.error(_(u"Can't complete Prosody command (error code: %(code)d): %(message)s") % {'code': reason.value.exitCode, 'message': self.data})
|
||||
self.deferred.errback(Failure(exceptions.InternalError))
|
||||
|
||||
@classmethod
|
||||
|
|
@ -117,7 +118,7 @@ class MiscAccount(object):
|
|||
# only focused on Prosody) is planed
|
||||
|
||||
def __init__(self, host):
|
||||
info(_(u"Plugin Account initialization"))
|
||||
log.info(_(u"Plugin Account initialization"))
|
||||
self.host = host
|
||||
host.bridge.addMethod("registerSatAccount", ".plugin", in_sign='sss', out_sign='', method=self._registerAccount, async=True)
|
||||
host.bridge.addMethod("getNewAccountDomain", ".plugin", in_sign='', out_sign='s', method=self.getNewAccountDomain, async=False)
|
||||
|
|
@ -126,10 +127,10 @@ class MiscAccount(object):
|
|||
if self._prosody_path is None:
|
||||
paths = which(self.getConfig('prosodyctl'))
|
||||
if not paths:
|
||||
error(_("Can't find %s") % (self.getConfig('prosodyctl'), ))
|
||||
log.error(_("Can't find %s") % (self.getConfig('prosodyctl'), ))
|
||||
else:
|
||||
self._prosody_path = dirname(paths[0])
|
||||
info(_('Prosody path found: %s') % (self._prosody_path, ))
|
||||
log.info(_('Prosody path found: %s') % (self._prosody_path, ))
|
||||
|
||||
self.__account_cb_id = host.registerCallback(self._accountDialogCb, with_data=True)
|
||||
self.__delete_account_id = host.registerCallback(self.__deleteAccountCb, with_data=True)
|
||||
|
|
@ -193,7 +194,7 @@ class MiscAccount(object):
|
|||
|
||||
def email_ko(ignore):
|
||||
#TODO: return error code to user
|
||||
error("Failed to send email to %s" % email)
|
||||
log.error("Failed to send email to %s" % email)
|
||||
|
||||
body = (u"""Welcome to Libervia, a Salut à Toi project part
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@
|
|||
|
||||
from sat.core.i18n import _
|
||||
from sat.core.constants import Const as C
|
||||
from logging import debug, info, warning, error
|
||||
from sat.core.log import getLogger
|
||||
log = getLogger(__name__)
|
||||
from twisted.internet import defer
|
||||
from twisted.words.protocols.jabber import jid
|
||||
from twisted.words.xish.domish import Element, generateElementsNamed
|
||||
|
|
@ -83,7 +84,7 @@ class GroupBlog(object):
|
|||
"""This class use a SàT PubSub Service to manage access on microblog"""
|
||||
|
||||
def __init__(self, host):
|
||||
info(_("Group blog plugin initialization"))
|
||||
log.info(_("Group blog plugin initialization"))
|
||||
self.host = host
|
||||
|
||||
host.bridge.addMethod("sendGroupBlog", ".plugin", in_sign='sassa{ss}s', out_sign='',
|
||||
|
|
@ -157,18 +158,18 @@ class GroupBlog(object):
|
|||
|
||||
#we first check that we have a item-access pubsub server
|
||||
if not hasattr(client, "item_access_pubsub"):
|
||||
debug(_('Looking for item-access powered pubsub server'))
|
||||
log.debug(_('Looking for item-access powered pubsub server'))
|
||||
#we don't have any pubsub server featuring item access yet
|
||||
item_access_pubsubs = yield self.host.findFeaturesSet((NS_PUBSUB_AUTO_CREATE, NS_PUBSUB_CREATOR_JID_CHECK), "pubsub", "service", profile_key=profile)
|
||||
# item_access_pubsubs = yield self.host.findFeaturesSet((NS_PUBSUB_ITEM_ACCESS, NS_PUBSUB_AUTO_CREATE, NS_PUBSUB_CREATOR_JID_CHECK), "pubsub", "service", profile_key=profile)
|
||||
try:
|
||||
client.item_access_pubsub = item_access_pubsubs.pop()
|
||||
info(_("item-access powered pubsub service found: [%s]") % client.item_access_pubsub.full())
|
||||
log.info(_("item-access powered pubsub service found: [%s]") % client.item_access_pubsub.full())
|
||||
except KeyError:
|
||||
client.item_access_pubsub = None
|
||||
|
||||
if not client.item_access_pubsub:
|
||||
error(_("No item-access powered pubsub server found, can't use group blog"))
|
||||
log.error(_("No item-access powered pubsub server found, can't use group blog"))
|
||||
raise NoCompatiblePubSubServerFound
|
||||
|
||||
defer.returnValue((profile, client))
|
||||
|
|
@ -186,7 +187,7 @@ class GroupBlog(object):
|
|||
if (not (origin_host)
|
||||
or len(event_host) < len(origin_host)
|
||||
or event_host[-len(origin_host):] != origin_host):
|
||||
warning("Host incoherence between %s and %s (hack attempt ?)" % (unicode(event.sender),
|
||||
log.warning("Host incoherence between %s and %s (hack attempt ?)" % (unicode(event.sender),
|
||||
unicode(publisher)))
|
||||
return False
|
||||
|
||||
|
|
@ -243,7 +244,7 @@ class GroupBlog(object):
|
|||
try:
|
||||
microblog_data["groups"] = '\n'.join(form.fields[P.OPT_ROSTER_GROUPS_ALLOWED].values)
|
||||
except KeyError:
|
||||
warning("No group found for roster access-model")
|
||||
log.warning("No group found for roster access-model")
|
||||
microblog_data["groups"] = ''
|
||||
|
||||
break
|
||||
|
|
@ -317,7 +318,7 @@ class GroupBlog(object):
|
|||
elif access_type == "JID":
|
||||
raise NotImplementedError
|
||||
else:
|
||||
error(_("Unknown access_type"))
|
||||
log.error(_("Unknown access_type"))
|
||||
raise BadAccessTypeError
|
||||
|
||||
defer_blog = self.host.plugins["XEP-0060"].publish(service, node_name, items=[mblog_item], profile_key=client.profile)
|
||||
|
|
@ -373,7 +374,7 @@ class GroupBlog(object):
|
|||
elif access_type == "JID":
|
||||
raise NotImplementedError
|
||||
else:
|
||||
error(_("Unknown access type"))
|
||||
log.error(_("Unknown access type"))
|
||||
raise BadAccessTypeError
|
||||
|
||||
return self._initialise(profile_key).addCallback(initialised)
|
||||
|
|
@ -395,10 +396,10 @@ class GroupBlog(object):
|
|||
# remove the associated comments node
|
||||
comments_service, comments_node = self.host.plugins["XEP-0277"].parseCommentUrl(comments)
|
||||
d = self.host.plugins["XEP-0060"].deleteNode(comments_service, comments_node, profile_key=profile)
|
||||
d.addErrback(lambda failure: error("Deletion of node %s failed: %s" % (comments_node, failure.getErrorMessage())))
|
||||
d.addErrback(lambda failure: log.error("Deletion of node %s failed: %s" % (comments_node, failure.getErrorMessage())))
|
||||
# remove the item itself
|
||||
d = self.host.plugins["XEP-0060"].retractItems(service_jid, node, [item_id], profile_key=profile)
|
||||
d.addErrback(lambda failure: error("Deletion of item %s from %s failed: %s" % (item_id, node, failure.getErrorMessage())))
|
||||
d.addErrback(lambda failure: log.error("Deletion of item %s from %s failed: %s" % (item_id, node, failure.getErrorMessage())))
|
||||
return d
|
||||
|
||||
def notify(d):
|
||||
|
|
@ -447,7 +448,7 @@ class GroupBlog(object):
|
|||
self.__fillCommentsElement(mblog_data, entry_id, node, service_jid)
|
||||
entry_d = self.host.plugins["XEP-0277"].data2entry(mblog_data, profile)
|
||||
entry_d.addCallback(lambda mblog_item: self.host.plugins["XEP-0060"].publish(service_jid, node, items=[mblog_item], profile_key=profile))
|
||||
entry_d.addErrback(lambda failure: error("Modification of %s failed: %s" % (pub_data, failure.getErrorMessage())))
|
||||
entry_d.addErrback(lambda failure: log.error("Modification of %s failed: %s" % (pub_data, failure.getErrorMessage())))
|
||||
return entry_d
|
||||
|
||||
return self._initialise(profile_key).addCallback(initialised)
|
||||
|
|
@ -501,7 +502,7 @@ class GroupBlog(object):
|
|||
self.host.plugins["XEP-0060"].subscribe(jid.JID(gbdata["comments_service"]), gbdata["comments_node"],
|
||||
profile_key=client.profile)
|
||||
except KeyError:
|
||||
warning("Missing key for comments")
|
||||
log.warning("Missing key for comments")
|
||||
defer.returnValue(ret)
|
||||
|
||||
def __getGroupBlogs(self, pub_jid_s, max_items=10, item_ids=None, profile_key=C.PROF_KEY_NONE):
|
||||
|
|
@ -775,8 +776,8 @@ class GroupBlog(object):
|
|||
|
||||
main_node = self.getNodeName(jid_)
|
||||
d = self.host.plugins["XEP-0060"].deleteNode(service, main_node, profile_key=profile)
|
||||
d.addCallback(lambda dummy: info(_("All microblog's main items from %s have been deleted!") % jid_.userhost()))
|
||||
d.addErrback(lambda failure: error(_("Deletion of node %(node)s failed: %(message)s") %
|
||||
d.addCallback(lambda dummy: log.info(_("All microblog's main items from %s have been deleted!") % jid_.userhost()))
|
||||
d.addErrback(lambda failure: log.error(_("Deletion of node %(node)s failed: %(message)s") %
|
||||
{'node': main_node, 'message': failure.getErrorMessage()}))
|
||||
return d
|
||||
|
||||
|
|
@ -799,7 +800,7 @@ class GroupBlog(object):
|
|||
main_node = self.getNodeName(jid_)
|
||||
d = self.host.plugins["XEP-0060"].getItems(service, main_node, profile_key=profile)
|
||||
d.addCallback(getComments, client)
|
||||
d.addErrback(lambda failure, main_node: error(_("Retrieval of items for node %(node)s failed: %(message)s") %
|
||||
d.addErrback(lambda failure, main_node: log.error(_("Retrieval of items for node %(node)s failed: %(message)s") %
|
||||
{'node': main_node, 'message': failure.getErrorMessage()}), main_node)
|
||||
blogs.append(d)
|
||||
|
||||
|
|
@ -822,7 +823,7 @@ class GroupBlog(object):
|
|||
service, node = self.host.plugins['XEP-0277'].parseCommentUrl(href)
|
||||
d = self.host.plugins["XEP-0060"].getItems(service, node, profile_key=profile_key)
|
||||
d.addCallback(lambda items, service, node: (service, node, items), service, node)
|
||||
d.addErrback(lambda failure, node: error(_("Retrieval of comments for node %(node)s failed: %(message)s") %
|
||||
d.addErrback(lambda failure, node: log.error(_("Retrieval of comments for node %(node)s failed: %(message)s") %
|
||||
{'node': node, 'message': failure.getErrorMessage()}), node)
|
||||
comments.append(d)
|
||||
dlist = defer.DeferredList(comments)
|
||||
|
|
@ -854,9 +855,9 @@ class GroupBlog(object):
|
|||
deletions = []
|
||||
if item_ids: # remove the comments of the user on the given post
|
||||
d = self.host.plugins['XEP-0060'].retractItems(service, node_id, item_ids, profile_key=profile_key)
|
||||
d.addCallback(lambda dummy, node_id: debug(_('Comments of user %(user)s in node %(node)s have been retracted') %
|
||||
d.addCallback(lambda dummy, node_id: log.debug(_('Comments of user %(user)s in node %(node)s have been retracted') %
|
||||
{'user': user_jid_s, 'node': node_id}), node_id)
|
||||
d.addErrback(lambda failure, node_id: error(_("Retraction of comments from %(user)s in node %(node)s failed: %(message)s") %
|
||||
d.addErrback(lambda failure, node_id: log.error(_("Retraction of comments from %(user)s in node %(node)s failed: %(message)s") %
|
||||
{'user': user_jid_s, 'node': node_id, 'message': failure.getErrorMessage()}), node_id)
|
||||
deletions.append(d)
|
||||
return defer.DeferredList(deletions)
|
||||
|
|
|
|||
|
|
@ -18,20 +18,17 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from sat.core.i18n import _
|
||||
from logging import debug, info, error
|
||||
import warnings
|
||||
from sat.core.log import getLogger
|
||||
log = getLogger(__name__)
|
||||
from twisted.internet import protocol, defer
|
||||
from twisted.words.protocols.jabber import error as jab_error
|
||||
from twisted.cred import portal, checkers, credentials
|
||||
from twisted.cred import error as cred_error
|
||||
from twisted.mail import imap4
|
||||
from twisted.python import failure
|
||||
from email.parser import Parser
|
||||
import email.message
|
||||
import os
|
||||
from cStringIO import StringIO
|
||||
from twisted.internet import reactor
|
||||
import pdb
|
||||
|
||||
from zope.interface import implements
|
||||
|
||||
|
|
@ -61,14 +58,14 @@ class IMAP_server(object):
|
|||
"""
|
||||
|
||||
def __init__(self, host):
|
||||
info(_("Plugin Imap Server initialization"))
|
||||
log.info(_("Plugin Imap Server initialization"))
|
||||
self.host = host
|
||||
|
||||
#parameters
|
||||
host.memory.updateParams(self.params)
|
||||
|
||||
port = int(self.host.memory.getParamA("IMAP Port", "Mail Server"))
|
||||
info(_("Launching IMAP server on port %d"), port)
|
||||
log.info(_("Launching IMAP server on port %d") % port)
|
||||
|
||||
self.server_factory = ImapServerFactory(self.host)
|
||||
reactor.listenTCP(port, self.server_factory)
|
||||
|
|
@ -78,7 +75,7 @@ class Message(object):
|
|||
implements(imap4.IMessage)
|
||||
|
||||
def __init__(self, uid, flags, mess_fp):
|
||||
debug('Message Init')
|
||||
log.debug('Message Init')
|
||||
self.uid = uid
|
||||
self.flags = flags
|
||||
self.mess_fp = mess_fp
|
||||
|
|
@ -87,21 +84,21 @@ class Message(object):
|
|||
def getUID(self):
|
||||
"""Retrieve the unique identifier associated with this message.
|
||||
"""
|
||||
debug('getUID (message)')
|
||||
log.debug('getUID (message)')
|
||||
return self.uid
|
||||
|
||||
def getFlags(self):
|
||||
"""Retrieve the flags associated with this message.
|
||||
@return: The flags, represented as strings.
|
||||
"""
|
||||
debug('getFlags')
|
||||
log.debug('getFlags')
|
||||
return self.flags
|
||||
|
||||
def getInternalDate(self):
|
||||
"""Retrieve the date internally associated with this message.
|
||||
@return: An RFC822-formatted date string.
|
||||
"""
|
||||
debug('getInternalDate')
|
||||
log.debug('getInternalDate')
|
||||
return self.message['Date']
|
||||
|
||||
def getHeaders(self, negate, *names):
|
||||
|
|
@ -111,7 +108,7 @@ class Message(object):
|
|||
should be omitted from the return value, rather than included.
|
||||
@return: A mapping of header field names to header field values
|
||||
"""
|
||||
debug('getHeaders %s - %s' % (negate, names))
|
||||
log.debug('getHeaders %s - %s' % (negate, names))
|
||||
final_dict = {}
|
||||
to_check = [name.lower() for name in names]
|
||||
for header in self.message.keys():
|
||||
|
|
@ -123,20 +120,20 @@ class Message(object):
|
|||
def getBodyFile(self):
|
||||
"""Retrieve a file object containing only the body of this message.
|
||||
"""
|
||||
debug('getBodyFile')
|
||||
log.debug('getBodyFile')
|
||||
return StringIO(self.message.get_payload())
|
||||
|
||||
def getSize(self):
|
||||
"""Retrieve the total size, in octets, of this message.
|
||||
"""
|
||||
debug('getSize')
|
||||
log.debug('getSize')
|
||||
self.mess_fp.seek(0, os.SEEK_END)
|
||||
return self.mess_fp.tell()
|
||||
|
||||
def isMultipart(self):
|
||||
"""Indicate whether this message has subparts.
|
||||
"""
|
||||
debug('isMultipart')
|
||||
log.debug('isMultipart')
|
||||
return False
|
||||
|
||||
def getSubPart(self, part):
|
||||
|
|
@ -144,7 +141,7 @@ class Message(object):
|
|||
@param part: The number of the part to retrieve, indexed from 0.
|
||||
@return: The specified sub-part.
|
||||
"""
|
||||
debug('getSubPart')
|
||||
log.debug('getSubPart')
|
||||
return TypeError
|
||||
|
||||
|
||||
|
|
@ -154,14 +151,14 @@ class SatMailbox(object):
|
|||
def __init__(self, host, name, profile):
|
||||
self.host = host
|
||||
self.listeners = set()
|
||||
debug('Mailbox init (%s)', name)
|
||||
log.debug('Mailbox init (%s)', name)
|
||||
if name != "INBOX":
|
||||
raise imap4.MailboxException("Only INBOX is managed for the moment")
|
||||
self.mailbox = self.host.plugins["Maildir"].accessMessageBox(name, self.newMessage, profile)
|
||||
|
||||
def newMessage(self):
|
||||
"""Called when a new message is in the mailbox"""
|
||||
debug("newMessage signal received")
|
||||
log.debug("newMessage signal received")
|
||||
nb_messages = self.getMessageCount()
|
||||
for listener in self.listeners:
|
||||
listener.newMessages(nb_messages, None)
|
||||
|
|
@ -169,13 +166,13 @@ class SatMailbox(object):
|
|||
def getUIDValidity(self):
|
||||
"""Return the unique validity identifier for this mailbox.
|
||||
"""
|
||||
debug('getUIDValidity')
|
||||
log.debug('getUIDValidity')
|
||||
return 0
|
||||
|
||||
def getUIDNext(self):
|
||||
"""Return the likely UID for the next message added to this mailbox.
|
||||
"""
|
||||
debug('getUIDNext')
|
||||
log.debug('getUIDNext')
|
||||
return self.mailbox.getNextUid()
|
||||
|
||||
def getUID(self, message):
|
||||
|
|
@ -183,41 +180,41 @@ class SatMailbox(object):
|
|||
@param message: The message sequence number
|
||||
@return: The UID of the message.
|
||||
"""
|
||||
debug('getUID (%i)' % message)
|
||||
log.debug('getUID (%i)' % message)
|
||||
#return self.mailbox.getUid(message-1) #XXX: it seems that this method get uid and not message sequence number
|
||||
return message
|
||||
|
||||
def getMessageCount(self):
|
||||
"""Return the number of messages in this mailbox.
|
||||
"""
|
||||
debug('getMessageCount')
|
||||
log.debug('getMessageCount')
|
||||
ret = self.mailbox.getMessageCount()
|
||||
debug("count = %i" % ret)
|
||||
log.debug("count = %i" % ret)
|
||||
return ret
|
||||
|
||||
def getRecentCount(self):
|
||||
"""Return the number of messages with the 'Recent' flag.
|
||||
"""
|
||||
debug('getRecentCount')
|
||||
log.debug('getRecentCount')
|
||||
return len(self.mailbox.getMessageIdsWithFlag('\\Recent'))
|
||||
|
||||
def getUnseenCount(self):
|
||||
"""Return the number of messages with the 'Unseen' flag.
|
||||
"""
|
||||
debug('getUnseenCount')
|
||||
log.debug('getUnseenCount')
|
||||
return self.getMessageCount() - len(self.mailbox.getMessageIdsWithFlag('\\SEEN'))
|
||||
|
||||
def isWriteable(self):
|
||||
"""Get the read/write status of the mailbox.
|
||||
@return: A true value if write permission is allowed, a false value otherwise.
|
||||
"""
|
||||
debug('isWriteable')
|
||||
log.debug('isWriteable')
|
||||
return True
|
||||
|
||||
def destroy(self):
|
||||
"""Called before this mailbox is deleted, permanently.
|
||||
"""
|
||||
debug('destroy')
|
||||
log.debug('destroy')
|
||||
|
||||
def requestStatus(self, names):
|
||||
"""Return status information about this mailbox.
|
||||
|
|
@ -229,7 +226,7 @@ class SatMailbox(object):
|
|||
information up would be costly, a deferred whose callback will
|
||||
eventually be passed this dictionary is returned instead.
|
||||
"""
|
||||
debug('requestStatus')
|
||||
log.debug('requestStatus')
|
||||
return imap4.statusRequestHelper(self, names)
|
||||
|
||||
def addListener(self, listener):
|
||||
|
|
@ -239,7 +236,7 @@ class SatMailbox(object):
|
|||
@param listener: An object to add to the set of those which will
|
||||
be notified when the contents of this mailbox change.
|
||||
"""
|
||||
debug('addListener %s' % listener)
|
||||
log.debug('addListener %s' % listener)
|
||||
self.listeners.add(listener)
|
||||
|
||||
def removeListener(self, listener):
|
||||
|
|
@ -252,7 +249,7 @@ class SatMailbox(object):
|
|||
@raise ValueError: Raised when the given object is not a listener for
|
||||
this mailbox.
|
||||
"""
|
||||
debug('removeListener')
|
||||
log.debug('removeListener')
|
||||
if listener in self.listeners:
|
||||
self.listeners.remove(listener)
|
||||
else:
|
||||
|
|
@ -267,7 +264,7 @@ class SatMailbox(object):
|
|||
id if the message is added successfully and whose errback is
|
||||
invoked otherwise.
|
||||
"""
|
||||
debug('addMessage')
|
||||
log.debug('addMessage')
|
||||
raise imap4.MailboxException("Client message addition not implemented yet")
|
||||
|
||||
def expunge(self):
|
||||
|
|
@ -275,7 +272,7 @@ class SatMailbox(object):
|
|||
@return: The list of message sequence numbers which were deleted,
|
||||
or a Deferred whose callback will be invoked with such a list.
|
||||
"""
|
||||
debug('expunge')
|
||||
log.debug('expunge')
|
||||
self.mailbox.removeDeleted()
|
||||
|
||||
def fetch(self, messages, uid):
|
||||
|
|
@ -284,13 +281,13 @@ class SatMailbox(object):
|
|||
about
|
||||
@param uid: If true, the IDs specified in the query are UIDs;
|
||||
"""
|
||||
debug('fetch (%s, %s)' % (messages, uid))
|
||||
log.debug('fetch (%s, %s)' % (messages, uid))
|
||||
if uid:
|
||||
messages.last = self.mailbox.getMaxUid()
|
||||
messages.getnext = self.mailbox.getNextExistingUid
|
||||
for mess_uid in messages:
|
||||
if mess_uid is None:
|
||||
debug('stopping iteration')
|
||||
log.debug('stopping iteration')
|
||||
raise StopIteration
|
||||
try:
|
||||
yield (mess_uid, Message(mess_uid, self.mailbox.getFlagsUid(mess_uid), self.mailbox.getMessageUid(mess_uid)))
|
||||
|
|
@ -318,7 +315,7 @@ class SatMailbox(object):
|
|||
been performed, or a Deferred whose callback will be invoked with
|
||||
such a dict.
|
||||
"""
|
||||
debug('store')
|
||||
log.debug('store')
|
||||
|
||||
flags = [flag.upper() for flag in flags]
|
||||
|
||||
|
|
@ -361,13 +358,13 @@ class SatMailbox(object):
|
|||
Flags with the \\ prefix are reserved for use as system flags.
|
||||
@return: A list of the flags that can be set on messages in this mailbox.
|
||||
"""
|
||||
debug('getFlags')
|
||||
log.debug('getFlags')
|
||||
return ['\\SEEN', '\\ANSWERED', '\\FLAGGED', '\\DELETED', '\\DRAFT'] # TODO: add '\\RECENT'
|
||||
|
||||
def getHierarchicalDelimiter(self):
|
||||
"""Get the character which delimits namespaces for in this mailbox.
|
||||
"""
|
||||
debug('getHierarchicalDelimiter')
|
||||
log.debug('getHierarchicalDelimiter')
|
||||
return '.'
|
||||
|
||||
|
||||
|
|
@ -375,12 +372,12 @@ class ImapSatAccount(imap4.MemoryAccount):
|
|||
#implements(imap4.IAccount)
|
||||
|
||||
def __init__(self, host, profile):
|
||||
debug("ImapAccount init")
|
||||
log.debug("ImapAccount init")
|
||||
self.host = host
|
||||
self.profile = profile
|
||||
imap4.MemoryAccount.__init__(self, profile)
|
||||
self.addMailbox("Inbox") # We only manage Inbox for the moment
|
||||
debug('INBOX added')
|
||||
log.debug('INBOX added')
|
||||
|
||||
def _emptyMailbox(self, name, id):
|
||||
return SatMailbox(self.host, name, self.profile)
|
||||
|
|
@ -393,7 +390,7 @@ class ImapRealm(object):
|
|||
self.host = host
|
||||
|
||||
def requestAvatar(self, avatarID, mind, *interfaces):
|
||||
debug('requestAvatar')
|
||||
log.debug('requestAvatar')
|
||||
profile = avatarID.decode('utf-8')
|
||||
if imap4.IAccount not in interfaces:
|
||||
raise NotImplementedError
|
||||
|
|
@ -436,13 +433,13 @@ class ImapServerFactory(protocol.ServerFactory):
|
|||
self.host = host
|
||||
|
||||
def startedConnecting(self, connector):
|
||||
debug(_("IMAP server connection started"))
|
||||
log.debug(_("IMAP server connection started"))
|
||||
|
||||
def clientConnectionLost(self, connector, reason):
|
||||
debug(_("IMAP server connection lost (reason: %s)"), reason)
|
||||
log.debug(_("IMAP server connection lost (reason: %s)"), reason)
|
||||
|
||||
def buildProtocol(self, addr):
|
||||
debug("Building protocol")
|
||||
log.debug("Building protocol")
|
||||
prot = protocol.ServerFactory.buildProtocol(self, addr)
|
||||
prot.portal = portal.Portal(ImapRealm(self.host))
|
||||
prot.portal.registerChecker(SatProfileCredentialChecker(self.host))
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue