예제 #1
0
 def get(self):
     # TODO: set timeout from config, blacklist this instance when retry fail
     output = self.queue.get(block=True)
     self.thread = StoppableThread(target=self._enqueue_output)
     self.thread.daemon = True
     self.thread.start()
     return output
예제 #2
0
 def __init__(self):
     StoppableThread.__init__(self)
     Singleton.__init__(self)
     GPIO.setmode(GPIO.BCM)
     GPIO.setwarnings(False)
     self.config = self._read_config()
     self.render = web.template.render('templates')
예제 #3
0
    def __init__(self, sock):
        self.logger = logging.getLogger(self.__class__.__name__)

        StoppableThread.__init__(self, name=self.__class__.__name__)
        self._sleep_period = 0.01

        self.sock = sock
        self.queue = Queue.Queue()
예제 #4
0
    def __init__(self, monitors, handlers, connection_manager):
        StoppableThread.__init__(self)
        print('Starting the monitoring service...')
        self.monitors = monitors
        self.handlers = handlers
        self.connection_manager = connection_manager

        self.infrastructure = dict()
        self.workers = []
예제 #5
0
def start_license_thread():
    global LICENSE_THREAD

    print bgcolors.OKBLUE + '\nStarting license update thread' + bgcolors.ENDC
    try:
        # TODO: Args need to removed
        LICENSE_THREAD = StoppableThread(target=update_usage,
                                         name='License-Thread')
        LICENSE_THREAD.start()
        print bgcolors.OKGREEN + 'Start Done\n' + bgcolors.ENDC

    except Exception as e:
        print e
예제 #6
0
class PlayerModel(object):
    def __init__(self):
        self.adaptors = []
        self.adaptor = None
        self.adaptorLock = Lock()
        self._log = ""
        self._player = None
        config = json.load(open('./config/config.json'))
        for k, v in config.iteritems():
            if k == 'youtube':
                for params in v:
                    self.adaptors.append(YoutubeMusic(params, self.log))
            elif k == 'gmusic':
                for params in v:
                    self.adaptors.append(GoogleMusic(params, self.log))

    def log(self, *args):
        self._log += ' '.join(map(lambda a: unicode(a), args)) + "\n"
        self._log = '\n'.join(self._log.split('\n')[-10:])

    def terminate(self):
        self.adaptorLock.acquire()
        if self.adaptor:
            self.adaptor.thread.terminate()
        self.ps.terminate()
        self._player.terminate()
        self.adaptorLock.release()

    def get(self):
        adaptor = random.choice(self.adaptors)
        self.adaptorLock.acquire()
        self.adaptor = adaptor
        self.adaptorLock.release()
        output = adaptor.get()
        if not output:
            return empty_response
        self.ps = subprocess.Popen(('ffplay', '-autoexit', '-loglevel',
                                    'panic', '-nodisp', '-vn', '-'),
                                   stdin=subprocess.PIPE)
        self._player = StoppableThread(target=self.ps.communicate,
                                       kwargs={"input": output.get("audio")})
        self._player.daemon = True
        self._player.start()
        return {
            "song_length": '%d sec' % output.get('song_length', 0),
            "album": output.get('album', ''),
            "artist": output.get('artist', ''),
            "title": output.get('title', ''),
            "song_size": "%d" % len(output.get('audio')),
            "message": self._log
        }
예제 #7
0
 def get(self):
     adaptor = random.choice(self.adaptors)
     self.adaptorLock.acquire()
     self.adaptor = adaptor
     self.adaptorLock.release()
     output = adaptor.get()
     if not output:
         return empty_response
     self.ps = subprocess.Popen(('ffplay', '-autoexit', '-loglevel',
                                 'panic', '-nodisp', '-vn', '-'),
                                stdin=subprocess.PIPE)
     self._player = StoppableThread(target=self.ps.communicate,
                                    kwargs={"input": output.get("audio")})
     self._player.daemon = True
     self._player.start()
     return {
         "song_length": '%d sec' % output.get('song_length', 0),
         "album": output.get('album', ''),
         "artist": output.get('artist', ''),
         "title": output.get('title', ''),
         "song_size": "%d" % len(output.get('audio')),
         "message": self._log
     }
