def stats_search_number_of_tickets(rt_object, query): """ This function will get the number of tickets. As most tickets will have a specific criteria, we will use this function to include it by default. The criteria will be defined in the default_query variable. :param rt_object: RTApi object :param query: The string to be appended to the default_query variable :return: A number or a list, depending on the detail variable """ if not query: raise ValueError('no query... error!') # The default query default_query = 'Queue = "General" AND ( "CF.{IS - Informatica e Sistemas}" = "DIR" ' \ 'OR "CF.{IS - Informatica e Sistemas}" = "DIR-INBOX" ) AND ' # The search query query = default_query + query # Get the information from the server. try: response = get_list_of_tickets(rt_object, query, False) except ValueError as e: raise ValueError(str(e)) return len(response)
def user_get_resolved_tickets(rt_object, email): config = DITICConfig() # Check if user is known... if not config.check_if_email_exist(email): raise ValueError("Unknown email/user:"******"%s" AND Queue = "general" AND Status = "resolved"' % (email) # Get the information from the server. try: response = get_list_of_tickets(rt_object, query) except NameError as e: raise ValueError("Error: " + str(e)) number_tickets_per_status = {email: len(response)} for line in response: try: auxiliary_date = strptime(line["lastupdated"]) auxiliary_date = "%02d/%02d" % (auxiliary_date.tm_mon, auxiliary_date.tm_mday) except ValueError: auxiliary_date = 0 line["auxiliary_date"] = auxiliary_date create_ticket_possible_actions(config, line, email, number_tickets_per_status) result = group_result_by(response, "auxiliary_date") email_limit = config.get_email_limits(email) return {"tickets": result}
def test_get_list_of_tickets_detail_True(): rt_object = RTApiMock() rt_object.set_return( [ u'rt/4.0.6 200 ok', u'', u'id: ticket/887677', u'owner: [email protected]', u'subject: create rt dashboard', u'status: open', u'priority: 26', u'cf.{servico}: csc-gsiic', u'cf.{is - informatica e sistemas}: dir-inbox', ] ) result = get_list_of_tickets(rt_object, 'Owner = "*****@*****.**" and Status == "open"', True) assert rt_object.uri == '/search/ticket' assert rt_object.data == { 'query': 'Owner = "*****@*****.**" and Status == "open"', 'format': 'l' } assert result == [ { u'status': u'open', u'priority': u'26', u'owner': u'*****@*****.**', u'cf.{is - informatica e sistemas}': u'dir-inbox', u'id': u'887677', u'cf.{servico}': u'csc-gsiic', u'subject': u'create rt dashboard' } ]
def stats_search_tickets(rt_object, query): """ This function will get the list of tickets. As most tickets will have a specific criteria, we will use this function to include it by default. The criteria will be defined in the default_query variable. :param rt_object: RTApi object :param query: The string to be appended to the default_query variable :return: A number or a list, depending on the detail variable """ if not query: raise ValueError('no query... error!') # The default query default_query = 'Queue = "General" AND ' # The search query query = default_query + query # Get the information from the server. try: response = get_list_of_tickets(rt_object, query) except ValueError: return [] return response
def stats_search_tickets(rt_object, query): """ This function will get the list of tickets. As most tickets will have a specific criteria, we will use this function to include it by default. The criteria will be defined in the default_query variable. :param rt_object: RTApi object :param query: The string to be appended to the default_query variable :return: A number or a list, depending on the detail variable """ if not query: raise ValueError('no query... error!') # The default query default_query = 'Queue = "General" AND ' # The search query query = default_query+query # Get the information from the server. try: response = get_list_of_tickets(rt_object, query) except ValueError: return [] return response
def archive_tickets(rt_object, ticket_id, ticket_email, user_email): """ In this function we will apply the ticket action requested by user. It is possible to change the ticket priority, owner, etc. :param rt_object: rt object for querying (must be users authenticated) :param ticket_id: The ticket we want to see possible actions :param ticket_email: The ticket owner (we need this because of the special user dir, dir-inbox and unknown) :param user_email: the user email who is requesting this action (we need this to take a ticket) :return: RT result (I think we must change this output!) """ # First of all, get the actual ticket information query = 'id = "%s"' % ticket_id # Get the information from the server. try: ticket_line = get_list_of_tickets(rt_object, query)[0] except NameError as e: return "Error:" + str(e) # There is so much to be done. So this is the default answer. result = "Still working on it... sorry for the inconvenience!" # INCREASE PRIORITY ############################## result = modify_ticket(rt_object, ticket_id, {"status": "archived"}) dictReturn = {"archive_result": result} return dictReturn
def stats_search_number_of_tickets(rt_object, query): """ This function will get the number of tickets. As most tickets will have a specific criteria, we will use this function to include it by default. The criteria will be defined in the default_query variable. :param rt_object: RTApi object :param query: The string to be appended to the default_query variable :return: A number or a list, depending on the detail variable """ if not query: raise ValueError('no query... error!') # The default query default_query = 'Queue = "General" AND ( "CF.{IS - Informatica e Sistemas}" = "DIR" ' \ 'OR "CF.{IS - Informatica e Sistemas}" = "DIR-INBOX" ) AND ' # The search query query = default_query+query # Get the information from the server. try: response = get_list_of_tickets(rt_object, query, False) except ValueError as e: raise ValueError(str(e)) return len(response)
def search_tickets(rt_object, search): """ Search for tickets that match those criteria. The search will focus on those fields: - Requestors.EmailAddress - Subject - cf{servico} - cc - admincc - Requestor.Name - Requestor.RealName The tickets must be under the following restrictions: - Belongs to Queue General - Must have "CF.{IS - Informatica e Sistemas}" equal to DIR or DIR-INBOX - Must be created or updated on the last 90 days :param rt_object: RTApi object :param search: the search criteria :return: """ config = DITICConfig() # Search last 30 days. previous_date = (date.today() - timedelta(90)).isoformat() # The search string query = ( 'Queue = "General" AND ( "CF.{IS - Informatica e Sistemas}" = "DIR" ' 'OR "CF.{IS - Informatica e Sistemas}" = "DIR-INBOX" ) AND ' '( Lastupdated > "' + previous_date + '" OR Created > "' + previous_date + '") ' 'AND ( Requestor.EmailAddress LIKE "%' + search + '%" ' ) for query_items in ["Subject", "cf.{servico}", "cc", "admincc", "Requestor.Name", "Requestor.RealName"]: query += ' OR %s LIKE "%%%s%%" ' % (query_items, search) query += ")" # Get the information from the server. try: response = get_list_of_tickets(rt_object, query) except NameError as e: raise ValueError("Error: " + str(e)) except ValueError: return {"no_result": True, "number_tickets": "No results...", "tickets": {}} number_tickets = len(response) for line in response: try: auxiliary_date = strptime(line["lastupdated"]) auxiliary_date = "%02d/%02d" % (auxiliary_date.tm_mon, auxiliary_date.tm_mday) except ValueError: auxiliary_date = 0 line["auxiliary_date"] = auxiliary_date result = group_result_by(response, "auxiliary_date") email_limit = config.get_email_limits(search) return {"no_result": False, "tickets": result, "number_tickets": number_tickets, "email_limit": email_limit}
def ticket_action(ticket_id, action): ticket_action_auxiliar(ticket_id, action) os.system('update_statistics') os.system("generate_summary_file") lista = get_list_of_tickets(rt_object, "id=%s" % ticket_id) print "-------------------" print "INICIO TICKET ACÇAO" for linha in lista: print linha print "FIM TICKET ACÇAO" print "-------------------" redirect("/detail/" + emailGlobal + "?o=" + request.query.o)
def __insert_into_project_management(rt_object, project_management_object, element, parent=0): # TODO this operation takes too long! One possible resolution is: # TODO - get all tickets using only get_ticket_links function # TODO - with all tickets ID, perform only one query for all info of all objects # TODO even so, this will take too long... :( element_dict = get_list_of_tickets(rt_object, 'id='+str(element))[0] project_management_object.add_element(element, parent, element_dict) # Get links for this element result = get_ticket_links(rt_object, element) for line in result: if line[0] == 'members': __insert_into_project_management(rt_object, project_management_object, int(line[1]), int(element)) return
def user_closed_tickets(rt_object, email): """ Get the closed tickets on the last X days. (X = 60) :param rt_object: RTApi object :param email: the user email (it must exist in the config) :return: """ config = DITICConfig() # Check if user is known... if not config.check_if_email_exist(email): raise ValueError('Unknown email/user:'******'Owner = "%s" AND Queue = "general" AND Status = "resolved" AND LastUpdated > "%s"' % ( email, previous_date) # Get the information from the server. try: response = get_list_of_tickets(rt_object, query) except NameError as e: raise ValueError('Error: ' + str(e)) number_tickets_per_status = {email: len(response)} for line in response: try: auxiliary_date = strptime(line['lastupdated']) auxiliary_date = '%02d/%02d' % (auxiliary_date.tm_mon, auxiliary_date.tm_mday) except ValueError: auxiliary_date = 0 line['auxiliary_date'] = auxiliary_date create_ticket_possible_actions(config, line, email, number_tickets_per_status) result = group_result_by(response, 'auxiliary_date') email_limit = config.get_email_limits(email) return { 'tickets': result, 'number_tickets_per_status': number_tickets_per_status, 'email_limit': email_limit, }
def user_closed_tickets(rt_object, email): """ Get the closed tickets on the last X days. (X = 60) :param rt_object: RTApi object :param email: the user email (it must exist in the config) :return: """ config = DITICConfig() # Check if user is known... if not config.check_if_email_exist(email): raise ValueError('Unknown email/user:'******'Owner = "%s" AND Queue = "general" AND Status = "resolved" AND LastUpdated > "%s"' % (email, previous_date) # Get the information from the server. try: response = get_list_of_tickets(rt_object, query) except NameError as e: raise ValueError('Error: '+str(e)) number_tickets_per_status = {email: len(response)} for line in response: try: auxiliary_date = strptime(line['lastupdated']) auxiliary_date = '%02d/%02d' % (auxiliary_date.tm_mon, auxiliary_date.tm_mday) except ValueError: auxiliary_date = 0 line['auxiliary_date'] = auxiliary_date create_ticket_possible_actions(config, line, email, number_tickets_per_status) result = group_result_by(response, 'auxiliary_date') email_limit = config.get_email_limits(email) return { 'tickets': result, 'number_tickets_per_status': number_tickets_per_status, 'email_limit': email_limit, }
def get_number_of_tickets(rt_object, query): """ This function will return the number of tickets that matches the query. :param rt_object: the RTApi object for querying :param query: the query :return: the number of tickets found """ # Just a simple check... ;) if query == '': return 0 # Get the information from the server. try: response = get_list_of_tickets(rt_object, query, detail=False) except ValueError: return 0 return len(response)
def get_number_of_tickets(rt_object, query): """ This function will return the number of tickets that matches the query. :param rt_object: the RTApi object for querying :param query: the query :return: the number of tickets found """ # Just a simple check... ;) if query == '': return 0 # Get the information from the server. try: response = get_list_of_tickets(rt_object, query, detail=False) except ValueError: return 0 return len(response)
def get_urgent_tickets(rt_object): """ This function will return the list of urgent tickets. To be an urgent ticket it must: - Be in the DIR-INBOX - Have status 'new' - Have the cf.{ditic-urgent} == yes :param rt_object: :return: """ query = '"cf.{is - informatica e sistemas}" = "dir-inbox" AND "cf.{ditic-urgent}" = "yes"' 'AND Owner = "nobody"' # Get the information from the server. try: return get_list_of_tickets(rt_object, query, detail=False) except ValueError: return []
def test_get_list_of_tickets_detail_False(): rt_object = RTApiMock() rt_object.set_return( [ u'rt/4.0.6 200 ok', u'', u'887677: create rt dashboard', ] ) result = get_list_of_tickets(rt_object, 'Owner = "*****@*****.**" and Status == "open"', False) assert rt_object.uri == '/search/ticket' assert rt_object.data == { 'query': 'Owner = "*****@*****.**" and Status == "open"', } assert result == [ { u'subject': u'create rt dashboard', u'id': u'887677', } ]
def __insert_into_project_management(rt_object, project_management_object, element, parent=0): # TODO this operation takes too long! One possible resolution is: # TODO - get all tickets using only get_ticket_links function # TODO - with all tickets ID, perform only one query for all info of all objects # TODO even so, this will take too long... :( element_dict = get_list_of_tickets(rt_object, 'id=' + str(element))[0] project_management_object.add_element(element, parent, element_dict) # Get links for this element result = get_ticket_links(rt_object, element) for line in result: if line[0] == 'members': __insert_into_project_management(rt_object, project_management_object, int(line[1]), int(element)) return
def get_urgent_tickets(rt_object): """ This function will return the list of urgent tickets. To be an urgent ticket it must: - Be in the DIR-INBOX - Have status 'new' - Have the cf.{ditic-urgent} == yes :param rt_object: :return: """ query = '"cf.{is - informatica e sistemas}" = "dir-inbox" AND "cf.{ditic - urgent}" = "yes"' \ 'AND Owner = "nobody"' # Get the information from the server. try: return get_list_of_tickets(rt_object, query, detail=False) except ValueError: return []
def search_tickets(rt_object, search): """ Search for tickets that match those criteria. The search will focus on those fields: - Requestors.EmailAddress - Subject - cf{servico} - cc - admincc - Requestor.Name - Requestor.RealName The tickets must be under the following restrictions: - Belongs to Queue General - Must have "CF.{IS - Informatica e Sistemas}" equal to DIR or DIR-INBOX - Must be created or updated on the last 90 days :param rt_object: RTApi object :param search: the search criteria :return: """ config = DITICConfig() # Search last 30 days. previous_date = (date.today() - timedelta(90)).isoformat() # The search string query = 'Queue = "General" AND ( "CF.{IS - Informatica e Sistemas}" = "DIR" ' \ 'OR "CF.{IS - Informatica e Sistemas}" = "DIR-INBOX" ) AND ' \ '( Lastupdated > "'+previous_date+'" OR Created > "'+previous_date+'") ' \ 'AND ( Requestor.EmailAddress LIKE "%'+search+'%" ' for query_items in [ 'Subject', 'cf.{servico}', 'cc', 'admincc', 'Requestor.Name', 'Requestor.RealName' ]: query += ' OR %s LIKE "%%%s%%" ' % (query_items, search) query += ')' # Get the information from the server. try: response = get_list_of_tickets(rt_object, query) except NameError as e: raise ValueError('Error: ' + str(e)) except ValueError: return { 'no_result': True, 'number_tickets': 'No results...', 'tickets': {}, } number_tickets = len(response) for line in response: try: auxiliary_date = strptime(line['lastupdated']) auxiliary_date = '%02d/%02d' % (auxiliary_date.tm_mon, auxiliary_date.tm_mday) except ValueError: auxiliary_date = 0 line['auxiliary_date'] = auxiliary_date result = group_result_by(response, 'auxiliary_date') email_limit = config.get_email_limits(search) return { 'no_result': False, 'tickets': result, 'number_tickets': number_tickets, 'email_limit': email_limit, }
def ticket_actions(rt_object, ticket_id, action, ticket_email, user_email): """ In this function we will apply the ticket action requested by user. It is possible to change the ticket priority, owner, etc. :param rt_object: rt object for querying (must be users authenticated) :param ticket_id: The ticket we want to see possible actions :param action: the action requested. :param ticket_email: The ticket owner (we need this because of the special user dir, dir-inbox and unknown) :param user_email: the user email who is requesting this action (we need this to take a ticket) :return: RT result (I think we must change this output!) """ # First of all, get the actual ticket information query = 'id = "%s"' % ticket_id # Get the information from the server. try: ticket_line = get_list_of_tickets(rt_object, query)[0] except NameError as e: return 'Error:' + str(e) # There is so much to be done. So this is the default answer. result = 'Still working on it... sorry for the inconvenience!' # INCREASE PRIORITY ############################## if action == 'increase_priority': result = modify_ticket( rt_object, ticket_id, {'priority': str(int(ticket_line['priority']) + 1)}) # DECREASE PRIORITY ############################## elif action == 'decrease_priority': result = modify_ticket( rt_object, ticket_id, {'priority': str(int(ticket_line['priority']) - 1)}) # BACK ############################## elif action == 'back': if ticket_email == 'dir-inbox': result = modify_ticket(rt_object, ticket_id, { 'cf.{is - informatica e sistemas}': 'dir', }) elif ticket_line['status'] == 'new': result = modify_ticket( rt_object, ticket_id, { 'owner': 'nobody', 'cf.{is - informatica e sistemas}': 'dir-inbox', }) elif ticket_line['status'] == 'open': result = modify_ticket( rt_object, ticket_id, { 'timeworked': calculate_time_worked(ticket_line) + ' minutes', 'starts': '0', 'status': 'new', 'cf.{is - informatica e sistemas}': 'in', }) elif ticket_line['status'] == 'stalled': result = modify_ticket( rt_object, ticket_id, { 'starts': ctime(time()), 'status': 'new', 'cf.{is - informatica e sistemas}': 'in', }) # FORWARD ############################## elif action == 'forward': if ticket_email == 'dir': result = modify_ticket( rt_object, ticket_id, { 'cf.{is - informatica e sistemas}': 'dir-inbox', }) elif ticket_line['status'] == 'new': result = modify_ticket( rt_object, ticket_id, { 'starts': ctime(time()), 'status': 'open', 'cf.{is - informatica e sistemas}': 'active', }) elif ticket_line['status'] == 'open': print "status open, action forward" result = modify_ticket( rt_object, ticket_id, { 'timeworked': calculate_time_worked(ticket_line) + ' minutes', 'starts': '0', 'status': 'resolved', 'cf.{is - informatica e sistemas}': 'done', }) # STALLED ############################## elif action == 'stalled': if ticket_line['status'] == 'open': result = modify_ticket( rt_object, ticket_id, { 'timeworked': calculate_time_worked(ticket_line) + ' minutes', 'starts': '0', 'status': 'stalled', 'cf.{is - informatica e sistemas}': 'stalled', }) # TAKE ############################## elif action == 'take': result = modify_ticket( rt_object, ticket_id, { 'owner': user_email, 'status': 'new', 'cf.{is - informatica e sistemas}': 'in', }) # URGENT ############################## elif action == 'set_urgent': result = modify_ticket(rt_object, ticket_id, { 'cf.{DITIC-Urgent}': 'yes', }) elif action == 'unset_urgent': result = modify_ticket(rt_object, ticket_id, { 'cf.{DITIC-Urgent}': 'no', }) # Interrupted ############################## elif action == 'interrupted': if ticket_line['cf.{ditic-interrupted}']: interrupted = int(ticket_line['cf.{ditic-interrupted}']) + 1 else: interrupted = 1 result = modify_ticket(rt_object, ticket_id, { 'cf.{DITIC-Interrupted}': str(interrupted), }) return ticket_actions(rt_object, ticket_id, 'back', ticket_email, user_email) return {'action_result': result}
def __generate_summary_file(rt_object, list_emails, list_status): """ This function will search all tickets and generate a summary to be used by the summary report. :param rt_object: the rt_object for accessing get_list_of_tickets :param list_emails: A set with the known emails. It is a set to optimize the search :param list_status: A list of available status :return: summary (TODO: how it is done!) """ # Get the date from which we start searching tickets. previous_date = (date.today() - timedelta(0)).isoformat() # First step: search for all tickets of known emails known_email_query = '' for email in DITICConfig().get_email_to_user().keys(): if known_email_query: known_email_query += ' OR ' known_email_query += ' Owner = "%s" ' % email email_query = ' AND ('+known_email_query+') ' # Get the information from the server. try: response = get_list_of_tickets(rt_object, r'Queue = "general" AND ( Resolved > "%s" ' r'OR Status != "deleted" ) %s' % (previous_date, email_query)) except ValueError as e: raise ValueError('Error1:' + str(e)) # Second step: search for all tickets of DIR and DIR-INBOX try: response += get_list_of_tickets(rt_object, r'Queue = "general" AND ( "CF.{IS - Informatica e Sistemas}" = "DIR"' r'OR "CF.{IS - Informatica e Sistemas}" = "DIR-INBOX" )' r'AND Owner = "nobody" AND Status != "resolved" ' r'AND Status != "deleted" ') except ValueError as e: #raise ValueError('Error:2' + str(e)) pass # Third step: search for all tickets of unknown emails known_email_query = '' for email in DITICConfig().get_email_to_user().keys(): known_email_query += ' AND Owner != "%s" ' % email email_query = known_email_query+' AND Owner != "nobody" ' # Get the information from the server. try: response += get_list_of_tickets(rt_object, ''' Queue = "general" AND Status != "deleted" AND ( "CF.{IS - Informatica e Sistemas}" = "DIR"' OR "CF.{IS - Informatica e Sistemas}" = "DIR-INBOX" ) %s ''' % email_query) except ValueError as e: if str(e) != 'no matching results.': raise ValueError('Error:3' + str(e)) # Lets create summary dictionary summary = dict() summary['unknown'] = {status: 0 for status in list_status} summary['dir'] = {status: 0 for status in list_status} summary['dir-inbox'] = {status: 0 for status in list_status} group_by_email = group_result_by(response, 'owner') for email in sorted(group_by_email.keys()): group_by_status = group_result_by(group_by_email[email], 'status') # If this email is known, then identify it # If user is nobody, then it can be DIR or DIR-INBOX # Otherwise, it is unknown! if email in list_emails: summary[email] = {status: 0 for status in list_status} elif email == 'nobody': pass else: email = 'unknown' # Count the number of tickets in every status for this email for status in sorted(group_by_status.keys()): if email == 'nobody': group_by_cf = group_result_by(group_by_status[status], 'cf.{is - informatica e sistemas}') summary['dir'][status] += len(group_by_cf.get('dir', '')) summary['dir-inbox'][status] += len(group_by_cf.get('dir-inbox', '')) else: summary[email][status] += len(group_by_status[status]) return summary
def test_get_list_of_tickets_ok(): rt_object = RTApiMock() rt_object.set_return( [ u'rt/4.0.6 200 ok', u'', u'id: ticket/887677', u'queue: general', u'owner: [email protected]', u'creator: [email protected]', u'subject: create rt dashboard', u'status: open', u'priority: 26', u'initialpriority: 25', u'finalpriority: 75', u'requestors: [email protected]', u'cc:', u'admincc:', u'created: wed jul 15 21:17:29 2015', u'starts: fri jul 24 13:08:34 2015', u'started: wed jul 15 21:17:38 2015', u'due: not set', u'resolved: sun jul 19 02:29:03 2015', u'told: not set', u'lastupdated: fri jul 24 13:08:14 2015', u'timeestimated: 0', u'timeworked: 1026 minutes', u'timeleft: 0', u'cf.{servico}: csc-gsiic', u'cf.{n\xba de equipamento}:', u'cf.{tipo interven\xe7\xe3o}:', u'cf.{is - informatica e sistemas}: dir-inbox', u'cf.{sistema}:', u'cf.{estado gsiic}:', u'cf.{prioridade do requerente}:', u'cf.{notas}:', u'cf.{tipo de pedido}:', u'cf.{linkreport}: relatorio' ] ) # Test if everything is ok... result = get_list_of_tickets(rt_object, 'Owner = "*****@*****.**" and Status == "open"') assert result == [ { u'status': u'open', u'resolved': u'sun jul 19 02:29:03 2015', u'cf.{n\xba de equipamento}': u'', u'creator': u'*****@*****.**', u'cc': u'', u'started': u'wed jul 15 21:17:38 2015', u'requestors': u'*****@*****.**', u'cf.{servico}': u'csc-gsiic', u'owner': u'*****@*****.**', u'cf.{is - informatica e sistemas}': u'dir-inbox', 'id': u'887677', u'subject': u'create rt dashboard', u'queue': u'general', u'cf.{sistema}': u'', u'timeleft': u'0', u'cf.{tipo de pedido}': u'', u'cf.{prioridade do requerente}': u'', u'created': u'wed jul 15 21:17:29 2015', u'cf.{notas}': u'', u'starts': u'fri jul 24 13:08:34 2015', u'due': u'not set', u'lastupdated': u'fri jul 24 13:08:14 2015', u'timeworked': u'1026 minutes', u'priority': u'26', u'admincc': u'', u'cf.{tipo interven\xe7\xe3o}': u'', u'cf.{estado gsiic}': u'', u'timeestimated': u'0', u'initialpriority': u'25', u'finalpriority': u'75', u'cf.{linkreport}': u'relatorio', u'told': u'not set' } ]
def __generate_summary_file(rt_object, list_emails, list_status): """ This function will search all tickets and generate a summary to be used by the summary report. :param rt_object: the rt_object for accessing get_list_of_tickets :param list_emails: A set with the known emails. It is a set to optimize the search :param list_status: A list of available status :return: summary (TODO: how it is done!) """ # Get the date from which we start searching tickets. previous_date = (date.today() - timedelta(0)).isoformat() # First step: search for all tickets of known emails known_email_query = '' for email in DITICConfig().get_email_to_user().keys(): if known_email_query: known_email_query += ' OR ' known_email_query += ' Owner = "%s" ' % email email_query = ' AND (' + known_email_query + ') ' # Get the information from the server. try: response = get_list_of_tickets( rt_object, r'Queue = "general" AND ( Resolved > "%s" ' r'OR ( Status != "resolved" ' r'AND Status != "deleted" ) ) %s' % (previous_date, email_query)) except ValueError as e: raise ValueError('Error1:' + str(e)) # Second step: search for all tickets of DIR and DIR-INBOX try: response += get_list_of_tickets( rt_object, r'Queue = "general" AND ( "CF.{IS - Informatica e Sistemas}" = "INBOX"' r'OR "CF.{IS - Informatica e Sistemas}" = "INBOX" )' r'AND Owner = "nobody" AND Status != "resolved" ' r'AND Status != "deleted" ') except ValueError as e: #raise ValueError('Error:2' + str(e)) pass # Third step: search for all tickets of unknown emails known_email_query = '' for email in DITICConfig().get_email_to_user().keys(): known_email_query += ' AND Owner != "%s" ' % email email_query = known_email_query + ' AND Owner != "nobody" ' # Get the information from the server. try: response += get_list_of_tickets( rt_object, ''' Queue = "general" AND Status != "resolved" AND Status != "deleted" AND ( "CF.{IS - Informatica e Sistemas}" = "INBOX"' OR "CF.{IS - Informatica e Sistemas}" = "INBOX" ) %s ''' % email_query) except ValueError as e: if str(e) != 'no matching results.': raise ValueError('Error:3' + str(e)) # Lets create summary dictionary summary = dict() summary['unknown'] = {status: 0 for status in list_status} summary['inbox'] = {status: 0 for status in list_status} #summary['dir-inbox'] = {status: 0 for status in list_status} group_by_email = group_result_by(response, 'owner') for email in sorted(group_by_email.keys()): group_by_status = group_result_by(group_by_email[email], 'status') # If this email is known, then identify it # If user is nobody, then it can be DIR or DIR-INBOX # Otherwise, it is unknown! if email in list_emails: summary[email] = {status: 0 for status in list_status} elif email == 'nobody': pass else: email = 'unknown' # Count the number of tickets in every status for this email for status in sorted(group_by_status.keys()): if email == 'nobody': group_by_cf = group_result_by( group_by_status[status], 'cf.{is - informatica e sistemas}') #summary['dir'][status] += len(group_by_cf.get('dir', '')) summary['inbox'][status] += len(group_by_cf.get('inbox', '')) else: summary[email][status] += len(group_by_status[status]) return summary
def test_get_list_of_tickets_no_results(): rt_object = RTApiMock() rt_object.set_return(['no matching results.']) with pytest.raises(ValueError) as value_error: get_list_of_tickets(rt_object, 'Owner = "*****@*****.**" and Status == "open"') assert 'no matching results.' in str(value_error)
def user_tickets_details(rt_object, email): query = 'Owner = "'+email+'" AND Queue = "general" ' config = DITICConfig() # If the user is dir, then build the search if email == 'dir': query = 'Queue = "general" AND "CF.{IS - Informatica e Sistemas}" = "DIR" AND Owner = "Nobody" AND ' \ 'Status != "deleted" ' # If the user is dir-inbox, then search for it elif email == 'dir-inbox': query = 'Queue = "general" AND "CF.{IS - Informatica e Sistemas}" = "DIR-INBOX" AND Owner = "Nobody" AND ' \ 'Status != "deleted" ' # If the user is unknown, then search all users but those that we already know elif email == 'unknown': query = 'Queue = "general" AND "CF.{IS - Informatica e Sistemas}" LIKE "DIR%" AND ' \ 'Status != "deleted" ' for user in config.get_email_to_user().keys(): query += 'AND Owner != "'+user+'" ' query += 'AND Owner != "Nobody"' # Otherwise, check if user is not known... elif not config.check_if_email_exist(email): raise ValueError('Unknown email/user:'******' AND Status != "deleted" ' # Get the information from the server. try: response = get_list_of_tickets(rt_object, query) except ValueError as e: response = [] if email == 'dir' or email == 'dir-inbox' or email == 'unknown': number_tickets_per_status = {email: len(response)} result = group_result_by(response, 'priority') for priority in result: for line in result[priority]: create_ticket_possible_actions(config, line, email, number_tickets_per_status) else: # Get some statistics response_grouped_by_status = group_result_by(response, 'status') number_tickets_per_status = {} for status in response_grouped_by_status: number_tickets_per_status[status] = len(response_grouped_by_status[status]) result = {} for status in response_grouped_by_status: grouped_by_priority = group_result_by(response_grouped_by_status[status], 'priority') result[status] = grouped_by_priority for priority in grouped_by_priority: for line in grouped_by_priority[priority]: create_ticket_possible_actions(config, line, email, number_tickets_per_status) # The user limits... email_limit = config.get_email_limits(email) return { 'tickets': result, 'number_tickets_per_status': number_tickets_per_status, 'email_limit': email_limit, }
def search_tickets(rt_object, search): """ Search for tickets that match those criteria. The search will focus on those fields: - Requestors.EmailAddress - Subject - cf{servico} - cc - admincc - Requestor.Name - Requestor.RealName The tickets must be under the following restrictions: - Belongs to Queue General - Must have "CF.{IS - Informatica e Sistemas}" equal to DIR or DIR-INBOX - Must be created or updated on the last 90 days :param rt_object: RTApi object :param search: the search criteria :return: """ config = DITICConfig() # Search last 30 days. previous_date = (date.today() - timedelta(90)).isoformat() # The search string query = 'Queue = "General" AND ( "CF.{IS - Informatica e Sistemas}" = "DIR" ' \ 'OR "CF.{IS - Informatica e Sistemas}" = "DIR-INBOX" ) AND ' \ '( Lastupdated > "'+previous_date+'" OR Created > "'+previous_date+'") ' \ 'AND ( Requestor.EmailAddress LIKE "%'+search+'%" ' for query_items in ['Subject', 'cf.{servico}', 'cc', 'admincc', 'Requestor.Name', 'Requestor.RealName']: query += ' OR %s LIKE "%%%s%%" ' % (query_items, search) query += ')' # Get the information from the server. try: response = get_list_of_tickets(rt_object, query) except NameError as e: raise ValueError('Error: '+str(e)) except ValueError: return { 'no_result': True, 'number_tickets': 'No results...', 'tickets': {}, } number_tickets = len(response) for line in response: try: auxiliary_date = strptime(line['lastupdated']) auxiliary_date = '%02d/%02d' % (auxiliary_date.tm_mon, auxiliary_date.tm_mday) except ValueError: auxiliary_date = 0 line['auxiliary_date'] = auxiliary_date result = group_result_by(response, 'auxiliary_date') email_limit = config.get_email_limits(search) return { 'no_result': False, 'tickets': result, 'number_tickets': number_tickets, 'email_limit': email_limit, }
def ticket_actions(rt_object, ticket_id, action, ticket_email, user_email): """ In this function we will apply the ticket action requested by user. It is possible to change the ticket priority, owner, etc. :param rt_object: rt object for querying (must be users authenticated) :param ticket_id: The ticket we want to see possible actions :param action: the action requested. :param ticket_email: The ticket owner (we need this because of the special user dir, dir-inbox and unknown) :param user_email: the user email who is requesting this action (we need this to take a ticket) :return: RT result (I think we must change this output!) """ # First of all, get the actual ticket information query = 'id = "%s"' % ticket_id # Get the information from the server. try: ticket_line = get_list_of_tickets(rt_object, query)[0] except NameError as e: return 'Error:'+str(e) # There is so much to be done. So this is the default answer. result = 'Still working on it... sorry for the inconvenience!' # INCREASE PRIORITY ############################## if action == 'increase_priority': result = modify_ticket( rt_object, ticket_id, { 'priority': str(int(ticket_line['priority']) + 1) } ) # DECREASE PRIORITY ############################## elif action == 'decrease_priority': result = modify_ticket( rt_object, ticket_id, { 'priority': str(int(ticket_line['priority']) - 1) } ) # BACK ############################## elif action == 'back': if ticket_email == 'dir-inbox': result = modify_ticket( rt_object, ticket_id, { 'cf.{is - informatica e sistemas}': 'dir', } ) elif ticket_line['status'] == 'new': result = modify_ticket( rt_object, ticket_id, { 'owner': 'nobody', 'cf.{is - informatica e sistemas}': 'dir-inbox', } ) elif ticket_line['status'] == 'open': result = modify_ticket( rt_object, ticket_id, { 'timeworked': calculate_time_worked(ticket_line) + ' minutes', 'starts': '0', 'status': 'new', 'cf.{is - informatica e sistemas}': 'in', } ) elif ticket_line['status'] == 'stalled': result = modify_ticket( rt_object, ticket_id, { 'starts': ctime(time()), 'status': 'new', 'cf.{is - informatica e sistemas}': 'in', } ) # FORWARD ############################## elif action == 'forward': if ticket_email == 'dir': result = modify_ticket( rt_object, ticket_id, { 'cf.{is - informatica e sistemas}': 'dir-inbox', } ) elif ticket_line['status'] == 'new': result = modify_ticket( rt_object, ticket_id, { 'starts': ctime(time()), 'status': 'open', 'cf.{is - informatica e sistemas}': 'active', } ) elif ticket_line['status'] == 'open': print "status open, action forward" result = modify_ticket( rt_object, ticket_id, { 'timeworked': calculate_time_worked(ticket_line) + ' minutes', 'starts': '0', 'status': 'resolved', 'cf.{is - informatica e sistemas}': 'done', } ) # STALLED ############################## elif action == 'stalled': if ticket_line['status'] == 'open': result = modify_ticket( rt_object, ticket_id, { 'timeworked': calculate_time_worked(ticket_line) + ' minutes', 'starts': '0', 'status': 'stalled', 'cf.{is - informatica e sistemas}': 'stalled', } ) # TAKE ############################## elif action == 'take': result = modify_ticket( rt_object, ticket_id, { 'owner': user_email, 'status': 'new', 'cf.{is - informatica e sistemas}': 'in', } ) # URGENT ############################## elif action == 'set_urgent': result = modify_ticket( rt_object, ticket_id, { 'cf.{DITIC-Urgent}': 'yes', } ) elif action == 'unset_urgent': result = modify_ticket( rt_object, ticket_id, { 'cf.{DITIC-Urgent}': 'no', } ) # Interrupted ############################## elif action == 'interrupted': if ticket_line['cf.{ditic-interrupted}']: interrupted = int(ticket_line['cf.{ditic-interrupted}']) + 1 else: interrupted = 1 result = modify_ticket( rt_object, ticket_id, { 'cf.{DITIC-Interrupted}': str(interrupted), } ) return ticket_actions(rt_object, ticket_id, 'back', ticket_email, user_email) return { 'action_result': result }
def test_get_list_of_tickets_invalid_query(): rt_object = RTApiMock() rt_object.set_return(['invalid query:']) with pytest.raises(ValueError) as value_error: get_list_of_tickets(rt_object, 'Owner = "*****@*****.**" and Status == "open"') assert 'invalid query' in str(value_error)
def user_tickets_details(rt_object, email): query = 'Owner = "' + email + '" AND Queue = "general" ' config = DITICConfig() # If the user is dir, then build the search if email == 'dir': query = 'Queue = "general" AND "CF.{IS - Informatica e Sistemas}" = "DIR" AND Owner = "Nobody" AND ' \ 'Status != "deleted" ' # If the user is dir-inbox, then search for it elif email == 'dir-inbox': query = 'Queue = "general" AND "CF.{IS - Informatica e Sistemas}" = "DIR-INBOX" AND Owner = "Nobody" AND ' \ 'Status != "deleted" ' # If the user is unknown, then search all users but those that we already know elif email == 'unknown': query = 'Queue = "general" AND "CF.{IS - Informatica e Sistemas}" LIKE "DIR%" AND ' \ 'Status != "deleted" ' for user in config.get_email_to_user().keys(): query += 'AND Owner != "' + user + '" ' query += 'AND Owner != "Nobody"' # Otherwise, check if user is not known... elif not config.check_if_email_exist(email): raise ValueError('Unknown email/user:'******' AND Status != "deleted" ' # Get the information from the server. try: response = get_list_of_tickets(rt_object, query) except ValueError as e: response = [] if email == 'dir' or email == 'dir-inbox' or email == 'unknown': number_tickets_per_status = {email: len(response)} result = group_result_by(response, 'priority') for priority in result: for line in result[priority]: create_ticket_possible_actions(config, line, email, number_tickets_per_status) else: # Get some statistics response_grouped_by_status = group_result_by(response, 'status') number_tickets_per_status = {} for status in response_grouped_by_status: number_tickets_per_status[status] = len( response_grouped_by_status[status]) result = {} for status in response_grouped_by_status: grouped_by_priority = group_result_by( response_grouped_by_status[status], 'priority') result[status] = grouped_by_priority for priority in grouped_by_priority: for line in grouped_by_priority[priority]: create_ticket_possible_actions(config, line, email, number_tickets_per_status) # The user limits... email_limit = config.get_email_limits(email) return { 'tickets': result, 'number_tickets_per_status': number_tickets_per_status, 'email_limit': email_limit, }
def test_get_list_of_tickets_invalid_username_or_password(): rt_object = RTApiMock() rt_object.set_return(['your username or password is incorrect']) with pytest.raises(ValueError) as value_error: get_list_of_tickets(rt_object, 'Owner = "*****@*****.**" and Status == "open"') assert 'your username or password is incorrect' in str(value_error)
#!/usr/bin/env python from ditic_kanban.config import DITICConfig from ditic_kanban.rt_api import get_list_of_tickets from ditic_kanban.rt_api import RTApi myconfig = DITICConfig() system = myconfig.get_system() email_rt_api = RTApi(system['server'], system['username'], system['password']) #query = 'Owner = "*****@*****.**" and Status = "rejected"' query = '"cf.{is - informatica e sistemas}" not like "dir" and "cf.{is - informatica e sistemas}" not like "dir-inbox"' response = get_list_of_tickets(email_rt_api, query) print response print len(response)
def ticket_actions(rt_object, ticket_id, action, ticket_email, user_email): """ In this function we will apply the ticket action requested by user. It is possible to change the ticket priority, owner, etc. :param rt_object: rt object for querying (must be users authenticated) :param ticket_id: The ticket we want to see possible actions :param action: the action requested. :param ticket_email: The ticket owner (we need this because of the special user dir, dir-inbox and unknown) :param user_email: the user email who is requesting this action (we need this to take a ticket) :return: RT result (I think we must change this output!) """ # First of all, get the actual ticket information query = 'id = "%s"' % ticket_id # Get the information from the server. try: ticket_line = get_list_of_tickets(rt_object, query)[0] except NameError as e: return "Error:" + str(e) # There is so much to be done. So this is the default answer. result = "Still working on it... sorry for the inconvenience!" # INCREASE PRIORITY ############################## if action == "increase_priority": result = modify_ticket(rt_object, ticket_id, {"priority": str(int(ticket_line["priority"]) + 1)}) # DECREASE PRIORITY ############################## elif action == "decrease_priority": result = modify_ticket(rt_object, ticket_id, {"priority": str(int(ticket_line["priority"]) - 1)}) # BACK ############################## elif action == "back": if ticket_email == "dir-inbox": result = modify_ticket(rt_object, ticket_id, {"cf.{is - informatica e sistemas}": "dir"}) elif ticket_line["status"] == "new": result = modify_ticket( rt_object, ticket_id, {"owner": "nobody", "cf.{is - informatica e sistemas}": "dir-inbox"} ) elif ticket_line["status"] == "open": result = modify_ticket( rt_object, ticket_id, {"timeworked": calculate_time_worked(ticket_line) + " minutes", "starts": "0", "status": "new"}, ) elif ticket_line["status"] == "rejected": result = modify_ticket(rt_object, ticket_id, {"starts": ctime(time()), "status": "open"}) elif ticket_line["status"] == "stalled": result = modify_ticket(rt_object, ticket_id, {"starts": ctime(time()), "status": "open"}) elif ticket_line["status"] == "resolved": result = modify_ticket(rt_object, ticket_id, {"starts": ctime(time()), "status": "open"}) # FORWARD ############################## elif action == "forward": if ticket_email == "dir": result = modify_ticket(rt_object, ticket_id, {"cf.{is - informatica e sistemas}": "dir-inbox"}) elif ticket_line["status"] == "new": result = modify_ticket(rt_object, ticket_id, {"starts": ctime(time()), "status": "open"}) elif ticket_line["status"] == "open": result = modify_ticket( rt_object, ticket_id, {"timeworked": calculate_time_worked(ticket_line) + " minutes", "starts": "0", "status": "resolved"}, ) elif ticket_line["status"] == "resolved": result = modify_ticket(rt_object, ticket_id, {"status": "archived"}) # STALLED ############################## elif action == "stalled": if ticket_line["status"] == "open": result = modify_ticket( rt_object, ticket_id, {"timeworked": calculate_time_worked(ticket_line) + " minutes", "starts": "0", "status": "stalled"}, ) # TAKE ############################## elif action == "take": result = modify_ticket(rt_object, ticket_id, {"owner": user_email, "status": "new"}) # URGENT ############################## elif action == "set_urgent": result = modify_ticket(rt_object, ticket_id, {"cf.{DITIC-Urgent}": "yes"}) elif action == "unset_urgent": result = modify_ticket(rt_object, ticket_id, {"cf.{DITIC-Urgent}": ""}) # Interrupted ############################## elif action == "interrupt": print "Interrupt!" a = datetime.datetime.now() if ticket_line["cf.{ditic-interrupted}"]: interrupted = int(ticket_line["cf.{ditic-interrupted}"]) + 1 else: interrupted = 1 result = modify_ticket( rt_object, ticket_id, { "cf.{DITIC-Interrupted}": str(interrupted), "cf.{DITIC-interrupted-time}": "%s %s %s %s %s %s" % (a.year, a.month, a.day, a.hour, a.minute, a.second), }, ) elif action == "back_interrupt": print "BackInterrupt!-> %s" % ticket_line["cf.{ditic-interrupted-time}"] if ticket_line["cf.{ditic-interrupted}"]: interrupted = int(ticket_line["cf.{ditic-interrupted}"]) + 1 tempo = calculaTempo(ticket_line["cf.{ditic-total-interrupt}"], ticket_line["cf.{ditic-interrupted-time}"]) result = modify_ticket( rt_object, ticket_id, {"cf.{DITIC-Interrupted}": str(interrupted), "cf.{DITIC-total-interrupt}": tempo} ) # return ticket_actions(rt_object, ticket_id, 'back', ticket_email, user_email) return {"action_result": result}