summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/default_config.cfg38
-rw-r--r--src/client.py4
-rw-r--r--src/common.py140
-rw-r--r--src/connection.py14
-rw-r--r--src/gui.py8
-rw-r--r--src/handler.py10
-rw-r--r--src/multiuserchat.py47
7 files changed, 244 insertions, 17 deletions
diff --git a/data/default_config.cfg b/data/default_config.cfg
index 8f6123d2..d4fe45a0 100644
--- a/data/default_config.cfg
+++ b/data/default_config.cfg
@@ -25,8 +25,8 @@ completion = normal
# a SPACE will always be added after that
after_completion = ,
-# a list of words (separated by a semicolon (:)) that will be highlighted if said by
-# someone on a room
+# a list of words (separated by a semicolon (:)) that will be
+# highlighted if said by someone on a room
highlight_on =
# if true, no join or quit message will be displayed in the rooms
@@ -35,5 +35,39 @@ hide_enter_join = False
# if true, no status change will be displayed in the rooms
hide_status_change = False
+# the full path to the photo (avatar) you want to use
+# it should be less than 16Ko
+photo = ../data/poezio_80.png
+
+
+# if true, information about the software (name and version)
+# Set to false if you don't want people to know that information
+send_poezio_info = true
+
+# if true, information about the Operation System you're using
+# will be sent when asked.
+# Set to false if you don't want people to know that information
+send_os_info = true
+
+# if true, your current time will be sent if asked
+# Set to false if you don't want people to know that information
+send_time = true
+
# the file where logs are saved (useless for the moment)
logfile = logs
+
+# Vcard
+# here are personal informations that you can set in your Vcard
+# Obviously, everything is optionnal.
+
+# your real full name
+full_name =
+
+# your personnal website
+website = http://codingteam.net/project/poezio
+
+# your e-mail address
+email =
+
+# anything you want to say about you
+comment = I am using Poezio, it's a cool Jabber client. Check it out at http://codingteam.net/project/poezio. \ No newline at end of file
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 <asterix AT lagaule.org>
+## Copyright (C) 2005-2006 Dimitur Kirov <dkirov AT gmail.com>
+## Nikos Kouremenos <kourem AT gmail.com>
+## Copyright (C) 2006 Alex Mauer <hawke AT hawkesnest.net>
+## Copyright (C) 2006-2007 Travis Shirk <travis AT pobox.com>
+## Copyright (C) 2006-2008 Jean-Marie Traissard <jim AT lapin.org>
+## Copyright (C) 2007 Lukas Petrovicky <lukas AT petrovicky.net>
+## James Newton <redshodan AT gmail.com>
+## Julien Pivotto <roidelapluie AT gmail.com>
+## Copyright (C) 2007-2008 Stephan Erb <steve-e AT h3c.de>
+## Copyright (C) 2008 Brendan Taylor <whateley AT gmail.com>
+## Jonathan Schleifer <js-gajim AT webkeks.org>
+##
+
# Copyright 2010, Florent Le Coz <louizatakk@fedoraproject.org>
# 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