예제 #1
0
 def test_tag_query_escaped_pipe(s):
     pat = Pattern(r'<albumartist=/Lee\|Bob/|matched|not matched>')
     s.assertEquals(pat.format(s.g), 'matched')
     pat = Pattern(r'<albumartist=\||matched|not matched>')
     s.assertEquals(pat.format(s.g), 'not matched')
     pat = Pattern(r'<comment=/Trouble\|Strife/|matched|not matched>')
     s.assertEquals(pat.format(s.g), 'matched')
예제 #2
0
 def test_tag_query_regex(s):
     pat = Pattern("<album=/'only'/|matched|not matched>")
     s.assertEquals(pat.format(s.g), 'matched')
     pat = Pattern("<album=/The .+ way/|matched|not matched>")
     s.assertEquals(pat.format(s.g), 'matched')
     pat = Pattern("</The .+ way/|matched|not matched>")
     s.assertEquals(pat.format(s.g), 'not matched')
예제 #3
0
 def test_same2(s):
     fpat = FileFromPattern('<~filename>')
     pat = Pattern('<~filename>')
     s.assertEquals(fpat.format_list(s.a),
                    {(fpat.format(s.a), fpat.format(s.a))})
     s.assertEquals(pat.format_list(s.a),
                    {(pat.format(s.a), pat.format(s.a))})
예제 #4
0
 def test_space(self):
     pat = Pattern("a ")
     self.assertEqual(pat.format(self.a), "a ")
     pat = Pattern(" a")
     self.assertEqual(pat.format(self.a), " a")
     pat = Pattern("a\n\n")
     self.assertEqual(pat.format(self.a), "a\n\n")
예제 #5
0
 def test_same(s):
     pat = Pattern('<~basename> <title>')
     s.failUnlessEqual(pat.format_list(s.a),
                       {(pat.format(s.a), pat.format(s.a))})
     pat = Pattern('/a<genre|/<genre>>/<title>')
     s.failUnlessEqual(pat.format_list(s.a),
                       {(pat.format(s.a), pat.format(s.a))})
예제 #6
0
 def test_tag_internal(self):
     if os.name != "nt":
         pat = Pattern("<~filename='/path/to/a.mp3'|matched|not matched>")
         self.assertEquals(pat.format(self.a), 'matched')
         pat = Pattern(
             "<~filename=/\\/path\\/to\\/a.mp3/|matched|not matched>")
         self.assertEquals(pat.format(self.a), 'matched')
     else:
         pat = Pattern(
             r"<~filename='C:\\\path\\\to\\\a.mp3'|matched|not matched>")
         self.assertEquals(pat.format(self.a), 'matched')
예제 #7
0
파일: mqtt.py 프로젝트: Muges/quodlibet
 def plugin_on_song_started(self, song):
     self.song = song
     pat_str = self.config_get(*Config.PAT_PLAYING)
     pattern = Pattern(pat_str)
     status = (pattern.format(song) if song
               else self.config_get(Config.STATUS_SONGLESS, ""))
     self._set_status(status)
예제 #8
0
 def plugin_songs(self, songs):
     # Check this is a launch, not a configure
     if self.chosen_site:
         url_pat = self.get_url_pattern(self.chosen_site)
         pat = Pattern(url_pat)
         urls = set()
         for song in songs:
             # Generate a sanitised AudioFile; allow through most tags
             subs = AudioFile()
             for k in (USER_TAGS + MACHINE_TAGS):
                 vals = song.comma(k)
                 if vals:
                     try:
                         encoded = unicode(vals).encode('utf-8')
                         subs[k] = (encoded if k == 'website'
                                    else quote_plus(encoded))
                     # Dodgy unicode problems
                     except KeyError:
                         print_d("Problem with %s tag values: %r"
                                 % (k, vals))
             url = str(pat.format(subs))
             if not url:
                 print_w("Couldn't build URL using \"%s\"."
                         "Check your pattern?" % url_pat)
                 return
             # Grr, set.add() should return boolean...
             if url not in urls:
                 urls.add(url)
                 website(url)
