Refactor search_log()
- use NATURAL JOIN in SQL query instead of multiple SELECT via _build_contact_where - make code more concise - update method documentation
This commit is contained in:
parent
950f763220
commit
fb7eb0718a
3 changed files with 43 additions and 39 deletions
|
@ -87,7 +87,7 @@ class StandardCommonCommands(CommandContainer):
|
||||||
@command('lastlog', overlap=True)
|
@command('lastlog', overlap=True)
|
||||||
@doc(_("Show logged messages which mention given text"))
|
@doc(_("Show logged messages which mention given text"))
|
||||||
def grep(self, text, limit=None):
|
def grep(self, text, limit=None):
|
||||||
results = gajim.logger.search_log(self.contact.jid, text, self.account)
|
results = gajim.logger.search_log(self.account, self.contact.jid, text)
|
||||||
|
|
||||||
if not results:
|
if not results:
|
||||||
raise CommandError(_("%s: Nothing found") % text)
|
raise CommandError(_("%s: Nothing found") % text)
|
||||||
|
|
|
@ -165,6 +165,7 @@ class Logger:
|
||||||
self.con.row_factory = self.namedtuple_factory
|
self.con.row_factory = self.namedtuple_factory
|
||||||
|
|
||||||
# DB functions
|
# DB functions
|
||||||
|
self.con.create_function("like", 1, self._like)
|
||||||
self.con.create_function("get_timeout", 0, self._get_timeout)
|
self.con.create_function("get_timeout", 0, self._get_timeout)
|
||||||
|
|
||||||
self.cur = self.con.cursor()
|
self.cur = self.con.cursor()
|
||||||
|
@ -202,6 +203,10 @@ class Logger:
|
||||||
timeout = now - (timeout * 60)
|
timeout = now - (timeout * 60)
|
||||||
return timeout
|
return timeout
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _like(search_str):
|
||||||
|
return '%{}%'.format(search_str)
|
||||||
|
|
||||||
def commit(self):
|
def commit(self):
|
||||||
try:
|
try:
|
||||||
self.con.commit()
|
self.con.commit()
|
||||||
|
@ -720,49 +725,46 @@ class Logger:
|
||||||
date.timestamp(),
|
date.timestamp(),
|
||||||
(date + delta).timestamp())).fetchall()
|
(date + delta).timestamp())).fetchall()
|
||||||
|
|
||||||
def search_log(self, jid, query, account, year=None, month=None, day=None):
|
def search_log(self, account, jid, query, date=None):
|
||||||
"""
|
"""
|
||||||
Search the conversation log for messages containing the `query` string.
|
Search the conversation log for messages containing the `query` string.
|
||||||
|
|
||||||
The search can either span the complete log for the given `account` and
|
The search can either span the complete log for the given
|
||||||
`jid` or be restriced to a single day by specifying `year`, `month` and
|
`account` and `jid` or be restriced to a single day by
|
||||||
`day`, where `month` and `day` are 1-based.
|
specifying `date`.
|
||||||
|
|
||||||
All messages matching the specified criteria will be returned in a list
|
:param account: The account
|
||||||
containing tuples of type `Logger.Message`. If no messages match the
|
|
||||||
criteria, an empty list will be returned.
|
:param jid: The jid for which we request the conversation
|
||||||
|
|
||||||
|
:param query: A search string
|
||||||
|
|
||||||
|
:param date: datetime.datetime instance
|
||||||
|
example: datetime.datetime(year, month, day)
|
||||||
|
|
||||||
|
returns a list of namedtuples
|
||||||
"""
|
"""
|
||||||
try:
|
jids = self._get_family_jids(account, jid)
|
||||||
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)
|
if date:
|
||||||
like_sql = '%' + query.replace("'", "''") + '%'
|
delta = datetime.timedelta(
|
||||||
if year and month and day:
|
hours=23, minutes=59, seconds=59, microseconds=999999)
|
||||||
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,
|
|
||||||
additional_data, log_line_id
|
|
||||||
FROM logs
|
|
||||||
WHERE (%s) AND message LIKE '%s'
|
|
||||||
AND time BETWEEN %d AND %d
|
|
||||||
ORDER BY time
|
|
||||||
''' % (where_sql, like_sql, start_of_day, last_second_of_day),
|
|
||||||
jid_tuple)
|
|
||||||
else:
|
|
||||||
self.cur.execute('''
|
|
||||||
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)
|
|
||||||
|
|
||||||
return self.cur.fetchall()
|
between = '''
|
||||||
|
AND time BETWEEN {start} AND {end}
|
||||||
|
'''.format(start=date.timestamp(),
|
||||||
|
end=(date + delta).timestamp())
|
||||||
|
|
||||||
|
sql = '''
|
||||||
|
SELECT contact_name, time, kind, show, message, subject,
|
||||||
|
additional_data, log_line_id
|
||||||
|
FROM logs NATURAL JOIN jids WHERE jid IN ({jids})
|
||||||
|
AND message LIKE like(?) {date_search}
|
||||||
|
ORDER BY time, log_line_id
|
||||||
|
'''.format(jids=', '.join('?' * len(jids)),
|
||||||
|
date_search=between if date else '')
|
||||||
|
|
||||||
|
return self.con.execute(sql, (*jids, query)).fetchall()
|
||||||
|
|
||||||
def get_days_with_logs(self, jid, year, month, max_day, account):
|
def get_days_with_logs(self, jid, year, month, max_day, account):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -541,13 +541,15 @@ class HistoryWindow:
|
||||||
# This may leed to wrong self nick in the displayed history (Uggh!)
|
# This may leed to wrong self nick in the displayed history (Uggh!)
|
||||||
account = list(gajim.contacts.get_accounts())[0]
|
account = list(gajim.contacts.get_accounts())[0]
|
||||||
|
|
||||||
year, month, day = False, False, False
|
date = None
|
||||||
if self.search_in_date.get_active():
|
if self.search_in_date.get_active():
|
||||||
year, month, day = self.calendar.get_date() # integers
|
year, month, day = self.calendar.get_date() # integers
|
||||||
month = gtkgui_helpers.make_gtk_month_python_month(month)
|
month = gtkgui_helpers.make_gtk_month_python_month(month)
|
||||||
|
date = datetime.datetime(year, month, day)
|
||||||
|
|
||||||
show_status = self.show_status_checkbutton.get_active()
|
show_status = self.show_status_checkbutton.get_active()
|
||||||
results = gajim.logger.search_log(jid, text, account, year, month, day)
|
|
||||||
|
results = gajim.logger.search_log(account, jid, text, date)
|
||||||
#FIXME:
|
#FIXME:
|
||||||
# add "subject: | message: " in message column if kind is single
|
# add "subject: | message: " in message column if kind is single
|
||||||
# also do we need show at all? (we do not search on subject)
|
# also do we need show at all? (we do not search on subject)
|
||||||
|
|
Loading…
Add table
Reference in a new issue