We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
mpd_status creates a new socket connection every second
I'm not sure if this should be a bug report or a feature request, but I've been bitten by this, erm, _feature_: I use `mopidy` (mpd with spotify integration) and that gets confused when a request comes in from `mpd_status` while it processes a mpd-command-block. 

This also keeps a lot of abandoned connections in `TIME_WAIT` state - 60 currently at my system. 

I've had a quick look at the code for this module, and the connection i s esatablished in `current_track()`. I do not know if it is possible, but the best apporach (IMHO) would be to `connect()` once and keep the socket alive until `py3status` gets reloaded. 
mpd_status creates a new socket connection every second
I'm not sure if this should be a bug report or a feature request, but I've been bitten by this, erm, _feature_: I use `mopidy` (mpd with spotify integration) and that gets confused when a request comes in from `mpd_status` while it processes a mpd-command-block. 

This also keeps a lot of abandoned connections in `TIME_WAIT` state - 60 currently at my system. 

I've had a quick look at the code for this module, and the connection i s esatablished in `current_track()`. I do not know if it is possible, but the best apporach (IMHO) would be to `connect()` once and keep the socket alive until `py3status` gets reloaded. 

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `py3status/modules/mpd_status.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 """
3 Display song currently playing in mpd.
4 
5 Configuration parameters:
6     cache_timeout: how often we refresh this module in seconds (default 2)
7     format: template string (see below)
8         (default '{state} [[[{artist}] - {title}]|[{file}]]')
9     hide_when_paused: hide the status if state is paused (default False)
10     hide_when_stopped: hide the status if state is stopped (default True)
11     host: mpd host (default 'localhost')
12     max_width: maximum status length (default 120)
13     password: mpd password (default None)
14     port: mpd port (default '6600')
15     state_pause: label to display for "paused" state (default '[pause]')
16     state_play: label to display for "playing" state (default '[play]')
17     state_stop: label to display for "stopped" state (default '[stop]')
18 
19 Color options:
20     color_pause: Paused, default color_degraded
21     color_play: Playing, default color_good
22     color_stop: Stopped, default color_bad
23 
24 Format placeholders:
25     {state} state (paused, playing. stopped) can be defined via `state_..`
26         configuration parameters
27     Refer to the mpc(1) manual page for the list of available placeholders to
28     be used in the format.  Placeholders should use braces `{}` rather than
29     percent `%%` eg `{artist}`.
30     Every placeholder can also be prefixed with
31     `next_` to retrieve the data for the song following the one currently
32     playing.
33 
34 Requires:
35     python-mpd2: (NOT python2-mpd2)
36 ```
37 # pip install python-mpd2
38 ```
39 
40 Note: previously formats using %field% where allowed for this module, but
41 standard placeholders should be used.
42 
43 Examples of `format`
44 ```
45 # Show state and (artist -) title, if no title fallback to file:
46 {state} [[[{artist} - ]{title}]|[{file}]]
47 
48 # Show state, [duration], title (or file) and next song title (or file):
49 {state} \[{time}\] [{title}|{file}] → [{next_title}|{next_file}]
50 ```
51 
52 @author shadowprince, zopieux
53 @license Eclipse Public License
54 
55 SAMPLE OUTPUT
56 {'color': '#00ff00', 'full_text': '[play] Music For Programming - Idol Eyes'}
57 
58 paused
59 {'color': '#ffff00', 'full_text': '[pause] Music For Programming - Idol Eyes'}
60 
61 stopped
62 {'color': '#ff0000', 'full_text': '[stop] Music For Programming - Idol Eyes'}
63 """
64 
65 import datetime
66 import re
67 import socket
68 from mpd import MPDClient, CommandError
69 
70 
71 def song_attr(song, attr):
72     def parse_mtime(date_str):
73         return datetime.datetime.strptime(date_str, '%Y-%m-%dT%H:%M:%SZ')
74 
75     if attr == 'time':
76         try:
77             duration = int(song['time'])
78             if duration > 0:
79                 minutes, seconds = divmod(duration, 60)
80                 return '{:d}:{:02d}'.format(minutes, seconds)
81             raise ValueError
82         except (KeyError, ValueError):
83             return ''
84     elif attr == 'position':
85         try:
86             return '{}'.format(int(song['pos']) + 1)
87         except (KeyError, ValueError):
88             return ''
89     elif attr == 'mtime':
90         return parse_mtime(song['last-modified']).strftime('%c')
91     elif attr == 'mdate':
92         return parse_mtime(song['last-modified']).strftime('%x')
93 
94     return song.get(attr, '')
95 
96 
97 class Py3status:
98     """
99     """
100     # available configuration parameters
101     cache_timeout = 2
102     format = '{state} [[[{artist}] - {title}]|[{file}]]'
103     hide_when_paused = False
104     hide_when_stopped = True
105     host = 'localhost'
106     max_width = 120
107     password = None
108     port = '6600'
109     state_pause = '[pause]'
110     state_play = '[play]'
111     state_stop = '[stop]'
112 
113     def post_config_hook(self):
114         # Convert from %placeholder% to {placeholder}
115         # This is not perfect but should be good enough
116         if not self.py3.get_placeholders_list(self.format) and '%' in self.format:
117             self.format = re.sub('%([a-z]+)%', r'{\1}', self.format)
118             self.py3.log('Old % style format DEPRECATED use { style format')
119 
120     def _state_character(self, state):
121         if state == 'play':
122             return self.state_play
123         elif state == 'pause':
124             return self.state_pause
125         elif state == 'stop':
126             return self.state_stop
127         return '?'
128 
129     def current_track(self):
130         try:
131             c = MPDClient()
132             c.connect(host=self.host, port=self.port)
133             if self.password:
134                 c.password(self.password)
135 
136             status = c.status()
137             song = int(status.get('song', 0))
138             next_song = int(status.get('nextsong', 0))
139 
140             state = status.get('state')
141 
142             if ((state == 'pause' and self.hide_when_paused) or
143                     (state == 'stop' and self.hide_when_stopped)):
144                 text = ''
145 
146             else:
147                 playlist_info = c.playlistinfo()
148                 try:
149                     song = playlist_info[song]
150                 except IndexError:
151                     song = {}
152                 try:
153                     next_song = playlist_info[next_song]
154                 except IndexError:
155                     next_song = {}
156 
157                 song['state'] = next_song['state'] \
158                               = self._state_character(state)
159 
160                 def attr_getter(attr):
161                     if attr.startswith('next_'):
162                         return song_attr(next_song, attr[5:])
163                     return song_attr(song, attr)
164 
165                 text = self.py3.safe_format(self.format, attr_getter=attr_getter)
166 
167         except socket.error:
168             text = "Failed to connect to mpd!"
169             state = None
170         except CommandError:
171             text = "Failed to authenticate to mpd!"
172             state = None
173             c.disconnect()
174         else:
175             c.disconnect()
176 
177         if len(text) > self.max_width:
178             text = u'{}...'.format(text[:self.max_width - 3])
179 
180         response = {
181             'cached_until': self.py3.time_in(self.cache_timeout),
182             'full_text': text,
183         }
184 
185         if state:
186             if state == 'play':
187                 response['color'] = self.py3.COLOR_PLAY or self.py3.COLOR_GOOD
188             elif state == 'pause':
189                 response['color'] = (self.py3.COLOR_PAUSE or
190                                      self.py3.COLOR_DEGRADED)
191             elif state == 'stop':
192                 response['color'] = self.py3.COLOR_STOP or self.py3.COLOR_BAD
193 
194         return response
195 
196 
197 if __name__ == "__main__":
198     """
199     Run module in test mode.
200     """
201     from py3status.module_test import module_test
202     module_test(Py3status)
203
```
--- 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/py3status/modules/mpd_status.py b/py3status/modules/mpd_status.py
--- a/py3status/modules/mpd_status.py
+++ b/py3status/modules/mpd_status.py
@@ -65,7 +65,7 @@
 import datetime
 import re
 import socket
