We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Fix logging TypeError (digitalocean.py)
[This same issue](https://github.com/AnalogJ/lexicon/pull/128/commits/903af58378ab9942d817c57e0330b5f7ac26b4e9) exists in `lexicon/providers/digitalocean.py` line 111. The same edit is needed to fix it. 

The error generated is:
```
Traceback (most recent call last):
  File "/usr/lib/python2.7/logging/__init__.py", line 861, in emit
    msg = self.format(record)
  File "/usr/lib/python2.7/logging/__init__.py", line 734, in format
    return fmt.format(record)
  File "/usr/lib/python2.7/logging/__init__.py", line 465, in format
    record.message = record.getMessage()
  File "/usr/lib/python2.7/logging/__init__.py", line 329, in getMessage
    msg = msg % self.args
TypeError: not all arguments converted during string formatting
Logged from file digitalocean.py, line 111
```
That section is:
```
 Line 110: # is always True at this point, if a non 200 response is returned an error is raised.
 Line 111: logger.debug('delete_record: {0}', True)
 Line 112: return True
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `lexicon/providers/digitalocean.py`
Content:
```
1 from __future__ import absolute_import
2 from __future__ import print_function
3 
4 import json
5 import logging
6 
7 import requests
8 
9 from .base import Provider as BaseProvider
10 
11 logger = logging.getLogger(__name__)
12 
13 
14 def ProviderParser(subparser):
15     subparser.add_argument("--auth-token", help="specify token used authenticate to DNS provider")
16 
17 class Provider(BaseProvider):
18 
19     def __init__(self, options, engine_overrides=None):
20         super(Provider, self).__init__(options, engine_overrides)
21         self.domain_id = None
22         self.api_endpoint = self.engine_overrides.get('api_endpoint', 'https://api.digitalocean.com/v2')
23 
24     def authenticate(self):
25 
26         payload = self._get('/domains/{0}'.format(self.options['domain']))
27         self.domain_id = self.options['domain']
28 
29     def create_record(self, type, name, content):
30         record = {
31             'type': type,
32             'name': self._relative_name(name),
33             'data': content,
34 
35         }
36         if type == 'CNAME':
37             record['data'] = record['data'].rstrip('.') + '.' # make sure a the data is always a FQDN for CNAMe.
38 
39         payload = self._post('/domains/{0}/records'.format(self.domain_id), record)
40 
41         logger.debug('create_record: %s', True)
42         return True
43 
44     # List all records. Return an empty list if no records found
45     # type, name and content are used to filter records.
46     # If possible filter during the query, otherwise filter after response is received.
47     def list_records(self, type=None, name=None, content=None):
48         url = '/domains/{0}/records'.format(self.domain_id)
49         records = []
50         payload = {}
51 
52         next = url
53         while next is not None:
54             payload = self._get(next)
55             if 'links' in payload \
56                     and 'pages' in payload['links'] \
57                     and 'next' in payload['links']['pages']:
58                 next = payload['links']['pages']['next']
59             else:
60                 next = None
61 
62             for record in payload['domain_records']:
63                 processed_record = {
64                     'type': record['type'],
65                     'name': "{0}.{1}".format(record['name'], self.domain_id),
66                     'ttl': '',
67                     'content': record['data'],
68                     'id': record['id']
69                 }
70                 records.append(processed_record)
71 
72         if type:
73             records = [record for record in records if record['type'] == type]
74         if name:
75             records = [record for record in records if record['name'] == self._full_name(name)]
76         if content:
77             records = [record for record in records if record['content'].lower() == content.lower()]
78 
79         logger.debug('list_records: %s', records)
80         return records
81 
82     # Create or update a record.
83     def update_record(self, identifier, type=None, name=None, content=None):
84 
85         data = {}
86         if type:
87             data['type'] = type
88         if name:
89             data['name'] = self._relative_name(name)
90         if content:
91             data['data'] = content
92 
93         payload = self._put('/domains/{0}/records/{1}'.format(self.domain_id, identifier), data)
94 
95         logger.debug('update_record: %s', True)
96         return True
97 
98     # Delete an existing record.
99     # If record does not exist, do nothing.
100     def delete_record(self, identifier=None, type=None, name=None, content=None):
101         if not identifier:
102             records = self.list_records(type, name, content)
103             logger.debug('records: %s', records)
104             if len(records) == 1:
105                 identifier = records[0]['id']
106             else:
107                 raise Exception('Record identifier could not be found.')
108         payload = self._delete('/domains/{0}/records/{1}'.format(self.domain_id, identifier))
109 
110         # is always True at this point, if a non 200 response is returned an error is raised.
111         logger.debug('delete_record: {0}', True)
112         return True
113 
114 
115     # Helpers
116     def _request(self, action='GET',  url='/', data=None, query_params=None):
117         if data is None:
118             data = {}
119         if query_params is None:
120             query_params = {}
121         default_headers = {
122             'Accept': 'application/json',
123             'Content-Type': 'application/json',
124             'Authorization': 'Bearer {0}'.format(self.options.get('auth_token'))
125         }
126         if not url.startswith(self.api_endpoint):
127             url = self.api_endpoint + url
128 
129         r = requests.request(action, url, params=query_params,
130                              data=json.dumps(data),
131                              headers=default_headers)
132         r.raise_for_status()  # if the request fails for any reason, throw an error.
133         if action == 'DELETE':
134             return ''
135         else:
136             return r.json()
137
```

Path: `lexicon/providers/dnsmadeeasy.py`
Content:
```
1 from __future__ import absolute_import
2 from __future__ import print_function
3 
4 import contextlib
5 import datetime
6 import hmac
7 import json
8 import locale
9 import logging
10 from hashlib import sha1
11 
12 import requests
13 from builtins import bytes
14 
15 from .base import Provider as BaseProvider
16 
17 logger = logging.getLogger(__name__)
18 
19 
20 def ProviderParser(subparser):
21     subparser.add_argument("--auth-username", help="specify username used to authenticate")
22     subparser.add_argument("--auth-token", help="specify token used authenticate=")
23 
24 class Provider(BaseProvider):
25 
26     def __init__(self, options, engine_overrides=None):
27         super(Provider, self).__init__(options, engine_overrides)
28         self.domain_id = None
29         self.api_endpoint = self.engine_overrides.get('api_endpoint', 'https://api.dnsmadeeasy.com/V2.0')
30 
31     def authenticate(self):
32 
33         try:
34             payload = self._get('/dns/managed/name', {'domainname': self.options['domain']})
35         except requests.exceptions.HTTPError as e:
36             if e.response.status_code == 404:
37                 payload = {}
38             else:
39                 raise e
40 
41         if not payload or not payload['id']:
42             raise Exception('No domain found')
43 
44         self.domain_id = payload['id']
45 
46 
47     # Create record. If record already exists with the same content, do nothing'
48     def create_record(self, type, name, content):
49         record = {
50             'type': type,
51             'name': self._relative_name(name),
52             'value': content,
53             'ttl': self.options['ttl']
54         }
55         payload = {}
56         try:
57             payload = self._post('/dns/managed/{0}/records/'.format(self.domain_id), record)
58         except requests.exceptions.HTTPError as e:
59             if e.response.status_code == 400:
60                 payload = {}
61 
62                 # http 400 is ok here, because the record probably already exists
63         logger.debug('create_record: %s', 'name' in payload)
64         return 'name' in payload
65 
66     # List all records. Return an empty list if no records found
67     # type, name and content are used to filter records.
68     # If possible filter during the query, otherwise filter after response is received.
69     def list_records(self, type=None, name=None, content=None):
70         filter = {}
71         if type:
72             filter['type'] = type
73         if name:
74             filter['recordName'] = self._relative_name(name)
75         payload = self._get('/dns/managed/{0}/records'.format(self.domain_id), filter)
76 
77         records = []
78         for record in payload['data']:
79             processed_record = {
80                 'type': record['type'],
81                 'name': '{0}.{1}'.format(record['name'], self.options['domain']),
82                 'ttl': record['ttl'],
83                 'content': record['value'],
84                 'id': record['id']
85             }
86 
87             processed_record = self._clean_TXT_record(processed_record)
88             records.append(processed_record)
89 
90         logger.debug('list_records: %s', records)
91         return records
92 
93     # Create or update a record.
94     def update_record(self, identifier, type=None, name=None, content=None):
95 
96         data = {
97             'id': identifier,
98             'ttl': self.options['ttl']
99         }
100 
101         if name:
102             data['name'] = self._relative_name(name)
103         if content:
104             data['value'] = content
105         if type:
106             data['type'] = type
107 
108         payload = self._put('/dns/managed/{0}/records/{1}'.format(self.domain_id, identifier), data)
109 
110         logger.debug('update_record: {0}', True)
111         return True
112 
113     # Delete an existing record.
114     # If record does not exist, do nothing.
115     def delete_record(self, identifier=None, type=None, name=None, content=None):
116         if not identifier:
117             records = self.list_records(type, name, content)
118             logger.debug('records: %s', records)
119             if len(records) == 1:
120                 identifier = records[0]['id']
121             else:
122                 raise Exception('Record identifier could not be found.')
123         payload = self._delete('/dns/managed/{0}/records/{1}'.format(self.domain_id, identifier))
124 
125         # is always True at this point, if a non 200 response is returned an error is raised.
126         logger.debug('delete_record: %s', True)
127         return True
128 
129 
130     # Helpers
131 
132     # this method allows you to set the locale when doing datetime string formatting.
133     # https://stackoverflow.com/questions/18593661/how-do-i-strftime-a-date-object-in-a-different-locale
134     @contextlib.contextmanager
135     def setlocale(self, *args, **kw):
136         saved = locale.setlocale(locale.LC_ALL)
137         #yield locale.setlocale(*args, **kw)
138         yield locale.setlocale(locale.LC_TIME, 'en_US.UTF-8')
139         locale.setlocale(locale.LC_ALL, saved)
140 
141     def _request(self, action='GET',  url='/', data=None, query_params=None):
142         if data is None:
143             data = {}
144         if query_params is None:
145             query_params = {}
146         default_headers = {
147             'Accept': 'application/json',
148             'Content-Type': 'application/json',
149             'x-dnsme-apiKey': self.options['auth_username']
150         }
151         default_auth = None
152 
153         # all requests require a HMAC header and timestamp header.
154         now = datetime.datetime.utcnow()
155         # required format: Sat, 12 Feb 2011 20:59:04 GMT
156         with self.setlocale(locale.LC_TIME, 'en_US.utf8'):
157             request_date = now.strftime('%a, %d %b %Y %H:%M:%S GMT')
158             hashed = hmac.new(bytes(self.options['auth_token'], 'ascii'), 
159                               bytes(request_date, 'ascii'), sha1)
160 
161             default_headers['x-dnsme-requestDate'] = request_date
162             default_headers['x-dnsme-hmac'] = hashed.hexdigest()
163 
164         r = requests.request(action, self.api_endpoint + url, params=query_params,
165                              data=json.dumps(data),
166                              headers=default_headers,
167                              auth=default_auth)
168         r.raise_for_status()  # if the request fails for any reason, throw an error.
169 
170         # PUT and DELETE actions dont return valid json.
171         if action == 'DELETE' or action == 'PUT':
172             return r.text
173         return r.json()
174
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/lexicon/providers/digitalocean.py b/lexicon/providers/digitalocean.py
--- a/lexicon/providers/digitalocean.py
+++ b/lexicon/providers/digitalocean.py
@@ -108,7 +108,7 @@
         payload = self._delete('/domains/{0}/records/{1}'.format(self.domain_id, identifier))
 
         # is always True at this point, if a non 200 response is returned an error is raised.
-        logger.debug('delete_record: {0}', True)
+        logger.debug('delete_record: %s', True)
         return True
 
 
diff --git a/lexicon/providers/dnsmadeeasy.py b/lexicon/providers/dnsmadeeasy.py
--- a/lexicon/providers/dnsmadeeasy.py
+++ b/lexicon/providers/dnsmadeeasy.py
@@ -107,7 +107,7 @@
 
         payload = self._put('/dns/managed/{0}/records/{1}'.format(self.domain_id, identifier), data)
 
-        logger.debug('update_record: {0}', True)
+        logger.debug('update_record: %s', True)
         return True
 
     # Delete an existing record.

{"golden_diff": "diff --git a/lexicon/providers/digitalocean.py b/lexicon/providers/digitalocean.py\n--- a/lexicon/providers/digitalocean.py\n+++ b/lexicon/providers/digitalocean.py\n@@ -108,7 +108,7 @@\n         payload = self._delete('/domains/{0}/records/{1}'.format(self.domain_id, identifier))\n \n         # is always True at this point, if a non 200 response is returned an error is raised.\n-        logger.debug('delete_record: {0}', True)\n+        logger.debug('delete_record: %s', True)\n         return True\n \n \ndiff --git a/lexicon/providers/dnsmadeeasy.py b/lexicon/providers/dnsmadeeasy.py\n--- a/lexicon/providers/dnsmadeeasy.py\n+++ b/lexicon/providers/dnsmadeeasy.py\n@@ -107,7 +107,7 @@\n \n         payload = self._put('/dns/managed/{0}/records/{1}'.format(self.domain_id, identifier), data)\n \n-        logger.debug('update_record: {0}', True)\n+        logger.debug('update_record: %s', True)\n         return True\n \n     # Delete an existing record.\n", "issue": "Fix logging TypeError (digitalocean.py)\n[This same issue](https://github.com/AnalogJ/lexicon/pull/128/commits/903af58378ab9942d817c57e0330b5f7ac26b4e9) exists in `lexicon/providers/digitalocean.py` line 111. The same edit is needed to fix it. \r\n\r\nThe error generated is:\r\n```\r\nTraceback (most recent call last):\r\n  File \"/usr/lib/python2.7/logging/__init__.py\", line 861, in emit\r\n    msg = self.format(record)\r\n  File \"/usr/lib/python2.7/logging/__init__.py\", line 734, in format\r\n    return fmt.format(record)\r\n  File \"/usr/lib/python2.7/logging/__init__.py\", line 465, in format\r\n    record.message = record.getMessage()\r\n  File \"/usr/lib/python2.7/logging/__init__.py\", line 329, in getMessage\r\n    msg = msg % self.args\r\nTypeError: not all arguments converted during string formatting\r\nLogged from file digitalocean.py, line 111\r\n```\r\nThat section is:\r\n```\r\n Line 110: # is always True at this point, if a non 200 response is returned an error is raised.\r\n Line 111: logger.debug('delete_record: {0}', True)\r\n Line 112: return True\r\n```\n", "before_files": [{"content": "from __future__ import absolute_import\nfrom __future__ import print_function\n\nimport json\nimport logging\n\nimport requests\n\nfrom .base import Provider as BaseProvider\n\nlogger = logging.getLogger(__name__)\n\n\ndef ProviderParser(subparser):\n    subparser.add_argument(\"--auth-token\", help=\"specify token used authenticate to DNS provider\")\n\nclass Provider(BaseProvider):\n\n    def __init__(self, options, engine_overrides=None):\n        super(Provider, self).__init__(options, engine_overrides)\n        self.domain_id = None\n        self.api_endpoint = self.engine_overrides.get('api_endpoint', 'https://api.digitalocean.com/v2')\n\n    def authenticate(self):\n\n        payload = self._get('/domains/{0}'.format(self.options['domain']))\n        self.domain_id = self.options['domain']\n\n    def create_record(self, type, name, content):\n        record = {\n            'type': type,\n            'name': self._relative_name(name),\n            'data': content,\n\n        }\n        if type == 'CNAME':\n            record['data'] = record['data'].rstrip('.') + '.' # make sure a the data is always a FQDN for CNAMe.\n\n        payload = self._post('/domains/{0}/records'.format(self.domain_id), record)\n\n        logger.debug('create_record: %s', True)\n        return True\n\n    # List all records. Return an empty list if no records found\n    # type, name and content are used to filter records.\n    # If possible filter during the query, otherwise filter after response is received.\n    def list_records(self, type=None, name=None, content=None):\n        url = '/domains/{0}/records'.format(self.domain_id)\n        records = []\n        payload = {}\n\n        next = url\n        while next is not None:\n            payload = self._get(next)\n            if 'links' in payload \\\n                    and 'pages' in payload['links'] \\\n                    and 'next' in payload['links']['pages']:\n                next = payload['links']['pages']['next']\n            else:\n                next = None\n\n            for record in payload['domain_records']:\n                processed_record = {\n                    'type': record['type'],\n                    'name': \"{0}.{1}\".format(record['name'], self.domain_id),\n                    'ttl': '',\n                    'content': record['data'],\n                    'id': record['id']\n                }\n                records.append(processed_record)\n\n        if type:\n            records = [record for record in records if record['type'] == type]\n        if name:\n            records = [record for record in records if record['name'] == self._full_name(name)]\n        if content:\n            records = [record for record in records if record['content'].lower() == content.lower()]\n\n        logger.debug('list_records: %s', records)\n        return records\n\n    # Create or update a record.\n    def update_record(self, identifier, type=None, name=None, content=None):\n\n        data = {}\n        if type:\n            data['type'] = type\n        if name:\n            data['name'] = self._relative_name(name)\n        if content:\n            data['data'] = content\n\n        payload = self._put('/domains/{0}/records/{1}'.format(self.domain_id, identifier), data)\n\n        logger.debug('update_record: %s', True)\n        return True\n\n    # Delete an existing record.\n    # If record does not exist, do nothing.\n    def delete_record(self, identifier=None, type=None, name=None, content=None):\n        if not identifier:\n            records = self.list_records(type, name, content)\n            logger.debug('records: %s', records)\n            if len(records) == 1:\n                identifier = records[0]['id']\n            else:\n                raise Exception('Record identifier could not be found.')\n        payload = self._delete('/domains/{0}/records/{1}'.format(self.domain_id, identifier))\n\n        # is always True at this point, if a non 200 response is returned an error is raised.\n        logger.debug('delete_record: {0}', True)\n        return True\n\n\n    # Helpers\n    def _request(self, action='GET',  url='/', data=None, query_params=None):\n        if data is None:\n            data = {}\n        if query_params is None:\n            query_params = {}\n        default_headers = {\n            'Accept': 'application/json',\n            'Content-Type': 'application/json',\n            'Authorization': 'Bearer {0}'.format(self.options.get('auth_token'))\n        }\n        if not url.startswith(self.api_endpoint):\n            url = self.api_endpoint + url\n\n        r = requests.request(action, url, params=query_params,\n                             data=json.dumps(data),\n                             headers=default_headers)\n        r.raise_for_status()  # if the request fails for any reason, throw an error.\n        if action == 'DELETE':\n            return ''\n        else:\n            return r.json()\n", "path": "lexicon/providers/digitalocean.py"}, {"content": "from __future__ import absolute_import\nfrom __future__ import print_function\n\nimport contextlib\nimport datetime\nimport hmac\nimport json\nimport locale\nimport logging\nfrom hashlib import sha1\n\nimport requests\nfrom builtins import bytes\n\nfrom .base import Provider as BaseProvider\n\nlogger = logging.getLogger(__name__)\n\n\ndef ProviderParser(subparser):\n    subparser.add_argument(\"--auth-username\", help=\"specify username used to authenticate\")\n    subparser.add_argument(\"--auth-token\", help=\"specify token used authenticate=\")\n\nclass Provider(BaseProvider):\n\n    def __init__(self, options, engine_overrides=None):\n        super(Provider, self).__init__(options, engine_overrides)\n        self.domain_id = None\n        self.api_endpoint = self.engine_overrides.get('api_endpoint', 'https://api.dnsmadeeasy.com/V2.0')\n\n    def authenticate(self):\n\n        try:\n            payload = self._get('/dns/managed/name', {'domainname': self.options['domain']})\n        except requests.exceptions.HTTPError as e:\n            if e.response.status_code == 404:\n                payload = {}\n            else:\n                raise e\n\n        if not payload or not payload['id']:\n            raise Exception('No domain found')\n\n        self.domain_id = payload['id']\n\n\n    # Create record. If record already exists with the same content, do nothing'\n    def create_record(self, type, name, content):\n        record = {\n            'type': type,\n            'name': self._relative_name(name),\n            'value': content,\n            'ttl': self.options['ttl']\n        }\n        payload = {}\n        try:\n            payload = self._post('/dns/managed/{0}/records/'.format(self.domain_id), record)\n        except requests.exceptions.HTTPError as e:\n            if e.response.status_code == 400:\n                payload = {}\n\n                # http 400 is ok here, because the record probably already exists\n        logger.debug('create_record: %s', 'name' in payload)\n        return 'name' in payload\n\n    # List all records. Return an empty list if no records found\n    # type, name and content are used to filter records.\n    # If possible filter during the query, otherwise filter after response is received.\n    def list_records(self, type=None, name=None, content=None):\n        filter = {}\n        if type:\n            filter['type'] = type\n        if name:\n            filter['recordName'] = self._relative_name(name)\n        payload = self._get('/dns/managed/{0}/records'.format(self.domain_id), filter)\n\n        records = []\n        for record in payload['data']:\n            processed_record = {\n                'type': record['type'],\n                'name': '{0}.{1}'.format(record['name'], self.options['domain']),\n                'ttl': record['ttl'],\n                'content': record['value'],\n                'id': record['id']\n            }\n\n            processed_record = self._clean_TXT_record(processed_record)\n            records.append(processed_record)\n\n        logger.debug('list_records: %s', records)\n        return records\n\n    # Create or update a record.\n    def update_record(self, identifier, type=None, name=None, content=None):\n\n        data = {\n            'id': identifier,\n            'ttl': self.options['ttl']\n        }\n\n        if name:\n            data['name'] = self._relative_name(name)\n        if content:\n            data['value'] = content\n        if type:\n            data['type'] = type\n\n        payload = self._put('/dns/managed/{0}/records/{1}'.format(self.domain_id, identifier), data)\n\n        logger.debug('update_record: {0}', True)\n        return True\n\n    # Delete an existing record.\n    # If record does not exist, do nothing.\n    def delete_record(self, identifier=None, type=None, name=None, content=None):\n        if not identifier:\n            records = self.list_records(type, name, content)\n            logger.debug('records: %s', records)\n            if len(records) == 1:\n                identifier = records[0]['id']\n            else:\n                raise Exception('Record identifier could not be found.')\n        payload = self._delete('/dns/managed/{0}/records/{1}'.format(self.domain_id, identifier))\n\n        # is always True at this point, if a non 200 response is returned an error is raised.\n        logger.debug('delete_record: %s', True)\n        return True\n\n\n    # Helpers\n\n    # this method allows you to set the locale when doing datetime string formatting.\n    # https://stackoverflow.com/questions/18593661/how-do-i-strftime-a-date-object-in-a-different-locale\n    @contextlib.contextmanager\n    def setlocale(self, *args, **kw):\n        saved = locale.setlocale(locale.LC_ALL)\n        #yield locale.setlocale(*args, **kw)\n        yield locale.setlocale(locale.LC_TIME, 'en_US.UTF-8')\n        locale.setlocale(locale.LC_ALL, saved)\n\n    def _request(self, action='GET',  url='/', data=None, query_params=None):\n        if data is None:\n            data = {}\n        if query_params is None:\n            query_params = {}\n        default_headers = {\n            'Accept': 'application/json',\n            'Content-Type': 'application/json',\n            'x-dnsme-apiKey': self.options['auth_username']\n        }\n        default_auth = None\n\n        # all requests require a HMAC header and timestamp header.\n        now = datetime.datetime.utcnow()\n        # required format: Sat, 12 Feb 2011 20:59:04 GMT\n        with self.setlocale(locale.LC_TIME, 'en_US.utf8'):\n            request_date = now.strftime('%a, %d %b %Y %H:%M:%S GMT')\n            hashed = hmac.new(bytes(self.options['auth_token'], 'ascii'), \n                              bytes(request_date, 'ascii'), sha1)\n\n            default_headers['x-dnsme-requestDate'] = request_date\n            default_headers['x-dnsme-hmac'] = hashed.hexdigest()\n\n        r = requests.request(action, self.api_endpoint + url, params=query_params,\n                             data=json.dumps(data),\n                             headers=default_headers,\n                             auth=default_auth)\n        r.raise_for_status()  # if the request fails for any reason, throw an error.\n\n        # PUT and DELETE actions dont return valid json.\n        if action == 'DELETE' or action == 'PUT':\n            return r.text\n        return r.json()\n", "path": "lexicon/providers/dnsmadeeasy.py"}], "after_files": [{"content": "from __future__ import absolute_import\nfrom __future__ import print_function\n\nimport json\nimport logging\n\nimport requests\n\nfrom .base import Provider as BaseProvider\n\nlogger = logging.getLogger(__name__)\n\n\ndef ProviderParser(subparser):\n    subparser.add_argument(\"--auth-token\", help=\"specify token used authenticate to DNS provider\")\n\nclass Provider(BaseProvider):\n\n    def __init__(self, options, engine_overrides=None):\n        super(Provider, self).__init__(options, engine_overrides)\n        self.domain_id = None\n        self.api_endpoint = self.engine_overrides.get('api_endpoint', 'https://api.digitalocean.com/v2')\n\n    def authenticate(self):\n\n        payload = self._get('/domains/{0}'.format(self.options['domain']))\n        self.domain_id = self.options['domain']\n\n    def create_record(self, type, name, content):\n        record = {\n            'type': type,\n            'name': self._relative_name(name),\n            'data': content,\n\n        }\n        if type == 'CNAME':\n            record['data'] = record['data'].rstrip('.') + '.' # make sure a the data is always a FQDN for CNAMe.\n\n        payload = self._post('/domains/{0}/records'.format(self.domain_id), record)\n\n        logger.debug('create_record: %s', True)\n        return True\n\n    # List all records. Return an empty list if no records found\n    # type, name and content are used to filter records.\n    # If possible filter during the query, otherwise filter after response is received.\n    def list_records(self, type=None, name=None, content=None):\n        url = '/domains/{0}/records'.format(self.domain_id)\n        records = []\n        payload = {}\n\n        next = url\n        while next is not None:\n            payload = self._get(next)\n            if 'links' in payload \\\n                    and 'pages' in payload['links'] \\\n                    and 'next' in payload['links']['pages']:\n                next = payload['links']['pages']['next']\n            else:\n                next = None\n\n            for record in payload['domain_records']:\n                processed_record = {\n                    'type': record['type'],\n                    'name': \"{0}.{1}\".format(record['name'], self.domain_id),\n                    'ttl': '',\n                    'content': record['data'],\n                    'id': record['id']\n                }\n                records.append(processed_record)\n\n        if type:\n            records = [record for record in records if record['type'] == type]\n        if name:\n            records = [record for record in records if record['name'] == self._full_name(name)]\n        if content:\n            records = [record for record in records if record['content'].lower() == content.lower()]\n\n        logger.debug('list_records: %s', records)\n        return records\n\n    # Create or update a record.\n    def update_record(self, identifier, type=None, name=None, content=None):\n\n        data = {}\n        if type:\n            data['type'] = type\n        if name:\n            data['name'] = self._relative_name(name)\n        if content:\n            data['data'] = content\n\n        payload = self._put('/domains/{0}/records/{1}'.format(self.domain_id, identifier), data)\n\n        logger.debug('update_record: %s', True)\n        return True\n\n    # Delete an existing record.\n    # If record does not exist, do nothing.\n    def delete_record(self, identifier=None, type=None, name=None, content=None):\n        if not identifier:\n            records = self.list_records(type, name, content)\n            logger.debug('records: %s', records)\n            if len(records) == 1:\n                identifier = records[0]['id']\n            else:\n                raise Exception('Record identifier could not be found.')\n        payload = self._delete('/domains/{0}/records/{1}'.format(self.domain_id, identifier))\n\n        # is always True at this point, if a non 200 response is returned an error is raised.\n        logger.debug('delete_record: %s', True)\n        return True\n\n\n    # Helpers\n    def _request(self, action='GET',  url='/', data=None, query_params=None):\n        if data is None:\n            data = {}\n        if query_params is None:\n            query_params = {}\n        default_headers = {\n            'Accept': 'application/json',\n            'Content-Type': 'application/json',\n            'Authorization': 'Bearer {0}'.format(self.options.get('auth_token'))\n        }\n        if not url.startswith(self.api_endpoint):\n            url = self.api_endpoint + url\n\n        r = requests.request(action, url, params=query_params,\n                             data=json.dumps(data),\n                             headers=default_headers)\n        r.raise_for_status()  # if the request fails for any reason, throw an error.\n        if action == 'DELETE':\n            return ''\n        else:\n            return r.json()\n", "path": "lexicon/providers/digitalocean.py"}, {"content": "from __future__ import absolute_import\nfrom __future__ import print_function\n\nimport contextlib\nimport datetime\nimport hmac\nimport json\nimport locale\nimport logging\nfrom hashlib import sha1\n\nimport requests\nfrom builtins import bytes\n\nfrom .base import Provider as BaseProvider\n\nlogger = logging.getLogger(__name__)\n\n\ndef ProviderParser(subparser):\n    subparser.add_argument(\"--auth-username\", help=\"specify username used to authenticate\")\n    subparser.add_argument(\"--auth-token\", help=\"specify token used authenticate=\")\n\nclass Provider(BaseProvider):\n\n    def __init__(self, options, engine_overrides=None):\n        super(Provider, self).__init__(options, engine_overrides)\n        self.domain_id = None\n        self.api_endpoint = self.engine_overrides.get('api_endpoint', 'https://api.dnsmadeeasy.com/V2.0')\n\n    def authenticate(self):\n\n        try:\n            payload = self._get('/dns/managed/name', {'domainname': self.options['domain']})\n        except requests.exceptions.HTTPError as e:\n            if e.response.status_code == 404:\n                payload = {}\n            else:\n                raise e\n\n        if not payload or not payload['id']:\n            raise Exception('No domain found')\n\n        self.domain_id = payload['id']\n\n\n    # Create record. If record already exists with the same content, do nothing'\n    def create_record(self, type, name, content):\n        record = {\n            'type': type,\n            'name': self._relative_name(name),\n            'value': content,\n            'ttl': self.options['ttl']\n        }\n        payload = {}\n        try:\n            payload = self._post('/dns/managed/{0}/records/'.format(self.domain_id), record)\n        except requests.exceptions.HTTPError as e:\n            if e.response.status_code == 400:\n                payload = {}\n\n                # http 400 is ok here, because the record probably already exists\n        logger.debug('create_record: %s', 'name' in payload)\n        return 'name' in payload\n\n    # List all records. Return an empty list if no records found\n    # type, name and content are used to filter records.\n    # If possible filter during the query, otherwise filter after response is received.\n    def list_records(self, type=None, name=None, content=None):\n        filter = {}\n        if type:\n            filter['type'] = type\n        if name:\n            filter['recordName'] = self._relative_name(name)\n        payload = self._get('/dns/managed/{0}/records'.format(self.domain_id), filter)\n\n        records = []\n        for record in payload['data']:\n            processed_record = {\n                'type': record['type'],\n                'name': '{0}.{1}'.format(record['name'], self.options['domain']),\n                'ttl': record['ttl'],\n                'content': record['value'],\n                'id': record['id']\n            }\n\n            processed_record = self._clean_TXT_record(processed_record)\n            records.append(processed_record)\n\n        logger.debug('list_records: %s', records)\n        return records\n\n    # Create or update a record.\n    def update_record(self, identifier, type=None, name=None, content=None):\n\n        data = {\n            'id': identifier,\n            'ttl': self.options['ttl']\n        }\n\n        if name:\n            data['name'] = self._relative_name(name)\n        if content:\n            data['value'] = content\n        if type:\n            data['type'] = type\n\n        payload = self._put('/dns/managed/{0}/records/{1}'.format(self.domain_id, identifier), data)\n\n        logger.debug('update_record: %s', True)\n        return True\n\n    # Delete an existing record.\n    # If record does not exist, do nothing.\n    def delete_record(self, identifier=None, type=None, name=None, content=None):\n        if not identifier:\n            records = self.list_records(type, name, content)\n            logger.debug('records: %s', records)\n            if len(records) == 1:\n                identifier = records[0]['id']\n            else:\n                raise Exception('Record identifier could not be found.')\n        payload = self._delete('/dns/managed/{0}/records/{1}'.format(self.domain_id, identifier))\n\n        # is always True at this point, if a non 200 response is returned an error is raised.\n        logger.debug('delete_record: %s', True)\n        return True\n\n\n    # Helpers\n\n    # this method allows you to set the locale when doing datetime string formatting.\n    # https://stackoverflow.com/questions/18593661/how-do-i-strftime-a-date-object-in-a-different-locale\n    @contextlib.contextmanager\n    def setlocale(self, *args, **kw):\n        saved = locale.setlocale(locale.LC_ALL)\n        #yield locale.setlocale(*args, **kw)\n        yield locale.setlocale(locale.LC_TIME, 'en_US.UTF-8')\n        locale.setlocale(locale.LC_ALL, saved)\n\n    def _request(self, action='GET',  url='/', data=None, query_params=None):\n        if data is None:\n            data = {}\n        if query_params is None:\n            query_params = {}\n        default_headers = {\n            'Accept': 'application/json',\n            'Content-Type': 'application/json',\n            'x-dnsme-apiKey': self.options['auth_username']\n        }\n        default_auth = None\n\n        # all requests require a HMAC header and timestamp header.\n        now = datetime.datetime.utcnow()\n        # required format: Sat, 12 Feb 2011 20:59:04 GMT\n        with self.setlocale(locale.LC_TIME, 'en_US.utf8'):\n            request_date = now.strftime('%a, %d %b %Y %H:%M:%S GMT')\n            hashed = hmac.new(bytes(self.options['auth_token'], 'ascii'), \n                              bytes(request_date, 'ascii'), sha1)\n\n            default_headers['x-dnsme-requestDate'] = request_date\n            default_headers['x-dnsme-hmac'] = hashed.hexdigest()\n\n        r = requests.request(action, self.api_endpoint + url, params=query_params,\n                             data=json.dumps(data),\n                             headers=default_headers,\n                             auth=default_auth)\n        r.raise_for_status()  # if the request fails for any reason, throw an error.\n\n        # PUT and DELETE actions dont return valid json.\n        if action == 'DELETE' or action == 'PUT':\n            return r.text\n        return r.json()\n", "path": "lexicon/providers/dnsmadeeasy.py"}]}