Honor profile given on commandline for plugin dir and history db and more.

Also added new property 'additional_data' to message event objects. Changes to this attribute (a dict) are passed on from event to event and are also written to the history db as json string (reading of those values isn't implemented yet).
This commit is contained in:
tmolitor 2016-09-05 00:01:29 +02:00
parent 7ef4240f63
commit 065d08cebf
14 changed files with 69 additions and 50 deletions

View File

@ -72,7 +72,8 @@ def create_log_db():
kind INTEGER, kind INTEGER,
show INTEGER, show INTEGER,
message TEXT, message TEXT,
subject TEXT subject TEXT,
additional_data TEXT DEFAULT '{}'
); );
CREATE INDEX idx_logs_jid_id_time ON logs (jid_id, time DESC); CREATE INDEX idx_logs_jid_id_time ON logs (jid_id, time DESC);

View File

@ -134,23 +134,36 @@ class ConfigPaths:
for key in self.paths.keys(): for key in self.paths.keys():
yield (key, self[key]) yield (key, self[key])
def init(self, root=None): def init(self, root=None, profile=''):
if root is not None: if root is not None:
self.config_root = self.cache_root = self.data_root = root self.config_root = self.cache_root = self.data_root = root
d = {'MY_DATA': '', 'LOG_DB': 'logs.db', 'MY_CACERTS': 'cacerts.pem', d = {'LOG_DB': 'logs.db', 'MY_CACERTS': 'cacerts.pem',
'MY_EMOTS': 'emoticons', 'MY_ICONSETS': 'iconsets', 'MY_EMOTS': 'emoticons', 'MY_ICONSETS': 'iconsets',
'MY_MOOD_ICONSETS': 'moods', 'MY_ACTIVITY_ICONSETS': 'activities', 'MY_MOOD_ICONSETS': 'moods', 'MY_ACTIVITY_ICONSETS': 'activities',
'PLUGINS_USER': 'plugins', 'PLUGINS_USER': 'plugins',
'RNG_SEED': 'rng_seed'} 'RNG_SEED': 'rng_seed',
'SECRETS_FILE': 'secrets', 'MY_PEER_CERTS': 'certs'}
for name in d: for name in d:
if len(profile) > 0:
d[name] += u'.' + profile
self.add(name, TYPE_DATA, windowsify(d[name])) self.add(name, TYPE_DATA, windowsify(d[name]))
self.add('MY_DATA', TYPE_DATA, '')
d = {'MY_CACHE': '', 'CACHE_DB': 'cache.db', 'VCARD': 'vcards', d = {'CACHE_DB': 'cache.db', 'VCARD': 'vcards',
'AVATAR': 'avatars'} 'AVATAR': 'avatars',
'PID_FILE': 'gajim.pid'}
for name in d: for name in d:
if len(profile) > 0:
d[name] += u'.' + profile
self.add(name, TYPE_CACHE, windowsify(d[name])) self.add(name, TYPE_CACHE, windowsify(d[name]))
self.add('MY_CACHE', TYPE_CACHE, '')
d = {'CONFIG_FILE': 'config', 'PLUGINS_CONFIG_DIR': 'pluginsconfig', 'MY_CERT': 'localcerts'}
for name in d:
if len(profile) > 0:
d[name] += u'.' + profile
self.add(name, TYPE_CONFIG, windowsify(d[name]))
self.add('MY_CONFIG', TYPE_CONFIG, '') self.add('MY_CONFIG', TYPE_CONFIG, '')
basedir = fse(os.environ.get('GAJIM_BASEDIR', defs.basedir)) basedir = fse(os.environ.get('GAJIM_BASEDIR', defs.basedir))
@ -172,28 +185,4 @@ class ConfigPaths:
except (ImportError, AttributeError): except (ImportError, AttributeError):
pass pass
def init_profile(self, profile=''):
conffile = windowsify('config')
pidfile = windowsify('gajim')
secretsfile = windowsify('secrets')
pluginsconfdir = windowsify('pluginsconfig')
certsdir = windowsify(u'certs')
localcertsdir = windowsify(u'localcerts')
if len(profile) > 0:
conffile += '.' + profile
pidfile += '.' + profile
secretsfile += '.' + profile
pluginsconfdir += '.' + profile
certsdir += u'.' + profile
localcertsdir += u'.' + profile
pidfile += '.pid'
self.add('CONFIG_FILE', TYPE_CONFIG, conffile)
self.add('PID_FILE', TYPE_CACHE, pidfile)
self.add('SECRETS_FILE', TYPE_DATA, secretsfile)
self.add('PLUGINS_CONFIG_DIR', TYPE_CONFIG, pluginsconfdir)
self.add('MY_PEER_CERTS', TYPE_DATA, certsdir)
self.add('MY_CERT', TYPE_CONFIG, localcertsdir)
gajimpaths = ConfigPaths() gajimpaths = ConfigPaths()

