root/branches/gajim_0.2-2/core/core.py

Revision 210, 18.1 kB (checked in by asterix, 4 years ago)

now we can register a new account

  • Property svn:keywords set to LastChangedDate LastChangedRevision LastChangedBy HeadURL Id
Line 
1#!/usr/bin/env python
2##      core/core.py
3##
4## Gajim Team:
5##      - Yann Le Boulanger <asterix@crans.org>
6##      - Vincent Hanquez <tab@snarc.org>
7##
8##      Copyright (C) 2003 Gajim Team
9##
10## This program is free software; you can redistribute it and/or modify
11## it under the terms of the GNU General Public License as published
12## by the Free Software Foundation; version 2 only.
13##
14## This program is distributed in the hope that it will be useful,
15## but WITHOUT ANY WARRANTY; without even the implied warranty of
16## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17## GNU General Public License for more details.
18##
19
20import sys, os
21
22sys.path.append("..")
23import time
24import string
25import logging
26
27import common.hub
28import common.jabber
29import common.optparser
30
31from common import i18n
32_ = i18n._
33
34log = logging.getLogger('core.core')
35log.setLevel(logging.DEBUG)
36
37CONFPATH = "~/.gajim/config"
38LOGPATH = os.path.expanduser("~/.gajim/logs/")
39
40class GajimCore:
41        """Core"""
42        def __init__(self):
43                self.log = 0
44                self.init_cfg_file()
45                self.cfgParser = common.optparser.OptionsParser(CONFPATH)
46                self.hub = common.hub.GajimHub()
47                self.parse()
48                if self.log:
49                        log.setLevel(logging.DEBUG)
50                else:
51                        log.setLevel(None)
52                self.connected = {}
53                #connexions {con: name, ...}
54                self.connexions = {}
55                for a in self.accounts:
56                        self.connected[a] = 0
57                self.myVCardID = []
58        # END __init__
59
60        def init_cfg_file(self):
61                """Initialize configuration file"""
62                fname = os.path.expanduser(CONFPATH)
63                reps = string.split(fname, '/')
64                del reps[0]
65                path = ''
66                while len(reps) > 1:
67                        path = path + '/' + reps[0]
68                        del reps[0]
69                        try:
70                                os.stat(os.path.expanduser(path))
71                        except OSError:
72                                try:
73                                        os.mkdir(os.path.expanduser(path))
74                                except:
75                                        print _("Can't create %s") % path
76                                        sys.exit
77                try:
78                        os.stat(fname)
79                except:
80                        print _("creating %s") % fname
81                        fic = open(fname, "w")
82                        fic.write("[Profile]\naccounts = \nlog = 0\n\n[Core]\ndelauth = 1\nalwaysauth = 0\nmodules = logger gtkgui\ndelroster = 1\n")
83                        fic.close()
84        # END init_cfg_file
85
86        def parse(self):
87                """Parse configuratoin file and create self.accounts"""
88                self.cfgParser.parseCfgFile()
89                self.accounts = {}
90                if self.cfgParser.tab.has_key('Profile'):
91                        if self.cfgParser.tab['Profile'].has_key('log'):
92                                self.log = self.cfgParser.tab['Profile']['log']
93                        if self.cfgParser.tab['Profile'].has_key('accounts'):
94                                accts = string.split(self.cfgParser.tab['Profile']['accounts'], ' ')
95                                if accts == ['']:
96                                        accts = []
97                                for a in accts:
98                                        self.accounts[a] = self.cfgParser.tab[a]
99
100        def vCardCB(self, con, vc):
101                """Called when we recieve a vCard
102                Parse the vCard and send it to plugins"""
103                vcard = {'jid': vc.getFrom().getBasic()}
104                if vc._getTag('vCard') == common.jabber.NS_VCARD:
105                        card = vc.getChildren()[0]
106                        for info in card.getChildren():
107                                if info.getChildren() == []:
108                                        vcard[info.getName()] = info.getData()
109                                else:
110                                        vcard[info.getName()] = {}
111                                        for c in info.getChildren():
112                                                 vcard[info.getName()][c.getName()] = c.getData()
113                        if vc.getID() in self.myVCardID:
114                                self.myVCardID.remove(vc.getID())
115                                self.hub.sendPlugin('MYVCARD', self.connexions[con], vcard)
116                        else:
117                                self.hub.sendPlugin('VCARD', self.connexions[con], vcard)
118
119        def messageCB(self, con, msg):
120                """Called when we recieve a message"""
121                self.hub.sendPlugin('MSG', self.connexions[con], \
122                        (str(msg.getFrom()), msg.getBody()))
123        # END messageCB
124
125        def presenceCB(self, con, prs):
126                """Called when we recieve a presence"""
127                who = str(prs.getFrom())
128                prio = prs.getPriority()
129                if not prio:
130                        prio = 0
131                type = prs.getType()
132                if type == None: type = 'available'
133                log.debug("PresenceCB : %s" % type)
134                if type == 'available':
135                        show = prs.getShow()
136                        if not show:
137                                show = 'online'
138                        self.hub.sendPlugin('NOTIFY', self.connexions[con], \
139                                (prs.getFrom().getBasic(), show, prs.getStatus(), \
140                                prs.getFrom().getResource(), prio))
141                elif type == 'unavailable':
142                        self.hub.sendPlugin('NOTIFY', self.connexions[con], \
143                                (prs.getFrom().getBasic(), 'offline', prs.getStatus(), \
144                                        prs.getFrom().getResource(), prio))
145                elif type == 'subscribe':
146                        log.debug("subscribe request from %s" % who)
147                        if self.cfgParser.Core['alwaysauth'] == 1 or \
148                                string.find(who, "@") <= 0:
149                                con.send(common.jabber.Presence(who, 'subscribed'))
150                                if string.find(who, "@") <= 0:
151                                        self.hub.sendPlugin('NOTIFY', self.connexions[con], \
152                                                (prs.getFrom().getBasic(), 'offline', 'offline', \
153                                                prs.getFrom().getResource(), prio))
154                        else:
155                                txt = prs.getStatus()
156                                if not txt:
157                                        txt = _("I would like to add you to my roster.")
158                                self.hub.sendPlugin('SUBSCRIBE', self.connexions[con], (who, 'txt'))
159                elif type == 'subscribed':
160                        jid = prs.getFrom()
161                        self.hub.sendPlugin('SUBSCRIBED', self.connexions[con],\
162                                (jid.getBasic(), jid.getNode(), jid.getResource()))
163                        self.hub.queueIn.put(('UPDUSER', self.connexions[con], \
164                                (jid.getBasic(), jid.getNode(), ['general'])))
165                        #BE CAREFUL : no con.updateRosterItem() in a callback
166                        log.debug("we are now subscribed to %s" % who)
167                elif type == 'unsubscribe':
168                        log.debug("unsubscribe request from %s" % who)
169                elif type == 'unsubscribed':
170                        log.debug("we are now unsubscribed to %s" % who)
171                        self.hub.sendPlugin('UNSUBSCRIBED', self.connexions[con], \
172                                prs.getFrom().getBasic())
173                elif type == 'error':
174                        errmsg = ''
175                        for child in prs._node.getChildren():
176                                if child.getName() == 'error':
177                                        errmsg = child.getData()
178                                        break
179                        self.hub.sendPlugin('NOTIFY', self.connexions[con], \
180                                (prs.getFrom().getBasic(), 'error', errmsg, \
181                                        prs.getFrom().getResource(), prio))
182        # END presenceCB
183
184        def disconnectedCB(self, con):
185                """Called when we are disconnected"""
186                log.debug("disconnectedCB")
187                if self.connexions.has_key(con):
188                        if self.connected[self.connexions[con]] == 1:
189                                self.connected[self.connexions[con]] = 0
190                        self.hub.sendPlugin('STATUS', self.connexions[con], 'offline')
191        # END disconenctedCB
192
193        def connect(self, account):
194                """Connect and authentificate to the Jabber server"""
195                hostname = self.cfgParser.tab[account]["hostname"]
196                name = self.cfgParser.tab[account]["name"]
197                password = self.cfgParser.tab[account]["password"]
198                ressource = self.cfgParser.tab[account]["ressource"]
199                if self.cfgParser.tab[account]["use_proxy"]:
200                        proxy = {"host":self.cfgParser.tab[account]["proxyhost"]}
201                        proxy["port"] = self.cfgParser.tab[account]["proxyport"]
202                else:
203                        proxy = None
204                if self.log:
205                        con = common.jabber.Client(host = hostname, debug = [], \
206                        log = sys.stderr, connection=common.xmlstream.TCP, port=5222, \
207                        proxy = proxy)
208                else:
209                        con = common.jabber.Client(host = hostname, debug = [], log = None, \
210                        connection=common.xmlstream.TCP, port=5222, proxy = proxy)
211                        #debug = [common.jabber.DBG_ALWAYS], log = sys.stderr, \
212                        #connection=common.xmlstream.TCP_SSL, port=5223, proxy = proxy)
213                try:
214                        con.connect()
215                except IOError, e:
216                        log.debug("Couldn't connect to %s %s" % (hostname, e))
217                        self.hub.sendPlugin('STATUS', account, 'offline')
218                        self.hub.sendPlugin('WARNING', None, _("Couldn't connect to %s") \
219                                % hostname)
220                        return 0
221                except common.xmlstream.socket.error, e:
222                        log.debug("Couldn't connect to %s %s" % (hostname, e))
223                        self.hub.sendPlugin('STATUS', account, 'offline')
224                        self.hub.sendPlugin('WARNING', None, _("Couldn't connect to %s : %s") \
225                                % (hostname, e))
226                        return 0
227                except common.xmlstream.error, e:
228                        log.debug("Couldn't connect to %s %s" % (hostname, e))
229                        self.hub.sendPlugin('STATUS', account, 'offline')
230                        self.hub.sendPlugin('WARNING', None, _("Couldn't connect to %s : %s") \
231                                % (hostname, e))
232                        return 0
233                else:
234                        log.debug("Connected to server")
235
236                        con.registerHandler('message', self.messageCB)
237                        con.registerHandler('presence', self.presenceCB)
238                        con.registerHandler('iq',self.vCardCB,'result')#common.jabber.NS_VCARD)
239                        con.setDisconnectHandler(self.disconnectedCB)
240                        #BUG in jabberpy library : if hostname is wrong : "boucle"
241                        if con.auth(name, password, ressource):
242                                self.connexions[con] = account
243                                con.requestRoster()
244                                roster = con.getRoster().getRaw()
245                                if not roster :
246                                        roster = {}
247                                self.hub.sendPlugin('ROSTER', account, roster)
248                                self.connected[account] = 1
249                                return con
250                        else:
251                                log.debug("Couldn't authentificate to %s" % hostname)
252                                self.hub.sendPlugin('STATUS', account, 'offline')
253                                self.hub.sendPlugin('WARNING', None, \
254                                        _("Authentification failed with %s, check your login and password") % hostname)
255                                return 0
256        # END connect
257
258        def mainLoop(self):
259                """Main Loop : Read the incomming queue to execute commands comming from
260                plugins and process Jabber"""
261                while 1:
262                        if not self.hub.queueIn.empty():
263                                ev = self.hub.queueIn.get()
264                                if ev[1] and (ev[1] in self.connexions.values()):
265                                        for con in self.connexions.keys():
266                                                if ev[1] == self.connexions[con]:
267                                                        break
268                                else:
269                                        con = None
270                                #('QUIT', account, ())
271                                if ev[0] == 'QUIT':
272                                        for con in self.connexions.keys():
273                                                if self.connected[self.connexions[con]] == 1:
274                                                        self.connected[self.connexions[con]] = 0
275                                                        con.disconnect()
276                                        self.hub.sendPlugin('QUIT', None, ())
277                                        return
278                                #('ASK_CONFIG', account, (who_ask, section, default_config))
279                                elif ev[0] == 'ASK_CONFIG':
280                                        if ev[2][1] == 'accounts':
281                                                self.hub.sendPlugin('CONFIG', None, (ev[2][0], self.accounts))
282                                        else:
283                                                if self.cfgParser.tab.has_key(ev[2][1]):
284                                                        config = self.cfgParser.__getattr__(ev[2][1])
285                                                        for item in ev[2][2].keys():
286                                                                if not config.has_key(item):
287                                                                        config[item] = ev[2][2][item]
288                                                        self.hub.sendPlugin('CONFIG', None, (ev[2][0], config))
289                                                else:
290                                                        self.cfgParser.tab[ev[2][1]] = ev[2][2]
291                                                        self.cfgParser.writeCfgFile()
292                                                        self.hub.sendPlugin('CONFIG', None, (ev[2][0], ev[2][2]))
293                                #('CONFIG', account, (section, config))
294                                elif ev[0] == 'CONFIG':
295                                        if ev[2][0] == 'accounts':
296                                                #Remove all old accounts
297                                                accts = string.split(self.cfgParser.tab\
298                                                        ['Profile']['accounts'], ' ')
299                                                if accts == ['']:
300                                                        accts = []
301                                                for a in accts:
302                                                        del self.cfgParser.tab[a]
303                                                #Write all new accounts
304                                                accts = ev[2][1].keys()
305                                                self.cfgParser.tab['Profile']['accounts'] = \
306                                                        string.join(accts)
307                                                for a in accts:
308                                                        self.cfgParser.tab[a] = ev[2][1][a]
309                                                        if not a in self.connected.keys():
310                                                                self.connected[a]= 0
311                                        else:
312                                                self.cfgParser.tab[ev[2][0]] = ev[2][1]
313                                        self.cfgParser.writeCfgFile()
314                                        #TODO: tell the changes to other plugins
315                                #('STATUS', account, (status, msg))
316                                elif ev[0] == 'STATUS':
317                                        if (ev[2][0] != 'offline') and (self.connected[ev[1]] == 0):
318                                                con = self.connect(ev[1])
319                                                if self.connected[ev[1]]:
320                                                        #send our presence
321                                                        type = 'available'
322                                                        if ev[2][0] == 'invisible':
323                                                                type = 'invisible'
324                                                        prio = 0
325                                                        if self.cfgParser.tab[ev[1]].has_key('priority'):
326                                                                prio = str(self.cfgParser.tab[ev[1]]['priority'])
327                                                        con.sendPresence(type, prio, ev[2][0], ev[2][1])
328                                                        self.hub.sendPlugin('STATUS', ev[1], ev[2][0])
329                                                        #ask our VCard
330                                                        iq = common.jabber.Iq(type="get")
331                                                        iq._setTag('vCard', common.jabber.NS_VCARD)
332                                                        id = con.getAnID()
333                                                        iq.setID(id)
334                                                        con.send(iq)
335                                                        self.myVCardID.append(id)
336                                        elif (ev[2][0] == 'offline') and (self.connected[ev[1]] == 1):
337                                                self.connected[ev[1]] = 0
338                                                con.disconnect()
339                                                self.hub.sendPlugin('STATUS', ev[1], 'offline')
340                                        elif ev[2][0] != 'offline' and self.connected[ev[1]] == 1:
341                                                type = 'available'
342                                                if ev[2][0] == 'invisible':
343                                                        type = 'invisible'
344                                                prio = 0
345                                                if self.cfgParser.tab[ev[1]].has_key('priority'):
346                                                        prio = str(self.cfgParser.tab[ev[1]]['priority'])
347                                                con.sendPresence(type, prio, ev[2][0], ev[2][1])
348                                                self.hub.sendPlugin('STATUS', ev[1], ev[2][0])
349                                #('MSG', account, (jid, msg))
350                                elif ev[0] == 'MSG':
351                                        msg = common.jabber.Message(ev[2][0], ev[2][1])
352                                        msg.setType('chat')
353                                        con.send(msg)
354                                        self.hub.sendPlugin('MSGSENT', ev[1], ev[2])
355                                #('SUB', account, (jid, txt))
356                                elif ev[0] == 'SUB':
357                                        log.debug('subscription request for %s' % ev[2][0])
358                                        pres = common.jabber.Presence(ev[2][0], 'subscribe')
359                                        if ev[2][1]:
360                                                pres.setStatus(ev[2][1])
361                                        else:
362                                                pres.setStatus(_("I would like to add you to my roster."))
363                                        con.send(pres)
364                                #('REQ', account, jid)
365                                elif ev[0] == 'AUTH':
366                                        con.send(common.jabber.Presence(ev[2], 'subscribed'))
367                                #('DENY', account, jid)
368                                elif ev[0] == 'DENY':
369                                        con.send(common.jabber.Presence(ev[2], 'unsubscribed'))
370                                #('UNSUB', account, jid)
371                                elif ev[0] == 'UNSUB':
372                                        delauth = 1
373                                        if self.cfgParser.Core.has_key('delauth'):
374                                                delauth = self.cfgParser.Core['delauth']
375                                        delroster = 1
376                                        if self.cfgParser.Core.has_key('delroster'):
377                                                delroster = self.cfgParser.Core['delroster']
378                                        if delauth:
379                                                con.send(common.jabber.Presence(ev[2], 'unsubscribe'))
380                                        if delroster:
381                                                con.removeRosterItem(ev[2])
382                                #('UNSUB_AGENT', account, agent)
383                                elif ev[0] == 'UNSUB_AGENT':
384                                        con.removeRosterItem(ev[2])
385                                        con.requestRegInfo(ev[2])
386                                        agent_info = con.getRegInfo()
387                                        key = agent_info['key']
388                                        iq = common.jabber.Iq(to=ev[2], type="set")
389                                        q = iq.setQuery(common.jabber.NS_REGISTER)
390                                        q.insertTag('remove')
391                                        q.insertTag('key').insertData(key)
392                                        id = con.getAnID()
393                                        iq.setID(id)
394                                        con.send(iq)
395                                        self.hub.sendPlugin('AGENT_REMOVED', ev[1], ev[2])
396                                #('UPDUSER', account, (jid, name, groups))
397                                elif ev[0] == 'UPDUSER':
398                                        con.updateRosterItem(jid=ev[2][0], name=ev[2][1], \
399                                                groups=ev[2][2])
400                                #('REQ_AGENTS', account, ())
401                                elif ev[0] == 'REQ_AGENTS':
402                                        agents = con.requestAgents()
403                                        self.hub.sendPlugin('AGENTS', ev[1], agents)
404                                #('REQ_AGENT_INFO', account, agent)
405                                elif ev[0] == 'REQ_AGENT_INFO':
406                                        con.requestRegInfo(ev[2])
407                                        agent_info = con.getRegInfo()
408                                        self.hub.sendPlugin('AGENT_INFO', ev[1], (ev[2], agent_info))
409                                #('REG_AGENT', account, infos)
410                                elif ev[0] == 'REG_AGENT':
411                                        con.sendRegInfo(ev[2])
412                                #('NEW_ACC', (hostname, login, password, name, ressource, prio, \
413                                # use_proxy, proxyhost, proxyport))
414                                elif ev[0] == 'NEW_ACC':
415                                        if ev[2][6]:
416                                                proxy = {'host': ev[2][7], 'port': ev[2][8]}
417                                        else:
418                                                proxy = None
419                                        c = common.jabber.Client(host = ev[2][0], debug = [], \
420                                                log = None, proxy = proxy)
421                                        try:
422                                                c.connect()
423                                        except IOError, e:
424                                                log.debug("Couldn't connect to %s %s" % (hostname, e))
425                                                return 0
426                                        else:
427                                                log.debug("Connected to server")
428                                                c.requestRegInfo()
429                                                req = c.getRegInfo()
430                                                c.setRegInfo( 'username', ev[2][1])
431                                                c.setRegInfo( 'password', ev[2][2])
432                                                #FIXME: if users already exist, no error message :(
433                                                if not c.sendRegInfo():
434                                                        print "error " + c.lastErr
435                                                else:
436                                                        self.hub.sendPlugin('ACC_OK', ev[1], ev[2])
437                                #('ACC_CHG', old_account, new_account)
438                                elif ev[0] == 'ACC_CHG':
439                                        self.connected[ev[2]] = self.connected[ev[1]]
440                                        del self.connected[ev[1]]
441                                        if con:
442                                                self.connexions[con] = self.connected[ev[2]]
443                                #('ASK_VCARD', account, jid)
444                                elif ev[0] == 'ASK_VCARD':
445                                        iq = common.jabber.Iq(to=ev[2], type="get")
446                                        iq._setTag('vCard', common.jabber.NS_VCARD)
447                                        iq.setID(con.getAnID())
448                                        con.send(iq)
449                                #('VCARD', {entry1: data, entry2: {entry21: data, ...}, ...})
450                                elif ev[0] == 'VCARD':
451                                        iq = common.jabber.Iq(type="set")
452                                        iq.setID(con.getAnID())
453                                        iq2 = iq._setTag('vCard', common.jabber.NS_VCARD)
454                                        for i in ev[2].keys():
455                                                if i != 'jid':
456                                                        if type(ev[2][i]) == type({}):
457                                                                iq3 = iq2.insertTag(i)
458                                                                for j in ev[2][i].keys():
459                                                                        iq3.insertTag(j).putData(ev[2][i][j])
460                                                        else:
461                                                                iq2.insertTag(i).putData(ev[2][i])
462                                        con.send(iq)
463                                #('AGENT_LOGGING', account, (agent, type))
464                                elif ev[0] == 'AGENT_LOGGING':
465                                        t = ev[2][1];
466                                        if not t:
467                                                t='available';
468                                        p = common.jabber.Presence(to=ev[2][0], type=t)
469                                        con.send(p)
470</