main_screen.py 9.0 KB

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