예제 #8
0
 def shutdown(self):
     print('Shutting down monitoring workers...')
     for worker in self.workers:
         worker.shutdown()
     StoppableThread.shutdown(self)
예제 #9
0
 def __init__(self, client, node_data, monitors):
     StoppableThread.__init__(self)
     self.client = client
     self.node_data = node_data
     self.monitors = monitors
예제 #10
0
                adaptors.append(GoogleMusic(params))

    while True:
        adaptor = random.choice(adaptors)
        output = adaptor.get()
        if not output:
            print("output is nil")
            break
        print("song length: %d sec" % output.get('song_length', 0))
        print("album:", output.get('album', ''))
        print("artist:", output.get('artist', ''))
        print("title:", output.get("title", ''))
        print("song size:", len(output.get('audio')))
        ps = subprocess.Popen(('ffplay', '-autoexit', '-loglevel', 'panic',
            '-nodisp', '-vn', '-'), stdin=subprocess.PIPE)
        player = StoppableThread(target=ps.communicate,
                    kwargs={"input": output.get("audio")})
        player.daemon = True

        timer = StoppableThread(target=time_elapse,
                                args=(output.get('song_length', 0), ))
        timer.daemon = True
        timer.start()
        player.start()
        try:
            player.join()
        except:
            adaptor.thread.terminate()
            player.terminate()
            timer.terminate()
            break
        timer.terminate()
