Advertisement
Guest User

Untitled

a guest
Sep 20th, 2014
202
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.11 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. try:
  4.     # python3
  5.     from urllib.request import urlopen
  6.     from urllib.parse import urlparse, urlencode, urlunparse
  7. except ImportError:
  8.     # python2
  9.     from urllib import urlencode
  10.     from urllib2 import urlopen
  11.     from urlparse import urlparse, urlunparse
  12.  
  13. import argparse
  14. import json
  15. import sys
  16. import os
  17. import re
  18.  
  19. from PySide.QtCore import *
  20. from PySide.QtGui import *
  21.  
  22.  
  23. BASEDIR = os.path.dirname(os.path.realpath(__file__))
  24. CONFIG_NAME = 'config'
  25.  
  26.  
  27. def get_client_id():
  28.     with urlopen('https://www.stereodose.com') as data:
  29.         match = re.search(r'var\s+sc_client_id\s*=\s*"(\w+)";',
  30.                           data.read().decode(sys.getdefaultencoding()))
  31.     return match.group(1) if match else str()
  32.  
  33.  
  34. def generate_config():
  35.     songs_dir = os.path.join(BASEDIR, 'songs')
  36.  
  37.     default = dict(
  38.         songs_directory=songs_dir,
  39.         client_id=get_client_id()
  40.     )
  41.     with open(os.path.join(BASEDIR, CONFIG_NAME), 'w') as config:
  42.         for key, value in default.items():
  43.             config.write('{key} = {value}\n'.format(key=key, value=value))
  44.  
  45.  
  46. def get_config():
  47.     config_path = os.path.join(BASEDIR, CONFIG_NAME)
  48.  
  49.     if not os.path.exists(config_path):
  50.         generate_config()
  51.  
  52.     with open(config_path) as config_file:
  53.         config = config_file.read()
  54.  
  55.     match = re.findall(r'(\S+)\s*=\s*(\S+)', config, re.M)
  56.     return dict(match)
  57.  
  58.  
  59. class Logger(object):
  60.  
  61.     def __init__(self):
  62.         pass
  63.  
  64.  
  65. class StereoSong(object):
  66.     """ Song interpretation """
  67.     def __init__(self, song):
  68.         self.uuid = song['uuid']
  69.         self.artist = song["artist"]
  70.         self.title = song["songtitle"]
  71.         self.name = self.__get_name()
  72.         self.__percent = 0.0
  73.  
  74.     def __get_name(self):
  75.         return re.sub(r'\w-', ' ', "{} {}".format(self.artist, self.title))
  76.  
  77.     def get_url(self, client_id):
  78.         return 'https://api.soundcloud.com/tracks/{}/stream?client_id={}'.format(self.uuid, client_id)
  79.  
  80.     @property
  81.     def percent(self):
  82.         return self.__percent
  83.     @percent.setter
  84.     def percent(self, value):
  85.         self.__percent = min(100, max(0, value))
  86.    
  87.  
  88.  
  89. class StereodoseHandler(object):
  90.     """ Simple API for stereodose """
  91.     def __init__(self, url):
  92.         super(StereodoseHandler, self).__init__()
  93.         self.url = url
  94.         self.songs = self.generate_songs()
  95.         self.__config = get_config()
  96.  
  97.     def generate_songs(self):
  98.         with urlopen(self.url) as data:
  99.             result = data.read().decode(sys.getdefaultencoding())
  100.  
  101.         def get_song_array():
  102.             match = re.search(r'var\s+songarray\s*=\s*(.+?);', result)
  103.             return json.loads(match.group(1)) if match else list()
  104.  
  105.         songs = [StereoSong(song) for song in get_song_array()]
  106.         return songs
  107.  
  108.     def download_songs(self):
  109.         song_dir = self.__config['songs_directory']
  110.  
  111.         if not os.path.exists(song_dir):
  112.             os.makedirs(song_dir)
  113.  
  114.         for song in self.songs:
  115.             songs_path = os.path.join(song_dir, song.name)
  116.  
  117.             if os.path.isfile(songs_path):
  118.                 continue
  119.  
  120.             try:
  121.                 download_song(url, song)
  122.             except ValueError:
  123.                 os.remove(songs_path)
  124.  
  125.         def download_song(self, song):
  126.             data = urlopen(song.get_url(self.__config['client_id']))
  127.             songs_path = os.path.join(self.__config['songs_directory'], song.name)
  128.             with open(songs_path, 'wb') as file:
  129.                 meta = data.info()
  130.                 file_size = int(meta.get("Content-Length"))
  131.  
  132.                 file_size_dl, block_sz = 0, 8192
  133.                 while True:
  134.                     buffer = data.read(block_sz)
  135.                     if not buffer:
  136.                         break
  137.  
  138.                     file_size_dl += len(buffer)
  139.                     file.write(buffer)
  140.                     status = file_size_dl * 100.0 / file_size
  141.  
  142.  
  143. class StereodoseGui(QWidget):
  144.     """ GUI class for StereodoseHandler """
  145.     def __init__(self, app):
  146.         super(StereodoseGui, self).__init__()
  147.         self.qt_app = app
  148.        
  149.         self.setMinimumSize(400, 185)
  150.         self.setWindowTitle('Dynamic Greeter')
  151.  
  152.     def run(self):
  153.         """ Show application window and start the main event loop """
  154.         self.show()
  155.         self.qt_app.exec_()
  156.  
  157.  
  158. def main():
  159.     arg_parser = argparse.ArgumentParser()
  160.     arg_parser.add_argument('-p', '--playlist', action='store')
  161.     args = arg_parser.parse_args()
  162.  
  163.     if args.playlist:
  164.         sd = StereodoseHandler(args.playlist)
  165.         sd.download_songs()
  166.     else:
  167.         qt_app = QApplication(sys.argv)
  168.         StereodoseGui(qt_app).run()
  169.  
  170. if __name__ == '__main__':
  171.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement