main_screen.py 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. import hashlib
  2. import time
  3. import os
  4. from threading import Thread
  5. import urllib
  6. import urllib2
  7. import json
  8. from .touch_manager import TouchManager
  9. from .screen_objects import *
  10. logger = logging.getLogger(__name__)
  11. class MainScreen():
  12. def __init__(self, size, manager, cache, core, fonts):
  13. self.core = core
  14. self.size = size
  15. self.base_size = self.size[1] / 8
  16. self.fonts = fonts
  17. self.manager = manager
  18. self.track = None
  19. self.cache = cache
  20. self.image = None
  21. self.artists = None
  22. self.touch_text_manager = ScreenObjectsManager()
  23. current_track = self.core.playback.current_track.get()
  24. if current_track is None:
  25. self.track_playback_ended(None, None)
  26. else:
  27. self.track_started(current_track)
  28. def update(self, screen):
  29. if self.track is not None:
  30. if self.image is not None:
  31. screen.blit(self.image, (self.base_size / 2, self.base_size + self.base_size / 2))
  32. self.touch_text_manager.get_touch_object("time_progress").set_value(self.core.playback.time_position.get() / 1000)
  33. self.touch_text_manager.get_touch_object("time_progress").set_text(time.strftime('%M:%S', time.gmtime(self.core.playback.time_position.get() / 1000)) + "/" + time.strftime('%M:%S', time.gmtime(self.track.length / 1000)))
  34. self.touch_text_manager.render(screen)
  35. return screen
  36. def track_started(self, track):
  37. self.image = None
  38. x = self.base_size * 5
  39. width = self.size[0] - self.base_size / 2 - x
  40. # Load all artists
  41. self.artists = []
  42. for artist in track.artists:
  43. self.artists.append(artist)
  44. #Track name
  45. label = TextItem(self.fonts['base'], MainScreen.get_track_name(track), (x, self.base_size * 2), (width, self.size[1]))
  46. self.touch_text_manager.set_object("track_name", label)
  47. #Album name
  48. label = TextItem(self.fonts['base'], MainScreen.get_track_album_name(track), (x, self.base_size * 3), (width, self.size[1]))
  49. self.touch_text_manager.set_object("album_name", label)
  50. #Artist
  51. label = TextItem(self.fonts['base'], self.get_artist_string(), (x, self.base_size * 4), (width, self.size[1]))
  52. self.touch_text_manager.set_object("artist_name", label)
  53. #Previous track button
  54. button = TouchAndTextItem(self.fonts['icon'], u"\ue61c", (0, self.base_size * 6), None)
  55. self.touch_text_manager.set_touch_object("previous", button)
  56. size_1 = button.get_right_pos()
  57. size_2 = self.fonts['icon'].size(u"\ue61d")[0]
  58. button = TouchAndTextItem(self.fonts['icon'], u"\ue61d", (self.size[0] - size_2, self.base_size * 6), None)
  59. self.touch_text_manager.set_touch_object("next", button)
  60. #Progress
  61. progress = Progressbar(self.fonts['base'],
  62. time.strftime('%M:%S', time.gmtime(0)) + "/" + time.strftime('%M:%S', time.gmtime(0)),
  63. (size_1, self.base_size * 6), (self.size[0] - size_1 - size_2, self.base_size),
  64. track.length / 1000, False)
  65. self.touch_text_manager.set_touch_object("time_progress", progress)
  66. self.track = track
  67. if not self.is_image_in_cache():
  68. thread = Thread(target=self.download_image(0))
  69. thread.start()
  70. else:
  71. self.load_image()
  72. def get_artist_string(self):
  73. artists_string = ''
  74. for artist in self.artists:
  75. artists_string += artist.name + ', '
  76. if len(artists_string) > 2:
  77. artists_string = artists_string[:-2]
  78. elif len(artists_string) == 0:
  79. artists_string = "Unknow Artist"
  80. return artists_string
  81. def get_image_file_name(self):
  82. name = MainScreen.get_track_album_name(self.track) + '-' + self.get_artist_string()
  83. md5name = hashlib.md5(name.encode('utf-8')).hexdigest()
  84. return md5name
  85. def get_cover_folder(self):
  86. if not os.path.isdir(self.cache + "/covers"):
  87. os.makedirs(self.cache + "/covers")
  88. return self.cache + "/covers/"
  89. def is_image_in_cache(self):
  90. self.get_cover_folder()
  91. return os.path.isfile(self.get_cover_folder() + self.get_image_file_name())
  92. def download_image(self, artist_index):
  93. if artist_index < len(self.artists):
  94. try:
  95. safe_artist = urllib.quote_plus(self.artists[artist_index].name)
  96. safe_album = urllib.quote_plus(MainScreen.get_track_album_name(self.track))
  97. url = "http://ws.audioscrobbler.com/2.0/?"
  98. params = "method=album.getinfo&api_key=59a04c6a73fb99d6e8996e01db306829&artist=" + safe_artist + "&album=" + safe_album + "&format=json"
  99. response = urllib2.urlopen(url + params)
  100. data = json.load(response)
  101. image = data['album']['image'][-1]['#text']
  102. urllib.urlretrieve(image, self.get_cover_folder() + self.get_image_file_name())
  103. self.load_image()
  104. except:
  105. self.download_image(artist_index + 1)
  106. else:
  107. logger.info("Cover could not be downloaded")
  108. # There is no cover so it will use all the screen size for the text
  109. width = self.size[0] - self.base_size
  110. current = TextItem(self.fonts['base'], MainScreen.get_track_name(self.track), (self.base_size / 2, self.base_size * 2),
  111. (width, -1))
  112. self.touch_text_manager.set_object("track_name", current)
  113. current = TextItem(self.fonts['base'], MainScreen.get_track_album_name(self.track), (self.base_size / 2, self.base_size * 3),
  114. (width, -1))
  115. self.touch_text_manager.set_object("album_name", current)
  116. current = TextItem(self.fonts['base'], self.get_artist_string(), (self.base_size / 2, self.base_size * 4),
  117. (width, -1))
  118. self.touch_text_manager.set_object("artist_name", current)
  119. def track_playback_ended(self, tl_track, time_position):
  120. self.image = None
  121. # There is no cover so it will use all the screen size for the text
  122. width = self.size[0] - self.base_size
  123. current = TextItem(self.fonts['base'], "Stopped", (self.base_size / 2, self.base_size * 2),
  124. (width, -1))
  125. self.touch_text_manager.set_object("track_name", current)
  126. current = TextItem(self.fonts['base'], "", (self.base_size / 2, self.base_size * 3),
  127. (width, -1))
  128. self.touch_text_manager.set_object("album_name", current)
  129. current = TextItem(self.fonts['base'], "", (self.base_size / 2, self.base_size * 4),
  130. (width, -1))
  131. self.touch_text_manager.set_object("artist_name", current)
  132. def load_image(self):
  133. size = self.base_size * 4
  134. self.image = pygame.transform.scale(
  135. pygame.image.load(self.get_cover_folder() + self.get_image_file_name()).convert(), (size, size))
  136. def touch_event(self, event):
  137. if event.type == TouchManager.click:
  138. objects = self.touch_text_manager.get_touch_objects_in_pos(event.current_pos)
  139. if objects is not None:
  140. for key in objects:
  141. if key == "time_progress":
  142. value = self.touch_text_manager.get_touch_object(key).get_pos_value(event.current_pos) * 1000
  143. self.core.playback.seek(value)
  144. elif key == "previous":
  145. self.core.playback.previous()
  146. elif key == "next":
  147. self.core.playback.next()
  148. elif event.type == TouchManager.swipe:
  149. if event.direction == TouchManager.left:
  150. self.core.playback.next()
  151. elif event.direction == TouchManager.right:
  152. self.core.playback.previous()
  153. elif event.direction == TouchManager.up:
  154. volume = self.core.playback.volume.get() + 10
  155. if volume > 100:
  156. volume = 100
  157. self.manager.backend.tell({'action': 'volume', 'value': volume})
  158. self.manager.volume_changed(volume)
  159. elif event.direction == TouchManager.down:
  160. volume = self.core.playback.volume.get() - 10
  161. if volume < 0:
  162. volume = 0
  163. self.manager.backend.tell({'action': 'volume', 'value': volume})
  164. self.manager.volume_changed(volume)
  165. @staticmethod
  166. def get_track_name(track):
  167. if track.name is None:
  168. return track.uri
  169. else:
  170. return track.name
  171. @staticmethod
  172. def get_track_album_name(track):
  173. if track.album is not None and track.album.name is not None and len(track.album.name)>0:
  174. return track.album.name
  175. else:
  176. return "Unknow Album"