예제 #9
0
    def test_escape_slash(s):
        fpat = s._create('<~filename>')
        s.assertTrue(fpat.format(s.a).endswith("_path_to_a.mp3"))

        pat = Pattern('<~filename>')
        if os.name != "nt":
            s.assertTrue(pat.format(s.a).startswith("/path/to/a"))
        else:
            s.assertTrue(pat.format(s.a).startswith("C:\\path\\to\\a"))

        if os.name != "nt":
            wpat = s._create(r'\\<artist>\\ "<title>')
            s.assertTrue(
                wpat.format(s.a).startswith(r'\Artist\ "Title5'))
        else:
            # FIXME..
            pass
예제 #10
0
def website_for(pat: Pattern, song: AudioFile) -> Optional[str]:
    """Gets a utf-8 encoded string for a website from the given pattern"""

    # Generate a sanitised AudioFile; allow through most tags
    subs = AudioFile()
    # See issue 2762
    for k in (USER_TAGS + MACHINE_TAGS + ['~filename']):
        vals = song.comma(k)
        if vals:
            try:
                # Escaping ~filename stops ~dirname ~basename etc working
                # But not escaping means ? % & will cause problems.
                # Who knows what user wants to do with /, seems better raw.
                subs[k] = (vals if k in ['website', '~filename']
                           else quote_plus(vals))
            except KeyError:
                print_d("Problem with %s tag values: %r" % (k, vals))
    return pat.format(subs) or None
예제 #11
0
 def test_conditional_equals(s):
     pat = Pattern('<artist=Artist|matched|not matched>')
     s.assertEquals(pat.format(s.a), 'matched')
     pat = Pattern('<artist=Artistic|matched|not matched>')
     s.assertEquals(pat.format(s.a), 'not matched')
예제 #12
0
 def test_conditional_genre(s):
     pat = Pattern('<genre|<genre>|music>')
     s.assertEquals(pat.format(s.a), 'music')
     s.assertEquals(pat.format(s.b), 'music')
     s.assertEquals(pat.format(s.c), '/, /')
예제 #13
0
class Command(JSONObject):
    """
    Wraps an arbitrary shell command and its argument pattern.
    Serialises as JSON for some editability
    """

    NAME = _("Command")

    FIELDS = {
        "name": Field(_("name"), _("The name of this command")),

        "command": Field(_("command"), _("The shell command syntax to run")),

        "parameter": Field(_("parameter"),
                           _("If specified, a parameter whose occurrences in "
                             "the command will be substituted with a "
                             "user-supplied value, e.g. by using 'PARAM' "
                             "all instances of '{PARAM}' in your command will "
                             "have the value prompted for when run")),

        "pattern": Field(_("pattern"),
                         _("The QL pattern, e.g. <~filename>, to use to "
                           "compute a value for the command. For playlists, "
                           "this also supports virtual tags <~playlistname> "
                           "and <~#playlistindex>.")),

        "unique": Field(_("unique"),
                        _("If set, this will remove duplicate computed values "
                          "of the pattern")),

        "max_args": Field(_("max args"),
                          _("The maximum number of argument to pass to the "
                            "command at one time (like xargs)")),
    }

    def __init__(self, name=None, command=None, pattern="<~filename>",
                 unique=False, parameter=None, max_args=10000,
                 warn_threshold=50):
        JSONObject.__init__(self, name)
        self.command = str(command or "")
        self.pattern = str(pattern)
        self.unique = bool(unique)
        self.max_args = max_args
        self.parameter = str(parameter or "")
        self.__pat = Pattern(self.pattern)
        self.warn_threshold = warn_threshold

    def run(self, songs, playlist_name=None):
        """
        Runs this command on `songs`,
        splitting into multiple calls if necessary.
        `playlist_name` if populated contains the Playlist's name.
        """
        args = []
        template_vars = {}
        if self.parameter:
            value = GetStringDialog(None, _("Input value"),
                                    _("Value for %s?") % self.parameter).run()
            template_vars[self.parameter] = value
        if playlist_name:
            print_d("Playlist command for %s" % playlist_name)
            template_vars["PLAYLIST"] = playlist_name
        self.command = self.command.format(**template_vars)
        print_d("Actual command=%s" % self.command)
        for i, song in enumerate(songs):
            wrapped = SongWrapper(song)
            if playlist_name:
                wrapped["~playlistname"] = playlist_name
                wrapped["~playlistindex"] = str(i + 1)
                wrapped["~#playlistindex"] = i + 1
            arg = str(self.__pat.format(wrapped))
            if not arg:
                print_w("Couldn't build shell command using \"%s\"."
                        "Check your pattern?" % self.pattern)
                break
            if not self.unique:
                args.append(arg)
            elif arg not in args:
                args.append(arg)
        max = int((self.max_args or 10000))
        com_words = self.command.split(" ")
        while args:
            print_d("Running %s with %d substituted arg(s) (of %d%s total)..."
                    % (self.command, min(max, len(args)), len(args),
                       " unique" if self.unique else ""))
            util.spawn(com_words + args[:max])
            args = args[max:]

    @property
    def playlists_only(self):
        return ("~playlistname" in self.pattern
                or "playlistindex" in self.pattern)

    def __str__(self):
        return 'Command: "{command} {pattern}"'.format(**dict(self.data))
