diff --git a/pyotrs/__init__.py b/pyotrs/__init__.py index f8c1702e68abe51d7578b6cf124e05427889e8f9..53a363d59c271ec9a5db2ed1cbe48fed7289303b 100644 --- a/pyotrs/__init__.py +++ b/pyotrs/__init__.py @@ -1,2 +1,2 @@ """ __init__.py """ -from .pyotrs import PyOTRS +from .client import * diff --git a/pyotrs/client.py b/pyotrs/client.py index 1c0e670e48449e75ffd8b71a4bcaeb295ed7fa9b..0ee2f7b3276ded16b4e23c9d99b5103424fd6a89 100644 --- a/pyotrs/client.py +++ b/pyotrs/client.py @@ -111,30 +111,31 @@ class Client(object): self.webservicename = webservicename if not session_id_file: - self.session_id_file = ".session_id.tmp" + self.session_id_file = "/tmp/.session_id.tmp" + else: + self.session_id_file = session_id_file if not session_timeout: self.session_timeout = 28800 # 8 hours is OTRS default + self.https_verify = https_verify + + # dummy initialization + self.data = None + self.data_type = None + self.data_json = None + # if session_id is passed in with a value other than None # ignore username and password and use session_id # if session_id is None then restore or create a Session! self.username = username self.password = password - self.session_id_file = session_id_file if not session_id: self.restore_or_set_up_session() else: self.session_id = session_id - self.https_verify = https_verify - - # dummy initialization - self.data = None - self.data_type = None - self.data_json = None - """ GenericInterface::Operation::Session::SessionCreate Client public methods: @@ -180,9 +181,9 @@ class Client(object): """ if not session_id: - client = TicketGet(self.baseurl, self.webservicename, session_id=self.session_id) + client = Client(self.baseurl, self.webservicename, session_id=self.session_id) else: - client = TicketGet(self.baseurl, self.webservicename, session_id=session_id) + client = Client(self.baseurl, self.webservicename, session_id=session_id) return client.ticket_get_by_id(1, dynamic_fields=0, all_articles=0) @@ -192,12 +193,21 @@ class Client(object): """ if os.path.isfile(self.session_id_file): with open(self.session_id_file, "r") as f: - data = json.loads(f.read()) - created = data['created'] + content = f.read() + try: + data = json.loads(content) + created = datetime.datetime.utcfromtimestamp(int(data['created'])) + expires = created + datetime.timedelta(minutes=self.session_timeout) if expires > datetime.datetime.utcnow(): self.session_id = data['session_id'] # still valid return True + except ValueError as err: + logger.error("JSON Parse Exception: {}".format(err)) + pass # pass this exception as + except Exception as err: + logger.error("Some Exception: {}".format(err)) + raise Exception("Some Exception: {}".format(err)) return False @@ -210,7 +220,7 @@ class Client(object): """ with open(self.session_id_file, "w") as f: - f.write(json.dumps({'created': datetime.datetime.utcnow(), + f.write(json.dumps({'created': str(int(time.time())), 'session_id': self.session_id})) return True @@ -224,7 +234,7 @@ class Client(object): payload = { "UserLogin": self.username, - "Password": self.password + "Password": self.password } try: @@ -246,20 +256,18 @@ class Client(object): return True - -class TicketCreate(Client): """ GenericInterface::Operation::Ticket::TicketCreate - TicketCreate public methods: + public methods: + * ticket_create """ - pass + def ticket_create(self): + pass - -class TicketGet(Client): """ GenericInterface::Operation::Ticket::TicketGet - TicketGet public methods: + public methods: * ticket_get_by_id """ @@ -343,8 +351,8 @@ class TicketGet(Client): "{0.webservicename}/Ticket/{1}".format(self, ticket_id) payload = { - "SessionID": self.session_id, - "AllArticles": all_articles, + "SessionID": self.session_id, + "AllArticles": all_articles, "DynamicFields": dynamic_fields } @@ -354,11 +362,9 @@ class TicketGet(Client): logger.error("Exception: {0}".format(err)) return False - -class TicketSearch(Client): """ GenericInterface::Operation::Ticket::TicketSearch - TicketSearch public methods: + public methods: * ticket_search * ticket_search_by_past_days """ @@ -488,7 +494,7 @@ class TicketSearch(Client): older = newer - 1440 * days payload = { - "SessionID": self.session_id, + "SessionID": self.session_id, "TicketLastChangeTimeNewerMinutes": newer, "TicketLastChangeTimeOlderMinutes": older } @@ -501,17 +507,13 @@ class TicketSearch(Client): logger.error("Exception: {0}".format(err)) return False - -class TicketUpdate(Client): - """ - GenericInterface::Operation::Ticket::TicketUpdate - TicketUpdate public methods: - * ticket_update_add_article - * ticket_update_set_dynamic_field_value - * ticket_update_set_state - * ticket_update_set_state_pending - * ticket_update_set_title - """ + # GenericInterface :: Operation::Ticket :: TicketUpdate + # public methods + # * ticket_update_add_article + # * ticket_update_set_dynamic_field_value + # * ticket_update_set_state + # * ticket_update_set_state_pending + # * ticket_update_set_title def _update_by_ticket_id(self, url, payload): """ update_by_ticket_id @@ -589,9 +591,9 @@ class TicketUpdate(Client): payload = { "SessionID": self.session_id, "Article": { - "Subject": article_subject, - "Body": article_body, - "TimeUnit": 0, + "Subject": article_subject, + "Body": article_body, + "TimeUnit": 0, "ContentType": "text/plain; charset=ISO-8859-15" } } @@ -629,7 +631,7 @@ class TicketUpdate(Client): "{0.webservicename}/Ticket/{1}".format(self, ticket_id) payload = { - "SessionID": self.session_id, + "SessionID": self.session_id, "DynamicField": {"Name": dynamic_field_name, "Value": dynamic_field_value} } @@ -658,7 +660,7 @@ class TicketUpdate(Client): payload = { "SessionID": self.session_id, - "Ticket": {"State": new_state} + "Ticket": {"State": new_state} } logger.debug("Updating {0} with: ".format(ticket_id)) @@ -693,16 +695,16 @@ class TicketUpdate(Client): pending_time = time.gmtime( time.time() + (pending_hours * 3600) + (pending_days * 3600 * 24)) pending_time_str = { - "Year": pending_time.tm_year, - "Month": pending_time.tm_mon, - "Day": pending_time.tm_mday, - "Hour": pending_time.tm_hour, + "Year": pending_time.tm_year, + "Month": pending_time.tm_mon, + "Day": pending_time.tm_mday, + "Hour": pending_time.tm_hour, "Minute": pending_time.tm_min } payload = { "SessionID": self.session_id, - "Ticket": {"State": new_state, "PendingTime": pending_time_str} + "Ticket": {"State": new_state, "PendingTime": pending_time_str} } logger.debug("Updating {0} with: ".format(ticket_id)) @@ -742,54 +744,4 @@ class TicketUpdate(Client): logger.error("Exception: {0}".format(err)) return False - -def _get_numeric_logger_level_from_string(level): - """Parse string and return appropriate numeric logger level - - Args: - level (str): the string representation of a logging level. - Level is one of these: [NOTSET|TRACE|DEBUG|INFO|WARNING|ERROR|CRITICAL] - - Returns: - int: value of the log level - see doctests below for mapping - if for some reason the level is not known return DEBUG (10) - - Examples: - - >>> print(_get_numeric_logger_level_from_string("NOTSET")) - 0 - >>> print(_get_numeric_logger_level_from_string("TRACE")) - 5 - >>> print(_get_numeric_logger_level_from_string("DEBUG")) - 10 - >>> print(_get_numeric_logger_level_from_string("INFO")) - 20 - >>> print(_get_numeric_logger_level_from_string("WARNING")) - 30 - >>> print(_get_numeric_logger_level_from_string("ERROR")) - 40 - >>> print(_get_numeric_logger_level_from_string("CRITICAL")) - 50 - >>> print(_get_numeric_logger_level_from_string("FOO_BAR")) - 10 - - """ - - if level == "NOTSET": - return 0 - elif level == "TRACE": - return 5 - elif level == "DEBUG": - return 10 - elif level == "INFO": - return 20 - elif level == "WARNING": - return 30 - elif level == "ERROR": - return 40 - elif level == "CRITICAL": - return 50 - else: - return 10 - # EOF diff --git a/pyotrs/pyotrs.py b/pyotrs/pyotrs.py deleted file mode 100644 index 62f694ad673ef5b532fd4859eb7c5fca6d3756f5..0000000000000000000000000000000000000000 --- a/pyotrs/pyotrs.py +++ /dev/null @@ -1,638 +0,0 @@ -# -*- coding: utf-8 -*- -"""Python wrapper for OTRS (using REST API) -Name: pyotrs.py -Description: PyOTRS - -Author: robert.habermann@dlh.de -Date: 2015-07-20 -""" - -# Versioning -from .version import __version__ - -import os -import sys -import json -import time -import datetime -import logging - -# import pymisc - -import requests -from requests.packages.urllib3 import disable_warnings - -### turn of plattform insecurity warnings from urllib3 -disable_warnings() - -logger = logging.getLogger(__name__) - -### path to certificate bundle and set to environment -# ca_certs = os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir) + -# "/LufthansaCA.crt" -#ca_certs = os.path.abspath("LufthansaCA.crt") -ca_certs = os.path.abspath("/etc/ssl/certs/ca-certificates.crt") - -os.environ['REQUESTS_CA_BUNDLE'] = ca_certs -os.environ['CURL_CA_BUNDLE'] = ca_certs - -### disable any proxies -proxies = {"http": "", "https": "", "no": ""} - - -class PyOTRS(object): - """PyOTRS class""" - - def __init__(self, - baseurl, - webservicename, - username=None, - password=None, - session_id=None, - session_id_file="/tmp/.session_id.tmp", - https_verify=True): - - self.baseurl = baseurl - self.webservicename = webservicename - self.data = None - self.https_verify = https_verify - - # dummy initialization - self.data_type = None - self.data_json = None - - # if session_id is passed in with a value other than None - # ignore username and password and use session_id - # if session_id is None then restore or create a Session! - self.username = username - self.password = password - self.session_id_file = session_id_file - - if session_id == None: - self.restore_or_set_up_session() - else: - self.session_id = session_id - - # Session Handling - - def restore_or_set_up_session(self): - """ Try to restore Session ID from file otherwise create new one - - """ - - # try to read session id from file - if self._read_session_id_from_file(): - # got one.. check whether it's still valid - if self._check_is_valid_session_id(): - logger.debug("Using valid Session ID from file (" + self.session_id_file + ")") - return True - - # got no (valid) Session ID from file.. try to create new one - if self.create_session(): - # safe new Session ID to file - if self._write_session_id_to_file(): - logger.debug("Saved new Session ID to file: " + self.session_id_file) - return True - else: - logger.error("Failed to save Session ID to file: " + self.session_id_file) - # pymisc.send_message_via_mail(subject="OTRS PyOTRS - Error - Failed to save - # Session ID!") - sys.exit(1) - else: - logger.error("Failed to create a Session ID!") - # pymisc.send_message_via_mail(subject="OTRS PyOTRS - Error - Failed to create a - # Session ID!") - sys.exit(1) - - def _check_is_valid_session_id(self, session_id=None): - """ check whether given Session ID is still valid - - Args: - session_id (str): A string containing the OTRS Session ID (default stored ID - from obj) - - """ - if session_id == None: - session_id = self.session_id - - return self.get_json_ticket_data_by_ticket_id(1, DynamicFields=0, AllArticles=0) - - def _read_session_id_from_file(self): - """ Retrieve a stored Session ID from file - - """ - if os.path.isfile(self.session_id_file): - with open(self.session_id_file, 'r') as f: - data = f.read() - self.session_id = data - return True - - return False - - def _write_session_id_to_file(self): - """ Write and store a Session ID to file - - Todo: - Error Handling and return True/False - - """ - - with open(self.session_id_file, 'w') as f: - f.write(self.session_id) - return True - - return False - - def create_session(self): - """ create new OTRS Session and store Session ID - - """ - - url = self.baseurl + "/otrs/nph-genericinterface.pl/Webservice/" + \ - self.webservicename + "/Session" - - payload = { - 'UserLogin': self.username, - 'Password' : self.password - } - - try: - self.data = requests.post(url, params=payload, proxies=proxies, - verify=self.https_verify) - - except requests.exceptions.RequestException as e: - print("Requests Exception: {}".format(e)) - sys.exit(1) - - try: - self.data_json = json.loads(self.data.content.decode()) - self.session_id = self.data_json['SessionID'] - return True - except Exception as e: - print("JSON Parse Exception: {}".format(e)) - sys.exit(1) - - - ### Gets (GenericInterface::Operation::Ticket::TicketGet) - - def _get_json_ticket_data(self, url, payload): - ''' helper function - _get_json_ticket_data - url [str] - payload [dict] - ''' - - try: - self.data = requests.get(url, proxies=proxies, params=payload, - verify=self.https_verify) - - # Just assume that we get valid JSON - self.data_json = json.loads(self.data.content.decode()) - logger.debug(self.data_json) - - if self.data_json.get('Ticket') is not None: - self.data_type = 'Ticket' - elif self.data_json.get('Error') is not None: - self.data_type = 'Error' - elif self.data_json.get('Session') is not None: - self.data_type = 'Session' - else: - logger.error('Unkown key in response JSON DICT!') - # critical error: Unknown response from OTRS API - FAIL NOW! - sys.exit(1) - logger.debug('Type was set to: ' + self.data_type) - - get_request_result_bool = True - - # critical error: HTTP request resulted in an error! - except Exception as e: - logger.error('Error with http communication: %s', e) - logger.error( - "Failed to access OTRS HTTP. Check Hostname, Proxy, SSL Certificate...!") - - get_request_result_bool = False - raise Exception('get http') - - # critical error: OTRS API sent an error! - if self.data_type == "Error": - logger.error(self.data_json['Error']) - logger.error( - "Failed to access OTRS API. Check Username and Password! Session ID expired?! " - "Does requested Ticket exist?") - get_request_result_bool = False - raise Exception('get api') - - _df_dict = {} - - _df_name_value_list = self.data_json['Ticket'][0]['DynamicField'] - for _df_name_value in _df_name_value_list: - _df_dict[_df_name_value['Name']] = _df_name_value['Value'] - - self.ticket_dynamic_fields = _df_dict - - return get_request_result_bool - - - def get_json_ticket_data_by_ticket_id(self, ticket_id, DynamicFields=1, AllArticles=0): - """ get_json_ticket_data_by_ticket_id - DynamicFields [0|1] will request OTRS to include all Dynamic Fields. Defaults to on - AllArticles [0|1] will request OTRS to include all Articles. Defaults to off - - Args: - ticket_id (int): Integer value of a Ticket ID - DynamicFields (int): will request OTRS to include all Dynamic Fields (default: 1) - AllArticles (int): will request OTRS to include all Articles (default: 0) - - Returns: - bool [true|false] - failed or successful - - """ - - url = self.baseurl + "/otrs/nph-genericinterface.pl/Webservice/" + self.webservicename +\ - "/Ticket/" + str( - ticket_id) - - payload = { - 'SessionID' : self.session_id, - 'AllArticles' : AllArticles, - 'DynamicFields': DynamicFields - } - - try: - return self._get_json_ticket_data(url, payload) - except: - return False - - - ### Updates (GenericInterface::Operation::Ticket::TicketUpdate) - - def _update_by_ticket_id(self, url, payload): - ''' update_by_ticket_id - url [str] - payload [dict] - ''' - - try: - self.data = requests.patch(url, proxies=proxies, data=json.dumps(payload), - verify=self.https_verify) - logger.debug("Received HTTP Status Code: " + str(self.data.status_code)) - logger.debug(self.data.content) - - # Just assume that we get valid JSON - self.data_json = json.loads(self.data.content.decode()) - # logger.debug(self.data_json) - - if self.data_json.get('Error') is not None: - self.data_type = 'Error' - elif self.data_json.get('TicketID') is not None: - self.data_type = 'TicketID' - else: - logger.error('Unkown key in response JSON DICT!') - patch_request_result_bool = False - logger.debug('Type was set to: ' + self.data_type) - - patch_request_result_bool = True - - # critical error: HTTP request resulted in an error! - except Exception as e: - logger.error('Error with http communication: %s', e) - logger.error( - "Failed to access OTRS HTTP. Check Hostname, Proxy, SSL Certificate and so on!") - - patch_request_result_bool = False - raise Exception('update http') - - # critical error: OTRS API sent an error! - if self.data_type == "Error": - logger.error(self.data_json['Error']) - logger.error( - "Failed to access OTRS API. Check Username and Password! Does requested Ticket " - "exist?") - - patch_request_result_bool = False - raise Exception('update api') - - return patch_request_result_bool - - - def update_by_ticket_id_set_title(self, ticket_id, title): - ''' update_by_ticket_id_set_scout_id - ticket_id [int] - title [str] - ''' - - url = self.baseurl + "/otrs/nph-genericinterface.pl/Webservice/" + self.webservicename +\ - "/Ticket/" + str( - ticket_id) - - payload = { - 'SessionID': self.session_id, - 'Ticket' : {'Title': title} - } - - logger.debug("Updating " + str(ticket_id) + " with: ") - logger.debug(json.dumps(payload)) - - try: - return self._update_by_ticket_id(url, payload) - except: - return False - - - def update_by_ticket_id_set_scout_id(self, ticket_id, scout_id): - ''' update_by_ticket_id_set_scout_id - ticket_id [int] - scout_id [str] - ''' - - url = self.baseurl + "/otrs/nph-genericinterface.pl/Webservice/" + self.webservicename +\ - "/Ticket/" + str( - ticket_id) - - payload = { - 'SessionID' : self.session_id, - 'DynamicField': {'Name': 'ScoutIM', 'Value': scout_id} - } - - logger.debug("Updating " + str(ticket_id) + " with: ") - logger.debug(json.dumps(payload)) - - try: - return self._update_by_ticket_id(url, payload) - except: - return False - - - def update_by_ticket_id_set_state(self, ticket_id, new_state="open"): - ''' update_by_ticket_id_set_scout_id - ticket_id [int] - new_state [str] default: "open" - ''' - - url = self.baseurl + "/otrs/nph-genericinterface.pl/Webservice/" + self.webservicename +\ - "/Ticket/" + str( - ticket_id) - - payload = { - 'SessionID': self.session_id, - 'Ticket' : {'State': new_state} - } - - logger.debug("Updating " + str(ticket_id) + " with: ") - logger.debug(json.dumps(payload)) - - try: - return self._update_by_ticket_id(url, payload) - except: - return False - - - def update_by_ticket_id_set_pending_state(self, ticket_id, new_state="pending reminder", - pending_days=1, pending_hours=0): - ''' update_by_ticket_id_set_scout_id - ticket_id [int] - state [str] - pending_days [int] default: 1 - pending_hours [int] default: 0 - ''' - - url = self.baseurl + "/otrs/nph-genericinterface.pl/Webservice/" + self.webservicename +\ - "/Ticket/" + str( - ticket_id) - - pending_time = time.gmtime( - time.time() + (pending_hours * 3600) + (pending_days * 3600 * 24)) - pending_time_str = { - "Year" : pending_time.tm_year, - "Month" : pending_time.tm_mon, - "Day" : pending_time.tm_mday, - "Hour" : pending_time.tm_hour, - "Minute": pending_time.tm_min - } - - payload = { - 'SessionID': self.session_id, - 'Ticket' : {'State': new_state, 'PendingTime': pending_time_str} - } - - logger.debug("Updating " + str(ticket_id) + " with: ") - logger.debug(json.dumps(payload)) - - try: - return self._update_by_ticket_id(url, payload) - except: - return False - - - def update_by_ticket_id_add_article(self, ticket_id, article_subject, article_body): - ''' update_by_ticket_id_set_scout_id - article_subject [str] - article_body [str] - ''' - - url = self.baseurl + "/otrs/nph-genericinterface.pl/Webservice/" + self.webservicename +\ - "/Ticket/" + str( - ticket_id) - - ### TODO ISO-8859-15 ? Oder UTF-8?! - payload = { - 'SessionID': self.session_id, - 'Article' : { - 'Subject' : article_subject, - 'Body' : article_body, - 'TimeUnit' : 0, - 'ContentType': 'text/plain; charset=ISO-8859-15' - } - } - - logger.debug("Updating " + str(ticket_id) + " with: ") - logger.debug(json.dumps(payload)) - - try: - return self._update_by_ticket_id(url, payload) - except: - return False - - - ### Searches (GenericInterface::Operation::Ticket::TicketSearch) - - def search_ticket(self, payload): - """Wrapper for search ticket - - Args: - payload (dict) - - Raises: - - - Returns: - True|False - - """ - - url = self.baseurl + "/otrs/nph-genericinterface.pl/Webservice/" + self.webservicename +\ - "/Ticket" - - return self._search_json_ticket_data(url, payload) - - - def _search_json_ticket_data(self, url, payload): - ''' helper function - _search_json_ticket_data - url [str] - payload [dict] - ''' - - headers = {'Content-Type': 'application/json'} - - json_payload = json.dumps(payload) - - try: - self.data = requests.get(url, proxies=proxies, data=json_payload, headers=headers, - verify=self.https_verify) - - # Just assume that we get valid JSON - self.data_json = json.loads(self.data.content.decode()) - logger.debug(self.data_json) - - if self.data_json.get('TicketID') is not None: - self.data_type = 'TicketID' - get_request_result_bool = True - else: - logger.debug('search found no results') - get_request_result_bool = False - - # critical error: HTTP request resulted in an error! - except Exception as e: - logger.error('Error with http communication: %s', e) - logger.error( - "Failed to access OTRS HTTP. Check Hostname, Proxy, SSL Certificate and so on!") - - get_request_result_bool = False - raise Exception('get http') - - # critical error: OTRS API sent an error! - if self.data_type == "Error": - logger.error(self.data_json['Error']) - logger.error( - "Failed to access OTRS API. Check Username and Password! Session ID expired?! " - "Does requested Ticket exist?") - get_request_result_bool = False - raise Exception('get api') - - return get_request_result_bool - - - def _minutes_since_midnight(self, now_obj): - seconds_since_midnight = ( - now_obj - now_obj.replace(hour=0, minute=0, second=0, microsecond=0)).total_seconds() - minutes_since_midnight = int(seconds_since_midnight / 60) - return minutes_since_midnight - - - def get_ticket_id_list_by_past_days(self, from_past_day=1, days=1, DynamicFields=1, - AllArticles=0): - """Search for tickets that where changed in a certain timeframe in the - past. Result is stored in object. This method returns True|False. - - Args: - from_past_day (int): day in the past to start from (e.g. 1 for yesterday) - days (int): day in the past (or today) where to end - DynamicFields (int): will request OTRS to include all Dynamic Fields (default: 1) - AllArticles (int): will request OTRS to include all Articles (default: 0) - - Notes: - from_past_day defaults to 1 - days defaults to 1 - This means that the ticket list will contain tickets between - yesteray 00:00:00 and yesterday 23:59:59. - e.g. use 0, 1 for today - e.g. use 1, 1 for yesterday - e.g. use 2, 1 for day before yesterday - e.g. use 8, 7 for last 7 days - e.g. on a Monday use 3, 1 to get tickets from last Friday - - Returns: - bool [true|false] - failed or successful - - """ - - url = self.baseurl + "/otrs/nph-genericinterface.pl/Webservice/" + self.webservicename +\ - "/Ticket" - - minute_offset = self._minutes_since_midnight(datetime.datetime.now()) - - # from_past_day = 0 means today (from 0:00:00 till now) - if from_past_day == 0: - newer = minute_offset - older = 0 - else: - newer = from_past_day * 1440 + minute_offset - older = newer - 1440 * days - - payload = { - 'SessionID' : self.session_id, - 'TicketLastChangeTimeNewerMinutes': newer, - 'TicketLastChangeTimeOlderMinutes': older - } - - logger.debug(payload) - - try: - return self._search_json_ticket_data(url, payload) - except Exception: - return False - - -def _get_numeric_logger_level_from_string(level): - """Parse string and return appropriate numeric logger level - - Args: - level (str): the string representation of a logging level. - Level is one of these: [NOTSET|TRACE|DEBUG|INFO|WARNING|ERROR|CRITICAL] - - Returns: - int: value of the log level - see doctests below for mapping - if for some reason the level is not known return DEBUG (10) - - Examples: - - >>> print(_get_numeric_logger_level_from_string("NOTSET")) - 0 - >>> print(_get_numeric_logger_level_from_string("TRACE")) - 5 - >>> print(_get_numeric_logger_level_from_string("DEBUG")) - 10 - >>> print(_get_numeric_logger_level_from_string("INFO")) - 20 - >>> print(_get_numeric_logger_level_from_string("WARNING")) - 30 - >>> print(_get_numeric_logger_level_from_string("ERROR")) - 40 - >>> print(_get_numeric_logger_level_from_string("CRITICAL")) - 50 - >>> print(_get_numeric_logger_level_from_string("FOO_BAR")) - 10 - - """ - - if level == "NOTSET": - return 0 - elif level == "TRACE": - return 5 - elif level == "DEBUG": - return 10 - elif level == "INFO": - return 20 - elif level == "WARNING": - return 30 - elif level == "ERROR": - return 40 - elif level == "CRITICAL": - return 50 - else: - return 10 - -### EOF diff --git a/tests/test_doctests.py b/tests/test_doctests.py index 5b4128d9b9386a85a9d4a4a3713a5d886dae0d9d..3d3001588fccab11e0875528aa0bd73df2431d48 100644 --- a/tests/test_doctests.py +++ b/tests/test_doctests.py @@ -1,7 +1,8 @@ from doctest import DocTestSuite from unittest import TestSuite + def load_tests(loader, tests, pattern): suite = TestSuite() - suite.addTests(DocTestSuite('pyotrs.pyotrs')) + suite.addTests(DocTestSuite('pyotrs.client')) return suite diff --git a/tests/test_pyotrs.py b/tests/test_pyotrs.py index 52d78541229ed896755345521a53ae0e0957665a..440239511bf3987eacf2f35bf1197da914099b60 100644 --- a/tests/test_pyotrs.py +++ b/tests/test_pyotrs.py @@ -21,7 +21,8 @@ import responses from mock import MagicMock, patch from pyotrs import Client -from pyotrs import TicketCreate, TicketGet, TicketSearch, TicketUpdate +from pyotrs import NoBaseURL, NoWebServiceName, NoCredentials +from pyotrs import SessionCreateError, SessionIDFileError, OTRSAPIError, OTRSHTTPError class PyOTRSTests(unittest.TestCase): @@ -89,9 +90,9 @@ class PyOTRSTests(unittest.TestCase): 'DynamicFields': 1 } - obj = TicketGet(self.base_url, self.webservice_name, username, password) + obj = Client(self.base_url, self.webservice_name, username, password) - self.assertRaisesRegexp(Exception, 'get api', obj._get_json_ticket_data, url=url, + self.assertRaisesRegexp(OTRSAPIError, 'get api', obj._get_json_ticket_data, url=url, payload=payload) """ Test Responses: when calling: get_json_ticket_data_by_ticket_id - Test 200 OK; Body Error @@ -117,13 +118,13 @@ class PyOTRSTests(unittest.TestCase): username = "wrong_username" password = "wrong_password" - obj = TicketGet(self.base_url, self.webservice_name, username, password) + obj = Client(self.base_url, self.webservice_name, username, password) obj.ticket_get_by_id(1) # self.logger.debug(obj.data) self.assertEqual({"Error": {"ErrorMessage": "TicketGet: Authorization failing!", - "ErrorCode" : "TicketGet.AuthFail"}}, obj.data.json()) + "ErrorCode": "TicketGet.AuthFail"}}, obj.data.json()) self.assertEqual(200, obj.data.status_code) """ Test Responses: update title on valid ticket """ @@ -148,7 +149,7 @@ class PyOTRSTests(unittest.TestCase): username = "fake_username" password = "fake_password" - obj = TicketUpdate(self.base_url, self.webservice_name, username, password) + obj = Client(self.base_url, self.webservice_name, username, password) obj.ticket_update_set_title(10, "Full New Title") self.assertEqual({"TicketNumber": "1970010100000010", "TicketID": "10"}, obj.data.json()) @@ -176,10 +177,10 @@ class PyOTRSTests(unittest.TestCase): username = "fake_username" password = "fake_password" - obj = TicketUpdate(self.base_url, self.webservice_name, username, password) + obj = Client(self.base_url, self.webservice_name, username, password) obj.ticket_update_set_title(20, "Full New Title") - self.assertEqual({"Error": {"ErrorCode" : "TicketUpdate.AccessDenied", + self.assertEqual({"Error": {"ErrorCode": "TicketUpdate.AccessDenied", "ErrorMessage": "TicketUpdate: User does not have access to the ticket!"}}, obj.data.json()) self.assertEqual(200, obj.data.status_code) @@ -209,7 +210,7 @@ class PyOTRSTests(unittest.TestCase): } ### create object - obj = TicketGet(self.base_url, self.webservice_name, username, password) + obj = Client(self.base_url, self.webservice_name, username, password) ### enable Mock obj._get_json_ticket_data = MagicMock() @@ -241,7 +242,7 @@ class PyOTRSTests(unittest.TestCase): mock_username = "wrong_username" mock_password = "wrong_password" - obj = TicketGet(self.base_url, self.webservice_name, mock_username, mock_password) + obj = Client(self.base_url, self.webservice_name, mock_username, mock_password) with patch('requests.get') as patched_get: obj.ticket_get_by_id(1) diff --git a/tox.ini b/tox.ini index 1648f53d8436ebeba5da1bd66ffa7cc232c26082..4aa37ed695f1d5fb07f39732d225c19941dcdc6d 100644 --- a/tox.ini +++ b/tox.ini @@ -53,8 +53,8 @@ basepython = python2.7 commands = flake8 \ --max-complexity=15 \ - --exclude=./build,.venv,.tox,dist,doc \ - --ignore=F403 \ + --exclude=./build,.venv,.tox,dist,doc,test_pyotrs.py \ + --ignore=F403,Q000 \ --max-line-length=99 \ []