First JCLComponent implementation

darcs-hash:20060814161654-86b55-e6f2553e9ebae6bb8b057795ddc4f53e449a5c68.gz
This commit is contained in:
David Rousselie
2006-08-14 18:16:54 +02:00
parent 8e524449cf
commit 12b0308572
7 changed files with 836 additions and 32 deletions

View File

@@ -21,30 +21,16 @@
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##
from jcl.model.account import *
import logging
import signal
from pyxmpp.jid import JID
from pyxmpp.jabberd.component import Component
from pyxmpp.presence import Presence
class JabberComponent(object):
def __init__(self):
pass
class Feeder(object):
def __init__(self):
pass
def feed(self, account):
pass
class Sender(object):
def __init__(self):
pass
def send(self, to_account, message):
pass
from jcl.model.account import Account
VERSION = "0.1"
###############################################################################
# JCL implementation
@@ -55,20 +41,327 @@ class JCLComponent(Component):
secret,
server,
port,
check_interval,
spool_dir,
storage,
name,
name = "Jabber Component Library generic component",
disco_category = "gateway",
disco_type = "headline"):
disco_type = "headline",
spool_dir = ".",
check_interval = 1,
account_class = Account):
Component.__init__(self, \
JID(jid), \
secret, \
port, \
disco_category, \
disco_type)
self.__logger = logging.getLogger("jcl.jabber.JCLComponent")
# TODO : self.__lang = Lang(default_lang)
self.__name = name
self.__disco_category = disco_category
self.__disco_type = disco_type
self.__interval = check_interval
self.running = False
self.__shutdown = 0
signal.signal(signal.SIGINT, self.signal_handler)
signal.signal(signal.SIGTERM, self.signal_handler)
spool_dir += "/" + jid
self.__account_class = account_class
self.__account_class.createTable(ifNotExists = True)
self.version = VERSION
def authenticated(self):
Component.authenticated(self)
self.__logger.debug("AUTHENTICATED")
# Send probe for transport
current_jid = None
for account in self.__account_class.select(orderBy = "user_jid"):
if account.user_jid != current_jid:
p = Presence(from_jid = unicode(self.jid), \
to_jid = account.user_jid, \
stanza_type = "probe")
self.stream.send(p)
current_jid = account.user_jid
p = Presence(from_jid = self.get_jid(account), \
to_jid = account.user_jid, \
stanza_type = "probe")
self.stream.send(p)
self.stream.set_iq_get_handler("query", "jabber:iq:version", \
self.handle_get_version)
self.stream.set_iq_get_handler("query", "jabber:iq:register", \
self.handle_get_register)
self.stream.set_iq_set_handler("query", "jabber:iq:register", \
self.handle_set_register)
self.stream.set_presence_handler("available", \
self.handle_presence_available)
self.stream.set_presence_handler("probe", \
self.handle_presence_available)
self.stream.set_presence_handler("unavailable", \
self.handle_presence_unavailable)
self.stream.set_presence_handler("unsubscribe", \
self.handle_presence_unsubscribe)
self.stream.set_presence_handler("unsubscribed", \
self.handle_presence_unsubscribed)
self.stream.set_presence_handler("subscribe", \
self.handle_presence_subscribe)
self.stream.set_presence_handler("subscribed", \
self.handle_presence_subscribed)
self.stream.set_message_handler("normal", \
self.handle_message)
def run(self):
self.connect()
self.running = True
thread.start_new_thread(self.time_handler, ())
try:
while (not self.__shutdown and self.stream
and not self.stream.eof and self.stream.socket is not None):
try:
self.stream.loop_iter(timeout)
except (KeyboardInterrupt, SystemExit, FatalStreamError, \
StreamError):
raise
except:
self.__logger.exception("Exception cought:")
finally:
self.running = False
if self.stream:
# TODO : send unavailble from transport and all account to users
pass
# for jid in self.__storage.keys(()):
# p = Presence(from_jid = unicode(self.jid), to_jid = jid, \
# stanza_type = "unavailable")
# self.stream.send(p)
# for jid, name in self.__storage.keys():
# if self.__storage[(jid, name)].status != "offline":
# p = Presence(from_jid = name + "@" + unicode(self.jid), \
# to_jid = jid, \
# stanza_type = "unavailable")
# self.stream.send(p)
threads = threading.enumerate()
for th in threads:
try:
th.join(10 * timeout)
except:
pass
for th in threads:
try:
th.join(timeout)
except:
pass
self.disconnect()
# TODO : terminate SQLObject
self.__logger.debug("Exitting normally")
def get_reg_form(self, lang_class, account_class):
pass
def get_reg_form_init(self, lang_class, account):
pass
def _ask_password(self, lang_class, account):
if not account.waiting_password_reply \
and account.status != "offline":
account.waiting_password_reply = True
msg = Message(from_jid = account.jid, \
to_jid = from_jid, \
stanza_type = "normal", \
subject = u"[PASSWORD] " + lang_class.ask_password_subject, \
body = lang_class.ask_password_body % \
(account.host, account.login))
self.stream.send(msg)
def get_jid(self, account):
return account.name + u"@" + unicode(self.jid)
## Handlers
""" Stop method handler """
def signal_handler(self, signum, frame):
self.__logger.debug("Signal %i received, shutting down..." % (signum,))
self.__shutdown = 1
def stream_state_changed(self,state,arg):
self.__logger.debug("*** State changed: %s %r ***" % (state,arg))
""" Discovery get info handler """
def disco_get_info(self, node, iq):
self.__logger.debug("DISCO_GET_INFO")
di = DiscoInfo()
if node is None:
di.add_feature("jabber:iq:version")
di.add_feature("jabber:iq:register")
DiscoIdentity(di, self.__name, \
self.__disco_category, \
self.__disco_type)
else:
di.add_feature("jabber:iq:register")
return di
""" Discovery get nested nodes handler """
def disco_get_items(self, node, iq):
self.__logger.debug("DISCO_GET_ITEMS")
# lang_class = self.__lang.get_lang_class_from_node(iq.get_node())
base_from_jid = unicode(iq.get_from().bare())
di = DiscoItems()
if not node:
# TODO : list accounts
for account in self.__accounts:
pass
# DiscoItem(di, JID(name + "@" + unicode(self.jid)), \
# name, str_name)
return di
""" Get Version handler """
def handle_get_version(self, iq):
self.__logger.debug("GET_VERSION")
iq = iq.make_result_response()
q = iq.new_query("jabber:iq:version")
q.newTextChild(q.ns(), "name", self.__name)
q.newTextChild(q.ns(), "version", self.version)
self.stream.send(iq)
return 1
""" Send back register form to user """
def handle_get_register(self, iq):
self.__logger.debug("GET_REGISTER")
# lang_class = self.__lang.get_lang_class_from_node(iq.get_node())
base_from_jid = unicode(iq.get_from().bare())
to = iq.get_to()
iq = iq.make_result_response()
q = iq.new_query("jabber:iq:register")
if to and to != self.jid:
self.get_reg_form_init(lang_class, \
self.__accounts.select() # TODO
).attach_xml(q)
else:
self.get_reg_form(lang_class).attach_xml(q)
self.stream.send(iq)
return 1
""" Handle user registration response """
def handle_set_register(self, iq):
self.__logger.debug("SET_REGISTER")
lang_class = self.__lang.get_lang_class_from_node(iq.get_node())
to = iq.get_to()
from_jid = iq.get_from()
base_from_jid = unicode(from_jid.bare())
remove = iq.xpath_eval("r:query/r:remove", \
{"r" : "jabber:iq:register"})
if remove:
for name in self.__storage.keys((base_from_jid,)):
self.__logger.debug("Deleting " + name + " for " + base_from_jid)
p = Presence(from_jid = name + "@" + unicode(self.jid), \
to_jid = from_jid, \
stanza_type = "unsubscribe")
self.stream.send(p)
p = Presence(from_jid = name + "@" + unicode(self.jid), \
to_jid = from_jid, \
stanza_type = "unsubscribed")
self.stream.send(p)
del self.__storage[(base_from_jid, name)]
p = Presence(from_jid = self.jid, to_jid = from_jid, \
stanza_type = "unsubscribe")
self.stream.send(p)
p = Presence(from_jid = self.jid, to_jid = from_jid, \
stanza_type = "unsubscribed")
self.stream.send(p)
return 1
query = iq.get_query()
x = X()
x.from_xml(query.children)
# TODO : get info from Xdata
""" Handle presence availability """
def handle_presence_available(self, stanza):
self.__logger.debug("PRESENCE_AVAILABLE")
from_jid = stanza.get_from()
base_from_jid = unicode(from_jid.bare())
name = stanza.get_to().node
lang_class = self.__lang.get_lang_class_from_node(stanza.get_node())
show = stanza.get_show()
self.__logger.debug("SHOW : " + str(show))
if name:
self.__logger.debug("TO : " + name + " " + base_from_jid)
# TODO : if to transport send back available to all user's account
# else send available presence
return 1
""" handle presence unavailability """
def handle_presence_unavailable(self, stanza):
self.__logger.debug("PRESENCE_UNAVAILABLE")
from_jid = stanza.get_from()
base_from_jid = unicode(from_jid.bare())
# TODO : send unavailable to all user's account if target is transport
# else send unavailable back
return 1
""" handle subscribe presence from user """
def handle_presence_subscribe(self, stanza):
self.__logger.debug("PRESENCE_SUBSCRIBE")
p = stanza.make_accept_response()
self.stream.send(p)
return 1
""" handle subscribed presence from user """
def handle_presence_subscribed(self, stanza):
self.__logger.debug("PRESENCE_SUBSCRIBED")
name = stanza.get_to().node
from_jid = stanza.get_from()
base_from_jid = unicode(from_jid.bare())
# TODO : send presence available to subscribed user
return 1
""" handle unsubscribe presence from user """
def handle_presence_unsubscribe(self, stanza):
self.__logger.debug("PRESENCE_UNSUBSCRIBE")
name = stanza.get_to().node
from_jid = stanza.get_from()
base_from_jid = unicode(from_jid.bare())
# TODO : delete from account base
p = Presence(from_jid = stanza.get_to(), to_jid = from_jid, \
stanza_type = "unsubscribe")
self.stream.send(p)
p = stanza.make_accept_response()
self.stream.send(p)
return 1
""" handle unsubscribed presence from user """
def handle_presence_unsubscribed(self, stanza):
self.__logger.debug("PRESENCE_UNSUBSCRIBED")
p = Presence(from_jid = stanza.get_to(), \
to_jid = stanza.get_from(), \
stanza_type = "unavailable")
self.stream.send(p)
return 1
""" Handle new message """
def handle_message(self, message):
self.__logger.debug("MESSAGE: " + message.get_body())
lang_class = self.__lang.get_lang_class_from_node(message.get_node())
name = message.get_to().node
base_from_jid = unicode(message.get_from().bare())
if re.compile("\[PASSWORD\]").search(message.get_subject()) is not None:
# TODO and self.__storage.has_key((base_from_jid, name)):
# account = self.__storage[(base_from_jid, name)]
account.password = message.get_body()
account.waiting_password_reply = False
msg = Message(from_jid = account.jid, \
to_jid = message.get_from(), \
stanza_type = "normal", \
subject = lang_class.password_saved_for_session, \
body = lang_class.password_saved_for_session)
self.stream.send(msg)
return 1
def handle_tick(self):
for account in Account.select("*"):
for message in self.__jabber_component.feeder.feed(account):
self.__jabber_component.sender.send(account, message)
pass