예제 #14
0
 def test_same2(s):
     fpat = FileFromPattern('<~filename>')
     pat = Pattern('<~filename>')
     s.assertEquals(fpat.format_list(s.a), set([fpat.format(s.a)]))
     s.assertEquals(pat.format_list(s.a), set([pat.format(s.a)]))
예제 #15
0
 def test_query_like_tag(self):
     pat = Pattern("<t=v>")
     self.assertEqual(pat.format(AudioFile({"t=v": "foo"})), "foo")
예제 #16
0
 def test_query_scope(self):
     pat = Pattern("<foo|<artist=Foo|x|y>|<artist=Foo|z|q>>")
     self.assertEqual(pat.format(self.f), "z")
예제 #17
0
class Command(JSONObject):
    """
    Wraps an arbitrary shell command and its argument pattern.
    Serialises as JSON for some editability
    """

    NAME = _("Command")

    FIELDS = {
        "name": Field(_("name"), _("The name of this command")),

        "command": Field(_("command"), _("The shell command syntax to run")),

        "parameter": Field(_("parameter"),
                           _("If specified, a parameter whose occurrences in "
                             "the command will be substituted with a "
                             "user-supplied value, e.g. by using 'PARAM' "
                             "all instances of '{PARAM}' in your command will "
                             "have the value prompted for when run")),

        "pattern": Field(_("pattern"),
                         _("The QL pattern, e.g. <~filename>, to use to "
                           "compute a value for the command. For playlists, "
                           "this also supports virtual tags <~playlistname> "
                           "and <~#playlistindex>.")),

        "unique": Field(_("unique"),
                        _("If set, this will remove duplicate computed values "
                          "of the pattern")),

        "max_args": Field(_("max args"),
                          _("The maximum number of argument to pass to the "
                            "command at one time (like xargs)")),
    }

    def __init__(self, name=None, command=None, pattern="<~filename>",
                 unique=False, parameter=None, max_args=10000,
                 warn_threshold=50):
        JSONObject.__init__(self, name)
        self.command = str(command or "")
        self.pattern = str(pattern)
        self.unique = bool(unique)
        self.max_args = max_args
        self.parameter = str(parameter or "")
        self.__pat = Pattern(self.pattern)
        self.warn_threshold = warn_threshold

    def run(self, songs, playlist_name=None):
        """
        Runs this command on `songs`,
        splitting into multiple calls if necessary.
        `playlist_name` if populated contains the Playlist's name.
        """
        args = []
        template_vars = {}
        if self.parameter:
            value = GetStringDialog(None, _("Input value"),
                                    _("Value for %s?") % self.parameter).run()
            template_vars[self.parameter] = value
        if playlist_name:
            print_d("Playlist command for %s" % playlist_name)
            template_vars["PLAYLIST"] = playlist_name

        actual_command = self.command.format(**template_vars)
        print_d("Actual command=%s" % actual_command)
        for i, song in enumerate(songs):
            wrapped = SongWrapper(song)
            if playlist_name:
                wrapped["~playlistname"] = playlist_name
                wrapped["~playlistindex"] = str(i + 1)
                wrapped["~#playlistindex"] = i + 1
            arg = str(self.__pat.format(wrapped))
            if not arg:
                print_w("Couldn't build shell command using \"%s\"."
                        "Check your pattern?" % self.pattern)
                break
            if not self.unique:
                args.append(arg)
            elif arg not in args:
                args.append(arg)
        max = int((self.max_args or 10000))
        com_words = actual_command.split(" ")
        while args:
            print_d("Running %s with %d substituted arg(s) (of %d%s total)..."
                    % (actual_command, min(max, len(args)), len(args),
                       " unique" if self.unique else ""))
            util.spawn(com_words + args[:max])
            args = args[max:]

    @property
    def playlists_only(self):
        return ("~playlistname" in self.pattern
                or "playlistindex" in self.pattern)

    def __str__(self):
        return "{command} {pattern}".format(**dict(self.data))
