Merge branch 'various-cleanups' into 'master'

Various small cleanups, with focus on logger and history window

See merge request !77
This commit is contained in:
Philipp Hörist 2017-03-31 16:44:32 +02:00
commit 1a5d6fbf30
16 changed files with 124 additions and 91 deletions

View File

@ -23,7 +23,7 @@
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
##
from enum import IntEnum
from enum import IntEnum, unique
from gi.repository import Gtk
import gtkgui_helpers
@ -32,6 +32,7 @@ from gi.repository import Pango
from common import gajim
@unique
class Column(IntEnum):
PREFERENCE_NAME = 0
VALUE = 1

View File

@ -87,8 +87,7 @@ class StandardCommonCommands(CommandContainer):
@command('lastlog', overlap=True)
@doc(_("Show logged messages which mention given text"))
def grep(self, text, limit=None):
results = gajim.logger.get_search_results_for_query(self.contact.jid,
text, self.account)
results = gajim.logger.search_log(self.contact.jid, text, self.account)
if not results:
raise CommandError(_("%s: Nothing found") % text)
@ -100,23 +99,22 @@ class StandardCommonCommands(CommandContainer):
raise CommandError(_("Limit must be an integer"))
for row in results:
contact, time, kind, show, message, subject, log_line_id = row
contact = row.contact_name
if not contact:
if kind == KindConstant.CHAT_MSG_SENT:
if row.kind == KindConstant.CHAT_MSG_SENT:
contact = gajim.nicks[self.account]
else:
contact = self.contact.name
time_obj = localtime(time)
date_obj = date.fromtimestamp(time)
time_obj = localtime(row.time)
date_obj = date.fromtimestamp(row.time)
date_ = strftime('%Y-%m-%d', time_obj)
time_ = strftime('%H:%M:%S', time_obj)
if date_obj == date.today():
formatted = "[%s] %s: %s" % (time_, contact, message)
formatted = "[%s] %s: %s" % (time_, contact, row.message)
else:
formatted = "[%s, %s] %s: %s" % (date_, time_, contact, message)
formatted = "[%s, %s] %s: %s" % (date_, time_, contact, row.message)
self.echo(formatted)

View File

@ -35,8 +35,9 @@
import re
from common import defs
from gi.repository import GLib
from enum import IntEnum
from enum import IntEnum, unique
@unique
class Option(IntEnum):
TYPE = 0
VAL = 1

View File

@ -26,8 +26,9 @@ import os
import sys
import tempfile
from common import defs
from enum import Enum
from enum import Enum, unique
@unique
class Type(Enum):
CONFIG = 0
CACHE = 1

View File

