Example #1
0
 def check_archived_song_accessible(self, key):
     archived_song = ArchivedSong.objects.get(id=key)
     location = song_utils.path_from_url(archived_song.url)
     downloader = None
     if not location:
         downloader = Downloader(self.musiq, archived_song.url)
         downloader.check()
     # the downloader raised no error, the song is accessible
     return downloader
Example #2
0
 def get_archived_song_location(self, key, downloader, ip):
     archived_song = ArchivedSong.objects.get(id=key)
     location = song_utils.path_from_url(archived_song.url)
     if location is None:
         location = downloader.fetch(archived_song.url)
     ArchivedSong.objects.filter(id=key).update(counter=F('counter') + 1)
     if self.musiq.base.settings.logging_enabled:
         RequestLog.objects.create(song=archived_song, address=ip)
     return location
Example #3
0
    def check_new_song_accessible(self, search_text):
        # collapse whitespaces
        search_text = ' '.join(search_text.split())

        # if the search text is a url that is already in the database and the song is cached offline, we don't need an online downloader
        downloader = None
        queryset = ArchivedSong.objects.filter(url=search_text)
        if queryset.count() == 1:
            song = queryset.get()
            location = song_utils.path_from_url(song.url)
            if location is not None:
                downloader = OfflineDownloader(location)

        # if the song was not found offline, we use the online downloader
        if downloader is None:
            downloader = Downloader(self.musiq, search_text)
            downloader.check()
            # the downloader raised no error, the song is accessible
        return downloader
Example #4
0
    def get_suggestions(self, request):
        terms = request.GET['term'].split()

        remaining_songs = ArchivedQuery.objects.select_related('song') \
            .values('song__id', 'song__title', 'song__url', 'song__artist', 'song__counter', 'query')

        for term in terms:
            remaining_songs = remaining_songs.filter(
                Q(song__title__icontains=term)
                | Q(song__artist__icontains=term) | Q(query__icontains=term))

        remaining_songs = remaining_songs \
            .values('song__id', 'song__title', 'song__url', 'song__artist', 'song__counter') \
            .distinct() \
            .order_by('-song__counter') \
            [:20]

        results = []
        for song in remaining_songs:
            if song_utils.path_from_url(song['song__url']) is not None:
                cached = True
            else:
                cached = False
            # don't suggest online songs when we don't have internet
            if not self.musiq.base.settings.has_internet:
                if not cached:
                    continue
            result_dict = {
                'key':
                song['song__id'],
                'value':
                song_utils.displayname(song['song__artist'],
                                       song['song__title']),
                'counter':
                song['song__counter'],
                'type':
                'cached' if cached else 'online',
            }
            results.append(result_dict)

        return HttpResponse(json.dumps(results))