70
src/jcl/jabber/feeder.py Normal file
View File

@@ -0,0 +1,70 @@
# -*- coding: UTF-8 -*-
##
## component.py
## Login : David Rousselie <dax@happycoders.org>
## Started on Wed Aug 9 21:04:42 2006 David Rousselie
## $Id$
##
## Copyright (C) 2006 David Rousselie
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##
from jcl.jabber.component import JCLComponent
from jcl.model.account import *
class FeederComponent(JCLComponent):
def __init__(self,
jid,
secret,
server,
port,
name = "Generic Feeder Component",
disco_category = "gateway",
disco_type = "headline",
spool_dir = ".",
check_interval = 1):
JCLComponent.__init__(self, \
jid, \
secret, \
server, \
port, \
name, \
disco_category, \
disco_type, \
spool_dir, \
check_interval)
def handle_tick(self):
for account in Account.select("*"):
for message in self.__jabber_component.feeder.feed(account):
self.__jabber_component.sender.send(account, message)
class Feeder(object):
def __init__(self):
pass
def feed(self, account):
pass
class Sender(object):
def __init__(self):
pass
def send(self, to_account, message):
pass

247
src/jcl/lang.py Normal file
View File

@@ -0,0 +1,247 @@
# -*- coding: utf-8 -*-
##
## lang.py
## Login : David Rousselie <dax@happycoders.org>
## Started on Sat Jan 28 16:37:11 2006 David Rousselie
## $Id$
##
## Copyright (C) 2006 David Rousselie
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##
# TODO delete not JCL translation
class Lang:
def __init__(self, default_lang = "en"):
self.default_lang = default_lang
def get_lang_from_node(self, node):
lang = node.getLang()
if lang is None:
print "Using default lang " + self.default_lang
lang = self.default_lang
return lang
def get_lang_class(self, lang):
return getattr(Lang, lang)
def get_lang_class_from_node(self, node):
return self.get_lang_class(self.get_lang_from_node(node))
class en:
register_title = u"Jabber Mail connection registration"
register_instructions = u"Enter connection parameters"
account_name = u"Connection name"
account_login = u"Login"
account_password = u"Password"
account_password_store = u"Store password on Jabber server?"
account_host = u"Host"
account_port = u"Port"
account_type = u"Mail server type"
account_mailbox = u"Mailbox path (IMAP)"
account_ffc_action = u"Action when state is 'Free For Chat'"
account_online_action = u"Action when state is 'Online'"
account_away_action = u"Action when state is 'Away'"
account_xa_action = u"Action when state is 'Not Available'"
account_dnd_action = u"Action when state is 'Do not Disturb'"
account_offline_action = u"Action when state is 'Offline'"
account_check_interval = u"Mail check interval (in minutes)"
account_live_email_only = u"Reports only emails received while connected to Jabber"
action_nothing = u"Do nothing"
action_retrieve = u"Retrieve mail"
action_digest = u"Send mail digest"
update_title = u"Jabber mail connection update"
update_instructions = u"Modifying connection '%s'"
connection_label = u"%s connection '%s'"
update_account_message_subject = u"Updated %s connection '%s'"
update_account_message_body = u"Registered with username '%s' and " \
"password '%s' on '%s'"
new_account_message_subject = u"New %s connection '%s' created"
new_account_message_body = u"Registered with " \
"username '%s' and password '%s' on '%s'"
ask_password_subject = u"Password request"
ask_password_body = u"Reply to this message with the password " \
"for the following account: \n" \
"\thost = %s\n" \
"\tlogin = %s\n"
password_saved_for_session = u"Password will be kept during your Jabber session"
check_error_subject = u"Error while checking emails."
check_error_body = u"An error appears while checking emails:\n\t%s"
new_mail_subject = u"New email from %s"
new_digest_subject = u"%i new email(s)"
class fr:
register_title = u"Enregistrement d'une nouvelle connexion à un serveur email."
register_instructions = u"Entrer les paramètres de connexion"
account_name = u"Nom de la connexion"
account_login = u"Nom d'utilisateur"
account_password = u"Mot de passe"
account_password_store = u"Sauvegarder le mot de passe sur le serveur Jabber ?"
account_host = u"Adresse du serveur email"
account_port = u"Port du serveur email"
account_type = u"Type du serveur email"
account_mailbox = u"Chemin de la boîte email (IMAP)"
account_ffc_action = u"Action lorsque l'état est 'Free For Chat'"
account_online_action = u"Action lorsque l'état est 'Online'"
account_away_action = u"Action lorsque l'état est 'Away'"
account_xa_action = u"Action lorsque l'état est 'Not Available'"
account_dnd_action = u"Action lorsque l'état est 'Do not Disturb'"
account_offline_action = u"Action lorsque l'état est 'Offline'"
account_check_interval = u"Interval de vérification de nouveaux emails (en minutes)"
account_live_email_only = u"Vérifier les nouveaux emails seulement " \
"lorsqu'une session Jabber est ouverte"
action_nothing = u"Ne rien faire"
action_retrieve = u"Récupérer l'email"
action_digest = u"Envoyer un résumé"
update_title = u"Mise à jour du compte JMC"
update_instructions = u"Modification de la connexion '%s'"
connection_label = u"Connexion %s '%s'"
update_account_message_subject = u"La connexion %s '%s' a été mise à jour"
update_account_message_body = u"Nom d'utilisateur : '%s'\nMot de passe : '%s'\nsur : '%s'"
new_account_message_subject = u"La connexion %s '%s' a été créée"
new_account_message_body = u"Nom d'utilisateur : '%s'\nMot de passe : '%s'\nsur : '%s'"
ask_password_subject = u"Demande de mot de passe"
ask_password_body = u"Répondre à ce message avec le mot de passe du " \
"compte suivant : \n" \
"\thost = %s\n" \
"\tlogin = %s\n"
password_saved_for_session = u"Le mot de passe sera garder tout au " \
"long de la session Jabber."
check_error_subject = u"Erreur lors de la vérification des emails."
check_error_body = u"Une erreur est survenue lors de la vérification " \
"des emails :\n\t%s"
new_mail_subject = u"Nouvel email de %s"
new_digest_subject = u"%i nouveau(x) email(s)"
class nl:
register_title = u"Registratie van verbindingen voor Jabber Mail"
register_instructions = u"Instellingen voor verbinding"
account_name = u"Accountnaam"
account_login = u"Gebruikersnaam"
account_password = u"Wachtwoord"
account_password_store = u"Wachtwoord opslaan op Jabber-server?"
account_host = u"Server"
account_port = u"Poort"
account_type = u"Soort account"
account_mailbox = u"Pad naar mailbox (IMAP)"
account_ffc_action = u"Actie bij aanwezigheid 'Chat'"
account_online_action = u"Actie bij aanwezigheid 'Beschikbaar'"
account_away_action = u"Actie bij aanwezigheid 'Afwezig'"
account_xa_action = u"Actie bij aanwezigheid 'Langdurig afwezig'"
account_dnd_action = u"Actie bij aanwezigheid 'Niet storen'"
account_offline_action = u"Actie bij aanwezigheid 'Niet beschikbaar'"
account_check_interval = u"Controle-interval (in minuten)"
account_live_email_only = u"Enkel controleren op e-mails als er een" \
"verbinding is met Jabber"
action_nothing = u"Niets doen"
action_retrieve = u"E-mail ophalen"
action_digest = u"Samenvatting verzenden"
update_title = u"Bijwerken van JMC"
update_instructions = u"Verbinding '%s' aanpassen"
connection_label = u"%s verbinding '%s'"
update_account_message_subject = u"Verbinding %s '%s' werd bijgewerkt"
update_account_message_body = u"Geregistreerd met gebruikersnaam '%s'"\
"en wachtwoord '%s' op '%s'"
new_account_message_subject = u"Nieuwe %s verbinding '%s' aangemaakt"
new_account_message_body = u"Geregistreerd met " \
"gebruikersnaam '%s' en wachtwoord '%s' op '%s'"
ask_password_subject = u"Wachtwoordaanvraag"
ask_password_body = u"Antwoord dit bericht met het volgende wachtwoord" \
"voor de volgende account: \n" \
"\thost = %s\n" \
"\tlogin = %s\n"
password_saved_for_session = u"Het wachtwoord zal worden bewaard tijdens uw Jabber-sessie"
check_error_subject = u"Fout tijdens controle op e-mails."
check_error_body = u"Fout tijdens controle op e-mails:\n\t%s"
new_mail_subject = u"Nieuwe e-mail van %s"
new_digest_subject = u"%i nieuwe e-mail(s)"
class es:
register_title = u"Registro de nueva cuenta de email"
register_instructions = u"Inserta los datos para la nueva cuenta"
account_name = u"Nombre para la cuenta"
account_login = u"Usuario (login)"
account_password = u"Contraseña"
account_password_store = u"¿Guardar la contraseña en el servidor Jabber?"
account_host = u"Host"
account_port = u"Puerto"
account_type = u"Tipo de servidor Mail"
account_mailbox = u"Ruta del mailbox (solo para IMAP)"
account_ffc_action = u"Acción para cuando tu estado sea 'Listopara hablar'"
account_online_action = u"Acción para cuando tu estado sea 'Conectado'"
account_away_action = u"Acción para cuando tu estado sea 'Ausente'"
account_xa_action = u"Acción para cuando tu estado sea 'No disponible'"
account_dnd_action = u"Acción para cuando tu estado sea 'No molestar'"
account_offline_action = u"Acción para cuando tu estado sea 'Desconectado'"
account_check_interval = u"Intervalo para comprobar emails nuevos (en minutos)"
account_live_email_only = u"Avisarme de emails nuevos solo cuando esté conectado"
action_nothing = u"No hacer nada"
action_retrieve = u"Mostrarme el email"
action_digest = u"Enviar resúmen"
update_title = u"Actualización de cuenta de email"
update_instructions = u"Modifica los datos de la cuenta '%s'"
connection_label = u"%s conexión '%s'"
update_account_message_subject = u"Actualizada %s conexión '%s'"
update_account_message_body = u"Registrado con el usuario '%s' y contraseña '%s' en '%s'"
new_account_message_subject = u"Nueva %s conexión '%s' creada"
new_account_message_body = u"Registrado con usuario '%s' y contraseña '%s' en '%s'"
ask_password_subject = u"Petición de contraseña"
ask_password_body = u"Para avisarte de emails nuevos, contesta a este mensaje con la contraseña " \
"de la cuenta: \n" \
"\tHost = %s\n" \
"\tUsuario = %s\n"
password_saved_for_session = u"La contraseña será guardada para esta sesión únicamente."
check_error_subject = u"Error al revisar los emails."
check_error_body = u"Un error apareció al revisar los emails:\n\t%s"
new_mail_subject = u"Nuevo email en %s"
new_digest_subject = u"%i email(s) nuevo(s)"
class pl:
register_title = u"Rejestracja w komponencie E-Mail"
register_instructions = u"Wprowadź parametry połączenia"
account_name = u"Nazwa połączenia"
account_login = u"Nazwa użytkownika"
account_password = u"Hasło"
account_password_store = u"Zachować hasło na serwerze Jabbera? "
account_host = u"Nazwa hosta"
account_port = u"Port"
account_type = u"Typ serwera email"
account_mailbox = u"Ścieżka do skrzynki odbiorczej (IMAP)"
account_ffc_action = u"Akcja gdy status to 'Chętny do rozmowy'"
account_online_action = u"Akcja gdy status to 'Dostępny'"
account_away_action = u"Akcja gdy status to 'Zaraz wracam'"
account_xa_action = u"Akcja gdy status to 'Niedostępny'"
account_dnd_action = u"Akcja gdy status to 'Nie przeszkadzać'"
account_offline_action = u"Akcja gdy status to 'Rozłączony'"
account_check_interval = u"Sprawdzaj email co (w minutach)"
account_live_email_only = u"Raportuj otrzymane emaile tylko\n gdy podłączony do Jabbera"
action_nothing = u"Nic nie rób"
action_retrieve = u"Pobierz emaila"
action_digest = u"Wyślij zarys emaila"
update_title = u"Modyfikacja połączenia z komponentem mailowym"
update_instructions = u"Modyfikacja połączenia '%s'"
connection_label = u"%s połączenie '%s'"
update_account_message_subject = u"Zmodyfikowane %s połączenie '%s'"
update_account_message_body = u"Zarejestrowany z nazwą użytkownika '%s' i hasłem '%s' na '%s'"
new_account_message_subject = u"Nowe %s połączenie '%s' utworzone"
new_account_message_body = u"Zarejestrowany z nazwą użytkownika '%s' i hasłem '%s' na '%s'"
ask_password_subject = u"Żądanie hasła"
ask_password_body = u"Odpowiedz na ta wiadomosc z hasłem dla podanego konta: \n" \
"\tnazwa hosta = %s\n" \
"\tnazwa uzytkownika = %s\n"
password_saved_for_session = u"Hasło będzie przechowywane podczas Twojej sesji Jabbera"
check_error_subject = u"Błąd podczas sprawdzania emaili."
check_error_body = u"Pojawił się błąd podczas sprawdzania emaili:\n\t%s"
new_mail_subject = u"Nowy email od %s"
new_digest_subject = u"%i nowy(ch) email(i)"

View File

@@ -24,7 +24,7 @@
from sqlobject import *
class Account(SQLObject):
jid = StringCol()
user_jid = StringCol()
name = StringCol()