From 64d9f44833ce199fb463e205add95ce7a8fcc5ce Mon Sep 17 00:00:00 2001 From: "louiz@4325f9fc-e183-4c21-96ce-0ab188b42d13" Date: Sun, 14 Feb 2010 03:51:03 +0000 Subject: fixed #1138 #1111 --- src/client.py | 4 +- src/common.py | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/connection.py | 14 ++++-- src/gui.py | 8 +-- src/handler.py | 10 ++-- src/multiuserchat.py | 47 ++++++++++++++++- 6 files changed, 208 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/client.py b/src/client.py index d3561a86..9840d259 100644 --- a/src/client.py +++ b/src/client.py @@ -20,8 +20,8 @@ import sys # disable any printout (this would mess the display) stderr = sys.stderr -# sys.stdout = open('/dev/null', 'w') -# sys.stderr = open('/dev/null', 'w') +sys.stdout = open('/dev/null', 'w') +sys.stderr = open('/dev/null', 'w') from connection import Connection from multiuserchat import MultiUserChat diff --git a/src/common.py b/src/common.py index 015f1cec..e4026efb 100644 --- a/src/common.py +++ b/src/common.py @@ -1,5 +1,21 @@ # -*- coding: utf-8 -*- +# some functions coming from gajim sources (thanks) + +## Copyright (C) 2003-2008 Yann Leboulanger +## Copyright (C) 2005-2006 Dimitur Kirov +## Nikos Kouremenos +## Copyright (C) 2006 Alex Mauer +## Copyright (C) 2006-2007 Travis Shirk +## Copyright (C) 2006-2008 Jean-Marie Traissard +## Copyright (C) 2007 Lukas Petrovicky +## James Newton +## Julien Pivotto +## Copyright (C) 2007-2008 Stephan Erb +## Copyright (C) 2008 Brendan Taylor +## Jonathan Schleifer +## + # Copyright 2010, Florent Le Coz # This program is free software: you can redistribute it and/or modify @@ -20,6 +36,7 @@ import base64 import os import mimetypes import hashlib +import subprocess def get_base64_from_file(path): if not os.path.isfile(path): @@ -33,3 +50,126 @@ def get_base64_from_file(path): sha1 = hashlib.sha1(data).hexdigest() mime_type = mimetypes.guess_type(path)[0] return (encoded, mime_type, sha1) + +def get_output_of_command(command): + try: + child_stdin, child_stdout = os.popen2(command) + except ValueError: + return None + + output = child_stdout.readlines() + child_stdout.close() + child_stdin.close() + + return output + +def is_in_path(command, return_abs_path=False): + """ + Return True if 'command' is found in one of the directories in the user's + path. If 'return_abs_path' is True, return the absolute path of the first + found command instead. Return False otherwise and on errors + """ + for directory in os.getenv('PATH').split(os.pathsep): + try: + if command in os.listdir(directory): + if return_abs_path: + return os.path.join(directory, command) + else: + return True + except OSError: + # If the user has non directories in his path + pass + return False + +distro_info = { + 'Arch Linux': '/etc/arch-release', + 'Aurox Linux': '/etc/aurox-release', + 'Conectiva Linux': '/etc/conectiva-release', + 'CRUX': '/usr/bin/crux', + 'Debian GNU/Linux': '/etc/debian_release', + 'Debian GNU/Linux': '/etc/debian_version', + 'Fedora Linux': '/etc/fedora-release', + 'Gentoo Linux': '/etc/gentoo-release', + 'Linux from Scratch': '/etc/lfs-release', + 'Mandrake Linux': '/etc/mandrake-release', + 'Slackware Linux': '/etc/slackware-release', + 'Slackware Linux': '/etc/slackware-version', + 'Solaris/Sparc': '/etc/release', + 'Source Mage': '/etc/sourcemage_version', + 'SUSE Linux': '/etc/SuSE-release', + 'Sun JDS': '/etc/sun-release', + 'PLD Linux': '/etc/pld-release', + 'Yellow Dog Linux': '/etc/yellowdog-release', + # many distros use the /etc/redhat-release for compatibility + # so Redhat is the last + 'Redhat Linux': '/etc/redhat-release' +} +def get_os_info(): + if os.name == 'nt': # could not happen, but... + ver = sys.getwindowsversion() + ver_format = ver[3], ver[0], ver[1] + win_version = { + (1, 4, 0): '95', + (1, 4, 10): '98', + (1, 4, 90): 'ME', + (2, 4, 0): 'NT', + (2, 5, 0): '2000', + (2, 5, 1): 'XP', + (2, 5, 2): '2003', + (2, 6, 0): 'Vista', + (2, 6, 1): '7', + } + if ver_format in win_version: + os_info = 'Windows' + ' ' + win_version[ver_format] + else: + os_info = 'Windows' + return os_info + elif os.name == 'posix': + executable = 'lsb_release' + params = ' --description --codename --release --short' + full_path_to_executable = is_in_path(executable, return_abs_path = True) + if full_path_to_executable: + command = executable + params + p = subprocess.Popen([command], shell=True, stdin=subprocess.PIPE, + stdout=subprocess.PIPE, close_fds=True) + p.wait() + output = temp_failure_retry(p.stdout.readline).strip() + # some distros put n/a in places, so remove those + output = output.replace('n/a', '').replace('N/A', '') + return output + + # lsb_release executable not available, so parse files + for distro_name in distro_info: + path_to_file = distro_info[distro_name] + if os.path.exists(path_to_file): + if os.access(path_to_file, os.X_OK): + # the file is executable (f.e. CRUX) + # yes, then run it and get the first line of output. + text = get_output_of_command(path_to_file)[0] + else: + fd = open(path_to_file) + text = fd.readline().strip() # get only first line + fd.close() + if path_to_file.endswith('version'): + # sourcemage_version and slackware-version files + # have all the info we need (name and version of distro) + if not os.path.basename(path_to_file).startswith( + 'sourcemage') or not\ + os.path.basename(path_to_file).startswith('slackware'): + text = distro_name + ' ' + text + elif path_to_file.endswith('aurox-release') or \ + path_to_file.endswith('arch-release'): + # file doesn't have version + text = distro_name + elif path_to_file.endswith('lfs-release'): # file just has version + text = distro_name + ' ' + text + os_info = text.replace('\n', '') + return os_info + + # our last chance, ask uname and strip it + uname_output = get_output_of_command('uname -sr') + if uname_output is not None: + os_info = uname_output[0] # only first line + return os_info + os_info = 'N/A' + return os_info diff --git a/src/connection.py b/src/connection.py index 2dec8f35..0e26f008 100644 --- a/src/connection.py +++ b/src/connection.py @@ -75,8 +75,8 @@ class Connection(threading.Thread): """ self.client.RegisterHandler('message', self.handler_message) self.client.RegisterHandler('presence', self.handler_presence) - self.client.RegisterHandler('iq', self.handler_iq) - self.client.RegisterHandler('error', self.handler_error) + self.client.RegisterHandler('iq', self.on_get_time, typ='get', ns="urn:xmpp:time") + self.client.RegisterHandler('iq', self.on_get_version, typ='get', ns=xmpp.NS_VERSION) def handler_presence(self, connection, presence): fro = presence.getFrom() @@ -91,9 +91,6 @@ class Connection(threading.Thread): def handler_message(self, connection, message): self.handler.emit('room-message', stanza=message) - def handler_iq(self, connection, iq): - self.handler.emit('room-iq', stanza=iq) - def handler_error(self, connection, error): pass @@ -106,3 +103,10 @@ class Connection(threading.Thread): else: log.warning('disconnecting...') sys.exit() + + def on_get_version(self, connection, iq): + self.handler.emit('send-version', iq_obj=iq) + + def on_get_time(self, connection, iq): + open('caca', 'w').write('works') + self.handler.emit('send-time', iq_obj=iq) diff --git a/src/gui.py b/src/gui.py index e2323c0a..625b59c0 100644 --- a/src/gui.py +++ b/src/gui.py @@ -232,7 +232,7 @@ class Gui(object): self.handler.connect('join-room', self.join_room) self.handler.connect('room-presence', self.room_presence) self.handler.connect('room-message', self.room_message) - self.handler.connect('room-iq', self.room_iq) + # self.handler.connect('room-iq', self.room_iq) def main_loop(self, stdscr): while 1: @@ -393,9 +393,9 @@ class Gui(object): self.window.text_win.refresh() curses.doupdate() - def room_iq(self, iq): - if len(sys.argv) > 1: - self.information(str(iq)) + # def room_iq(self, iq): + # if len(sys.argv) > 1: + # self.information(str(iq)) def execute(self): line = self.window.input.get_text() diff --git a/src/handler.py b/src/handler.py index 681af6d7..4fa6cca8 100644 --- a/src/handler.py +++ b/src/handler.py @@ -46,9 +46,13 @@ class Handler(Singleton): # A message is received # Args: the stanza object - 'room-iq': list(), - # An iq is received - # Args: the stanza object + 'send-version': list(), + # We send our version + # Args: the stanza we reply to + + 'send-time': list() + # We send our time + # Args: the stanza we reply to } def connect(self, signal, func): diff --git a/src/multiuserchat.py b/src/multiuserchat.py index 8c948513..95ffe9b1 100644 --- a/src/multiuserchat.py +++ b/src/multiuserchat.py @@ -23,6 +23,9 @@ import xmpp import common import threading +from time import (altzone, daylight, gmtime, localtime, mktime, strftime, + time as time_time, timezone, tzname) + from handler import Handler from config import config @@ -69,7 +72,12 @@ class VcardSender(threading.Thread): if not self.connection: return vcard = { - "FN":"Poezio tester", + "FN":config.get('full_name', ''), + "URL":config.get('website', ''), + "EMAIL":{ + "USERID":config.get('email', '') + }, + "DESC":config.get('comment', 'A proud Poezio user') } photo_file_path = config.get('photo', '../data/poezio_80.png') (image, mime_type, sha1) = common.get_base64_from_file(photo_file_path) @@ -112,6 +120,8 @@ class MultiUserChat(object): self.handler = Handler() self.handler.connect('join-room', self.join_room) self.handler.connect('on-connected', self.on_connected) + self.handler.connect('send-version', self.send_version) + self.handler.connect('send-time', self.send_time) def on_connected(self, jid): self.own_jid = jid @@ -275,3 +285,38 @@ class MultiUserChat(object): if status: pres.setStatus(status) self.connection.send(pres) + + def send_version(self, iq_obj): + """ + from gajim and modified + """ + iq_obj = iq_obj.buildReply('result') + qp = iq_obj.getTag('query') + if config.get('send_poezio_info', 'true') == 'true': + qp.setTagData('name', 'Poezio') + qp.setTagData('version', '0.6 trunk') + else: + qp.setTagData('name', 'Unknown') + qp.setTagData('version', 'Unknown') + if config.get('send_os_info', 'true') == 'true': + qp.setTagData('os', common.get_os_info()) + else: + qp.setTagData('os', 'Unknown') + self.connection.send(iq_obj) + raise xmpp.protocol.NodeProcessed + + def send_time(self, iq_obj): + """ + from gajim + """ + iq_obj = iq_obj.buildReply('result') + qp = iq_obj.setTag('time', + namespace="urn:xmpp:time") + if config.get('send_time', 'true') == 'true': + qp.setTagData('utc', strftime('%Y-%m-%dT%H:%M:%SZ', gmtime())) + isdst = localtime().tm_isdst + zone = -(timezone, altzone)[isdst] / 60 + tzo = (zone / 60, abs(zone % 60)) + qp.setTagData('tzo', '%+03d:%02d' % (tzo)) + self.connection.send(iq_obj) + raise common.xmpp.NodeProcessed -- cgit v1.2.3