예제 #11
0
class YoutubeMusic(object):
    def __init__(self, config, log=print):
        self.config = config
        self.credential_dir = os.path.join(os.path.expanduser('.'),
                                           '.credential')
        self.credential_path = os.path.join(self.credential_dir,
                                            'credential.pkl')

        self.credentials = self.get_credentials()
        http = google_auth_httplib2.AuthorizedHttp(self.credentials,
                                                   http=build_http())
        self.service = discovery.build(API_SERVICE_NAME,
                                       API_VERSION,
                                       http=http)
        self.cache_play_list = {}
        self.cache_song_list = {}
        random.seed()
        self.thread = None
        self.queue = Queue()
        self.log = log
        self._enqueue_output()

    def get_credentials(self):
        if not os.path.exists(self.credential_dir):
            os.makedirs(self.credential_dir)
        if os.path.exists(self.credential_path):
            with open(self.credential_path, 'rb') as f:
                return cPickle.load(f)

        flow = InstalledAppFlow.from_client_config(
            self.config, SCOPE, redirect_uri='urn:ietf:wg:oauth:2.0:oob')
        flow.run_local_server()
        session = flow.authorized_session()
        with open(self.credential_path, 'wb') as f:
            cPickle.dump(session.credentials, f, cPickle.HIGHEST_PROTOCOL)
        return session.credentials

    def playlist(self):
        '''
        example
        {
          "kind": "youtube#playlistListResponse",
          "etag": "ETAG",
          "pageInfo": {
            "totalResults": 7,
            "resultsPerPage": 25
          },
          "items": [
            {
              "kind": "youtube#playlist",
              "etag": "ETAG",
              "id": "ID",
              "snippet": {
                "publishedAt": "2016-02-19T16:01:09.000Z",
                "channelId": "ID_STRING",
                "title": "TITLE",
                "description": "",
                "thumbnails": {
                  "default": {
                    "url": "https://i.ytimg.com/vi/pZWYqkEwChE/default.jpg",
                    "width": 120,
                    "height": 90
                  },
                  "medium": {
                    "url": "https://i.ytimg.com/vi/pZWYqkEwChE/mqdefault.jpg",
                    "width": 320,
                    "height": 180
                  },
                  "high": {
                    "url": "https://i.ytimg.com/vi/pZWYqkEwChE/hqdefault.jpg",
                    "width": 480,
                    "height": 360
                  },
                  "standard": {
                    "url": "https://i.ytimg.com/vi/pZWYqkEwChE/sddefault.jpg",
                    "width": 640,
                    "height": 480
                  },
                  "maxres": {
                    "url": "https://i.ytimg.com/vi/pZWYqkEwChE/maxresdefault.jpg",
                    "width": 1280,
                    "height": 720
                  }
                },
                "channelTitle": "USER_NAME",
                "localized": {
                  "title": "TITLE_LOCAL",
                  "description": ""
                }
              }
            }
          ]
        }
        '''
        while True:
            try:
                data = self.service.playlists().list(part='snippet',
                                                     maxResults=50,
                                                     mine=True).execute()
                result = {}
                for item in data.get('items', []):
                    if item.get('id') in self.config.get('blacklist', []):
                        continue
                    snippet = item.get('snippet', {})
                    result[item.get('id', '')] = [
                        snippet.get('title'),
                        snippet.get('description')
                    ]
                return result
            except Exception as e:
                self.log(e)

    def playlistSongs(self, id):
        nextPageToken = ""
        songs = {}
        while True:
            try:
                data = self.service.playlistItems().list(
                    part='snippet',
                    maxResults=50,
                    playlistId=id,
                    pageToken=nextPageToken).execute()

                for i in data.get('items', []):
                    snippet = i.get('snippet', {})
                    videoId = snippet.get('resourceId', {}).get('videoId', '')
                    songs[videoId] = snippet.get('title', '')
                nextPageToken = data.get('nextPageToken', '')
                if nextPageToken == '':
                    break
            except Exception as e:
                self.log(e)
        return songs

    # Deprecated
    def getVideoUrlHQ(self, vid):
        vinfo = requests.get(
            'http://www.youtube.com/get_video_info?video_id=' + vid)
        params = parse_qs(vinfo.content)
        signature = parse_qs(params['probe_url'][0])['signature'][0]
        self.log(params['title'][0])
        self.log(params['length_seconds'][0])
        self.log(params['author'][0])
        self.log(params.keys())

        stream_map = params.get('adaptive_fmts', [''])[0] + ',' + params.get(
            'url_encoded_fmt_stream_map', [''])[0]
        if 'rtmpe%3Dyes' in stream_map:
            raise Exception("rtmpe cannot be downloaded")
        vid_info = stream_map.split(',')

        for video_query in vid_info:
            if len(video_query) == 0:
                continue
            video = parse_qs(video_query)
            url = video['url'][0]
            if 'sig' in video:
                url += '&signature=' + video['sig'][0]
            elif 's' in video:
                encrypted_sig = video['s'][0]
                raise Exception('not implemented')
            return url

    def getVideoUrlDirect(self, vid):
        # blacklist webm, since most players cannot read
        yd = YoutubeIE(downloader=YoutubeDL(params={"quiet": True}))
        info = yd._real_extract('https://www.youtube.com/watch?v=%s' % vid)
        _max = -1
        url = ''
        result = {}
        for fmt in info['formats']:
            if fmt.get('height', 0) > _max and result.get('ext', '') != 'webm':
                _max = fmt.get('height', 0)
                result = fmt
                url = fmt['url']
        return url, result.get('ext', ''), info.get('duration', 0)

    def getAudioUrlDirect(self, vid):
        # only get audio format, but usually in bad quality...
        video = pafy.new('https://www.youtube.com/watch?v=%s' % vid)
        bestaudio = video.getbestaudio()
        self.log(bestaudio.bitrate)
        return bestaudio.url, bestaudio.extension, bestaudio.length

    def _enqueue_output(self):
        retry = 3
        while retry > 0:
            retry -= 1
            if not self.cache_play_list:
                self.cache_play_list = self.playlist()
            pid = random.choice(self.cache_play_list.keys())
            if not self.cache_song_list.get(pid, None):
                self.cache_song_list[pid] = self.playlistSongs(pid)

            self.log("select playlist:", pid, self.cache_play_list[pid][0])
            if not self.cache_song_list.get(pid):
                print("select fail")
                self.cache_play_list.pop(pid)
                retry += 1
                continue
            vid = random.choice(self.cache_song_list[pid].keys())
            self.log("downloading https://www.youtube.com/watch?v=" + vid)
            url = None
            ext = ''
            length = 0
            try:
                url, ext, length = self.getVideoUrlDirect(vid)
            except Exception as e:
                self.log(vid + ' exract fail')
                try:
                    self.log(e)
                except:
                    pass
                self.cache_song_list[pid].pop(vid)
                retry += 1
                continue
            if not url:
                self.log(vid + "'s video info get fail")
                continue
            result = requests.get(url, headers=HEADER)
            if result.status_code != 200:
                self.log("fail to download video")
                continue
            video = result.content
            if len(video) == 0:
                self.log(vid + ' download fail')
                self.cache_song_list[pid].pop(vid)
                retry += 1
                continue
            output = {
                'song_length': length,
                'album': '',
                'artist': '',
                'title': self.cache_song_list[pid][vid],
                'audio': video,
                'song_size': len(video)
            }
            self.queue.put(output)
            break
        if retry == 0:
            self.log("Youtube download fail, please restart the program")
            self.queue.put({})

    def get(self):
        output = self.queue.get(block=True)
        self.thread = StoppableThread(target=self._enqueue_output)
        self.thread.daeamon = True
        self.thread.start()
        return output
