From 792845e1ac767a9858abe173368321881a521933 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Mon, 22 Mar 2021 14:39:11 -0400 Subject: [PATCH 01/20] peter's initial changes --- specification/zendesk/routing_attribute.json | 7 + .../zendesk/routing_attribute_value.json | 7 + tools/gen_classes.py | 23 +- zenpy/__init__.py | 3 +- zenpy/gen_classes.py | 447 + zenpy/lib/api.py | 35 +- zenpy/lib/api_objects/__init__.py | 12662 ++++++++-------- zenpy/lib/api_objects/chat_objects.py | 2254 +-- zenpy/lib/api_objects/help_centre_objects.py | 3712 ++--- zenpy/lib/api_objects/talk_objects.py | 1210 +- zenpy/lib/endpoint.py | 3 + zenpy/lib/mapping.py | 4 +- zenpy/lib/response.py | 23 + 13 files changed, 10507 insertions(+), 9883 deletions(-) create mode 100644 specification/zendesk/routing_attribute.json create mode 100644 specification/zendesk/routing_attribute_value.json create mode 100644 zenpy/gen_classes.py diff --git a/specification/zendesk/routing_attribute.json b/specification/zendesk/routing_attribute.json new file mode 100644 index 00000000..cfa50434 --- /dev/null +++ b/specification/zendesk/routing_attribute.json @@ -0,0 +1,7 @@ +{ + "url": "https://facetoe1.zendesk.com/api/v2/routing/attributes/15821cba-7326-11e8-b07e-950ba849aa27.json", + "created_at": "2017-12-01T19:29:31Z", + "updated_at": "2017-12-01T19:29:31Z", + "id": "15821cba-7326-11e8-b07e-950ba849aa27", + "name": "Language" +} \ No newline at end of file diff --git a/specification/zendesk/routing_attribute_value.json b/specification/zendesk/routing_attribute_value.json new file mode 100644 index 00000000..3a49e1e4 --- /dev/null +++ b/specification/zendesk/routing_attribute_value.json @@ -0,0 +1,7 @@ +{ + "url": "https://facetoe1.zendesk.com/api/v2/routing/attributes/15821cba-7326-11e8-b07e-950ba849aa27.json", + "created_at": "2017-12-01T19:29:31Z", + "updated_at": "2017-12-01T19:29:31Z", + "id": "b376b35a-e38b-11e8-a292-e3b6377c5575", + "name": "French" +} \ No newline at end of file diff --git a/tools/gen_classes.py b/tools/gen_classes.py index 7a850299..74dbd2a5 100755 --- a/tools/gen_classes.py +++ b/tools/gen_classes.py @@ -433,14 +433,15 @@ def process_specification_directory(glob_pattern, outfile_name, namespace, write out_file.write("\n\n\n".join((header, formatted_code))) -process_specification_directory('zendesk/*.json', 'api_objects/__init__.py', - namespace='core') -process_specification_directory('chat/*.json', 'api_objects/chat_objects.py', - namespace='chat', - write_baseclass=False) -process_specification_directory('help_centre/*.json', 'api_objects/help_centre_objects.py', - namespace='help_center', - write_baseclass=False) -process_specification_directory('talk/*.json', 'api_objects/talk_objects.py', - namespace='core', - write_baseclass=False) +if __name__ == '__main__': + process_specification_directory('zendesk/*.json', 'api_objects/__init__.py', + namespace='core') + process_specification_directory('chat/*.json', 'api_objects/chat_objects.py', + namespace='chat', + write_baseclass=False) + process_specification_directory('help_centre/*.json', 'api_objects/help_centre_objects.py', + namespace='help_center', + write_baseclass=False) + process_specification_directory('talk/*.json', 'api_objects/talk_objects.py', + namespace='core', + write_baseclass=False) diff --git a/zenpy/__init__.py b/zenpy/__init__.py index 4d0a21ae..5eb89abb 100644 --- a/zenpy/__init__.py +++ b/zenpy/__init__.py @@ -38,7 +38,7 @@ TalkApi, CustomAgentRolesApi, SearchApi, - UserFieldsApi, + UserFieldsApi, RoutingAttributesApi ) from zenpy.lib.cache import ZenpyCache, ZenpyCacheManager @@ -162,6 +162,7 @@ def __init__( self.custom_agent_roles = CustomAgentRolesApi( config, object_type="custom_agent_role" ) + self.routing_attributes = RoutingAttributesApi(config) @staticmethod def http_adapter_kwargs(): diff --git a/zenpy/gen_classes.py b/zenpy/gen_classes.py new file mode 100644 index 00000000..74dbd2a5 --- /dev/null +++ b/zenpy/gen_classes.py @@ -0,0 +1,447 @@ +#!/usr/bin/env python +import functools +import glob +import json +import re +import sys +from multiprocessing.pool import Pool +from optparse import OptionParser + +import os +from yapf.yapflib.yapf_api import FormatCode + +__author__ = 'facetoe' +from jinja2 import Template + + +class TemplateObject(object): + OBJECT_TEMPLATE = None + + def render(self): + return Template(self.OBJECT_TEMPLATE).render(object=self) + + +class Class(TemplateObject): + OBJECT_TEMPLATE = ''' +class {{object.name}}(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + {{-object.init.render()-}} + {{-object.properties.render()-}} + + +''' + + def __init__(self, name, _json, doc_json): + attributes = [] + object_name = to_snake_case(name).lower() + 's' + + for attr_name, attr in iter(sorted(_json.items())): + attribute = Attribute(attr_name=attr_name, attr_value=attr, parent_object=to_snake_case(name).lower()) + if object_name in doc_json and attr_name in doc_json[object_name]: + doc_strings = [] + attr_docs = doc_json[object_name][attr_name] + if attr_docs['type'] not in ('string', 'boolean', 'date', 'integer', 'array', 'object', 'timestamp'): + attr_docs['type'] = ':class:`%s`' % attr_docs['type'] + + for key, value in sorted(attr_docs.items()): + doc_strings.append("%s: %s" % (key.capitalize(), value.replace('*', ''))) + attribute.attr_docs = doc_strings + attributes.append(attribute) + + attributes = sorted(attributes, key=lambda x: x.attr_name) + self.name = name + self.init = Init(attributes) + self.properties = Properties(attributes) + + +class Init(TemplateObject): + OBJECT_TEMPLATE = """ + {% if object.init_params %} + def __init__(self, api=None, {{ object.init_params }}, **kwargs): + {% else %} + def __init__(self, api=None, **kwargs): + {% endif %} + self.api = api + {% for attr in object.attributes -%} + {% if attr.attr_docs and attr.attr_name %} + {% for docline in attr.attr_docs %} + # {{ docline-}} + {% endfor %} + {% endif -%} + {% if attr.attr_name and not attr.attr_name.startswith('_') -%} + self.{{attr.attr_name}} = {{attr.attr_name}} + {% elif attr.attr_name %} + self.{{attr.attr_name}} = None + {% endif -%} + {% endfor %} + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + """ + + def __init__(self, attributes): + self.attributes = attributes + self.init_params = ", ".join( + ["{}=None".format(a.attr_name) + for a in attributes + if not a.attr_name.startswith('_') and a.attr_name]) + self.attributes = attributes + + +class Properties(TemplateObject): + OBJECT_TEMPLATE = """ + {%- for prop in object.properties -%} + {{- prop.render() -}} + {% endfor %} + """ + + def __init__(self, attributes): + self.properties = [Property(a) for a in attributes] + + +class Property(TemplateObject): + OBJECT_TEMPLATE = """ + {%- if object.attribute.is_property -%} + @property + def {{object.attribute.object_name}}(self): + {% if object.attribute.attr_docs -%} + \"\"\" + | {{ object.attribute.attr_docs[0] }} + \"\"\" + {%- endif -%} + {{- object.prop_body -}} + + @{{object.attribute.object_name}}.setter + def {{object.attribute.object_name}}(self, {{object.attribute.object_name}}): + {{- object.prop_setter_body -}} + {%- endif -%} + + """ + + DATE_TEMPLATE = """ + if self.{{object.attribute.key}}: + return dateutil.parser.parse(self.{{object.attribute.key}}) + """ + + PROPERTY_TEMPLATE = """ + if self.api and self.{{object.attribute.attr_name}}: + return self.api._get_{{object.attribute.object_type}}(self.{{object.attribute.attr_name}}) + """ + + SETTER_TEMPLATE_ASSIGN = """ + if {{object.attribute.object_name}}: + self.{{object.attribute.attr_name}} = {{object.attribute.attr_assignment}} + self._{{object.attribute.object_name}} = {{object.attribute.object_name}} + """ + + SETTER_TEMPLATE_OBJECT_DEFAULT = """ + if {{object.attribute.object_name}}: + self._{{object.attribute.object_name}} = {{object.attribute.object_name}} + """ + + SETTER_TEMPLATE_DEFAULT = """ + if {{object.attribute.object_name}}: + self.{{object.attribute.attr_name}} = {{object.attribute.object_name}} + """ + + def __init__(self, attribute): + self.attribute = attribute + self.prop_name = attribute.object_name + self.prop_body = self.get_prop_body(attribute) + self.prop_setter_body = self.get_prop_setter_body(attribute) + + def get_prop_body(self, attribute): + if attribute.object_type == 'date': + template = self.DATE_TEMPLATE + else: + template = self.PROPERTY_TEMPLATE + + return Template(template).render(object=self, trim_blocks=True) + + def get_prop_setter_body(self, attribute): + if attribute.attr_assignment: + template = self.SETTER_TEMPLATE_ASSIGN + elif attribute.object_name in ('phone_number'): + template = self.SETTER_TEMPLATE_OBJECT_DEFAULT + else: + template = self.SETTER_TEMPLATE_DEFAULT + return Template(template).render(object=self, trim_blocks=True) + + +class Attribute(object): + def __init__(self, parent_object, attr_name, attr_value, attr_docs=None): + if attr_name == 'from': + attr_name = 'from_' + + self.parent_object = parent_object + self.key = '_{}'.format(attr_name) if attr_name.endswith('timestamp') else attr_name + self.attr_docs = attr_docs + self.object_type = self.get_object_type(attr_name, attr_value) + self.object_name = self.get_object_name(attr_name, attr_value) + self.attr_name = self.get_attr_name(attr_name=attr_name, attr_type=self.object_type) + self.attr_assignment = self.get_attr_assignment(self.object_name, self.object_type, attr_name) + self.is_property = self.get_is_property(attr_name) + + def get_object_type(self, attr_name, attr_value): + if attr_name in ('assignee_id', 'submitter_id', 'requester_id', + 'author_id', 'updater_id', 'recipient_id', + 'created_by_id', 'updated_by_id'): + object_type = 'user' + elif attr_name in ('photo',): + object_type = 'attachment' + elif attr_name.endswith('time_in_minutes'): + object_type = 'ticket_metric_item' + elif attr_name in ('recipients', 'collaborator_ids'): + object_type = 'users' + elif attr_name in ('forum_topic_id',): + object_type = 'topic' + elif (attr_name.endswith('_at') or attr_name.endswith('timestamp')) and not isinstance(attr_value, int): + object_type = 'date' + else: + object_type = attr_name.replace('_id', '') + + return object_type + + def get_attr_name(self, attr_type, attr_name): + should_modify = attr_name.endswith('timestamp') and attr_type != 'timestamp' + if should_modify: + return "_%s" % attr_name + else: + return attr_name + + def get_attr_assignment(self, object_name, object_type, key): + if object_type not in (key, 'date') and object_name not in ('phone_number') and key.endswith('_id'): + return '%s.id' % object_name + elif key.endswith('_ids'): + return '[o.id for o in %(object_name)s]' % locals() + + def get_object_name(self, attr_name, attr_value): + if attr_name == 'locale_id': + return attr_name + for replacement in ('_at', '_id'): + if attr_name.endswith(replacement): + return attr_name.replace(replacement, '') + elif attr_name.endswith('_ids'): + return "%ss" % attr_name.replace('_ids', '') + return attr_name + + def get_is_property(self, attr_name): + if attr_name in ('locale_id', 'external_id', 'graph_object_id', + 'agreement_id', 'content_id', 'item_id', 'source_id', 'community_id', + 'issue_id', 'instance_id'): + return False + elif self.parent_object == 'skip' and attr_name in ('ticket', 'ticket_id'): + return False + if attr_name.endswith('_id') or attr_name.endswith('_ids'): + return True + elif self.object_type == 'date': + return True + return False + + def __str__(self): + return "[is_prop=%(is_property)s, " \ + "key=%(key)s, " \ + "obj_type=%(object_type)s, " \ + "obj_name=%(object_name)s, " \ + "attr_name=%(attr_name)s, " \ + "assn=%(attr_assignment)s]" \ + "attr_doc=%(attr_docs)s " % self.__dict__ + + def __repr__(self): + return self.__str__() + + +def to_snake_case(name): + s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name) + return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower() + + +BASE_CLASS = ''' +###################################################################### +# Do not modify, these classes are autogenerated by gen_classes.py # +###################################################################### + +import json +import dateutil.parser +from zenpy.lib.util import json_encode_for_printing, json_encode_for_zendesk + + +class BaseObject(object): + """ + Base for all Zenpy objects. Keeps track of which attributes have been modified. + """ + + def __new__(cls, *args, **kwargs): + instance = super(BaseObject, cls).__new__(cls) + instance.__dict__['_dirty_attributes'] = set() + instance.__dict__['_dirty_callback'] = None + instance.__dict__['_always_dirty'] = set() + return instance + + def __setattr__(self, key, value): + if key not in ('_dirty', '_dirty_callback', '_always_dirty'): + self.__dict__['_dirty_attributes'].add(key) + if self._dirty_callback is not None: + self._dirty_callback() + object.__setattr__(self, key, value) + + def _clean_dirty(self, obj=None): + """ Recursively clean self and all child objects. """ + obj = obj or self + obj.__dict__['_dirty_attributes'].clear() + obj._dirty = False + for key, val in vars(obj).items(): + if isinstance(val, BaseObject): + self._clean_dirty(val) + else: + func = getattr(val, '_clean_dirty', None) + if callable(func): + func() + + def _set_dirty(self, obj=None): + """ Recursively set self and all child objects _dirty flag. """ + obj = obj or self + for key, value in vars(obj).items(): + if key not in ('api', '_dirty_attributes', '_always_dirty', '_dirty_callback', '_dirty'): + setattr(obj, key, value) + if isinstance(value, BaseObject): + self._set_dirty(value) + + def to_json(self, indent=2): + """ Return self formatted as JSON. """ + return json.dumps(self, default=json_encode_for_printing, indent=indent) + + def to_dict(self, serialize=False): + """ + This method returns the object as a Python dict. If serialize is passed, only those attributes + that have been modified will be included in the result. + """ + if serialize: + encode_method = json_encode_for_zendesk + else: + encode_method = json_encode_for_printing + return json.loads(json.dumps(self._to_dict(serialize=serialize), default=encode_method)) + + def _to_dict(self, serialize=False): + """ + This method works by copying self.__dict__, and removing everything that should not be serialized. + """ + copy_dict = self.__dict__.copy() + for key, value in vars(self).items(): + # We want to send all ids to Zendesk always + if serialize and key == 'id': + continue + + # If this is a Zenpy object, convert it to a dict. + if not serialize and isinstance(value, BaseObject): + copy_dict[key] = copy_dict.pop(key).to_dict() + + # This object has a flag indicating it has been dirtied, so we want to send it off. + elif serialize and getattr(value, '_dirty', False): + continue + + # Here we have an attribute that should always be sent to Zendesk. + elif serialize and key in self._always_dirty: + continue + + # These are for internal tracking, so just delete. + elif key in ('api', '_dirty_attributes', '_always_dirty', '_dirty_callback', '_dirty'): + del copy_dict[key] + + # If the attribute has not been modified, do not send it. + elif serialize and key not in self._dirty_attributes: + del copy_dict[key] + + # Some reserved words are prefixed with an underscore, remove it here. + elif key.startswith('_'): + copy_dict[key[1:]] = copy_dict[key] + del copy_dict[key] + return copy_dict + + def __repr__(self): + class_name = type(self).__name__ + if class_name in ('UserField',): + return "{}()".format(class_name) + + def formatted(item): + return item if (isinstance(item, int) or item is None) else "'{}'".format(item) + + for identifier in ('id', 'token', 'key', 'name', 'account_key'): + if hasattr(self, identifier): + return "{}({}={})".format(class_name, identifier, formatted(getattr(self, identifier))) + return "{}()".format(class_name)''' + +parser = OptionParser() + +parser.add_option("--spec-path", "-s", dest="spec_path", + help="Location of .json spec", metavar="SPEC_PATH") +parser.add_option("--doc-json", "-d", dest="doc_json_path", + help="Location of .json documentation file", metavar="DOC_JSON") +parser.add_option("--out-path", "-o", dest="out_path", + help="Where to put generated classes", + metavar="OUT_PATH", + default=os.getcwd()) + +(options, args) = parser.parse_args() + +if not options.spec_path: + print("--spec-path is required!") + sys.exit() +elif not os.path.isdir(options.spec_path): + print("--spec-path must be a directory!") + sys.exit() +elif not options.doc_json_path: + print("--doc-json is required!") + sys.exit() + +doc_json = json.load(open(options.doc_json_path)) + + +def process_file(namespace, path): + class_name = os.path.basename(os.path.splitext(path)[0]).capitalize() + class_name = "".join([w.capitalize() for w in class_name.split('_')]) + with open(path) as f: + class_code = Class(class_name, json.load(f), doc_json[namespace]).render() + print("Processed: %s -> %s" % (os.path.basename(path), class_name)) + return class_code + + +def process_specification_directory(glob_pattern, outfile_name, namespace, write_baseclass=True,): + with open(os.path.join(options.out_path, outfile_name), 'w+') as out_file: + paths = [p for p in glob.glob(os.path.join(options.spec_path, glob_pattern))] + classes = list() + + func = functools.partial(process_file, namespace) + with Pool() as pool: + classes.extend(pool.map(func, paths)) + print("Formatting...") + formatted_code = FormatCode("\n".join(sorted(classes)))[0] + if write_baseclass: + header = BASE_CLASS + else: + header = "from zenpy.lib.api_objects import BaseObject\nimport dateutil.parser" + + out_file.write("\n\n\n".join((header, formatted_code))) + +if __name__ == '__main__': + process_specification_directory('zendesk/*.json', 'api_objects/__init__.py', + namespace='core') + process_specification_directory('chat/*.json', 'api_objects/chat_objects.py', + namespace='chat', + write_baseclass=False) + process_specification_directory('help_centre/*.json', 'api_objects/help_centre_objects.py', + namespace='help_center', + write_baseclass=False) + process_specification_directory('talk/*.json', 'api_objects/talk_objects.py', + namespace='core', + write_baseclass=False) diff --git a/zenpy/lib/api.py b/zenpy/lib/api.py index 0322ad44..6257e9ae 100644 --- a/zenpy/lib/api.py +++ b/zenpy/lib/api.py @@ -61,6 +61,7 @@ def __init__(self, subdomain, session, timeout, ratelimit, CombinationResponseHandler, ViewResponseHandler, SlaPolicyResponseHandler, + RoutingAttributesResponseHandler, RequestCommentResponseHandler, GenericZendeskResponseHandler, HTTPOKResponseHandler, @@ -239,7 +240,7 @@ def _serialize(self, zenpy_object): return json.loads( json.dumps(zenpy_object, default=json_encode_for_zendesk)) - def _query_zendesk(self, endpoint, object_type, *endpoint_args, + def _query_zendesk(self, endpoint, object_type, raw_response, *endpoint_args, **endpoint_kwargs): """ Query Zendesk for items. If an id or list of ids are passed, attempt to locate these items @@ -261,7 +262,7 @@ def _query_zendesk(self, endpoint, object_type, *endpoint_args, return item else: return self._get(url=self._build_url( - endpoint(*endpoint_args, **endpoint_kwargs))) + endpoint(*endpoint_args, **endpoint_kwargs)), raw_response=raw_response) elif 'ids' in endpoint_kwargs: cached_objects = [] # Check to see if we have all objects in the cache. @@ -272,7 +273,7 @@ def _query_zendesk(self, endpoint, object_type, *endpoint_args, if not obj: return self._get( self._build_url(endpoint=endpoint( - *endpoint_args, **endpoint_kwargs))) + *endpoint_args, **endpoint_kwargs)), raw_response=raw_response) cached_objects.append(obj) return ZendeskResultGenerator(self, {}, response_objects=cached_objects, @@ -280,7 +281,7 @@ def _query_zendesk(self, endpoint, object_type, *endpoint_args, else: return self._get( self._build_url( - endpoint=endpoint(*endpoint_args, **endpoint_kwargs))) + endpoint=endpoint(*endpoint_args, **endpoint_kwargs)), raw_response=raw_response) def _check_response(self, response): """ @@ -345,8 +346,8 @@ def __init__(self, config, object_type, endpoint=None): super(Api, self).__init__(**config) self._object_mapping = ZendeskObjectMapping(self) - def __call__(self, *args, **kwargs): - return self._query_zendesk(self.endpoint, self.object_type, *args, + def __call__(self, raw_response=False, *args, **kwargs): + return self._query_zendesk(self.endpoint, self.object_type, raw_response, *args, **kwargs) def _get_user(self, user_id): @@ -428,6 +429,11 @@ def _get_view(self, view_id): 'view', id=view_id) + def _get_routing_attribute(self, attribute_id): + return self._query_zendesk(EndpointFactory('attributes'), + 'attribute', + id=attribute_id) + def _get_topic(self, forum_topic_id): return self._query_zendesk(EndpointFactory('help_centre').topics, 'topic', @@ -1829,6 +1835,23 @@ def make_default(self, user, group_membership): return self._put(self._build_url( self.endpoint.make_default(user, group_membership)), payload={}) + + +class RoutingAttributesApi(CRUDApi): + def __init__(self, config): + super(RoutingAttributesApi, self).__init__(config, object_type='attribute') + + def values(self, attribute_id): + """ + Return all attribute values for attribute. + """ + return self._get(self._build_url(self.endpoint.values(id=attribute_id))) + + def value(self, attribute_id, value_id): + """ + Return specified attribute value for attribute. + """ + return self._get(self._build_url(self.endpoint.value(id=attribute_id))) class JiraLinkApi(CRUDApi): diff --git a/zenpy/lib/api_objects/__init__.py b/zenpy/lib/api_objects/__init__.py index 2a8e4e7e..0358d5e7 100644 --- a/zenpy/lib/api_objects/__init__.py +++ b/zenpy/lib/api_objects/__init__.py @@ -1,6276 +1,6386 @@ - -###################################################################### -# Do not modify, these classes are autogenerated by gen_classes.py # -###################################################################### - -import json -import dateutil.parser -from zenpy.lib.util import json_encode_for_printing, json_encode_for_zendesk - - -class BaseObject(object): - """ - Base for all Zenpy objects. Keeps track of which attributes have been modified. - """ - - def __new__(cls, *args, **kwargs): - instance = super(BaseObject, cls).__new__(cls) - instance.__dict__['_dirty_attributes'] = set() - instance.__dict__['_dirty_callback'] = None - instance.__dict__['_always_dirty'] = set() - return instance - - def __setattr__(self, key, value): - if key not in ('_dirty', '_dirty_callback', '_always_dirty'): - self.__dict__['_dirty_attributes'].add(key) - if self._dirty_callback is not None: - self._dirty_callback() - object.__setattr__(self, key, value) - - def _clean_dirty(self, obj=None): - """ Recursively clean self and all child objects. """ - obj = obj or self - obj.__dict__['_dirty_attributes'].clear() - obj._dirty = False - for key, val in vars(obj).items(): - if isinstance(val, BaseObject): - self._clean_dirty(val) - else: - func = getattr(val, '_clean_dirty', None) - if callable(func): - func() - - def _set_dirty(self, obj=None): - """ Recursively set self and all child objects _dirty flag. """ - obj = obj or self - for key, value in vars(obj).items(): - if key not in ('api', '_dirty_attributes', '_always_dirty', '_dirty_callback', '_dirty'): - setattr(obj, key, value) - if isinstance(value, BaseObject): - self._set_dirty(value) - - def to_json(self, indent=2): - """ Return self formatted as JSON. """ - return json.dumps(self, default=json_encode_for_printing, indent=indent) - - def to_dict(self, serialize=False): - """ - This method returns the object as a Python dict. If serialize is passed, only those attributes - that have been modified will be included in the result. - """ - if serialize: - encode_method = json_encode_for_zendesk - else: - encode_method = json_encode_for_printing - return json.loads(json.dumps(self._to_dict(serialize=serialize), default=encode_method)) - - def _to_dict(self, serialize=False): - """ - This method works by copying self.__dict__, and removing everything that should not be serialized. - """ - copy_dict = self.__dict__.copy() - for key, value in vars(self).items(): - # We want to send all ids to Zendesk always - if serialize and key == 'id': - continue - - # If this is a Zenpy object, convert it to a dict. - if not serialize and isinstance(value, BaseObject): - copy_dict[key] = copy_dict.pop(key).to_dict() - - # This object has a flag indicating it has been dirtied, so we want to send it off. - elif serialize and getattr(value, '_dirty', False): - continue - - # Here we have an attribute that should always be sent to Zendesk. - elif serialize and key in self._always_dirty: - continue - - # These are for internal tracking, so just delete. - elif key in ('api', '_dirty_attributes', '_always_dirty', '_dirty_callback', '_dirty'): - del copy_dict[key] - - # If the attribute has not been modified, do not send it. - elif serialize and key not in self._dirty_attributes: - del copy_dict[key] - - # Some reserved words are prefixed with an underscore, remove it here. - elif key.startswith('_'): - copy_dict[key[1:]] = copy_dict[key] - del copy_dict[key] - return copy_dict - - def __repr__(self): - class_name = type(self).__name__ - if class_name in ('UserField',): - return "{}()".format(class_name) - - def formatted(item): - return item if (isinstance(item, int) or item is None) else "'{}'".format(item) - - for identifier in ('id', 'token', 'key', 'name', 'account_key'): - if hasattr(self, identifier): - return "{}({}={})".format(class_name, identifier, formatted(getattr(self, identifier))) - return "{}()".format(class_name) - - -class Activity(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - actor=None, - created_at=None, - id=None, - title=None, - updated_at=None, - url=None, - user=None, - verb=None, - **kwargs): - - self.api = api - self.actor = actor - self.created_at = created_at - self.id = id - self.title = title - self.updated_at = updated_at - self.url = url - self.user = user - self.verb = verb - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class AgentMacroReference(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - id=None, - macro_id=None, - macro_title=None, - type=None, - via=None, - **kwargs): - - self.api = api - self.id = id - self.macro_id = macro_id - self.macro_title = macro_title - self.type = type - self.via = via - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def macro(self): - - if self.api and self.macro_id: - return self.api._get_macro(self.macro_id) - - @macro.setter - def macro(self, macro): - if macro: - self.macro_id = macro.id - self._macro = macro - - -class Attachment(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - content_type=None, - content_url=None, - file_name=None, - id=None, - size=None, - thumbnails=None, - **kwargs): - - self.api = api - - # Comment: The content type of the image. Example value: image/png - # Read-only: yes - # Type: string - self.content_type = content_type - - # Comment: A full URL where the attachment image file can be downloaded - # Read-only: yes - # Type: string - self.content_url = content_url - - # Comment: The name of the image file - # Read-only: yes - # Type: string - self.file_name = file_name - - # Comment: Automatically assigned when created - # Read-only: yes - # Type: integer - self.id = id - - # Comment: The size of the image file in bytes - # Read-only: yes - # Type: integer - self.size = size - - # Comment: An array of Photo objects. Note that thumbnails do not have thumbnails. - # Read-only: yes - # Type: array - self.thumbnails = thumbnails - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Audit(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - author_id=None, - created_at=None, - events=None, - id=None, - metadata=None, - ticket_id=None, - via=None, - **kwargs): - - self.api = api - self.author_id = author_id - self.created_at = created_at - self.events = events - self.id = id - self.metadata = metadata - self.ticket_id = ticket_id - self.via = via - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def author(self): - - if self.api and self.author_id: - return self.api._get_user(self.author_id) - - @author.setter - def author(self, author): - if author: - self.author_id = author.id - self._author = author - - @property - def created(self): - - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def ticket(self): - - if self.api and self.ticket_id: - return self.api._get_ticket(self.ticket_id) - - @ticket.setter - def ticket(self, ticket): - if ticket: - self.ticket_id = ticket.id - self._ticket = ticket - - -class Automation(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - actions=None, - active=None, - conditions=None, - created_at=None, - id=None, - position=None, - raw_title=None, - title=None, - updated_at=None, - url=None, - **kwargs): - - self.api = api - - # Comment: An object describing what the automation will do - # Type: :class:`Actions` - self.actions = actions - - # Comment: Whether the automation is active - # Type: boolean - self.active = active - - # Comment: An object that describes the conditions under which the automation will execute - # Type: :class:`Conditions` - self.conditions = conditions - - # Comment: The time the automation was created - # Type: date - self.created_at = created_at - - # Comment: Automatically assigned when created - # Type: integer - self.id = id - - # Comment: Position of the automation, determines the order they will execute in - # Type: integer - self.position = position - self.raw_title = raw_title - - # Comment: The title of the automation - # Type: string - self.title = title - - # Comment: The time of the last update of the automation - # Type: date - self.updated_at = updated_at - self.url = url - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - """ - | Comment: The time the automation was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - """ - | Comment: The time of the last update of the automation - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class Brand(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - active=None, - brand_url=None, - created_at=None, - default=None, - has_help_center=None, - help_center_state=None, - host_mapping=None, - id=None, - logo=None, - name=None, - subdomain=None, - updated_at=None, - url=None, - **kwargs): - - self.api = api - - # Comment: If the brand is set as active - # Mandatory: no - # Read-only: no - # Type: boolean - self.active = active - - # Comment: The url of the brand - # Mandatory: no - # Read-only: no - # Type: string - self.brand_url = brand_url - - # Comment: The time the brand was created - # Mandatory: no - # Read-only: yes - # Type: date - self.created_at = created_at - - # Comment: Is the brand the default brand for this account - # Mandatory: no - # Read-only: no - # Type: boolean - self.default = default - - # Comment: If the brand has a Help Center - # Mandatory: no - # Read-only: no - # Type: boolean - self.has_help_center = has_help_center - - # Comment: The state of the Help Center: enabled, disabled, or restricted - # Mandatory: no - # Read-only: yes - # Type: string - self.help_center_state = help_center_state - - # Comment: The hostmapping to this brand, if any (only admins view this key) - # Mandatory: no - # Read-only: no - # Type: string - self.host_mapping = host_mapping - - # Comment: Automatically assigned when the brand is created - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: Logo image for this brand - # Mandatory: no - # Read-only: no - # Type: :class:`Attachment` - self.logo = logo - - # Comment: The name of the brand - # Mandatory: yes - # Read-only: no - # Type: string - self.name = name - - # Comment: The subdomain of the brand - # Mandatory: yes - # Read-only: no - # Type: string - self.subdomain = subdomain - - # Comment: The time of the last update of the brand - # Mandatory: no - # Read-only: yes - # Type: date - self.updated_at = updated_at - - # Comment: The API url of this brand - # Mandatory: no - # Read-only: yes - # Type: string - self.url = url - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - """ - | Comment: The time the brand was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - """ - | Comment: The time of the last update of the brand - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class CcEvent(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - id=None, - recipients=None, - type=None, - via=None, - **kwargs): - - self.api = api - self.id = id - self.recipients = recipients - self.type = type - self.via = via - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class ChangeEvent(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - field_name=None, - id=None, - previous_value=None, - type=None, - value=None, - **kwargs): - - self.api = api - self.field_name = field_name - self.id = id - self.previous_value = previous_value - self.type = type - self.value = value - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Comment(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - attachments=None, - author_id=None, - body=None, - created_at=None, - id=None, - metadata=None, - public=None, - type=None, - via=None, - **kwargs): - - self.api = api - self.attachments = attachments - self.author_id = author_id - self.body = body - self.created_at = created_at - self.id = id - self.metadata = metadata - self.public = public - self.type = type - self.via = via - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def author(self): - - if self.api and self.author_id: - return self.api._get_user(self.author_id) - - @author.setter - def author(self, author): - if author: - self.author_id = author.id - self._author = author - - @property - def created(self): - - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - -class CommentPrivacyChangeEvent(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - comment_id=None, - id=None, - public=None, - type=None, - **kwargs): - - self.api = api - self.comment_id = comment_id - self.id = id - self.public = public - self.type = type - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def comment(self): - - if self.api and self.comment_id: - return self.api._get_comment(self.comment_id) - - @comment.setter - def comment(self, comment): - if comment: - self.comment_id = comment.id - self._comment = comment - - -class Conditions(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, api=None, all=None, any=None, **kwargs): - - self.api = api - self.all = all - self.any = any - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class CreateEvent(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - field_name=None, - id=None, - type=None, - value=None, - **kwargs): - - self.api = api - self.field_name = field_name - self.id = id - self.type = type - self.value = value - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class CustomAgentRole(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - configuration=None, - created_at=None, - description=None, - id=None, - name=None, - role_type=None, - updated_at=None, - **kwargs): - - self.api = api - self.configuration = configuration - self.created_at = created_at - self.description = description - self.id = id - self.name = name - self.role_type = role_type - self.updated_at = updated_at - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class CustomField(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, api=None, id=None, value=None, **kwargs): - - self.api = api - self.id = id - self.value = value - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class CustomFieldOption(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - id=None, - name=None, - position=None, - raw_name=None, - url=None, - value=None, - **kwargs): - - self.api = api - self.id = id - self.name = name - self.position = position - self.raw_name = raw_name - self.url = url - self.value = value - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Definitions(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, api=None, all=None, any=None, **kwargs): - - self.api = api - self.all = all - self.any = any - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class ErrorEvent(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, api=None, id=None, message=None, type=None, **kwargs): - - self.api = api - self.id = id - self.message = message - self.type = type - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Export(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, api=None, status=None, view_id=None, **kwargs): - - self.api = api - self.status = status - self.view_id = view_id - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def view(self): - - if self.api and self.view_id: - return self.api._get_view(self.view_id) - - @view.setter - def view(self, view): - if view: - self.view_id = view.id - self._view = view - - -class ExternalEvent(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - body=None, - id=None, - resource=None, - type=None, - **kwargs): - - self.api = api - self.body = body - self.id = id - self.resource = resource - self.type = type - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class FacebookCommentEvent(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - attachments=None, - author_id=None, - body=None, - data=None, - graph_object_id=None, - html_body=None, - id=None, - public=None, - trusted=None, - type=None, - **kwargs): - - self.api = api - self.attachments = attachments - self.author_id = author_id - self.body = body - self.data = data - self.graph_object_id = graph_object_id - self.html_body = html_body - self.id = id - self.public = public - self.trusted = trusted - self.type = type - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def author(self): - - if self.api and self.author_id: - return self.api._get_user(self.author_id) - - @author.setter - def author(self, author): - if author: - self.author_id = author.id - self._author = author - - -class FacebookEvent(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - body=None, - communication=None, - id=None, - page=None, - ticket_via=None, - type=None, - **kwargs): - - self.api = api - self.body = body - self.communication = communication - self.id = id - self.page = page - self.ticket_via = ticket_via - self.type = type - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Group(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - created_at=None, - deleted=None, - id=None, - name=None, - updated_at=None, - url=None, - **kwargs): - - self.api = api - - # Comment: The time the group was created - # Mandatory: no - # Read-only: yes - # Type: date - self.created_at = created_at - - # Comment: Deleted groups get marked as such - # Mandatory: no - # Read-only: yes - # Type: boolean - self.deleted = deleted - - # Comment: Automatically assigned when creating groups - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: The name of the group - # Mandatory: yes - # Read-only: no - # Type: string - self.name = name - - # Comment: The time of the last update of the group - # Mandatory: no - # Read-only: yes - # Type: date - self.updated_at = updated_at - - # Comment: The API url of this group - # Mandatory: no - # Read-only: yes - # Type: string - self.url = url - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - """ - | Comment: The time the group was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - """ - | Comment: The time of the last update of the group - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class GroupMembership(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - created_at=None, - default=None, - group_id=None, - id=None, - updated_at=None, - url=None, - user_id=None, - **kwargs): - - self.api = api - - # Comment: The time the membership was created - # Mandatory: no - # Read-only: yes - # Type: date - self.created_at = created_at - - # Comment: If true, tickets assigned directly to the agent will assume this membership's group. - # Mandatory: no - # Read-only: no - # Type: boolean - self.default = default - - # Comment: The id of a group - # Mandatory: yes - # Read-only: no - # Type: integer - self.group_id = group_id - - # Comment: Automatically assigned upon creation - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: The time of the last update of the membership - # Mandatory: no - # Read-only: yes - # Type: date - self.updated_at = updated_at - - # Comment: The API url of this record - # Mandatory: no - # Read-only: yes - # Type: string - self.url = url - - # Comment: The id of an agent - # Mandatory: yes - # Read-only: no - # Type: integer - self.user_id = user_id - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - """ - | Comment: The time the membership was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def group(self): - """ - | Comment: The id of a group - """ - if self.api and self.group_id: - return self.api._get_group(self.group_id) - - @group.setter - def group(self, group): - if group: - self.group_id = group.id - self._group = group - - @property - def updated(self): - """ - | Comment: The time of the last update of the membership - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - @property - def user(self): - """ - | Comment: The id of an agent - """ - if self.api and self.user_id: - return self.api._get_user(self.user_id) - - @user.setter - def user(self, user): - if user: - self.user_id = user.id - self._user = user - - -class Identity(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - created_at=None, - deliverable_state=None, - id=None, - primary=None, - type=None, - undeliverable_count=None, - updated_at=None, - url=None, - user_id=None, - value=None, - verified=None, - **kwargs): - - self.api = api - self.created_at = created_at - self.deliverable_state = deliverable_state - self.id = id - self.primary = primary - self.type = type - self.undeliverable_count = undeliverable_count - self.updated_at = updated_at - self.url = url - self.user_id = user_id - self.value = value - self.verified = verified - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - @property - def user(self): - - if self.api and self.user_id: - return self.api._get_user(self.user_id) - - @user.setter - def user(self, user): - if user: - self.user_id = user.id - self._user = user - - -class Item(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - created_at=None, - default_locale_id=None, - id=None, - name=None, - outdated=None, - placeholder=None, - updated_at=None, - url=None, - variants=None, - **kwargs): - - self.api = api - self.created_at = created_at - self.default_locale_id = default_locale_id - self.id = id - self.name = name - self.outdated = outdated - self.placeholder = placeholder - self.updated_at = updated_at - self.url = url - self.variants = variants - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def default_locale(self): - - if self.api and self.default_locale_id: - return self.api._get_default_locale(self.default_locale_id) - - @default_locale.setter - def default_locale(self, default_locale): - if default_locale: - self.default_locale_id = default_locale.id - self._default_locale = default_locale - - @property - def updated(self): - - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class JobStatus(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - id=None, - message=None, - progress=None, - results=None, - status=None, - total=None, - url=None, - **kwargs): - - self.api = api - self.id = id - self.message = message - self.progress = progress - self.results = results - self.status = status - self.total = total - self.url = url - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class JobStatusResult(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - action=None, - errors=None, - id=None, - status=None, - success=None, - title=None, - **kwargs): - - self.api = api - self.action = action - self.errors = errors - self.id = id - self.status = status - self.success = success - self.title = title - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Link(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - created_at=None, - id=None, - issue_id=None, - issue_key=None, - ticket_id=None, - updated_at=None, - url=None, - **kwargs): - - self.api = api - self.created_at = created_at - self.id = id - self.issue_id = issue_id - self.issue_key = issue_key - self.ticket_id = ticket_id - self.updated_at = updated_at - self.url = url - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def ticket(self): - - if self.api and self.ticket_id: - return self.api._get_ticket(self.ticket_id) - - @ticket.setter - def ticket(self, ticket): - if ticket: - self.ticket_id = ticket.id - self._ticket = ticket - - @property - def updated(self): - - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class Locale(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - created_at=None, - default=None, - id=None, - locale=None, - name=None, - native_name=None, - presentation_name=None, - rtl=None, - updated_at=None, - url=None, - **kwargs): - - self.api = api - self.created_at = created_at - self.default = default - - # Description: Either the ID or the bcp-47 code of the locale (es-419, en-us, pr-br) - # Type: string - self.id = id - self.locale = locale - self.name = name - self.native_name = native_name - self.presentation_name = presentation_name - self.rtl = rtl - self.updated_at = updated_at - self.url = url - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class LogmeinTranscriptEvent(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, api=None, body=None, id=None, type=None, **kwargs): - - self.api = api - self.body = body - self.id = id - self.type = type - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Macro(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - actions=None, - active=None, - created_at=None, - description=None, - id=None, - position=None, - restriction=None, - title=None, - updated_at=None, - url=None, - **kwargs): - - self.api = api - - # Comment: An object describing what the macro will do - # Type: :class:`Actions` - self.actions = actions - - # Comment: Useful for determining if the macro should be displayed - # Type: boolean - self.active = active - - # Comment: The time the macro was created - # Type: date - self.created_at = created_at - - # Comment: The description of the macro - # Type: string - self.description = description - - # Comment: Automatically assigned when created - # Type: integer - self.id = id - - # Comment: The position of the macro - # Type: integer - self.position = position - - # Comment: Who may access this macro. Will be null when everyone in the account can access it - # Type: object - self.restriction = restriction - - # Comment: The title of the macro - # Type: string - self.title = title - - # Comment: The time of the last update of the macro - # Type: date - self.updated_at = updated_at - self.url = url - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - """ - | Comment: The time the macro was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - """ - | Comment: The time of the last update of the macro - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class MacroResult(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, api=None, ticket=None, **kwargs): - - self.api = api - self.ticket = ticket - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Metadata(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, api=None, custom=None, system=None, **kwargs): - - self.api = api - self.custom = custom - self.system = system - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class NotificationEvent(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - body=None, - id=None, - recipients=None, - subject=None, - type=None, - via=None, - **kwargs): - - self.api = api - self.body = body - self.id = id - self.recipients = recipients - self.subject = subject - self.type = type - self.via = via - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Organization(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - created_at=None, - details=None, - domain_names=None, - external_id=None, - group_id=None, - id=None, - name=None, - notes=None, - organization_fields=None, - shared_comments=None, - shared_tickets=None, - tags=None, - updated_at=None, - url=None, - **kwargs): - - self.api = api - - # Comment: The time the organization was created - # Mandatory: no - # Read-only: yes - # Type: date - self.created_at = created_at - - # Comment: Any details obout the organization, such as the address - # Mandatory: no - # Read-only: no - # Type: string - self.details = details - - # Comment: An array of domain names associated with this organization - # Mandatory: no - # Read-only: no - # Type: array - self.domain_names = domain_names - - # Comment: A unique external id to associate organizations to an external record - # Mandatory: no - # Read-only: no - # Type: string - self.external_id = external_id - - # Comment: New tickets from users in this organization are automatically put in this group - # Mandatory: no - # Read-only: no - # Type: integer - self.group_id = group_id - - # Comment: Automatically assigned when the organization is created - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: A unique name for the organization - # Mandatory: yes - # Read-only: no - # Type: string - self.name = name - - # Comment: Any notes you have about the organization - # Mandatory: no - # Read-only: no - # Type: string - self.notes = notes - - # Comment: Custom fields for this organization - # Mandatory: no - # Read-only: no - # Type: :class:`hash` - self.organization_fields = organization_fields - - # Comment: End users in this organization are able to see each other's comments on tickets - # Mandatory: no - # Read-only: no - # Type: boolean - self.shared_comments = shared_comments - - # Comment: End users in this organization are able to see each other's tickets - # Mandatory: no - # Read-only: no - # Type: boolean - self.shared_tickets = shared_tickets - - # Comment: The tags of the organization - # Mandatory: no - # Read-only: no - # Type: array - self.tags = tags - - # Comment: The time of the last update of the organization - # Mandatory: no - # Read-only: yes - # Type: date - self.updated_at = updated_at - - # Comment: The API url of this organization - # Mandatory: no - # Read-only: yes - # Type: string - self.url = url - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - """ - | Comment: The time the organization was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def group(self): - """ - | Comment: New tickets from users in this organization are automatically put in this group - """ - if self.api and self.group_id: - return self.api._get_group(self.group_id) - - @group.setter - def group(self, group): - if group: - self.group_id = group.id - self._group = group - - @property - def updated(self): - """ - | Comment: The time of the last update of the organization - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class OrganizationActivityEvent(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - body=None, - id=None, - recipients=None, - subject=None, - type=None, - via=None, - **kwargs): - - self.api = api - self.body = body - self.id = id - self.recipients = recipients - self.subject = subject - self.type = type - self.via = via - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class OrganizationField(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - active=None, - created_at=None, - description=None, - id=None, - key=None, - position=None, - raw_description=None, - raw_title=None, - regexp_for_validation=None, - title=None, - type=None, - updated_at=None, - url=None, - **kwargs): - - self.api = api - - # Comment: If true, this field is available for use - # Mandatory: no - # Read-only: no - # Type: boolean - self.active = active - - # Comment: The time the ticket field was created - # Mandatory: no - # Read-only: yes - # Type: date - self.created_at = created_at - - # Comment: User-defined description of this field's purpose - # Mandatory: no - # Read-only: no - # Type: string - self.description = description - - # Comment: Automatically assigned upon creation - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: A unique key that identifies this custom field. This is used for updating the field and referencing in placeholders. - # Mandatory: on create - # Read-only: no - # Type: string - self.key = key - - # Comment: Ordering of the field relative to other fields - # Mandatory: no - # Read-only: no - # Type: integer - self.position = position - - # Comment: The dynamic content placeholder, if present, or the "description" value, if not. See Dynamic Content - # Mandatory: no - # Read-only: no - # Type: string - self.raw_description = raw_description - - # Comment: The dynamic content placeholder, if present, or the "title" value, if not. See Dynamic Content - # Mandatory: no - # Read-only: no - # Type: string - self.raw_title = raw_title - - # Comment: Regular expression field only. The validation pattern for a field value to be deemed valid. - # Mandatory: no - # Read-only: no - # Type: string - self.regexp_for_validation = regexp_for_validation - - # Comment: The title of the custom field - # Mandatory: yes - # Read-only: no - # Type: string - self.title = title - - # Comment: Type of the custom field: "checkbox", "date", "decimal", "dropdown", "integer", "regexp", "text", or "textarea" - # Mandatory: yes - # Read-only: no - # Type: string - self.type = type - - # Comment: The time of the last update of the ticket field - # Mandatory: no - # Read-only: yes - # Type: date - self.updated_at = updated_at - - # Comment: The URL for this resource - # Mandatory: no - # Read-only: yes - # Type: string - self.url = url - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - """ - | Comment: The time the ticket field was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - """ - | Comment: The time of the last update of the ticket field - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class OrganizationMembership(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - created_at=None, - default=None, - id=None, - organization_id=None, - updated_at=None, - url=None, - user_id=None, - **kwargs): - - self.api = api - - # Comment: When this record was created - # Mandatory: no - # Read-only: yes - # Type: date - self.created_at = created_at - - # Comment: Denotes whether this is the default organization membership for the user. If false, returns null - # Mandatory: yes - # Read-only: no - # Type: boolean - self.default = default - - # Comment: Automatically assigned when the membership is created - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: The ID of the organization associated with this user, in this membership - # Mandatory: yes - # Read-only: yes - # Type: integer - self.organization_id = organization_id - - # Comment: When this record last got updated - # Mandatory: no - # Read-only: yes - # Type: date - self.updated_at = updated_at - - # Comment: The API url of this membership - # Mandatory: no - # Read-only: yes - # Type: string - self.url = url - - # Comment: The ID of the user for whom this memberships belongs - # Mandatory: yes - # Read-only: yes - # Type: integer - self.user_id = user_id - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - """ - | Comment: When this record was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def organization(self): - """ - | Comment: The ID of the organization associated with this user, in this membership - """ - if self.api and self.organization_id: - return self.api._get_organization(self.organization_id) - - @organization.setter - def organization(self, organization): - if organization: - self.organization_id = organization.id - self._organization = organization - - @property - def updated(self): - """ - | Comment: When this record last got updated - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - @property - def user(self): - """ - | Comment: The ID of the user for whom this memberships belongs - """ - if self.api and self.user_id: - return self.api._get_user(self.user_id) - - @user.setter - def user(self, user): - if user: - self.user_id = user.id - self._user = user - - -class PolicyMetric(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - business_hours=None, - metric=None, - priority=None, - target=None, - **kwargs): - - self.api = api - self.business_hours = business_hours - self.metric = metric - self.priority = priority - self.target = target - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class PushEvent(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - id=None, - type=None, - value=None, - value_reference=None, - **kwargs): - - self.api = api - self.id = id - self.type = type - self.value = value - self.value_reference = value_reference - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Recipient(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - created_at=None, - delivered_at=None, - delivery_id=None, - id=None, - survey_id=None, - survey_name=None, - updated_at=None, - user_email=None, - user_id=None, - user_name=None, - **kwargs): - - self.api = api - self.created_at = created_at - self.delivered_at = delivered_at - self.delivery_id = delivery_id - self.id = id - self.survey_id = survey_id - self.survey_name = survey_name - self.updated_at = updated_at - self.user_email = user_email - self.user_id = user_id - self.user_name = user_name - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def delivered(self): - - if self.delivered_at: - return dateutil.parser.parse(self.delivered_at) - - @delivered.setter - def delivered(self, delivered): - if delivered: - self.delivered_at = delivered - - @property - def delivery(self): - - if self.api and self.delivery_id: - return self.api._get_delivery(self.delivery_id) - - @delivery.setter - def delivery(self, delivery): - if delivery: - self.delivery_id = delivery.id - self._delivery = delivery - - @property - def survey(self): - - if self.api and self.survey_id: - return self.api._get_survey(self.survey_id) - - @survey.setter - def survey(self, survey): - if survey: - self.survey_id = survey.id - self._survey = survey - - @property - def updated(self): - - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - @property - def user(self): - - if self.api and self.user_id: - return self.api._get_user(self.user_id) - - @user.setter - def user(self, user): - if user: - self.user_id = user.id - self._user = user - - -class RecipientAddress(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - brand_id=None, - created_at=None, - default=None, - email=None, - forwarding_status=None, - id=None, - name=None, - spf_status=None, - updated_at=None, - **kwargs): - - self.api = api - self.brand_id = brand_id - self.created_at = created_at - self.default = default - self.email = email - self.forwarding_status = forwarding_status - self.id = id - self.name = name - self.spf_status = spf_status - self.updated_at = updated_at - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def brand(self): - - if self.api and self.brand_id: - return self.api._get_brand(self.brand_id) - - @brand.setter - def brand(self, brand): - if brand: - self.brand_id = brand.id - self._brand = brand - - @property - def created(self): - - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class Request(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - assignee_id=None, - can_be_solved_by_me=None, - collaborator_ids=None, - created_at=None, - custom_fields=None, - description=None, - due_at=None, - fields=None, - id=None, - organization_id=None, - priority=None, - requester_id=None, - status=None, - subject=None, - type=None, - updated_at=None, - url=None, - via=None, - **kwargs): - - self.api = api - - # Comment: The id of the assignee if the field is visible to end users - # Mandatory: no - # Read-only: yes - # Type: integer - self.assignee_id = assignee_id - - # Comment: If true, end user can mark request as solved. - # Mandatory: no - # Read-only: yes - # Type: boolean - self.can_be_solved_by_me = can_be_solved_by_me - - # Comment: Who are currently CC'ed on the ticket - # Mandatory: no - # Read-only: yes - # Type: array - self.collaborator_ids = collaborator_ids - - # Comment: When this record was created - # Mandatory: no - # Read-only: yes - # Type: date - self.created_at = created_at - - # Comment: The fields and entries for this request - # Mandatory: no - # Read-only: no - # Type: :class:`Array` - self.custom_fields = custom_fields - - # Comment: The first comment on the request - # Mandatory: yes - # Read-only: yes - # Type: string - self.description = description - - # Comment: When the task is due (only applies if the request is of type "task") - # Mandatory: no - # Read-only: no - # Type: date - self.due_at = due_at - self.fields = fields - - # Comment: Automatically assigned when creating requests - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: The organization of the requester - # Mandatory: no - # Read-only: yes - # Type: integer - self.organization_id = organization_id - - # Comment: The priority of the request, "low", "normal", "high", "urgent" - # Mandatory: no - # Read-only: no - # Type: string - self.priority = priority - - # Comment: The id of the requester - # Mandatory: no - # Read-only: yes - # Type: integer - self.requester_id = requester_id - - # Comment: The state of the request, "new", "open", "pending", "hold", "solved", "closed" - # Mandatory: no - # Read-only: no - # Type: string - self.status = status - - # Comment: The value of the subject field for this request if the subject field is visible to end users; a truncated version of the description otherwise - # Mandatory: yes - # Read-only: no - # Type: string - self.subject = subject - - # Comment: The type of the request, "question", "incident", "problem", "task" - # Mandatory: no - # Read-only: no - # Type: string - self.type = type - - # Comment: When this record last got updated - # Mandatory: no - # Read-only: yes - # Type: date - self.updated_at = updated_at - - # Comment: The API url of this request - # Mandatory: no - # Read-only: yes - # Type: string - self.url = url - - # Comment: This object explains how the request was created - # Mandatory: no - # Read-only: yes - # Type: :class:`Via` - self.via = via - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def assignee(self): - """ - | Comment: The id of the assignee if the field is visible to end users - """ - if self.api and self.assignee_id: - return self.api._get_user(self.assignee_id) - - @assignee.setter - def assignee(self, assignee): - if assignee: - self.assignee_id = assignee.id - self._assignee = assignee - - @property - def collaborators(self): - """ - | Comment: Who are currently CC'ed on the ticket - """ - if self.api and self.collaborator_ids: - return self.api._get_users(self.collaborator_ids) - - @collaborators.setter - def collaborators(self, collaborators): - if collaborators: - self.collaborator_ids = [o.id for o in collaborators] - self._collaborators = collaborators - - @property - def created(self): - """ - | Comment: When this record was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def due(self): - """ - | Comment: When the task is due (only applies if the request is of type "task") - """ - if self.due_at: - return dateutil.parser.parse(self.due_at) - - @due.setter - def due(self, due): - if due: - self.due_at = due - - @property - def organization(self): - """ - | Comment: The organization of the requester - """ - if self.api and self.organization_id: - return self.api._get_organization(self.organization_id) - - @organization.setter - def organization(self, organization): - if organization: - self.organization_id = organization.id - self._organization = organization - - @property - def requester(self): - """ - | Comment: The id of the requester - """ - if self.api and self.requester_id: - return self.api._get_user(self.requester_id) - - @requester.setter - def requester(self, requester): - if requester: - self.requester_id = requester.id - self._requester = requester - - @property - def updated(self): - """ - | Comment: When this record last got updated - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class Response(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - comment=None, - delivered_at=None, - delivery_id=None, - id=None, - rated_at=None, - rating=None, - recipient_id=None, - survey_id=None, - survey_name=None, - user_email=None, - user_id=None, - user_name=None, - **kwargs): - - self.api = api - self.comment = comment - self.delivered_at = delivered_at - self.delivery_id = delivery_id - self.id = id - self.rated_at = rated_at - self.rating = rating - self.recipient_id = recipient_id - self.survey_id = survey_id - self.survey_name = survey_name - self.user_email = user_email - self.user_id = user_id - self.user_name = user_name - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def delivered(self): - - if self.delivered_at: - return dateutil.parser.parse(self.delivered_at) - - @delivered.setter - def delivered(self, delivered): - if delivered: - self.delivered_at = delivered - - @property - def delivery(self): - - if self.api and self.delivery_id: - return self.api._get_delivery(self.delivery_id) - - @delivery.setter - def delivery(self, delivery): - if delivery: - self.delivery_id = delivery.id - self._delivery = delivery - - @property - def rated(self): - - if self.rated_at: - return dateutil.parser.parse(self.rated_at) - - @rated.setter - def rated(self, rated): - if rated: - self.rated_at = rated - - @property - def recipient(self): - - if self.api and self.recipient_id: - return self.api._get_user(self.recipient_id) - - @recipient.setter - def recipient(self, recipient): - if recipient: - self.recipient_id = recipient.id - self._recipient = recipient - - @property - def survey(self): - - if self.api and self.survey_id: - return self.api._get_survey(self.survey_id) - - @survey.setter - def survey(self, survey): - if survey: - self.survey_id = survey.id - self._survey = survey - - @property - def user(self): - - if self.api and self.user_id: - return self.api._get_user(self.user_id) - - @user.setter - def user(self, user): - if user: - self.user_id = user.id - self._user = user - - -class SatisfactionRating(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - assignee_id=None, - created_at=None, - group_id=None, - id=None, - requester_id=None, - score=None, - ticket_id=None, - updated_at=None, - url=None, - **kwargs): - - self.api = api - - # Comment: The id of agent assigned to at the time of rating - # Mandatory: yes - # Read-only: yes - # Type: integer - self.assignee_id = assignee_id - - # Comment: The time the satisfaction rating got created - # Mandatory: no - # Read-only: yes - # Type: date - self.created_at = created_at - - # Comment: The id of group assigned to at the time of rating - # Mandatory: yes - # Read-only: yes - # Type: integer - self.group_id = group_id - - # Comment: Automatically assigned upon creation - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: The id of ticket requester submitting the rating - # Mandatory: yes - # Read-only: yes - # Type: integer - self.requester_id = requester_id - - # Comment: The rating: "offered", "unoffered", "good" or "bad" - # Mandatory: yes - # Read-only: no - # Type: string - self.score = score - - # Comment: The id of ticket being rated - # Mandatory: yes - # Read-only: yes - # Type: integer - self.ticket_id = ticket_id - - # Comment: The time the satisfaction rating got updated - # Mandatory: no - # Read-only: yes - # Type: date - self.updated_at = updated_at - - # Comment: The API url of this rating - # Mandatory: no - # Read-only: yes - # Type: string - self.url = url - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def assignee(self): - """ - | Comment: The id of agent assigned to at the time of rating - """ - if self.api and self.assignee_id: - return self.api._get_user(self.assignee_id) - - @assignee.setter - def assignee(self, assignee): - if assignee: - self.assignee_id = assignee.id - self._assignee = assignee - - @property - def created(self): - """ - | Comment: The time the satisfaction rating got created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def group(self): - """ - | Comment: The id of group assigned to at the time of rating - """ - if self.api and self.group_id: - return self.api._get_group(self.group_id) - - @group.setter - def group(self, group): - if group: - self.group_id = group.id - self._group = group - - @property - def requester(self): - """ - | Comment: The id of ticket requester submitting the rating - """ - if self.api and self.requester_id: - return self.api._get_user(self.requester_id) - - @requester.setter - def requester(self, requester): - if requester: - self.requester_id = requester.id - self._requester = requester - - @property - def ticket(self): - """ - | Comment: The id of ticket being rated - """ - if self.api and self.ticket_id: - return self.api._get_ticket(self.ticket_id) - - @ticket.setter - def ticket(self, ticket): - if ticket: - self.ticket_id = ticket.id - self._ticket = ticket - - @property - def updated(self): - """ - | Comment: The time the satisfaction rating got updated - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class SatisfactionRatingEvent(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - assignee_id=None, - body=None, - id=None, - score=None, - type=None, - **kwargs): - - self.api = api - self.assignee_id = assignee_id - self.body = body - self.id = id - self.score = score - self.type = type - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def assignee(self): - - if self.api and self.assignee_id: - return self.api._get_user(self.assignee_id) - - @assignee.setter - def assignee(self, assignee): - if assignee: - self.assignee_id = assignee.id - self._assignee = assignee - - -class Schedule(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - created_at=None, - id=None, - intervals=None, - name=None, - time_zone=None, - updated_at=None, - url=None, - **kwargs): - - self.api = api - - # Comment: Time the schedule was created - # Type: date - self.created_at = created_at - - # Comment: Automatically assigned upon creation - # Type: integer - self.id = id - - # Comment: Array of intervals for the schedule - # Type: array - self.intervals = intervals - - # Comment: Name of the schedule - # Type: string - self.name = name - - # Comment: Time zone of the schedule - # Type: string - self.time_zone = time_zone - - # Comment: Time the schedule was last updated - # Type: date - self.updated_at = updated_at - self.url = url - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - """ - | Comment: Time the schedule was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - """ - | Comment: Time the schedule was last updated - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class SharingAgreement(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - created_at=None, - id=None, - name=None, - partner_name=None, - remote_subdomain=None, - status=None, - type=None, - **kwargs): - - self.api = api - - # Comment: The time the record was created - # Type: date - self.created_at = created_at - - # Comment: Automatically assigned upon creation - # Type: integer - self.id = id - - # Comment: Name of this sharing agreement - # Type: string - self.name = name - - # Comment: Can be one of the following: 'jira', null - # Type: string - self.partner_name = partner_name - - # Comment: Subdomain of the remote account or null if not associated with an account - # Type: string - self.remote_subdomain = remote_subdomain - - # Comment: Can be one of the following: 'accepted', 'declined', 'pending', 'inactive' - # Type: string - self.status = status - - # Comment: Can be one of the following: 'inbound', 'outbound' - # Type: string - self.type = type - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - """ - | Comment: The time the record was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - -class Skip(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - created_at=None, - id=None, - reason=None, - ticket=None, - ticket_id=None, - updated_at=None, - user_id=None, - **kwargs): - - self.api = api - self.created_at = created_at - self.id = id - self.reason = reason - self.ticket = ticket - self.ticket_id = ticket_id - self.updated_at = updated_at - self.user_id = user_id - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - @property - def user(self): - - if self.api and self.user_id: - return self.api._get_user(self.user_id) - - @user.setter - def user(self, user): - if user: - self.user_id = user.id - self._user = user - - -class SlaPolicy(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - created_at=None, - description=None, - filter=None, - id=None, - policy_metrics=None, - position=None, - title=None, - updated_at=None, - url=None, - **kwargs): - - self.api = api - self.created_at = created_at - self.description = description - self.filter = filter - self.id = id - self.policy_metrics = policy_metrics - self.position = position - self.title = title - self.updated_at = updated_at - self.url = url - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class Source(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, api=None, from_=None, rel=None, to=None, **kwargs): - - self.api = api - self.from_ = from_ - self.rel = rel - self.to = to - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Status(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - action=None, - errors=None, - id=None, - status=None, - success=None, - title=None, - **kwargs): - - self.api = api - self.action = action - self.errors = errors - self.id = id - self.status = status - self.success = success - self.title = title - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class SuspendedTicket(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - author=None, - brand_id=None, - cause=None, - content=None, - created_at=None, - id=None, - recipient=None, - subject=None, - ticket_id=None, - updated_at=None, - url=None, - via=None, - **kwargs): - - self.api = api - - # Comment: The author id (if available), name and email - # Mandatory: no - # Read-only: yes - # Type: object - self.author = author - - # Comment: The id of the brand this ticket is associated with - only applicable for enterprise accounts - # Mandatory: no - # Read-only: yes - # Type: integer - self.brand_id = brand_id - - # Comment: Why the ticket was suspended - # Mandatory: no - # Read-only: yes - # Type: string - self.cause = cause - - # Comment: The content that was flagged - # Mandatory: no - # Read-only: yes - # Type: string - self.content = content - - # Comment: When this record was created - # Mandatory: no - # Read-only: yes - # Type: date - self.created_at = created_at - - # Comment: Automatically assigned - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: The original recipient e-mail address of the ticket - # Mandatory: no - # Read-only: yes - # Type: string - self.recipient = recipient - - # Comment: The value of the subject field for this ticket - # Mandatory: no - # Read-only: yes - # Type: string - self.subject = subject - - # Comment: The ticket ID this suspended email is associated with, if available - # Mandatory: no - # Read-only: yes - # Type: integer - self.ticket_id = ticket_id - - # Comment: When this record last got updated - # Mandatory: no - # Read-only: yes - # Type: date - self.updated_at = updated_at - - # Comment: The API url of this ticket - # Mandatory: no - # Read-only: yes - # Type: string - self.url = url - - # Comment: This object explains how the ticket was created - # Mandatory: no - # Read-only: yes - # Type: :class:`Via` - self.via = via - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def brand(self): - """ - | Comment: The id of the brand this ticket is associated with - only applicable for enterprise accounts - """ - if self.api and self.brand_id: - return self.api._get_brand(self.brand_id) - - @brand.setter - def brand(self, brand): - if brand: - self.brand_id = brand.id - self._brand = brand - - @property - def created(self): - """ - | Comment: When this record was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def ticket(self): - """ - | Comment: The ticket ID this suspended email is associated with, if available - """ - if self.api and self.ticket_id: - return self.api._get_ticket(self.ticket_id) - - @ticket.setter - def ticket(self, ticket): - if ticket: - self.ticket_id = ticket.id - self._ticket = ticket - - @property - def updated(self): - """ - | Comment: When this record last got updated - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class System(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - client=None, - ip_address=None, - latitude=None, - location=None, - longitude=None, - **kwargs): - - self.api = api - self.client = client - self.ip_address = ip_address - self.latitude = latitude - self.location = location - self.longitude = longitude - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Tag(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, api=None, count=None, name=None, **kwargs): - - self.api = api - self.count = count - self.name = name - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Target(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - active=None, - content_type=None, - created_at=None, - id=None, - method=None, - password=None, - target_url=None, - title=None, - type=None, - url=None, - username=None, - **kwargs): - - self.api = api - - # Comment: Whether or not the target is activated - # Mandatory: - # Type: boolean - self.active = active - self.content_type = content_type - - # Comment: The time the target was created - # Mandatory: - # Type: date - self.created_at = created_at - - # Comment: Automatically assigned when created - # Mandatory: - # Type: integer - self.id = id - self.method = method - self.password = password - self.target_url = target_url - - # Comment: A name for the target - # Mandatory: yes - # Type: string - self.title = title - - # Comment: A pre-defined target, such as "basecamp_target". See the additional attributes for the type that follow - # Mandatory: - # Type: string - self.type = type - self.url = url - self.username = username - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - """ - | Comment: The time the target was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - -class Thumbnail(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - content_type=None, - content_url=None, - file_name=None, - id=None, - size=None, - **kwargs): - - self.api = api - self.content_type = content_type - self.content_url = content_url - self.file_name = file_name - self.id = id - self.size = size - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Ticket(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - assignee_id=None, - brand_id=None, - collaborator_ids=None, - created_at=None, - custom_fields=None, - description=None, - due_at=None, - external_id=None, - fields=None, - forum_topic_id=None, - group_id=None, - has_incidents=None, - id=None, - organization_id=None, - priority=None, - problem_id=None, - raw_subject=None, - recipient=None, - requester_id=None, - satisfaction_rating=None, - sharing_agreement_ids=None, - status=None, - subject=None, - submitter_id=None, - tags=None, - type=None, - updated_at=None, - url=None, - via=None, - **kwargs): - - self.api = api - - # Comment: The agent currently assigned to the ticket - # Mandatory: no - # Read-only: no - # Type: integer - self.assignee_id = assignee_id - - # Comment: Enterprise only. The id of the brand this ticket is associated with - # Mandatory: no - # Read-only: no - # Type: integer - self.brand_id = brand_id - - # Comment: The ids of users currently cc'ed on the ticket - # Mandatory: no - # Read-only: no - # Type: array - self.collaborator_ids = collaborator_ids - - # Comment: When this record was created - # Mandatory: no - # Read-only: yes - # Type: date - self.created_at = created_at - - # Comment: Custom fields for the ticket. See Setting custom field values - # Mandatory: no - # Read-only: no - # Type: array - self.custom_fields = custom_fields - - # Comment: The first comment on the ticket - # Mandatory: no - # Read-only: yes - # Type: string - self.description = description - - # Comment: If this is a ticket of type "task" it has a due date. Due date format uses ISO 8601 format. - # Mandatory: no - # Read-only: no - # Type: date - self.due_at = due_at - - # Comment: An id you can use to link Zendesk Support tickets to local records - # Mandatory: no - # Read-only: no - # Type: string - self.external_id = external_id - self.fields = fields - - # Comment: The topic this ticket originated from, if any - # Mandatory: no - # Read-only: no - # Type: integer - self.forum_topic_id = forum_topic_id - - # Comment: The group this ticket is assigned to - # Mandatory: no - # Read-only: no - # Type: integer - self.group_id = group_id - - # Comment: Is true of this ticket has been marked as a problem, false otherwise - # Mandatory: no - # Read-only: yes - # Type: boolean - self.has_incidents = has_incidents - - # Comment: Automatically assigned when the ticket is created - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: The organization of the requester. You can only specify the ID of an organization associated with the requester. See Organization Memberships - # Mandatory: no - # Read-only: no - # Type: integer - self.organization_id = organization_id - - # Comment: The urgency with which the ticket should be addressed. Possible values: "urgent", "high", "normal", "low" - # Mandatory: no - # Read-only: no - # Type: string - self.priority = priority - - # Comment: For tickets of type "incident", the ID of the problem the incident is linked to - # Mandatory: no - # Read-only: no - # Type: integer - self.problem_id = problem_id - - # Comment: The dynamic content placeholder, if present, or the "subject" value, if not. See Dynamic Content - # Mandatory: no - # Read-only: no - # Type: string - self.raw_subject = raw_subject - - # Comment: The original recipient e-mail address of the ticket - # Mandatory: no - # Read-only: no - # Type: string - self.recipient = recipient - - # Comment: The user who requested this ticket - # Mandatory: yes - # Read-only: no - # Type: integer - self.requester_id = requester_id - - # Comment: The satisfaction rating of the ticket, if it exists, or the state of satisfaction, 'offered' or 'unoffered' - # Mandatory: no - # Read-only: yes - # Type: object - self.satisfaction_rating = satisfaction_rating - - # Comment: The ids of the sharing agreements used for this ticket - # Mandatory: no - # Read-only: yes - # Type: array - self.sharing_agreement_ids = sharing_agreement_ids - - # Comment: The state of the ticket. Possible values: "new", "open", "pending", "hold", "solved", "closed" - # Mandatory: no - # Read-only: no - # Type: string - self.status = status - - # Comment: The value of the subject field for this ticket - # Mandatory: no - # Read-only: no - # Type: string - self.subject = subject - - # Comment: The user who submitted the ticket. The submitter always becomes the author of the first comment on the ticket - # Mandatory: no - # Read-only: no - # Type: integer - self.submitter_id = submitter_id - - # Comment: The array of tags applied to this ticket - # Mandatory: no - # Read-only: no - # Type: array - self.tags = tags - - # Comment: The type of this ticket. Possible values: "problem", "incident", "question" or "task" - # Mandatory: no - # Read-only: no - # Type: string - self.type = type - - # Comment: When this record last got updated - # Mandatory: no - # Read-only: yes - # Type: date - self.updated_at = updated_at - - # Comment: The API url of this ticket - # Mandatory: no - # Read-only: yes - # Type: string - self.url = url - - # Comment: This object explains how the ticket was created - # Mandatory: no - # Read-only: yes - # Type: :class:`Via` - self.via = via - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def assignee(self): - """ - | Comment: The agent currently assigned to the ticket - """ - if self.api and self.assignee_id: - return self.api._get_user(self.assignee_id) - - @assignee.setter - def assignee(self, assignee): - if assignee: - self.assignee_id = assignee.id - self._assignee = assignee - - @property - def brand(self): - """ - | Comment: Enterprise only. The id of the brand this ticket is associated with - """ - if self.api and self.brand_id: - return self.api._get_brand(self.brand_id) - - @brand.setter - def brand(self, brand): - if brand: - self.brand_id = brand.id - self._brand = brand - - @property - def collaborators(self): - """ - | Comment: The ids of users currently cc'ed on the ticket - """ - if self.api and self.collaborator_ids: - return self.api._get_users(self.collaborator_ids) - - @collaborators.setter - def collaborators(self, collaborators): - if collaborators: - self.collaborator_ids = [o.id for o in collaborators] - self._collaborators = collaborators - - @property - def created(self): - """ - | Comment: When this record was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def due(self): - """ - | Comment: If this is a ticket of type "task" it has a due date. Due date format uses ISO 8601 format. - """ - if self.due_at: - return dateutil.parser.parse(self.due_at) - - @due.setter - def due(self, due): - if due: - self.due_at = due - - @property - def forum_topic(self): - """ - | Comment: The topic this ticket originated from, if any - """ - if self.api and self.forum_topic_id: - return self.api._get_topic(self.forum_topic_id) - - @forum_topic.setter - def forum_topic(self, forum_topic): - if forum_topic: - self.forum_topic_id = forum_topic.id - self._forum_topic = forum_topic - - @property - def group(self): - """ - | Comment: The group this ticket is assigned to - """ - if self.api and self.group_id: - return self.api._get_group(self.group_id) - - @group.setter - def group(self, group): - if group: - self.group_id = group.id - self._group = group - - @property - def organization(self): - """ - | Comment: The organization of the requester. You can only specify the ID of an organization associated with the requester. See Organization Memberships - """ - if self.api and self.organization_id: - return self.api._get_organization(self.organization_id) - - @organization.setter - def organization(self, organization): - if organization: - self.organization_id = organization.id - self._organization = organization - - @property - def problem(self): - """ - | Comment: For tickets of type "incident", the ID of the problem the incident is linked to - """ - if self.api and self.problem_id: - return self.api._get_problem(self.problem_id) - - @problem.setter - def problem(self, problem): - if problem: - self.problem_id = problem.id - self._problem = problem - - @property - def requester(self): - """ - | Comment: The user who requested this ticket - """ - if self.api and self.requester_id: - return self.api._get_user(self.requester_id) - - @requester.setter - def requester(self, requester): - if requester: - self.requester_id = requester.id - self._requester = requester - - @property - def sharing_agreements(self): - """ - | Comment: The ids of the sharing agreements used for this ticket - """ - if self.api and self.sharing_agreement_ids: - return self.api._get_sharing_agreements(self.sharing_agreement_ids) - - @sharing_agreements.setter - def sharing_agreements(self, sharing_agreements): - if sharing_agreements: - self.sharing_agreement_ids = [o.id for o in sharing_agreements] - self._sharing_agreements = sharing_agreements - - @property - def submitter(self): - """ - | Comment: The user who submitted the ticket. The submitter always becomes the author of the first comment on the ticket - """ - if self.api and self.submitter_id: - return self.api._get_user(self.submitter_id) - - @submitter.setter - def submitter(self, submitter): - if submitter: - self.submitter_id = submitter.id - self._submitter = submitter - - @property - def updated(self): - """ - | Comment: When this record last got updated - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class TicketAudit(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, api=None, audit=None, ticket=None, **kwargs): - - self.api = api - self.audit = audit - self.ticket = ticket - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class TicketEvent(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - child_events=None, - id=None, - ticket_id=None, - timestamp=None, - updater_id=None, - via=None, - **kwargs): - - self.api = api - self.child_events = child_events - self.id = id - self.ticket_id = ticket_id - self.timestamp = timestamp - self.updater_id = updater_id - self.via = via - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def ticket(self): - - if self.api and self.ticket_id: - return self.api._get_ticket(self.ticket_id) - - @ticket.setter - def ticket(self, ticket): - if ticket: - self.ticket_id = ticket.id - self._ticket = ticket - - @property - def updater(self): - - if self.api and self.updater_id: - return self.api._get_user(self.updater_id) - - @updater.setter - def updater(self, updater): - if updater: - self.updater_id = updater.id - self._updater = updater - - -class TicketField(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - active=None, - collapsed_for_agents=None, - created_at=None, - description=None, - editable_in_portal=None, - id=None, - position=None, - raw_description=None, - raw_title=None, - raw_title_in_portal=None, - regexp_for_validation=None, - required=None, - required_in_portal=None, - tag=None, - title=None, - title_in_portal=None, - type=None, - updated_at=None, - url=None, - visible_in_portal=None, - **kwargs): - - self.api = api - - # Comment: Whether this field is available - # Mandatory: no - # Read-only: no - # Type: boolean - self.active = active - - # Comment: If this field should be shown to agents by default or be hidden alongside infrequently used fields. Classic interface only - # Mandatory: no - # Read-only: no - # Type: boolean - self.collapsed_for_agents = collapsed_for_agents - - # Comment: The time the ticket field was created - # Mandatory: no - # Read-only: yes - # Type: date - self.created_at = created_at - - # Comment: The description of the purpose of this ticket field, shown to users - # Mandatory: no - # Read-only: no - # Type: string - self.description = description - - # Comment: Whether this field is editable by end users - # Mandatory: no - # Read-only: no - # Type: boolean - self.editable_in_portal = editable_in_portal - - # Comment: Automatically assigned upon creation - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: A relative position for the ticket fields that determines the order of ticket fields on a ticket. Note that positions 0 to 7 are reserved for system fields - # Mandatory: no - # Read-only: no - # Type: integer - self.position = position - - # Comment: The dynamic content placeholder, if present, or the "description" value, if not. See Dynamic Content - # Mandatory: no - # Read-only: no - # Type: string - self.raw_description = raw_description - - # Comment: The dynamic content placeholder, if present, or the "title" value, if not. See Dynamic Content - # Mandatory: no - # Read-only: no - # Type: string - self.raw_title = raw_title - - # Comment: The dynamic content placeholder, if present, or the "title_in_portal" value, if not. See Dynamic Content - # Mandatory: no - # Read-only: no - # Type: string - self.raw_title_in_portal = raw_title_in_portal - - # Comment: Regular expression field only. The validation pattern for a field value to be deemed valid. - # Mandatory: no - # Read-only: no - # Type: string - self.regexp_for_validation = regexp_for_validation - - # Comment: If it's required for this field to have a value when updated by agents - # Mandatory: no - # Read-only: no - # Type: boolean - self.required = required - - # Comment: If it's required for this field to have a value when updated by end users - # Mandatory: no - # Read-only: no - # Type: boolean - self.required_in_portal = required_in_portal - - # Comment: A tag value to set for checkbox fields when checked - # Mandatory: no - # Read-only: no - # Type: string - self.tag = tag - - # Comment: The title of the ticket field - # Mandatory: yes - # Read-only: no - # Type: string - self.title = title - - # Comment: The title of the ticket field when shown to end users - # Mandatory: no - # Read-only: no - # Type: string - self.title_in_portal = title_in_portal - - # Comment: The type of the ticket field: "checkbox", "date", "decimal", "integer", "regexp", "tagger", "text", or "textarea". Type is not editable once created. - # Mandatory: yes - # Read-only: no - # Type: string - self.type = type - - # Comment: The time of the last update of the ticket field - # Mandatory: no - # Read-only: yes - # Type: date - self.updated_at = updated_at - - # Comment: The URL for this resource - # Mandatory: no - # Read-only: yes - # Type: string - self.url = url - - # Comment: Whether this field is available to end users - # Mandatory: no - # Read-only: no - # Type: boolean - self.visible_in_portal = visible_in_portal - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - """ - | Comment: The time the ticket field was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - """ - | Comment: The time of the last update of the ticket field - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class TicketForm(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - active=None, - created_at=None, - default=None, - display_name=None, - end_user_visible=None, - id=None, - in_all_brands=None, - in_all_organizations=None, - name=None, - position=None, - raw_display_name=None, - raw_name=None, - restricted_brand_ids=None, - restricted_organization_ids=None, - ticket_field_ids=None, - updated_at=None, - url=None, - **kwargs): - - self.api = api - - # Comment: If the form is set as active - # Mandatory: no - # Read-only: no - # Type: boolean - self.active = active - self.created_at = created_at - - # Comment: Is the form the default form for this account - # Mandatory: no - # Read-only: no - # Type: boolean - self.default = default - - # Comment: The name of the form that is displayed to an end user - # Mandatory: no - # Read-only: no - # Type: string - self.display_name = display_name - - # Comment: Is the form visible to the end user - # Mandatory: no - # Read-only: no - # Type: boolean - self.end_user_visible = end_user_visible - self.id = id - - # Comment: Is the form available for use in all brands on this account - # Mandatory: no - # Read-only: no - # Type: boolean - self.in_all_brands = in_all_brands - self.in_all_organizations = in_all_organizations - - # Comment: The name of the form - # Mandatory: yes - # Read-only: no - # Type: string - self.name = name - - # Comment: The position of this form among other forms in the account, i.e. dropdown - # Mandatory: no - # Read-only: no - # Type: integer - self.position = position - - # Comment: The dynamic content placeholder, if present, or the "display_name" value, if not. See Dynamic Content - # Mandatory: no - # Read-only: no - # Type: string - self.raw_display_name = raw_display_name - - # Comment: The dynamic content placeholder, if present, or the "name" value, if not. See Dynamic Content - # Mandatory: no - # Read-only: no - # Type: string - self.raw_name = raw_name - - # Comment: ids of all brands that this ticket form is restricted to - # Mandatory: no - # Read-only: yes - # Type: array - self.restricted_brand_ids = restricted_brand_ids - self.restricted_organization_ids = restricted_organization_ids - - # Comment: ids of all ticket fields which are in this ticket form - # Mandatory: no - # Read-only: no - # Type: array - self.ticket_field_ids = ticket_field_ids - self.updated_at = updated_at - self.url = url - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def restricted_brands(self): - """ - | Comment: ids of all brands that this ticket form is restricted to - """ - if self.api and self.restricted_brand_ids: - return self.api._get_restricted_brands(self.restricted_brand_ids) - - @restricted_brands.setter - def restricted_brands(self, restricted_brands): - if restricted_brands: - self.restricted_brand_ids = [o.id for o in restricted_brands] - self._restricted_brands = restricted_brands - - @property - def restricted_organizations(self): - - if self.api and self.restricted_organization_ids: - return self.api._get_restricted_organizations( - self.restricted_organization_ids) - - @restricted_organizations.setter - def restricted_organizations(self, restricted_organizations): - if restricted_organizations: - self.restricted_organization_ids = [ - o.id for o in restricted_organizations - ] - self._restricted_organizations = restricted_organizations - - @property - def ticket_fields(self): - """ - | Comment: ids of all ticket fields which are in this ticket form - """ - if self.api and self.ticket_field_ids: - return self.api._get_ticket_fields(self.ticket_field_ids) - - @ticket_fields.setter - def ticket_fields(self, ticket_fields): - if ticket_fields: - self.ticket_field_ids = [o.id for o in ticket_fields] - self._ticket_fields = ticket_fields - - @property - def updated(self): - - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class TicketMetric(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - agent_wait_time_in_minutes=None, - assigned_at=None, - assignee_stations=None, - assignee_updated_at=None, - created_at=None, - first_resolution_time_in_minutes=None, - full_resolution_time_in_minutes=None, - group_stations=None, - id=None, - initially_assigned_at=None, - latest_comment_added_at=None, - on_hold_time_in_minutes=None, - reopens=None, - replies=None, - reply_time_in_minutes=None, - requester_updated_at=None, - requester_wait_time_in_minutes=None, - solved_at=None, - status_updated_at=None, - ticket_id=None, - updated_at=None, - **kwargs): - - self.api = api - - # Comment: Number of minutes the agent spent waiting inside and out of business hours - # Mandatory: no - # Read-only: yes - # Type: object - self.agent_wait_time_in_minutes = agent_wait_time_in_minutes - - # Comment: When the ticket was last assigned - # Mandatory: no - # Read-only: yes - # Type: date - self.assigned_at = assigned_at - - # Comment: Number of assignees this ticket had - # Mandatory: no - # Read-only: yes - # Type: integer - self.assignee_stations = assignee_stations - - # Comment: When the assignee last updated the ticket - # Mandatory: no - # Read-only: yes - # Type: date - self.assignee_updated_at = assignee_updated_at - - # Comment: When this record was created - # Mandatory: no - # Read-only: yes - # Type: date - self.created_at = created_at - - # Comment: Number of minutes to the first resolution time inside and out of business hours - # Mandatory: no - # Read-only: yes - # Type: object - self.first_resolution_time_in_minutes = first_resolution_time_in_minutes - - # Comment: Number of minutes to the full resolution inside and out of business hours - # Mandatory: no - # Read-only: yes - # Type: object - self.full_resolution_time_in_minutes = full_resolution_time_in_minutes - - # Comment: Number of groups this ticket passed through - # Mandatory: no - # Read-only: yes - # Type: integer - self.group_stations = group_stations - - # Comment: Automatically assigned - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: When the ticket was initially assigned - # Mandatory: no - # Read-only: yes - # Type: date - self.initially_assigned_at = initially_assigned_at - - # Comment: When the latest comment was added - # Mandatory: no - # Read-only: yes - # Type: date - self.latest_comment_added_at = latest_comment_added_at - self.on_hold_time_in_minutes = on_hold_time_in_minutes - - # Comment: Total number of times the ticket was reopened - # Mandatory: no - # Read-only: yes - # Type: integer - self.reopens = reopens - - # Comment: Total number of times ticket was replied to - # Mandatory: no - # Read-only: yes - # Type: integer - self.replies = replies - - # Comment: Number of minutes to the first reply inside and out of business hours - # Mandatory: no - # Read-only: yes - # Type: object - self.reply_time_in_minutes = reply_time_in_minutes - - # Comment: When the requester last updated the ticket - # Mandatory: no - # Read-only: yes - # Type: date - self.requester_updated_at = requester_updated_at - - # Comment: Number of minutes the requester spent waiting inside and out of business hours - # Mandatory: no - # Read-only: yes - # Type: object - self.requester_wait_time_in_minutes = requester_wait_time_in_minutes - - # Comment: When the ticket was solved - # Mandatory: no - # Read-only: yes - # Type: date - self.solved_at = solved_at - - # Comment: When the status was last updated - # Mandatory: no - # Read-only: yes - # Type: date - self.status_updated_at = status_updated_at - - # Comment: Id of the associated ticket - # Mandatory: no - # Read-only: yes - # Type: integer - self.ticket_id = ticket_id - - # Comment: When this record last got updated - # Mandatory: no - # Read-only: yes - # Type: date - self.updated_at = updated_at - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def assigned(self): - """ - | Comment: When the ticket was last assigned - """ - if self.assigned_at: - return dateutil.parser.parse(self.assigned_at) - - @assigned.setter - def assigned(self, assigned): - if assigned: - self.assigned_at = assigned - - @property - def assignee_updated(self): - """ - | Comment: When the assignee last updated the ticket - """ - if self.assignee_updated_at: - return dateutil.parser.parse(self.assignee_updated_at) - - @assignee_updated.setter - def assignee_updated(self, assignee_updated): - if assignee_updated: - self.assignee_updated_at = assignee_updated - - @property - def created(self): - """ - | Comment: When this record was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def initially_assigned(self): - """ - | Comment: When the ticket was initially assigned - """ - if self.initially_assigned_at: - return dateutil.parser.parse(self.initially_assigned_at) - - @initially_assigned.setter - def initially_assigned(self, initially_assigned): - if initially_assigned: - self.initially_assigned_at = initially_assigned - - @property - def latest_comment_added(self): - """ - | Comment: When the latest comment was added - """ - if self.latest_comment_added_at: - return dateutil.parser.parse(self.latest_comment_added_at) - - @latest_comment_added.setter - def latest_comment_added(self, latest_comment_added): - if latest_comment_added: - self.latest_comment_added_at = latest_comment_added - - @property - def requester_updated(self): - """ - | Comment: When the requester last updated the ticket - """ - if self.requester_updated_at: - return dateutil.parser.parse(self.requester_updated_at) - - @requester_updated.setter - def requester_updated(self, requester_updated): - if requester_updated: - self.requester_updated_at = requester_updated - - @property - def solved(self): - """ - | Comment: When the ticket was solved - """ - if self.solved_at: - return dateutil.parser.parse(self.solved_at) - - @solved.setter - def solved(self, solved): - if solved: - self.solved_at = solved - - @property - def status_updated(self): - """ - | Comment: When the status was last updated - """ - if self.status_updated_at: - return dateutil.parser.parse(self.status_updated_at) - - @status_updated.setter - def status_updated(self, status_updated): - if status_updated: - self.status_updated_at = status_updated - - @property - def ticket(self): - """ - | Comment: Id of the associated ticket - """ - if self.api and self.ticket_id: - return self.api._get_ticket(self.ticket_id) - - @ticket.setter - def ticket(self, ticket): - if ticket: - self.ticket_id = ticket.id - self._ticket = ticket - - @property - def updated(self): - """ - | Comment: When this record last got updated - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class TicketMetricEvent(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - deleted=None, - id=None, - instance_id=None, - metric=None, - sla=None, - status=None, - ticket_id=None, - time=None, - type=None, - **kwargs): - - self.api = api - self.deleted = deleted - - # Comment: Automatically assigned when the record is created - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: The instance of the metric associated with the event. See instance_id - # Mandatory: no - # Read-only: yes - # Type: integer - self.instance_id = instance_id - - # Comment: One of the following: agent_work_time, pausable_update_time, periodic_update_time, reply_time, requester_wait_time, or resolution_time - # Mandatory: no - # Read-only: yes - # Type: string - self.metric = metric - self.sla = sla - self.status = status - - # Comment: Id of the associated ticket - # Mandatory: no - # Read-only: yes - # Type: integer - self.ticket_id = ticket_id - - # Comment: The time the event occurred - # Mandatory: no - # Read-only: yes - # Type: date - self.time = time - - # Comment: One of the following: activate, pause, fulfill, apply_sla, breach, or update_status. See Metric event types - # Mandatory: no - # Read-only: yes - # Type: string - self.type = type - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def ticket(self): - """ - | Comment: Id of the associated ticket - """ - if self.api and self.ticket_id: - return self.api._get_ticket(self.ticket_id) - - @ticket.setter - def ticket(self, ticket): - if ticket: - self.ticket_id = ticket.id - self._ticket = ticket - - -class TicketMetricItem(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, api=None, business=None, calendar=None, **kwargs): - - self.api = api - self.business = business - self.calendar = calendar - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class TicketSharingEvent(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - action=None, - agreement_id=None, - id=None, - type=None, - **kwargs): - - self.api = api - self.action = action - self.agreement_id = agreement_id - self.id = id - self.type = type - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Topic(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - body=None, - created_at=None, - forum_id=None, - id=None, - locked=None, - pinned=None, - position=None, - search_phrases=None, - submitter_id=None, - tags=None, - title=None, - topic_type=None, - updated_at=None, - updater_id=None, - url=None, - **kwargs): - - self.api = api - self.body = body - self.created_at = created_at - self.forum_id = forum_id - self.id = id - self.locked = locked - self.pinned = pinned - self.position = position - self.search_phrases = search_phrases - self.submitter_id = submitter_id - self.tags = tags - self.title = title - self.topic_type = topic_type - self.updated_at = updated_at - self.updater_id = updater_id - self.url = url - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def forum(self): - - if self.api and self.forum_id: - return self.api._get_forum(self.forum_id) - - @forum.setter - def forum(self, forum): - if forum: - self.forum_id = forum.id - self._forum = forum - - @property - def submitter(self): - - if self.api and self.submitter_id: - return self.api._get_user(self.submitter_id) - - @submitter.setter - def submitter(self, submitter): - if submitter: - self.submitter_id = submitter.id - self._submitter = submitter - - @property - def updated(self): - - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - @property - def updater(self): - - if self.api and self.updater_id: - return self.api._get_user(self.updater_id) - - @updater.setter - def updater(self, updater): - if updater: - self.updater_id = updater.id - self._updater = updater - - -class Trigger(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - actions=None, - active=None, - conditions=None, - description=None, - id=None, - position=None, - title=None, - **kwargs): - - self.api = api - - # Comment: An array of Actions describing what the trigger will do - # Type: array - self.actions = actions - - # Comment: Whether the trigger is active - # Type: boolean - self.active = active - - # Comment: An object that describes the conditions under which the trigger will execute - # Type: :class:`Conditions` - self.conditions = conditions - - # Comment: The description of the trigger - # Type: string - self.description = description - - # Comment: Automatically assigned when created - # Type: integer - self.id = id - - # Comment: Position of the trigger, determines the order they will execute in - # Type: integer - self.position = position - - # Comment: The title of the trigger - # Type: string - self.title = title - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class TweetEvent(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - body=None, - direct_message=None, - id=None, - recipients=None, - type=None, - **kwargs): - - self.api = api - self.body = body - self.direct_message = direct_message - self.id = id - self.recipients = recipients - self.type = type - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Upload(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - attachment=None, - attachments=None, - expires_at=None, - token=None, - **kwargs): - - self.api = api - self.attachment = attachment - self.attachments = attachments - self.expires_at = expires_at - self.token = token - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def expires(self): - - if self.expires_at: - return dateutil.parser.parse(self.expires_at) - - @expires.setter - def expires(self, expires): - if expires: - self.expires_at = expires - - -class User(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - active=None, - alias=None, - chat_only=None, - created_at=None, - custom_role_id=None, - details=None, - email=None, - external_id=None, - id=None, - last_login_at=None, - locale=None, - locale_id=None, - moderator=None, - name=None, - notes=None, - only_private_comments=None, - organization_id=None, - phone=None, - photo=None, - restricted_agent=None, - role=None, - shared=None, - shared_agent=None, - signature=None, - suspended=None, - tags=None, - ticket_restriction=None, - time_zone=None, - two_factor_auth_enabled=None, - updated_at=None, - url=None, - user_fields=None, - verified=None, - **kwargs): - - self.api = api - - # Comment: false if the user has been deleted - # Mandatory: no - # Read-only: yes - # Type: boolean - self.active = active - - # Comment: An alias displayed to end users - # Mandatory: no - # Read-only: no - # Type: string - self.alias = alias - - # Comment: Whether or not the user is a chat-only agent - # Mandatory: no - # Read-only: yes - # Type: boolean - self.chat_only = chat_only - - # Comment: The time the user was created - # Mandatory: no - # Read-only: yes - # Type: date - self.created_at = created_at - - # Comment: A custom role if the user is an agent on the Enterprise plan - # Mandatory: no - # Read-only: no - # Type: integer - self.custom_role_id = custom_role_id - - # Comment: Any details you want to store about the user, such as an address - # Mandatory: no - # Read-only: no - # Type: string - self.details = details - - # Comment: The user's primary email address. Writeable on create only. On update, a secondary email is added. See Email Address - # Mandatory: no - # Read-only: no - # Type: string - self.email = email - - # Comment: A unique identifier from another system. The API treats the id as case insensitive. Example: ian1 and Ian1 are the same user - # Mandatory: no - # Read-only: no - # Type: string - self.external_id = external_id - - # Comment: Automatically assigned when the user is created - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: The last time the user signed in to Zendesk Support - # Mandatory: no - # Read-only: yes - # Type: date - self.last_login_at = last_login_at - - # Comment: The user's locale - # Mandatory: no - # Read-only: yes - # Type: string - self.locale = locale - - # Comment: The user's language identifier - # Mandatory: no - # Read-only: no - # Type: integer - self.locale_id = locale_id - - # Comment: Designates whether the user has forum moderation capabilities - # Mandatory: no - # Read-only: no - # Type: boolean - self.moderator = moderator - - # Comment: The user's name - # Mandatory: yes - # Read-only: no - # Type: string - self.name = name - - # Comment: Any notes you want to store about the user - # Mandatory: no - # Read-only: no - # Type: string - self.notes = notes - - # Comment: true if the user can only create private comments - # Mandatory: no - # Read-only: no - # Type: boolean - self.only_private_comments = only_private_comments - - # Comment: The id of the organization the user is associated with - # Mandatory: no - # Read-only: no - # Type: integer - self.organization_id = organization_id - - # Comment: The user's primary phone number. See Phone Number below - # Mandatory: no - # Read-only: no - # Type: string - self.phone = phone - - # Comment: The user's profile picture represented as an Attachment object - # Mandatory: no - # Read-only: no - # Type: :class:`Attachment` - self.photo = photo - - # Comment: If the agent has any restrictions; false for admins and unrestricted agents, true for other agents - # Mandatory: no - # Read-only: no - # Type: boolean - self.restricted_agent = restricted_agent - - # Comment: The user's role. Possible values are "end-user", "agent", or "admin" - # Mandatory: no - # Read-only: no - # Type: string - self.role = role - - # Comment: If the user is shared from a different Zendesk Support instance. Ticket sharing accounts only - # Mandatory: no - # Read-only: yes - # Type: boolean - self.shared = shared - - # Comment: If the user is a shared agent from a different Zendesk Support instance. Ticket sharing accounts only - # Mandatory: no - # Read-only: yes - # Type: boolean - self.shared_agent = shared_agent - - # Comment: The user's signature. Only agents and admins can have signatures - # Mandatory: no - # Read-only: no - # Type: string - self.signature = signature - - # Comment: If the agent is suspended. Tickets from suspended users are also suspended, and these users cannot sign in to the end user portal - # Mandatory: no - # Read-only: no - # Type: boolean - self.suspended = suspended - - # Comment: The user's tags. Only present if your account has user tagging enabled - # Mandatory: no - # Read-only: no - # Type: array - self.tags = tags - - # Comment: Specifies which tickets the user has access to. Possible values are: "organization", "groups", "assigned", "requested", null - # Mandatory: no - # Read-only: no - # Type: string - self.ticket_restriction = ticket_restriction - - # Comment: The user's time zone. See Time Zone - # Mandatory: no - # Read-only: no - # Type: string - self.time_zone = time_zone - - # Comment: If two factor authentication is enabled. - # Mandatory: no - # Read-only: yes - # Type: boolean - self.two_factor_auth_enabled = two_factor_auth_enabled - - # Comment: The time the user was last updated - # Mandatory: no - # Read-only: yes - # Type: date - self.updated_at = updated_at - - # Comment: The user's API url - # Mandatory: no - # Read-only: yes - # Type: string - self.url = url - - # Comment: Values of custom fields in the user's profile. See User Fields - # Mandatory: no - # Read-only: no - # Type: object - self.user_fields = user_fields - - # Comment: The user's primary identity is verified or not. For secondary identities, see User Identities - # Mandatory: no - # Read-only: no - # Type: boolean - self.verified = verified - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - """ - | Comment: The time the user was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def custom_role(self): - """ - | Comment: A custom role if the user is an agent on the Enterprise plan - """ - if self.api and self.custom_role_id: - return self.api._get_custom_role(self.custom_role_id) - - @custom_role.setter - def custom_role(self, custom_role): - if custom_role: - self.custom_role_id = custom_role.id - self._custom_role = custom_role - - @property - def last_login(self): - """ - | Comment: The last time the user signed in to Zendesk Support - """ - if self.last_login_at: - return dateutil.parser.parse(self.last_login_at) - - @last_login.setter - def last_login(self, last_login): - if last_login: - self.last_login_at = last_login - - @property - def organization(self): - """ - | Comment: The id of the organization the user is associated with - """ - if self.api and self.organization_id: - return self.api._get_organization(self.organization_id) - - @organization.setter - def organization(self, organization): - if organization: - self.organization_id = organization.id - self._organization = organization - - @property - def updated(self): - """ - | Comment: The time the user was last updated - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class UserField(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - active=None, - created_at=None, - description=None, - id=None, - key=None, - position=None, - raw_description=None, - raw_title=None, - regexp_for_validation=None, - title=None, - type=None, - updated_at=None, - url=None, - **kwargs): - - self.api = api - - # Comment: If true, this field is available for use - # Mandatory: no - # Read-only: no - # Type: boolean - self.active = active - - # Comment: The time the ticket field was created - # Mandatory: no - # Read-only: yes - # Type: date - self.created_at = created_at - - # Comment: User-defined description of this field's purpose - # Mandatory: no - # Read-only: no - # Type: string - self.description = description - - # Comment: Automatically assigned upon creation - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: A unique key that identifies this custom field. This is used for updating the field and referencing in placeholders. - # Mandatory: on create - # Read-only: no - # Type: string - self.key = key - - # Comment: Ordering of the field relative to other fields - # Mandatory: no - # Read-only: no - # Type: integer - self.position = position - - # Comment: The dynamic content placeholder, if present, or the "description" value, if not. See Dynamic Content - # Mandatory: no - # Read-only: no - # Type: string - self.raw_description = raw_description - - # Comment: The dynamic content placeholder, if present, or the "title" value, if not. See Dynamic Content - # Mandatory: no - # Read-only: no - # Type: string - self.raw_title = raw_title - - # Comment: Regular expression field only. The validation pattern for a field value to be deemed valid. - # Mandatory: no - # Read-only: no - # Type: string - self.regexp_for_validation = regexp_for_validation - - # Comment: The title of the custom field - # Mandatory: yes - # Read-only: no - # Type: string - self.title = title - - # Comment: Type of the custom field: "checkbox", "date", "decimal", "dropdown", "integer", "regexp", "text", or "textarea" - # Mandatory: yes - # Read-only: no - # Type: string - self.type = type - - # Comment: The time of the last update of the ticket field - # Mandatory: no - # Read-only: yes - # Type: date - self.updated_at = updated_at - - # Comment: The URL for this resource - # Mandatory: no - # Read-only: yes - # Type: string - self.url = url - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - """ - | Comment: The time the ticket field was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - """ - | Comment: The time of the last update of the ticket field - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class UserRelated(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - assigned_tickets=None, - ccd_tickets=None, - entry_subscriptions=None, - forum_subscriptions=None, - organization_subscriptions=None, - requested_tickets=None, - subscriptions=None, - topic_comments=None, - topics=None, - votes=None, - **kwargs): - - self.api = api - self.assigned_tickets = assigned_tickets - self.ccd_tickets = ccd_tickets - self.entry_subscriptions = entry_subscriptions - self.forum_subscriptions = forum_subscriptions - self.organization_subscriptions = organization_subscriptions - self.requested_tickets = requested_tickets - self.subscriptions = subscriptions - self.topic_comments = topic_comments - self.topics = topics - self.votes = votes - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Variant(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - active=None, - content=None, - created_at=None, - default=None, - id=None, - locale_id=None, - outdated=None, - updated_at=None, - url=None, - **kwargs): - - self.api = api - self.active = active - self.content = content - self.created_at = created_at - self.default = default - self.id = id - self.locale_id = locale_id - self.outdated = outdated - self.updated_at = updated_at - self.url = url - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class Via(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, api=None, source=None, **kwargs): - - self.api = api - self.source = source - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class View(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - active=None, - conditions=None, - created_at=None, - execution=None, - id=None, - position=None, - raw_title=None, - restriction=None, - sla_id=None, - title=None, - updated_at=None, - url=None, - **kwargs): - - self.api = api - - # Comment: Whether the view is active - # Read-only: no - # Type: boolean - self.active = active - - # Comment: An object describing how the view is constructed - # Read-only: no - # Type: :class:`Conditions` - self.conditions = conditions - - # Comment: The time the view was created - # Read-only: yes - # Type: date - self.created_at = created_at - - # Comment: An object describing how the view should be executed - # Read-only: no - # Type: :class:`Execute` - self.execution = execution - - # Comment: Automatically assigned when created - # Read-only: yes - # Type: integer - self.id = id - - # Comment: The position of the view - # Read-only: no - # Type: integer - self.position = position - self.raw_title = raw_title - - # Comment: Who may access this account. Will be null when everyone in the account can access it. - # Read-only: no - # Type: object - self.restriction = restriction - self.sla_id = sla_id - - # Comment: The title of the view - # Read-only: no - # Type: string - self.title = title - - # Comment: The time of the last update of the view - # Read-only: yes - # Type: date - self.updated_at = updated_at - self.url = url - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - """ - | Comment: The time the view was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def sla(self): - - if self.api and self.sla_id: - return self.api._get_sla(self.sla_id) - - @sla.setter - def sla(self, sla): - if sla: - self.sla_id = sla.id - self._sla = sla - - @property - def updated(self): - """ - | Comment: The time of the last update of the view - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class ViewCount(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - channel=None, - fresh=None, - poll_wait=None, - pretty=None, - refresh=None, - url=None, - value=None, - view_id=None, - **kwargs): - - self.api = api - self.channel = channel - self.fresh = fresh - self.poll_wait = poll_wait - self.pretty = pretty - self.refresh = refresh - self.url = url - self.value = value - self.view_id = view_id - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def view(self): - - if self.api and self.view_id: - return self.api._get_view(self.view_id) - - @view.setter - def view(self, view): - if view: - self.view_id = view.id - self._view = view - - -class ViewRow(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - created=None, - custom_fields=None, - fields=None, - group_id=None, - priority=None, - requester_id=None, - score=None, - subject=None, - ticket=None, - **kwargs): - - self.api = api - self.created = created - self.custom_fields = custom_fields - self.fields = fields - self.group_id = group_id - self.priority = priority - self.requester_id = requester_id - self.score = score - self.subject = subject - self.ticket = ticket - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def group(self): - - if self.api and self.group_id: - return self.api._get_group(self.group_id) - - @group.setter - def group(self, group): - if group: - self.group_id = group.id - self._group = group - - @property - def requester(self): - - if self.api and self.requester_id: - return self.api._get_user(self.requester_id) - - @requester.setter - def requester(self, requester): - if requester: - self.requester_id = requester.id - self._requester = requester - - -class VoiceCommentEvent(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - attachments=None, - author_id=None, - body=None, - data=None, - formatted_from=None, - formatted_to=None, - html_body=None, - id=None, - public=None, - transcription_visible=None, - trusted=None, - type=None, - **kwargs): - - self.api = api - self.attachments = attachments - self.author_id = author_id - self.body = body - self.data = data - self.formatted_from = formatted_from - self.formatted_to = formatted_to - self.html_body = html_body - self.id = id - self.public = public - self.transcription_visible = transcription_visible - self.trusted = trusted - self.type = type - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def author(self): - - if self.api and self.author_id: - return self.api._get_user(self.author_id) - - @author.setter - def author(self, author): - if author: - self.author_id = author.id - self._author = author + +###################################################################### +# Do not modify, these classes are autogenerated by gen_classes.py # +###################################################################### + +import json +import dateutil.parser +from zenpy.lib.util import json_encode_for_printing, json_encode_for_zendesk + + +class BaseObject(object): + """ + Base for all Zenpy objects. Keeps track of which attributes have been modified. + """ + + def __new__(cls, *args, **kwargs): + instance = super(BaseObject, cls).__new__(cls) + instance.__dict__['_dirty_attributes'] = set() + instance.__dict__['_dirty_callback'] = None + instance.__dict__['_always_dirty'] = set() + return instance + + def __setattr__(self, key, value): + if key not in ('_dirty', '_dirty_callback', '_always_dirty'): + self.__dict__['_dirty_attributes'].add(key) + if self._dirty_callback is not None: + self._dirty_callback() + object.__setattr__(self, key, value) + + def _clean_dirty(self, obj=None): + """ Recursively clean self and all child objects. """ + obj = obj or self + obj.__dict__['_dirty_attributes'].clear() + obj._dirty = False + for key, val in vars(obj).items(): + if isinstance(val, BaseObject): + self._clean_dirty(val) + else: + func = getattr(val, '_clean_dirty', None) + if callable(func): + func() + + def _set_dirty(self, obj=None): + """ Recursively set self and all child objects _dirty flag. """ + obj = obj or self + for key, value in vars(obj).items(): + if key not in ('api', '_dirty_attributes', '_always_dirty', '_dirty_callback', '_dirty'): + setattr(obj, key, value) + if isinstance(value, BaseObject): + self._set_dirty(value) + + def to_json(self, indent=2): + """ Return self formatted as JSON. """ + return json.dumps(self, default=json_encode_for_printing, indent=indent) + + def to_dict(self, serialize=False): + """ + This method returns the object as a Python dict. If serialize is passed, only those attributes + that have been modified will be included in the result. + """ + if serialize: + encode_method = json_encode_for_zendesk + else: + encode_method = json_encode_for_printing + return json.loads(json.dumps(self._to_dict(serialize=serialize), default=encode_method)) + + def _to_dict(self, serialize=False): + """ + This method works by copying self.__dict__, and removing everything that should not be serialized. + """ + copy_dict = self.__dict__.copy() + for key, value in vars(self).items(): + # We want to send all ids to Zendesk always + if serialize and key == 'id': + continue + + # If this is a Zenpy object, convert it to a dict. + if not serialize and isinstance(value, BaseObject): + copy_dict[key] = copy_dict.pop(key).to_dict() + + # This object has a flag indicating it has been dirtied, so we want to send it off. + elif serialize and getattr(value, '_dirty', False): + continue + + # Here we have an attribute that should always be sent to Zendesk. + elif serialize and key in self._always_dirty: + continue + + # These are for internal tracking, so just delete. + elif key in ('api', '_dirty_attributes', '_always_dirty', '_dirty_callback', '_dirty'): + del copy_dict[key] + + # If the attribute has not been modified, do not send it. + elif serialize and key not in self._dirty_attributes: + del copy_dict[key] + + # Some reserved words are prefixed with an underscore, remove it here. + elif key.startswith('_'): + copy_dict[key[1:]] = copy_dict[key] + del copy_dict[key] + return copy_dict + + def __repr__(self): + class_name = type(self).__name__ + if class_name in ('UserField',): + return "{}()".format(class_name) + + def formatted(item): + return item if (isinstance(item, int) or item is None) else "'{}'".format(item) + + for identifier in ('id', 'token', 'key', 'name', 'account_key'): + if hasattr(self, identifier): + return "{}({}={})".format(class_name, identifier, formatted(getattr(self, identifier))) + return "{}()".format(class_name) + + +class Activity(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + actor=None, + created_at=None, + id=None, + title=None, + updated_at=None, + url=None, + user=None, + verb=None, + **kwargs): + + self.api = api + self.actor = actor + self.created_at = created_at + self.id = id + self.title = title + self.updated_at = updated_at + self.url = url + self.user = user + self.verb = verb + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class AgentMacroReference(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + id=None, + macro_id=None, + macro_title=None, + type=None, + via=None, + **kwargs): + + self.api = api + self.id = id + self.macro_id = macro_id + self.macro_title = macro_title + self.type = type + self.via = via + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def macro(self): + + if self.api and self.macro_id: + return self.api._get_macro(self.macro_id) + + @macro.setter + def macro(self, macro): + if macro: + self.macro_id = macro.id + self._macro = macro + + +class Attachment(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + content_type=None, + content_url=None, + file_name=None, + id=None, + size=None, + thumbnails=None, + **kwargs): + + self.api = api + + # Comment: The content type of the image. Example value: image/png + # Read-only: yes + # Type: string + self.content_type = content_type + + # Comment: A full URL where the attachment image file can be downloaded + # Read-only: yes + # Type: string + self.content_url = content_url + + # Comment: The name of the image file + # Read-only: yes + # Type: string + self.file_name = file_name + + # Comment: Automatically assigned when created + # Read-only: yes + # Type: integer + self.id = id + + # Comment: The size of the image file in bytes + # Read-only: yes + # Type: integer + self.size = size + + # Comment: An array of Photo objects. Note that thumbnails do not have thumbnails. + # Read-only: yes + # Type: array + self.thumbnails = thumbnails + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Audit(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + author_id=None, + created_at=None, + events=None, + id=None, + metadata=None, + ticket_id=None, + via=None, + **kwargs): + + self.api = api + self.author_id = author_id + self.created_at = created_at + self.events = events + self.id = id + self.metadata = metadata + self.ticket_id = ticket_id + self.via = via + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def author(self): + + if self.api and self.author_id: + return self.api._get_user(self.author_id) + + @author.setter + def author(self, author): + if author: + self.author_id = author.id + self._author = author + + @property + def created(self): + + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def ticket(self): + + if self.api and self.ticket_id: + return self.api._get_ticket(self.ticket_id) + + @ticket.setter + def ticket(self, ticket): + if ticket: + self.ticket_id = ticket.id + self._ticket = ticket + + +class Automation(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + actions=None, + active=None, + conditions=None, + created_at=None, + id=None, + position=None, + raw_title=None, + title=None, + updated_at=None, + url=None, + **kwargs): + + self.api = api + + # Comment: An object describing what the automation will do + # Type: :class:`Actions` + self.actions = actions + + # Comment: Whether the automation is active + # Type: boolean + self.active = active + + # Comment: An object that describes the conditions under which the automation will execute + # Type: :class:`Conditions` + self.conditions = conditions + + # Comment: The time the automation was created + # Type: date + self.created_at = created_at + + # Comment: Automatically assigned when created + # Type: integer + self.id = id + + # Comment: Position of the automation, determines the order they will execute in + # Type: integer + self.position = position + self.raw_title = raw_title + + # Comment: The title of the automation + # Type: string + self.title = title + + # Comment: The time of the last update of the automation + # Type: date + self.updated_at = updated_at + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + """ + | Comment: The time the automation was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + """ + | Comment: The time of the last update of the automation + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class Brand(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + active=None, + brand_url=None, + created_at=None, + default=None, + has_help_center=None, + help_center_state=None, + host_mapping=None, + id=None, + logo=None, + name=None, + subdomain=None, + updated_at=None, + url=None, + **kwargs): + + self.api = api + + # Comment: If the brand is set as active + # Mandatory: no + # Read-only: no + # Type: boolean + self.active = active + + # Comment: The url of the brand + # Mandatory: no + # Read-only: no + # Type: string + self.brand_url = brand_url + + # Comment: The time the brand was created + # Mandatory: no + # Read-only: yes + # Type: date + self.created_at = created_at + + # Comment: Is the brand the default brand for this account + # Mandatory: no + # Read-only: no + # Type: boolean + self.default = default + + # Comment: If the brand has a Help Center + # Mandatory: no + # Read-only: no + # Type: boolean + self.has_help_center = has_help_center + + # Comment: The state of the Help Center: enabled, disabled, or restricted + # Mandatory: no + # Read-only: yes + # Type: string + self.help_center_state = help_center_state + + # Comment: The hostmapping to this brand, if any (only admins view this key) + # Mandatory: no + # Read-only: no + # Type: string + self.host_mapping = host_mapping + + # Comment: Automatically assigned when the brand is created + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: Logo image for this brand + # Mandatory: no + # Read-only: no + # Type: :class:`Attachment` + self.logo = logo + + # Comment: The name of the brand + # Mandatory: yes + # Read-only: no + # Type: string + self.name = name + + # Comment: The subdomain of the brand + # Mandatory: yes + # Read-only: no + # Type: string + self.subdomain = subdomain + + # Comment: The time of the last update of the brand + # Mandatory: no + # Read-only: yes + # Type: date + self.updated_at = updated_at + + # Comment: The API url of this brand + # Mandatory: no + # Read-only: yes + # Type: string + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + """ + | Comment: The time the brand was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + """ + | Comment: The time of the last update of the brand + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class CcEvent(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + id=None, + recipients=None, + type=None, + via=None, + **kwargs): + + self.api = api + self.id = id + self.recipients = recipients + self.type = type + self.via = via + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class ChangeEvent(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + field_name=None, + id=None, + previous_value=None, + type=None, + value=None, + **kwargs): + + self.api = api + self.field_name = field_name + self.id = id + self.previous_value = previous_value + self.type = type + self.value = value + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Comment(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + attachments=None, + author_id=None, + body=None, + created_at=None, + id=None, + metadata=None, + public=None, + type=None, + via=None, + **kwargs): + + self.api = api + self.attachments = attachments + self.author_id = author_id + self.body = body + self.created_at = created_at + self.id = id + self.metadata = metadata + self.public = public + self.type = type + self.via = via + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def author(self): + + if self.api and self.author_id: + return self.api._get_user(self.author_id) + + @author.setter + def author(self, author): + if author: + self.author_id = author.id + self._author = author + + @property + def created(self): + + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + +class CommentPrivacyChangeEvent(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + comment_id=None, + id=None, + public=None, + type=None, + **kwargs): + + self.api = api + self.comment_id = comment_id + self.id = id + self.public = public + self.type = type + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def comment(self): + + if self.api and self.comment_id: + return self.api._get_comment(self.comment_id) + + @comment.setter + def comment(self, comment): + if comment: + self.comment_id = comment.id + self._comment = comment + + +class Conditions(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, api=None, all=None, any=None, **kwargs): + + self.api = api + self.all = all + self.any = any + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class CreateEvent(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + field_name=None, + id=None, + type=None, + value=None, + **kwargs): + + self.api = api + self.field_name = field_name + self.id = id + self.type = type + self.value = value + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class CustomAgentRole(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + configuration=None, + created_at=None, + description=None, + id=None, + name=None, + role_type=None, + updated_at=None, + **kwargs): + + self.api = api + self.configuration = configuration + self.created_at = created_at + self.description = description + self.id = id + self.name = name + self.role_type = role_type + self.updated_at = updated_at + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class CustomField(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, api=None, id=None, value=None, **kwargs): + + self.api = api + self.id = id + self.value = value + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class CustomFieldOption(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + id=None, + name=None, + position=None, + raw_name=None, + url=None, + value=None, + **kwargs): + + self.api = api + self.id = id + self.name = name + self.position = position + self.raw_name = raw_name + self.url = url + self.value = value + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Definitions(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, api=None, all=None, any=None, **kwargs): + + self.api = api + self.all = all + self.any = any + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class ErrorEvent(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, api=None, id=None, message=None, type=None, **kwargs): + + self.api = api + self.id = id + self.message = message + self.type = type + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Export(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, api=None, status=None, view_id=None, **kwargs): + + self.api = api + self.status = status + self.view_id = view_id + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def view(self): + + if self.api and self.view_id: + return self.api._get_view(self.view_id) + + @view.setter + def view(self, view): + if view: + self.view_id = view.id + self._view = view + + +class ExternalEvent(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + body=None, + id=None, + resource=None, + type=None, + **kwargs): + + self.api = api + self.body = body + self.id = id + self.resource = resource + self.type = type + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class FacebookCommentEvent(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + attachments=None, + author_id=None, + body=None, + data=None, + graph_object_id=None, + html_body=None, + id=None, + public=None, + trusted=None, + type=None, + **kwargs): + + self.api = api + self.attachments = attachments + self.author_id = author_id + self.body = body + self.data = data + self.graph_object_id = graph_object_id + self.html_body = html_body + self.id = id + self.public = public + self.trusted = trusted + self.type = type + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def author(self): + + if self.api and self.author_id: + return self.api._get_user(self.author_id) + + @author.setter + def author(self, author): + if author: + self.author_id = author.id + self._author = author + + +class FacebookEvent(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + body=None, + communication=None, + id=None, + page=None, + ticket_via=None, + type=None, + **kwargs): + + self.api = api + self.body = body + self.communication = communication + self.id = id + self.page = page + self.ticket_via = ticket_via + self.type = type + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Group(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + created_at=None, + deleted=None, + id=None, + name=None, + updated_at=None, + url=None, + **kwargs): + + self.api = api + + # Comment: The time the group was created + # Mandatory: no + # Read-only: yes + # Type: date + self.created_at = created_at + + # Comment: Deleted groups get marked as such + # Mandatory: no + # Read-only: yes + # Type: boolean + self.deleted = deleted + + # Comment: Automatically assigned when creating groups + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: The name of the group + # Mandatory: yes + # Read-only: no + # Type: string + self.name = name + + # Comment: The time of the last update of the group + # Mandatory: no + # Read-only: yes + # Type: date + self.updated_at = updated_at + + # Comment: The API url of this group + # Mandatory: no + # Read-only: yes + # Type: string + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + """ + | Comment: The time the group was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + """ + | Comment: The time of the last update of the group + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class GroupMembership(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + created_at=None, + default=None, + group_id=None, + id=None, + updated_at=None, + url=None, + user_id=None, + **kwargs): + + self.api = api + + # Comment: The time the membership was created + # Mandatory: no + # Read-only: yes + # Type: date + self.created_at = created_at + + # Comment: If true, tickets assigned directly to the agent will assume this membership's group. + # Mandatory: no + # Read-only: no + # Type: boolean + self.default = default + + # Comment: The id of a group + # Mandatory: yes + # Read-only: no + # Type: integer + self.group_id = group_id + + # Comment: Automatically assigned upon creation + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: The time of the last update of the membership + # Mandatory: no + # Read-only: yes + # Type: date + self.updated_at = updated_at + + # Comment: The API url of this record + # Mandatory: no + # Read-only: yes + # Type: string + self.url = url + + # Comment: The id of an agent + # Mandatory: yes + # Read-only: no + # Type: integer + self.user_id = user_id + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + """ + | Comment: The time the membership was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def group(self): + """ + | Comment: The id of a group + """ + if self.api and self.group_id: + return self.api._get_group(self.group_id) + + @group.setter + def group(self, group): + if group: + self.group_id = group.id + self._group = group + + @property + def updated(self): + """ + | Comment: The time of the last update of the membership + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + @property + def user(self): + """ + | Comment: The id of an agent + """ + if self.api and self.user_id: + return self.api._get_user(self.user_id) + + @user.setter + def user(self, user): + if user: + self.user_id = user.id + self._user = user + + +class Identity(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + created_at=None, + deliverable_state=None, + id=None, + primary=None, + type=None, + undeliverable_count=None, + updated_at=None, + url=None, + user_id=None, + value=None, + verified=None, + **kwargs): + + self.api = api + self.created_at = created_at + self.deliverable_state = deliverable_state + self.id = id + self.primary = primary + self.type = type + self.undeliverable_count = undeliverable_count + self.updated_at = updated_at + self.url = url + self.user_id = user_id + self.value = value + self.verified = verified + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + @property + def user(self): + + if self.api and self.user_id: + return self.api._get_user(self.user_id) + + @user.setter + def user(self, user): + if user: + self.user_id = user.id + self._user = user + + +class Item(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + created_at=None, + default_locale_id=None, + id=None, + name=None, + outdated=None, + placeholder=None, + updated_at=None, + url=None, + variants=None, + **kwargs): + + self.api = api + self.created_at = created_at + self.default_locale_id = default_locale_id + self.id = id + self.name = name + self.outdated = outdated + self.placeholder = placeholder + self.updated_at = updated_at + self.url = url + self.variants = variants + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def default_locale(self): + + if self.api and self.default_locale_id: + return self.api._get_default_locale(self.default_locale_id) + + @default_locale.setter + def default_locale(self, default_locale): + if default_locale: + self.default_locale_id = default_locale.id + self._default_locale = default_locale + + @property + def updated(self): + + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class JobStatus(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + id=None, + message=None, + progress=None, + results=None, + status=None, + total=None, + url=None, + **kwargs): + + self.api = api + self.id = id + self.message = message + self.progress = progress + self.results = results + self.status = status + self.total = total + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class JobStatusResult(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + action=None, + errors=None, + id=None, + status=None, + success=None, + title=None, + **kwargs): + + self.api = api + self.action = action + self.errors = errors + self.id = id + self.status = status + self.success = success + self.title = title + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Link(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + created_at=None, + id=None, + issue_id=None, + issue_key=None, + ticket_id=None, + updated_at=None, + url=None, + **kwargs): + + self.api = api + self.created_at = created_at + self.id = id + self.issue_id = issue_id + self.issue_key = issue_key + self.ticket_id = ticket_id + self.updated_at = updated_at + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def ticket(self): + + if self.api and self.ticket_id: + return self.api._get_ticket(self.ticket_id) + + @ticket.setter + def ticket(self, ticket): + if ticket: + self.ticket_id = ticket.id + self._ticket = ticket + + @property + def updated(self): + + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class Locale(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + created_at=None, + default=None, + id=None, + locale=None, + name=None, + native_name=None, + presentation_name=None, + rtl=None, + updated_at=None, + url=None, + **kwargs): + + self.api = api + self.created_at = created_at + self.default = default + + # Description: Either the ID or the bcp-47 code of the locale (es-419, en-us, pr-br) + # Type: string + self.id = id + self.locale = locale + self.name = name + self.native_name = native_name + self.presentation_name = presentation_name + self.rtl = rtl + self.updated_at = updated_at + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class LogmeinTranscriptEvent(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, api=None, body=None, id=None, type=None, **kwargs): + + self.api = api + self.body = body + self.id = id + self.type = type + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Macro(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + actions=None, + active=None, + created_at=None, + description=None, + id=None, + position=None, + restriction=None, + title=None, + updated_at=None, + url=None, + **kwargs): + + self.api = api + + # Comment: An object describing what the macro will do + # Type: :class:`Actions` + self.actions = actions + + # Comment: Useful for determining if the macro should be displayed + # Type: boolean + self.active = active + + # Comment: The time the macro was created + # Type: date + self.created_at = created_at + + # Comment: The description of the macro + # Type: string + self.description = description + + # Comment: Automatically assigned when created + # Type: integer + self.id = id + + # Comment: The position of the macro + # Type: integer + self.position = position + + # Comment: Who may access this macro. Will be null when everyone in the account can access it + # Type: object + self.restriction = restriction + + # Comment: The title of the macro + # Type: string + self.title = title + + # Comment: The time of the last update of the macro + # Type: date + self.updated_at = updated_at + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + """ + | Comment: The time the macro was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + """ + | Comment: The time of the last update of the macro + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class MacroResult(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, api=None, ticket=None, **kwargs): + + self.api = api + self.ticket = ticket + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Metadata(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, api=None, custom=None, system=None, **kwargs): + + self.api = api + self.custom = custom + self.system = system + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class NotificationEvent(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + body=None, + id=None, + recipients=None, + subject=None, + type=None, + via=None, + **kwargs): + + self.api = api + self.body = body + self.id = id + self.recipients = recipients + self.subject = subject + self.type = type + self.via = via + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Organization(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + created_at=None, + details=None, + domain_names=None, + external_id=None, + group_id=None, + id=None, + name=None, + notes=None, + organization_fields=None, + shared_comments=None, + shared_tickets=None, + tags=None, + updated_at=None, + url=None, + **kwargs): + + self.api = api + + # Comment: The time the organization was created + # Mandatory: no + # Read-only: yes + # Type: date + self.created_at = created_at + + # Comment: Any details obout the organization, such as the address + # Mandatory: no + # Read-only: no + # Type: string + self.details = details + + # Comment: An array of domain names associated with this organization + # Mandatory: no + # Read-only: no + # Type: array + self.domain_names = domain_names + + # Comment: A unique external id to associate organizations to an external record + # Mandatory: no + # Read-only: no + # Type: string + self.external_id = external_id + + # Comment: New tickets from users in this organization are automatically put in this group + # Mandatory: no + # Read-only: no + # Type: integer + self.group_id = group_id + + # Comment: Automatically assigned when the organization is created + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: A unique name for the organization + # Mandatory: yes + # Read-only: no + # Type: string + self.name = name + + # Comment: Any notes you have about the organization + # Mandatory: no + # Read-only: no + # Type: string + self.notes = notes + + # Comment: Custom fields for this organization + # Mandatory: no + # Read-only: no + # Type: :class:`hash` + self.organization_fields = organization_fields + + # Comment: End users in this organization are able to see each other's comments on tickets + # Mandatory: no + # Read-only: no + # Type: boolean + self.shared_comments = shared_comments + + # Comment: End users in this organization are able to see each other's tickets + # Mandatory: no + # Read-only: no + # Type: boolean + self.shared_tickets = shared_tickets + + # Comment: The tags of the organization + # Mandatory: no + # Read-only: no + # Type: array + self.tags = tags + + # Comment: The time of the last update of the organization + # Mandatory: no + # Read-only: yes + # Type: date + self.updated_at = updated_at + + # Comment: The API url of this organization + # Mandatory: no + # Read-only: yes + # Type: string + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + """ + | Comment: The time the organization was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def group(self): + """ + | Comment: New tickets from users in this organization are automatically put in this group + """ + if self.api and self.group_id: + return self.api._get_group(self.group_id) + + @group.setter + def group(self, group): + if group: + self.group_id = group.id + self._group = group + + @property + def updated(self): + """ + | Comment: The time of the last update of the organization + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class OrganizationActivityEvent(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + body=None, + id=None, + recipients=None, + subject=None, + type=None, + via=None, + **kwargs): + + self.api = api + self.body = body + self.id = id + self.recipients = recipients + self.subject = subject + self.type = type + self.via = via + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class OrganizationField(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + active=None, + created_at=None, + description=None, + id=None, + key=None, + position=None, + raw_description=None, + raw_title=None, + regexp_for_validation=None, + title=None, + type=None, + updated_at=None, + url=None, + **kwargs): + + self.api = api + + # Comment: If true, this field is available for use + # Mandatory: no + # Read-only: no + # Type: boolean + self.active = active + + # Comment: The time the ticket field was created + # Mandatory: no + # Read-only: yes + # Type: date + self.created_at = created_at + + # Comment: User-defined description of this field's purpose + # Mandatory: no + # Read-only: no + # Type: string + self.description = description + + # Comment: Automatically assigned upon creation + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: A unique key that identifies this custom field. This is used for updating the field and referencing in placeholders. + # Mandatory: on create + # Read-only: no + # Type: string + self.key = key + + # Comment: Ordering of the field relative to other fields + # Mandatory: no + # Read-only: no + # Type: integer + self.position = position + + # Comment: The dynamic content placeholder, if present, or the "description" value, if not. See Dynamic Content + # Mandatory: no + # Read-only: no + # Type: string + self.raw_description = raw_description + + # Comment: The dynamic content placeholder, if present, or the "title" value, if not. See Dynamic Content + # Mandatory: no + # Read-only: no + # Type: string + self.raw_title = raw_title + + # Comment: Regular expression field only. The validation pattern for a field value to be deemed valid. + # Mandatory: no + # Read-only: no + # Type: string + self.regexp_for_validation = regexp_for_validation + + # Comment: The title of the custom field + # Mandatory: yes + # Read-only: no + # Type: string + self.title = title + + # Comment: Type of the custom field: "checkbox", "date", "decimal", "dropdown", "integer", "regexp", "text", or "textarea" + # Mandatory: yes + # Read-only: no + # Type: string + self.type = type + + # Comment: The time of the last update of the ticket field + # Mandatory: no + # Read-only: yes + # Type: date + self.updated_at = updated_at + + # Comment: The URL for this resource + # Mandatory: no + # Read-only: yes + # Type: string + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + """ + | Comment: The time the ticket field was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + """ + | Comment: The time of the last update of the ticket field + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class OrganizationMembership(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + created_at=None, + default=None, + id=None, + organization_id=None, + updated_at=None, + url=None, + user_id=None, + **kwargs): + + self.api = api + + # Comment: When this record was created + # Mandatory: no + # Read-only: yes + # Type: date + self.created_at = created_at + + # Comment: Denotes whether this is the default organization membership for the user. If false, returns null + # Mandatory: yes + # Read-only: no + # Type: boolean + self.default = default + + # Comment: Automatically assigned when the membership is created + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: The ID of the organization associated with this user, in this membership + # Mandatory: yes + # Read-only: yes + # Type: integer + self.organization_id = organization_id + + # Comment: When this record last got updated + # Mandatory: no + # Read-only: yes + # Type: date + self.updated_at = updated_at + + # Comment: The API url of this membership + # Mandatory: no + # Read-only: yes + # Type: string + self.url = url + + # Comment: The ID of the user for whom this memberships belongs + # Mandatory: yes + # Read-only: yes + # Type: integer + self.user_id = user_id + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + """ + | Comment: When this record was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def organization(self): + """ + | Comment: The ID of the organization associated with this user, in this membership + """ + if self.api and self.organization_id: + return self.api._get_organization(self.organization_id) + + @organization.setter + def organization(self, organization): + if organization: + self.organization_id = organization.id + self._organization = organization + + @property + def updated(self): + """ + | Comment: When this record last got updated + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + @property + def user(self): + """ + | Comment: The ID of the user for whom this memberships belongs + """ + if self.api and self.user_id: + return self.api._get_user(self.user_id) + + @user.setter + def user(self, user): + if user: + self.user_id = user.id + self._user = user + + +class PolicyMetric(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + business_hours=None, + metric=None, + priority=None, + target=None, + **kwargs): + + self.api = api + self.business_hours = business_hours + self.metric = metric + self.priority = priority + self.target = target + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class PushEvent(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + id=None, + type=None, + value=None, + value_reference=None, + **kwargs): + + self.api = api + self.id = id + self.type = type + self.value = value + self.value_reference = value_reference + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Recipient(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + created_at=None, + delivered_at=None, + delivery_id=None, + id=None, + survey_id=None, + survey_name=None, + updated_at=None, + user_email=None, + user_id=None, + user_name=None, + **kwargs): + + self.api = api + self.created_at = created_at + self.delivered_at = delivered_at + self.delivery_id = delivery_id + self.id = id + self.survey_id = survey_id + self.survey_name = survey_name + self.updated_at = updated_at + self.user_email = user_email + self.user_id = user_id + self.user_name = user_name + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def delivered(self): + + if self.delivered_at: + return dateutil.parser.parse(self.delivered_at) + + @delivered.setter + def delivered(self, delivered): + if delivered: + self.delivered_at = delivered + + @property + def delivery(self): + + if self.api and self.delivery_id: + return self.api._get_delivery(self.delivery_id) + + @delivery.setter + def delivery(self, delivery): + if delivery: + self.delivery_id = delivery.id + self._delivery = delivery + + @property + def survey(self): + + if self.api and self.survey_id: + return self.api._get_survey(self.survey_id) + + @survey.setter + def survey(self, survey): + if survey: + self.survey_id = survey.id + self._survey = survey + + @property + def updated(self): + + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + @property + def user(self): + + if self.api and self.user_id: + return self.api._get_user(self.user_id) + + @user.setter + def user(self, user): + if user: + self.user_id = user.id + self._user = user + + +class RecipientAddress(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + brand_id=None, + created_at=None, + default=None, + email=None, + forwarding_status=None, + id=None, + name=None, + spf_status=None, + updated_at=None, + **kwargs): + + self.api = api + self.brand_id = brand_id + self.created_at = created_at + self.default = default + self.email = email + self.forwarding_status = forwarding_status + self.id = id + self.name = name + self.spf_status = spf_status + self.updated_at = updated_at + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def brand(self): + + if self.api and self.brand_id: + return self.api._get_brand(self.brand_id) + + @brand.setter + def brand(self, brand): + if brand: + self.brand_id = brand.id + self._brand = brand + + @property + def created(self): + + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class Request(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + assignee_id=None, + can_be_solved_by_me=None, + collaborator_ids=None, + created_at=None, + custom_fields=None, + description=None, + due_at=None, + fields=None, + id=None, + organization_id=None, + priority=None, + requester_id=None, + status=None, + subject=None, + type=None, + updated_at=None, + url=None, + via=None, + **kwargs): + + self.api = api + + # Comment: The id of the assignee if the field is visible to end users + # Mandatory: no + # Read-only: yes + # Type: integer + self.assignee_id = assignee_id + + # Comment: If true, end user can mark request as solved. + # Mandatory: no + # Read-only: yes + # Type: boolean + self.can_be_solved_by_me = can_be_solved_by_me + + # Comment: Who are currently CC'ed on the ticket + # Mandatory: no + # Read-only: yes + # Type: array + self.collaborator_ids = collaborator_ids + + # Comment: When this record was created + # Mandatory: no + # Read-only: yes + # Type: date + self.created_at = created_at + + # Comment: The fields and entries for this request + # Mandatory: no + # Read-only: no + # Type: :class:`Array` + self.custom_fields = custom_fields + + # Comment: The first comment on the request + # Mandatory: yes + # Read-only: yes + # Type: string + self.description = description + + # Comment: When the task is due (only applies if the request is of type "task") + # Mandatory: no + # Read-only: no + # Type: date + self.due_at = due_at + self.fields = fields + + # Comment: Automatically assigned when creating requests + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: The organization of the requester + # Mandatory: no + # Read-only: yes + # Type: integer + self.organization_id = organization_id + + # Comment: The priority of the request, "low", "normal", "high", "urgent" + # Mandatory: no + # Read-only: no + # Type: string + self.priority = priority + + # Comment: The id of the requester + # Mandatory: no + # Read-only: yes + # Type: integer + self.requester_id = requester_id + + # Comment: The state of the request, "new", "open", "pending", "hold", "solved", "closed" + # Mandatory: no + # Read-only: no + # Type: string + self.status = status + + # Comment: The value of the subject field for this request if the subject field is visible to end users; a truncated version of the description otherwise + # Mandatory: yes + # Read-only: no + # Type: string + self.subject = subject + + # Comment: The type of the request, "question", "incident", "problem", "task" + # Mandatory: no + # Read-only: no + # Type: string + self.type = type + + # Comment: When this record last got updated + # Mandatory: no + # Read-only: yes + # Type: date + self.updated_at = updated_at + + # Comment: The API url of this request + # Mandatory: no + # Read-only: yes + # Type: string + self.url = url + + # Comment: This object explains how the request was created + # Mandatory: no + # Read-only: yes + # Type: :class:`Via` + self.via = via + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def assignee(self): + """ + | Comment: The id of the assignee if the field is visible to end users + """ + if self.api and self.assignee_id: + return self.api._get_user(self.assignee_id) + + @assignee.setter + def assignee(self, assignee): + if assignee: + self.assignee_id = assignee.id + self._assignee = assignee + + @property + def collaborators(self): + """ + | Comment: Who are currently CC'ed on the ticket + """ + if self.api and self.collaborator_ids: + return self.api._get_users(self.collaborator_ids) + + @collaborators.setter + def collaborators(self, collaborators): + if collaborators: + self.collaborator_ids = [o.id for o in collaborators] + self._collaborators = collaborators + + @property + def created(self): + """ + | Comment: When this record was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def due(self): + """ + | Comment: When the task is due (only applies if the request is of type "task") + """ + if self.due_at: + return dateutil.parser.parse(self.due_at) + + @due.setter + def due(self, due): + if due: + self.due_at = due + + @property + def organization(self): + """ + | Comment: The organization of the requester + """ + if self.api and self.organization_id: + return self.api._get_organization(self.organization_id) + + @organization.setter + def organization(self, organization): + if organization: + self.organization_id = organization.id + self._organization = organization + + @property + def requester(self): + """ + | Comment: The id of the requester + """ + if self.api and self.requester_id: + return self.api._get_user(self.requester_id) + + @requester.setter + def requester(self, requester): + if requester: + self.requester_id = requester.id + self._requester = requester + + @property + def updated(self): + """ + | Comment: When this record last got updated + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class Response(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + comment=None, + delivered_at=None, + delivery_id=None, + id=None, + rated_at=None, + rating=None, + recipient_id=None, + survey_id=None, + survey_name=None, + user_email=None, + user_id=None, + user_name=None, + **kwargs): + + self.api = api + self.comment = comment + self.delivered_at = delivered_at + self.delivery_id = delivery_id + self.id = id + self.rated_at = rated_at + self.rating = rating + self.recipient_id = recipient_id + self.survey_id = survey_id + self.survey_name = survey_name + self.user_email = user_email + self.user_id = user_id + self.user_name = user_name + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def delivered(self): + + if self.delivered_at: + return dateutil.parser.parse(self.delivered_at) + + @delivered.setter + def delivered(self, delivered): + if delivered: + self.delivered_at = delivered + + @property + def delivery(self): + + if self.api and self.delivery_id: + return self.api._get_delivery(self.delivery_id) + + @delivery.setter + def delivery(self, delivery): + if delivery: + self.delivery_id = delivery.id + self._delivery = delivery + + @property + def rated(self): + + if self.rated_at: + return dateutil.parser.parse(self.rated_at) + + @rated.setter + def rated(self, rated): + if rated: + self.rated_at = rated + + @property + def recipient(self): + + if self.api and self.recipient_id: + return self.api._get_user(self.recipient_id) + + @recipient.setter + def recipient(self, recipient): + if recipient: + self.recipient_id = recipient.id + self._recipient = recipient + + @property + def survey(self): + + if self.api and self.survey_id: + return self.api._get_survey(self.survey_id) + + @survey.setter + def survey(self, survey): + if survey: + self.survey_id = survey.id + self._survey = survey + + @property + def user(self): + + if self.api and self.user_id: + return self.api._get_user(self.user_id) + + @user.setter + def user(self, user): + if user: + self.user_id = user.id + self._user = user + + +class RoutingAttribute(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + created_at=None, + id=None, + name=None, + updated_at=None, + url=None, + **kwargs): + + self.api = api + self.created_at = created_at + self.id = id + self.name = name + self.updated_at = updated_at + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class RoutingAttributeValue(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + created_at=None, + id=None, + name=None, + updated_at=None, + url=None, + **kwargs): + + self.api = api + self.created_at = created_at + self.id = id + self.name = name + self.updated_at = updated_at + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class SatisfactionRating(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + assignee_id=None, + created_at=None, + group_id=None, + id=None, + requester_id=None, + score=None, + ticket_id=None, + updated_at=None, + url=None, + **kwargs): + + self.api = api + + # Comment: The id of agent assigned to at the time of rating + # Mandatory: yes + # Read-only: yes + # Type: integer + self.assignee_id = assignee_id + + # Comment: The time the satisfaction rating got created + # Mandatory: no + # Read-only: yes + # Type: date + self.created_at = created_at + + # Comment: The id of group assigned to at the time of rating + # Mandatory: yes + # Read-only: yes + # Type: integer + self.group_id = group_id + + # Comment: Automatically assigned upon creation + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: The id of ticket requester submitting the rating + # Mandatory: yes + # Read-only: yes + # Type: integer + self.requester_id = requester_id + + # Comment: The rating: "offered", "unoffered", "good" or "bad" + # Mandatory: yes + # Read-only: no + # Type: string + self.score = score + + # Comment: The id of ticket being rated + # Mandatory: yes + # Read-only: yes + # Type: integer + self.ticket_id = ticket_id + + # Comment: The time the satisfaction rating got updated + # Mandatory: no + # Read-only: yes + # Type: date + self.updated_at = updated_at + + # Comment: The API url of this rating + # Mandatory: no + # Read-only: yes + # Type: string + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def assignee(self): + """ + | Comment: The id of agent assigned to at the time of rating + """ + if self.api and self.assignee_id: + return self.api._get_user(self.assignee_id) + + @assignee.setter + def assignee(self, assignee): + if assignee: + self.assignee_id = assignee.id + self._assignee = assignee + + @property + def created(self): + """ + | Comment: The time the satisfaction rating got created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def group(self): + """ + | Comment: The id of group assigned to at the time of rating + """ + if self.api and self.group_id: + return self.api._get_group(self.group_id) + + @group.setter + def group(self, group): + if group: + self.group_id = group.id + self._group = group + + @property + def requester(self): + """ + | Comment: The id of ticket requester submitting the rating + """ + if self.api and self.requester_id: + return self.api._get_user(self.requester_id) + + @requester.setter + def requester(self, requester): + if requester: + self.requester_id = requester.id + self._requester = requester + + @property + def ticket(self): + """ + | Comment: The id of ticket being rated + """ + if self.api and self.ticket_id: + return self.api._get_ticket(self.ticket_id) + + @ticket.setter + def ticket(self, ticket): + if ticket: + self.ticket_id = ticket.id + self._ticket = ticket + + @property + def updated(self): + """ + | Comment: The time the satisfaction rating got updated + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class SatisfactionRatingEvent(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + assignee_id=None, + body=None, + id=None, + score=None, + type=None, + **kwargs): + + self.api = api + self.assignee_id = assignee_id + self.body = body + self.id = id + self.score = score + self.type = type + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def assignee(self): + + if self.api and self.assignee_id: + return self.api._get_user(self.assignee_id) + + @assignee.setter + def assignee(self, assignee): + if assignee: + self.assignee_id = assignee.id + self._assignee = assignee + + +class Schedule(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + created_at=None, + id=None, + intervals=None, + name=None, + time_zone=None, + updated_at=None, + url=None, + **kwargs): + + self.api = api + + # Comment: Time the schedule was created + # Type: date + self.created_at = created_at + + # Comment: Automatically assigned upon creation + # Type: integer + self.id = id + + # Comment: Array of intervals for the schedule + # Type: array + self.intervals = intervals + + # Comment: Name of the schedule + # Type: string + self.name = name + + # Comment: Time zone of the schedule + # Type: string + self.time_zone = time_zone + + # Comment: Time the schedule was last updated + # Type: date + self.updated_at = updated_at + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + """ + | Comment: Time the schedule was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + """ + | Comment: Time the schedule was last updated + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class SharingAgreement(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + created_at=None, + id=None, + name=None, + partner_name=None, + remote_subdomain=None, + status=None, + type=None, + **kwargs): + + self.api = api + + # Comment: The time the record was created + # Type: date + self.created_at = created_at + + # Comment: Automatically assigned upon creation + # Type: integer + self.id = id + + # Comment: Name of this sharing agreement + # Type: string + self.name = name + + # Comment: Can be one of the following: 'jira', null + # Type: string + self.partner_name = partner_name + + # Comment: Subdomain of the remote account or null if not associated with an account + # Type: string + self.remote_subdomain = remote_subdomain + + # Comment: Can be one of the following: 'accepted', 'declined', 'pending', 'inactive' + # Type: string + self.status = status + + # Comment: Can be one of the following: 'inbound', 'outbound' + # Type: string + self.type = type + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + """ + | Comment: The time the record was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + +class Skip(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + created_at=None, + id=None, + reason=None, + ticket=None, + ticket_id=None, + updated_at=None, + user_id=None, + **kwargs): + + self.api = api + self.created_at = created_at + self.id = id + self.reason = reason + self.ticket = ticket + self.ticket_id = ticket_id + self.updated_at = updated_at + self.user_id = user_id + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + @property + def user(self): + + if self.api and self.user_id: + return self.api._get_user(self.user_id) + + @user.setter + def user(self, user): + if user: + self.user_id = user.id + self._user = user + + +class SlaPolicy(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + created_at=None, + description=None, + filter=None, + id=None, + policy_metrics=None, + position=None, + title=None, + updated_at=None, + url=None, + **kwargs): + + self.api = api + self.created_at = created_at + self.description = description + self.filter = filter + self.id = id + self.policy_metrics = policy_metrics + self.position = position + self.title = title + self.updated_at = updated_at + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class Source(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, api=None, from_=None, rel=None, to=None, **kwargs): + + self.api = api + self.from_ = from_ + self.rel = rel + self.to = to + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Status(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + action=None, + errors=None, + id=None, + status=None, + success=None, + title=None, + **kwargs): + + self.api = api + self.action = action + self.errors = errors + self.id = id + self.status = status + self.success = success + self.title = title + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class SuspendedTicket(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + author=None, + brand_id=None, + cause=None, + content=None, + created_at=None, + id=None, + recipient=None, + subject=None, + ticket_id=None, + updated_at=None, + url=None, + via=None, + **kwargs): + + self.api = api + + # Comment: The author id (if available), name and email + # Mandatory: no + # Read-only: yes + # Type: object + self.author = author + + # Comment: The id of the brand this ticket is associated with - only applicable for enterprise accounts + # Mandatory: no + # Read-only: yes + # Type: integer + self.brand_id = brand_id + + # Comment: Why the ticket was suspended + # Mandatory: no + # Read-only: yes + # Type: string + self.cause = cause + + # Comment: The content that was flagged + # Mandatory: no + # Read-only: yes + # Type: string + self.content = content + + # Comment: When this record was created + # Mandatory: no + # Read-only: yes + # Type: date + self.created_at = created_at + + # Comment: Automatically assigned + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: The original recipient e-mail address of the ticket + # Mandatory: no + # Read-only: yes + # Type: string + self.recipient = recipient + + # Comment: The value of the subject field for this ticket + # Mandatory: no + # Read-only: yes + # Type: string + self.subject = subject + + # Comment: The ticket ID this suspended email is associated with, if available + # Mandatory: no + # Read-only: yes + # Type: integer + self.ticket_id = ticket_id + + # Comment: When this record last got updated + # Mandatory: no + # Read-only: yes + # Type: date + self.updated_at = updated_at + + # Comment: The API url of this ticket + # Mandatory: no + # Read-only: yes + # Type: string + self.url = url + + # Comment: This object explains how the ticket was created + # Mandatory: no + # Read-only: yes + # Type: :class:`Via` + self.via = via + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def brand(self): + """ + | Comment: The id of the brand this ticket is associated with - only applicable for enterprise accounts + """ + if self.api and self.brand_id: + return self.api._get_brand(self.brand_id) + + @brand.setter + def brand(self, brand): + if brand: + self.brand_id = brand.id + self._brand = brand + + @property + def created(self): + """ + | Comment: When this record was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def ticket(self): + """ + | Comment: The ticket ID this suspended email is associated with, if available + """ + if self.api and self.ticket_id: + return self.api._get_ticket(self.ticket_id) + + @ticket.setter + def ticket(self, ticket): + if ticket: + self.ticket_id = ticket.id + self._ticket = ticket + + @property + def updated(self): + """ + | Comment: When this record last got updated + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class System(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + client=None, + ip_address=None, + latitude=None, + location=None, + longitude=None, + **kwargs): + + self.api = api + self.client = client + self.ip_address = ip_address + self.latitude = latitude + self.location = location + self.longitude = longitude + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Tag(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, api=None, count=None, name=None, **kwargs): + + self.api = api + self.count = count + self.name = name + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Target(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + active=None, + content_type=None, + created_at=None, + id=None, + method=None, + password=None, + target_url=None, + title=None, + type=None, + url=None, + username=None, + **kwargs): + + self.api = api + + # Comment: Whether or not the target is activated + # Mandatory: + # Type: boolean + self.active = active + self.content_type = content_type + + # Comment: The time the target was created + # Mandatory: + # Type: date + self.created_at = created_at + + # Comment: Automatically assigned when created + # Mandatory: + # Type: integer + self.id = id + self.method = method + self.password = password + self.target_url = target_url + + # Comment: A name for the target + # Mandatory: yes + # Type: string + self.title = title + + # Comment: A pre-defined target, such as "basecamp_target". See the additional attributes for the type that follow + # Mandatory: + # Type: string + self.type = type + self.url = url + self.username = username + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + """ + | Comment: The time the target was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + +class Thumbnail(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + content_type=None, + content_url=None, + file_name=None, + id=None, + size=None, + **kwargs): + + self.api = api + self.content_type = content_type + self.content_url = content_url + self.file_name = file_name + self.id = id + self.size = size + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Ticket(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + assignee_id=None, + brand_id=None, + collaborator_ids=None, + created_at=None, + custom_fields=None, + description=None, + due_at=None, + external_id=None, + fields=None, + forum_topic_id=None, + group_id=None, + has_incidents=None, + id=None, + organization_id=None, + priority=None, + problem_id=None, + raw_subject=None, + recipient=None, + requester_id=None, + satisfaction_rating=None, + sharing_agreement_ids=None, + status=None, + subject=None, + submitter_id=None, + tags=None, + type=None, + updated_at=None, + url=None, + via=None, + **kwargs): + + self.api = api + + # Comment: The agent currently assigned to the ticket + # Mandatory: no + # Read-only: no + # Type: integer + self.assignee_id = assignee_id + + # Comment: Enterprise only. The id of the brand this ticket is associated with + # Mandatory: no + # Read-only: no + # Type: integer + self.brand_id = brand_id + + # Comment: The ids of users currently cc'ed on the ticket + # Mandatory: no + # Read-only: no + # Type: array + self.collaborator_ids = collaborator_ids + + # Comment: When this record was created + # Mandatory: no + # Read-only: yes + # Type: date + self.created_at = created_at + + # Comment: Custom fields for the ticket. See Setting custom field values + # Mandatory: no + # Read-only: no + # Type: array + self.custom_fields = custom_fields + + # Comment: The first comment on the ticket + # Mandatory: no + # Read-only: yes + # Type: string + self.description = description + + # Comment: If this is a ticket of type "task" it has a due date. Due date format uses ISO 8601 format. + # Mandatory: no + # Read-only: no + # Type: date + self.due_at = due_at + + # Comment: An id you can use to link Zendesk Support tickets to local records + # Mandatory: no + # Read-only: no + # Type: string + self.external_id = external_id + self.fields = fields + + # Comment: The topic this ticket originated from, if any + # Mandatory: no + # Read-only: no + # Type: integer + self.forum_topic_id = forum_topic_id + + # Comment: The group this ticket is assigned to + # Mandatory: no + # Read-only: no + # Type: integer + self.group_id = group_id + + # Comment: Is true of this ticket has been marked as a problem, false otherwise + # Mandatory: no + # Read-only: yes + # Type: boolean + self.has_incidents = has_incidents + + # Comment: Automatically assigned when the ticket is created + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: The organization of the requester. You can only specify the ID of an organization associated with the requester. See Organization Memberships + # Mandatory: no + # Read-only: no + # Type: integer + self.organization_id = organization_id + + # Comment: The urgency with which the ticket should be addressed. Possible values: "urgent", "high", "normal", "low" + # Mandatory: no + # Read-only: no + # Type: string + self.priority = priority + + # Comment: For tickets of type "incident", the ID of the problem the incident is linked to + # Mandatory: no + # Read-only: no + # Type: integer + self.problem_id = problem_id + + # Comment: The dynamic content placeholder, if present, or the "subject" value, if not. See Dynamic Content + # Mandatory: no + # Read-only: no + # Type: string + self.raw_subject = raw_subject + + # Comment: The original recipient e-mail address of the ticket + # Mandatory: no + # Read-only: no + # Type: string + self.recipient = recipient + + # Comment: The user who requested this ticket + # Mandatory: yes + # Read-only: no + # Type: integer + self.requester_id = requester_id + + # Comment: The satisfaction rating of the ticket, if it exists, or the state of satisfaction, 'offered' or 'unoffered' + # Mandatory: no + # Read-only: yes + # Type: object + self.satisfaction_rating = satisfaction_rating + + # Comment: The ids of the sharing agreements used for this ticket + # Mandatory: no + # Read-only: yes + # Type: array + self.sharing_agreement_ids = sharing_agreement_ids + + # Comment: The state of the ticket. Possible values: "new", "open", "pending", "hold", "solved", "closed" + # Mandatory: no + # Read-only: no + # Type: string + self.status = status + + # Comment: The value of the subject field for this ticket + # Mandatory: no + # Read-only: no + # Type: string + self.subject = subject + + # Comment: The user who submitted the ticket. The submitter always becomes the author of the first comment on the ticket + # Mandatory: no + # Read-only: no + # Type: integer + self.submitter_id = submitter_id + + # Comment: The array of tags applied to this ticket + # Mandatory: no + # Read-only: no + # Type: array + self.tags = tags + + # Comment: The type of this ticket. Possible values: "problem", "incident", "question" or "task" + # Mandatory: no + # Read-only: no + # Type: string + self.type = type + + # Comment: When this record last got updated + # Mandatory: no + # Read-only: yes + # Type: date + self.updated_at = updated_at + + # Comment: The API url of this ticket + # Mandatory: no + # Read-only: yes + # Type: string + self.url = url + + # Comment: This object explains how the ticket was created + # Mandatory: no + # Read-only: yes + # Type: :class:`Via` + self.via = via + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def assignee(self): + """ + | Comment: The agent currently assigned to the ticket + """ + if self.api and self.assignee_id: + return self.api._get_user(self.assignee_id) + + @assignee.setter + def assignee(self, assignee): + if assignee: + self.assignee_id = assignee.id + self._assignee = assignee + + @property + def brand(self): + """ + | Comment: Enterprise only. The id of the brand this ticket is associated with + """ + if self.api and self.brand_id: + return self.api._get_brand(self.brand_id) + + @brand.setter + def brand(self, brand): + if brand: + self.brand_id = brand.id + self._brand = brand + + @property + def collaborators(self): + """ + | Comment: The ids of users currently cc'ed on the ticket + """ + if self.api and self.collaborator_ids: + return self.api._get_users(self.collaborator_ids) + + @collaborators.setter + def collaborators(self, collaborators): + if collaborators: + self.collaborator_ids = [o.id for o in collaborators] + self._collaborators = collaborators + + @property + def created(self): + """ + | Comment: When this record was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def due(self): + """ + | Comment: If this is a ticket of type "task" it has a due date. Due date format uses ISO 8601 format. + """ + if self.due_at: + return dateutil.parser.parse(self.due_at) + + @due.setter + def due(self, due): + if due: + self.due_at = due + + @property + def forum_topic(self): + """ + | Comment: The topic this ticket originated from, if any + """ + if self.api and self.forum_topic_id: + return self.api._get_topic(self.forum_topic_id) + + @forum_topic.setter + def forum_topic(self, forum_topic): + if forum_topic: + self.forum_topic_id = forum_topic.id + self._forum_topic = forum_topic + + @property + def group(self): + """ + | Comment: The group this ticket is assigned to + """ + if self.api and self.group_id: + return self.api._get_group(self.group_id) + + @group.setter + def group(self, group): + if group: + self.group_id = group.id + self._group = group + + @property + def organization(self): + """ + | Comment: The organization of the requester. You can only specify the ID of an organization associated with the requester. See Organization Memberships + """ + if self.api and self.organization_id: + return self.api._get_organization(self.organization_id) + + @organization.setter + def organization(self, organization): + if organization: + self.organization_id = organization.id + self._organization = organization + + @property + def problem(self): + """ + | Comment: For tickets of type "incident", the ID of the problem the incident is linked to + """ + if self.api and self.problem_id: + return self.api._get_problem(self.problem_id) + + @problem.setter + def problem(self, problem): + if problem: + self.problem_id = problem.id + self._problem = problem + + @property + def requester(self): + """ + | Comment: The user who requested this ticket + """ + if self.api and self.requester_id: + return self.api._get_user(self.requester_id) + + @requester.setter + def requester(self, requester): + if requester: + self.requester_id = requester.id + self._requester = requester + + @property + def sharing_agreements(self): + """ + | Comment: The ids of the sharing agreements used for this ticket + """ + if self.api and self.sharing_agreement_ids: + return self.api._get_sharing_agreements(self.sharing_agreement_ids) + + @sharing_agreements.setter + def sharing_agreements(self, sharing_agreements): + if sharing_agreements: + self.sharing_agreement_ids = [o.id for o in sharing_agreements] + self._sharing_agreements = sharing_agreements + + @property + def submitter(self): + """ + | Comment: The user who submitted the ticket. The submitter always becomes the author of the first comment on the ticket + """ + if self.api and self.submitter_id: + return self.api._get_user(self.submitter_id) + + @submitter.setter + def submitter(self, submitter): + if submitter: + self.submitter_id = submitter.id + self._submitter = submitter + + @property + def updated(self): + """ + | Comment: When this record last got updated + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class TicketAudit(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, api=None, audit=None, ticket=None, **kwargs): + + self.api = api + self.audit = audit + self.ticket = ticket + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class TicketEvent(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + child_events=None, + id=None, + ticket_id=None, + timestamp=None, + updater_id=None, + via=None, + **kwargs): + + self.api = api + self.child_events = child_events + self.id = id + self.ticket_id = ticket_id + self.timestamp = timestamp + self.updater_id = updater_id + self.via = via + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def ticket(self): + + if self.api and self.ticket_id: + return self.api._get_ticket(self.ticket_id) + + @ticket.setter + def ticket(self, ticket): + if ticket: + self.ticket_id = ticket.id + self._ticket = ticket + + @property + def updater(self): + + if self.api and self.updater_id: + return self.api._get_user(self.updater_id) + + @updater.setter + def updater(self, updater): + if updater: + self.updater_id = updater.id + self._updater = updater + + +class TicketField(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + active=None, + collapsed_for_agents=None, + created_at=None, + description=None, + editable_in_portal=None, + id=None, + position=None, + raw_description=None, + raw_title=None, + raw_title_in_portal=None, + regexp_for_validation=None, + required=None, + required_in_portal=None, + tag=None, + title=None, + title_in_portal=None, + type=None, + updated_at=None, + url=None, + visible_in_portal=None, + **kwargs): + + self.api = api + + # Comment: Whether this field is available + # Mandatory: no + # Read-only: no + # Type: boolean + self.active = active + + # Comment: If this field should be shown to agents by default or be hidden alongside infrequently used fields. Classic interface only + # Mandatory: no + # Read-only: no + # Type: boolean + self.collapsed_for_agents = collapsed_for_agents + + # Comment: The time the ticket field was created + # Mandatory: no + # Read-only: yes + # Type: date + self.created_at = created_at + + # Comment: The description of the purpose of this ticket field, shown to users + # Mandatory: no + # Read-only: no + # Type: string + self.description = description + + # Comment: Whether this field is editable by end users + # Mandatory: no + # Read-only: no + # Type: boolean + self.editable_in_portal = editable_in_portal + + # Comment: Automatically assigned upon creation + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: A relative position for the ticket fields that determines the order of ticket fields on a ticket. Note that positions 0 to 7 are reserved for system fields + # Mandatory: no + # Read-only: no + # Type: integer + self.position = position + + # Comment: The dynamic content placeholder, if present, or the "description" value, if not. See Dynamic Content + # Mandatory: no + # Read-only: no + # Type: string + self.raw_description = raw_description + + # Comment: The dynamic content placeholder, if present, or the "title" value, if not. See Dynamic Content + # Mandatory: no + # Read-only: no + # Type: string + self.raw_title = raw_title + + # Comment: The dynamic content placeholder, if present, or the "title_in_portal" value, if not. See Dynamic Content + # Mandatory: no + # Read-only: no + # Type: string + self.raw_title_in_portal = raw_title_in_portal + + # Comment: Regular expression field only. The validation pattern for a field value to be deemed valid. + # Mandatory: no + # Read-only: no + # Type: string + self.regexp_for_validation = regexp_for_validation + + # Comment: If it's required for this field to have a value when updated by agents + # Mandatory: no + # Read-only: no + # Type: boolean + self.required = required + + # Comment: If it's required for this field to have a value when updated by end users + # Mandatory: no + # Read-only: no + # Type: boolean + self.required_in_portal = required_in_portal + + # Comment: A tag value to set for checkbox fields when checked + # Mandatory: no + # Read-only: no + # Type: string + self.tag = tag + + # Comment: The title of the ticket field + # Mandatory: yes + # Read-only: no + # Type: string + self.title = title + + # Comment: The title of the ticket field when shown to end users + # Mandatory: no + # Read-only: no + # Type: string + self.title_in_portal = title_in_portal + + # Comment: The type of the ticket field: "checkbox", "date", "decimal", "integer", "regexp", "tagger", "text", or "textarea". Type is not editable once created. + # Mandatory: yes + # Read-only: no + # Type: string + self.type = type + + # Comment: The time of the last update of the ticket field + # Mandatory: no + # Read-only: yes + # Type: date + self.updated_at = updated_at + + # Comment: The URL for this resource + # Mandatory: no + # Read-only: yes + # Type: string + self.url = url + + # Comment: Whether this field is available to end users + # Mandatory: no + # Read-only: no + # Type: boolean + self.visible_in_portal = visible_in_portal + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + """ + | Comment: The time the ticket field was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + """ + | Comment: The time of the last update of the ticket field + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class TicketForm(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + active=None, + created_at=None, + default=None, + display_name=None, + end_user_visible=None, + id=None, + in_all_brands=None, + in_all_organizations=None, + name=None, + position=None, + raw_display_name=None, + raw_name=None, + restricted_brand_ids=None, + restricted_organization_ids=None, + ticket_field_ids=None, + updated_at=None, + url=None, + **kwargs): + + self.api = api + + # Comment: If the form is set as active + # Mandatory: no + # Read-only: no + # Type: boolean + self.active = active + self.created_at = created_at + + # Comment: Is the form the default form for this account + # Mandatory: no + # Read-only: no + # Type: boolean + self.default = default + + # Comment: The name of the form that is displayed to an end user + # Mandatory: no + # Read-only: no + # Type: string + self.display_name = display_name + + # Comment: Is the form visible to the end user + # Mandatory: no + # Read-only: no + # Type: boolean + self.end_user_visible = end_user_visible + self.id = id + + # Comment: Is the form available for use in all brands on this account + # Mandatory: no + # Read-only: no + # Type: boolean + self.in_all_brands = in_all_brands + self.in_all_organizations = in_all_organizations + + # Comment: The name of the form + # Mandatory: yes + # Read-only: no + # Type: string + self.name = name + + # Comment: The position of this form among other forms in the account, i.e. dropdown + # Mandatory: no + # Read-only: no + # Type: integer + self.position = position + + # Comment: The dynamic content placeholder, if present, or the "display_name" value, if not. See Dynamic Content + # Mandatory: no + # Read-only: no + # Type: string + self.raw_display_name = raw_display_name + + # Comment: The dynamic content placeholder, if present, or the "name" value, if not. See Dynamic Content + # Mandatory: no + # Read-only: no + # Type: string + self.raw_name = raw_name + + # Comment: ids of all brands that this ticket form is restricted to + # Mandatory: no + # Read-only: yes + # Type: array + self.restricted_brand_ids = restricted_brand_ids + self.restricted_organization_ids = restricted_organization_ids + + # Comment: ids of all ticket fields which are in this ticket form + # Mandatory: no + # Read-only: no + # Type: array + self.ticket_field_ids = ticket_field_ids + self.updated_at = updated_at + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def restricted_brands(self): + """ + | Comment: ids of all brands that this ticket form is restricted to + """ + if self.api and self.restricted_brand_ids: + return self.api._get_restricted_brands(self.restricted_brand_ids) + + @restricted_brands.setter + def restricted_brands(self, restricted_brands): + if restricted_brands: + self.restricted_brand_ids = [o.id for o in restricted_brands] + self._restricted_brands = restricted_brands + + @property + def restricted_organizations(self): + + if self.api and self.restricted_organization_ids: + return self.api._get_restricted_organizations( + self.restricted_organization_ids) + + @restricted_organizations.setter + def restricted_organizations(self, restricted_organizations): + if restricted_organizations: + self.restricted_organization_ids = [ + o.id for o in restricted_organizations + ] + self._restricted_organizations = restricted_organizations + + @property + def ticket_fields(self): + """ + | Comment: ids of all ticket fields which are in this ticket form + """ + if self.api and self.ticket_field_ids: + return self.api._get_ticket_fields(self.ticket_field_ids) + + @ticket_fields.setter + def ticket_fields(self, ticket_fields): + if ticket_fields: + self.ticket_field_ids = [o.id for o in ticket_fields] + self._ticket_fields = ticket_fields + + @property + def updated(self): + + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class TicketMetric(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + agent_wait_time_in_minutes=None, + assigned_at=None, + assignee_stations=None, + assignee_updated_at=None, + created_at=None, + first_resolution_time_in_minutes=None, + full_resolution_time_in_minutes=None, + group_stations=None, + id=None, + initially_assigned_at=None, + latest_comment_added_at=None, + on_hold_time_in_minutes=None, + reopens=None, + replies=None, + reply_time_in_minutes=None, + requester_updated_at=None, + requester_wait_time_in_minutes=None, + solved_at=None, + status_updated_at=None, + ticket_id=None, + updated_at=None, + **kwargs): + + self.api = api + + # Comment: Number of minutes the agent spent waiting inside and out of business hours + # Mandatory: no + # Read-only: yes + # Type: object + self.agent_wait_time_in_minutes = agent_wait_time_in_minutes + + # Comment: When the ticket was last assigned + # Mandatory: no + # Read-only: yes + # Type: date + self.assigned_at = assigned_at + + # Comment: Number of assignees this ticket had + # Mandatory: no + # Read-only: yes + # Type: integer + self.assignee_stations = assignee_stations + + # Comment: When the assignee last updated the ticket + # Mandatory: no + # Read-only: yes + # Type: date + self.assignee_updated_at = assignee_updated_at + + # Comment: When this record was created + # Mandatory: no + # Read-only: yes + # Type: date + self.created_at = created_at + + # Comment: Number of minutes to the first resolution time inside and out of business hours + # Mandatory: no + # Read-only: yes + # Type: object + self.first_resolution_time_in_minutes = first_resolution_time_in_minutes + + # Comment: Number of minutes to the full resolution inside and out of business hours + # Mandatory: no + # Read-only: yes + # Type: object + self.full_resolution_time_in_minutes = full_resolution_time_in_minutes + + # Comment: Number of groups this ticket passed through + # Mandatory: no + # Read-only: yes + # Type: integer + self.group_stations = group_stations + + # Comment: Automatically assigned + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: When the ticket was initially assigned + # Mandatory: no + # Read-only: yes + # Type: date + self.initially_assigned_at = initially_assigned_at + + # Comment: When the latest comment was added + # Mandatory: no + # Read-only: yes + # Type: date + self.latest_comment_added_at = latest_comment_added_at + self.on_hold_time_in_minutes = on_hold_time_in_minutes + + # Comment: Total number of times the ticket was reopened + # Mandatory: no + # Read-only: yes + # Type: integer + self.reopens = reopens + + # Comment: Total number of times ticket was replied to + # Mandatory: no + # Read-only: yes + # Type: integer + self.replies = replies + + # Comment: Number of minutes to the first reply inside and out of business hours + # Mandatory: no + # Read-only: yes + # Type: object + self.reply_time_in_minutes = reply_time_in_minutes + + # Comment: When the requester last updated the ticket + # Mandatory: no + # Read-only: yes + # Type: date + self.requester_updated_at = requester_updated_at + + # Comment: Number of minutes the requester spent waiting inside and out of business hours + # Mandatory: no + # Read-only: yes + # Type: object + self.requester_wait_time_in_minutes = requester_wait_time_in_minutes + + # Comment: When the ticket was solved + # Mandatory: no + # Read-only: yes + # Type: date + self.solved_at = solved_at + + # Comment: When the status was last updated + # Mandatory: no + # Read-only: yes + # Type: date + self.status_updated_at = status_updated_at + + # Comment: Id of the associated ticket + # Mandatory: no + # Read-only: yes + # Type: integer + self.ticket_id = ticket_id + + # Comment: When this record last got updated + # Mandatory: no + # Read-only: yes + # Type: date + self.updated_at = updated_at + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def assigned(self): + """ + | Comment: When the ticket was last assigned + """ + if self.assigned_at: + return dateutil.parser.parse(self.assigned_at) + + @assigned.setter + def assigned(self, assigned): + if assigned: + self.assigned_at = assigned + + @property + def assignee_updated(self): + """ + | Comment: When the assignee last updated the ticket + """ + if self.assignee_updated_at: + return dateutil.parser.parse(self.assignee_updated_at) + + @assignee_updated.setter + def assignee_updated(self, assignee_updated): + if assignee_updated: + self.assignee_updated_at = assignee_updated + + @property + def created(self): + """ + | Comment: When this record was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def initially_assigned(self): + """ + | Comment: When the ticket was initially assigned + """ + if self.initially_assigned_at: + return dateutil.parser.parse(self.initially_assigned_at) + + @initially_assigned.setter + def initially_assigned(self, initially_assigned): + if initially_assigned: + self.initially_assigned_at = initially_assigned + + @property + def latest_comment_added(self): + """ + | Comment: When the latest comment was added + """ + if self.latest_comment_added_at: + return dateutil.parser.parse(self.latest_comment_added_at) + + @latest_comment_added.setter + def latest_comment_added(self, latest_comment_added): + if latest_comment_added: + self.latest_comment_added_at = latest_comment_added + + @property + def requester_updated(self): + """ + | Comment: When the requester last updated the ticket + """ + if self.requester_updated_at: + return dateutil.parser.parse(self.requester_updated_at) + + @requester_updated.setter + def requester_updated(self, requester_updated): + if requester_updated: + self.requester_updated_at = requester_updated + + @property + def solved(self): + """ + | Comment: When the ticket was solved + """ + if self.solved_at: + return dateutil.parser.parse(self.solved_at) + + @solved.setter + def solved(self, solved): + if solved: + self.solved_at = solved + + @property + def status_updated(self): + """ + | Comment: When the status was last updated + """ + if self.status_updated_at: + return dateutil.parser.parse(self.status_updated_at) + + @status_updated.setter + def status_updated(self, status_updated): + if status_updated: + self.status_updated_at = status_updated + + @property + def ticket(self): + """ + | Comment: Id of the associated ticket + """ + if self.api and self.ticket_id: + return self.api._get_ticket(self.ticket_id) + + @ticket.setter + def ticket(self, ticket): + if ticket: + self.ticket_id = ticket.id + self._ticket = ticket + + @property + def updated(self): + """ + | Comment: When this record last got updated + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class TicketMetricEvent(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + deleted=None, + id=None, + instance_id=None, + metric=None, + sla=None, + status=None, + ticket_id=None, + time=None, + type=None, + **kwargs): + + self.api = api + self.deleted = deleted + + # Comment: Automatically assigned when the record is created + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: The instance of the metric associated with the event. See instance_id + # Mandatory: no + # Read-only: yes + # Type: integer + self.instance_id = instance_id + + # Comment: One of the following: agent_work_time, pausable_update_time, periodic_update_time, reply_time, requester_wait_time, or resolution_time + # Mandatory: no + # Read-only: yes + # Type: string + self.metric = metric + self.sla = sla + self.status = status + + # Comment: Id of the associated ticket + # Mandatory: no + # Read-only: yes + # Type: integer + self.ticket_id = ticket_id + + # Comment: The time the event occurred + # Mandatory: no + # Read-only: yes + # Type: date + self.time = time + + # Comment: One of the following: activate, pause, fulfill, apply_sla, breach, or update_status. See Metric event types + # Mandatory: no + # Read-only: yes + # Type: string + self.type = type + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def ticket(self): + """ + | Comment: Id of the associated ticket + """ + if self.api and self.ticket_id: + return self.api._get_ticket(self.ticket_id) + + @ticket.setter + def ticket(self, ticket): + if ticket: + self.ticket_id = ticket.id + self._ticket = ticket + + +class TicketMetricItem(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, api=None, business=None, calendar=None, **kwargs): + + self.api = api + self.business = business + self.calendar = calendar + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class TicketSharingEvent(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + action=None, + agreement_id=None, + id=None, + type=None, + **kwargs): + + self.api = api + self.action = action + self.agreement_id = agreement_id + self.id = id + self.type = type + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Topic(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + body=None, + created_at=None, + forum_id=None, + id=None, + locked=None, + pinned=None, + position=None, + search_phrases=None, + submitter_id=None, + tags=None, + title=None, + topic_type=None, + updated_at=None, + updater_id=None, + url=None, + **kwargs): + + self.api = api + self.body = body + self.created_at = created_at + self.forum_id = forum_id + self.id = id + self.locked = locked + self.pinned = pinned + self.position = position + self.search_phrases = search_phrases + self.submitter_id = submitter_id + self.tags = tags + self.title = title + self.topic_type = topic_type + self.updated_at = updated_at + self.updater_id = updater_id + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def forum(self): + + if self.api and self.forum_id: + return self.api._get_forum(self.forum_id) + + @forum.setter + def forum(self, forum): + if forum: + self.forum_id = forum.id + self._forum = forum + + @property + def submitter(self): + + if self.api and self.submitter_id: + return self.api._get_user(self.submitter_id) + + @submitter.setter + def submitter(self, submitter): + if submitter: + self.submitter_id = submitter.id + self._submitter = submitter + + @property + def updated(self): + + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + @property + def updater(self): + + if self.api and self.updater_id: + return self.api._get_user(self.updater_id) + + @updater.setter + def updater(self, updater): + if updater: + self.updater_id = updater.id + self._updater = updater + + +class Trigger(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + actions=None, + active=None, + conditions=None, + description=None, + id=None, + position=None, + title=None, + **kwargs): + + self.api = api + + # Comment: An array of Actions describing what the trigger will do + # Type: array + self.actions = actions + + # Comment: Whether the trigger is active + # Type: boolean + self.active = active + + # Comment: An object that describes the conditions under which the trigger will execute + # Type: :class:`Conditions` + self.conditions = conditions + + # Comment: The description of the trigger + # Type: string + self.description = description + + # Comment: Automatically assigned when created + # Type: integer + self.id = id + + # Comment: Position of the trigger, determines the order they will execute in + # Type: integer + self.position = position + + # Comment: The title of the trigger + # Type: string + self.title = title + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class TweetEvent(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + body=None, + direct_message=None, + id=None, + recipients=None, + type=None, + **kwargs): + + self.api = api + self.body = body + self.direct_message = direct_message + self.id = id + self.recipients = recipients + self.type = type + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Upload(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + attachment=None, + attachments=None, + expires_at=None, + token=None, + **kwargs): + + self.api = api + self.attachment = attachment + self.attachments = attachments + self.expires_at = expires_at + self.token = token + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def expires(self): + + if self.expires_at: + return dateutil.parser.parse(self.expires_at) + + @expires.setter + def expires(self, expires): + if expires: + self.expires_at = expires + + +class User(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + active=None, + alias=None, + chat_only=None, + created_at=None, + custom_role_id=None, + details=None, + email=None, + external_id=None, + id=None, + last_login_at=None, + locale=None, + locale_id=None, + moderator=None, + name=None, + notes=None, + only_private_comments=None, + organization_id=None, + phone=None, + photo=None, + restricted_agent=None, + role=None, + shared=None, + shared_agent=None, + signature=None, + suspended=None, + tags=None, + ticket_restriction=None, + time_zone=None, + two_factor_auth_enabled=None, + updated_at=None, + url=None, + user_fields=None, + verified=None, + **kwargs): + + self.api = api + + # Comment: false if the user has been deleted + # Mandatory: no + # Read-only: yes + # Type: boolean + self.active = active + + # Comment: An alias displayed to end users + # Mandatory: no + # Read-only: no + # Type: string + self.alias = alias + + # Comment: Whether or not the user is a chat-only agent + # Mandatory: no + # Read-only: yes + # Type: boolean + self.chat_only = chat_only + + # Comment: The time the user was created + # Mandatory: no + # Read-only: yes + # Type: date + self.created_at = created_at + + # Comment: A custom role if the user is an agent on the Enterprise plan + # Mandatory: no + # Read-only: no + # Type: integer + self.custom_role_id = custom_role_id + + # Comment: Any details you want to store about the user, such as an address + # Mandatory: no + # Read-only: no + # Type: string + self.details = details + + # Comment: The user's primary email address. Writeable on create only. On update, a secondary email is added. See Email Address + # Mandatory: no + # Read-only: no + # Type: string + self.email = email + + # Comment: A unique identifier from another system. The API treats the id as case insensitive. Example: ian1 and Ian1 are the same user + # Mandatory: no + # Read-only: no + # Type: string + self.external_id = external_id + + # Comment: Automatically assigned when the user is created + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: The last time the user signed in to Zendesk Support + # Mandatory: no + # Read-only: yes + # Type: date + self.last_login_at = last_login_at + + # Comment: The user's locale + # Mandatory: no + # Read-only: yes + # Type: string + self.locale = locale + + # Comment: The user's language identifier + # Mandatory: no + # Read-only: no + # Type: integer + self.locale_id = locale_id + + # Comment: Designates whether the user has forum moderation capabilities + # Mandatory: no + # Read-only: no + # Type: boolean + self.moderator = moderator + + # Comment: The user's name + # Mandatory: yes + # Read-only: no + # Type: string + self.name = name + + # Comment: Any notes you want to store about the user + # Mandatory: no + # Read-only: no + # Type: string + self.notes = notes + + # Comment: true if the user can only create private comments + # Mandatory: no + # Read-only: no + # Type: boolean + self.only_private_comments = only_private_comments + + # Comment: The id of the organization the user is associated with + # Mandatory: no + # Read-only: no + # Type: integer + self.organization_id = organization_id + + # Comment: The user's primary phone number. See Phone Number below + # Mandatory: no + # Read-only: no + # Type: string + self.phone = phone + + # Comment: The user's profile picture represented as an Attachment object + # Mandatory: no + # Read-only: no + # Type: :class:`Attachment` + self.photo = photo + + # Comment: If the agent has any restrictions; false for admins and unrestricted agents, true for other agents + # Mandatory: no + # Read-only: no + # Type: boolean + self.restricted_agent = restricted_agent + + # Comment: The user's role. Possible values are "end-user", "agent", or "admin" + # Mandatory: no + # Read-only: no + # Type: string + self.role = role + + # Comment: If the user is shared from a different Zendesk Support instance. Ticket sharing accounts only + # Mandatory: no + # Read-only: yes + # Type: boolean + self.shared = shared + + # Comment: If the user is a shared agent from a different Zendesk Support instance. Ticket sharing accounts only + # Mandatory: no + # Read-only: yes + # Type: boolean + self.shared_agent = shared_agent + + # Comment: The user's signature. Only agents and admins can have signatures + # Mandatory: no + # Read-only: no + # Type: string + self.signature = signature + + # Comment: If the agent is suspended. Tickets from suspended users are also suspended, and these users cannot sign in to the end user portal + # Mandatory: no + # Read-only: no + # Type: boolean + self.suspended = suspended + + # Comment: The user's tags. Only present if your account has user tagging enabled + # Mandatory: no + # Read-only: no + # Type: array + self.tags = tags + + # Comment: Specifies which tickets the user has access to. Possible values are: "organization", "groups", "assigned", "requested", null + # Mandatory: no + # Read-only: no + # Type: string + self.ticket_restriction = ticket_restriction + + # Comment: The user's time zone. See Time Zone + # Mandatory: no + # Read-only: no + # Type: string + self.time_zone = time_zone + + # Comment: If two factor authentication is enabled. + # Mandatory: no + # Read-only: yes + # Type: boolean + self.two_factor_auth_enabled = two_factor_auth_enabled + + # Comment: The time the user was last updated + # Mandatory: no + # Read-only: yes + # Type: date + self.updated_at = updated_at + + # Comment: The user's API url + # Mandatory: no + # Read-only: yes + # Type: string + self.url = url + + # Comment: Values of custom fields in the user's profile. See User Fields + # Mandatory: no + # Read-only: no + # Type: object + self.user_fields = user_fields + + # Comment: The user's primary identity is verified or not. For secondary identities, see User Identities + # Mandatory: no + # Read-only: no + # Type: boolean + self.verified = verified + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + """ + | Comment: The time the user was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def custom_role(self): + """ + | Comment: A custom role if the user is an agent on the Enterprise plan + """ + if self.api and self.custom_role_id: + return self.api._get_custom_role(self.custom_role_id) + + @custom_role.setter + def custom_role(self, custom_role): + if custom_role: + self.custom_role_id = custom_role.id + self._custom_role = custom_role + + @property + def last_login(self): + """ + | Comment: The last time the user signed in to Zendesk Support + """ + if self.last_login_at: + return dateutil.parser.parse(self.last_login_at) + + @last_login.setter + def last_login(self, last_login): + if last_login: + self.last_login_at = last_login + + @property + def organization(self): + """ + | Comment: The id of the organization the user is associated with + """ + if self.api and self.organization_id: + return self.api._get_organization(self.organization_id) + + @organization.setter + def organization(self, organization): + if organization: + self.organization_id = organization.id + self._organization = organization + + @property + def updated(self): + """ + | Comment: The time the user was last updated + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class UserField(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + active=None, + created_at=None, + description=None, + id=None, + key=None, + position=None, + raw_description=None, + raw_title=None, + regexp_for_validation=None, + title=None, + type=None, + updated_at=None, + url=None, + **kwargs): + + self.api = api + + # Comment: If true, this field is available for use + # Mandatory: no + # Read-only: no + # Type: boolean + self.active = active + + # Comment: The time the ticket field was created + # Mandatory: no + # Read-only: yes + # Type: date + self.created_at = created_at + + # Comment: User-defined description of this field's purpose + # Mandatory: no + # Read-only: no + # Type: string + self.description = description + + # Comment: Automatically assigned upon creation + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: A unique key that identifies this custom field. This is used for updating the field and referencing in placeholders. + # Mandatory: on create + # Read-only: no + # Type: string + self.key = key + + # Comment: Ordering of the field relative to other fields + # Mandatory: no + # Read-only: no + # Type: integer + self.position = position + + # Comment: The dynamic content placeholder, if present, or the "description" value, if not. See Dynamic Content + # Mandatory: no + # Read-only: no + # Type: string + self.raw_description = raw_description + + # Comment: The dynamic content placeholder, if present, or the "title" value, if not. See Dynamic Content + # Mandatory: no + # Read-only: no + # Type: string + self.raw_title = raw_title + + # Comment: Regular expression field only. The validation pattern for a field value to be deemed valid. + # Mandatory: no + # Read-only: no + # Type: string + self.regexp_for_validation = regexp_for_validation + + # Comment: The title of the custom field + # Mandatory: yes + # Read-only: no + # Type: string + self.title = title + + # Comment: Type of the custom field: "checkbox", "date", "decimal", "dropdown", "integer", "regexp", "text", or "textarea" + # Mandatory: yes + # Read-only: no + # Type: string + self.type = type + + # Comment: The time of the last update of the ticket field + # Mandatory: no + # Read-only: yes + # Type: date + self.updated_at = updated_at + + # Comment: The URL for this resource + # Mandatory: no + # Read-only: yes + # Type: string + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + """ + | Comment: The time the ticket field was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + """ + | Comment: The time of the last update of the ticket field + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class UserRelated(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + assigned_tickets=None, + ccd_tickets=None, + entry_subscriptions=None, + forum_subscriptions=None, + organization_subscriptions=None, + requested_tickets=None, + subscriptions=None, + topic_comments=None, + topics=None, + votes=None, + **kwargs): + + self.api = api + self.assigned_tickets = assigned_tickets + self.ccd_tickets = ccd_tickets + self.entry_subscriptions = entry_subscriptions + self.forum_subscriptions = forum_subscriptions + self.organization_subscriptions = organization_subscriptions + self.requested_tickets = requested_tickets + self.subscriptions = subscriptions + self.topic_comments = topic_comments + self.topics = topics + self.votes = votes + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Variant(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + active=None, + content=None, + created_at=None, + default=None, + id=None, + locale_id=None, + outdated=None, + updated_at=None, + url=None, + **kwargs): + + self.api = api + self.active = active + self.content = content + self.created_at = created_at + self.default = default + self.id = id + self.locale_id = locale_id + self.outdated = outdated + self.updated_at = updated_at + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class Via(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, api=None, source=None, **kwargs): + + self.api = api + self.source = source + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class View(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + active=None, + conditions=None, + created_at=None, + execution=None, + id=None, + position=None, + raw_title=None, + restriction=None, + sla_id=None, + title=None, + updated_at=None, + url=None, + **kwargs): + + self.api = api + + # Comment: Whether the view is active + # Read-only: no + # Type: boolean + self.active = active + + # Comment: An object describing how the view is constructed + # Read-only: no + # Type: :class:`Conditions` + self.conditions = conditions + + # Comment: The time the view was created + # Read-only: yes + # Type: date + self.created_at = created_at + + # Comment: An object describing how the view should be executed + # Read-only: no + # Type: :class:`Execute` + self.execution = execution + + # Comment: Automatically assigned when created + # Read-only: yes + # Type: integer + self.id = id + + # Comment: The position of the view + # Read-only: no + # Type: integer + self.position = position + self.raw_title = raw_title + + # Comment: Who may access this account. Will be null when everyone in the account can access it. + # Read-only: no + # Type: object + self.restriction = restriction + self.sla_id = sla_id + + # Comment: The title of the view + # Read-only: no + # Type: string + self.title = title + + # Comment: The time of the last update of the view + # Read-only: yes + # Type: date + self.updated_at = updated_at + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + """ + | Comment: The time the view was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def sla(self): + + if self.api and self.sla_id: + return self.api._get_sla(self.sla_id) + + @sla.setter + def sla(self, sla): + if sla: + self.sla_id = sla.id + self._sla = sla + + @property + def updated(self): + """ + | Comment: The time of the last update of the view + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class ViewCount(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + channel=None, + fresh=None, + poll_wait=None, + pretty=None, + refresh=None, + url=None, + value=None, + view_id=None, + **kwargs): + + self.api = api + self.channel = channel + self.fresh = fresh + self.poll_wait = poll_wait + self.pretty = pretty + self.refresh = refresh + self.url = url + self.value = value + self.view_id = view_id + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def view(self): + + if self.api and self.view_id: + return self.api._get_view(self.view_id) + + @view.setter + def view(self, view): + if view: + self.view_id = view.id + self._view = view + + +class ViewRow(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + created=None, + custom_fields=None, + fields=None, + group_id=None, + priority=None, + requester_id=None, + score=None, + subject=None, + ticket=None, + **kwargs): + + self.api = api + self.created = created + self.custom_fields = custom_fields + self.fields = fields + self.group_id = group_id + self.priority = priority + self.requester_id = requester_id + self.score = score + self.subject = subject + self.ticket = ticket + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def group(self): + + if self.api and self.group_id: + return self.api._get_group(self.group_id) + + @group.setter + def group(self, group): + if group: + self.group_id = group.id + self._group = group + + @property + def requester(self): + + if self.api and self.requester_id: + return self.api._get_user(self.requester_id) + + @requester.setter + def requester(self, requester): + if requester: + self.requester_id = requester.id + self._requester = requester + + +class VoiceCommentEvent(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + attachments=None, + author_id=None, + body=None, + data=None, + formatted_from=None, + formatted_to=None, + html_body=None, + id=None, + public=None, + transcription_visible=None, + trusted=None, + type=None, + **kwargs): + + self.api = api + self.attachments = attachments + self.author_id = author_id + self.body = body + self.data = data + self.formatted_from = formatted_from + self.formatted_to = formatted_to + self.html_body = html_body + self.id = id + self.public = public + self.transcription_visible = transcription_visible + self.trusted = trusted + self.type = type + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def author(self): + + if self.api and self.author_id: + return self.api._get_user(self.author_id) + + @author.setter + def author(self, author): + if author: + self.author_id = author.id + self._author = author diff --git a/zenpy/lib/api_objects/chat_objects.py b/zenpy/lib/api_objects/chat_objects.py index ea33e0eb..41c9b8fd 100644 --- a/zenpy/lib/api_objects/chat_objects.py +++ b/zenpy/lib/api_objects/chat_objects.py @@ -1,1127 +1,1127 @@ -from zenpy.lib.api_objects import BaseObject -import dateutil.parser - - -class Account(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - account_key=None, - billing=None, - create_date=None, - plan=None, - status=None, - **kwargs): - - self.api = api - - # Description: The widget key for the account - # Read-only: yes - # Type: string - self.account_key = account_key - - # Description: The billing information of the account - # Read-only: no - # Type: :class:`email` - self.billing = billing - - # Description: The date of creation of the account - # Read-only: yes - # Type: timestamp - self.create_date = create_date - - # Description: Information about the package of the account - # Read-only: yes - # Type: :class:`dictionary` - self.plan = plan - - # Description: The status of the account - # Read-only: yes - # Type: string - self.status = status - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Agent(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - create_date=None, - departments=None, - display_name=None, - email=None, - enabled=None, - first_name=None, - id=None, - last_login=None, - last_name=None, - login_count=None, - roles=None, - **kwargs): - - self.api = api - - # Description: The date of creation of the agent - # Read-only: yes - # Type: timestamp - self.create_date = create_date - - # Description: The departments for the agent - # Read-only: yes - # Type: array - self.departments = departments - - # Description: The name to be displayed for the agent - # Read-only: no - # Type: string - self.display_name = display_name - - # Description: The email ID of the agent - # Read-only: no - # Type: integer - self.email = email - - # Description: Describes whether the agent is enabled - # Read-only: no - # Type: integer - self.enabled = enabled - - # Description: The agent's first name - # Read-only: no - # Type: string - self.first_name = first_name - - # Description: The ID of the agent - # Read-only: yes - # Type: integer - self.id = id - self.last_login = last_login - - # Description: The agent's last name - # Read-only: no - # Type: string - self.last_name = last_name - self.login_count = login_count - - # Description: Special role privileges. See below for values (deprecated) - # Read-only: yes - # Type: object - self.roles = roles - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Ban(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, api=None, ip_address=None, visitor=None, **kwargs): - - self.api = api - - # Description: The IP address of the banned visitor - # Read-only: yes - # Type: string - self.ip_address = ip_address - self.visitor = visitor - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Billing(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - additional_info=None, - address1=None, - address2=None, - city=None, - company=None, - country_code=None, - email=None, - first_name=None, - last_name=None, - postal_code=None, - state=None, - **kwargs): - - self.api = api - self.additional_info = additional_info - self.address1 = address1 - self.address2 = address2 - self.city = city - self.company = company - self.country_code = country_code - self.email = email - self.first_name = first_name - self.last_name = last_name - self.postal_code = postal_code - self.state = state - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Chat(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - agent_ids=None, - agent_names=None, - comment=None, - count=None, - department_id=None, - department_name=None, - duration=None, - history=None, - id=None, - missed=None, - rating=None, - referrer_search_engine=None, - referrer_search_terms=None, - response_time=None, - session=None, - started_by=None, - tags=None, - triggered=None, - triggered_response=None, - type=None, - unread=None, - visitor=None, - webpath=None, - zendesk_ticket_id=None, - **kwargs): - - self.api = api - - self._end_timestamp = None - - # Description: Timestamp for the chat - # Read-only: yes - # Type: timestamp - - self._timestamp = None - - # Description: IDs of agents involved in the chat - # Read-only: yes - # Type: array - self.agent_ids = agent_ids - - # Description: Names of agents involved in the chat - # Read-only: yes - # Type: array - self.agent_names = agent_names - - # Description: The customer comment on the chat - # Read-only: no - # Type: string - self.comment = comment - - # Description: Number of messages (each) by the visitor and the agent(s) - # Read-only: yes - # Type: object - self.count = count - - # Description: The ID of the department to which the chat is directed - # Read-only: yes - # Type: integer - self.department_id = department_id - - # Description: The name of the department to which the chat is directed - # Read-only: yes - # Type: integer - self.department_name = department_name - - # Description: Duration of the chat - # Read-only: yes - # Type: timestamp - self.duration = duration - - # Description: Chronological list of messages in the chat - # Read-only: yes - # Type: array - self.history = history - - # Description: The ID of the chat - # Read-only: yes - # Type: string - self.id = id - - # Description: Whether the chat was missed or not - # Read-only: yes - # Type: boolean - self.missed = missed - - # Description: The customer satisfaction rating for the chat - # Read-only: no - # Type: string - self.rating = rating - self.referrer_search_engine = referrer_search_engine - self.referrer_search_terms = referrer_search_terms - - # Description: Statistics about the response times in the chat, avg, max and first - # Read-only: yes - # Type: object - self.response_time = response_time - - # Description: Information related to the session of the session of the chat - # Read-only: yes - # Type: object - self.session = session - - # Description: Who started the chat. Can be one of visitor, agent or trigger - # Read-only: yes - # Type: string - self.started_by = started_by - - # Description: Tags associated with the chat - # Read-only: no - # Type: array - self.tags = tags - - # Description: Whether the chat was a triggered chat or not - # Read-only: yes - # Type: boolean - self.triggered = triggered - - # Description: Whether the response was a triggered response or not - # Read-only: yes - # Type: boolean - self.triggered_response = triggered_response - - # Description: Chat type. One of offline_msg, chat - # Read-only: yes - # Type: string - self.type = type - - # Description: Whether the chat is unread - # Read-only: no - # Type: boolean - self.unread = unread - - # Description: Information about the visitor - # Read-only: yes - # Type: object - self.visitor = visitor - - # Description: The list of pages the customer navigated to during the chat - # Read-only: yes - # Type: array - self.webpath = webpath - - # Description: The ID of the Zendesk Support ticket created from this chat. Available only if using version 2 of the Zendesk Chat-Support integration - # Read-only: yes - # Type: integer - self.zendesk_ticket_id = zendesk_ticket_id - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def end_timestamp(self): - - if self._end_timestamp: - return dateutil.parser.parse(self._end_timestamp) - - @end_timestamp.setter - def end_timestamp(self, end_timestamp): - if end_timestamp: - self._end_timestamp = end_timestamp - - @property - def timestamp(self): - """ - | Description: Timestamp for the chat - """ - if self._timestamp: - return dateutil.parser.parse(self._timestamp) - - @timestamp.setter - def timestamp(self, timestamp): - if timestamp: - self._timestamp = timestamp - - @property - def agents(self): - """ - | Description: IDs of agents involved in the chat - """ - if self.api and self.agent_ids: - return self.api._get_agents(self.agent_ids) - - @agents.setter - def agents(self, agents): - if agents: - self.agent_ids = [o.id for o in agents] - self._agents = agents - - @property - def department(self): - """ - | Description: The ID of the department to which the chat is directed - """ - if self.api and self.department_id: - return self.api._get_department(self.department_id) - - @department.setter - def department(self, department): - if department: - self.department_id = department.id - self._department = department - - @property - def zendesk_ticket(self): - """ - | Description: The ID of the Zendesk Support ticket created from this chat. Available only if using version 2 of the Zendesk Chat-Support integration - """ - if self.api and self.zendesk_ticket_id: - return self.api._get_zendesk_ticket(self.zendesk_ticket_id) - - @zendesk_ticket.setter - def zendesk_ticket(self, zendesk_ticket): - if zendesk_ticket: - self.zendesk_ticket_id = zendesk_ticket.id - self._zendesk_ticket = zendesk_ticket - - -class Count(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - agent=None, - total=None, - visitor=None, - **kwargs): - - self.api = api - self.agent = agent - self.total = total - self.visitor = visitor - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Definition(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - actions=None, - condition=None, - event=None, - **kwargs): - - self.api = api - self.actions = actions - self.condition = condition - self.event = event - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Department(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - description=None, - enabled=None, - id=None, - members=None, - name=None, - settings=None, - **kwargs): - - self.api = api - - # Description: The description of the department - # Read-only: no - # Type: string - self.description = description - - # Description: Describes whether the department is enabled - # Read-only: no - # Type: integer - self.enabled = enabled - - # Description: The ID of the department - # Read-only: yes - # Type: integer - self.id = id - - # Description: The member agent IDs for the account - # Read-only: no - # Type: array - self.members = members - - # Description: The name of the department - # Read-only: no - # Type: string - self.name = name - - # Description: The settings for the department - # Read-only: no - # Type: object - self.settings = settings - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Goal(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - attribution_model=None, - attribution_period=None, - description=None, - enabled=None, - id=None, - name=None, - settings=None, - **kwargs): - - self.api = api - - # Description: Describes the attribution model associated with the goal. One of first_touch, last_touch - # Read-only: no - # Type: string - self.attribution_model = attribution_model - - # Description: Describes the attribution period in days for this goal. Range between 1 to 30 - # Read-only: no - # Type: integer - self.attribution_period = attribution_period - - # Description: The description of the goal - # Read-only: no - # Type: string - self.description = description - - # Description: Describes whether the goal is enabled - # Read-only: no - # Type: integer - self.enabled = enabled - - # Description: The ID of the goal - # Read-only: yes - # Type: integer - self.id = id - - # Description: The name of the goal - # Read-only: no - # Type: string - self.name = name - - # Description: The settings for the goal. Contains the conditions array (described below). - # Read-only: no - # Type: object - self.settings = settings - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class IpAddress(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - id=None, - ip_address=None, - reason=None, - type=None, - **kwargs): - - self.api = api - self.id = id - self.ip_address = ip_address - self.reason = reason - self.type = type - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class OfflineMessage(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - department_id=None, - department_name=None, - id=None, - message=None, - session=None, - type=None, - unread=None, - visitor=None, - zendesk_ticket_id=None, - **kwargs): - - self.api = api - - self._timestamp = None - self.department_id = department_id - self.department_name = department_name - self.id = id - self.message = message - self.session = session - self.type = type - self.unread = unread - self.visitor = visitor - self.zendesk_ticket_id = zendesk_ticket_id - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def timestamp(self): - - if self._timestamp: - return dateutil.parser.parse(self._timestamp) - - @timestamp.setter - def timestamp(self, timestamp): - if timestamp: - self._timestamp = timestamp - - @property - def department(self): - - if self.api and self.department_id: - return self.api._get_department(self.department_id) - - @department.setter - def department(self, department): - if department: - self.department_id = department.id - self._department = department - - @property - def zendesk_ticket(self): - - if self.api and self.zendesk_ticket_id: - return self.api._get_zendesk_ticket(self.zendesk_ticket_id) - - @zendesk_ticket.setter - def zendesk_ticket(self, zendesk_ticket): - if zendesk_ticket: - self.zendesk_ticket_id = zendesk_ticket.id - self._zendesk_ticket = zendesk_ticket - - -class Plan(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - agent_leaderboard=None, - agent_reports=None, - analytics=None, - chat_reports=None, - daily_reports=None, - email_reports=None, - file_upload=None, - goals=None, - high_load=None, - integrations=None, - ip_restriction=None, - long_desc=None, - max_advanced_triggers=None, - max_agents=None, - max_basic_triggers=None, - max_concurrent_chats=None, - max_departments=None, - max_history_search_days=None, - monitoring=None, - name=None, - operating_hours=None, - price=None, - rest_api=None, - short_desc=None, - sla=None, - support=None, - unbranding=None, - widget_customization=None, - **kwargs): - - self.api = api - self.agent_leaderboard = agent_leaderboard - self.agent_reports = agent_reports - self.analytics = analytics - self.chat_reports = chat_reports - self.daily_reports = daily_reports - self.email_reports = email_reports - self.file_upload = file_upload - self.goals = goals - self.high_load = high_load - self.integrations = integrations - self.ip_restriction = ip_restriction - self.long_desc = long_desc - self.max_advanced_triggers = max_advanced_triggers - self.max_agents = max_agents - self.max_basic_triggers = max_basic_triggers - self.max_concurrent_chats = max_concurrent_chats - self.max_departments = max_departments - self.max_history_search_days = max_history_search_days - self.monitoring = monitoring - self.name = name - self.operating_hours = operating_hours - self.price = price - self.rest_api = rest_api - self.short_desc = short_desc - self.sla = sla - self.support = support - self.unbranding = unbranding - self.widget_customization = widget_customization - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class ResponseTime(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, api=None, avg=None, first=None, max=None, **kwargs): - - self.api = api - self.avg = avg - self.first = first - self.max = max - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Roles(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, api=None, administrator=None, owner=None, **kwargs): - - self.api = api - self.administrator = administrator - self.owner = owner - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class SearchResult(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - id=None, - preview=None, - type=None, - url=None, - **kwargs): - - self.api = api - - self._timestamp = None - self.id = id - self.preview = preview - self.type = type - self.url = url - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def timestamp(self): - - if self._timestamp: - return dateutil.parser.parse(self._timestamp) - - @timestamp.setter - def timestamp(self, timestamp): - if timestamp: - self._timestamp = timestamp - - -class Session(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - browser=None, - city=None, - country_code=None, - country_name=None, - end_date=None, - id=None, - ip=None, - platform=None, - region=None, - start_date=None, - user_agent=None, - **kwargs): - - self.api = api - self.browser = browser - self.city = city - self.country_code = country_code - self.country_name = country_name - self.end_date = end_date - self.id = id - self.ip = ip - self.platform = platform - self.region = region - self.start_date = start_date - self.user_agent = user_agent - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Shortcut(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - message=None, - name=None, - options=None, - tags=None, - **kwargs): - - self.api = api - - # Description: The message of the shortcut - # Read-only: no - # Type: string - self.message = message - - # Description: The name of the shortcut - # Read-only: no - # Type: string - self.name = name - - # Description: Options for the shortcut - # Read-only: no - # Type: integer - self.options = options - - # Description: List of tags that will be added to chat if the shortcut is used - # Read-only: no - # Type: array - self.tags = tags - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Trigger(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - definition=None, - description=None, - enabled=None, - name=None, - **kwargs): - - self.api = api - self.definition = definition - - # Description: The description of the trigger - # Read-only: no - # Type: string - self.description = description - - # Description: Whether the trigger is enabled or not - # Read-only: no - # Type: integer - self.enabled = enabled - - # Description: The name of the trigger - # Read-only: no - # Type: string - self.name = name - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Visitor(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - email=None, - id=None, - name=None, - notes=None, - phone=None, - **kwargs): - - self.api = api - - # Description: The email ID of the visitor - # Read-only: no - # Type: :class:`email` - self.email = email - - # Description: The ID of the visitor - # Read-only: yes - # Type: integer - self.id = id - - # Description: The name to be displayed for the visitor - # Read-only: no - # Type: string - self.name = name - - # Description: Any additional notes about the visitor - # Read-only: yes - # Type: string - self.notes = notes - - # Description: The phone number of the visitor (if available) - # Read-only: no - # Type: integer - self.phone = phone - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Webpath(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, api=None, from_=None, title=None, to=None, **kwargs): - - self.api = api - - self._timestamp = None - self.from_ = from_ - self.title = title - self.to = to - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def timestamp(self): - - if self._timestamp: - return dateutil.parser.parse(self._timestamp) - - @timestamp.setter - def timestamp(self, timestamp): - if timestamp: - self._timestamp = timestamp +from zenpy.lib.api_objects import BaseObject +import dateutil.parser + + +class Account(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + account_key=None, + billing=None, + create_date=None, + plan=None, + status=None, + **kwargs): + + self.api = api + + # Description: The widget key for the account + # Read-only: yes + # Type: string + self.account_key = account_key + + # Description: The billing information of the account + # Read-only: no + # Type: :class:`email` + self.billing = billing + + # Description: The date of creation of the account + # Read-only: yes + # Type: timestamp + self.create_date = create_date + + # Description: Information about the package of the account + # Read-only: yes + # Type: :class:`dictionary` + self.plan = plan + + # Description: The status of the account + # Read-only: yes + # Type: string + self.status = status + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Agent(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + create_date=None, + departments=None, + display_name=None, + email=None, + enabled=None, + first_name=None, + id=None, + last_login=None, + last_name=None, + login_count=None, + roles=None, + **kwargs): + + self.api = api + + # Description: The date of creation of the agent + # Read-only: yes + # Type: timestamp + self.create_date = create_date + + # Description: The departments for the agent + # Read-only: yes + # Type: array + self.departments = departments + + # Description: The name to be displayed for the agent + # Read-only: no + # Type: string + self.display_name = display_name + + # Description: The email ID of the agent + # Read-only: no + # Type: integer + self.email = email + + # Description: Describes whether the agent is enabled + # Read-only: no + # Type: integer + self.enabled = enabled + + # Description: The agent's first name + # Read-only: no + # Type: string + self.first_name = first_name + + # Description: The ID of the agent + # Read-only: yes + # Type: integer + self.id = id + self.last_login = last_login + + # Description: The agent's last name + # Read-only: no + # Type: string + self.last_name = last_name + self.login_count = login_count + + # Description: Special role privileges. See below for values (deprecated) + # Read-only: yes + # Type: object + self.roles = roles + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Ban(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, api=None, ip_address=None, visitor=None, **kwargs): + + self.api = api + + # Description: The IP address of the banned visitor + # Read-only: yes + # Type: string + self.ip_address = ip_address + self.visitor = visitor + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Billing(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + additional_info=None, + address1=None, + address2=None, + city=None, + company=None, + country_code=None, + email=None, + first_name=None, + last_name=None, + postal_code=None, + state=None, + **kwargs): + + self.api = api + self.additional_info = additional_info + self.address1 = address1 + self.address2 = address2 + self.city = city + self.company = company + self.country_code = country_code + self.email = email + self.first_name = first_name + self.last_name = last_name + self.postal_code = postal_code + self.state = state + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Chat(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + agent_ids=None, + agent_names=None, + comment=None, + count=None, + department_id=None, + department_name=None, + duration=None, + history=None, + id=None, + missed=None, + rating=None, + referrer_search_engine=None, + referrer_search_terms=None, + response_time=None, + session=None, + started_by=None, + tags=None, + triggered=None, + triggered_response=None, + type=None, + unread=None, + visitor=None, + webpath=None, + zendesk_ticket_id=None, + **kwargs): + + self.api = api + + self._end_timestamp = None + + # Description: Timestamp for the chat + # Read-only: yes + # Type: timestamp + + self._timestamp = None + + # Description: IDs of agents involved in the chat + # Read-only: yes + # Type: array + self.agent_ids = agent_ids + + # Description: Names of agents involved in the chat + # Read-only: yes + # Type: array + self.agent_names = agent_names + + # Description: The customer comment on the chat + # Read-only: no + # Type: string + self.comment = comment + + # Description: Number of messages (each) by the visitor and the agent(s) + # Read-only: yes + # Type: object + self.count = count + + # Description: The ID of the department to which the chat is directed + # Read-only: yes + # Type: integer + self.department_id = department_id + + # Description: The name of the department to which the chat is directed + # Read-only: yes + # Type: integer + self.department_name = department_name + + # Description: Duration of the chat + # Read-only: yes + # Type: timestamp + self.duration = duration + + # Description: Chronological list of messages in the chat + # Read-only: yes + # Type: array + self.history = history + + # Description: The ID of the chat + # Read-only: yes + # Type: string + self.id = id + + # Description: Whether the chat was missed or not + # Read-only: yes + # Type: boolean + self.missed = missed + + # Description: The customer satisfaction rating for the chat + # Read-only: no + # Type: string + self.rating = rating + self.referrer_search_engine = referrer_search_engine + self.referrer_search_terms = referrer_search_terms + + # Description: Statistics about the response times in the chat, avg, max and first + # Read-only: yes + # Type: object + self.response_time = response_time + + # Description: Information related to the session of the session of the chat + # Read-only: yes + # Type: object + self.session = session + + # Description: Who started the chat. Can be one of visitor, agent or trigger + # Read-only: yes + # Type: string + self.started_by = started_by + + # Description: Tags associated with the chat + # Read-only: no + # Type: array + self.tags = tags + + # Description: Whether the chat was a triggered chat or not + # Read-only: yes + # Type: boolean + self.triggered = triggered + + # Description: Whether the response was a triggered response or not + # Read-only: yes + # Type: boolean + self.triggered_response = triggered_response + + # Description: Chat type. One of offline_msg, chat + # Read-only: yes + # Type: string + self.type = type + + # Description: Whether the chat is unread + # Read-only: no + # Type: boolean + self.unread = unread + + # Description: Information about the visitor + # Read-only: yes + # Type: object + self.visitor = visitor + + # Description: The list of pages the customer navigated to during the chat + # Read-only: yes + # Type: array + self.webpath = webpath + + # Description: The ID of the Zendesk Support ticket created from this chat. Available only if using version 2 of the Zendesk Chat-Support integration + # Read-only: yes + # Type: integer + self.zendesk_ticket_id = zendesk_ticket_id + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def end_timestamp(self): + + if self._end_timestamp: + return dateutil.parser.parse(self._end_timestamp) + + @end_timestamp.setter + def end_timestamp(self, end_timestamp): + if end_timestamp: + self._end_timestamp = end_timestamp + + @property + def timestamp(self): + """ + | Description: Timestamp for the chat + """ + if self._timestamp: + return dateutil.parser.parse(self._timestamp) + + @timestamp.setter + def timestamp(self, timestamp): + if timestamp: + self._timestamp = timestamp + + @property + def agents(self): + """ + | Description: IDs of agents involved in the chat + """ + if self.api and self.agent_ids: + return self.api._get_agents(self.agent_ids) + + @agents.setter + def agents(self, agents): + if agents: + self.agent_ids = [o.id for o in agents] + self._agents = agents + + @property + def department(self): + """ + | Description: The ID of the department to which the chat is directed + """ + if self.api and self.department_id: + return self.api._get_department(self.department_id) + + @department.setter + def department(self, department): + if department: + self.department_id = department.id + self._department = department + + @property + def zendesk_ticket(self): + """ + | Description: The ID of the Zendesk Support ticket created from this chat. Available only if using version 2 of the Zendesk Chat-Support integration + """ + if self.api and self.zendesk_ticket_id: + return self.api._get_zendesk_ticket(self.zendesk_ticket_id) + + @zendesk_ticket.setter + def zendesk_ticket(self, zendesk_ticket): + if zendesk_ticket: + self.zendesk_ticket_id = zendesk_ticket.id + self._zendesk_ticket = zendesk_ticket + + +class Count(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + agent=None, + total=None, + visitor=None, + **kwargs): + + self.api = api + self.agent = agent + self.total = total + self.visitor = visitor + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Definition(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + actions=None, + condition=None, + event=None, + **kwargs): + + self.api = api + self.actions = actions + self.condition = condition + self.event = event + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Department(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + description=None, + enabled=None, + id=None, + members=None, + name=None, + settings=None, + **kwargs): + + self.api = api + + # Description: The description of the department + # Read-only: no + # Type: string + self.description = description + + # Description: Describes whether the department is enabled + # Read-only: no + # Type: integer + self.enabled = enabled + + # Description: The ID of the department + # Read-only: yes + # Type: integer + self.id = id + + # Description: The member agent IDs for the account + # Read-only: no + # Type: array + self.members = members + + # Description: The name of the department + # Read-only: no + # Type: string + self.name = name + + # Description: The settings for the department + # Read-only: no + # Type: object + self.settings = settings + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Goal(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + attribution_model=None, + attribution_period=None, + description=None, + enabled=None, + id=None, + name=None, + settings=None, + **kwargs): + + self.api = api + + # Description: Describes the attribution model associated with the goal. One of first_touch, last_touch + # Read-only: no + # Type: string + self.attribution_model = attribution_model + + # Description: Describes the attribution period in days for this goal. Range between 1 to 30 + # Read-only: no + # Type: integer + self.attribution_period = attribution_period + + # Description: The description of the goal + # Read-only: no + # Type: string + self.description = description + + # Description: Describes whether the goal is enabled + # Read-only: no + # Type: integer + self.enabled = enabled + + # Description: The ID of the goal + # Read-only: yes + # Type: integer + self.id = id + + # Description: The name of the goal + # Read-only: no + # Type: string + self.name = name + + # Description: The settings for the goal. Contains the conditions array (described below). + # Read-only: no + # Type: object + self.settings = settings + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class IpAddress(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + id=None, + ip_address=None, + reason=None, + type=None, + **kwargs): + + self.api = api + self.id = id + self.ip_address = ip_address + self.reason = reason + self.type = type + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class OfflineMessage(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + department_id=None, + department_name=None, + id=None, + message=None, + session=None, + type=None, + unread=None, + visitor=None, + zendesk_ticket_id=None, + **kwargs): + + self.api = api + + self._timestamp = None + self.department_id = department_id + self.department_name = department_name + self.id = id + self.message = message + self.session = session + self.type = type + self.unread = unread + self.visitor = visitor + self.zendesk_ticket_id = zendesk_ticket_id + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def timestamp(self): + + if self._timestamp: + return dateutil.parser.parse(self._timestamp) + + @timestamp.setter + def timestamp(self, timestamp): + if timestamp: + self._timestamp = timestamp + + @property + def department(self): + + if self.api and self.department_id: + return self.api._get_department(self.department_id) + + @department.setter + def department(self, department): + if department: + self.department_id = department.id + self._department = department + + @property + def zendesk_ticket(self): + + if self.api and self.zendesk_ticket_id: + return self.api._get_zendesk_ticket(self.zendesk_ticket_id) + + @zendesk_ticket.setter + def zendesk_ticket(self, zendesk_ticket): + if zendesk_ticket: + self.zendesk_ticket_id = zendesk_ticket.id + self._zendesk_ticket = zendesk_ticket + + +class Plan(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + agent_leaderboard=None, + agent_reports=None, + analytics=None, + chat_reports=None, + daily_reports=None, + email_reports=None, + file_upload=None, + goals=None, + high_load=None, + integrations=None, + ip_restriction=None, + long_desc=None, + max_advanced_triggers=None, + max_agents=None, + max_basic_triggers=None, + max_concurrent_chats=None, + max_departments=None, + max_history_search_days=None, + monitoring=None, + name=None, + operating_hours=None, + price=None, + rest_api=None, + short_desc=None, + sla=None, + support=None, + unbranding=None, + widget_customization=None, + **kwargs): + + self.api = api + self.agent_leaderboard = agent_leaderboard + self.agent_reports = agent_reports + self.analytics = analytics + self.chat_reports = chat_reports + self.daily_reports = daily_reports + self.email_reports = email_reports + self.file_upload = file_upload + self.goals = goals + self.high_load = high_load + self.integrations = integrations + self.ip_restriction = ip_restriction + self.long_desc = long_desc + self.max_advanced_triggers = max_advanced_triggers + self.max_agents = max_agents + self.max_basic_triggers = max_basic_triggers + self.max_concurrent_chats = max_concurrent_chats + self.max_departments = max_departments + self.max_history_search_days = max_history_search_days + self.monitoring = monitoring + self.name = name + self.operating_hours = operating_hours + self.price = price + self.rest_api = rest_api + self.short_desc = short_desc + self.sla = sla + self.support = support + self.unbranding = unbranding + self.widget_customization = widget_customization + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class ResponseTime(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, api=None, avg=None, first=None, max=None, **kwargs): + + self.api = api + self.avg = avg + self.first = first + self.max = max + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Roles(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, api=None, administrator=None, owner=None, **kwargs): + + self.api = api + self.administrator = administrator + self.owner = owner + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class SearchResult(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + id=None, + preview=None, + type=None, + url=None, + **kwargs): + + self.api = api + + self._timestamp = None + self.id = id + self.preview = preview + self.type = type + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def timestamp(self): + + if self._timestamp: + return dateutil.parser.parse(self._timestamp) + + @timestamp.setter + def timestamp(self, timestamp): + if timestamp: + self._timestamp = timestamp + + +class Session(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + browser=None, + city=None, + country_code=None, + country_name=None, + end_date=None, + id=None, + ip=None, + platform=None, + region=None, + start_date=None, + user_agent=None, + **kwargs): + + self.api = api + self.browser = browser + self.city = city + self.country_code = country_code + self.country_name = country_name + self.end_date = end_date + self.id = id + self.ip = ip + self.platform = platform + self.region = region + self.start_date = start_date + self.user_agent = user_agent + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Shortcut(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + message=None, + name=None, + options=None, + tags=None, + **kwargs): + + self.api = api + + # Description: The message of the shortcut + # Read-only: no + # Type: string + self.message = message + + # Description: The name of the shortcut + # Read-only: no + # Type: string + self.name = name + + # Description: Options for the shortcut + # Read-only: no + # Type: integer + self.options = options + + # Description: List of tags that will be added to chat if the shortcut is used + # Read-only: no + # Type: array + self.tags = tags + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Trigger(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + definition=None, + description=None, + enabled=None, + name=None, + **kwargs): + + self.api = api + self.definition = definition + + # Description: The description of the trigger + # Read-only: no + # Type: string + self.description = description + + # Description: Whether the trigger is enabled or not + # Read-only: no + # Type: integer + self.enabled = enabled + + # Description: The name of the trigger + # Read-only: no + # Type: string + self.name = name + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Visitor(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + email=None, + id=None, + name=None, + notes=None, + phone=None, + **kwargs): + + self.api = api + + # Description: The email ID of the visitor + # Read-only: no + # Type: :class:`email` + self.email = email + + # Description: The ID of the visitor + # Read-only: yes + # Type: integer + self.id = id + + # Description: The name to be displayed for the visitor + # Read-only: no + # Type: string + self.name = name + + # Description: Any additional notes about the visitor + # Read-only: yes + # Type: string + self.notes = notes + + # Description: The phone number of the visitor (if available) + # Read-only: no + # Type: integer + self.phone = phone + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Webpath(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, api=None, from_=None, title=None, to=None, **kwargs): + + self.api = api + + self._timestamp = None + self.from_ = from_ + self.title = title + self.to = to + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def timestamp(self): + + if self._timestamp: + return dateutil.parser.parse(self._timestamp) + + @timestamp.setter + def timestamp(self, timestamp): + if timestamp: + self._timestamp = timestamp diff --git a/zenpy/lib/api_objects/help_centre_objects.py b/zenpy/lib/api_objects/help_centre_objects.py index 49965ff7..fd60defb 100644 --- a/zenpy/lib/api_objects/help_centre_objects.py +++ b/zenpy/lib/api_objects/help_centre_objects.py @@ -1,1856 +1,1856 @@ -from zenpy.lib.api_objects import BaseObject -import dateutil.parser - - -class AccessPolicy(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - manageable_by=None, - required_tags=None, - restricted_to_group_ids=None, - restricted_to_organization_ids=None, - viewable_by=None, - **kwargs): - - self.api = api - self.manageable_by = manageable_by - self.required_tags = required_tags - self.restricted_to_group_ids = restricted_to_group_ids - self.restricted_to_organization_ids = restricted_to_organization_ids - self.viewable_by = viewable_by - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def restricted_to_groups(self): - - if self.api and self.restricted_to_group_ids: - return self.api._get_restricted_to_groups( - self.restricted_to_group_ids) - - @restricted_to_groups.setter - def restricted_to_groups(self, restricted_to_groups): - if restricted_to_groups: - self.restricted_to_group_ids = [o.id for o in restricted_to_groups] - self._restricted_to_groups = restricted_to_groups - - @property - def restricted_to_organizations(self): - - if self.api and self.restricted_to_organization_ids: - return self.api._get_restricted_to_organizations( - self.restricted_to_organization_ids) - - @restricted_to_organizations.setter - def restricted_to_organizations(self, restricted_to_organizations): - if restricted_to_organizations: - self.restricted_to_organization_ids = [ - o.id for o in restricted_to_organizations - ] - self._restricted_to_organizations = restricted_to_organizations - - -class Article(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - author_id=None, - body=None, - comments_disabled=None, - created_at=None, - draft=None, - html_url=None, - id=None, - label_names=None, - locale=None, - name=None, - outdated=None, - outdated_locales=None, - permission_group_id=None, - position=None, - promoted=None, - section_id=None, - source_locale=None, - title=None, - updated_at=None, - url=None, - user_segment_id=None, - vote_count=None, - vote_sum=None, - **kwargs): - - self.api = api - - # Comment: The id of the user who wrote the article (set to the user who made the request on create by default) - # Mandatory: no - # Read-only: no - # Type: integer - self.author_id = author_id - - # Comment: The body of the article - # Mandatory: no - # Read-only: no - # Type: string - self.body = body - - # Comment: True if comments are disabled; false otherwise - # Mandatory: no - # Read-only: no - # Type: boolean - self.comments_disabled = comments_disabled - - # Comment: The time the article was created - # Mandatory: no - # Read-only: yes - # Type: timestamp - self.created_at = created_at - - # Comment: True if the translation for the current locale is a draft; false otherwise. false by default. Can be set when creating but not when updating. For updating, see Translations - # Mandatory: no - # Read-only: yes - # Type: boolean - self.draft = draft - - # Comment: The url of the article in Help Center - # Mandatory: no - # Read-only: yes - # Type: string - self.html_url = html_url - - # Comment: Automatically assigned when the article is created - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: An array of label names associated with this article. By default no label names are used. Only available on certain plans - # Mandatory: no - # Read-only: no - # Type: string - self.label_names = label_names - - # Comment: The locale that the article is being displayed in - # Mandatory: yes - # Read-only: no - # Type: string - self.locale = locale - self.name = name - - # Comment: Deprecated. Always false because the source translation is always the most up-to-date translation - # Mandatory: no - # Read-only: yes - # Type: boolean - self.outdated = outdated - - # Comment: Locales in which the article was marked as outdated - # Mandatory: no - # Read-only: yes - # Type: array - self.outdated_locales = outdated_locales - - # Comment: The id of the permission group which defines who can edit and publish this article - # Mandatory: yes - # Read-only: no - # Type: integer - self.permission_group_id = permission_group_id - - # Comment: The position of this article in the article list. 0 by default - # Mandatory: no - # Read-only: no - # Type: integer - self.position = position - - # Comment: True if this article is promoted; false otherwise. false by default - # Mandatory: no - # Read-only: no - # Type: boolean - self.promoted = promoted - - # Comment: The id of the section to which this article belongs - # Mandatory: no - # Read-only: no - # Type: integer - self.section_id = section_id - - # Comment: The source (default) locale of the article - # Mandatory: no - # Read-only: yes - # Type: string - self.source_locale = source_locale - - # Comment: The title of the article - # Mandatory: yes - # Read-only: no - # Type: string - self.title = title - - # Comment: The time the article was last updated - # Mandatory: no - # Read-only: yes - # Type: timestamp - self.updated_at = updated_at - - # Comment: The API url of the article - # Mandatory: no - # Read-only: yes - # Type: string - self.url = url - - # Comment: The id of the user segment which defines who can see this article. Set to null to make it accessible to everyone - # Mandatory: yes - # Read-only: no - # Type: integer - self.user_segment_id = user_segment_id - - # Comment: The total number of upvotes and downvotes - # Mandatory: no - # Read-only: yes - # Type: integer - self.vote_count = vote_count - - # Comment: The sum of upvotes (+1) and downvotes (-1), which may be positive or negative - # Mandatory: no - # Read-only: yes - # Type: integer - self.vote_sum = vote_sum - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def author(self): - """ - | Comment: The id of the user who wrote the article (set to the user who made the request on create by default) - """ - if self.api and self.author_id: - return self.api._get_user(self.author_id) - - @author.setter - def author(self, author): - if author: - self.author_id = author.id - self._author = author - - @property - def created(self): - """ - | Comment: The time the article was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def permission_group(self): - """ - | Comment: The id of the permission group which defines who can edit and publish this article - """ - if self.api and self.permission_group_id: - return self.api._get_permission_group(self.permission_group_id) - - @permission_group.setter - def permission_group(self, permission_group): - if permission_group: - self.permission_group_id = permission_group.id - self._permission_group = permission_group - - @property - def section(self): - """ - | Comment: The id of the section to which this article belongs - """ - if self.api and self.section_id: - return self.api._get_section(self.section_id) - - @section.setter - def section(self, section): - if section: - self.section_id = section.id - self._section = section - - @property - def updated(self): - """ - | Comment: The time the article was last updated - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - @property - def user_segment(self): - """ - | Comment: The id of the user segment which defines who can see this article. Set to null to make it accessible to everyone - """ - if self.api and self.user_segment_id: - return self.api._get_user_segment(self.user_segment_id) - - @user_segment.setter - def user_segment(self, user_segment): - if user_segment: - self.user_segment_id = user_segment.id - self._user_segment = user_segment - - -class ArticleAttachment(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - article_id=None, - content_type=None, - content_url=None, - created_at=None, - display_file_name=None, - file_name=None, - id=None, - inline=None, - legacy=None, - relative_path=None, - size=None, - updated_at=None, - url=None, - **kwargs): - - self.api = api - - # Comment: Id of the associated article, if present - # Type: integer - self.article_id = article_id - - # Comment: The content type of the file. Example: image/png - # Type: string - self.content_type = content_type - - # Comment: A full URL where the attachment file can be downloaded - # Type: string - self.content_url = content_url - - # Comment: The time at which the article attachment was created - # Type: timestamp - self.created_at = created_at - self.display_file_name = display_file_name - - # Comment: The name of the file - # Type: string - self.file_name = file_name - - # Comment: Automatically assigned when the article attachment is created - # Type: integer - self.id = id - - # Comment: If true, the attached file is shown in the dedicated admin UI for inline attachments and its url can be referenced in the HTML body of the article. If false, the attachment is listed in the list of attachments. Default is false - # Type: boolean - self.inline = inline - self.legacy = legacy - self.relative_path = relative_path - - # Comment: The size of the attachment file in bytes - # Type: integer - self.size = size - - # Comment: The time at which the article attachment was last updated - # Type: timestamp - self.updated_at = updated_at - - # Comment: The API url of this article attachment - # Type: string - self.url = url - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def article(self): - """ - | Comment: Id of the associated article, if present - """ - if self.api and self.article_id: - return self.api._get_article(self.article_id) - - @article.setter - def article(self, article): - if article: - self.article_id = article.id - self._article = article - - @property - def created(self): - """ - | Comment: The time at which the article attachment was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - """ - | Comment: The time at which the article attachment was last updated - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class Category(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - created_at=None, - description=None, - html_url=None, - id=None, - locale=None, - name=None, - outdated=None, - position=None, - source_locale=None, - updated_at=None, - url=None, - **kwargs): - - self.api = api - self.created_at = created_at - self.description = description - self.html_url = html_url - self.id = id - self.locale = locale - self.name = name - self.outdated = outdated - self.position = position - self.source_locale = source_locale - self.updated_at = updated_at - self.url = url - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class Comment(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - author_id=None, - body=None, - created_at=None, - html_url=None, - id=None, - locale=None, - source_id=None, - source_type=None, - updated_at=None, - url=None, - vote_count=None, - vote_sum=None, - **kwargs): - - self.api = api - - # Comment: The id of the author of this comment. Writable on create by Help Center managers -- see Create Comment - # Mandatory: no - # Read-only: yes - # Type: integer - self.author_id = author_id - - # Comment: The comment made by the author - # Mandatory: yes - # Read-only: no - # Type: string - self.body = body - - # Comment: The time at which the comment was created. Writable on create by Help Center managers -- see Create Comment - # Mandatory: no - # Read-only: yes - # Type: timestamp - self.created_at = created_at - - # Comment: The url at which the comment is presented in Help Center - # Mandatory: no - # Read-only: yes - # Type: string - self.html_url = html_url - - # Comment: Automatically assigned when the comment is created - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: The locale in which this comment was made - # Mandatory: yes - # Read-only: no - # Type: string - self.locale = locale - - # Comment: The id of the item on which this comment was made - # Mandatory: no - # Read-only: yes - # Type: integer - self.source_id = source_id - - # Comment: The type of the item on which this comment was made. Currently only supports 'Article' - # Mandatory: no - # Read-only: yes - # Type: string - self.source_type = source_type - - # Comment: The time at which the comment was last updated - # Mandatory: no - # Read-only: yes - # Type: timestamp - self.updated_at = updated_at - - # Comment: The API url of this comment - # Mandatory: no - # Read-only: yes - # Type: string - self.url = url - - # Comment: The total number of upvotes and downvotes - # Mandatory: no - # Read-only: yes - # Type: integer - self.vote_count = vote_count - - # Comment: The sum of upvotes (+1) and downvotes (-1), which may be positive or negative - # Mandatory: no - # Read-only: yes - # Type: integer - self.vote_sum = vote_sum - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def author(self): - """ - | Comment: The id of the author of this comment. Writable on create by Help Center managers -- see Create Comment - """ - if self.api and self.author_id: - return self.api._get_user(self.author_id) - - @author.setter - def author(self, author): - if author: - self.author_id = author.id - self._author = author - - @property - def created(self): - """ - | Comment: The time at which the comment was created. Writable on create by Help Center managers -- see Create Comment - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - """ - | Comment: The time at which the comment was last updated - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class Label(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - created_at=None, - id=None, - name=None, - updated_at=None, - url=None, - **kwargs): - - self.api = api - - # Comment: The time at which the label was created - # Mandatory: no - # Read-only: yes - # Type: timestamp - self.created_at = created_at - - # Comment: Automatically assigned when the label is created - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: The actual name of the label - # Mandatory: yes - # Read-only: no - # Type: string - self.name = name - - # Comment: The time at which the label was last updated - # Mandatory: no - # Read-only: yes - # Type: timestamp - self.updated_at = updated_at - - # Comment: The API url of this label - # Mandatory: no - # Read-only: yes - # Type: string - self.url = url - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - """ - | Comment: The time at which the label was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - """ - | Comment: The time at which the label was last updated - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class ManagementPermissionGroup(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - built_in=None, - created_at=None, - edit=None, - id=None, - name=None, - publish=None, - updated_at=None, - **kwargs): - - self.api = api - self.built_in = built_in - self.created_at = created_at - self.edit = edit - self.id = id - self.name = name - self.publish = publish - self.updated_at = updated_at - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class Post(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - author_id=None, - closed=None, - comment_count=None, - created_at=None, - details=None, - featured=None, - follower_count=None, - html_url=None, - id=None, - pinned=None, - status=None, - title=None, - topic_id=None, - updated_at=None, - url=None, - vote_count=None, - vote_sum=None, - **kwargs): - - self.api = api - - # Comment: The id of the author of the post. Writable on create by Help Center managers -- see Create Post - # Mandatory: no - # Read-only: yes - # Type: integer - self.author_id = author_id - - # Comment: Whether further comments are allowed - # Mandatory: no - # Read-only: no - # Type: boolean - self.closed = closed - - # Comment: The number of comments on the post - # Mandatory: no - # Read-only: yes - # Type: integer - self.comment_count = comment_count - - # Comment: When the post was created. Writable on create by Help Center managers -- see Create Post - # Mandatory: no - # Read-only: yes - # Type: timestamp - self.created_at = created_at - - # Comment: The details of the post - # Mandatory: yes - # Read-only: no - # Type: string - self.details = details - - # Comment: Whether the post is featured - # Mandatory: no - # Read-only: no - # Type: boolean - self.featured = featured - - # Comment: The number of followers of the post - # Mandatory: no - # Read-only: yes - # Type: integer - self.follower_count = follower_count - - # Comment: The community url of the post - # Mandatory: no - # Read-only: yes - # Type: string - self.html_url = html_url - - # Comment: Automatically assigned when the post is created - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: When true, pins the post to the top of its topic - # Mandatory: no - # Read-only: no - # Type: boolean - self.pinned = pinned - - # Comment: The status of the post. Possible values: "planned", "not_planned" , "answered", or "completed" - # Mandatory: no - # Read-only: no - # Type: string - self.status = status - - # Comment: The title of the post - # Mandatory: yes - # Read-only: no - # Type: string - self.title = title - - # Comment: The id of the topic that the post belongs to - # Mandatory: yes - # Read-only: no - # Type: integer - self.topic_id = topic_id - - # Comment: When the post was last updated - # Mandatory: no - # Read-only: yes - # Type: timestamp - self.updated_at = updated_at - - # Comment: The API url of the post - # Mandatory: no - # Read-only: yes - # Type: string - self.url = url - - # Comment: The total number of upvotes and downvotes - # Mandatory: no - # Read-only: yes - # Type: integer - self.vote_count = vote_count - - # Comment: The sum of upvotes (+1) and downvotes (-1), which may be positive or negative - # Mandatory: no - # Read-only: yes - # Type: integer - self.vote_sum = vote_sum - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def author(self): - """ - | Comment: The id of the author of the post. Writable on create by Help Center managers -- see Create Post - """ - if self.api and self.author_id: - return self.api._get_user(self.author_id) - - @author.setter - def author(self, author): - if author: - self.author_id = author.id - self._author = author - - @property - def created(self): - """ - | Comment: When the post was created. Writable on create by Help Center managers -- see Create Post - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def topic(self): - """ - | Comment: The id of the topic that the post belongs to - """ - if self.api and self.topic_id: - return self.api._get_topic(self.topic_id) - - @topic.setter - def topic(self, topic): - if topic: - self.topic_id = topic.id - self._topic = topic - - @property - def updated(self): - """ - | Comment: When the post was last updated - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class Section(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - category_id=None, - created_at=None, - description=None, - html_url=None, - id=None, - locale=None, - manageable_by=None, - name=None, - outdated=None, - position=None, - sorting=None, - source_locale=None, - updated_at=None, - url=None, - user_segment_id=None, - **kwargs): - - self.api = api - - # Comment: The id of the category to which this section belongs - # Mandatory: no - # Read-only: no - # Type: integer - self.category_id = category_id - - # Comment: The time at which the section was created - # Mandatory: no - # Read-only: yes - # Type: timestamp - self.created_at = created_at - - # Comment: The description of the section - # Mandatory: no - # Read-only: no - # Type: string - self.description = description - - # Comment: The url of this section in HC - # Mandatory: no - # Read-only: yes - # Type: string - self.html_url = html_url - - # Comment: Automatically assigned when creating subscriptions - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: The locale in which the section is displayed - # Mandatory: yes - # Read-only: no - # Type: string - self.locale = locale - - # Comment: The set of users who can manage this section - # Mandatory: no - # Read-only: no - # Type: string - self.manageable_by = manageable_by - - # Comment: The name of the section - # Mandatory: yes - # Read-only: no - # Type: string - self.name = name - - # Comment: Whether the section is out of date - # Mandatory: no - # Read-only: yes - # Type: boolean - self.outdated = outdated - - # Comment: The position of this section in the section list. By default the section is added to the end of the list - # Mandatory: no - # Read-only: no - # Type: integer - self.position = position - self.sorting = sorting - - # Comment: The source (default) locale of the section - # Mandatory: no - # Read-only: yes - # Type: string - self.source_locale = source_locale - - # Comment: The time at which the section was last updated - # Mandatory: no - # Read-only: yes - # Type: timestamp - self.updated_at = updated_at - - # Comment: The API url of this section - # Mandatory: no - # Read-only: yes - # Type: string - self.url = url - - # Comment: The id of the user segment to which this section belongs - # Mandatory: no - # Read-only: no - # Type: integer - self.user_segment_id = user_segment_id - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def category(self): - """ - | Comment: The id of the category to which this section belongs - """ - if self.api and self.category_id: - return self.api._get_category(self.category_id) - - @category.setter - def category(self, category): - if category: - self.category_id = category.id - self._category = category - - @property - def created(self): - """ - | Comment: The time at which the section was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - """ - | Comment: The time at which the section was last updated - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - @property - def user_segment(self): - """ - | Comment: The id of the user segment to which this section belongs - """ - if self.api and self.user_segment_id: - return self.api._get_user_segment(self.user_segment_id) - - @user_segment.setter - def user_segment(self, user_segment): - if user_segment: - self.user_segment_id = user_segment.id - self._user_segment = user_segment - - -class Subscription(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - content_id=None, - created_at=None, - id=None, - locale=None, - updated_at=None, - url=None, - user_id=None, - **kwargs): - - self.api = api - - # Comment: The id of the subscribed item - # Mandatory: no - # Read-only: yes - # Type: integer - self.content_id = content_id - - # Comment: The time at which the subscription was created - # Mandatory: no - # Read-only: yes - # Type: timestamp - self.created_at = created_at - - # Comment: Automatically assigned when the subscription is created - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: The locale of the subscribed item - # Mandatory: yes - # Read-only: yes - # Type: string - self.locale = locale - - # Comment: The time at which the subscription was last updated - # Mandatory: no - # Read-only: yes - # Type: timestamp - self.updated_at = updated_at - - # Comment: The API url of the subscription - # Mandatory: no - # Read-only: yes - # Type: string - self.url = url - - # Comment: The id of the user who has this subscription - # Mandatory: no - # Read-only: yes - # Type: integer - self.user_id = user_id - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - """ - | Comment: The time at which the subscription was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - """ - | Comment: The time at which the subscription was last updated - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - @property - def user(self): - """ - | Comment: The id of the user who has this subscription - """ - if self.api and self.user_id: - return self.api._get_user(self.user_id) - - @user.setter - def user(self, user): - if user: - self.user_id = user.id - self._user = user - - -class Topic(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - community_id=None, - created_at=None, - description=None, - follower_count=None, - html_url=None, - id=None, - name=None, - position=None, - updated_at=None, - url=None, - user_segment_id=None, - **kwargs): - - self.api = api - self.community_id = community_id - - # Comment: When the topic was created - # Mandatory: no - # Read-only: yes - # Type: timestamp - self.created_at = created_at - - # Comment: The description of the topic. By default an empty string - # Mandatory: no - # Read-only: no - # Type: string - self.description = description - - # Comment: The number of users following the topic - # Mandatory: no - # Read-only: yes - # Type: integer - self.follower_count = follower_count - - # Comment: The community url of the topic - # Mandatory: no - # Read-only: yes - # Type: string - self.html_url = html_url - - # Comment: Automatically assigned when the topic is created - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: The name of the topic - # Mandatory: yes - # Read-only: no - # Type: string - self.name = name - - # Comment: The position of the topic relative to other topics in the community - # Mandatory: no - # Read-only: no - # Type: integer - self.position = position - - # Comment: When the topic was last updated - # Mandatory: no - # Read-only: yes - # Type: timestamp - self.updated_at = updated_at - - # Comment: The API url of the topic - # Mandatory: no - # Read-only: yes - # Type: string - self.url = url - - # Comment: The id of the user segment to which this topic belongs - # Mandatory: no - # Read-only: no - # Type: integer - self.user_segment_id = user_segment_id - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - """ - | Comment: When the topic was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - """ - | Comment: When the topic was last updated - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - @property - def user_segment(self): - """ - | Comment: The id of the user segment to which this topic belongs - """ - if self.api and self.user_segment_id: - return self.api._get_user_segment(self.user_segment_id) - - @user_segment.setter - def user_segment(self, user_segment): - if user_segment: - self.user_segment_id = user_segment.id - self._user_segment = user_segment - - -class Translation(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - body=None, - created_at=None, - created_by_id=None, - draft=None, - hidden=None, - html_url=None, - id=None, - locale=None, - outdated=None, - source_id=None, - source_type=None, - title=None, - updated_at=None, - updated_by_id=None, - url=None, - **kwargs): - - self.api = api - - # Comment: The body of the translation. Empty by default - # Mandatory: no - # Read-only: no - # Type: string - self.body = body - - # Comment: The time at which the translation was created - # Mandatory: no - # Read-only: yes - # Type: timestamp - self.created_at = created_at - - # Comment: The id of the user who created the translation - # Mandatory: no - # Read-only: yes - # Type: integer - self.created_by_id = created_by_id - - # Comment: True if the translation is a draft; false otherwise. False by default - # Mandatory: no - # Read-only: no - # Type: boolean - self.draft = draft - self.hidden = hidden - - # Comment: The url of the translation in Help Center - # Mandatory: no - # Read-only: yes - # Type: string - self.html_url = html_url - - # Comment: Automatically assigned when a translation is created - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: The locale of the translation - # Mandatory: yes - # Read-only: no - # Type: string - self.locale = locale - - # Comment: True if the translation is outdated; false otherwise. False by default - # Mandatory: no - # Read-only: no - # Type: boolean - self.outdated = outdated - - # Comment: The id of the item that has this translation - # Mandatory: no - # Read-only: yes - # Type: integer - self.source_id = source_id - - # Comment: The type of the item that has this translation. Can be Article, Section, or Category - # Mandatory: no - # Read-only: yes - # Type: string - self.source_type = source_type - - # Comment: The title of the translation - # Mandatory: yes - # Read-only: no - # Type: string - self.title = title - - # Comment: The time at which the translation was last updated - # Mandatory: no - # Read-only: yes - # Type: timestamp - self.updated_at = updated_at - - # Comment: The id of the user who last updated the translation - # Mandatory: no - # Read-only: yes - # Type: integer - self.updated_by_id = updated_by_id - - # Comment: The API url of the translation - # Mandatory: no - # Read-only: yes - # Type: string - self.url = url - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - """ - | Comment: The time at which the translation was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def created_by(self): - """ - | Comment: The id of the user who created the translation - """ - if self.api and self.created_by_id: - return self.api._get_user(self.created_by_id) - - @created_by.setter - def created_by(self, created_by): - if created_by: - self.created_by_id = created_by.id - self._created_by = created_by - - @property - def updated(self): - """ - | Comment: The time at which the translation was last updated - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - @property - def updated_by(self): - """ - | Comment: The id of the user who last updated the translation - """ - if self.api and self.updated_by_id: - return self.api._get_user(self.updated_by_id) - - @updated_by.setter - def updated_by(self, updated_by): - if updated_by: - self.updated_by_id = updated_by.id - self._updated_by = updated_by - - -class UserSegment(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - built_in=None, - created_at=None, - group_ids=None, - id=None, - name=None, - organization_ids=None, - tags=None, - updated_at=None, - user_type=None, - **kwargs): - - self.api = api - - # Comment: Whether the user segment is built-in. Built-in user segments cannot be modified - # Mandatory: no - # Read-only: yes - # Type: boolean - self.built_in = built_in - - # Comment: When the user segment was created - # Mandatory: no - # Read-only: yes - # Type: timestamp - self.created_at = created_at - - # Comment: The ids of the groups that have access - # Mandatory: no - # Read-only: no - # Type: array - self.group_ids = group_ids - - # Comment: Automatically assigned when the user segment is created - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: User segment name (localized to the locale of the current user for built-in user segments) - # Mandatory: no - # Read-only: no - # Type: string - self.name = name - - # Comment: The ids of the organizations that have access - # Mandatory: no - # Read-only: no - # Type: array - self.organization_ids = organization_ids - - # Comment: The tags a user must have to have access - # Mandatory: no - # Read-only: no - # Type: array - self.tags = tags - - # Comment: When the user segment was last updated - # Mandatory: no - # Read-only: yes - # Type: timestamp - self.updated_at = updated_at - - # Comment: The set of users who can view content - # Mandatory: yes - # Read-only: no - # Type: string - self.user_type = user_type - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - """ - | Comment: When the user segment was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def groups(self): - """ - | Comment: The ids of the groups that have access - """ - if self.api and self.group_ids: - return self.api._get_groups(self.group_ids) - - @groups.setter - def groups(self, groups): - if groups: - self.group_ids = [o.id for o in groups] - self._groups = groups - - @property - def organizations(self): - """ - | Comment: The ids of the organizations that have access - """ - if self.api and self.organization_ids: - return self.api._get_organizations(self.organization_ids) - - @organizations.setter - def organizations(self, organizations): - if organizations: - self.organization_ids = [o.id for o in organizations] - self._organizations = organizations - - @property - def updated(self): - """ - | Comment: When the user segment was last updated - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class Vote(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - created_at=None, - id=None, - item_id=None, - item_type=None, - updated_at=None, - url=None, - user_id=None, - value=None, - **kwargs): - - self.api = api - - # Comment: The time at which the vote was created - # Mandatory: no - # Read-only: yes - # Type: timestamp - self.created_at = created_at - - # Comment: Automatically assigned when the vote is created - # Mandatory: no - # Read-only: yes - # Type: integer - self.id = id - - # Comment: The id of the item for which this vote was cast - # Mandatory: no - # Read-only: yes - # Type: integer - self.item_id = item_id - - # Comment: The type of the item. Can be "Article", "Post" or "PostComment" - # Mandatory: no - # Read-only: yes - # Type: string - self.item_type = item_type - - # Comment: The time at which the vote was last updated - # Mandatory: no - # Read-only: yes - # Type: timestamp - self.updated_at = updated_at - - # Comment: The API url of this vote - # Mandatory: no - # Read-only: yes - # Type: string - self.url = url - - # Comment: The id of the user who cast this vote - # Mandatory: no - # Read-only: yes - # Type: integer - self.user_id = user_id - - # Comment: The value of the vote - # Mandatory: yes - # Read-only: no - # Type: integer - self.value = value - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - """ - | Comment: The time at which the vote was created - """ - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def updated(self): - """ - | Comment: The time at which the vote was last updated - """ - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - @property - def user(self): - """ - | Comment: The id of the user who cast this vote - """ - if self.api and self.user_id: - return self.api._get_user(self.user_id) - - @user.setter - def user(self, user): - if user: - self.user_id = user.id - self._user = user +from zenpy.lib.api_objects import BaseObject +import dateutil.parser + + +class AccessPolicy(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + manageable_by=None, + required_tags=None, + restricted_to_group_ids=None, + restricted_to_organization_ids=None, + viewable_by=None, + **kwargs): + + self.api = api + self.manageable_by = manageable_by + self.required_tags = required_tags + self.restricted_to_group_ids = restricted_to_group_ids + self.restricted_to_organization_ids = restricted_to_organization_ids + self.viewable_by = viewable_by + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def restricted_to_groups(self): + + if self.api and self.restricted_to_group_ids: + return self.api._get_restricted_to_groups( + self.restricted_to_group_ids) + + @restricted_to_groups.setter + def restricted_to_groups(self, restricted_to_groups): + if restricted_to_groups: + self.restricted_to_group_ids = [o.id for o in restricted_to_groups] + self._restricted_to_groups = restricted_to_groups + + @property + def restricted_to_organizations(self): + + if self.api and self.restricted_to_organization_ids: + return self.api._get_restricted_to_organizations( + self.restricted_to_organization_ids) + + @restricted_to_organizations.setter + def restricted_to_organizations(self, restricted_to_organizations): + if restricted_to_organizations: + self.restricted_to_organization_ids = [ + o.id for o in restricted_to_organizations + ] + self._restricted_to_organizations = restricted_to_organizations + + +class Article(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + author_id=None, + body=None, + comments_disabled=None, + created_at=None, + draft=None, + html_url=None, + id=None, + label_names=None, + locale=None, + name=None, + outdated=None, + outdated_locales=None, + permission_group_id=None, + position=None, + promoted=None, + section_id=None, + source_locale=None, + title=None, + updated_at=None, + url=None, + user_segment_id=None, + vote_count=None, + vote_sum=None, + **kwargs): + + self.api = api + + # Comment: The id of the user who wrote the article (set to the user who made the request on create by default) + # Mandatory: no + # Read-only: no + # Type: integer + self.author_id = author_id + + # Comment: The body of the article + # Mandatory: no + # Read-only: no + # Type: string + self.body = body + + # Comment: True if comments are disabled; false otherwise + # Mandatory: no + # Read-only: no + # Type: boolean + self.comments_disabled = comments_disabled + + # Comment: The time the article was created + # Mandatory: no + # Read-only: yes + # Type: timestamp + self.created_at = created_at + + # Comment: True if the translation for the current locale is a draft; false otherwise. false by default. Can be set when creating but not when updating. For updating, see Translations + # Mandatory: no + # Read-only: yes + # Type: boolean + self.draft = draft + + # Comment: The url of the article in Help Center + # Mandatory: no + # Read-only: yes + # Type: string + self.html_url = html_url + + # Comment: Automatically assigned when the article is created + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: An array of label names associated with this article. By default no label names are used. Only available on certain plans + # Mandatory: no + # Read-only: no + # Type: string + self.label_names = label_names + + # Comment: The locale that the article is being displayed in + # Mandatory: yes + # Read-only: no + # Type: string + self.locale = locale + self.name = name + + # Comment: Deprecated. Always false because the source translation is always the most up-to-date translation + # Mandatory: no + # Read-only: yes + # Type: boolean + self.outdated = outdated + + # Comment: Locales in which the article was marked as outdated + # Mandatory: no + # Read-only: yes + # Type: array + self.outdated_locales = outdated_locales + + # Comment: The id of the permission group which defines who can edit and publish this article + # Mandatory: yes + # Read-only: no + # Type: integer + self.permission_group_id = permission_group_id + + # Comment: The position of this article in the article list. 0 by default + # Mandatory: no + # Read-only: no + # Type: integer + self.position = position + + # Comment: True if this article is promoted; false otherwise. false by default + # Mandatory: no + # Read-only: no + # Type: boolean + self.promoted = promoted + + # Comment: The id of the section to which this article belongs + # Mandatory: no + # Read-only: no + # Type: integer + self.section_id = section_id + + # Comment: The source (default) locale of the article + # Mandatory: no + # Read-only: yes + # Type: string + self.source_locale = source_locale + + # Comment: The title of the article + # Mandatory: yes + # Read-only: no + # Type: string + self.title = title + + # Comment: The time the article was last updated + # Mandatory: no + # Read-only: yes + # Type: timestamp + self.updated_at = updated_at + + # Comment: The API url of the article + # Mandatory: no + # Read-only: yes + # Type: string + self.url = url + + # Comment: The id of the user segment which defines who can see this article. Set to null to make it accessible to everyone + # Mandatory: yes + # Read-only: no + # Type: integer + self.user_segment_id = user_segment_id + + # Comment: The total number of upvotes and downvotes + # Mandatory: no + # Read-only: yes + # Type: integer + self.vote_count = vote_count + + # Comment: The sum of upvotes (+1) and downvotes (-1), which may be positive or negative + # Mandatory: no + # Read-only: yes + # Type: integer + self.vote_sum = vote_sum + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def author(self): + """ + | Comment: The id of the user who wrote the article (set to the user who made the request on create by default) + """ + if self.api and self.author_id: + return self.api._get_user(self.author_id) + + @author.setter + def author(self, author): + if author: + self.author_id = author.id + self._author = author + + @property + def created(self): + """ + | Comment: The time the article was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def permission_group(self): + """ + | Comment: The id of the permission group which defines who can edit and publish this article + """ + if self.api and self.permission_group_id: + return self.api._get_permission_group(self.permission_group_id) + + @permission_group.setter + def permission_group(self, permission_group): + if permission_group: + self.permission_group_id = permission_group.id + self._permission_group = permission_group + + @property + def section(self): + """ + | Comment: The id of the section to which this article belongs + """ + if self.api and self.section_id: + return self.api._get_section(self.section_id) + + @section.setter + def section(self, section): + if section: + self.section_id = section.id + self._section = section + + @property + def updated(self): + """ + | Comment: The time the article was last updated + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + @property + def user_segment(self): + """ + | Comment: The id of the user segment which defines who can see this article. Set to null to make it accessible to everyone + """ + if self.api and self.user_segment_id: + return self.api._get_user_segment(self.user_segment_id) + + @user_segment.setter + def user_segment(self, user_segment): + if user_segment: + self.user_segment_id = user_segment.id + self._user_segment = user_segment + + +class ArticleAttachment(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + article_id=None, + content_type=None, + content_url=None, + created_at=None, + display_file_name=None, + file_name=None, + id=None, + inline=None, + legacy=None, + relative_path=None, + size=None, + updated_at=None, + url=None, + **kwargs): + + self.api = api + + # Comment: Id of the associated article, if present + # Type: integer + self.article_id = article_id + + # Comment: The content type of the file. Example: image/png + # Type: string + self.content_type = content_type + + # Comment: A full URL where the attachment file can be downloaded + # Type: string + self.content_url = content_url + + # Comment: The time at which the article attachment was created + # Type: timestamp + self.created_at = created_at + self.display_file_name = display_file_name + + # Comment: The name of the file + # Type: string + self.file_name = file_name + + # Comment: Automatically assigned when the article attachment is created + # Type: integer + self.id = id + + # Comment: If true, the attached file is shown in the dedicated admin UI for inline attachments and its url can be referenced in the HTML body of the article. If false, the attachment is listed in the list of attachments. Default is false + # Type: boolean + self.inline = inline + self.legacy = legacy + self.relative_path = relative_path + + # Comment: The size of the attachment file in bytes + # Type: integer + self.size = size + + # Comment: The time at which the article attachment was last updated + # Type: timestamp + self.updated_at = updated_at + + # Comment: The API url of this article attachment + # Type: string + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def article(self): + """ + | Comment: Id of the associated article, if present + """ + if self.api and self.article_id: + return self.api._get_article(self.article_id) + + @article.setter + def article(self, article): + if article: + self.article_id = article.id + self._article = article + + @property + def created(self): + """ + | Comment: The time at which the article attachment was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + """ + | Comment: The time at which the article attachment was last updated + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class Category(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + created_at=None, + description=None, + html_url=None, + id=None, + locale=None, + name=None, + outdated=None, + position=None, + source_locale=None, + updated_at=None, + url=None, + **kwargs): + + self.api = api + self.created_at = created_at + self.description = description + self.html_url = html_url + self.id = id + self.locale = locale + self.name = name + self.outdated = outdated + self.position = position + self.source_locale = source_locale + self.updated_at = updated_at + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class Comment(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + author_id=None, + body=None, + created_at=None, + html_url=None, + id=None, + locale=None, + source_id=None, + source_type=None, + updated_at=None, + url=None, + vote_count=None, + vote_sum=None, + **kwargs): + + self.api = api + + # Comment: The id of the author of this comment. Writable on create by Help Center managers -- see Create Comment + # Mandatory: no + # Read-only: yes + # Type: integer + self.author_id = author_id + + # Comment: The comment made by the author + # Mandatory: yes + # Read-only: no + # Type: string + self.body = body + + # Comment: The time at which the comment was created. Writable on create by Help Center managers -- see Create Comment + # Mandatory: no + # Read-only: yes + # Type: timestamp + self.created_at = created_at + + # Comment: The url at which the comment is presented in Help Center + # Mandatory: no + # Read-only: yes + # Type: string + self.html_url = html_url + + # Comment: Automatically assigned when the comment is created + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: The locale in which this comment was made + # Mandatory: yes + # Read-only: no + # Type: string + self.locale = locale + + # Comment: The id of the item on which this comment was made + # Mandatory: no + # Read-only: yes + # Type: integer + self.source_id = source_id + + # Comment: The type of the item on which this comment was made. Currently only supports 'Article' + # Mandatory: no + # Read-only: yes + # Type: string + self.source_type = source_type + + # Comment: The time at which the comment was last updated + # Mandatory: no + # Read-only: yes + # Type: timestamp + self.updated_at = updated_at + + # Comment: The API url of this comment + # Mandatory: no + # Read-only: yes + # Type: string + self.url = url + + # Comment: The total number of upvotes and downvotes + # Mandatory: no + # Read-only: yes + # Type: integer + self.vote_count = vote_count + + # Comment: The sum of upvotes (+1) and downvotes (-1), which may be positive or negative + # Mandatory: no + # Read-only: yes + # Type: integer + self.vote_sum = vote_sum + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def author(self): + """ + | Comment: The id of the author of this comment. Writable on create by Help Center managers -- see Create Comment + """ + if self.api and self.author_id: + return self.api._get_user(self.author_id) + + @author.setter + def author(self, author): + if author: + self.author_id = author.id + self._author = author + + @property + def created(self): + """ + | Comment: The time at which the comment was created. Writable on create by Help Center managers -- see Create Comment + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + """ + | Comment: The time at which the comment was last updated + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class Label(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + created_at=None, + id=None, + name=None, + updated_at=None, + url=None, + **kwargs): + + self.api = api + + # Comment: The time at which the label was created + # Mandatory: no + # Read-only: yes + # Type: timestamp + self.created_at = created_at + + # Comment: Automatically assigned when the label is created + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: The actual name of the label + # Mandatory: yes + # Read-only: no + # Type: string + self.name = name + + # Comment: The time at which the label was last updated + # Mandatory: no + # Read-only: yes + # Type: timestamp + self.updated_at = updated_at + + # Comment: The API url of this label + # Mandatory: no + # Read-only: yes + # Type: string + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + """ + | Comment: The time at which the label was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + """ + | Comment: The time at which the label was last updated + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class ManagementPermissionGroup(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + built_in=None, + created_at=None, + edit=None, + id=None, + name=None, + publish=None, + updated_at=None, + **kwargs): + + self.api = api + self.built_in = built_in + self.created_at = created_at + self.edit = edit + self.id = id + self.name = name + self.publish = publish + self.updated_at = updated_at + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class Post(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + author_id=None, + closed=None, + comment_count=None, + created_at=None, + details=None, + featured=None, + follower_count=None, + html_url=None, + id=None, + pinned=None, + status=None, + title=None, + topic_id=None, + updated_at=None, + url=None, + vote_count=None, + vote_sum=None, + **kwargs): + + self.api = api + + # Comment: The id of the author of the post. Writable on create by Help Center managers -- see Create Post + # Mandatory: no + # Read-only: yes + # Type: integer + self.author_id = author_id + + # Comment: Whether further comments are allowed + # Mandatory: no + # Read-only: no + # Type: boolean + self.closed = closed + + # Comment: The number of comments on the post + # Mandatory: no + # Read-only: yes + # Type: integer + self.comment_count = comment_count + + # Comment: When the post was created. Writable on create by Help Center managers -- see Create Post + # Mandatory: no + # Read-only: yes + # Type: timestamp + self.created_at = created_at + + # Comment: The details of the post + # Mandatory: yes + # Read-only: no + # Type: string + self.details = details + + # Comment: Whether the post is featured + # Mandatory: no + # Read-only: no + # Type: boolean + self.featured = featured + + # Comment: The number of followers of the post + # Mandatory: no + # Read-only: yes + # Type: integer + self.follower_count = follower_count + + # Comment: The community url of the post + # Mandatory: no + # Read-only: yes + # Type: string + self.html_url = html_url + + # Comment: Automatically assigned when the post is created + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: When true, pins the post to the top of its topic + # Mandatory: no + # Read-only: no + # Type: boolean + self.pinned = pinned + + # Comment: The status of the post. Possible values: "planned", "not_planned" , "answered", or "completed" + # Mandatory: no + # Read-only: no + # Type: string + self.status = status + + # Comment: The title of the post + # Mandatory: yes + # Read-only: no + # Type: string + self.title = title + + # Comment: The id of the topic that the post belongs to + # Mandatory: yes + # Read-only: no + # Type: integer + self.topic_id = topic_id + + # Comment: When the post was last updated + # Mandatory: no + # Read-only: yes + # Type: timestamp + self.updated_at = updated_at + + # Comment: The API url of the post + # Mandatory: no + # Read-only: yes + # Type: string + self.url = url + + # Comment: The total number of upvotes and downvotes + # Mandatory: no + # Read-only: yes + # Type: integer + self.vote_count = vote_count + + # Comment: The sum of upvotes (+1) and downvotes (-1), which may be positive or negative + # Mandatory: no + # Read-only: yes + # Type: integer + self.vote_sum = vote_sum + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def author(self): + """ + | Comment: The id of the author of the post. Writable on create by Help Center managers -- see Create Post + """ + if self.api and self.author_id: + return self.api._get_user(self.author_id) + + @author.setter + def author(self, author): + if author: + self.author_id = author.id + self._author = author + + @property + def created(self): + """ + | Comment: When the post was created. Writable on create by Help Center managers -- see Create Post + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def topic(self): + """ + | Comment: The id of the topic that the post belongs to + """ + if self.api and self.topic_id: + return self.api._get_topic(self.topic_id) + + @topic.setter + def topic(self, topic): + if topic: + self.topic_id = topic.id + self._topic = topic + + @property + def updated(self): + """ + | Comment: When the post was last updated + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class Section(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + category_id=None, + created_at=None, + description=None, + html_url=None, + id=None, + locale=None, + manageable_by=None, + name=None, + outdated=None, + position=None, + sorting=None, + source_locale=None, + updated_at=None, + url=None, + user_segment_id=None, + **kwargs): + + self.api = api + + # Comment: The id of the category to which this section belongs + # Mandatory: no + # Read-only: no + # Type: integer + self.category_id = category_id + + # Comment: The time at which the section was created + # Mandatory: no + # Read-only: yes + # Type: timestamp + self.created_at = created_at + + # Comment: The description of the section + # Mandatory: no + # Read-only: no + # Type: string + self.description = description + + # Comment: The url of this section in HC + # Mandatory: no + # Read-only: yes + # Type: string + self.html_url = html_url + + # Comment: Automatically assigned when creating subscriptions + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: The locale in which the section is displayed + # Mandatory: yes + # Read-only: no + # Type: string + self.locale = locale + + # Comment: The set of users who can manage this section + # Mandatory: no + # Read-only: no + # Type: string + self.manageable_by = manageable_by + + # Comment: The name of the section + # Mandatory: yes + # Read-only: no + # Type: string + self.name = name + + # Comment: Whether the section is out of date + # Mandatory: no + # Read-only: yes + # Type: boolean + self.outdated = outdated + + # Comment: The position of this section in the section list. By default the section is added to the end of the list + # Mandatory: no + # Read-only: no + # Type: integer + self.position = position + self.sorting = sorting + + # Comment: The source (default) locale of the section + # Mandatory: no + # Read-only: yes + # Type: string + self.source_locale = source_locale + + # Comment: The time at which the section was last updated + # Mandatory: no + # Read-only: yes + # Type: timestamp + self.updated_at = updated_at + + # Comment: The API url of this section + # Mandatory: no + # Read-only: yes + # Type: string + self.url = url + + # Comment: The id of the user segment to which this section belongs + # Mandatory: no + # Read-only: no + # Type: integer + self.user_segment_id = user_segment_id + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def category(self): + """ + | Comment: The id of the category to which this section belongs + """ + if self.api and self.category_id: + return self.api._get_category(self.category_id) + + @category.setter + def category(self, category): + if category: + self.category_id = category.id + self._category = category + + @property + def created(self): + """ + | Comment: The time at which the section was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + """ + | Comment: The time at which the section was last updated + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + @property + def user_segment(self): + """ + | Comment: The id of the user segment to which this section belongs + """ + if self.api and self.user_segment_id: + return self.api._get_user_segment(self.user_segment_id) + + @user_segment.setter + def user_segment(self, user_segment): + if user_segment: + self.user_segment_id = user_segment.id + self._user_segment = user_segment + + +class Subscription(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + content_id=None, + created_at=None, + id=None, + locale=None, + updated_at=None, + url=None, + user_id=None, + **kwargs): + + self.api = api + + # Comment: The id of the subscribed item + # Mandatory: no + # Read-only: yes + # Type: integer + self.content_id = content_id + + # Comment: The time at which the subscription was created + # Mandatory: no + # Read-only: yes + # Type: timestamp + self.created_at = created_at + + # Comment: Automatically assigned when the subscription is created + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: The locale of the subscribed item + # Mandatory: yes + # Read-only: yes + # Type: string + self.locale = locale + + # Comment: The time at which the subscription was last updated + # Mandatory: no + # Read-only: yes + # Type: timestamp + self.updated_at = updated_at + + # Comment: The API url of the subscription + # Mandatory: no + # Read-only: yes + # Type: string + self.url = url + + # Comment: The id of the user who has this subscription + # Mandatory: no + # Read-only: yes + # Type: integer + self.user_id = user_id + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + """ + | Comment: The time at which the subscription was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + """ + | Comment: The time at which the subscription was last updated + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + @property + def user(self): + """ + | Comment: The id of the user who has this subscription + """ + if self.api and self.user_id: + return self.api._get_user(self.user_id) + + @user.setter + def user(self, user): + if user: + self.user_id = user.id + self._user = user + + +class Topic(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + community_id=None, + created_at=None, + description=None, + follower_count=None, + html_url=None, + id=None, + name=None, + position=None, + updated_at=None, + url=None, + user_segment_id=None, + **kwargs): + + self.api = api + self.community_id = community_id + + # Comment: When the topic was created + # Mandatory: no + # Read-only: yes + # Type: timestamp + self.created_at = created_at + + # Comment: The description of the topic. By default an empty string + # Mandatory: no + # Read-only: no + # Type: string + self.description = description + + # Comment: The number of users following the topic + # Mandatory: no + # Read-only: yes + # Type: integer + self.follower_count = follower_count + + # Comment: The community url of the topic + # Mandatory: no + # Read-only: yes + # Type: string + self.html_url = html_url + + # Comment: Automatically assigned when the topic is created + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: The name of the topic + # Mandatory: yes + # Read-only: no + # Type: string + self.name = name + + # Comment: The position of the topic relative to other topics in the community + # Mandatory: no + # Read-only: no + # Type: integer + self.position = position + + # Comment: When the topic was last updated + # Mandatory: no + # Read-only: yes + # Type: timestamp + self.updated_at = updated_at + + # Comment: The API url of the topic + # Mandatory: no + # Read-only: yes + # Type: string + self.url = url + + # Comment: The id of the user segment to which this topic belongs + # Mandatory: no + # Read-only: no + # Type: integer + self.user_segment_id = user_segment_id + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + """ + | Comment: When the topic was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + """ + | Comment: When the topic was last updated + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + @property + def user_segment(self): + """ + | Comment: The id of the user segment to which this topic belongs + """ + if self.api and self.user_segment_id: + return self.api._get_user_segment(self.user_segment_id) + + @user_segment.setter + def user_segment(self, user_segment): + if user_segment: + self.user_segment_id = user_segment.id + self._user_segment = user_segment + + +class Translation(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + body=None, + created_at=None, + created_by_id=None, + draft=None, + hidden=None, + html_url=None, + id=None, + locale=None, + outdated=None, + source_id=None, + source_type=None, + title=None, + updated_at=None, + updated_by_id=None, + url=None, + **kwargs): + + self.api = api + + # Comment: The body of the translation. Empty by default + # Mandatory: no + # Read-only: no + # Type: string + self.body = body + + # Comment: The time at which the translation was created + # Mandatory: no + # Read-only: yes + # Type: timestamp + self.created_at = created_at + + # Comment: The id of the user who created the translation + # Mandatory: no + # Read-only: yes + # Type: integer + self.created_by_id = created_by_id + + # Comment: True if the translation is a draft; false otherwise. False by default + # Mandatory: no + # Read-only: no + # Type: boolean + self.draft = draft + self.hidden = hidden + + # Comment: The url of the translation in Help Center + # Mandatory: no + # Read-only: yes + # Type: string + self.html_url = html_url + + # Comment: Automatically assigned when a translation is created + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: The locale of the translation + # Mandatory: yes + # Read-only: no + # Type: string + self.locale = locale + + # Comment: True if the translation is outdated; false otherwise. False by default + # Mandatory: no + # Read-only: no + # Type: boolean + self.outdated = outdated + + # Comment: The id of the item that has this translation + # Mandatory: no + # Read-only: yes + # Type: integer + self.source_id = source_id + + # Comment: The type of the item that has this translation. Can be Article, Section, or Category + # Mandatory: no + # Read-only: yes + # Type: string + self.source_type = source_type + + # Comment: The title of the translation + # Mandatory: yes + # Read-only: no + # Type: string + self.title = title + + # Comment: The time at which the translation was last updated + # Mandatory: no + # Read-only: yes + # Type: timestamp + self.updated_at = updated_at + + # Comment: The id of the user who last updated the translation + # Mandatory: no + # Read-only: yes + # Type: integer + self.updated_by_id = updated_by_id + + # Comment: The API url of the translation + # Mandatory: no + # Read-only: yes + # Type: string + self.url = url + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + """ + | Comment: The time at which the translation was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def created_by(self): + """ + | Comment: The id of the user who created the translation + """ + if self.api and self.created_by_id: + return self.api._get_user(self.created_by_id) + + @created_by.setter + def created_by(self, created_by): + if created_by: + self.created_by_id = created_by.id + self._created_by = created_by + + @property + def updated(self): + """ + | Comment: The time at which the translation was last updated + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + @property + def updated_by(self): + """ + | Comment: The id of the user who last updated the translation + """ + if self.api and self.updated_by_id: + return self.api._get_user(self.updated_by_id) + + @updated_by.setter + def updated_by(self, updated_by): + if updated_by: + self.updated_by_id = updated_by.id + self._updated_by = updated_by + + +class UserSegment(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + built_in=None, + created_at=None, + group_ids=None, + id=None, + name=None, + organization_ids=None, + tags=None, + updated_at=None, + user_type=None, + **kwargs): + + self.api = api + + # Comment: Whether the user segment is built-in. Built-in user segments cannot be modified + # Mandatory: no + # Read-only: yes + # Type: boolean + self.built_in = built_in + + # Comment: When the user segment was created + # Mandatory: no + # Read-only: yes + # Type: timestamp + self.created_at = created_at + + # Comment: The ids of the groups that have access + # Mandatory: no + # Read-only: no + # Type: array + self.group_ids = group_ids + + # Comment: Automatically assigned when the user segment is created + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: User segment name (localized to the locale of the current user for built-in user segments) + # Mandatory: no + # Read-only: no + # Type: string + self.name = name + + # Comment: The ids of the organizations that have access + # Mandatory: no + # Read-only: no + # Type: array + self.organization_ids = organization_ids + + # Comment: The tags a user must have to have access + # Mandatory: no + # Read-only: no + # Type: array + self.tags = tags + + # Comment: When the user segment was last updated + # Mandatory: no + # Read-only: yes + # Type: timestamp + self.updated_at = updated_at + + # Comment: The set of users who can view content + # Mandatory: yes + # Read-only: no + # Type: string + self.user_type = user_type + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + """ + | Comment: When the user segment was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def groups(self): + """ + | Comment: The ids of the groups that have access + """ + if self.api and self.group_ids: + return self.api._get_groups(self.group_ids) + + @groups.setter + def groups(self, groups): + if groups: + self.group_ids = [o.id for o in groups] + self._groups = groups + + @property + def organizations(self): + """ + | Comment: The ids of the organizations that have access + """ + if self.api and self.organization_ids: + return self.api._get_organizations(self.organization_ids) + + @organizations.setter + def organizations(self, organizations): + if organizations: + self.organization_ids = [o.id for o in organizations] + self._organizations = organizations + + @property + def updated(self): + """ + | Comment: When the user segment was last updated + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class Vote(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + created_at=None, + id=None, + item_id=None, + item_type=None, + updated_at=None, + url=None, + user_id=None, + value=None, + **kwargs): + + self.api = api + + # Comment: The time at which the vote was created + # Mandatory: no + # Read-only: yes + # Type: timestamp + self.created_at = created_at + + # Comment: Automatically assigned when the vote is created + # Mandatory: no + # Read-only: yes + # Type: integer + self.id = id + + # Comment: The id of the item for which this vote was cast + # Mandatory: no + # Read-only: yes + # Type: integer + self.item_id = item_id + + # Comment: The type of the item. Can be "Article", "Post" or "PostComment" + # Mandatory: no + # Read-only: yes + # Type: string + self.item_type = item_type + + # Comment: The time at which the vote was last updated + # Mandatory: no + # Read-only: yes + # Type: timestamp + self.updated_at = updated_at + + # Comment: The API url of this vote + # Mandatory: no + # Read-only: yes + # Type: string + self.url = url + + # Comment: The id of the user who cast this vote + # Mandatory: no + # Read-only: yes + # Type: integer + self.user_id = user_id + + # Comment: The value of the vote + # Mandatory: yes + # Read-only: no + # Type: integer + self.value = value + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + """ + | Comment: The time at which the vote was created + """ + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def updated(self): + """ + | Comment: The time at which the vote was last updated + """ + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + @property + def user(self): + """ + | Comment: The id of the user who cast this vote + """ + if self.api and self.user_id: + return self.api._get_user(self.user_id) + + @user.setter + def user(self, user): + if user: + self.user_id = user.id + self._user = user diff --git a/zenpy/lib/api_objects/talk_objects.py b/zenpy/lib/api_objects/talk_objects.py index 36910535..543bbed3 100644 --- a/zenpy/lib/api_objects/talk_objects.py +++ b/zenpy/lib/api_objects/talk_objects.py @@ -1,605 +1,605 @@ -from zenpy.lib.api_objects import BaseObject -import dateutil.parser - - -class AccountOverview(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - average_call_duration=None, - average_callback_wait_time=None, - average_hold_time=None, - average_queue_wait_time=None, - average_time_to_answer=None, - average_wrap_up_time=None, - max_calls_waiting=None, - max_queue_wait_time=None, - total_call_duration=None, - total_callback_calls=None, - total_calls=None, - total_calls_abandoned_in_queue=None, - total_calls_outside_business_hours=None, - total_calls_with_exceeded_queue_wait_time=None, - total_calls_with_requested_voicemail=None, - total_embeddable_callback_calls=None, - total_hold_time=None, - total_inbound_calls=None, - total_outbound_calls=None, - total_textback_requests=None, - total_voicemails=None, - total_wrap_up_time=None, - **kwargs): - - self.api = api - self.average_call_duration = average_call_duration - self.average_callback_wait_time = average_callback_wait_time - self.average_hold_time = average_hold_time - self.average_queue_wait_time = average_queue_wait_time - self.average_time_to_answer = average_time_to_answer - self.average_wrap_up_time = average_wrap_up_time - self.max_calls_waiting = max_calls_waiting - self.max_queue_wait_time = max_queue_wait_time - self.total_call_duration = total_call_duration - self.total_callback_calls = total_callback_calls - self.total_calls = total_calls - self.total_calls_abandoned_in_queue = total_calls_abandoned_in_queue - self.total_calls_outside_business_hours = total_calls_outside_business_hours - self.total_calls_with_exceeded_queue_wait_time = total_calls_with_exceeded_queue_wait_time - self.total_calls_with_requested_voicemail = total_calls_with_requested_voicemail - self.total_embeddable_callback_calls = total_embeddable_callback_calls - self.total_hold_time = total_hold_time - self.total_inbound_calls = total_inbound_calls - self.total_outbound_calls = total_outbound_calls - self.total_textback_requests = total_textback_requests - self.total_voicemails = total_voicemails - self.total_wrap_up_time = total_wrap_up_time - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class AgentsActivity(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - accepted_transfers=None, - agent_id=None, - available_time=None, - avatar_url=None, - average_hold_time=None, - average_talk_time=None, - average_wrap_up_time=None, - calls_accepted=None, - calls_denied=None, - calls_missed=None, - calls_put_on_hold=None, - forwarding_number=None, - name=None, - online_time=None, - started_transfers=None, - status=None, - status_code=None, - total_call_duration=None, - total_hold_time=None, - total_talk_time=None, - total_wrap_up_time=None, - via=None, - **kwargs): - - self.api = api - self.accepted_transfers = accepted_transfers - self.agent_id = agent_id - self.available_time = available_time - self.avatar_url = avatar_url - self.average_hold_time = average_hold_time - self.average_talk_time = average_talk_time - self.average_wrap_up_time = average_wrap_up_time - self.calls_accepted = calls_accepted - self.calls_denied = calls_denied - self.calls_missed = calls_missed - self.calls_put_on_hold = calls_put_on_hold - self.forwarding_number = forwarding_number - self.name = name - self.online_time = online_time - self.started_transfers = started_transfers - self.status = status - self.status_code = status_code - self.total_call_duration = total_call_duration - self.total_hold_time = total_hold_time - self.total_talk_time = total_talk_time - self.total_wrap_up_time = total_wrap_up_time - self.via = via - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def agent(self): - - if self.api and self.agent_id: - return self.api._get_agent(self.agent_id) - - @agent.setter - def agent(self, agent): - if agent: - self.agent_id = agent.id - self._agent = agent - - -class AgentsOverview(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - average_accepted_transfers=None, - average_available_time=None, - average_calls_accepted=None, - average_calls_denied=None, - average_calls_missed=None, - average_calls_put_on_hold=None, - average_hold_time=None, - average_online_time=None, - average_started_transfers=None, - average_talk_time=None, - average_wrap_up_time=None, - total_accepted_transfers=None, - total_calls_accepted=None, - total_calls_denied=None, - total_calls_missed=None, - total_calls_put_on_hold=None, - total_hold_time=None, - total_started_transfers=None, - total_talk_time=None, - total_wrap_up_time=None, - **kwargs): - - self.api = api - self.average_accepted_transfers = average_accepted_transfers - self.average_available_time = average_available_time - self.average_calls_accepted = average_calls_accepted - self.average_calls_denied = average_calls_denied - self.average_calls_missed = average_calls_missed - self.average_calls_put_on_hold = average_calls_put_on_hold - self.average_hold_time = average_hold_time - self.average_online_time = average_online_time - self.average_started_transfers = average_started_transfers - self.average_talk_time = average_talk_time - self.average_wrap_up_time = average_wrap_up_time - self.total_accepted_transfers = total_accepted_transfers - self.total_calls_accepted = total_calls_accepted - self.total_calls_denied = total_calls_denied - self.total_calls_missed = total_calls_missed - self.total_calls_put_on_hold = total_calls_put_on_hold - self.total_hold_time = total_hold_time - self.total_started_transfers = total_started_transfers - self.total_talk_time = total_talk_time - self.total_wrap_up_time = total_wrap_up_time - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class Call(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - agent_id=None, - call_charge=None, - call_group_id=None, - call_recording_consent=None, - call_recording_consent_action=None, - call_recording_consent_keypress=None, - callback=None, - callback_source=None, - completion_status=None, - consultation_time=None, - created_at=None, - customer_id=None, - customer_requested_voicemail=None, - default_group=None, - direction=None, - duration=None, - exceeded_queue_wait_time=None, - hold_time=None, - id=None, - ivr_action=None, - ivr_destination_group_name=None, - ivr_hops=None, - ivr_routed_to=None, - ivr_time_spent=None, - minutes_billed=None, - not_recording_time=None, - outside_business_hours=None, - overflowed=None, - overflowed_to=None, - phone_number=None, - phone_number_id=None, - quality_issues=None, - recording_control_interactions=None, - recording_time=None, - talk_time=None, - ticket_id=None, - time_to_answer=None, - updated_at=None, - voicemail=None, - wait_time=None, - wrap_up_time=None, - **kwargs): - - self.api = api - self.agent_id = agent_id - self.call_charge = call_charge - self.call_group_id = call_group_id - self.call_recording_consent = call_recording_consent - self.call_recording_consent_action = call_recording_consent_action - self.call_recording_consent_keypress = call_recording_consent_keypress - self.callback = callback - self.callback_source = callback_source - self.completion_status = completion_status - self.consultation_time = consultation_time - self.created_at = created_at - self.customer_id = customer_id - self.customer_requested_voicemail = customer_requested_voicemail - self.default_group = default_group - self.direction = direction - self.duration = duration - self.exceeded_queue_wait_time = exceeded_queue_wait_time - self.hold_time = hold_time - self.id = id - self.ivr_action = ivr_action - self.ivr_destination_group_name = ivr_destination_group_name - self.ivr_hops = ivr_hops - self.ivr_routed_to = ivr_routed_to - self.ivr_time_spent = ivr_time_spent - self.minutes_billed = minutes_billed - self.not_recording_time = not_recording_time - self.outside_business_hours = outside_business_hours - self.overflowed = overflowed - self.overflowed_to = overflowed_to - self.phone_number = phone_number - self.phone_number_id = phone_number_id - self.quality_issues = quality_issues - self.recording_control_interactions = recording_control_interactions - self.recording_time = recording_time - self.talk_time = talk_time - self.ticket_id = ticket_id - self.time_to_answer = time_to_answer - self.updated_at = updated_at - self.voicemail = voicemail - self.wait_time = wait_time - self.wrap_up_time = wrap_up_time - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def agent(self): - - if self.api and self.agent_id: - return self.api._get_agent(self.agent_id) - - @agent.setter - def agent(self, agent): - if agent: - self.agent_id = agent.id - self._agent = agent - - @property - def call_group(self): - - if self.api and self.call_group_id: - return self.api._get_call_group(self.call_group_id) - - @call_group.setter - def call_group(self, call_group): - if call_group: - self.call_group_id = call_group.id - self._call_group = call_group - - @property - def created(self): - - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def customer(self): - - if self.api and self.customer_id: - return self.api._get_customer(self.customer_id) - - @customer.setter - def customer(self, customer): - if customer: - self.customer_id = customer.id - self._customer = customer - - @property - def phone_number(self): - - if self.api and self.phone_number_id: - return self.api._get_phone_number(self.phone_number_id) - - @phone_number.setter - def phone_number(self, phone_number): - if phone_number: - self._phone_number = phone_number - - @property - def ticket(self): - - if self.api and self.ticket_id: - return self.api._get_ticket(self.ticket_id) - - @ticket.setter - def ticket(self, ticket): - if ticket: - self.ticket_id = ticket.id - self._ticket = ticket - - @property - def updated(self): - - if self.updated_at: - return dateutil.parser.parse(self.updated_at) - - @updated.setter - def updated(self, updated): - if updated: - self.updated_at = updated - - -class CurrentQueueActivity(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - agents_online=None, - average_wait_time=None, - callbacks_waiting=None, - calls_waiting=None, - embeddable_callbacks_waiting=None, - longest_wait_time=None, - **kwargs): - - self.api = api - self.agents_online = agents_online - self.average_wait_time = average_wait_time - self.callbacks_waiting = callbacks_waiting - self.calls_waiting = calls_waiting - self.embeddable_callbacks_waiting = embeddable_callbacks_waiting - self.longest_wait_time = longest_wait_time - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - -class PhoneNumbers(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - capabilities=None, - country_code=None, - created_at=None, - default_greeting_ids=None, - default_group_id=None, - display_number=None, - greeting_ids=None, - group_ids=None, - id=None, - location=None, - name=None, - nickname=None, - number=None, - recorded=None, - sms_group_id=None, - toll_free=None, - transcription=None, - **kwargs): - - self.api = api - self.capabilities = capabilities - self.country_code = country_code - self.created_at = created_at - self.default_greeting_ids = default_greeting_ids - self.default_group_id = default_group_id - self.display_number = display_number - self.greeting_ids = greeting_ids - self.group_ids = group_ids - self.id = id - self.location = location - self.name = name - self.nickname = nickname - self.number = number - self.recorded = recorded - self.sms_group_id = sms_group_id - self.toll_free = toll_free - self.transcription = transcription - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def created(self): - - if self.created_at: - return dateutil.parser.parse(self.created_at) - - @created.setter - def created(self, created): - if created: - self.created_at = created - - @property - def default_greetings(self): - - if self.api and self.default_greeting_ids: - return self.api._get_default_greetings(self.default_greeting_ids) - - @default_greetings.setter - def default_greetings(self, default_greetings): - if default_greetings: - self.default_greeting_ids = [o.id for o in default_greetings] - self._default_greetings = default_greetings - - @property - def default_group(self): - - if self.api and self.default_group_id: - return self.api._get_default_group(self.default_group_id) - - @default_group.setter - def default_group(self, default_group): - if default_group: - self.default_group_id = default_group.id - self._default_group = default_group - - @property - def greetings(self): - - if self.api and self.greeting_ids: - return self.api._get_greetings(self.greeting_ids) - - @greetings.setter - def greetings(self, greetings): - if greetings: - self.greeting_ids = [o.id for o in greetings] - self._greetings = greetings - - @property - def groups(self): - - if self.api and self.group_ids: - return self.api._get_groups(self.group_ids) - - @groups.setter - def groups(self, groups): - if groups: - self.group_ids = [o.id for o in groups] - self._groups = groups - - @property - def sms_group(self): - - if self.api and self.sms_group_id: - return self.api._get_sms_group(self.sms_group_id) - - @sms_group.setter - def sms_group(self, sms_group): - if sms_group: - self.sms_group_id = sms_group.id - self._sms_group = sms_group - - -class ShowAvailability(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - def __init__(self, - api=None, - available=None, - behaviour=None, - state_id=None, - status=None, - via=None, - **kwargs): - - self.api = api - self.available = available - self.behaviour = behaviour - self.state_id = state_id - self.status = status - self.via = via - - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - - @property - def state(self): - - if self.api and self.state_id: - return self.api._get_state(self.state_id) - - @state.setter - def state(self, state): - if state: - self.state_id = state.id - self._state = state +from zenpy.lib.api_objects import BaseObject +import dateutil.parser + + +class AccountOverview(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + average_call_duration=None, + average_callback_wait_time=None, + average_hold_time=None, + average_queue_wait_time=None, + average_time_to_answer=None, + average_wrap_up_time=None, + max_calls_waiting=None, + max_queue_wait_time=None, + total_call_duration=None, + total_callback_calls=None, + total_calls=None, + total_calls_abandoned_in_queue=None, + total_calls_outside_business_hours=None, + total_calls_with_exceeded_queue_wait_time=None, + total_calls_with_requested_voicemail=None, + total_embeddable_callback_calls=None, + total_hold_time=None, + total_inbound_calls=None, + total_outbound_calls=None, + total_textback_requests=None, + total_voicemails=None, + total_wrap_up_time=None, + **kwargs): + + self.api = api + self.average_call_duration = average_call_duration + self.average_callback_wait_time = average_callback_wait_time + self.average_hold_time = average_hold_time + self.average_queue_wait_time = average_queue_wait_time + self.average_time_to_answer = average_time_to_answer + self.average_wrap_up_time = average_wrap_up_time + self.max_calls_waiting = max_calls_waiting + self.max_queue_wait_time = max_queue_wait_time + self.total_call_duration = total_call_duration + self.total_callback_calls = total_callback_calls + self.total_calls = total_calls + self.total_calls_abandoned_in_queue = total_calls_abandoned_in_queue + self.total_calls_outside_business_hours = total_calls_outside_business_hours + self.total_calls_with_exceeded_queue_wait_time = total_calls_with_exceeded_queue_wait_time + self.total_calls_with_requested_voicemail = total_calls_with_requested_voicemail + self.total_embeddable_callback_calls = total_embeddable_callback_calls + self.total_hold_time = total_hold_time + self.total_inbound_calls = total_inbound_calls + self.total_outbound_calls = total_outbound_calls + self.total_textback_requests = total_textback_requests + self.total_voicemails = total_voicemails + self.total_wrap_up_time = total_wrap_up_time + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class AgentsActivity(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + accepted_transfers=None, + agent_id=None, + available_time=None, + avatar_url=None, + average_hold_time=None, + average_talk_time=None, + average_wrap_up_time=None, + calls_accepted=None, + calls_denied=None, + calls_missed=None, + calls_put_on_hold=None, + forwarding_number=None, + name=None, + online_time=None, + started_transfers=None, + status=None, + status_code=None, + total_call_duration=None, + total_hold_time=None, + total_talk_time=None, + total_wrap_up_time=None, + via=None, + **kwargs): + + self.api = api + self.accepted_transfers = accepted_transfers + self.agent_id = agent_id + self.available_time = available_time + self.avatar_url = avatar_url + self.average_hold_time = average_hold_time + self.average_talk_time = average_talk_time + self.average_wrap_up_time = average_wrap_up_time + self.calls_accepted = calls_accepted + self.calls_denied = calls_denied + self.calls_missed = calls_missed + self.calls_put_on_hold = calls_put_on_hold + self.forwarding_number = forwarding_number + self.name = name + self.online_time = online_time + self.started_transfers = started_transfers + self.status = status + self.status_code = status_code + self.total_call_duration = total_call_duration + self.total_hold_time = total_hold_time + self.total_talk_time = total_talk_time + self.total_wrap_up_time = total_wrap_up_time + self.via = via + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def agent(self): + + if self.api and self.agent_id: + return self.api._get_agent(self.agent_id) + + @agent.setter + def agent(self, agent): + if agent: + self.agent_id = agent.id + self._agent = agent + + +class AgentsOverview(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + average_accepted_transfers=None, + average_available_time=None, + average_calls_accepted=None, + average_calls_denied=None, + average_calls_missed=None, + average_calls_put_on_hold=None, + average_hold_time=None, + average_online_time=None, + average_started_transfers=None, + average_talk_time=None, + average_wrap_up_time=None, + total_accepted_transfers=None, + total_calls_accepted=None, + total_calls_denied=None, + total_calls_missed=None, + total_calls_put_on_hold=None, + total_hold_time=None, + total_started_transfers=None, + total_talk_time=None, + total_wrap_up_time=None, + **kwargs): + + self.api = api + self.average_accepted_transfers = average_accepted_transfers + self.average_available_time = average_available_time + self.average_calls_accepted = average_calls_accepted + self.average_calls_denied = average_calls_denied + self.average_calls_missed = average_calls_missed + self.average_calls_put_on_hold = average_calls_put_on_hold + self.average_hold_time = average_hold_time + self.average_online_time = average_online_time + self.average_started_transfers = average_started_transfers + self.average_talk_time = average_talk_time + self.average_wrap_up_time = average_wrap_up_time + self.total_accepted_transfers = total_accepted_transfers + self.total_calls_accepted = total_calls_accepted + self.total_calls_denied = total_calls_denied + self.total_calls_missed = total_calls_missed + self.total_calls_put_on_hold = total_calls_put_on_hold + self.total_hold_time = total_hold_time + self.total_started_transfers = total_started_transfers + self.total_talk_time = total_talk_time + self.total_wrap_up_time = total_wrap_up_time + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class Call(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + agent_id=None, + call_charge=None, + call_group_id=None, + call_recording_consent=None, + call_recording_consent_action=None, + call_recording_consent_keypress=None, + callback=None, + callback_source=None, + completion_status=None, + consultation_time=None, + created_at=None, + customer_id=None, + customer_requested_voicemail=None, + default_group=None, + direction=None, + duration=None, + exceeded_queue_wait_time=None, + hold_time=None, + id=None, + ivr_action=None, + ivr_destination_group_name=None, + ivr_hops=None, + ivr_routed_to=None, + ivr_time_spent=None, + minutes_billed=None, + not_recording_time=None, + outside_business_hours=None, + overflowed=None, + overflowed_to=None, + phone_number=None, + phone_number_id=None, + quality_issues=None, + recording_control_interactions=None, + recording_time=None, + talk_time=None, + ticket_id=None, + time_to_answer=None, + updated_at=None, + voicemail=None, + wait_time=None, + wrap_up_time=None, + **kwargs): + + self.api = api + self.agent_id = agent_id + self.call_charge = call_charge + self.call_group_id = call_group_id + self.call_recording_consent = call_recording_consent + self.call_recording_consent_action = call_recording_consent_action + self.call_recording_consent_keypress = call_recording_consent_keypress + self.callback = callback + self.callback_source = callback_source + self.completion_status = completion_status + self.consultation_time = consultation_time + self.created_at = created_at + self.customer_id = customer_id + self.customer_requested_voicemail = customer_requested_voicemail + self.default_group = default_group + self.direction = direction + self.duration = duration + self.exceeded_queue_wait_time = exceeded_queue_wait_time + self.hold_time = hold_time + self.id = id + self.ivr_action = ivr_action + self.ivr_destination_group_name = ivr_destination_group_name + self.ivr_hops = ivr_hops + self.ivr_routed_to = ivr_routed_to + self.ivr_time_spent = ivr_time_spent + self.minutes_billed = minutes_billed + self.not_recording_time = not_recording_time + self.outside_business_hours = outside_business_hours + self.overflowed = overflowed + self.overflowed_to = overflowed_to + self.phone_number = phone_number + self.phone_number_id = phone_number_id + self.quality_issues = quality_issues + self.recording_control_interactions = recording_control_interactions + self.recording_time = recording_time + self.talk_time = talk_time + self.ticket_id = ticket_id + self.time_to_answer = time_to_answer + self.updated_at = updated_at + self.voicemail = voicemail + self.wait_time = wait_time + self.wrap_up_time = wrap_up_time + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def agent(self): + + if self.api and self.agent_id: + return self.api._get_agent(self.agent_id) + + @agent.setter + def agent(self, agent): + if agent: + self.agent_id = agent.id + self._agent = agent + + @property + def call_group(self): + + if self.api and self.call_group_id: + return self.api._get_call_group(self.call_group_id) + + @call_group.setter + def call_group(self, call_group): + if call_group: + self.call_group_id = call_group.id + self._call_group = call_group + + @property + def created(self): + + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def customer(self): + + if self.api and self.customer_id: + return self.api._get_customer(self.customer_id) + + @customer.setter + def customer(self, customer): + if customer: + self.customer_id = customer.id + self._customer = customer + + @property + def phone_number(self): + + if self.api and self.phone_number_id: + return self.api._get_phone_number(self.phone_number_id) + + @phone_number.setter + def phone_number(self, phone_number): + if phone_number: + self._phone_number = phone_number + + @property + def ticket(self): + + if self.api and self.ticket_id: + return self.api._get_ticket(self.ticket_id) + + @ticket.setter + def ticket(self, ticket): + if ticket: + self.ticket_id = ticket.id + self._ticket = ticket + + @property + def updated(self): + + if self.updated_at: + return dateutil.parser.parse(self.updated_at) + + @updated.setter + def updated(self, updated): + if updated: + self.updated_at = updated + + +class CurrentQueueActivity(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + agents_online=None, + average_wait_time=None, + callbacks_waiting=None, + calls_waiting=None, + embeddable_callbacks_waiting=None, + longest_wait_time=None, + **kwargs): + + self.api = api + self.agents_online = agents_online + self.average_wait_time = average_wait_time + self.callbacks_waiting = callbacks_waiting + self.calls_waiting = calls_waiting + self.embeddable_callbacks_waiting = embeddable_callbacks_waiting + self.longest_wait_time = longest_wait_time + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + +class PhoneNumbers(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + capabilities=None, + country_code=None, + created_at=None, + default_greeting_ids=None, + default_group_id=None, + display_number=None, + greeting_ids=None, + group_ids=None, + id=None, + location=None, + name=None, + nickname=None, + number=None, + recorded=None, + sms_group_id=None, + toll_free=None, + transcription=None, + **kwargs): + + self.api = api + self.capabilities = capabilities + self.country_code = country_code + self.created_at = created_at + self.default_greeting_ids = default_greeting_ids + self.default_group_id = default_group_id + self.display_number = display_number + self.greeting_ids = greeting_ids + self.group_ids = group_ids + self.id = id + self.location = location + self.name = name + self.nickname = nickname + self.number = number + self.recorded = recorded + self.sms_group_id = sms_group_id + self.toll_free = toll_free + self.transcription = transcription + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def created(self): + + if self.created_at: + return dateutil.parser.parse(self.created_at) + + @created.setter + def created(self, created): + if created: + self.created_at = created + + @property + def default_greetings(self): + + if self.api and self.default_greeting_ids: + return self.api._get_default_greetings(self.default_greeting_ids) + + @default_greetings.setter + def default_greetings(self, default_greetings): + if default_greetings: + self.default_greeting_ids = [o.id for o in default_greetings] + self._default_greetings = default_greetings + + @property + def default_group(self): + + if self.api and self.default_group_id: + return self.api._get_default_group(self.default_group_id) + + @default_group.setter + def default_group(self, default_group): + if default_group: + self.default_group_id = default_group.id + self._default_group = default_group + + @property + def greetings(self): + + if self.api and self.greeting_ids: + return self.api._get_greetings(self.greeting_ids) + + @greetings.setter + def greetings(self, greetings): + if greetings: + self.greeting_ids = [o.id for o in greetings] + self._greetings = greetings + + @property + def groups(self): + + if self.api and self.group_ids: + return self.api._get_groups(self.group_ids) + + @groups.setter + def groups(self, groups): + if groups: + self.group_ids = [o.id for o in groups] + self._groups = groups + + @property + def sms_group(self): + + if self.api and self.sms_group_id: + return self.api._get_sms_group(self.sms_group_id) + + @sms_group.setter + def sms_group(self, sms_group): + if sms_group: + self.sms_group_id = sms_group.id + self._sms_group = sms_group + + +class ShowAvailability(BaseObject): + """ + ###################################################################### + # Do not modify, this class is autogenerated by gen_classes.py # + ###################################################################### + """ + def __init__(self, + api=None, + available=None, + behaviour=None, + state_id=None, + status=None, + via=None, + **kwargs): + + self.api = api + self.available = available + self.behaviour = behaviour + self.state_id = state_id + self.status = status + self.via = via + + for key, value in kwargs.items(): + setattr(self, key, value) + + for key in self.to_dict(): + if getattr(self, key) is None: + try: + self._dirty_attributes.remove(key) + except KeyError: + continue + + @property + def state(self): + + if self.api and self.state_id: + return self.api._get_state(self.state_id) + + @state.setter + def state(self, state): + if state: + self.state_id = state.id + self._state = state diff --git a/zenpy/lib/endpoint.py b/zenpy/lib/endpoint.py index 5107d602..d28679de 100644 --- a/zenpy/lib/endpoint.py +++ b/zenpy/lib/endpoint.py @@ -649,6 +649,9 @@ class EndpointFactory(object): views.export = SecondaryEndpoint('views/%(id)s/export.json') views.search = ViewSearchEndpoint('views/search.json') recipient_addresses = PrimaryEndpoint('recipient_addresses') + attributes = PrimaryEndpoint('routing/attributes') + attributes.values = SecondaryEndpoint('routing/attributes/%(id)s/values') + attributes.value = MultipleIDEndpoint('routing/attributes/{0}/values/{1}.json') class Dummy(object): pass diff --git a/zenpy/lib/mapping.py b/zenpy/lib/mapping.py index 66290fa1..c9f7cdd6 100644 --- a/zenpy/lib/mapping.py +++ b/zenpy/lib/mapping.py @@ -99,7 +99,9 @@ class ZendeskObjectMapping(object): 'link': Link, 'skip': Skip, 'schedule': Schedule, - 'custom_role': CustomAgentRole + 'custom_role': CustomAgentRole, + 'attribute': RoutingAttribute, + 'attribute_value': RoutingAttributeValue } skip_attrs = [] diff --git a/zenpy/lib/response.py b/zenpy/lib/response.py index 2ddf1340..6a2e6ca8 100644 --- a/zenpy/lib/response.py +++ b/zenpy/lib/response.py @@ -323,6 +323,29 @@ def build(self, response): "Could not handle response: {}".format(response_json)) +class RoutingAttributesResponseHandler(GenericZendeskResponseHandler): + @staticmethod + def applies_to(api, response): + endpoint_path = get_endpoint_path(api, response) + return endpoint_path.startswith('/routing') + + def deserialize(self, response_json): + deserialized_response = super(RoutingAttributesResponseHandler, self).deserialize(response_json) + + if 'attributes' in deserialized_response: + return deserialized_response['attributes'] + elif 'attribute' in deserialized_response: + return deserialized_response['attribute'] + elif 'attribute_values' in deserialized_response: + return deserialized_response['attribute_values'] + elif 'attribute_value' in deserialized_response: + return deserialized_response['attribute_value'] + + + def build(self, response): + return self.deserialize(response.json()) + + class RequestCommentResponseHandler(GenericZendeskResponseHandler): @staticmethod def applies_to(api, response): From 387485322e99f1aa65645de3b1244768e6319edd Mon Sep 17 00:00:00 2001 From: James Tanner Date: Mon, 22 Mar 2021 16:04:49 -0400 Subject: [PATCH 02/20] fix unit tests --- zenpy/lib/api.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/zenpy/lib/api.py b/zenpy/lib/api.py index 6257e9ae..52a3621d 100644 --- a/zenpy/lib/api.py +++ b/zenpy/lib/api.py @@ -102,12 +102,12 @@ def _delete(self, url, payload=None): timeout=self.timeout) return self._process_response(response) - def _get(self, url, raw_response=False, **kwargs): + def _get(self, url, **kwargs): response = self._call_api(self.session.get, url, timeout=self.timeout, **kwargs) - if raw_response: + if kwargs.get('raw_response'): return response else: return self._process_response(response) @@ -123,7 +123,12 @@ def _call_api(self, http_method, url, **kwargs): :param kwargs: Any additional kwargs to pass on to requests. """ log.debug("{}: {} - {}".format(http_method.__name__.upper(), url, + kwargs)) + + if 'raw_response' in kwargs: + kwargs.pop('raw_response', None) + if self.ratelimit is not None: # This path indicates we're taking a proactive approach to not hit the rate limit response = self._ratelimit(http_method=http_method, @@ -240,8 +245,7 @@ def _serialize(self, zenpy_object): return json.loads( json.dumps(zenpy_object, default=json_encode_for_zendesk)) - def _query_zendesk(self, endpoint, object_type, raw_response, *endpoint_args, - **endpoint_kwargs): + def _query_zendesk(self, endpoint, object_type, *endpoint_args, **endpoint_kwargs): """ Query Zendesk for items. If an id or list of ids are passed, attempt to locate these items in the relevant cache. If they cannot be found, or no ids are passed, execute a call to Zendesk @@ -262,7 +266,7 @@ def _query_zendesk(self, endpoint, object_type, raw_response, *endpoint_args, return item else: return self._get(url=self._build_url( - endpoint(*endpoint_args, **endpoint_kwargs)), raw_response=raw_response) + endpoint(*endpoint_args, **endpoint_kwargs))) elif 'ids' in endpoint_kwargs: cached_objects = [] # Check to see if we have all objects in the cache. @@ -273,7 +277,7 @@ def _query_zendesk(self, endpoint, object_type, raw_response, *endpoint_args, if not obj: return self._get( self._build_url(endpoint=endpoint( - *endpoint_args, **endpoint_kwargs)), raw_response=raw_response) + *endpoint_args, **endpoint_kwargs))) cached_objects.append(obj) return ZendeskResultGenerator(self, {}, response_objects=cached_objects, @@ -281,7 +285,7 @@ def _query_zendesk(self, endpoint, object_type, raw_response, *endpoint_args, else: return self._get( self._build_url( - endpoint=endpoint(*endpoint_args, **endpoint_kwargs)), raw_response=raw_response) + endpoint=endpoint(*endpoint_args, **endpoint_kwargs))) def _check_response(self, response): """ @@ -346,9 +350,8 @@ def __init__(self, config, object_type, endpoint=None): super(Api, self).__init__(**config) self._object_mapping = ZendeskObjectMapping(self) - def __call__(self, raw_response=False, *args, **kwargs): - return self._query_zendesk(self.endpoint, self.object_type, raw_response, *args, - **kwargs) + def __call__(self, *args, **kwargs): + return self._query_zendesk(self.endpoint, self.object_type, *args, **kwargs) def _get_user(self, user_id): if int(user_id) < 0: From a539cf0ba8cc0c2d6a1fefcf0b372fb4164e0454 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Mon, 22 Mar 2021 16:36:57 -0400 Subject: [PATCH 03/20] dos2unix json files --- specification/zendesk/routing_attribute_value.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/specification/zendesk/routing_attribute_value.json b/specification/zendesk/routing_attribute_value.json index 3a49e1e4..6f5f6a85 100644 --- a/specification/zendesk/routing_attribute_value.json +++ b/specification/zendesk/routing_attribute_value.json @@ -1,7 +1,7 @@ -{ - "url": "https://facetoe1.zendesk.com/api/v2/routing/attributes/15821cba-7326-11e8-b07e-950ba849aa27.json", - "created_at": "2017-12-01T19:29:31Z", - "updated_at": "2017-12-01T19:29:31Z", - "id": "b376b35a-e38b-11e8-a292-e3b6377c5575", - "name": "French" +{ + "url": "https://facetoe1.zendesk.com/api/v2/routing/attributes/15821cba-7326-11e8-b07e-950ba849aa27.json", + "created_at": "2017-12-01T19:29:31Z", + "updated_at": "2017-12-01T19:29:31Z", + "id": "b376b35a-e38b-11e8-a292-e3b6377c5575", + "name": "French" } \ No newline at end of file From dd996388217075f8fea338ae61ef4800a2075d95 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Wed, 24 Mar 2021 11:42:47 -0400 Subject: [PATCH 04/20] remove empty spaces --- zenpy/lib/api.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zenpy/lib/api.py b/zenpy/lib/api.py index 52a3621d..fc693f7b 100644 --- a/zenpy/lib/api.py +++ b/zenpy/lib/api.py @@ -1838,8 +1838,8 @@ def make_default(self, user, group_membership): return self._put(self._build_url( self.endpoint.make_default(user, group_membership)), payload={}) - - + + class RoutingAttributesApi(CRUDApi): def __init__(self, config): super(RoutingAttributesApi, self).__init__(config, object_type='attribute') @@ -1849,7 +1849,7 @@ def values(self, attribute_id): Return all attribute values for attribute. """ return self._get(self._build_url(self.endpoint.values(id=attribute_id))) - + def value(self, attribute_id, value_id): """ Return specified attribute value for attribute. From 34a42106b5fd874a68299c2be7c8fcdbdeeff335 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Wed, 24 Mar 2021 11:46:25 -0400 Subject: [PATCH 05/20] more blank spaces --- zenpy/lib/response.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/zenpy/lib/response.py b/zenpy/lib/response.py index 6a2e6ca8..beeb2a51 100644 --- a/zenpy/lib/response.py +++ b/zenpy/lib/response.py @@ -328,10 +328,10 @@ class RoutingAttributesResponseHandler(GenericZendeskResponseHandler): def applies_to(api, response): endpoint_path = get_endpoint_path(api, response) return endpoint_path.startswith('/routing') - + def deserialize(self, response_json): deserialized_response = super(RoutingAttributesResponseHandler, self).deserialize(response_json) - + if 'attributes' in deserialized_response: return deserialized_response['attributes'] elif 'attribute' in deserialized_response: @@ -340,11 +340,10 @@ def deserialize(self, response_json): return deserialized_response['attribute_values'] elif 'attribute_value' in deserialized_response: return deserialized_response['attribute_value'] - - + def build(self, response): return self.deserialize(response.json()) - + class RequestCommentResponseHandler(GenericZendeskResponseHandler): @staticmethod From b9e430ec6267ca00b6b9aadcb515a10167339b03 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Wed, 24 Mar 2021 16:12:29 -0400 Subject: [PATCH 06/20] add routing attribute value support --- zenpy/__init__.py | 5 +-- zenpy/lib/api.py | 81 +++++++++++++++++++++++++++++++++---------- zenpy/lib/endpoint.py | 23 ++++++++++-- zenpy/lib/mapping.py | 6 +++- zenpy/lib/response.py | 11 ++++-- 5 files changed, 100 insertions(+), 26 deletions(-) diff --git a/zenpy/__init__.py b/zenpy/__init__.py index 5eb89abb..a64c56e5 100644 --- a/zenpy/__init__.py +++ b/zenpy/__init__.py @@ -38,7 +38,8 @@ TalkApi, CustomAgentRolesApi, SearchApi, - UserFieldsApi, RoutingAttributesApi + UserFieldsApi, + RoutingApi ) from zenpy.lib.cache import ZenpyCache, ZenpyCacheManager @@ -162,7 +163,7 @@ def __init__( self.custom_agent_roles = CustomAgentRolesApi( config, object_type="custom_agent_role" ) - self.routing_attributes = RoutingAttributesApi(config) + self.routing = RoutingApi(config) @staticmethod def http_adapter_kwargs(): diff --git a/zenpy/lib/api.py b/zenpy/lib/api.py index fc693f7b..bfa92555 100644 --- a/zenpy/lib/api.py +++ b/zenpy/lib/api.py @@ -61,7 +61,7 @@ def __init__(self, subdomain, session, timeout, ratelimit, CombinationResponseHandler, ViewResponseHandler, SlaPolicyResponseHandler, - RoutingAttributesResponseHandler, + RoutingResponseHandler, RequestCommentResponseHandler, GenericZendeskResponseHandler, HTTPOKResponseHandler, @@ -107,10 +107,7 @@ def _get(self, url, **kwargs): url, timeout=self.timeout, **kwargs) - if kwargs.get('raw_response'): - return response - else: - return self._process_response(response) + return self._process_response(response) def _call_api(self, http_method, url, **kwargs): """ @@ -153,6 +150,9 @@ def _call_api(self, http_method, url, **kwargs): sleep(1) response = http_method(url, **kwargs) + #if '.post' in str(http_method): + # import epdb; epdb.st() + self._check_response(response) self._update_callsafety(response) return response @@ -259,6 +259,9 @@ def _query_zendesk(self, endpoint, object_type, *endpoint_args, **endpoint_kwarg :return: either a ResultGenerator or a Zenpy object. """ + #if 'value' in str(object_type): + # import epdb; epdb.st() + _id = endpoint_kwargs.get('id', None) if _id: item = self.cache.get(object_type, _id) @@ -283,6 +286,10 @@ def _query_zendesk(self, endpoint, object_type, *endpoint_args, **endpoint_kwarg response_objects=cached_objects, object_type=object_type) else: + + if 'value' in str(object_type): + import epdb; epdb.st() + return self._get( self._build_url( endpoint=endpoint(*endpoint_args, **endpoint_kwargs))) @@ -1839,23 +1846,61 @@ def make_default(self, user, group_membership): self.endpoint.make_default(user, group_membership)), payload={}) +''' +class AvailabilitiesApi(TalkApiBase): + def __init__(self, config, endpoint, object_type): + super(AvailabilitiesApi, self).__init__(config, + object_type=object_type, + endpoint=endpoint) +''' -class RoutingAttributesApi(CRUDApi): - def __init__(self, config): - super(RoutingAttributesApi, self).__init__(config, object_type='attribute') +class RoutingAttributeValueApi(CRUDApi): - def values(self, attribute_id): - """ - Return all attribute values for attribute. - """ - return self._get(self._build_url(self.endpoint.values(id=attribute_id))) + # defines the top level key for REST payloads + object_type = 'attribute_value' - def value(self, attribute_id, value_id): - """ - Return specified attribute value for attribute. - """ - return self._get(self._build_url(self.endpoint.value(id=attribute_id))) + # values are children of attributes, so an attribute must be passed + # to the constructor ... + def __init__(self, config, attribute=None): + print(f'# ATTRIBUTE {attribute}') + super(RoutingAttributeValueApi, self).__init__(config, object_type=self.object_type) + + +class RoutingAttributeApi(CRUDApi): + # defines the top level key for REST payloads + object_type = 'attribute' + + def __init__(self, config): + super(RoutingAttributeApi, self).__init__(config, object_type=self.object_type) + self.values = RoutingAttributeValueApi(config) + + +class RoutingApi(CRUDApi): + def __init__(self, config): + super(RoutingApi, self).__init__(config, object_type='routing') + self.attributes = RoutingAttributeApi(config) + + + ''' + def attributes(self): + # https://tannerjc2.zendesk.com/api/v2/routing/attributes.json + url = self._build_url(self.endpoint.attributes()) + print('\033[96m' + 'get url ' + url + '\033[0m') + #import epdb; epdb.st() + res = self._get(url) + #import epdb; epdb.st() + return res + ''' + + ''' + def values(self, attribute=None): + url = self._build_url(self.endpoint.attributes()) + url = url.replace('.json', '/' + attribute.id + '/values') + res = self._get(url) + #import epdb; epdb.st() + return res + ''' class JiraLinkApi(CRUDApi): def __init__(self, config): diff --git a/zenpy/lib/endpoint.py b/zenpy/lib/endpoint.py index d28679de..8ea0e16a 100644 --- a/zenpy/lib/endpoint.py +++ b/zenpy/lib/endpoint.py @@ -649,13 +649,30 @@ class EndpointFactory(object): views.export = SecondaryEndpoint('views/%(id)s/export.json') views.search = ViewSearchEndpoint('views/search.json') recipient_addresses = PrimaryEndpoint('recipient_addresses') - attributes = PrimaryEndpoint('routing/attributes') - attributes.values = SecondaryEndpoint('routing/attributes/%(id)s/values') - attributes.value = MultipleIDEndpoint('routing/attributes/{0}/values/{1}.json') + class Dummy(object): pass + routings = Dummy() + routings.attributes = PrimaryEndpoint('routing/attributes') + attribute = PrimaryEndpoint('routing/attributes') + attributes = PrimaryEndpoint('routing/attributes') + routing_attribute = PrimaryEndpoint('routing/attributes') + routing_attributes = PrimaryEndpoint('routing/attributes') + routings.attributes.values = MultipleIDEndpoint('routing/attributes/{0}/values/{1}.json') + #values = MultipleIDEndpoint('routing/attributes/{0}/values/{1}.json') + values = SecondaryEndpoint('routing/attributes/%(id)s/values.json') + attribute_values = SecondaryEndpoint('routing/attributes/%(id)s/values.json') + + ''' + #routings = PrimaryEndpoint('routing') + routing_attribute = PrimaryEndpoint('routing/attributes') + routing_attributes = PrimaryEndpoint('routing/attributes') + routing_values = SecondaryEndpoint('routing/attributes/%(id)s/values') + routing_value = MultipleIDEndpoint('routing/attributes/{0}/values/{1}.json') + ''' + talk = Dummy() talk.calls = Dummy() talk.calls.incremental = IncrementalEndpoint( diff --git a/zenpy/lib/mapping.py b/zenpy/lib/mapping.py index c9f7cdd6..94d75c64 100644 --- a/zenpy/lib/mapping.py +++ b/zenpy/lib/mapping.py @@ -100,8 +100,12 @@ class ZendeskObjectMapping(object): 'skip': Skip, 'schedule': Schedule, 'custom_role': CustomAgentRole, + 'routing_attribute': RoutingAttribute, 'attribute': RoutingAttribute, - 'attribute_value': RoutingAttributeValue + 'attribute_value': RoutingAttributeValue, + 'attribute_values': RoutingAttributeValue, + 'routing_attribute_value': RoutingAttributeValue, + 'value': RoutingAttributeValue } skip_attrs = [] diff --git a/zenpy/lib/response.py b/zenpy/lib/response.py index beeb2a51..0eaa3917 100644 --- a/zenpy/lib/response.py +++ b/zenpy/lib/response.py @@ -20,6 +20,7 @@ class ResponseHandler(object): def __init__(self, api, object_mapping=None): self.api = api self.object_mapping = object_mapping or api._object_mapping + print('rh init') @staticmethod @abstractmethod @@ -64,6 +65,7 @@ def deserialize(self, response_json): # Locate and store the single objects. for zenpy_object_name in self.object_mapping.class_mapping: + #print('# ' + zenpy_object_name) if zenpy_object_name in response_json: zenpy_object = self.object_mapping.object_from_json( zenpy_object_name, response_json[zenpy_object_name]) @@ -323,16 +325,20 @@ def build(self, response): "Could not handle response: {}".format(response_json)) -class RoutingAttributesResponseHandler(GenericZendeskResponseHandler): +class RoutingResponseHandler(GenericZendeskResponseHandler): @staticmethod def applies_to(api, response): endpoint_path = get_endpoint_path(api, response) return endpoint_path.startswith('/routing') def deserialize(self, response_json): - deserialized_response = super(RoutingAttributesResponseHandler, self).deserialize(response_json) + print('\033[96m' + 'rarh deserialize' + str(response_json) + '\033[0m') + deserialized_response = super(RoutingResponseHandler, self).deserialize(response_json) + + print('\033[96m' + 'rarh deserialized' + str(deserialized_response) + '\033[0m') if 'attributes' in deserialized_response: + print('\033[96m' + 'rarh deserialize return ' + str(deserialized_response['attributes']) + '\033[0m') return deserialized_response['attributes'] elif 'attribute' in deserialized_response: return deserialized_response['attribute'] @@ -342,6 +348,7 @@ def deserialize(self, response_json): return deserialized_response['attribute_value'] def build(self, response): + print('\033[96m' + 'rarh build' + '\033[0m') return self.deserialize(response.json()) From 1ac6a7c03a7977e996fbafc8ece86d73c0e70b09 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Wed, 24 Mar 2021 16:43:27 -0400 Subject: [PATCH 07/20] remove unused mappings --- zenpy/lib/mapping.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/zenpy/lib/mapping.py b/zenpy/lib/mapping.py index 94d75c64..fb354892 100644 --- a/zenpy/lib/mapping.py +++ b/zenpy/lib/mapping.py @@ -100,11 +100,8 @@ class ZendeskObjectMapping(object): 'skip': Skip, 'schedule': Schedule, 'custom_role': CustomAgentRole, - 'routing_attribute': RoutingAttribute, 'attribute': RoutingAttribute, 'attribute_value': RoutingAttributeValue, - 'attribute_values': RoutingAttributeValue, - 'routing_attribute_value': RoutingAttributeValue, 'value': RoutingAttributeValue } From 717643da52cc669f2a546f12ce2ab2976b338636 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Wed, 24 Mar 2021 16:57:47 -0400 Subject: [PATCH 08/20] cleanup endpoints --- zenpy/lib/endpoint.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/zenpy/lib/endpoint.py b/zenpy/lib/endpoint.py index 8ea0e16a..539dcb36 100644 --- a/zenpy/lib/endpoint.py +++ b/zenpy/lib/endpoint.py @@ -650,29 +650,15 @@ class EndpointFactory(object): views.search = ViewSearchEndpoint('views/search.json') recipient_addresses = PrimaryEndpoint('recipient_addresses') - class Dummy(object): pass routings = Dummy() - routings.attributes = PrimaryEndpoint('routing/attributes') - attribute = PrimaryEndpoint('routing/attributes') attributes = PrimaryEndpoint('routing/attributes') - routing_attribute = PrimaryEndpoint('routing/attributes') routing_attributes = PrimaryEndpoint('routing/attributes') - routings.attributes.values = MultipleIDEndpoint('routing/attributes/{0}/values/{1}.json') - #values = MultipleIDEndpoint('routing/attributes/{0}/values/{1}.json') values = SecondaryEndpoint('routing/attributes/%(id)s/values.json') attribute_values = SecondaryEndpoint('routing/attributes/%(id)s/values.json') - ''' - #routings = PrimaryEndpoint('routing') - routing_attribute = PrimaryEndpoint('routing/attributes') - routing_attributes = PrimaryEndpoint('routing/attributes') - routing_values = SecondaryEndpoint('routing/attributes/%(id)s/values') - routing_value = MultipleIDEndpoint('routing/attributes/{0}/values/{1}.json') - ''' - talk = Dummy() talk.calls = Dummy() talk.calls.incremental = IncrementalEndpoint( From ddf0674e56a6655c87469ce2a6b70f4dfd76fd0d Mon Sep 17 00:00:00 2001 From: James Tanner Date: Thu, 25 Mar 2021 17:06:49 -0400 Subject: [PATCH 09/20] checkin --- specification/zendesk/attribute_value.json | 8 + zenpy/gen_classes.py | 447 --------------------- zenpy/lib/api.py | 10 + zenpy/lib/endpoint.py | 2 + zenpy/lib/mapping.py | 3 +- 5 files changed, 22 insertions(+), 448 deletions(-) create mode 100644 specification/zendesk/attribute_value.json delete mode 100644 zenpy/gen_classes.py diff --git a/specification/zendesk/attribute_value.json b/specification/zendesk/attribute_value.json new file mode 100644 index 00000000..2bb3e059 --- /dev/null +++ b/specification/zendesk/attribute_value.json @@ -0,0 +1,8 @@ +{ + "attribute_id": "9b660de4-72d1-11eb-814d-d9d87f5c2ded", + "created_at": "2021-02-19T16:43:38Z", + "id": "9d80ff0a-72d1-11eb-95e0-f5b65d6795d8", + "name": "Finance", + "updated_at": "2021-02-19T20:01:08Z", + "url": "https://pdi-testboxlab.zendesk.com/api/v2/routing/attributes/9b660de4-72d1-11eb-814d-d9d87f5c2ded/values/9d80ff0a-72d1-11eb-95e0-f5b65d6795d8.json" +} diff --git a/zenpy/gen_classes.py b/zenpy/gen_classes.py deleted file mode 100644 index 74dbd2a5..00000000 --- a/zenpy/gen_classes.py +++ /dev/null @@ -1,447 +0,0 @@ -#!/usr/bin/env python -import functools -import glob -import json -import re -import sys -from multiprocessing.pool import Pool -from optparse import OptionParser - -import os -from yapf.yapflib.yapf_api import FormatCode - -__author__ = 'facetoe' -from jinja2 import Template - - -class TemplateObject(object): - OBJECT_TEMPLATE = None - - def render(self): - return Template(self.OBJECT_TEMPLATE).render(object=self) - - -class Class(TemplateObject): - OBJECT_TEMPLATE = ''' -class {{object.name}}(BaseObject): - """ - ###################################################################### - # Do not modify, this class is autogenerated by gen_classes.py # - ###################################################################### - """ - {{-object.init.render()-}} - {{-object.properties.render()-}} - - -''' - - def __init__(self, name, _json, doc_json): - attributes = [] - object_name = to_snake_case(name).lower() + 's' - - for attr_name, attr in iter(sorted(_json.items())): - attribute = Attribute(attr_name=attr_name, attr_value=attr, parent_object=to_snake_case(name).lower()) - if object_name in doc_json and attr_name in doc_json[object_name]: - doc_strings = [] - attr_docs = doc_json[object_name][attr_name] - if attr_docs['type'] not in ('string', 'boolean', 'date', 'integer', 'array', 'object', 'timestamp'): - attr_docs['type'] = ':class:`%s`' % attr_docs['type'] - - for key, value in sorted(attr_docs.items()): - doc_strings.append("%s: %s" % (key.capitalize(), value.replace('*', ''))) - attribute.attr_docs = doc_strings - attributes.append(attribute) - - attributes = sorted(attributes, key=lambda x: x.attr_name) - self.name = name - self.init = Init(attributes) - self.properties = Properties(attributes) - - -class Init(TemplateObject): - OBJECT_TEMPLATE = """ - {% if object.init_params %} - def __init__(self, api=None, {{ object.init_params }}, **kwargs): - {% else %} - def __init__(self, api=None, **kwargs): - {% endif %} - self.api = api - {% for attr in object.attributes -%} - {% if attr.attr_docs and attr.attr_name %} - {% for docline in attr.attr_docs %} - # {{ docline-}} - {% endfor %} - {% endif -%} - {% if attr.attr_name and not attr.attr_name.startswith('_') -%} - self.{{attr.attr_name}} = {{attr.attr_name}} - {% elif attr.attr_name %} - self.{{attr.attr_name}} = None - {% endif -%} - {% endfor %} - for key, value in kwargs.items(): - setattr(self, key, value) - - for key in self.to_dict(): - if getattr(self, key) is None: - try: - self._dirty_attributes.remove(key) - except KeyError: - continue - """ - - def __init__(self, attributes): - self.attributes = attributes - self.init_params = ", ".join( - ["{}=None".format(a.attr_name) - for a in attributes - if not a.attr_name.startswith('_') and a.attr_name]) - self.attributes = attributes - - -class Properties(TemplateObject): - OBJECT_TEMPLATE = """ - {%- for prop in object.properties -%} - {{- prop.render() -}} - {% endfor %} - """ - - def __init__(self, attributes): - self.properties = [Property(a) for a in attributes] - - -class Property(TemplateObject): - OBJECT_TEMPLATE = """ - {%- if object.attribute.is_property -%} - @property - def {{object.attribute.object_name}}(self): - {% if object.attribute.attr_docs -%} - \"\"\" - | {{ object.attribute.attr_docs[0] }} - \"\"\" - {%- endif -%} - {{- object.prop_body -}} - - @{{object.attribute.object_name}}.setter - def {{object.attribute.object_name}}(self, {{object.attribute.object_name}}): - {{- object.prop_setter_body -}} - {%- endif -%} - - """ - - DATE_TEMPLATE = """ - if self.{{object.attribute.key}}: - return dateutil.parser.parse(self.{{object.attribute.key}}) - """ - - PROPERTY_TEMPLATE = """ - if self.api and self.{{object.attribute.attr_name}}: - return self.api._get_{{object.attribute.object_type}}(self.{{object.attribute.attr_name}}) - """ - - SETTER_TEMPLATE_ASSIGN = """ - if {{object.attribute.object_name}}: - self.{{object.attribute.attr_name}} = {{object.attribute.attr_assignment}} - self._{{object.attribute.object_name}} = {{object.attribute.object_name}} - """ - - SETTER_TEMPLATE_OBJECT_DEFAULT = """ - if {{object.attribute.object_name}}: - self._{{object.attribute.object_name}} = {{object.attribute.object_name}} - """ - - SETTER_TEMPLATE_DEFAULT = """ - if {{object.attribute.object_name}}: - self.{{object.attribute.attr_name}} = {{object.attribute.object_name}} - """ - - def __init__(self, attribute): - self.attribute = attribute - self.prop_name = attribute.object_name - self.prop_body = self.get_prop_body(attribute) - self.prop_setter_body = self.get_prop_setter_body(attribute) - - def get_prop_body(self, attribute): - if attribute.object_type == 'date': - template = self.DATE_TEMPLATE - else: - template = self.PROPERTY_TEMPLATE - - return Template(template).render(object=self, trim_blocks=True) - - def get_prop_setter_body(self, attribute): - if attribute.attr_assignment: - template = self.SETTER_TEMPLATE_ASSIGN - elif attribute.object_name in ('phone_number'): - template = self.SETTER_TEMPLATE_OBJECT_DEFAULT - else: - template = self.SETTER_TEMPLATE_DEFAULT - return Template(template).render(object=self, trim_blocks=True) - - -class Attribute(object): - def __init__(self, parent_object, attr_name, attr_value, attr_docs=None): - if attr_name == 'from': - attr_name = 'from_' - - self.parent_object = parent_object - self.key = '_{}'.format(attr_name) if attr_name.endswith('timestamp') else attr_name - self.attr_docs = attr_docs - self.object_type = self.get_object_type(attr_name, attr_value) - self.object_name = self.get_object_name(attr_name, attr_value) - self.attr_name = self.get_attr_name(attr_name=attr_name, attr_type=self.object_type) - self.attr_assignment = self.get_attr_assignment(self.object_name, self.object_type, attr_name) - self.is_property = self.get_is_property(attr_name) - - def get_object_type(self, attr_name, attr_value): - if attr_name in ('assignee_id', 'submitter_id', 'requester_id', - 'author_id', 'updater_id', 'recipient_id', - 'created_by_id', 'updated_by_id'): - object_type = 'user' - elif attr_name in ('photo',): - object_type = 'attachment' - elif attr_name.endswith('time_in_minutes'): - object_type = 'ticket_metric_item' - elif attr_name in ('recipients', 'collaborator_ids'): - object_type = 'users' - elif attr_name in ('forum_topic_id',): - object_type = 'topic' - elif (attr_name.endswith('_at') or attr_name.endswith('timestamp')) and not isinstance(attr_value, int): - object_type = 'date' - else: - object_type = attr_name.replace('_id', '') - - return object_type - - def get_attr_name(self, attr_type, attr_name): - should_modify = attr_name.endswith('timestamp') and attr_type != 'timestamp' - if should_modify: - return "_%s" % attr_name - else: - return attr_name - - def get_attr_assignment(self, object_name, object_type, key): - if object_type not in (key, 'date') and object_name not in ('phone_number') and key.endswith('_id'): - return '%s.id' % object_name - elif key.endswith('_ids'): - return '[o.id for o in %(object_name)s]' % locals() - - def get_object_name(self, attr_name, attr_value): - if attr_name == 'locale_id': - return attr_name - for replacement in ('_at', '_id'): - if attr_name.endswith(replacement): - return attr_name.replace(replacement, '') - elif attr_name.endswith('_ids'): - return "%ss" % attr_name.replace('_ids', '') - return attr_name - - def get_is_property(self, attr_name): - if attr_name in ('locale_id', 'external_id', 'graph_object_id', - 'agreement_id', 'content_id', 'item_id', 'source_id', 'community_id', - 'issue_id', 'instance_id'): - return False - elif self.parent_object == 'skip' and attr_name in ('ticket', 'ticket_id'): - return False - if attr_name.endswith('_id') or attr_name.endswith('_ids'): - return True - elif self.object_type == 'date': - return True - return False - - def __str__(self): - return "[is_prop=%(is_property)s, " \ - "key=%(key)s, " \ - "obj_type=%(object_type)s, " \ - "obj_name=%(object_name)s, " \ - "attr_name=%(attr_name)s, " \ - "assn=%(attr_assignment)s]" \ - "attr_doc=%(attr_docs)s " % self.__dict__ - - def __repr__(self): - return self.__str__() - - -def to_snake_case(name): - s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name) - return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower() - - -BASE_CLASS = ''' -###################################################################### -# Do not modify, these classes are autogenerated by gen_classes.py # -###################################################################### - -import json -import dateutil.parser -from zenpy.lib.util import json_encode_for_printing, json_encode_for_zendesk - - -class BaseObject(object): - """ - Base for all Zenpy objects. Keeps track of which attributes have been modified. - """ - - def __new__(cls, *args, **kwargs): - instance = super(BaseObject, cls).__new__(cls) - instance.__dict__['_dirty_attributes'] = set() - instance.__dict__['_dirty_callback'] = None - instance.__dict__['_always_dirty'] = set() - return instance - - def __setattr__(self, key, value): - if key not in ('_dirty', '_dirty_callback', '_always_dirty'): - self.__dict__['_dirty_attributes'].add(key) - if self._dirty_callback is not None: - self._dirty_callback() - object.__setattr__(self, key, value) - - def _clean_dirty(self, obj=None): - """ Recursively clean self and all child objects. """ - obj = obj or self - obj.__dict__['_dirty_attributes'].clear() - obj._dirty = False - for key, val in vars(obj).items(): - if isinstance(val, BaseObject): - self._clean_dirty(val) - else: - func = getattr(val, '_clean_dirty', None) - if callable(func): - func() - - def _set_dirty(self, obj=None): - """ Recursively set self and all child objects _dirty flag. """ - obj = obj or self - for key, value in vars(obj).items(): - if key not in ('api', '_dirty_attributes', '_always_dirty', '_dirty_callback', '_dirty'): - setattr(obj, key, value) - if isinstance(value, BaseObject): - self._set_dirty(value) - - def to_json(self, indent=2): - """ Return self formatted as JSON. """ - return json.dumps(self, default=json_encode_for_printing, indent=indent) - - def to_dict(self, serialize=False): - """ - This method returns the object as a Python dict. If serialize is passed, only those attributes - that have been modified will be included in the result. - """ - if serialize: - encode_method = json_encode_for_zendesk - else: - encode_method = json_encode_for_printing - return json.loads(json.dumps(self._to_dict(serialize=serialize), default=encode_method)) - - def _to_dict(self, serialize=False): - """ - This method works by copying self.__dict__, and removing everything that should not be serialized. - """ - copy_dict = self.__dict__.copy() - for key, value in vars(self).items(): - # We want to send all ids to Zendesk always - if serialize and key == 'id': - continue - - # If this is a Zenpy object, convert it to a dict. - if not serialize and isinstance(value, BaseObject): - copy_dict[key] = copy_dict.pop(key).to_dict() - - # This object has a flag indicating it has been dirtied, so we want to send it off. - elif serialize and getattr(value, '_dirty', False): - continue - - # Here we have an attribute that should always be sent to Zendesk. - elif serialize and key in self._always_dirty: - continue - - # These are for internal tracking, so just delete. - elif key in ('api', '_dirty_attributes', '_always_dirty', '_dirty_callback', '_dirty'): - del copy_dict[key] - - # If the attribute has not been modified, do not send it. - elif serialize and key not in self._dirty_attributes: - del copy_dict[key] - - # Some reserved words are prefixed with an underscore, remove it here. - elif key.startswith('_'): - copy_dict[key[1:]] = copy_dict[key] - del copy_dict[key] - return copy_dict - - def __repr__(self): - class_name = type(self).__name__ - if class_name in ('UserField',): - return "{}()".format(class_name) - - def formatted(item): - return item if (isinstance(item, int) or item is None) else "'{}'".format(item) - - for identifier in ('id', 'token', 'key', 'name', 'account_key'): - if hasattr(self, identifier): - return "{}({}={})".format(class_name, identifier, formatted(getattr(self, identifier))) - return "{}()".format(class_name)''' - -parser = OptionParser() - -parser.add_option("--spec-path", "-s", dest="spec_path", - help="Location of .json spec", metavar="SPEC_PATH") -parser.add_option("--doc-json", "-d", dest="doc_json_path", - help="Location of .json documentation file", metavar="DOC_JSON") -parser.add_option("--out-path", "-o", dest="out_path", - help="Where to put generated classes", - metavar="OUT_PATH", - default=os.getcwd()) - -(options, args) = parser.parse_args() - -if not options.spec_path: - print("--spec-path is required!") - sys.exit() -elif not os.path.isdir(options.spec_path): - print("--spec-path must be a directory!") - sys.exit() -elif not options.doc_json_path: - print("--doc-json is required!") - sys.exit() - -doc_json = json.load(open(options.doc_json_path)) - - -def process_file(namespace, path): - class_name = os.path.basename(os.path.splitext(path)[0]).capitalize() - class_name = "".join([w.capitalize() for w in class_name.split('_')]) - with open(path) as f: - class_code = Class(class_name, json.load(f), doc_json[namespace]).render() - print("Processed: %s -> %s" % (os.path.basename(path), class_name)) - return class_code - - -def process_specification_directory(glob_pattern, outfile_name, namespace, write_baseclass=True,): - with open(os.path.join(options.out_path, outfile_name), 'w+') as out_file: - paths = [p for p in glob.glob(os.path.join(options.spec_path, glob_pattern))] - classes = list() - - func = functools.partial(process_file, namespace) - with Pool() as pool: - classes.extend(pool.map(func, paths)) - print("Formatting...") - formatted_code = FormatCode("\n".join(sorted(classes)))[0] - if write_baseclass: - header = BASE_CLASS - else: - header = "from zenpy.lib.api_objects import BaseObject\nimport dateutil.parser" - - out_file.write("\n\n\n".join((header, formatted_code))) - -if __name__ == '__main__': - process_specification_directory('zendesk/*.json', 'api_objects/__init__.py', - namespace='core') - process_specification_directory('chat/*.json', 'api_objects/chat_objects.py', - namespace='chat', - write_baseclass=False) - process_specification_directory('help_centre/*.json', 'api_objects/help_centre_objects.py', - namespace='help_center', - write_baseclass=False) - process_specification_directory('talk/*.json', 'api_objects/talk_objects.py', - namespace='core', - write_baseclass=False) diff --git a/zenpy/lib/api.py b/zenpy/lib/api.py index bfa92555..7266dd15 100644 --- a/zenpy/lib/api.py +++ b/zenpy/lib/api.py @@ -1876,10 +1876,20 @@ def __init__(self, config): self.values = RoutingAttributeValueApi(config) +class RoutingAgentApi(CRUDApi): + + # defines the top level key for REST payloads + object_type = 'agent' + + def __init__(self, config): + super(RoutingAgentApi, self).__init__(config, object_type=self.object_type) + + class RoutingApi(CRUDApi): def __init__(self, config): super(RoutingApi, self).__init__(config, object_type='routing') self.attributes = RoutingAttributeApi(config) + self.agents = RoutingAgentApi(config) ''' diff --git a/zenpy/lib/endpoint.py b/zenpy/lib/endpoint.py index 539dcb36..e665875a 100644 --- a/zenpy/lib/endpoint.py +++ b/zenpy/lib/endpoint.py @@ -659,6 +659,8 @@ class Dummy(object): values = SecondaryEndpoint('routing/attributes/%(id)s/values.json') attribute_values = SecondaryEndpoint('routing/attributes/%(id)s/values.json') + agents = PrimaryEndpoint('routing/agents') + talk = Dummy() talk.calls = Dummy() talk.calls.incremental = IncrementalEndpoint( diff --git a/zenpy/lib/mapping.py b/zenpy/lib/mapping.py index fb354892..5db79f10 100644 --- a/zenpy/lib/mapping.py +++ b/zenpy/lib/mapping.py @@ -102,7 +102,8 @@ class ZendeskObjectMapping(object): 'custom_role': CustomAgentRole, 'attribute': RoutingAttribute, 'attribute_value': RoutingAttributeValue, - 'value': RoutingAttributeValue + 'value': RoutingAttributeValue, + 'instance_value': RoutingAgentInstanceValue } skip_attrs = [] From a0e3cfe9b87509f8b09c60d510a49057eee2b515 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Fri, 26 Mar 2021 11:02:00 -0400 Subject: [PATCH 10/20] add target for gen classes --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 0f072694..10a7642f 100644 --- a/Makefile +++ b/Makefile @@ -13,3 +13,5 @@ unittest: nosetests -v --stop +gen_classes: + cd tools && ./gen_classes.py --spec-path ../specification --doc-json doc_dict.json -o ../zenpy/lib/ From 2db9c1d2bbacf9ac39bf1f116e980f57c2526cb3 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Fri, 26 Mar 2021 11:22:20 -0400 Subject: [PATCH 11/20] update mapping --- zenpy/lib/mapping.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zenpy/lib/mapping.py b/zenpy/lib/mapping.py index 5db79f10..7ad24568 100644 --- a/zenpy/lib/mapping.py +++ b/zenpy/lib/mapping.py @@ -103,7 +103,7 @@ class ZendeskObjectMapping(object): 'attribute': RoutingAttribute, 'attribute_value': RoutingAttributeValue, 'value': RoutingAttributeValue, - 'instance_value': RoutingAgentInstanceValue + 'instance_value': RoutingAttributeValue } skip_attrs = [] From 254f19e2d59804f506ed7d40b5ae769248bac3d0 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Fri, 26 Mar 2021 12:44:08 -0400 Subject: [PATCH 12/20] add create method for agent attributes --- zenpy/lib/api.py | 81 +++++++++++++++++++++++++++---------------- zenpy/lib/endpoint.py | 1 + zenpy/lib/mapping.py | 3 +- 3 files changed, 55 insertions(+), 30 deletions(-) diff --git a/zenpy/lib/api.py b/zenpy/lib/api.py index 7266dd15..ab5d950f 100644 --- a/zenpy/lib/api.py +++ b/zenpy/lib/api.py @@ -287,8 +287,8 @@ def _query_zendesk(self, endpoint, object_type, *endpoint_args, **endpoint_kwarg object_type=object_type) else: - if 'value' in str(object_type): - import epdb; epdb.st() + #if 'value' in str(object_type): + # import epdb; epdb.st() return self._get( self._build_url( @@ -1846,13 +1846,6 @@ def make_default(self, user, group_membership): self.endpoint.make_default(user, group_membership)), payload={}) -''' -class AvailabilitiesApi(TalkApiBase): - def __init__(self, config, endpoint, object_type): - super(AvailabilitiesApi, self).__init__(config, - object_type=object_type, - endpoint=endpoint) -''' class RoutingAttributeValueApi(CRUDApi): @@ -1876,6 +1869,55 @@ def __init__(self, config): self.values = RoutingAttributeValueApi(config) +class RoutingAgentInstanceValuesApi(CRUDApi): + # defines the top level key for REST payloads + object_type = 'attribute_value_ids' + + def __init__(self, config): + super(RoutingAgentInstanceValuesApi, self).__init__(config, object_type=self.object_type) + + + ''' + class CRUDRequest(BaseZendeskRequest): + """ + Generic CRUD request. Most CRUD operations are handled by this class. + """ + def post(self, api_objects, *args, **kwargs): + self.check_type(api_objects) + + create_or_update = kwargs.pop('create_or_update', False) + create = kwargs.pop('create', False) + if isinstance(api_objects, Iterable) and create_or_update: + kwargs['create_or_update_many'] = True + endpoint = self.api.endpoint.create_or_update_many + elif isinstance(api_objects, Iterable): + kwargs['create_many'] = True + endpoint = self.api.endpoint + elif create_or_update: + endpoint = self.api.endpoint.create_or_update + elif create: + endpoint = self.api.endpoint.create + else: + endpoint = self.api.endpoint + + payload = self.build_payload(api_objects) + url = self.api._build_url(endpoint(*args, **kwargs)) + return self.api._post(url, payload) + ''' + + #return CRUDRequest(self).post(article, create=True, id=section) + + def create(self, attribute_value_ids, id=None): + cr = CRUDRequest(self) + endpoint = cr.api.endpoint + url = cr.api._build_url(endpoint(id=id)) + payload = { + 'attribute_value_ids': [x.id for x in attribute_value_ids] + } + #import epdb; epdb.st() + return cr.api._post(url, payload) + + class RoutingAgentApi(CRUDApi): # defines the top level key for REST payloads @@ -1883,6 +1925,7 @@ class RoutingAgentApi(CRUDApi): def __init__(self, config): super(RoutingAgentApi, self).__init__(config, object_type=self.object_type) + self.instance_values = RoutingAgentInstanceValuesApi(config) class RoutingApi(CRUDApi): @@ -1892,26 +1935,6 @@ def __init__(self, config): self.agents = RoutingAgentApi(config) - ''' - def attributes(self): - # https://tannerjc2.zendesk.com/api/v2/routing/attributes.json - url = self._build_url(self.endpoint.attributes()) - print('\033[96m' + 'get url ' + url + '\033[0m') - #import epdb; epdb.st() - res = self._get(url) - #import epdb; epdb.st() - return res - ''' - - ''' - def values(self, attribute=None): - url = self._build_url(self.endpoint.attributes()) - url = url.replace('.json', '/' + attribute.id + '/values') - res = self._get(url) - #import epdb; epdb.st() - return res - ''' - class JiraLinkApi(CRUDApi): def __init__(self, config): super(JiraLinkApi, self).__init__(config, object_type='link') diff --git a/zenpy/lib/endpoint.py b/zenpy/lib/endpoint.py index e665875a..89b453cd 100644 --- a/zenpy/lib/endpoint.py +++ b/zenpy/lib/endpoint.py @@ -660,6 +660,7 @@ class Dummy(object): attribute_values = SecondaryEndpoint('routing/attributes/%(id)s/values.json') agents = PrimaryEndpoint('routing/agents') + attribute_value_ids = SecondaryEndpoint('routing/agents/%(id)s/instance_values.json') talk = Dummy() talk.calls = Dummy() diff --git a/zenpy/lib/mapping.py b/zenpy/lib/mapping.py index 7ad24568..bd534276 100644 --- a/zenpy/lib/mapping.py +++ b/zenpy/lib/mapping.py @@ -103,7 +103,8 @@ class ZendeskObjectMapping(object): 'attribute': RoutingAttribute, 'attribute_value': RoutingAttributeValue, 'value': RoutingAttributeValue, - 'instance_value': RoutingAttributeValue + 'instance_value': RoutingAttributeValue, + 'attribute_value_ids': RoutingAttributeValue } skip_attrs = [] From e5ddb279bed9d94bc97c4e5ae7065fc13d391768 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Fri, 26 Mar 2021 12:53:21 -0400 Subject: [PATCH 13/20] remove debug prints --- zenpy/lib/response.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/zenpy/lib/response.py b/zenpy/lib/response.py index 0eaa3917..4d54488b 100644 --- a/zenpy/lib/response.py +++ b/zenpy/lib/response.py @@ -332,13 +332,9 @@ def applies_to(api, response): return endpoint_path.startswith('/routing') def deserialize(self, response_json): - print('\033[96m' + 'rarh deserialize' + str(response_json) + '\033[0m') deserialized_response = super(RoutingResponseHandler, self).deserialize(response_json) - print('\033[96m' + 'rarh deserialized' + str(deserialized_response) + '\033[0m') - if 'attributes' in deserialized_response: - print('\033[96m' + 'rarh deserialize return ' + str(deserialized_response['attributes']) + '\033[0m') return deserialized_response['attributes'] elif 'attribute' in deserialized_response: return deserialized_response['attribute'] @@ -348,7 +344,6 @@ def deserialize(self, response_json): return deserialized_response['attribute_value'] def build(self, response): - print('\033[96m' + 'rarh build' + '\033[0m') return self.deserialize(response.json()) From f2db3b7cca2cd7ee911a547623fc1d8c4fc618f5 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Fri, 26 Mar 2021 12:54:40 -0400 Subject: [PATCH 14/20] cleanup --- zenpy/lib/api.py | 34 ++-------------------------------- 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/zenpy/lib/api.py b/zenpy/lib/api.py index ab5d950f..920fa81e 100644 --- a/zenpy/lib/api.py +++ b/zenpy/lib/api.py @@ -1876,45 +1876,15 @@ class RoutingAgentInstanceValuesApi(CRUDApi): def __init__(self, config): super(RoutingAgentInstanceValuesApi, self).__init__(config, object_type=self.object_type) - - ''' - class CRUDRequest(BaseZendeskRequest): - """ - Generic CRUD request. Most CRUD operations are handled by this class. - """ - def post(self, api_objects, *args, **kwargs): - self.check_type(api_objects) - - create_or_update = kwargs.pop('create_or_update', False) - create = kwargs.pop('create', False) - if isinstance(api_objects, Iterable) and create_or_update: - kwargs['create_or_update_many'] = True - endpoint = self.api.endpoint.create_or_update_many - elif isinstance(api_objects, Iterable): - kwargs['create_many'] = True - endpoint = self.api.endpoint - elif create_or_update: - endpoint = self.api.endpoint.create_or_update - elif create: - endpoint = self.api.endpoint.create - else: - endpoint = self.api.endpoint - - payload = self.build_payload(api_objects) - url = self.api._build_url(endpoint(*args, **kwargs)) - return self.api._post(url, payload) - ''' - - #return CRUDRequest(self).post(article, create=True, id=section) - def create(self, attribute_value_ids, id=None): + # bypass default crudrequest post so we can have + # direct control over payload creation ... cr = CRUDRequest(self) endpoint = cr.api.endpoint url = cr.api._build_url(endpoint(id=id)) payload = { 'attribute_value_ids': [x.id for x in attribute_value_ids] } - #import epdb; epdb.st() return cr.api._post(url, payload) From 9db65e7dcec8762c43d0c6ae5fe10f56842b9eb0 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Fri, 26 Mar 2021 13:55:39 -0400 Subject: [PATCH 15/20] test test? --- tests/test_api/test_routing_api.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/test_api/test_routing_api.py diff --git a/tests/test_api/test_routing_api.py b/tests/test_api/test_routing_api.py new file mode 100644 index 00000000..2d266211 --- /dev/null +++ b/tests/test_api/test_routing_api.py @@ -0,0 +1,12 @@ +from zenpy.lib.api_objects import RoutingAttribute +from test_api.fixtures import SingleCreateApiTestCase +from zenpy.lib.exception import ZenpyException + +# https://developer.zendesk.com/rest_api/docs/support/skill_based_routing + +class TestRoutingApi(SingleCreateApiTestCase): + __test__ = True + ZenpyType = RoutingAttribute + object_kwargs = dict(name='test_attribute') + api_name = 'routing.attributes' + From fb39b018b18f4c00cfc0157d1a5684276b2cf9e2 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Sun, 28 Mar 2021 22:16:17 -0400 Subject: [PATCH 16/20] test --- zenpy/lib/api_objects/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/zenpy/lib/api_objects/__init__.py b/zenpy/lib/api_objects/__init__.py index 0358d5e7..dc7729f7 100644 --- a/zenpy/lib/api_objects/__init__.py +++ b/zenpy/lib/api_objects/__init__.py @@ -2978,6 +2978,7 @@ def user(self, user): self._user = user + class RoutingAttribute(BaseObject): """ ###################################################################### From ae850a367e1a0dffb50426bedef44a3f434cf3c4 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Mon, 29 Mar 2021 10:30:49 -0400 Subject: [PATCH 17/20] remove debug print --- zenpy/lib/response.py | 1 - 1 file changed, 1 deletion(-) diff --git a/zenpy/lib/response.py b/zenpy/lib/response.py index 4d54488b..96929f02 100644 --- a/zenpy/lib/response.py +++ b/zenpy/lib/response.py @@ -20,7 +20,6 @@ class ResponseHandler(object): def __init__(self, api, object_mapping=None): self.api = api self.object_mapping = object_mapping or api._object_mapping - print('rh init') @staticmethod @abstractmethod From a8ad7a2ed6f8b6044ea5997fd28a806760ca6c1d Mon Sep 17 00:00:00 2001 From: James Tanner Date: Thu, 1 Apr 2021 11:59:35 -0400 Subject: [PATCH 18/20] add support for routing attribute definitions --- zenpy/lib/api.py | 13 +++++++++++++ zenpy/lib/endpoint.py | 4 ++++ zenpy/lib/response.py | 4 ++++ 3 files changed, 21 insertions(+) diff --git a/zenpy/lib/api.py b/zenpy/lib/api.py index 920fa81e..af279d70 100644 --- a/zenpy/lib/api.py +++ b/zenpy/lib/api.py @@ -1859,6 +1859,18 @@ def __init__(self, config, attribute=None): super(RoutingAttributeValueApi, self).__init__(config, object_type=self.object_type) +class RoutingAttributeDefinitionApi(CRUDApi): + + # defines the top level key for REST payloads + object_type = 'definition' + + # values are children of attributes, so an attribute must be passed + # to the constructor ... + def __init__(self, config, attribute=None): + print(f'# ATTRIBUTE {attribute}') + super(RoutingAttributeDefinitionApi, self).__init__(config, object_type=self.object_type) + + class RoutingAttributeApi(CRUDApi): # defines the top level key for REST payloads @@ -1867,6 +1879,7 @@ class RoutingAttributeApi(CRUDApi): def __init__(self, config): super(RoutingAttributeApi, self).__init__(config, object_type=self.object_type) self.values = RoutingAttributeValueApi(config) + self.definitions = RoutingAttributeDefinitionApi(config) class RoutingAgentInstanceValuesApi(CRUDApi): diff --git a/zenpy/lib/endpoint.py b/zenpy/lib/endpoint.py index 89b453cd..bbf7c6de 100644 --- a/zenpy/lib/endpoint.py +++ b/zenpy/lib/endpoint.py @@ -659,6 +659,10 @@ class Dummy(object): values = SecondaryEndpoint('routing/attributes/%(id)s/values.json') attribute_values = SecondaryEndpoint('routing/attributes/%(id)s/values.json') + # https://{subdomain}.zendesk.com/api/v2/routing/attributes/definitions.json + definitions = PrimaryEndpoint('routing/attributes/definitions.json') + attribute_definitions = PrimaryEndpoint('routing/attributes/definitions.json') + agents = PrimaryEndpoint('routing/agents') attribute_value_ids = SecondaryEndpoint('routing/agents/%(id)s/instance_values.json') diff --git a/zenpy/lib/response.py b/zenpy/lib/response.py index 96929f02..21e3c6c0 100644 --- a/zenpy/lib/response.py +++ b/zenpy/lib/response.py @@ -341,6 +341,10 @@ def deserialize(self, response_json): return deserialized_response['attribute_values'] elif 'attribute_value' in deserialized_response: return deserialized_response['attribute_value'] + elif 'definitions' in deserialized_response: + # definitions -> conditions_any + # definitions -> conditions_all + return deserialized_response['definitions'] def build(self, response): return self.deserialize(response.json()) From e1e6b2c9fbe9fef252349d449ab37105d609bd2f Mon Sep 17 00:00:00 2001 From: James Tanner Date: Mon, 12 Apr 2021 14:35:18 -0400 Subject: [PATCH 19/20] remove debug print --- zenpy/lib/api.py | 1 - 1 file changed, 1 deletion(-) diff --git a/zenpy/lib/api.py b/zenpy/lib/api.py index af279d70..d52c74e9 100644 --- a/zenpy/lib/api.py +++ b/zenpy/lib/api.py @@ -1855,7 +1855,6 @@ class RoutingAttributeValueApi(CRUDApi): # values are children of attributes, so an attribute must be passed # to the constructor ... def __init__(self, config, attribute=None): - print(f'# ATTRIBUTE {attribute}') super(RoutingAttributeValueApi, self).__init__(config, object_type=self.object_type) From b0e5b003b0fb624c4a782fe9b5c84c3e73b65202 Mon Sep 17 00:00:00 2001 From: James Tanner Date: Thu, 15 Apr 2021 18:07:05 -0400 Subject: [PATCH 20/20] undo change to api.py:_get --- zenpy/lib/api.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/zenpy/lib/api.py b/zenpy/lib/api.py index d52c74e9..382524cc 100644 --- a/zenpy/lib/api.py +++ b/zenpy/lib/api.py @@ -102,12 +102,15 @@ def _delete(self, url, payload=None): timeout=self.timeout) return self._process_response(response) - def _get(self, url, **kwargs): + def _get(self, url, raw_response=False, **kwargs): response = self._call_api(self.session.get, url, timeout=self.timeout, **kwargs) - return self._process_response(response) + if raw_response: + return response + else: + return self._process_response(response) def _call_api(self, http_method, url, **kwargs): """