poller.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. # -*- coding: utf-8 -*-
  2. #
  3. import os
  4. from mpd import MPDClient, MPDError, CommandError
  5. class PollerError(Exception):
  6. """Fatal error in poller."""
  7. class MPDPoller(object):
  8. _host = "/tmp/mpd/socket"
  9. # _host = "localhost"
  10. _port = "6600"
  11. _client = None
  12. def __init__(self, host, port="6600"):
  13. self._host = host
  14. self._port = port
  15. self._client = MPDClient(use_unicode=True)
  16. self._client.timeout = 60 * 60 * 1000
  17. def connect(self):
  18. try:
  19. self._client.connect(self._host, self._port)
  20. # Catch socket errors
  21. except IOError as err:
  22. errno, strerror = err
  23. raise PollerError("Could not connect to '%s': %s" %
  24. (self._host, strerror))
  25. # Catch all other possible errors
  26. except MPDError as e:
  27. raise PollerError("Could not connect to '%s': %s" %
  28. (self._host, e))
  29. def disconnect(self):
  30. # Try to tell MPD to close the connection first
  31. try:
  32. self._client.close()
  33. # If that fails, ignore it and disconnect
  34. except (MPDError, IOError):
  35. pass
  36. try:
  37. self._client.disconnect()
  38. # Disconnecting failed, setup a new client object instead
  39. # This should never happen. If it does, something is seriously broken,
  40. # and the client object shouldn't be trusted to be re-used.
  41. except (MPDError, IOError):
  42. self._client = MPDClient(use_unicode=True)
  43. self._client.timeout = 60 * 60 * 1000
  44. def general(self, func, *args):
  45. ret = None
  46. try:
  47. ret = func(*args)
  48. except CommandError:
  49. return False
  50. except (MPDError, IOError):
  51. print("first error")
  52. self.disconnect()
  53. try:
  54. self.connect()
  55. except PollerError as e:
  56. raise PollerError("Reconnecting failed: %s" % e)
  57. try:
  58. ret = func(*args)
  59. except (MPDError, IOError) as e:
  60. raise PollerError("Couldn't retrieve current song: %s" % e)
  61. return ret
  62. def ping(self):
  63. return self.general(self._client.ping)
  64. def poll(self):
  65. song = self.general(self._client.status)
  66. """
  67. while playing:
  68. {u'songid': u'4', u'playlistlength': u'4', u'playlist': u'7', u'repeat': u'0', u'consume': u'0', u'mixrampdb': u'0.000000', u'random': u'0', u'state': u'play', u'elapsed': u'148.758', u'volume': u'100', u'single': u'0', u'time': u'149:436', u'duration': u'435.670', u'song': u'3', u'audio': u'44100:24:2', u'bitrate': u'192'}
  69. """
  70. # print(song)
  71. return song
  72. def stop(self):
  73. self.general(self._client.stop)
  74. def addfile(self, url):
  75. self.general(self._client.add, url)
  76. def delete(self, posid):
  77. self.general(self._client.delete, posid)
  78. def play(self, posid):
  79. song = self.poll()
  80. if "song" in song:
  81. if int(song["song"]) != posid:
  82. self.general(self._client.play, posid)
  83. else:
  84. if "state" in song:
  85. if song["state"] == "play":
  86. self.general(self._client.pause)
  87. elif song["state"] == "pause":
  88. self.general(self._client.pause)
  89. elif song["state"] == "stop":
  90. self.general(self._client.play, posid)
  91. else:
  92. self.general(self._client.play, posid)
  93. self.general(self._client.setvol, 100)
  94. return posid
  95. def playlist(self):
  96. lst = self.general(self._client.playlistinfo)
  97. return lst
  98. for i in lst:
  99. if "title" in i:
  100. print(i["title"])
  101. elif "file" in i:
  102. print(os.path.basename(i["file"]))
  103. def listfiles(self, path):
  104. files = self.general(self._client.lsinfo, path)
  105. return files
  106. for i in sorted(files):
  107. if "directory" in i:
  108. print("D %s" % i["directory"])
  109. elif "file" in i:
  110. print(i["file"])
  111. def rootfiles(self):
  112. files = self.general(self._client.lsinfo, "/")
  113. return files
  114. for i in sorted(files):
  115. if "directory" in i:
  116. print("D %s" % i["directory"])
  117. elif "file" in i:
  118. print(i["file"])
  119. def main():
  120. from time import sleep
  121. poller = MPDPoller()
  122. poller.connect()
  123. while True:
  124. print("poll:")
  125. print(poller.poll())
  126. """
  127. print("playlist:")
  128. print(poller.playlist())
  129. print("rootfiles:")
  130. poller.rootfiles()
  131. """
  132. sleep(120)
  133. if __name__ == "__main__":
  134. import sys
  135. try:
  136. main()
  137. except PollerError as e:
  138. print("Fatal poller error: %s" % e)
  139. sys.exit(1)
  140. except Exception as e:
  141. print("Unexpected exception: %s" % e)
  142. sys.exit(1)
  143. except:
  144. sys.exit(0)