main_screen.py 9.9 KB

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