Example #5
0
    def _loop(self):
        while True:

            catch_up = None
            if models.CurrentSong.objects.exists():
                # recover interrupted song from database
                current_song = models.CurrentSong.objects.get()

                # continue with the current song (approximately) where we last left
                duration = song_utils.get_duration(current_song.location)
                catch_up = (timezone.now() -
                            current_song.created).total_seconds()
            else:
                self.queue_semaphore.acquire()

                # select the next song depending on settings
                if self.musiq.base.settings.voting_system:
                    with transaction.atomic():
                        song = self.queue.all().order_by('-votes', 'index')[0]
                        song_id = song.id
                        self.queue.remove(song.id)
                elif self.shuffle:
                    index = random.randint(
                        0,
                        models.QueuedSong.objects.count() - 1)
                    song_id = models.QueuedSong.objects.all()[index].id
                    song = self.queue.remove(song_id)
                else:
                    # move the first song in the queue into the current song
                    song_id, song = self.queue.dequeue()

                if song is None:
                    # either the semaphore didn't match up with the actual count of songs in the queue or a race condition occured
                    self.musiq.base.logger.info('dequeued on empty list')
                    continue

                location = song_utils.path_from_url(song.url)
                current_song = models.CurrentSong.objects.create(
                    queue_key=song_id,
                    votes=song.votes,
                    url=song.url,
                    artist=song.artist,
                    title=song.title,
                    duration=song.duration,
                    location=location)

                try:
                    archived_song = models.ArchivedSong.objects.get(
                        url=current_song.url)
                    if self.musiq.base.settings.voting_system:
                        votes = current_song.votes
                    else:
                        votes = None
                    if self.musiq.base.settings.logging_enabled:
                        models.PlayLog.objects.create(song=archived_song,
                                                      votes=votes)
                except (models.ArchivedSong.DoesNotExist,
                        models.ArchivedSong.MultipleObjectsReturned):
                    pass

            self.musiq.update_state()

            with self.mpd_command(important=True):
                self.player.add('file://' + current_song.location)
                self.player.play()
                if catch_up is not None:
                    self.player.seekcur(catch_up)
            self.musiq.update_state()

            self._wait_until_song_end()

            with self.mpd_command(important=True):
                try:
                    self.player.delete(0)
                except mpd.base.CommandError:
                    # catch Bad song index if there is no song
                    pass
            current_song.delete()

            if self.repeat:
                self.queue.enqueue(current_song.location)
                self.queue_semaphore.release()
            else:
                # the song left the queue, we can delete big downloads
                song_utils.decide_deletion(current_song.location)

            self.musiq.update_state()

            if self.musiq.base.user_manager.partymode_enabled(
            ) and random.random() < self.musiq.base.settings.alarm_probability:
                self.alarm_playing.set()
                self.musiq.base.lights.alarm_started()

                with self.mpd_command(important=True):
                    self.player.add('file://' + os.path.join(
                        settings.BASE_DIR, 'config/sounds/alarm.mp3'))
                    self.player.play()
                self._wait_until_song_end()

                self.musiq.base.lights.alarm_stopped()
                with self.mpd_command(important=True):
                    self.player.delete(0)
                self.alarm_playing.clear()
Example #6
0
    def get_suggestions(self, request):
        terms = request.GET['term'].split()
        suggest_playlist = request.GET['playlist'] == 'true'

        results = []
        if suggest_playlist:
            remaining_playlists = ArchivedPlaylist.objects.prefetch_related(
                'queries')
            # exclude radios from suggestions
            remaining_playlists = remaining_playlists.exclude(
                list_id__startswith='RD').exclude(list_id__contains='&list=RD')

            for term in terms:
                remaining_playlists = remaining_playlists.filter(
                    Q(title__icontains=term)
                    | Q(queries__query__icontains=term))

            remaining_playlists = remaining_playlists \
                .values('id', 'title', 'counter') \
                .distinct() \
                .order_by('-counter') \
                [:20]

            for playlist in remaining_playlists:
                cached = False
                result_dict = {
                    'key': playlist['id'],
                    'value': playlist['title'],
                    'counter': playlist['counter'],
                    'type': 'cached' if cached else 'online',
                }
                results.append(result_dict)
        else:
            remaining_songs = ArchivedSong.objects.prefetch_related('queries')

            for term in terms:
                remaining_songs = remaining_songs.filter(
                    Q(title__icontains=term) | Q(artist__icontains=term)
                    | Q(queries__query__icontains=term))

            remaining_songs = remaining_songs \
                .values('id', 'title', 'url', 'artist', 'counter') \
                .distinct() \
                .order_by('-counter') \
                [:20]

            for song in remaining_songs:
                if song_utils.path_from_url(song['url']) is not None:
                    cached = True
                else:
                    cached = False
                # don't suggest online songs when we don't have internet
                if not self.musiq.base.settings.has_internet:
                    if not cached:
                        continue
                result_dict = {
                    'key': song['id'],
                    'value': song_utils.displayname(song['artist'],
                                                    song['title']),
                    'counter': song['counter'],
                    'type': 'cached' if cached else 'online',
                }
                results.append(result_dict)

        return HttpResponse(json.dumps(results))