예제 #18
0
 def test_conditional_other_number_dot_title(s):
     pat = Pattern('<tracknumber|<tracknumber>|00>. <title>')
     s.assertEquals(pat.format(s.a), '5/6. Title5')
     s.assertEquals(pat.format(s.b), '6. Title6')
     s.assertEquals(pat.format(s.c), '00. test/subdir')
예제 #19
0
 def test_duplicate_query(self):
     pat = Pattern('<u=yes|<u=yes|x|y>|<u=yes|q|z>>')
     self.assertEqual(pat.format(AudioFile({"u": u"yes"})), "x")
     self.assertEqual(pat.format(AudioFile({"u": u"no"})), "z")
예제 #20
0
 def test_recnumber_dot_title(s):
     pat = Pattern(r'\<<tracknumber>\>. <title>')
     s.assertEquals(pat.format(s.a), '<5/6>. Title5')
     s.assertEquals(pat.format(s.b), '<6>. Title6')
     s.assertEquals(pat.format(s.c), '<>. test/subdir')
예제 #21
0
 def test_tag_query_quoting(s):
     pat = Pattern('<album=The only way|matched|not matched>')
     s.assertEquals(pat.format(s.g), 'not matched')
     pat = Pattern("<album=\"The 'only' way!\"|matched|not matched>")
     s.assertEquals(pat.format(s.g), 'matched')
예제 #22
0
 def test_number_dot_genre(s):
     pat = Pattern('<tracknumber>. <genre>')
     s.assertEquals(pat.format(s.a), '5/6. ')
     s.assertEquals(pat.format(s.b), '6. ')
     s.assertEquals(pat.format(s.c), '. /, /')
예제 #23
0
 def test_conditional_notfile(s):
     pat = Pattern('<tracknumber|<tracknumber>|00>')
     s.assertEquals(pat.format(s.a), '5/6')
     s.assertEquals(pat.format(s.b), '6')
     s.assertEquals(pat.format(s.c), '00')
예제 #24
0
    def test_escape(self):
        pat = Pattern("a \\<foo\\|bla\\>")
        self.assertEqual(pat.format(self.a), "a <foo|bla>")

        pat = Pattern(r"a\\<foo>")
        self.assertEqual(pat.format(self.a), "a\\")
예제 #25
0
 def test_generated_and_not_generated(s):
     pat = Pattern('<~basename> <title>')
     res = pat.format(s.a)
     s.assertEquals(
         res, os.path.basename(s.a["~filename"]) + " " + s.a["title"])
예제 #26
0
 def test_conditional_unknown(s):
     pat = Pattern('<album|foo|bar>')
     s.assertEquals(pat.format(s.a), 'bar')
예제 #27
0
 def test_numeric(self):
     pat = Pattern("<~#rating>")
     self.assertEqual(pat.format(self.a), "0.50")
예제 #28
0
 def test_conditional_equals_unicode(s):
     pat = Pattern(u'<artist=Artist|matched|not matched>')
     s.assertEquals(pat.format(s.g), 'not matched')
     pat = Pattern(u'<artist=un élève français|matched|not matched>')
     s.assertEquals(pat.format(s.g), 'matched')
예제 #29
0
 def test_tag_internal(self):
     pat = Pattern("<~filename='/path/to/a.mp3'|matched|not matched>")
     self.assertEquals(pat.format(self.a), 'matched')
     pat = Pattern("<~filename=/\\/path\\/to\\/a.mp3/|matched|not matched>")
     self.assertEquals(pat.format(self.a), 'matched')
예제 #30
0
 def test_same(s):
     pat = Pattern('<~basename> <title>')
     s.failUnlessEqual(pat.format_list(s.a), set([pat.format(s.a)]))
     pat = Pattern('/a<genre|/<genre>>/<title>')
     s.failUnlessEqual(pat.format_list(s.a), set([pat.format(s.a)]))
