<commit_before>import os
import pprint
import sys
from multiprocessing.pool import ThreadPool

from twisted.internet.defer import inlineCallbacks
from twisted.logger import Logger

from autobahn.twisted.util import sleep
from autobahn.twisted.wamp import ApplicationSession
from autobahn.wamp.exception import ApplicationError

sys.path.append('../youtube-dl')
from youtube_dl import YoutubeDL

import playlist
import model_transformer

PLAYLIST_STORE = 'playlist.json'

PRINCIPAL = ''
PRINCIPAL_TICKET  = ''

if 'JUKEBOX_SERVER_PRINCIPAL' in os.environ:
    PRINCIPAL = os.environ['JUKEBOX_SERVER_PRINCIPAL']
if 'JUKEBOX_SERVER_PRINCIPAL_TICKET' in os.environ:
    PRINCIPAL_TICKET = os.environ['JUKEBOX_SERVER_PRINCIPAL_TICKET']

pp = pprint.PrettyPrinter(indent=2)

class Jukebox(ApplicationSession):

    log = Logger()

    def onConnect(self):
        self.join(self.config.realm, [u'ticket'], PRINCIPAL)

    def onChallenge(self, challenge):
        if challenge.method == u'ticket':
            return PRINCIPAL_TICKET

    @inlineCallbacks
    def onJoin(self, details):
        self.playlist = playlist.Playlist(PLAYLIST_STORE)
        self.thread_pool = ThreadPool(processes=20)

        # jukebox actions
        yield self.register(self.get_playlist,
                'com.forrestli.jukebox.get_playlist')
        yield self.register(self.add, 'com.forrestli.jukebox.add')
        yield self.register(self.remove, 'com.forrestli.jukebox.remove')
        yield self.register(self.play, 'com.forrestli.jukebox.play')
        yield self.register(self.move_song, 'com.forrestli.jukebox.move_song')

        yield self.subscribe(self.on_finish_song,
                'com.forrestli.jukebox.event.player.finished')

    @inlineCallbacks
    def ydl_get_info(self, url):
        def _extract(url):
            opts = {
                'skip_download': True,
                'format': 'bestaudio'
            }
            with YoutubeDL(opts) as ydl:
                return ydl.extract_info(url, False)
        async_result = self.thread_pool.apply_async(_extract, (url,))
        while not async_result.ready():
            yield sleep(1)
        if async_result.successful():
            return async_result.get()
        else:
            return None

    def get_playlist(self):
        return self.playlist.get_playlist()

    @inlineCallbacks
    def add(self, url):
        self.log.info('[jukebox.add]: {url}', url=url)

        info = yield self.ydl_get_info(url)
        info = model_transformer.transform(info)

        self.playlist.add_song(info)
        yield self.publish('com.forrestli.jukebox.event.playlist.add', info)
        return True
<commit_msg>add playlist support<commit_after>import os
import pprint
import sys
from multiprocessing.pool import ThreadPool

from twisted.internet.defer import inlineCallbacks
from twisted.logger import Logger

from autobahn.twisted.util import sleep
from autobahn.twisted.wamp import ApplicationSession
from autobahn.wamp.exception import ApplicationError

sys.path.append('../youtube-dl')
from youtube_dl import YoutubeDL

import playlist
import model_transformer

PLAYLIST_STORE = 'playlist.json'

PRINCIPAL = ''
PRINCIPAL_TICKET  = ''

if 'JUKEBOX_SERVER_PRINCIPAL' in os.environ:
    PRINCIPAL = os.environ['JUKEBOX_SERVER_PRINCIPAL']
if 'JUKEBOX_SERVER_PRINCIPAL_TICKET' in os.environ:
    PRINCIPAL_TICKET = os.environ['JUKEBOX_SERVER_PRINCIPAL_TICKET']

pp = pprint.PrettyPrinter(indent=2)

class Jukebox(ApplicationSession):

    log = Logger()

    def onConnect(self):
        self.join(self.config.realm, [u'ticket'], PRINCIPAL)

    def onChallenge(self, challenge):
        if challenge.method == u'ticket':
            return PRINCIPAL_TICKET

    @inlineCallbacks
    def onJoin(self, details):
        self.playlist = playlist.Playlist(PLAYLIST_STORE)
        self.thread_pool = ThreadPool(processes=20)

        # jukebox actions
        yield self.register(self.get_playlist,
                'com.forrestli.jukebox.get_playlist')
        yield self.register(self.add, 'com.forrestli.jukebox.add')
        yield self.register(self.remove, 'com.forrestli.jukebox.remove')
        yield self.register(self.play, 'com.forrestli.jukebox.play')
        yield self.register(self.move_song, 'com.forrestli.jukebox.move_song')

        yield self.subscribe(self.on_finish_song,
                'com.forrestli.jukebox.event.player.finished')

    @inlineCallbacks
    def ydl_get_info(self, url):
        def _extract(url):
            opts = {
                'skip_download': True,
                'format': 'bestaudio'
            }
            with YoutubeDL(opts) as ydl:
                return ydl.extract_info(url, False)
        async_result = self.thread_pool.apply_async(_extract, (url,))
        while not async_result.ready():
            yield sleep(1)
        if async_result.successful():
            return async_result.get()
        else:
            return None

    def get_playlist(self):
        return self.playlist.get_playlist()

    @inlineCallbacks
    def add(self, url):
        self.log.info('[jukebox.add]: {url}', url=url)

        info = yield self.ydl_get_info(url)
        if '_type' in info and info['_type'] == 'playlist':
            for entry in info['entries']:
                song = model_transformer.transform(entry)
                self.playlist.add_song(song)
                yield self.publish('com.forrestli.jukebox.event.playlist.add', song)

        return True

{'fraction_non_alphanumeric': 0.09959868661072602, 'fraction_numerical': 0.001459321415541773, 'mean_word_length': 2.891412349183818, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '590083', 'n_tokens_mistral': 1821, 'n_tokens_neox': 1744, 'n_words': 327}