예제 #12
0
 def get(self):
     output = self.queue.get(block=True)
     self.thread = StoppableThread(target=self._enqueue_output)
     self.thread.daeamon = True
     self.thread.start()
     return output
예제 #13
0
class GoogleMusic(object):
    def __init__(self, config, log=print):
        self.OAUTH_PATH = config.get('oauth_path', '/tmp/oauth.cred')
        self.mm = Musicmanager()
        if os.path.isfile(self.OAUTH_PATH):
            success = self.mm.login(oauth_credentials=self.OAUTH_PATH)
            if not success:
                self.mm.perform_oauth(storage_filepath=self.OAUTH_PATH,
                                      open_browser=True)
        else:
            self.mm.perform_oauth(storage_filepath=self.OAUTH_PATH,
                                  open_browser=True)
        random.seed()
        self.songs = self.mm.get_uploaded_songs()
        self.queue = Queue()
        self.thread = None
        self.log = log
        self._enqueue_output()

    def _enqueue_output(self):
        song = random.choice(self.songs)
        self.log("get song id" + song['id'])
        retry = 3
        while retry > 0:
            try:
                filename, audio = self.mm.download_song(song['id'])
                if len(audio) == 0:
                    self.log("audio size 0")
                    song = random.choice(self.songs)
                    continue

                filelike = StringIO.StringIO(audio)
                metadata = mutagen.File(filelike)
                output = {
                    'song_length': 0,
                    'album': '',
                    'artist': '',
                    'title': '',
                    'audio': audio
                }

                if metadata:
                    output['song_length'] = metadata.info.length
                    output['album'] = fix_name(
                        (metadata.tags or metadata).get('TALB', dummy).text[0])
                    output['artist'] = fix_name(
                        (metadata.tags or metadata).get('TPE1', dummy).text[0])
                    output['title'] = fix_name(
                        (metadata.tags or metadata).get('TIT2', dummy).text[0])

                self.queue.put(output)
                break
            except CallFailure:
                self.log("call failure")
                song = random.choice(self.songs)
                retry -= 1

        if retry == 0:
            self.log("Google Music download fail, please restart the program")
            self.queue.put({})

    def get(self):
        # TODO: set timeout from config, blacklist this instance when retry fail
        output = self.queue.get(block=True)
        self.thread = StoppableThread(target=self._enqueue_output)
        self.thread.daemon = True
        self.thread.start()
        return output