-from mpd import MPDClient, CommandError
+from mpd import MPDClient, CommandError, ConnectionError
 
 
 def song_attr(song, attr):
@@ -116,6 +116,27 @@
         if not self.py3.get_placeholders_list(self.format) and '%' in self.format:
             self.format = re.sub('%([a-z]+)%', r'{\1}', self.format)
             self.py3.log('Old % style format DEPRECATED use { style format')
+        # class variables:
+        self.client = None
+
+    def _get_mpd(self, disconnect=False):
+        if disconnect:
+            try:
+                self.client.disconnect()
+            finally:
+                self.client = None
+            return
+
+        try:
+            if self.client is None:
+                self.client = MPDClient()
+                self.client.connect(host=self.host, port=self.port)
+                if self.password:
+                    self.client.password(self.password)
+            return self.client
+        except (socket.error, ConnectionError, CommandError) as e:
+            self.client = None
+            raise e
 
     def _state_character(self, state):
         if state == 'play':
@@ -128,12 +149,7 @@
 
     def current_track(self):
         try:
-            c = MPDClient()
-            c.connect(host=self.host, port=self.port)
-            if self.password:
-                c.password(self.password)
-
-            status = c.status()
+            status = self._get_mpd().status()
             song = int(status.get('song', 0))
             next_song = int(status.get('nextsong', 0))
 
