Example #1
0
from datetime import datetime

from quodlibet import print_d
from quodlibet.formats import AudioFile
from quodlibet.query import Query, QueryType
from quodlibet.query._match import Tag, Inter, Union, Numcmp, NumexprTag, \
    Numexpr, True_, False_

INVERSE_OPS = {
    operator.le: operator.gt,
    operator.gt: operator.le,
    operator.lt: operator.ge,
    operator.ge: operator.lt
}

_DUMMY_AF = AudioFile()
_CLOCK = time.time


def convert_time(t):
    return datetime.strftime(datetime.fromtimestamp(int(t)), '%Y-%m-%d %H:%S')


# Convert QL to Soundcloud tags with optional value mapper
_QL_TO_SC = {
    'genre': ('genres', None),
    'length': ('duration', lambda x: int((x or 0) * 1000)),
    'date': ('created_at', convert_time),
    'tags': ('tags', None),
    'bpm': ('bpm', None),
    'artist': ('q', None),
Example #2
0
    def parse(self):
        try:
            doc = feedparser.parse(self.uri)
        except:
            return False

        try:
            album = doc.channel.title
        except AttributeError:
            return False

        if album:
            self.name = album
        else:
            self.name = _("Unknown")

        defaults = AudioFile({"feed": self.uri})
        try:
            self.__fill_af(doc.channel, defaults)
        except:
            return False

        entries = []
        uris = set()
        for entry in doc.entries:
            try:
                for enclosure in entry.enclosures:
                    try:
                        if ("audio" in enclosure.type
                                or "ogg" in enclosure.type
                                or formats.filter(enclosure.url)):
                            uri = enclosure.url.encode('ascii', 'replace')
                            try:
                                size = enclosure.length
                            except AttributeError:
                                size = 0
                            entries.append((uri, entry, size))
                            uris.add(uri)
                            break
                    except AttributeError:
                        pass
            except AttributeError:
                pass

        for entry in list(self):
            if entry["~uri"] not in uris:
                self.remove(entry)
            else:
                uris.remove(entry["~uri"])

        entries.reverse()
        for uri, entry, size in entries:
            if uri in uris:
                song = RemoteFile(uri)
                song["~#size"] = size
                song.fill_metadata = False
                song.update(defaults)
                song["album"] = self.name
                try:
                    self.__fill_af(entry, song)
                except:
                    pass
                else:
                    self.insert(0, song)
        self.__lastgot = time.time()
        return bool(uris)
Example #3
0
 def test_Menu(self):
     self.create_plugin(name='Name', desc='Desc', funcs=['plugin_song'])
     self.handler.Menu(None, [AudioFile()])
Example #4
0
# -*- coding: utf-8 -*-
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation

from collections import defaultdict

from quodlibet.formats import AudioFile
from quodlibet.order.reorder import OrderWeighted, OrderShuffle
from quodlibet.qltk.songmodel import PlaylistModel
from tests import TestCase

r0 = AudioFile({'~#rating': 0})
r1 = AudioFile({'~#rating': 0.33})
r2 = AudioFile({'~#rating': 0.66})
r3 = AudioFile({'~#rating': 1.0})


class TOrderWeighted(TestCase):

    def test_weighted(self):
        pl = PlaylistModel()
        pl.set([r3, r1, r2, r0])
        order = OrderWeighted()
        scores = defaultdict(int)
        for i in range(500):
            order.reset(pl)
            cur = pl.current_iter
            for j in range(3, -1, -1):
                cur = order.next_explicit(pl, cur)
                scores[pl[cur][0]] += j
Example #5
0
# Copyright 2017 Christoph Reiter
#           2021 halfbrained@github
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

from gi.repository import Gtk

from quodlibet.formats import AudioFile
from quodlibet.util.songwrapper import SongWrapper
from tests.plugin import PluginTestCase

AUDIO_FILE = SongWrapper(AudioFile({'~filename': "/tmp/foobar"}))


class Dummy:
    dummy_val = "str!"

    def dummy_meth(self, arg, varg=101):
        pass


DUMMY_COMPLETIONS = [
    ('dummy_meth', ' (arg, varg=101)'),
    ('dummy_val', ''),
]
NAMESPACE_COMPLETIONS = ('dummy', '')

Example #6
0
 def test_bookmark_invalid(self):
     af = AudioFile({"~bookmark": ("Not Valid\n1:40 Mark 2\n"
                                   "-20 Not Valid 2\n1:20 Mark 1")})
     self.failUnlessEqual(
         [(80, "Mark 1"), (100, "Mark 2"), (-1, "Not Valid"),
          (-1, "-20 Not Valid 2")], af.bookmarks)
Example #7
0
# -*- coding: utf-8 -*-
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation

from gi.repository import Gtk

from tests import TestCase

from quodlibet import config
from quodlibet.formats import AudioFile
from quodlibet.util.path import fsnative
from quodlibet.qltk.delete import DeleteDialog, TrashDialog, TrashMenuItem

SONG = AudioFile({"~filename": fsnative(u"/dev/null")})
SONG.sanitize()


class TDeleteDialog(TestCase):
    def setUp(self):
        config.init()

    def tearDown(self):
        config.quit()

    def test_delete_songs(self):
        dialog = DeleteDialog.for_songs(None, [])
        dialog.destroy()

    def test_delete_files(self):
        dialog = DeleteDialog.for_files(None, [])
Example #8
0
 def test_mountpoint_no_value(self):
     af = AudioFile({"~filename": fsnative(u"foo")})
     assert not Query(u"~mountpoint=bla").search(af)
Example #9
0
 def test_search_almostequal(self):
     a, b = AudioFile({"~#rating": 0.771}), AudioFile({"~#rating": 0.769})
     self.failUnless(Query("#(rating = 0.77)").search(a))
     self.failUnless(Query("#(rating = 0.77)").search(b))