main_screen.py 9.8 KB

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