@@ -144,7 +160,7 @@
                 text = ''
 
             else:
-                playlist_info = c.playlistinfo()
+                playlist_info = self._get_mpd().playlistinfo()
                 try:
                     song = playlist_info[song]
                 except IndexError:
@@ -167,12 +183,14 @@
         except socket.error:
             text = "Failed to connect to mpd!"
             state = None
+        except ConnectionError:
+            text = "Error while connecting to mpd!"
+            state = None
+            self._get_mpd(disconnect=True)
         except CommandError:
             text = "Failed to authenticate to mpd!"
             state = None
-            c.disconnect()
-        else:
-            c.disconnect()
+            self._get_mpd(disconnect=True)
 
         if len(text) > self.max_width:
             text = u'{}...'.format(text[:self.max_width - 3])
@@ -193,6 +211,9 @@
 
         return response
 
+    def kill(self):
+        self._get_mpd(disconnect=True)
+
 
 if __name__ == "__main__":
     """

{"golden_diff": "diff --git a/py3status/modules/mpd_status.py b/py3status/modules/mpd_status.py\n--- a/py3status/modules/mpd_status.py\n+++ b/py3status/modules/mpd_status.py\n@@ -65,7 +65,7 @@\n import datetime\n import re\n import socket\n-from mpd import MPDClient, CommandError\n+from mpd import MPDClient, CommandError, ConnectionError\n \n \n def song_attr(song, attr):\n@@ -116,6 +116,27 @@\n         if not self.py3.get_placeholders_list(self.format) and '%' in self.format:\n             self.format = re.sub('%([a-z]+)%', r'{\\1}', self.format)\n             self.py3.log('Old % style format DEPRECATED use { style format')\n+        # class variables:\n+        self.client = None\n+\n+    def _get_mpd(self, disconnect=False):\n+        if disconnect:\n+            try:\n+                self.client.disconnect()\n+            finally:\n+                self.client = None\n+            return\n+\n+        try:\n+            if self.client is None:\n+                self.client = MPDClient()\n+                self.client.connect(host=self.host, port=self.port)\n+                if self.password:\n+                    self.client.password(self.password)\n+            return self.client\n+        except (socket.error, ConnectionError, CommandError) as e:\n+            self.client = None\n+            raise e\n \n     def _state_character(self, state):\n         if state == 'play':\n@@ -128,12 +149,7 @@\n \n     def current_track(self):\n         try:\n-            c = MPDClient()\n-            c.connect(host=self.host, port=self.port)\n-            if self.password:\n-                c.password(self.password)\n-\n-            status = c.status()\n+            status = self._get_mpd().status()\n             song = int(status.get('song', 0))\n             next_song = int(status.get('nextsong', 0))\n \n@@ -144,7 +160,7 @@\n                 text = ''\n \n             else:\n-                playlist_info = c.playlistinfo()\n+                playlist_info = self._get_mpd().playlistinfo()\n                 try:\n                     song = playlist_info[song]\n                 except IndexError:\n@@ -167,12 +183,14 @@\n         except socket.error:\n             text = \"Failed to connect to mpd!\"\n             state = None\n+        except ConnectionError:\n+            text = \"Error while connecting to mpd!\"\n+            state = None\n+            self._get_mpd(disconnect=True)\n         except CommandError:\n             text = \"Failed to authenticate to mpd!\"\n             state = None\n-            c.disconnect()\n-        else:\n-            c.disconnect()\n+            self._get_mpd(disconnect=True)\n \n         if len(text) > self.max_width:\n             text = u'{}...'.format(text[:self.max_width - 3])\n@@ -193,6 +211,9 @@\n \n         return response\n \n+    def kill(self):\n+        self._get_mpd(disconnect=True)\n+\n \n if __name__ == \"__main__\":\n     \"\"\"\n", "issue": "mpd_status creates a new socket connection every second\nI'm not sure if this should be a bug report or a feature request, but I've been bitten by this, erm, _feature_: I use `mopidy` (mpd with spotify integration) and that gets confused when a request comes in from `mpd_status` while it processes a mpd-command-block. \r\n\r\nThis also keeps a lot of abandoned connections in `TIME_WAIT` state - 60 currently at my system. \r\n\r\nI've had a quick look at the code for this module, and the connection i s esatablished in `current_track()`. I do not know if it is possible, but the best apporach (IMHO) would be to `connect()` once and keep the socket alive until `py3status` gets reloaded. \nmpd_status creates a new socket connection every second\nI'm not sure if this should be a bug report or a feature request, but I've been bitten by this, erm, _feature_: I use `mopidy` (mpd with spotify integration) and that gets confused when a request comes in from `mpd_status` while it processes a mpd-command-block. \r\n\r\nThis also keeps a lot of abandoned connections in `TIME_WAIT` state - 60 currently at my system. \r\n\r\nI've had a quick look at the code for this module, and the connection i s esatablished in `current_track()`. I do not know if it is possible, but the best apporach (IMHO) would be to `connect()` once and keep the socket alive until `py3status` gets reloaded. \n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"\nDisplay song currently playing in mpd.\n\nConfiguration parameters:\n    cache_timeout: how often we refresh this module in seconds (default 2)\n    format: template string (see below)\n        (default '{state} [[[{artist}] - {title}]|[{file}]]')\n    hide_when_paused: hide the status if state is paused (default False)\n    hide_when_stopped: hide the status if state is stopped (default True)\n    host: mpd host (default 'localhost')\n    max_width: maximum status length (default 120)\n    password: mpd password (default None)\n    port: mpd port (default '6600')\n    state_pause: label to display for \"paused\" state (default '[pause]')\n    state_play: label to display for \"playing\" state (default '[play]')\n    state_stop: label to display for \"stopped\" state (default '[stop]')\n\nColor options:\n    color_pause: Paused, default color_degraded\n    color_play: Playing, default color_good\n    color_stop: Stopped, default color_bad\n\nFormat placeholders:\n    {state} state (paused, playing. stopped) can be defined via `state_..`\n        configuration parameters\n    Refer to the mpc(1) manual page for the list of available placeholders to\n    be used in the format.  Placeholders should use braces `{}` rather than\n    percent `%%` eg `{artist}`.\n    Every placeholder can also be prefixed with\n    `next_` to retrieve the data for the song following the one currently\n    playing.\n\nRequires:\n    python-mpd2: (NOT python2-mpd2)\n```\n# pip install python-mpd2\n```\n\nNote: previously formats using %field% where allowed for this module, but\nstandard placeholders should be used.\n\nExamples of `format`\n```\n# Show state and (artist -) title, if no title fallback to file:\n{state} [[[{artist} - ]{title}]|[{file}]]\n\n# Show state, [duration], title (or file) and next song title (or file):\n{state} \\[{time}\\] [{title}|{file}] \u2192 [{next_title}|{next_file}]\n```\n\n@author shadowprince, zopieux\n@license Eclipse Public License\n\nSAMPLE OUTPUT\n{'color': '#00ff00', 'full_text': '[play] Music For Programming - Idol Eyes'}\n\npaused\n{'color': '#ffff00', 'full_text': '[pause] Music For Programming - Idol Eyes'}\n\nstopped\n{'color': '#ff0000', 'full_text': '[stop] Music For Programming - Idol Eyes'}\n\"\"\"\n\nimport datetime\nimport re\nimport socket\nfrom mpd import MPDClient, CommandError\n\n\ndef song_attr(song, attr):\n    def parse_mtime(date_str):\n        return datetime.datetime.strptime(date_str, '%Y-%m-%dT%H:%M:%SZ')\n\n    if attr == 'time':\n        try:\n            duration = int(song['time'])\n            if duration > 0:\n                minutes, seconds = divmod(duration, 60)\n                return '{:d}:{:02d}'.format(minutes, seconds)\n            raise ValueError\n        except (KeyError, ValueError):\n            return ''\n    elif attr == 'position':\n        try:\n            return '{}'.format(int(song['pos']) + 1)\n        except (KeyError, ValueError):\n            return ''\n    elif attr == 'mtime':\n        return parse_mtime(song['last-modified']).strftime('%c')\n    elif attr == 'mdate':\n        return parse_mtime(song['last-modified']).strftime('%x')\n\n    return song.get(attr, '')\n\n\nclass Py3status:\n    \"\"\"\n    \"\"\"\n    # available configuration parameters\n    cache_timeout = 2\n    format = '{state} [[[{artist}] - {title}]|[{file}]]'\n    hide_when_paused = False\n    hide_when_stopped = True\n    host = 'localhost'\n    max_width = 120\n    password = None\n    port = '6600'\n    state_pause = '[pause]'\n    state_play = '[play]'\n    state_stop = '[stop]'\n\n    def post_config_hook(self):\n        # Convert from %placeholder% to {placeholder}\n        # This is not perfect but should be good enough\n        if not self.py3.get_placeholders_list(self.format) and '%' in self.format:\n            self.format = re.sub('%([a-z]+)%', r'{\\1}', self.format)\n            self.py3.log('Old % style format DEPRECATED use { style format')\n\n    def _state_character(self, state):\n        if state == 'play':\n            return self.state_play\n        elif state == 'pause':\n            return self.state_pause\n        elif state == 'stop':\n            return self.state_stop\n        return '?'\n\n    def current_track(self):\n        try:\n            c = MPDClient()\n            c.connect(host=self.host, port=self.port)\n            if self.password:\n                c.password(self.password)\n\n            status = c.status()\n            song = int(status.get('song', 0))\n            next_song = int(status.get('nextsong', 0))\n\n            state = status.get('state')\n\n            if ((state == 'pause' and self.hide_when_paused) or\n                    (state == 'stop' and self.hide_when_stopped)):\n                text = ''\n\n            else:\n                playlist_info = c.playlistinfo()\n                try:\n                    song = playlist_info[song]\n                except IndexError:\n                    song = {}\n                try:\n                    next_song = playlist_info[next_song]\n                except IndexError:\n                    next_song = {}\n\n                song['state'] = next_song['state'] \\\n                              = self._state_character(state)\n\n                def attr_getter(attr):\n                    if attr.startswith('next_'):\n                        return song_attr(next_song, attr[5:])\n                    return song_attr(song, attr)\n\n                text = self.py3.safe_format(self.format, attr_getter=attr_getter)\n\n        except socket.error:\n            text = \"Failed to connect to mpd!\"\n            state = None\n        except CommandError:\n            text = \"Failed to authenticate to mpd!\"\n            state = None\n            c.disconnect()\n        else:\n            c.disconnect()\n\n        if len(text) > self.max_width:\n            text = u'{}...'.format(text[:self.max_width - 3])\n\n        response = {\n            'cached_until': self.py3.time_in(self.cache_timeout),\n            'full_text': text,\n        }\n\n        if state:\n            if state == 'play':\n                response['color'] = self.py3.COLOR_PLAY or self.py3.COLOR_GOOD\n            elif state == 'pause':\n                response['color'] = (self.py3.COLOR_PAUSE or\n                                     self.py3.COLOR_DEGRADED)\n            elif state == 'stop':\n                response['color'] = self.py3.COLOR_STOP or self.py3.COLOR_BAD\n\n        return response\n\n\nif __name__ == \"__main__\":\n    \"\"\"\n    Run module in test mode.\n    \"\"\"\n    from py3status.module_test import module_test\n    module_test(Py3status)\n", "path": "py3status/modules/mpd_status.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"\nDisplay song currently playing in mpd.\n\nConfiguration parameters:\n    cache_timeout: how often we refresh this module in seconds (default 2)\n    format: template string (see below)\n        (default '{state} [[[{artist}] - {title}]|[{file}]]')\n    hide_when_paused: hide the status if state is paused (default False)\n    hide_when_stopped: hide the status if state is stopped (default True)\n    host: mpd host (default 'localhost')\n    max_width: maximum status length (default 120)\n    password: mpd password (default None)\n    port: mpd port (default '6600')\n    state_pause: label to display for \"paused\" state (default '[pause]')\n    state_play: label to display for \"playing\" state (default '[play]')\n    state_stop: label to display for \"stopped\" state (default '[stop]')\n\nColor options:\n    color_pause: Paused, default color_degraded\n    color_play: Playing, default color_good\n    color_stop: Stopped, default color_bad\n\nFormat placeholders:\n    {state} state (paused, playing. stopped) can be defined via `state_..`\n        configuration parameters\n    Refer to the mpc(1) manual page for the list of available placeholders to\n    be used in the format.  Placeholders should use braces `{}` rather than\n    percent `%%` eg `{artist}`.\n    Every placeholder can also be prefixed with\n    `next_` to retrieve the data for the song following the one currently\n    playing.\n\nRequires:\n    python-mpd2: (NOT python2-mpd2)\n```\n# pip install python-mpd2\n```\n\nNote: previously formats using %field% where allowed for this module, but\nstandard placeholders should be used.\n\nExamples of `format`\n```\n# Show state and (artist -) title, if no title fallback to file:\n{state} [[[{artist} - ]{title}]|[{file}]]\n\n# Show state, [duration], title (or file) and next song title (or file):\n{state} \\[{time}\\] [{title}|{file}] \u2192 [{next_title}|{next_file}]\n```\n\n@author shadowprince, zopieux\n@license Eclipse Public License\n\nSAMPLE OUTPUT\n{'color': '#00ff00', 'full_text': '[play] Music For Programming - Idol Eyes'}\n\npaused\n{'color': '#ffff00', 'full_text': '[pause] Music For Programming - Idol Eyes'}\n\nstopped\n{'color': '#ff0000', 'full_text': '[stop] Music For Programming - Idol Eyes'}\n\"\"\"\n\nimport datetime\nimport re\nimport socket\nfrom mpd import MPDClient, CommandError, ConnectionError\n\n\ndef song_attr(song, attr):\n    def parse_mtime(date_str):\n        return datetime.datetime.strptime(date_str, '%Y-%m-%dT%H:%M:%SZ')\n\n    if attr == 'time':\n        try:\n            duration = int(song['time'])\n            if duration > 0:\n                minutes, seconds = divmod(duration, 60)\n                return '{:d}:{:02d}'.format(minutes, seconds)\n            raise ValueError\n        except (KeyError, ValueError):\n            return ''\n    elif attr == 'position':\n        try:\n            return '{}'.format(int(song['pos']) + 1)\n        except (KeyError, ValueError):\n            return ''\n    elif attr == 'mtime':\n        return parse_mtime(song['last-modified']).strftime('%c')\n    elif attr == 'mdate':\n        return parse_mtime(song['last-modified']).strftime('%x')\n\n    return song.get(attr, '')\n\n\nclass Py3status:\n    \"\"\"\n    \"\"\"\n    # available configuration parameters\n    cache_timeout = 2\n    format = '{state} [[[{artist}] - {title}]|[{file}]]'\n    hide_when_paused = False\n    hide_when_stopped = True\n    host = 'localhost'\n    max_width = 120\n    password = None\n    port = '6600'\n    state_pause = '[pause]'\n    state_play = '[play]'\n    state_stop = '[stop]'\n\n    def post_config_hook(self):\n        # Convert from %placeholder% to {placeholder}\n        # This is not perfect but should be good enough\n        if not self.py3.get_placeholders_list(self.format) and '%' in self.format:\n            self.format = re.sub('%([a-z]+)%', r'{\\1}', self.format)\n            self.py3.log('Old % style format DEPRECATED use { style format')\n        # class variables:\n        self.client = None\n\n    def _get_mpd(self, disconnect=False):\n        if disconnect:\n            try:\n                self.client.disconnect()\n            finally:\n                self.client = None\n            return\n\n        try:\n            if self.client is None:\n                self.client = MPDClient()\n                self.client.connect(host=self.host, port=self.port)\n                if self.password:\n                    self.client.password(self.password)\n            return self.client\n        except (socket.error, ConnectionError, CommandError) as e:\n            self.client = None\n            raise e\n\n    def _state_character(self, state):\n        if state == 'play':\n            return self.state_play\n        elif state == 'pause':\n            return self.state_pause\n        elif state == 'stop':\n            return self.state_stop\n        return '?'\n\n    def current_track(self):\n        try:\n            status = self._get_mpd().status()\n            song = int(status.get('song', 0))\n            next_song = int(status.get('nextsong', 0))\n\n            state = status.get('state')\n\n            if ((state == 'pause' and self.hide_when_paused) or\n                    (state == 'stop' and self.hide_when_stopped)):\n                text = ''\n\n            else:\n                playlist_info = self._get_mpd().playlistinfo()\n                try:\n                    song = playlist_info[song]\n                except IndexError:\n                    song = {}\n                try:\n                    next_song = playlist_info[next_song]\n                except IndexError:\n                    next_song = {}\n\n                song['state'] = next_song['state'] \\\n                              = self._state_character(state)\n\n                def attr_getter(attr):\n                    if attr.startswith('next_'):\n                        return song_attr(next_song, attr[5:])\n                    return song_attr(song, attr)\n\n                text = self.py3.safe_format(self.format, attr_getter=attr_getter)\n\n        except socket.error:\n            text = \"Failed to connect to mpd!\"\n            state = None\n        except ConnectionError:\n            text = \"Error while connecting to mpd!\"\n            state = None\n            self._get_mpd(disconnect=True)\n        except CommandError:\n            text = \"Failed to authenticate to mpd!\"\n            state = None\n            self._get_mpd(disconnect=True)\n\n        if len(text) > self.max_width:\n            text = u'{}...'.format(text[:self.max_width - 3])\n\n        response = {\n            'cached_until': self.py3.time_in(self.cache_timeout),\n            'full_text': text,\n        }\n\n        if state:\n            if state == 'play':\n                response['color'] = self.py3.COLOR_PLAY or self.py3.COLOR_GOOD\n            elif state == 'pause':\n                response['color'] = (self.py3.COLOR_PAUSE or\n                                     self.py3.COLOR_DEGRADED)\n            elif state == 'stop':\n                response['color'] = self.py3.COLOR_STOP or self.py3.COLOR_BAD\n\n        return response\n\n    def kill(self):\n        self._get_mpd(disconnect=True)\n\n\nif __name__ == \"__main__\":\n    \"\"\"\n    Run module in test mode.\n    \"\"\"\n    from py3status.module_test import module_test\n    module_test(Py3status)\n", "path": "py3status/modules/mpd_status.py"}]}