Refactor get_conversation_for_date()

- use NATURAL JOIN in SQL query instead of multiple SELECT via
_build_contact_where

- make code more concise

- update method documentation

- Fix a bug where messages were displayed in wrong order when
they had the same timestamp
This commit is contained in:
Philipp Hörist 2017-07-15 13:41:17 +02:00
parent 40ba449f47
commit 950f763220
2 changed files with 25 additions and 25 deletions

View File

@ -689,40 +689,36 @@ class Logger:
start_of_day = int(time.mktime(local_time)) start_of_day = int(time.mktime(local_time))
return start_of_day return start_of_day
def get_conversation_for_date(self, jid, year, month, day, account): def get_conversation_for_date(self, account, jid, date):
""" """
Load the complete conversation with a given jid on a specific date Load the complete conversation with a given jid on a specific date
The conversation contains all messages that were exchanged between :param account: The account
`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 :param jid: The jid for which we request the conversation
`Logger.Message`. Messages in the list are sorted chronologically. An
empty list will be returned if there are no messages in the log database :param date: datetime.datetime instance
for the requested combination of `jid` and `account` on the given date. example: datetime.datetime(year, month, day)
returns a list of namedtuples
""" """
try:
self.get_jid_id(jid)
except exceptions.PysqliteOperationalError:
# Error trying to create a new jid_id. This means there is no log
return []
where_sql, jid_tuple = self._build_contact_where(account, jid)
start_of_day = self.get_unix_time_from_date(year, month, day) jids = self._get_family_jids(account, jid)
seconds_in_a_day = 86400 # 60 * 60 * 24
last_second_of_day = start_of_day + seconds_in_a_day - 1
self.cur.execute(''' delta = datetime.timedelta(
hours=23, minutes=59, seconds=59, microseconds=999999)
sql = '''
SELECT contact_name, time, kind, show, message, subject, SELECT contact_name, time, kind, show, message, subject,
additional_data, log_line_id additional_data, log_line_id
FROM logs FROM logs NATURAL JOIN jids WHERE jid IN ({jids})
WHERE (%s) AND time BETWEEN ? AND ?
AND time BETWEEN %d AND %d ORDER BY time, log_line_id
ORDER BY time '''.format(jids=', '.join('?' * len(jids)))
''' % (where_sql, start_of_day, last_second_of_day), jid_tuple)
return self.cur.fetchall() return self.con.execute(sql, (*jids,
date.timestamp(),
(date + delta).timestamp())).fetchall()
def search_log(self, jid, query, account, year=None, month=None, day=None): def search_log(self, jid, query, account, year=None, month=None, day=None):
""" """

View File

@ -30,6 +30,7 @@ from gi.repository import Gdk
from gi.repository import GLib from gi.repository import GLib
import time import time
import calendar import calendar
import datetime
from enum import IntEnum, unique from enum import IntEnum, unique
@ -397,8 +398,11 @@ class HistoryWindow:
self.last_time_printout = 0 self.last_time_printout = 0
show_status = self.show_status_checkbutton.get_active() show_status = self.show_status_checkbutton.get_active()
date = datetime.datetime(year, month, day)
conversation = gajim.logger.get_conversation_for_date( conversation = gajim.logger.get_conversation_for_date(
self.jid, year, month, day, self.account) self.account, self.jid, date)
for message in conversation: for message in conversation:
if not show_status and message.kind in (KindConstant.GCSTATUS, if not show_status and message.kind in (KindConstant.GCSTATUS,
KindConstant.STATUS): KindConstant.STATUS):