We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[APP SUBMITTED]: AttributeError: 'module' object has no attribute 'core'

### INFO
**Python Version**: `2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:53:40) [MSC v.1500 64 bit (AMD64)]`
**Operating System**: `Windows-7-6.1.7601-SP1`
**Locale**: `cp1252`
**Branch**: [master](../tree/master)
**Database**: `44.9`
**Commit**: pymedusa/Medusa@77b20916ab577b82112ebc624f816054788c63f2
**Link to Log**: https://gist.github.com/7f6099e1c66cecd44e069bffee91a3ac
### ERROR
<pre>
2018-04-23 16:08:49 ERROR    Thread_18 :: [77b2091] Exception generated: 'module' object has no attribute 'core'
Traceback (most recent call last):
  File "C:\Medusa\Medusa\medusa\server\web\core\base.py", line 285, in async_call
    result = function(**kwargs)
  File "C:\Medusa\Medusa\medusa\server\web\home\handler.py", line 357, in testGrowl
    result = notifiers.growl_notifier.test_notify(host, password)
  File "C:\Medusa\Medusa\medusa\notifiers\growl.py", line 22, in test_notify
    self._sendRegistration(host, password)
  File "C:\Medusa\Medusa\medusa\notifiers\growl.py", line 174, in _sendRegistration
    register = gntp.core.GNTPRegister()
