Source

VPlayer / similarartistspopulator.py

# -*- coding: utf-8 -*-
import time
import random

from PyQt4 import QtCore

from logger import log
from search import Search
from logininfo import LoginInfo
from lastfm import SimilarArtists


class SimilarArtistsPopulator(QtCore.QThread):
    threads = []
    artists = []
    progress = 0
    error = False
    def __init__(self, artists):
        QtCore.QThread.__init__(self)
        settings = QtCore.QSettings()
        mail = settings.value('login/email').toString()
        uid = settings.value('login/id').toString()
        passw = str(settings.value('login/password').toString())
        if not mail or not uid or not passw:
            self.run = lambda:self.emit(QtCore.SIGNAL('status'), 'nologin')
            return
        self.artists = artists

    def similar_artists(self, artists = []):

        self.request_artist_count = len(artists)
        self.artists = []
        self.tracks = []
        if not artists:
            return []
        threads = []
        log.debug('requesting similar from lastfm...')
        for artist in artists:
            client = SimilarArtists(artist)
            self.threads.append(client)
            QtCore.QObject.connect(client, QtCore.SIGNAL('results'), self._artists_receiver)
            QtCore.QObject.connect(client, QtCore.SIGNAL('status'), self._status_receiver)
            client.start()

        def threads_alive(threadlist):
            for thread in threadlist:
                if thread.isRunning():
                    return True

        while threads_alive(self.threads):
            time.sleep(0.1)

        if self.error:
            return

        random.shuffle(self.artists)
        threads = []
        for artist in self.artists[:10]:
            client = Search(artist, 0)
            threads.append(client)
            QtCore.QObject.connect(client, QtCore.SIGNAL('results'), self._tracks_receiver)
            QtCore.QObject.connect(client, QtCore.SIGNAL('status'), self._status_receiver)
            client.start()
            log.debug('Waiting a half of second...')
            time.sleep(0.5)

        while threads_alive(threads):
            time.sleep(0.1)
        threads = []

        random.shuffle(self.tracks)
        self.emit(QtCore.SIGNAL('results'), self.tracks)

    def run(self):
        self.emit(QtCore.SIGNAL('status'), 'begin')
        self.similar_artists(self.artists)
        self.emit(QtCore.SIGNAL('status'), 'done')

    def _status_receiver(self, status):
        if status == 'error':
            self.error = True
            self.emit(QtCore.SIGNAL('status'), 'error')
        if status == 'wronglogin':
            self.error = True
            self.emit(QtCore.SIGNAL('status'), 'wronglogin')
            log.error('Wrong login')

    def _artists_receiver(self, results):#results):
        log.info('Artists received')
        self.artists += results[:10]
        self.progress += 10/self.request_artist_count
        self.emit(QtCore.SIGNAL('status'), self.progress)

    def _tracks_receiver(self, tracks):
        if not tracks:
            log.info('Could not find tracks for some artist')
            return
        log.info('Tracks received')
        self.progress += 9
        self.emit(QtCore.SIGNAL('status'), self.progress)
        tracks = tracks[1]
        toadd = []
        for track in tracks:
            if track.artist.upper() in [a.upper() for a in self.artists]:
                if track not in toadd and track not in self.tracks:
                    toadd.append(track)
        tracks = toadd
        if len(tracks)>5:
            numbers = []
            while len(numbers)<5:
                n = random.randint(0,len(tracks)-1)
                if n not in numbers:
                    numbers.append(n)
            for n in numbers:
                self.tracks.append(tracks[n])
        else:
            self.tracks += tracks