예제 #31
0
 def test_conditional_equals(s):
     pat = Pattern('<artist=Artist|matched|not matched>')
     s.assertEquals(pat.format(s.a), 'matched')
     pat = Pattern('<artist=Artistic|matched|not matched>')
     s.assertEquals(pat.format(s.a), 'not matched')
예제 #32
0
 def test_query_scope(self):
     pat = Pattern("<foo|<artist=Foo|x|y>|<artist=Foo|z|q>>")
     self.assertEqual(pat.format(self.f), "z")
예제 #33
0
 def test_duplicate_query(self):
     pat = Pattern('<u=yes|<u=yes|x|y>|<u=yes|q|z>>')
     self.assertEqual(pat.format(AudioFile({"u": "yes"})), "x")
     self.assertEqual(pat.format(AudioFile({"u": "no"})), "z")
예제 #34
0
 def test_query_numeric(self):
     pat = Pattern("<#(foo=42)|42|other>")
     self.assertEqual(pat.format(AudioFile()), "other")
     self.assertEqual(pat.format(AudioFile({"foo": "42"})), "42")
예제 #35
0
파일: mqtt.py 프로젝트: tonydolan/quodlibet
 def plugin_on_paused(self):
     pat_str = self.config_get(*Config.PAT_PAUSED)
     pattern = Pattern(pat_str)
     self.status = pattern.format(self.song) if self.song else ""
     self._set_status(self.status)
예제 #36
0
 def test_conditional_notfile(s):
     pat = Pattern('<tracknumber|<tracknumber>|00>')
     s.assertEquals(pat.format(s.a), '5/6')
     s.assertEquals(pat.format(s.b), '6')
     s.assertEquals(pat.format(s.c), '00')
예제 #37
0
 def test_conditional_unknown(s):
     pat = Pattern('<album|foo|bar>')
     s.assertEquals(pat.format(s.a), 'bar')
예제 #38
0
 def test_conditional_subdir(s):
     pat = Pattern('/a<genre|/<genre>>/<title>')
     s.assertEquals(pat.format(s.a), '/a/Title5')
     s.assertEquals(pat.format(s.b), '/a/Title6')
     s.assertEquals(pat.format(s.c), '/a//, //test/subdir')
예제 #39
0
 def test_conditional_equals_unicode(s):
     pat = Pattern(u'<artist=Artist|matched|not matched>')
     s.assertEquals(pat.format(s.g), 'not matched')
     pat = Pattern(u'<artist=un élève français|matched|not matched>')
     s.assertEquals(pat.format(s.g), 'matched')
예제 #40
0
 def test_recnumber_dot_title(s):
     pat = Pattern('\<<tracknumber>\>. <title>')
     s.assertEquals(pat.format(s.a), '<5/6>. Title5')
     s.assertEquals(pat.format(s.b), '<6>. Title6')
     s.assertEquals(pat.format(s.c), '<>. test/subdir')
예제 #41
0
 def test_tag_query_escaping(s):
     pat = Pattern('<albumartist=Lee "Scratch" Perry|matched|not matched>')
     s.assertEquals(pat.format(s.g), 'matched')
예제 #42
0
 def test_generated(s):
     pat = Pattern('<~basename>')
     s.assertEquals(pat.format(s.a), os.path.basename(s.a["~filename"]))
예제 #43
0
 def test_tag_query_disallowed_free_text(s):
     pat = Pattern("<The only way|matched|not matched>")
     s.assertEquals(pat.format(s.g), 'not matched')
예제 #44
0
 def test_generated_and_not_generated(s):
     pat = Pattern('<~basename> <title>')
     res = pat.format(s.a)
     s.assertEquals(
         res, os.path.basename(s.a["~filename"]) + " " + s.a["title"])
예제 #45
0
 def test_query_numeric(self):
     pat = Pattern("<#(foo=42)|42|other>")
     self.assertEqual(pat.format(AudioFile()), "other")
     self.assertEqual(pat.format(AudioFile({"foo": "42"})), "42")
