##### ##### This file is part of Mail-in-a-Box-LDAP which is released under the ##### terms of the GNU Affero General Public License as published by the ##### Free Software Foundation, either version 3 of the License, or (at ##### your option) any later version. See file LICENSE or go to ##### https://github.com/downtownallday/mailinabox-ldap for full license ##### details. ##### from .Timeseries import Timeseries from .exceptions import InvalidArgsError import logging log = logging.getLogger(__name__) def select_list_suggestions(conn, args): try: query_type = args['type'] query = args['query'].strip() ts = None if 'start_date' in args: # use Timeseries to get a normalized start/end range ts = Timeseries( 'select list suggestions', args['start_date'], args['end_date'], 0 ) except KeyError: raise InvalidArgsError() # escape query with backslash for fuzzy match (LIKE) query_escaped = query.replace("\\", "\\\\").replace("%","\\%").replace("_","\\_") limit = 100 queries = { 'remote_host': { 'select': "DISTINCT CASE WHEN remote_host='unknown' THEN remote_ip ELSE remote_host END", 'from': "mta_connection", 'join': {}, 'order_by': "remote_host", 'where_exact': [ "(remote_host = ? OR remote_ip = ?)" ], 'args_exact': [ query, query ], 'where_fuzzy': [ "(remote_host LIKE ? ESCAPE '\\' OR remote_ip LIKE ? ESCAPE '\\')" ], 'args_fuzzy': [ '%'+query_escaped+'%', query_escaped+'%' ] }, 'rcpt_to': { 'select': "DISTINCT rcpt_to", 'from': 'mta_delivery', 'join': {}, 'order_by': "rcpt_to", 'where_exact': [ "rcpt_to = ?" ], 'args_exact': [ query, ], 'where_fuzzy': [ "rcpt_to LIKE ? ESCAPE '\\'" ], 'args_fuzzy': [ '%'+query_escaped+'%' ] }, 'envelope_from': { 'select': "DISTINCT envelope_from", 'from': "mta_accept", 'join': {}, 'order_by': 'envelope_from', 'where_exact': [ "envelope_from = ?" ], 'args_exact': [ query, ], 'where_fuzzy': [ "envelope_from LIKE ? ESCAPE '\\'" ], 'args_fuzzy': [ '%'+query_escaped+'%' ] }, } q = queries.get(query_type) if not q: raise InvalidArgError() if ts: q['where_exact'] += [ 'connect_time>=?', 'connect_time=?', 'connect_time=limit } finally: c.close()