View File

@ -1028,6 +1028,8 @@ class MamMessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
def generate(self): def generate(self):
if not self.stanza: if not self.stanza:
return return
if not hasattr(self, 'additional_data'):
self.additional_data = {}
account = self.conn.name account = self.conn.name
self.msg_ = self.stanza.getTag('message') self.msg_ = self.stanza.getTag('message')
# use timestamp of archived message, if available and archive timestamp otherwise # use timestamp of archived message, if available and archive timestamp otherwise
@ -1066,6 +1068,8 @@ class MamDecryptedMessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
def generate(self): def generate(self):
self.nick = None self.nick = None
msg_ = self.msg_obj.msg_ msg_ = self.msg_obj.msg_
if not hasattr(self, 'additional_data'):
self.additional_data = self.msg_obj.additional_data
self.with_ = self.msg_obj.with_ self.with_ = self.msg_obj.with_
self.direction = self.msg_obj.direction self.direction = self.msg_obj.direction
self.tim = self.msg_obj.tim self.tim = self.msg_obj.tim
@ -1106,6 +1110,8 @@ class MessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
self.get_id() self.get_id()
self.forwarded = False self.forwarded = False
self.sent = False self.sent = False
if not hasattr(self, 'additional_data'):
self.additional_data = {}
account = self.conn.name account = self.conn.name
@ -1384,6 +1390,8 @@ class DecryptedMessageReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
def generate(self): def generate(self):
self.stanza = self.msg_obj.stanza self.stanza = self.msg_obj.stanza
if not hasattr(self, 'additional_data'):
self.additional_data = self.msg_obj.additional_data
self.id_ = self.msg_obj.id_ self.id_ = self.msg_obj.id_
self.jid = self.msg_obj.jid self.jid = self.msg_obj.jid
self.fjid = self.msg_obj.fjid self.fjid = self.msg_obj.fjid
@ -1491,6 +1499,8 @@ class GcMessageReceivedEvent(nec.NetworkIncomingEvent):
def generate(self): def generate(self):
self.stanza = self.msg_obj.stanza self.stanza = self.msg_obj.stanza
if not hasattr(self, 'additional_data'):
self.additional_data = self.msg_obj.additional_data
self.fjid = self.msg_obj.fjid self.fjid = self.msg_obj.fjid
self.msgtxt = self.msg_obj.msgtxt self.msgtxt = self.msg_obj.msgtxt
self.jid = self.msg_obj.jid self.jid = self.msg_obj.jid
@ -1813,6 +1823,11 @@ class StanzaReceivedEvent(nec.NetworkIncomingEvent):
name = 'stanza-received' name = 'stanza-received'
base_network_events = [] base_network_events = []
def generate(self):
if not hasattr(self, 'additional_data'):
self.additional_data = {}
return True
class StanzaSentEvent(nec.NetworkIncomingEvent): class StanzaSentEvent(nec.NetworkIncomingEvent):
name = 'stanza-sent' name = 'stanza-sent'
base_network_events = [] base_network_events = []

View File