예제 #46
0
 def test_number_dot_title_dot(s):
     pat = Pattern('<tracknumber>. <title>.')
     s.assertEquals(pat.format(s.a), '5/6. Title5.')
     s.assertEquals(pat.format(s.b), '6. Title6.')
     s.assertEquals(pat.format(s.c), '. test/subdir.')
예제 #47
0
 def test_conditional_subdir(s):
     pat = Pattern('/a<genre|/<genre>>/<title>')
     s.assertEquals(pat.format(s.a), '/a/Title5')
     s.assertEquals(pat.format(s.b), '/a/Title6')
     s.assertEquals(pat.format(s.c), '/a//, //test/subdir')
예제 #48
0
 def test_number_dot_genre(s):
     pat = Pattern('<tracknumber>. <genre>')
     s.assertEquals(pat.format(s.a), '5/6. ')
     s.assertEquals(pat.format(s.b), '6. ')
     s.assertEquals(pat.format(s.c), '. /, /')
예제 #49
0
 def test_generated(s):
     pat = Pattern('<~basename>')
     s.assertEquals(pat.format(s.a), os.path.basename(s.a["~filename"]))
예제 #50
0
 def test_unicode_with_int(s):
     song = AudioFile({"tracknumber": "5/6",
         "title": "\xe3\x81\x99\xe3\x81\xbf\xe3\x82\x8c".decode('utf-8')})
     pat = Pattern('<~#track>. <title>')
     s.assertEquals(pat.format(song),
         "5. \xe3\x81\x99\xe3\x81\xbf\xe3\x82\x8c".decode('utf-8'))
예제 #51
0
 def test_number_dot_title_dot(s):
     pat = Pattern('<tracknumber>. <title>.')
     s.assertEquals(pat.format(s.a), '5/6. Title5.')
     s.assertEquals(pat.format(s.b), '6. Title6.')
     s.assertEquals(pat.format(s.c), '. test/subdir.')
예제 #52
0
 def test_query_like_tag(self):
     pat = Pattern("<t=v>")
     self.assertEqual(pat.format(AudioFile({"t=v": "foo"})), "foo")
예제 #53
0
 def test_unicode_with_int(s):
     song = AudioFile({"tracknumber": "5/6",
         "title": b"\xe3\x81\x99\xe3\x81\xbf\xe3\x82\x8c".decode('utf-8')})
     pat = Pattern('<~#track>. <title>')
     s.assertEquals(pat.format(song),
         b"5. \xe3\x81\x99\xe3\x81\xbf\xe3\x82\x8c".decode('utf-8'))
예제 #54
0
 def test_conditional_other_number_dot_title(s):
     pat = Pattern('<tracknumber|<tracknumber>|00>. <title>')
     s.assertEquals(pat.format(s.a), '5/6. Title5')
     s.assertEquals(pat.format(s.b), '6. Title6')
     s.assertEquals(pat.format(s.c), '00. test/subdir')
예제 #55
0
class Command(JSONObject):
    """
    Wraps an arbitrary shell command and its argument pattern.
    Serialises as JSON for some editability
    """

    NAME = _("Command")

    FIELDS = {
        "name": Field(_("name"), _("The name of this command")),

        "command": Field(_("command"), _("The shell command syntax to run")),

        "parameter": Field(_("parameter"),
                           _("If specified, a parameter whose occurrences in "
                             "the command will be substituted with a "
                             "user-supplied value, e.g. by using 'PARAM' "
                             "all instances of '{PARAM}' in your command will "
                             "have the value prompted for when run")),

        "pattern": Field(_("pattern"),
                         _("The QL pattern, e.g. <~filename>, to use to "
                           "compute a value for the command")),

        "unique": Field(_("unique"),
                        _("If set, this will remove duplicate computed values "
                          "of the pattern")),

        "max_args": Field(_("max args"),
                          _("The maximum number of argument to pass to the "
                            "command at one time (like xargs)")),
    }

    def __init__(self, name=None, command=None, pattern="<~filename>",
                 unique=False, parameter=None, max_args=10000,
                 warn_threshold=100):
        JSONObject.__init__(self, name)
        self.command = str(command or "")
        self.pattern = str(pattern)
        self.unique = bool(unique)
        self.max_args = max_args
        self.parameter = str(parameter or "")
        self.__pat = Pattern(self.pattern)
        self.warn_threshold = warn_threshold

    def run(self, songs):
        """
        Runs this command on `songs`,
        splitting into multiple calls if necessary
        """
        args = []
        if self.parameter:
            value = GetStringDialog(None, _("Input value"),
                                    _("Value for %s?") % self.parameter).run()
            self.command = self.command.format(**{self.parameter: value})
            print_d("Actual command=%s" % self.command)
        for song in songs:
            arg = str(self.__pat.format(song))
            if not arg:
                print_w("Couldn't build shell command using \"%s\"."
                        "Check your pattern?" % self.pattern)
                break
            if not self.unique:
                args.append(arg)
            elif arg not in args:
                args.append(arg)
        max = int((self.max_args or 10000))
        com_words = self.command.split(" ")
        while args:
            print_d("Running %s with %d substituted arg(s) (of %d%s total)..."
                    % (self.command, min(max, len(args)), len(args),
                       " unique" if self.unique else ""))
            util.spawn(com_words + args[:max])
            args = args[max:]

    def __str__(self):
        return "Command= {command} {pattern}".format(**dict(self.data))
