Commit 175a792c authored by Liorithiel's avatar Liorithiel

Merging changes from trunk (6774:7465)

parent 755964c3
# Set the C flags to include the GTK+ and Python libraries
PYTHON ?= python
PYTHONVER = `$(PYTHON) -c 'import sys; print sys.version[:3]'`
gtk_CFLAGS = `pkg-config --cflags gtk+-2.0 pygtk-2.0` -fPIC -I/usr/include/python$(PYTHONVER) -I.
gtk_LDFLAGS = `pkg-config --libs gtk+-2.0 pygtk-2.0` -lpython$(PYTHONVER)
all: trayicon.so gtkspell.so
# Build the shared objects
trayicon.so: trayicon.o eggtrayicon.o trayiconmodule.o
$(CC) -shared $^ -o $@ $(LDFLAGS) $(gtk_LDFLAGS)
gtkspell.so:
$(CC) $(OPTFLAGS) $(CFLAGS) $(LDFLAGS) $(gtk_CFLAGS) $(gtk_LDFLAGS) `pkg-config --libs --cflags gtkspell-2.0` -shared gtkspellmodule.c $^ -o $@
# The path to the GTK+ python types
DEFS=`pkg-config --variable=defsdir pygtk-2.0`
%.o: %.c
$(CC) -o $@ -c $< $(CFLAGS) $(gtk_CFLAGS)
# Generate the C wrapper from the defs and our override file
trayicon.c: trayicon.defs trayicon.override
pygtk-codegen-2.0 --prefix trayicon \
--register $(DEFS)/gdk-types.defs \
--register $(DEFS)/gtk-types.defs \
--override trayicon.override \
trayicon.defs > $@
# A rule to clean the generated files
clean:
rm -f trayicon.so *.o trayicon.c gtkspell.so *~
.PHONY: clean
SUBDIRS = common
CLEANFILES = \
trayicon.c
INCLUDES = \
$(PYTHON_INCLUDES)
if BUILD_GTKSPELL
gtkspelllib_LTLIBRARIES = gtkspell.la
gtkspelllibdir = $(libdir)/gajim
gtkspell_la_LIBADD = \
$(GTKSPELL_LIBS) $(PYGTK_LIBS)
gtkspell_la_SOURCES = \
gtkspellmodule.c
gtkspell_la_LDFLAGS = \
-module -avoid-version
gtkspell_la_CFLAGS = $(GTKSPELL_CFLAGS) $(PYGTK_CFLAGS)
endif
if BUILD_TRAYICON
trayiconlib_LTLIBRARIES = trayicon.la
trayiconlibdir = $(libdir)/gajim
trayicon_la_LIBADD = $(PYGTK_LIBS)
trayicon_la_SOURCES = \
eggtrayicon.c \
trayiconmodule.c
nodist_trayicon_la_SOURCES = \
trayicon.c
trayicon_la_LDFLAGS = \
-module -avoid-version
trayicon_la_CFLAGS = $(PYGTK_CFLAGS)
trayicon.c:
pygtk-codegen-2.0 --prefix trayicon \
--register $(PYGTK_DEFS)/gdk-types.defs \
--register $(PYGTK_DEFS)/gtk-types.defs \
--override $(srcdir)/trayicon.override \
$(srcdir)/trayicon.defs > $@
endif
gajimsrcdir = $(pkgdatadir)/src
gajimsrc_DATA = $(srcdir)/*.py
gajimsrc1dir = $(pkgdatadir)/src/common
gajimsrc1_DATA = \
$(srcdir)/common/*.py
gajimsrc2dir = $(pkgdatadir)/src/common/xmpp
gajimsrc2_DATA = \
$(srcdir)/common/xmpp/*.py
gajimsrc3dir = $(pkgdatadir)/src/common/zeroconf
gajimsrc3_DATA = \
$(srcdir)/common/zeroconf/*.py
DISTCLEANFILES =
EXTRA_DIST = $(gajimsrc_DATA) \
$(gajimsrc1_DATA) \
$(gajimsrc2_DATA) \
$(gajimsrc3_DATA) \
gtkspellmodule.c \
eggtrayicon.c \
trayiconmodule.c \
eggtrayicon.h \
trayicon.defs \
trayicon.override
MAINTAINERCLEANFILES = Makefile.in
## advanced.py
##
## Contributors for this file:
## - Yann Le Boulanger <asterix@lagaule.org>
## - Nikos Kouremenos <kourem@gmail.com>
## - Vincent Hanquez <tab@snarc.org>
##
## Copyright (C) 2003-2004 Yann Le Boulanger <asterix@lagaule.org>
## Vincent Hanquez <tab@snarc.org>
## Copyright (C) 2005 Yann Le Boulanger <asterix@lagaule.org>
## Vincent Hanquez <tab@snarc.org>
## Nikos Kouremenos <nkour@jabber.org>
## Dimitur Kirov <dkirov@gmail.com>
## Travis Shirk <travis@pobox.com>
## Norman Rasmussen <norman@rasmussen.co.za>
## Copyright (C) 2005-2006 Yann Le Boulanger <asterix@lagaule.org>
## Copyright (C) 2005-2006 Nikos Kouremenos <kourem@gmail.com>
## Copyright (C) 2005 Vincent Hanquez <tab@snarc.org>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published
......@@ -42,7 +32,7 @@ C_TYPE
GTKGUI_GLADE = 'manage_accounts_window.glade'
class AdvancedConfigurationWindow:
class AdvancedConfigurationWindow(object):
def __init__(self):
self.xml = gtkgui_helpers.get_glade('advanced_configuration_window.glade')
self.window = self.xml.get_widget('advanced_configuration_window')
......
......@@ -8,7 +8,7 @@
## Vincent Hanquez <tab@snarc.org>
## Copyright (C) 2005 Yann Le Boulanger <asterix@lagaule.org>
## Vincent Hanquez <tab@snarc.org>
## Nikos Kouremenos <nkour@jabber.org>
## Nikos Kouremenos <kourem@gmail.com>
## Dimitur Kirov <dkirov@gmail.com>
## Travis Shirk <travis@pobox.com>
## Norman Rasmussen <norman@rasmussen.co.za>
......
This diff is collapsed.
......@@ -2,13 +2,13 @@
##
## Contributors for this file:
## - Yann Le Boulanger <asterix@lagaule.org>
## - Nikos Kouremenos <nkour@jabber.org>
## - Nikos Kouremenos <kourem@gmail.com>
##
## Copyright (C) 2003-2004 Yann Le Boulanger <asterix@lagaule.org>
## Vincent Hanquez <tab@snarc.org>
## Copyright (C) 2005 Yann Le Boulanger <asterix@lagaule.org>
## Vincent Hanquez <tab@snarc.org>
## Nikos Kouremenos <nkour@jabber.org>
## Nikos Kouremenos <kourem@gmail.com>
## Dimitur Kirov <dkirov@gmail.com>
## Travis Shirk <travis@pobox.com>
## Norman Rasmussen <norman@rasmussen.co.za>
......
# Set the C flags to include the GTK+ and Python libraries
PYTHON ?= python
PYTHONVER = `$(PYTHON) -c 'import sys; print sys.version[:3]'`
HAVE_XSCRNSAVER = $(shell pkg-config --exists xscrnsaver && echo 'YES')
ifeq ($(HAVE_XSCRNSAVER),YES)
# We link with libXScrnsaver from modular X.Org X11
gtk_and_x_CFLAGS = `pkg-config --cflags gtk+-2.0 pygtk-2.0 xscrnsaver` -fpic -I/usr/include/python$(PYTHONVER) -I.
gtk_and_x_LDFLAGS = `pkg-config --libs gtk+-2.0 pygtk-2.0 xscrnsaver` -lpython$(PYTHONVER)
else
# # We link with libXScrnsaver from monolithic X.Org X11
gtk_and_x_CFLAGS = `pkg-config --cflags gtk+-2.0 pygtk-2.0` -fpic -I/usr/include/python$(PYTHONVER) -I.
gtk_and_x_LDFLAGS = `pkg-config --libs gtk+-2.0 pygtk-2.0` \
-L/usr/X11R6$(LIBDIR) -lX11 -lXss -lXext -lpython$(PYTHONVER)
endif
all: idle.so
idle.so:
$(CC) $(OPTFLAGS) $(CFLAGS) $(LDFLAGS) $(gtk_and_x_CFLAGS) $(gtk_and_x_LDFLAGS) -shared idle.c $^ -o $@
clean:
rm -f *.so
rm -rf build
INCLUDES = \
$(PYTHON_INCLUDES)
if BUILD_IDLE
idlelib_LTLIBRARIES = idle.la
idlelibdir = $(libdir)/gajim
idle_la_LIBADD = $(XSCRNSAVER_LIBS)
idle_la_SOURCES = idle.c
idle_la_LDFLAGS = \
-module -avoid-version
idle_la_CFLAGS = $(XSCRNSAVER_CFLAGS) $(PYTHON_INCLUDES)
endif
DISTCLEANFILES =
EXTRA_DIST =
MAINTAINERCLEANFILES = Makefile.in
## Contributors for this file:
## - Yann Le Boulanger <asterix@lagaule.org>
## - Nikos Kouremenos <kourem@gmail.com>
## - Travis Shirk <travis@pobox.com>
##
## Copyright (C) 2003-2004 Yann Le Boulanger <asterix@lagaule.org>
## Vincent Hanquez <tab@snarc.org>
## Copyright (C) 2005 Yann Le Boulanger <asterix@lagaule.org>
## Vincent Hanquez <tab@snarc.org>
## Nikos Kouremenos <nkour@jabber.org>
## Dimitur Kirov <dkirov@gmail.com>
## Travis Shirk <travis@pobox.com>
## Norman Rasmussen <norman@rasmussen.co.za>
## Copyright (C) 2005-2006 Yann Le Boulanger <asterix@lagaule.org>
## Copyright (C) 2005-2006 Nikos Kouremenos <kourem@gmail.com>
## Copyright (C) 2005-2006 Travis Shirk <travis@pobox.com>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published
......@@ -29,7 +20,14 @@ import stat
from common import gajim
import logger
from pysqlite2 import dbapi2 as sqlite # DO NOT MOVE ABOVE OF import gajim
# DO NOT MOVE ABOVE OF import gajim
try:
import sqlite3 as sqlite # python 2.5
except ImportError:
try:
from pysqlite2 import dbapi2 as sqlite
except ImportError:
raise exceptions.PysqliteNotAvailable
def create_log_db():
print _('creating logs database')
......@@ -57,11 +55,13 @@ def create_log_db():
jid_id INTEGER
);
CREATE INDEX idx_unread_messages_jid_id ON unread_messages (jid_id);
CREATE TABLE transports_cache (
transport TEXT UNIQUE,
type INTEGER
);
CREATE TABLE logs(
log_line_id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
jid_id INTEGER,
......@@ -72,6 +72,8 @@ def create_log_db():
message TEXT,
subject TEXT
);
CREATE INDEX idx_logs_jid_id_kind ON logs (jid_id, kind);
'''
)
......
This diff is collapsed.
import os
import sys
import tempfile
# Note on path and filename encodings:
#
# In general it is very difficult to do this correctly.
# We may pull information from environment variables, and what encoding that is
# in is anyone's guess. Any information we request directly from the file
# system will be in filesystemencoding, and (parts of) paths that we write in
# this source code will be in whatever encoding the source is in. (I hereby
# declare this file to be UTF-8 encoded.)
#
# To make things more complicated, modern Windows filesystems use UTF-16, but
# the API tends to hide this from us.
#
# I tried to minimize problems by passing Unicode strings to OS functions as
# much as possible. Hopefully this makes the function return an Unicode string
# as well. If not, we get an 8-bit string in filesystemencoding, which we can
# happily pass to functions that operate on files and directories, so we can
# just leave it as is. Since these paths are meant to be internal to Gajim and
# not displayed to the user, Unicode is not really necessary here.
def fse(s):
'''Convert from filesystem encoding if not already Unicode'''
return unicode(s, sys.getfilesystemencoding())
class ConfigPaths:
def __init__(this, root=None):
this.root = root
this.paths = {}
if this.root is None:
if os.name == 'nt':
try:
# Documents and Settings\[User Name]\Application Data\Gajim
# How are we supposed to know what encoding the environment
# variable 'appdata' is in? Assuming it to be in filesystem
# encoding.
this.root = os.path.join(fse(os.environ[u'appdata']), u'Gajim')
except KeyError:
# win9x, in cwd
this.root = u''
else: # Unices
# Pass in an Unicode string, and hopefully get one back.
this.root = os.path.expanduser(u'~/.gajim')
def add_from_root(this, name, path):
this.paths[name] = (True, path)
def add(this, name, path):
this.paths[name] = (False, path)
def __getitem__(this, key):
relative, path = this.paths[key]
if not relative:
return path
return os.path.join(this.root, path)
def get(this, key, default=None):
try:
return this[key]
except KeyError:
return default
def iteritems(this):
for key in this.paths.iterkeys():
yield (key, this[key])
def windowsify(s):
if os.name == 'nt':
return s.capitalize()
return s
def init():
paths = ConfigPaths()
# LOG is deprecated
k = ( 'LOG', 'LOG_DB', 'VCARD', 'AVATAR', 'MY_EMOTS' )
v = (u'logs', u'logs.db', u'vcards', u'avatars', u'emoticons')
if os.name == 'nt':
v = map(lambda x: x.capitalize(), v)
for n, p in zip(k, v):
paths.add_from_root(n, p)
paths.add('DATA', os.path.join(u'..', windowsify(u'data')))
paths.add('HOME', os.path.expanduser(u'~'))
paths.add('TMP', fse(tempfile.gettempdir()))
try:
import svn_config
svn_config.configure(paths)
except (ImportError, AttributeError):
pass
#for k, v in paths.iteritems():
# print "%s: %s" % (k, v)
return paths
gajimpaths = init()
def init_profile(profile, paths=gajimpaths):
conffile = windowsify(u'config')
pidfile = windowsify(u'gajim')
if len(profile) > 0:
conffile += u'.' + profile
pidfile += u'.' + profile
pidfile += u'.pid'
paths.add_from_root('CONFIG_FILE', conffile)
paths.add_from_root('PID_FILE', pidfile)
This diff is collapsed.
This diff is collapsed.
## common/contacts.py
##
## Contributors for this file:
## - Yann Le Boulanger <asterix@lagaule.org>
## Copyright (C) 2006 Yann Le Boulanger <asterix@lagaule.org>
## Copyright (C) 2006 Nikos Kouremenos <kourem@gmail.com>
##
## Copyright (C) 2003-2004 Yann Le Boulanger <asterix@lagaule.org>
## Vincent Hanquez <tab@snarc.org>
## Copyright (C) 2005 Yann Le Boulanger <asterix@lagaule.org>
## Vincent Hanquez <tab@snarc.org>
## Nikos Kouremenos <nkour@jabber.org>
## Dimitur Kirov <dkirov@gmail.com>
## Travis Shirk <travis@pobox.com>
## Norman Rasmussen <norman@rasmussen.co.za>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published
......@@ -27,8 +19,8 @@ import common.gajim
class Contact:
'''Information concerning each contact'''
def __init__(self, jid='', name='', groups=[], show='', status='', sub='',
ask='', resource='', priority=0, keyID='', our_chatstate=None,
chatstate=None, last_status_time=None, msg_id = None, composing_jep = None):
ask='', resource='', priority=0, keyID='', our_chatstate=None,
chatstate=None, last_status_time=None, msg_id = None, composing_jep = None):
self.jid = jid
self.name = name
self.groups = groups
......@@ -67,10 +59,40 @@ class Contact:
return self.name
return self.jid.split('@')[0]
def is_hidden_from_roster(self):
'''if contact should not be visible in roster'''
# XEP-0162: http://www.xmpp.org/extensions/xep-0162.html
if self.is_transport():
return False
if self.sub in ('both', 'to'):
return False
if self.sub in ('none', 'from') and self.ask == 'subscribe':
return False
if self.sub in ('none', 'from') and (self.name or len(self.groups)):
return False
if _('Not in Roster') in self.groups:
return False
return True
def is_observer(self):
# XEP-0162: http://www.xmpp.org/extensions/xep-0162.html
is_observer = False
if self.sub == 'from' and not self.is_transport()\
and self.is_hidden_from_roster():
is_observer = True
return is_observer
def is_transport(self):
# if not '@' or '@' starts the jid then contact is transport
if self.jid.find('@') <= 0:
return True
return False
class GC_Contact:
'''Information concerning each groupchat contact'''
def __init__(self, room_jid='', name='', show='', status='', role='',
affiliation='', jid = '', resource = ''):
affiliation='', jid = '', resource = ''):
self.room_jid = room_jid
self.name = name
self.show = show
......@@ -220,6 +242,51 @@ class Contacts:
return self._contacts[account][jid][0]
return None
def get_contacts_from_group(self, account, group):
'''Returns all contacts in the given group'''
group_contacts = []
for jid in self._contacts[account]:
contacts = self.get_contacts_from_jid(account, jid)
if group in contacts[0].groups:
group_contacts += contacts
return group_contacts
def get_nb_online_total_contacts(self, accounts = [], groups = []):
'''Returns the number of online contacts and the total number of
contacts'''
if accounts == []:
accounts = self.get_accounts()
nbr_online = 0
nbr_total = 0
for account in accounts:
our_jid = common.gajim.get_jid_from_account(account)
for jid in self.get_jid_list(account):
if jid == our_jid:
continue
if common.gajim.jid_is_transport(jid) and not \
common.gajim.config.get('show_transports_group'):
# do not count transports
continue
contact = self.get_contact_with_highest_priority(account, jid)
in_groups = False
if groups == []:
in_groups = True
else:
contact_groups = contact.groups
if not contact_groups:
# Contact is not in a group, so count it in General group
contact_groups.append(_('General'))
for group in groups:
if group in contact_groups:
in_groups = True
break
if in_groups:
if contact.show not in ('offline', 'error'):
nbr_online += 1
nbr_total += 1
return nbr_online, nbr_total
def define_metacontacts(self, account, tags_list):
self._metacontacts_tags[account] = tags_list
......
......@@ -16,32 +16,56 @@
##
import os
import sys
from common import gajim
from common import exceptions
_GAJIM_ERROR_IFACE = 'org.gajim.dbus.Error'
try:
import dbus
version = getattr(dbus, 'version', (0, 20, 0))
supported = True
import dbus.service
import dbus.glib
supported = True # does use have D-Bus bindings?
except ImportError:
version = (0, 0, 0)
supported = False
if not os.name == 'nt': # only say that to non Windows users
print _('D-Bus python bindings are missing in this computer')
print _('D-Bus capabilities of Gajim cannot be used')
class SystemBus:
'''A Singleton for the DBus SystemBus'''
def __init__(self):
self.system_bus = None
# dbus 0.23 leads to segfault with threads_init()
if sys.version[:4] >= '2.4' and version[1] < 30:
supported = False
def SystemBus(self):
if not supported:
raise exceptions.DbusNotSupported
if version >= (0, 41, 0):
import dbus.service
import dbus.glib # cause dbus 0.35+ doesn't return signal replies without it
if not self.present():
raise exceptions.SystemBusNotPresent
return self.system_bus
def bus(self):
return self.SystemBus()
def present(self):
if not supported:
return False
if self.system_bus is None:
try:
self.system_bus = dbus.SystemBus()
except dbus.dbus_bindings.DBusException:
self.system_bus = None
return False
if self.system_bus is None:
return False
return True
system_bus = SystemBus()
class SessionBus:
'''A Singleton for the DBus SessionBus'''
'''A Singleton for the D-Bus SessionBus'''
def __init__(self):
self.session_bus = None
......@@ -102,4 +126,13 @@ def get_interface(interface, path):
def get_notifications_interface():
'''Returns the notifications interface.'''
return get_interface('org.freedesktop.Notifications','/org/freedesktop/Notifications')
return get_interface('org.freedesktop.Notifications',
'/org/freedesktop/Notifications')
if supported:
class MissingArgument(dbus.DBusException):
_dbus_error_name = _GAJIM_ERROR_IFACE + '.MissingArgument'
class InvalidArgument(dbus.DBusException):
'''Raised when one of the provided arguments is invalid.'''
_dbus_error_name = _GAJIM_ERROR_IFACE + '.InvalidArgument'
docdir = '../'
datadir = '../'
version = '0.10.1.7'
import sys, os.path
for base in ('.', 'common'):
sys.path.append(os.path.join(base, '.libs'))
......@@ -5,7 +5,7 @@
##
## Copyright (C) 2006 Yann Le Boulanger <asterix@lagaule.org>
## Vincent Hanquez <tab@snarc.org>
## Nikos Kouremenos <nkour@jabber.org>
## Nikos Kouremenos <kourem@gmail.com>
## Dimitur Kirov <dkirov@gmail.com>
## Travis Shirk <travis@pobox.com>
## Norman Rasmussen <norman@rasmussen.co.za>
......@@ -81,7 +81,7 @@ class Events:
gajim.interface.systray.set_img()
def remove_events(self, account, jid, event = None, types = []):
'''if event is not speficied, remove all events from this jid,
'''if event is not specified, remove all events from this jid,
optionnaly only from given type
return True if no such event found'''
if not self._events.has_key(account):
......@@ -118,11 +118,11 @@ class Events:
if gajim.interface.systray_capabilities:
gajim.interface.systray.set_img()
def get_nb_events(self, types = []):
return self._get_nb_events(types = types)
def get_nb_events(self, types = [], account = None):
return self._get_nb_events(types = types, account = account)
def get_events(self, account, jid = None, types = []):
'''if event is not speficied, remove all events from this jid,
'''if event is not specified, get all events from this jid,
optionnaly only from given type'''
if not self._events.has_key(account):
return []
......@@ -149,7 +149,7 @@ class Events:
return first_event
def _get_nb_events(self, account = None, jid = None, attribute = None, types = []):
'''return the number of events'''
'''return the number of pending events'''
nb = 0
if account:
accounts = [account]
......@@ -223,7 +223,7 @@ class Events:
return self._get_first_event_with_attribute(events)
def get_nb_roster_events(self, account = None, jid = None, types = []):
'''returns the number of events displayedin roster'''
'''returns the number of events displayed in roster'''
return self._get_nb_events(attribute = 'roster', account = account,
jid = jid, types = types)
......
## exceptions.py
##
## Contributors for this file:
## - Yann Le Boulanger <asterix@lagaule.org>
## - Nikos Kouremenos <kourem@gmail.com>
##
## Copyright (C) 2003-2004 Yann Le Boulanger <asterix@lagaule.org>
## Vincent Hanquez <tab@snarc.org>
## Copyright (C) 2005 Yann Le Boulanger <asterix@lagaule.org>
## Vincent Hanquez <tab@snarc.org>
## Nikos Kouremenos <nkour@jabber.org>
## Dimitur Kirov <dkirov@gmail.com>
## Travis Shirk <travis@pobox.com>
## Norman Rasmussen <norman@rasmussen.co.za>
## Copyright (C) 2005-2006 Yann Le Boulanger <asterix@lagaule.org>
## Copyright (C) 2005-2006 Nikos Kouremenos <kourem@gmail.com>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published
......@@ -54,3 +44,12 @@ class SessionBusNotPresent(Exception):
def __str__(self):
return _('Session bus is not available.\nTry reading http://trac.gajim.org/wiki/GajimDBus')
class GajimGeneralException(Exception):
'''This exception ir our general exception'''
def __init__(self, text=''):
Exception.__init__(self)
self.text = text
def __str__(self):
return self.text
......@@ -15,9 +15,7 @@
## GNU General Public License for more details.
##
import os
import sys
import tempfile
import logging
import locale
......@@ -25,10 +23,36 @@ import config
from contacts import Contacts
from events import Events
try:
import defs
except ImportError:
print >> sys.stderr, '''defs.py is missing!
If you start gajim from svn:
* Make sure you have GNU autotools installed.
This includes the following packages:
automake >= 1.8
autoconf >= 2.59
intltool-0.35
libtool
* Run
$ sh autogen.sh
* Optionally, install gajim