@ -32,6 +32,7 @@ import os
import sys import sys
import time import time
import datetime import datetime
import json
from gzip import GzipFile from gzip import GzipFile
from io import BytesIO from io import BytesIO
from gi.repository import GLib from gi.repository import GLib
@ -141,6 +142,8 @@ class Logger:
# if locked, wait up to 20 sec to unlock # if locked, wait up to 20 sec to unlock
# before raise (hopefully should be enough) # before raise (hopefully should be enough)
print("*****")
print("%s/%s" % (LOG_DB_FOLDER, LOG_DB_FILE))
self.con = sqlite.connect(LOG_DB_FILE, timeout=20.0, self.con = sqlite.connect(LOG_DB_FILE, timeout=20.0,
isolation_level='IMMEDIATE') isolation_level='IMMEDIATE')
os.chdir(back) os.chdir(back)
@ -412,7 +415,7 @@ class Logger:
def commit_to_db(self, values, write_unread=False): def commit_to_db(self, values, write_unread=False):
sql = '''INSERT INTO logs (jid_id, contact_name, time, kind, show, sql = '''INSERT INTO logs (jid_id, contact_name, time, kind, show,
message, subject) VALUES (?, ?, ?, ?, ?, ?, ?)''' message, subject, additional_data) VALUES (?, ?, ?, ?, ?, ?, ?, ?)'''
try: try:
self.cur.execute(sql, values) self.cur.execute(sql, values)
except sqlite.OperationalError as e: except sqlite.OperationalError as e:
@ -495,7 +498,7 @@ class Logger:
all_messages.append(results[0] + (shown,)) all_messages.append(results[0] + (shown,))
return all_messages return all_messages
def write(self, kind, jid, message=None, show=None, tim=None, subject=None): def write(self, kind, jid, message=None, show=None, tim=None, subject=None, additional_data={}):
""" """
Write a row (status, gcstatus, message etc) to logs database Write a row (status, gcstatus, message etc) to logs database
@ -517,6 +520,7 @@ class Logger:
# then it holds status message # then it holds status message
message_col = message message_col = message
subject_col = subject subject_col = subject
additional_data_col = json.dumps(additional_data)
if tim: if tim:
time_col = int(float(time.mktime(tim))) time_col = int(float(time.mktime(tim)))
else: else:
@ -576,7 +580,7 @@ class Logger:
return return
values = (jid_id, contact_name_col, time_col, kind_col, show_col, values = (jid_id, contact_name_col, time_col, kind_col, show_col,
message_col, subject_col) message_col, subject_col, additional_data_col)
return self.commit_to_db(values, write_unread) return self.commit_to_db(values, write_unread)
def get_last_conversation_lines(self, jid, restore_how_many_rows, def get_last_conversation_lines(self, jid, restore_how_many_rows,

View File

@ -945,4 +945,21 @@ class OptionsParser:
gajim.config.set('video_input_device', 'autovideosrc') gajim.config.set('video_input_device', 'autovideosrc')
if self.old_values['video_input_device'] == 'videotestsrc is-live=true ! video/x-raw-yuv,framerate=10/1': if self.old_values['video_input_device'] == 'videotestsrc is-live=true ! video/x-raw-yuv,framerate=10/1':
gajim.config.set('video_input_device', 'videotestsrc is-live=true ! video/x-raw,framerate=10/1') gajim.config.set('video_input_device', 'videotestsrc is-live=true ! video/x-raw,framerate=10/1')
back = os.getcwd()
os.chdir(logger.LOG_DB_FOLDER)
con = sqlite.connect(logger.LOG_DB_FILE)
os.chdir(back)
cur = con.cursor()
try:
cur.executescript(
'''
ALTER TABLE logs ADD COLUMN 'additional_data' TEXT DEFAULT '{}';
'''
)
con.commit()
except sqlite.OperationalError:
pass
con.close()
gajim.config.set('version', '0.16.10.1') gajim.config.set('version', '0.16.10.1')

View File

@ -28,7 +28,6 @@ if __name__ == '__main__':
from common import i18n from common import i18n
import common.configpaths import common.configpaths
common.configpaths.gajimpaths.init(None) common.configpaths.gajimpaths.init(None)
common.configpaths.gajimpaths.init_profile()
from common import helpers from common import helpers
from nbxmpp.idlequeue import IdleCommand from nbxmpp.idlequeue import IdleCommand

View File

@ -178,9 +178,8 @@ profile, config_path = parseOpts()
del parseOpts del parseOpts
import common.configpaths import common.configpaths
common.configpaths.gajimpaths.init(config_path) common.configpaths.gajimpaths.init(config_path, profile)
del config_path del config_path
common.configpaths.gajimpaths.init_profile(profile)
del profile del profile
if os.name == 'nt': if os.name == 'nt':

View File

@ -2528,13 +2528,12 @@ class Interface:
want_type=True) want_type=True)
if pixbuf is None: if pixbuf is None:
return return
extension = '.' + typ
if typ not in ('jpeg', 'png'): if typ not in ('jpeg', 'png'):
gajim.log.debug('gtkpixbuf cannot save other than jpeg and '\ gajim.log.info('gtkpixbuf cannot save other than jpeg and '\
'png formats. saving %s\'avatar as png file (originaly %s)'\ 'png formats. saving \'%s\' avatar as png file (originaly: %s)'\
% (jid, typ)) % (jid, typ))
typ = 'png' typ = 'png'
extension = '.png' extension = '.' + typ
path_to_original_file = path_to_file + extension path_to_original_file = path_to_file + extension
try: try:
pixbuf.savev(path_to_original_file, typ, [], []) pixbuf.savev(path_to_original_file, typ, [], [])