예제 #56
0
 def test_conditional_genre(s):
     pat = Pattern('<genre|<genre>|music>')
     s.assertEquals(pat.format(s.a), 'music')
     s.assertEquals(pat.format(s.b), 'music')
     s.assertEquals(pat.format(s.c), '/, /')
예제 #57
0
파일: mqtt.py 프로젝트: Muges/quodlibet
 def plugin_on_paused(self):
     pat_str = self.config_get(*Config.PAT_PAUSED)
     pattern = Pattern(pat_str)
     self.status = pattern.format(self.song) if self.song else ""
     self._set_status(self.status)
예제 #58
0
class Command(JSONObject):
    """
    Wraps an arbitrary shell command and its argument pattern.
    Serialises as JSON for some editability
    """

    NAME = _("Command")

    FIELDS = {
        "name":
        Field(_("name"), _("The name of this command")),
        "command":
        Field(_("command"), _("The shell command syntax to run")),
        "parameter":
        Field(
            _("parameter"),
            _("If specified, a parameter whose occurrences in "
              "the command will be substituted with a "
              "user-supplied value, e.g. by using 'PARAM' "
              "all instances of '{PARAM}' in your command will "
              "have the value prompted for when run")),
        "pattern":
        Field(
            _("pattern"),
            _("The QL pattern, e.g. <~filename>, to use to "
              "compute a value for the command")),
        "unique":
        Field(
            _("unique"),
            _("If set, this will remove duplicate computed values "
              "of the pattern")),
        "max_args":
        Field(
            _("max args"),
            _("The maximum number of argument to pass to the "
              "command at one time (like xargs)")),
    }

    def __init__(self,
                 name=None,
                 command=None,
                 pattern="<~filename>",
                 unique=False,
                 parameter=None,
                 max_args=10000,
                 warn_threshold=100):
        JSONObject.__init__(self, name)
        self.command = str(command or "")
        self.pattern = str(pattern)
        self.unique = bool(unique)
        self.max_args = max_args
        self.parameter = str(parameter or "")
        self.__pat = Pattern(self.pattern)
        self.warn_threshold = warn_threshold

    def run(self, songs):
        """
        Runs this command on `songs`,
        splitting into multiple calls if necessary
        """
        args = []
        if self.parameter:
            value = GetStringDialog(None, _("Input value"),
                                    _("Value for %s?") % self.parameter).run()
            self.command = self.command.format(**{self.parameter: value})
            print_d("Actual command=%s" % self.command)
        for song in songs:
            arg = str(self.__pat.format(song))
            if not arg:
                print_w("Couldn't build shell command using \"%s\"."
                        "Check your pattern?" % self.pattern)
                break
            if not self.unique:
                args.append(arg)
            elif arg not in args:
                args.append(arg)
        max = int((self.max_args or 10000))
        com_words = self.command.split(" ")
        while args:
            print_d(
                "Running %s with %d substituted arg(s) (of %d%s total)..." %
                (self.command, min(max, len(args)), len(args),
                 " unique" if self.unique else ""))
            util.spawn(com_words + args[:max])
            args = args[max:]

    def __str__(self):
        return "Command= {command} {pattern}".format(**dict(self.data))