main_screen.py 10 KB

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