View File

@ -91,7 +91,6 @@ del parseOpts
import common.configpaths import common.configpaths
common.configpaths.gajimpaths.init(config_path) common.configpaths.gajimpaths.init(config_path)
del config_path del config_path
common.configpaths.gajimpaths.init_profile()
from common import exceptions from common import exceptions
from common import gajim from common import gajim
import gtkgui_helpers import gtkgui_helpers

View File

@ -50,7 +50,6 @@ import operator
if __name__ == '__main__': if __name__ == '__main__':
from common import i18n from common import i18n
import common.configpaths import common.configpaths
common.configpaths.gajimpaths.init_profile()
common.configpaths.gajimpaths.init(None) common.configpaths.gajimpaths.init(None)
import gtkgui_helpers import gtkgui_helpers
from common import gajim from common import gajim

View File

@ -121,10 +121,10 @@ text=None, timeout=-1):
notification.set_category(event_type) notification.set_category(event_type)
notification._data = {} notification._data = {}
notification._data.event_type = event_type notification._data["event_type"] = event_type
notification._data.jid = jid notification._data["jid"] = jid
notification._data.account = account notification._data["account"] = account
notification._data.msg_type = msg_type notification._data["msg_type"] = msg_type
notification.set_property('icon-name', path_to_image) notification.set_property('icon-name', path_to_image)
if 'actions' in Notify.get_server_caps(): if 'actions' in Notify.get_server_caps():
notification.add_action('default', 'Default Action', notification.add_action('default', 'Default Action',

View File

@ -101,7 +101,7 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
else: else:
msg_to_log = obj.msgtxt msg_to_log = obj.msgtxt
obj.msg_log_id = gajim.logger.write(log_type, obj.fjid, obj.msg_log_id = gajim.logger.write(log_type, obj.fjid,
msg_to_log, tim=obj.timestamp, subject=obj.subject) msg_to_log, tim=obj.timestamp, subject=obj.subject, additional_data=obj.additional_data)
except exceptions.PysqliteOperationalError as e: except exceptions.PysqliteOperationalError as e:
gajim.nec.push_incoming_event(InformationEvent(None, gajim.nec.push_incoming_event(InformationEvent(None,
conn=self.conn, level='error', pri_txt=_('Disk Write Error'), conn=self.conn, level='error', pri_txt=_('Disk Write Error'),
@ -147,7 +147,7 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession):
contact.msg_log_id = obj.msg_log_id contact.msg_log_id = obj.msg_log_id
# THIS MUST BE AFTER chatstates handling # THIS MUST BE AFTER chatstates handling
# AND BEFORE playsound (else we ear sounding on chatstates!) # AND BEFORE playsound (else we hear sounding on chatstates!)
if not obj.msgtxt: # empty message text if not obj.msgtxt: # empty message text
return True return True

View File

@ -37,7 +37,6 @@ def setup_env():
import common.configpaths import common.configpaths
common.configpaths.gajimpaths.init(configdir) common.configpaths.gajimpaths.init(configdir)
common.configpaths.gajimpaths.init_profile()
# for some reason common.gajim needs to be imported before xmpppy? # for some reason common.gajim needs to be imported before xmpppy?
from common import gajim from common import gajim

View File

@ -51,7 +51,6 @@ os.mkdir(configdir)
import common.configpaths import common.configpaths
common.configpaths.gajimpaths.init(configdir) common.configpaths.gajimpaths.init(configdir)
common.configpaths.gajimpaths.init_profile()
# for some reason common.gajim needs to be imported before xmpppy? # for some reason common.gajim needs to be imported before xmpppy?
from common import gajim from common import gajim