@ -23,7 +23,7 @@ import hashlib
import logging
import os
import threading
from enum import IntEnum
from enum import IntEnum, unique
import nbxmpp
from common import gajim
from common import configpaths
@ -39,6 +39,7 @@ from common.jingle_ftstates import (
log = logging.getLogger('gajim.c.jingle_ft')
@unique
class State(IntEnum):
NOT_STARTED = 0
INITIALIZED = 1

View File

@ -29,7 +29,7 @@ Handles Jingle sessions (XEP 0166)
# * timeout
import logging
from enum import Enum
from enum import Enum, unique
import nbxmpp
from common import gajim
from common.jingle_transport import get_jingle_transport, JingleTransportIBB
@ -43,6 +43,7 @@ from common.connection_handlers_events import (
log = logging.getLogger("gajim.c.jingle_session")
# FIXME: Move it to JingleSession.States?
@unique
class JingleStates(Enum):
"""
States in which jingle session may exist

View File

@ -19,7 +19,7 @@ Handles Jingle Transports (currently only ICE-UDP)
import logging
import socket
from enum import IntEnum
from enum import IntEnum, unique
import nbxmpp
from common import gajim
@ -34,6 +34,7 @@ def get_jingle_transport(node):
return transports[namespace](node)
@unique
class TransportType(IntEnum):
"""
Possible types of a JingleTransport

View File

@ -33,10 +33,11 @@ import sys
import time
import datetime
import json
from collections import namedtuple
from gzip import GzipFile
from io import BytesIO
from gi.repository import GLib
from enum import IntEnum
from enum import IntEnum, unique
from common import exceptions
from common import gajim
@ -51,10 +52,12 @@ CACHE_DB_PATH = gajim.gajimpaths['CACHE_DB']
import logging
log = logging.getLogger('gajim.c.logger')
@unique
class JIDConstant(IntEnum):
NORMAL_TYPE = 0
ROOM_TYPE = 1
@unique
class KindConstant(IntEnum):
STATUS = 0
GCSTATUS = 1
@ -65,6 +68,7 @@ class KindConstant(IntEnum):
CHAT_MSG_SENT = 6
ERROR = 7
@unique
class ShowConstant(IntEnum):
ONLINE = 0
CHAT = 1
@ -73,6 +77,7 @@ class ShowConstant(IntEnum):
DND = 4
OFFLINE = 5
@unique
class TypeConstant(IntEnum):
AIM = 0
GG = 1
@ -90,6 +95,7 @@ class TypeConstant(IntEnum):
MRIM = 13
NO_TRANSPORT = 14
@unique
class SubscriptionConstant(IntEnum):
NONE = 0
TO = 1
@ -182,7 +188,7 @@ class Logger:
def get_jids_already_in_db(self):
try:
self.cur.execute('SELECT jid FROM jids')
# list of tupples: [('aaa@bbb',), ('cc@dd',)]
# list of tuples: [('aaa@bbb',), ('cc@dd',)]
rows = self.cur.fetchall()
except sqlite.DatabaseError:
raise exceptions.DatabaseMalformed
@ -583,8 +589,8 @@ class Logger:
"""
Accept how many rows to restore and when to time them out (in minutes)
(mark them as too old) and number of messages that are in queue and are
already logged but pending to be viewed, returns a list of tupples
containg time, kind, message, sibject list with empty tupple if nothing
already logged but pending to be viewed, returns a list of tuples
containg time, kind, message, subject list with empty tuple if nothing
found to meet our demands
"""
try:
@ -625,17 +631,27 @@ class Logger:
# returns time in seconds for the second that starts that date since epoch
# gimme unixtime from year month day:
d = datetime.date(year, month, day)
local_time = d.timetuple() # time tupple (compat with time.localtime())
local_time = d.timetuple() # time tuple (compat with time.localtime())
# we have time since epoch baby :)
start_of_day = int(time.mktime(local_time))
return start_of_day
Message = namedtuple('Message',
['contact_name', 'time', 'kind', 'show', 'message', 'subject',
'additional_data', 'log_line_id'])
def get_conversation_for_date(self, jid, year, month, day, account):
"""
Return contact_name, time, kind, show, message, subject, additional_data, log_line_id
Load the complete conversation with a given jid on a specific date
For each row in a list of tupples, returns list with empty tupple if we
found nothing to meet our demands
The conversation contains all messages that were exchanged between
`account` and `jid` on the day specified by `year`, `month` and `day`,
where `month` and `day` are 1-based.
The conversation will be returned as a list of single messages of type
`Logger.Message`. Messages in the list are sorted chronologically. An
empty list will be returned if there are no messages in the log database
for the requested combination of `jid` and `account` on the given date.
"""
try:
self.get_jid_id(jid)
@ -657,22 +673,23 @@ class Logger:
ORDER BY time
''' % (where_sql, start_of_day, last_second_of_day), jid_tuple)
results = self.cur.fetchall()
messages = []
for entry in results:
additional_data = json.loads(entry[6])
parsed_entry = entry[:6] + (additional_data, ) + entry[7:]
messages.append(parsed_entry)
results = [self.Message(*row) for row in self.cur.fetchall()]
for message in results:
message._replace(additional_data=json.loads(message.additional_data))
return messages
return results
def get_search_results_for_query(self, jid, query, account, year=False,
month=False, day=False):
def search_log(self, jid, query, account, year=None, month=None, day=None):
"""
Returns contact_name, time, kind, show, message, subject, log_line_id
Search the conversation log for messages containing the `query` string.
For each row in a list of tupples, returns list with empty tupple if we
found nothing to meet our demands
The search can either span the complete log for the given `account` and
`jid` or be restriced to a single day by specifying `year`, `month` and
`day`, where `month` and `day` are 1-based.
All messages matching the specified criteria will be returned in a list
containing tuples of type `Logger.Message`. If no messages match the
criteria, an empty list will be returned.
"""
try:
self.get_jid_id(jid)
@ -682,12 +699,14 @@ class Logger:
where_sql, jid_tuple = self._build_contact_where(account, jid)
like_sql = '%' + query.replace("'", "''") + '%'
if year:
if year and month and day:
start_of_day = self.get_unix_time_from_date(year, month, day)
seconds_in_a_day = 86400 # 60 * 60 * 24
last_second_of_day = start_of_day + seconds_in_a_day - 1
self.cur.execute('''
SELECT contact_name, time, kind, show, message, subject, log_line_id FROM logs
SELECT contact_name, time, kind, show, message, subject,
additional_data, log_line_id
FROM logs
WHERE (%s) AND message LIKE '%s'
AND time BETWEEN %d AND %d
ORDER BY time
@ -695,12 +714,17 @@ class Logger:
jid_tuple)
else:
self.cur.execute('''
SELECT contact_name, time, kind, show, message, subject, log_line_id FROM logs
SELECT contact_name, time, kind, show, message, subject,
additional_data, log_line_id
FROM logs
WHERE (%s) AND message LIKE '%s'
ORDER BY time
''' % (where_sql, like_sql), jid_tuple)
results = self.cur.fetchall()
results = [self.Message(*row) for row in self.cur.fetchall()]
for message in results:
message._replace(additional_data=json.loads(message.additional_data))
return results
def get_days_with_logs(self, jid, year, month, max_day, account):

View File

@ -17,8 +17,9 @@
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
##
from enum import IntEnum
from enum import IntEnum, unique
@unique
class Constant(IntEnum):
NAME = 0
DOMAIN = 1
@ -26,6 +27,7 @@ class Constant(IntEnum):
BARE_NAME = 3
TXT = 4
@unique
class ConstantRI(IntEnum):
INTERFACE = 0
PROTOCOL = 1

View File

@ -29,7 +29,7 @@ from gi.repository import Pango
import os
import time
from enum import IntEnum
from enum import IntEnum, unique
import gtkgui_helpers
import tooltips
@ -44,6 +44,7 @@ from nbxmpp.protocol import NS_JINGLE_FILE_TRANSFER
import logging
log = logging.getLogger('gajim.filetransfer_window')
@unique
class Column(IntEnum):
IMAGE = 0
LABELS = 1

View File

@ -46,7 +46,7 @@ import cell_renderer_image
import dataforms_widget
import nbxmpp
from enum import IntEnum
from enum import IntEnum, unique
from common import events
from common import gajim
@ -65,6 +65,7 @@ from common.connection_handlers_events import GcMessageOutgoingEvent
import logging
log = logging.getLogger('gajim.groupchat_control')
@unique
class Column(IntEnum):
IMG = 0 # image to show state (online, new message etc)
NICK = 1 # contact nickame or ROLE name

View File

@ -77,8 +77,9 @@ from common.logger import LOG_DB_PATH, JIDConstant, KindConstant
from common import helpers
import dialogs
from enum import IntEnum
from enum import IntEnum, unique
@unique
class Column(IntEnum):
UNIXTIME = 2
MESSAGE = 3
@ -252,7 +253,7 @@ class HistoryManager:
# get those jids that have at least one entry in logs
self.cur.execute('SELECT jid, jid_id FROM jids WHERE jid_id IN ('
'SELECT distinct logs.jid_id FROM logs) ORDER BY jid')
# list of tupples: [('aaa@bbb',), ('cc@dd',)]
# list of tuples: [('aaa@bbb',), ('cc@dd',)]
rows = self.cur.fetchall()
for row in rows:
self.jids_already_in.append(row[0]) # jid

View File

@ -31,7 +31,7 @@ from gi.repository import GLib
import time
import calendar
from enum import IntEnum
from enum import IntEnum, unique
import gtkgui_helpers
import conversation_textview
@ -43,6 +43,7 @@ from common import exceptions
from common.logger import ShowConstant, KindConstant
@unique
class InfoColumn(IntEnum):
'''Completion dict'''
JID = 0
@ -50,6 +51,7 @@ class InfoColumn(IntEnum):
NAME = 2
COMPLETION = 3
@unique
class Column(IntEnum):
LOG_JID = 0
CONTACT_NAME = 1
@ -340,7 +342,7 @@ class HistoryWindow:
return
year, month, day = self.calendar.get_date() # integers
month = gtkgui_helpers.make_gtk_month_python_month(month)
self._add_lines_for_date(year, month, day)
self._load_conversation(year, month, day)
def on_calendar_month_changed(self, widget):
"""
@ -385,34 +387,38 @@ class HistoryWindow:
return show
def _add_lines_for_date(self, year, month, day):
def _load_conversation(self, year, month, day):
"""
Add all the lines for given date in textbuffer
Load the conversation between `self.jid` and `self.account` held on the
given date into the history textbuffer. Values for `month` and `day`
are 1-based.
"""
self.history_buffer.set_text('') # clear the buffer first
self.history_buffer.set_text('')
self.last_time_printout = 0
show_status = self.show_status_checkbutton.get_active()
lines = gajim.logger.get_conversation_for_date(self.jid, year, month, day, self.account)
for line in lines:
# line[0] is contact_name, line[1] is time of message
# line[2] is kind, line[3] is show, line[4] is message, line[5] is subject
# line[6] is additional_data, line[7] is log_line_id
if not show_status and line[2] in (KindConstant.GCSTATUS,
KindConstant.STATUS):
conversation = gajim.logger.get_conversation_for_date(
self.jid, year, month, day, self.account)
for message in conversation:
if not show_status and message.kind in (KindConstant.GCSTATUS,
KindConstant.STATUS):
continue
self._add_new_line(line[0], line[1], line[2], line[3], line[4],
line[5], line[6], line[7])
self._add_message(message)
def _add_new_line(self, contact_name, tim, kind, show, message, subject,
additional_data, log_line_id):
"""
Add a new line in textbuffer
"""
if not message and kind not in (KindConstant.STATUS,
KindConstant.GCSTATUS):
def _add_message(self, msg):
if not msg.message and msg.kind not in (KindConstant.STATUS,
KindConstant.GCSTATUS):
return
tim = msg.time
kind = msg.kind
show = msg.show
message = msg.message
subject = msg.subject
log_line_id = msg.log_line_id
contact_name = msg.contact_name
additional_data = msg.additional_data
buf = self.history_buffer
end_iter = buf.get_end_iter()
@ -423,7 +429,7 @@ class HistoryWindow:
timestamp_str = gajim.config.get('time_stamp')
timestamp_str = helpers.from_one_line(timestamp_str)
tim = time.strftime(timestamp_str, time.localtime(float(tim)))
buf.insert(end_iter, tim) # add time
buf.insert(end_iter, tim)
elif gajim.config.get('print_time') == 'sometimes':
every_foo_seconds = 60 * gajim.config.get(
'print_ichat_every_foo_minutes')
@ -441,13 +447,11 @@ class HistoryWindow:
if kind == KindConstant.GC_MSG:
tag_name = 'incoming'
elif kind in (KindConstant.SINGLE_MSG_RECV,
KindConstant.CHAT_MSG_RECV):
elif kind in (KindConstant.SINGLE_MSG_RECV, KindConstant.CHAT_MSG_RECV):
contact_name = self.completion_dict[self.jid][InfoColumn.NAME]
tag_name = 'incoming'
tag_msg = 'incomingtxt'
elif kind in (KindConstant.SINGLE_MSG_SENT,
KindConstant.CHAT_MSG_SENT):
elif kind in (KindConstant.SINGLE_MSG_SENT, KindConstant.CHAT_MSG_SENT):
if self.account:
contact_name = gajim.nicks[self.account]
else:
@ -539,33 +543,27 @@ class HistoryWindow:
month = gtkgui_helpers.make_gtk_month_python_month(month)
show_status = self.show_status_checkbutton.get_active()
# contact_name, time, kind, show, message, subject
results = gajim.logger.get_search_results_for_query(
jid, text, account, year, month, day)
results = gajim.logger.search_log(jid, text, account, year, month, day)
#FIXME:
# add "subject: | message: " in message column if kind is single
# also do we need show at all? (we do not search on subject)
for row in results:
if not show_status and row[2] in (KindConstant.GCSTATUS,
KindConstant.STATUS):
if not show_status and row.kind in (KindConstant.GCSTATUS,
KindConstant.STATUS):
continue
contact_name = row[0]
contact_name = row.contact_name
if not contact_name:
kind = row[2]
if kind == KindConstant.CHAT_MSG_SENT: # it's us! :)
if row.kind == KindConstant.CHAT_MSG_SENT: # it's us! :)
contact_name = gajim.nicks[account]
else:
contact_name = self.completion_dict[jid][InfoColumn.NAME]
tim = row[1]
message = row[4]
log_line_id = row[6]
local_time = time.localtime(tim)
local_time = time.localtime(row.time)
date = time.strftime('%Y-%m-%d', local_time)
# jid (to which log is assigned to), name, date, message,
# time (full unix time)
model.append((jid, contact_name, date, message, str(tim), log_line_id))
model.append((jid, contact_name, date, row.message,
str(row.time), row.log_line_id))
def on_results_treeview_row_activated(self, widget, path, column):
"""
@ -576,7 +574,7 @@ class HistoryWindow:
cur_year, cur_month, cur_day = self.calendar.get_date()
cur_month = gtkgui_helpers.make_gtk_month_python_month(cur_month)
model = widget.get_model()
# make it a tupple (Y, M, D, 0, 0, 0...)
# make it a tuple (Y, M, D, 0, 0, 0...)
tim = time.strptime(model[path][Column.UNIXTIME], '%Y-%m-%d')
year = tim[0]
gtk_month = tim[1]

View File

@ -157,7 +157,7 @@ class MessageControl(object):
Derivded classes MUST implement this.
"""
# Return a markup'd label and optional Gtk.Color in a tupple like:
# Return a markup'd label and optional Gtk.Color in a tuple like:
# return (label_str, None)
pass

View File

@ -32,7 +32,7 @@ from gi.repository import GdkPixbuf
from gi.repository import GLib, Gdk
import os
from enum import IntEnum
from enum import IntEnum, unique
import gtkgui_helpers
from dialogs import WarningDialog, YesNoDialog, ArchiveChooserDialog
@ -43,6 +43,7 @@ from plugins.helpers import GajimPluginActivateException
from plugins.plugins_i18n import _
from common.exceptions import PluginsystemError
@unique
class Column(IntEnum):
PLUGIN = 0
NAME = 1

View File

@ -43,7 +43,7 @@ import os
import time
import locale
from enum import IntEnum
from enum import IntEnum, unique
import common.sleepy
import history_window
@ -69,6 +69,7 @@ from message_window import MessageWindowMgr
from nbxmpp.protocol import NS_FILE, NS_ROSTERX, NS_CONFERENCE
@unique
class Column(IntEnum):
IMG = 0 # image to show state (online, new message etc)
NAME = 1 # cellrenderer text that holds contact nickame
@ -5792,7 +5793,7 @@ class RosterWindow:
self._iters = {}
# for merged mode
self._iters['MERGED'] = {'account': None, 'groups': {}}
# holds a list of (jid, account) tupples
# holds a list of (jid, account) tuples
self._last_selected_contact = []
self.transports_state_images = {'16': {}, '32': {}, 'opened': {},
'closed': {}}