AttributeError: 'module' object has no attribute 'core'
</pre>
---
_STAFF NOTIFIED_: @pymedusa/support @pymedusa/moderators


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `medusa/notifiers/growl.py`
Content:
```
1 # coding=utf-8
2 
3 from __future__ import print_function
4 from __future__ import unicode_literals
5 
6 import logging
7 import socket
8 from builtins import object
9 
10 import gntp
11 
12 from medusa import app, common
13 from medusa.helper.exceptions import ex
14 from medusa.logger.adapters.style import BraceAdapter
15 
16 log = BraceAdapter(logging.getLogger(__name__))
17 log.logger.addHandler(logging.NullHandler())
18 
19 
20 class Notifier(object):
21     def test_notify(self, host, password):
22         self._sendRegistration(host, password)
23         return self._sendGrowl('Test Growl', 'Testing Growl settings from Medusa', 'Test', host, password,
24                                force=True)
25 
26     def notify_snatch(self, ep_name, is_proper):
27         if app.GROWL_NOTIFY_ONSNATCH:
28             self._sendGrowl(
29                 common.notifyStrings[
30                     (common.NOTIFY_SNATCH, common.NOTIFY_SNATCH_PROPER)[is_proper]
31                 ], ep_name)
32 
33     def notify_download(self, ep_name):
34         if app.GROWL_NOTIFY_ONDOWNLOAD:
35             self._sendGrowl(common.notifyStrings[common.NOTIFY_DOWNLOAD], ep_name)
36 
37     def notify_subtitle_download(self, ep_name, lang):
38         if app.GROWL_NOTIFY_ONSUBTITLEDOWNLOAD:
39             self._sendGrowl(common.notifyStrings[common.NOTIFY_SUBTITLE_DOWNLOAD], ep_name + ': ' + lang)
40 
41     def notify_git_update(self, new_version='??'):
42         update_text = common.notifyStrings[common.NOTIFY_GIT_UPDATE_TEXT]
43         title = common.notifyStrings[common.NOTIFY_GIT_UPDATE]
44         self._sendGrowl(title, update_text + new_version)
45 
46     def notify_login(self, ipaddress=''):
47         update_text = common.notifyStrings[common.NOTIFY_LOGIN_TEXT]
48         title = common.notifyStrings[common.NOTIFY_LOGIN]
49         self._sendGrowl(title, update_text.format(ipaddress))
50 
51     def _send_growl(self, options, message=None):
52 
53         # Initialize Notification
54         notice = gntp.core.GNTPNotice(
55             app=options['app'],
56             name=options['name'],
57             title=options['title'],
58             password=options['password'],
59         )
60 
61         # Optional
62         if options['sticky']:
63             notice.add_header('Notification-Sticky', options['sticky'])
64         if options['priority']:
65             notice.add_header('Notification-Priority', options['priority'])
66         if options['icon']:
67             notice.add_header('Notification-Icon', app.LOGO_URL)
68 
69         if message:
70             notice.add_header('Notification-Text', message)
71 
72         response = self._send(options['host'], options['port'], notice.encode(), options['debug'])
73         return True if isinstance(response, gntp.core.GNTPOK) else False
74 
75     @staticmethod
76     def _send(host, port, data, debug=False):
77         if debug:
78             print('<Sending>\n', data, '\n</Sending>')
79 
80         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
81         s.connect((host, port))
82         s.send(data)
83         response = gntp.core.parse_gntp(s.recv(1024))
84         s.close()
85 
86         if debug:
87             print('<Received>\n', response, '\n</Received>')
88 
89         return response
90 
91     def _sendGrowl(self, title='Medusa Notification', message=None, name=None, host=None, password=None,
92                    force=False):
93         if not app.USE_GROWL and not force:
94             return False
95 
96         if name is None:
97             name = title
98 
99         if host is None:
100             hostParts = app.GROWL_HOST.split(':')
101         else:
102             hostParts = host.split(':')
103 
104         if len(hostParts) != 2 or hostParts[1] == '':
105             port = 23053
106         else:
107             port = int(hostParts[1])
108 
109         growlHosts = [(hostParts[0], port)]
110 
111         opts = {
112             'name': name,
113             'title': title,
114             'app': 'Medusa',
115             'sticky': None,
116             'priority': None,
117             'debug': False
118         }
119 
120         if password is None:
121             opts['password'] = app.GROWL_PASSWORD
122         else:
123             opts['password'] = password
124 
125         opts['icon'] = True
126 
127         for pc in growlHosts:
128             opts['host'] = pc[0]
129             opts['port'] = pc[1]
130             log.debug(
131                 u'GROWL: Sending growl to {host}:{port} - {msg!r}',
132                 {'msg': message, 'host': opts['host'], 'port': opts['port']}
133             )
134             try:
135                 if self._send_growl(opts, message):
136                     return True
137                 else:
138                     if self._sendRegistration(host, password):
139                         return self._send_growl(opts, message)
140                     else:
141                         return False
142             except Exception as error:
143                 log.warning(
144                     u'GROWL: Unable to send growl to {host}:{port} - {msg!r}',
145                     {'msg': ex(error), 'host': opts['host'], 'port': opts['port']}
146                 )
147                 return False
148 
149     def _sendRegistration(self, host=None, password=None):
150         opts = {}
151 
152         if host is None:
153             hostParts = app.GROWL_HOST.split(':')
154         else:
155             hostParts = host.split(':')
156 
157         if len(hostParts) != 2 or hostParts[1] == '':
158             port = 23053
159         else:
160             port = int(hostParts[1])
161 
162         opts['host'] = hostParts[0]
163         opts['port'] = port
164 
165         if password is None:
166             opts['password'] = app.GROWL_PASSWORD
167         else:
168             opts['password'] = password
169 
170         opts['app'] = 'Medusa'
171         opts['debug'] = False
172 
173         # Send Registration
174         register = gntp.core.GNTPRegister()
175         register.add_header('Application-Name', opts['app'])
176         register.add_header('Application-Icon', app.LOGO_URL)
177 
178         register.add_notification('Test', True)
179         register.add_notification(common.notifyStrings[common.NOTIFY_SNATCH], True)
180         register.add_notification(common.notifyStrings[common.NOTIFY_DOWNLOAD], True)
181         register.add_notification(common.notifyStrings[common.NOTIFY_GIT_UPDATE], True)
182 
183         if opts['password']:
184             register.set_password(opts['password'])
185 
186         try:
187             return self._send(opts['host'], opts['port'], register.encode(), opts['debug'])
188         except Exception as error:
189             log.warning(
190                 u'GROWL: Unable to send growl to {host}:{port} - {msg!r}',
191                 {'msg': ex(error), 'host': opts['host'], 'port': opts['port']}
192             )
193             return False
194
```
--- 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/medusa/notifiers/growl.py b/medusa/notifiers/growl.py
--- a/medusa/notifiers/growl.py
+++ b/medusa/notifiers/growl.py
@@ -7,7 +7,7 @@
 import socket
 from builtins import object
 
-import gntp
+import gntp.core
 
 from medusa import app, common
 from medusa.helper.exceptions import ex

{"golden_diff": "diff --git a/medusa/notifiers/growl.py b/medusa/notifiers/growl.py\n--- a/medusa/notifiers/growl.py\n+++ b/medusa/notifiers/growl.py\n@@ -7,7 +7,7 @@\n import socket\n from builtins import object\n \n-import gntp\n+import gntp.core\n \n from medusa import app, common\n from medusa.helper.exceptions import ex\n", "issue": "[APP SUBMITTED]: AttributeError: 'module' object has no attribute 'core'\n\n### INFO\n**Python Version**: `2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:53:40) [MSC v.1500 64 bit (AMD64)]`\n**Operating System**: `Windows-7-6.1.7601-SP1`\n**Locale**: `cp1252`\n**Branch**: [master](../tree/master)\n**Database**: `44.9`\n**Commit**: pymedusa/Medusa@77b20916ab577b82112ebc624f816054788c63f2\n**Link to Log**: https://gist.github.com/7f6099e1c66cecd44e069bffee91a3ac\n### ERROR\n<pre>\n2018-04-23 16:08:49 ERROR    Thread_18 :: [77b2091] Exception generated: 'module' object has no attribute 'core'\nTraceback (most recent call last):\n  File \"C:\\Medusa\\Medusa\\medusa\\server\\web\\core\\base.py\", line 285, in async_call\n    result = function(**kwargs)\n  File \"C:\\Medusa\\Medusa\\medusa\\server\\web\\home\\handler.py\", line 357, in testGrowl\n    result = notifiers.growl_notifier.test_notify(host, password)\n  File \"C:\\Medusa\\Medusa\\medusa\\notifiers\\growl.py\", line 22, in test_notify\n    self._sendRegistration(host, password)\n  File \"C:\\Medusa\\Medusa\\medusa\\notifiers\\growl.py\", line 174, in _sendRegistration\n    register = gntp.core.GNTPRegister()\nAttributeError: 'module' object has no attribute 'core'\n</pre>\n---\n_STAFF NOTIFIED_: @pymedusa/support @pymedusa/moderators\n\n", "before_files": [{"content": "# coding=utf-8\n\nfrom __future__ import print_function\nfrom __future__ import unicode_literals\n\nimport logging\nimport socket\nfrom builtins import object\n\nimport gntp\n\nfrom medusa import app, common\nfrom medusa.helper.exceptions import ex\nfrom medusa.logger.adapters.style import BraceAdapter\n\nlog = BraceAdapter(logging.getLogger(__name__))\nlog.logger.addHandler(logging.NullHandler())\n\n\nclass Notifier(object):\n    def test_notify(self, host, password):\n        self._sendRegistration(host, password)\n        return self._sendGrowl('Test Growl', 'Testing Growl settings from Medusa', 'Test', host, password,\n                               force=True)\n\n    def notify_snatch(self, ep_name, is_proper):\n        if app.GROWL_NOTIFY_ONSNATCH:\n            self._sendGrowl(\n                common.notifyStrings[\n                    (common.NOTIFY_SNATCH, common.NOTIFY_SNATCH_PROPER)[is_proper]\n                ], ep_name)\n\n    def notify_download(self, ep_name):\n        if app.GROWL_NOTIFY_ONDOWNLOAD:\n            self._sendGrowl(common.notifyStrings[common.NOTIFY_DOWNLOAD], ep_name)\n\n    def notify_subtitle_download(self, ep_name, lang):\n        if app.GROWL_NOTIFY_ONSUBTITLEDOWNLOAD:\n            self._sendGrowl(common.notifyStrings[common.NOTIFY_SUBTITLE_DOWNLOAD], ep_name + ': ' + lang)\n\n    def notify_git_update(self, new_version='??'):\n        update_text = common.notifyStrings[common.NOTIFY_GIT_UPDATE_TEXT]\n        title = common.notifyStrings[common.NOTIFY_GIT_UPDATE]\n        self._sendGrowl(title, update_text + new_version)\n\n    def notify_login(self, ipaddress=''):\n        update_text = common.notifyStrings[common.NOTIFY_LOGIN_TEXT]\n        title = common.notifyStrings[common.NOTIFY_LOGIN]\n        self._sendGrowl(title, update_text.format(ipaddress))\n\n    def _send_growl(self, options, message=None):\n\n        # Initialize Notification\n        notice = gntp.core.GNTPNotice(\n            app=options['app'],\n            name=options['name'],\n            title=options['title'],\n            password=options['password'],\n        )\n\n        # Optional\n        if options['sticky']:\n            notice.add_header('Notification-Sticky', options['sticky'])\n        if options['priority']:\n            notice.add_header('Notification-Priority', options['priority'])\n        if options['icon']:\n            notice.add_header('Notification-Icon', app.LOGO_URL)\n\n        if message:\n            notice.add_header('Notification-Text', message)\n\n        response = self._send(options['host'], options['port'], notice.encode(), options['debug'])\n        return True if isinstance(response, gntp.core.GNTPOK) else False\n\n    @staticmethod\n    def _send(host, port, data, debug=False):\n        if debug:\n            print('<Sending>\\n', data, '\\n</Sending>')\n\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n        s.connect((host, port))\n        s.send(data)\n        response = gntp.core.parse_gntp(s.recv(1024))\n        s.close()\n\n        if debug:\n            print('<Received>\\n', response, '\\n</Received>')\n\n        return response\n\n    def _sendGrowl(self, title='Medusa Notification', message=None, name=None, host=None, password=None,\n                   force=False):\n        if not app.USE_GROWL and not force:\n            return False\n\n        if name is None:\n            name = title\n\n        if host is None:\n            hostParts = app.GROWL_HOST.split(':')\n        else:\n            hostParts = host.split(':')\n\n        if len(hostParts) != 2 or hostParts[1] == '':\n            port = 23053\n        else:\n            port = int(hostParts[1])\n\n        growlHosts = [(hostParts[0], port)]\n\n        opts = {\n            'name': name,\n            'title': title,\n            'app': 'Medusa',\n            'sticky': None,\n            'priority': None,\n            'debug': False\n        }\n\n        if password is None:\n            opts['password'] = app.GROWL_PASSWORD\n        else:\n            opts['password'] = password\n\n        opts['icon'] = True\n\n        for pc in growlHosts:\n            opts['host'] = pc[0]\n            opts['port'] = pc[1]\n            log.debug(\n                u'GROWL: Sending growl to {host}:{port} - {msg!r}',\n                {'msg': message, 'host': opts['host'], 'port': opts['port']}\n            )\n            try:\n                if self._send_growl(opts, message):\n                    return True\n                else:\n                    if self._sendRegistration(host, password):\n                        return self._send_growl(opts, message)\n                    else:\n                        return False\n            except Exception as error:\n                log.warning(\n                    u'GROWL: Unable to send growl to {host}:{port} - {msg!r}',\n                    {'msg': ex(error), 'host': opts['host'], 'port': opts['port']}\n                )\n                return False\n\n    def _sendRegistration(self, host=None, password=None):\n        opts = {}\n\n        if host is None:\n            hostParts = app.GROWL_HOST.split(':')\n        else:\n            hostParts = host.split(':')\n\n        if len(hostParts) != 2 or hostParts[1] == '':\n            port = 23053\n        else:\n            port = int(hostParts[1])\n\n        opts['host'] = hostParts[0]\n        opts['port'] = port\n\n        if password is None:\n            opts['password'] = app.GROWL_PASSWORD\n        else:\n            opts['password'] = password\n\n        opts['app'] = 'Medusa'\n        opts['debug'] = False\n\n        # Send Registration\n        register = gntp.core.GNTPRegister()\n        register.add_header('Application-Name', opts['app'])\n        register.add_header('Application-Icon', app.LOGO_URL)\n\n        register.add_notification('Test', True)\n        register.add_notification(common.notifyStrings[common.NOTIFY_SNATCH], True)\n        register.add_notification(common.notifyStrings[common.NOTIFY_DOWNLOAD], True)\n        register.add_notification(common.notifyStrings[common.NOTIFY_GIT_UPDATE], True)\n\n        if opts['password']:\n            register.set_password(opts['password'])\n\n        try:\n            return self._send(opts['host'], opts['port'], register.encode(), opts['debug'])\n        except Exception as error:\n            log.warning(\n                u'GROWL: Unable to send growl to {host}:{port} - {msg!r}',\n                {'msg': ex(error), 'host': opts['host'], 'port': opts['port']}\n            )\n            return False\n", "path": "medusa/notifiers/growl.py"}], "after_files": [{"content": "# coding=utf-8\n\nfrom __future__ import print_function\nfrom __future__ import unicode_literals\n\nimport logging\nimport socket\nfrom builtins import object\n\nimport gntp.core\n\nfrom medusa import app, common\nfrom medusa.helper.exceptions import ex\nfrom medusa.logger.adapters.style import BraceAdapter\n\nlog = BraceAdapter(logging.getLogger(__name__))\nlog.logger.addHandler(logging.NullHandler())\n\n\nclass Notifier(object):\n    def test_notify(self, host, password):\n        self._sendRegistration(host, password)\n        return self._sendGrowl('Test Growl', 'Testing Growl settings from Medusa', 'Test', host, password,\n                               force=True)\n\n    def notify_snatch(self, ep_name, is_proper):\n        if app.GROWL_NOTIFY_ONSNATCH:\n            self._sendGrowl(\n                common.notifyStrings[\n                    (common.NOTIFY_SNATCH, common.NOTIFY_SNATCH_PROPER)[is_proper]\n                ], ep_name)\n\n    def notify_download(self, ep_name):\n        if app.GROWL_NOTIFY_ONDOWNLOAD:\n            self._sendGrowl(common.notifyStrings[common.NOTIFY_DOWNLOAD], ep_name)\n\n    def notify_subtitle_download(self, ep_name, lang):\n        if app.GROWL_NOTIFY_ONSUBTITLEDOWNLOAD:\n            self._sendGrowl(common.notifyStrings[common.NOTIFY_SUBTITLE_DOWNLOAD], ep_name + ': ' + lang)\n\n    def notify_git_update(self, new_version='??'):\n        update_text = common.notifyStrings[common.NOTIFY_GIT_UPDATE_TEXT]\n        title = common.notifyStrings[common.NOTIFY_GIT_UPDATE]\n        self._sendGrowl(title, update_text + new_version)\n\n    def notify_login(self, ipaddress=''):\n        update_text = common.notifyStrings[common.NOTIFY_LOGIN_TEXT]\n        title = common.notifyStrings[common.NOTIFY_LOGIN]\n        self._sendGrowl(title, update_text.format(ipaddress))\n\n    def _send_growl(self, options, message=None):\n\n        # Initialize Notification\n        notice = gntp.core.GNTPNotice(\n            app=options['app'],\n            name=options['name'],\n            title=options['title'],\n            password=options['password'],\n        )\n\n        # Optional\n        if options['sticky']:\n            notice.add_header('Notification-Sticky', options['sticky'])\n        if options['priority']:\n            notice.add_header('Notification-Priority', options['priority'])\n        if options['icon']:\n            notice.add_header('Notification-Icon', app.LOGO_URL)\n\n        if message:\n            notice.add_header('Notification-Text', message)\n\n        response = self._send(options['host'], options['port'], notice.encode(), options['debug'])\n        return True if isinstance(response, gntp.core.GNTPOK) else False\n\n    @staticmethod\n    def _send(host, port, data, debug=False):\n        if debug:\n            print('<Sending>\\n', data, '\\n</Sending>')\n\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n        s.connect((host, port))\n        s.send(data)\n        response = gntp.core.parse_gntp(s.recv(1024))\n        s.close()\n\n        if debug:\n            print('<Received>\\n', response, '\\n</Received>')\n\n        return response\n\n    def _sendGrowl(self, title='Medusa Notification', message=None, name=None, host=None, password=None,\n                   force=False):\n        if not app.USE_GROWL and not force:\n            return False\n\n        if name is None:\n            name = title\n\n        if host is None:\n            hostParts = app.GROWL_HOST.split(':')\n        else:\n            hostParts = host.split(':')\n\n        if len(hostParts) != 2 or hostParts[1] == '':\n            port = 23053\n        else:\n            port = int(hostParts[1])\n\n        growlHosts = [(hostParts[0], port)]\n\n        opts = {\n            'name': name,\n            'title': title,\n            'app': 'Medusa',\n            'sticky': None,\n            'priority': None,\n            'debug': False\n        }\n\n        if password is None:\n            opts['password'] = app.GROWL_PASSWORD\n        else:\n            opts['password'] = password\n\n        opts['icon'] = True\n\n        for pc in growlHosts:\n            opts['host'] = pc[0]\n            opts['port'] = pc[1]\n            log.debug(\n                u'GROWL: Sending growl to {host}:{port} - {msg!r}',\n                {'msg': message, 'host': opts['host'], 'port': opts['port']}\n            )\n            try:\n                if self._send_growl(opts, message):\n                    return True\n                else:\n                    if self._sendRegistration(host, password):\n                        return self._send_growl(opts, message)\n                    else:\n                        return False\n            except Exception as error:\n                log.warning(\n                    u'GROWL: Unable to send growl to {host}:{port} - {msg!r}',\n                    {'msg': ex(error), 'host': opts['host'], 'port': opts['port']}\n                )\n                return False\n\n    def _sendRegistration(self, host=None, password=None):\n        opts = {}\n\n        if host is None:\n            hostParts = app.GROWL_HOST.split(':')\n        else:\n            hostParts = host.split(':')\n\n        if len(hostParts) != 2 or hostParts[1] == '':\n            port = 23053\n        else:\n            port = int(hostParts[1])\n\n        opts['host'] = hostParts[0]\n        opts['port'] = port\n\n        if password is None:\n            opts['password'] = app.GROWL_PASSWORD\n        else:\n            opts['password'] = password\n\n        opts['app'] = 'Medusa'\n        opts['debug'] = False\n\n        # Send Registration\n        register = gntp.core.GNTPRegister()\n        register.add_header('Application-Name', opts['app'])\n        register.add_header('Application-Icon', app.LOGO_URL)\n\n        register.add_notification('Test', True)\n        register.add_notification(common.notifyStrings[common.NOTIFY_SNATCH], True)\n        register.add_notification(common.notifyStrings[common.NOTIFY_DOWNLOAD], True)\n        register.add_notification(common.notifyStrings[common.NOTIFY_GIT_UPDATE], True)\n\n        if opts['password']:\n            register.set_password(opts['password'])\n\n        try:\n            return self._send(opts['host'], opts['port'], register.encode(), opts['debug'])\n        except Exception as error:\n            log.warning(\n                u'GROWL: Unable to send growl to {host}:{port} - {msg!r}',\n                {'msg': ex(error), 'host': opts['host'], 'port': opts['port']}\n            )\n            return False\n", "path": "medusa/notifiers/growl.py"}]}