def test_required_kwonly_parameters(self): def func(a, *, required_kwarg): pass with self.assertRaises(TypeError, msg="Functions with required keyword-only parameters are not supported"): register_script_function(func)
def setUp(self): config.setting = { 'enabled_plugins': '', } self.parser = ScriptParser() def func_noargstest(parser): return "" register_script_function(func_noargstest, "noargstest")
def sanitize(char): if char in CHAR_TABLE: return CHAR_TABLE[char] return char def fix_forbidden(word): return "".join(sanitize(char) for char in word) def replace_forbidden(value): return [fix_forbidden(x) for x in value] def script_replace_forbidden(parser, value): return fix_forbidden(value) def main(tagger, metadata, release, track=None): for name, value in metadata.rawitems(): if name in FILTER_TAGS: metadata[name] = replace_forbidden(value) metadata.register_track_metadata_processor(main) metadata.register_album_metadata_processor(main) register_script_function(script_replace_forbidden, name="replace_forbidden")
PLUGIN_AUTHOR = "Wieland Hoffmann" PLUGIN_DESCRIPTION = """Adds a `stop` function that can be used to stop the file naming string at a specific point. It's useful if you have several different file naming schemes with lots of nested `if`s. This does *only* work for file naming.""" PLUGIN_VERSION = "0.1" PLUGIN_API_VERSIONS = ["0.15", "0.16", "2.0"] from picard.script import register_script_function, ScriptParser STOP_MARKER = '-\o\-JUSTSTOPHERE-/o/-' class StoppingScriptParser(ScriptParser): def eval(self, script, context=None, file=None): result = ScriptParser.eval(self, script, context, file) return result.split(STOP_MARKER)[0] from picard.ui.options import renaming renaming.ScriptParser = StoppingScriptParser from picard import file file.ScriptParser = StoppingScriptParser def stop(parser, emptyarg): return STOP_MARKER register_script_function(stop)
@register_track_metadata_processor def track_metadata_processor(album, metadata, track_node, release_node): """ Determine track metadata using track and artist last.fm tags """ log.info('received track metadata trigger') lfmws = LastFMTagger(album, metadata, release_node) lfmws.before_finalize.append(lfmws.process_track_tags) lfmws.request_track_toptags() lfmws.request_artist_toptags() @register_album_metadata_processor def album_metadata_processor(album, metadata, release_node): """ Determine album metadata using album and all artist and all track last.fm tags in the album. """ log.info('received album metadata trigger') lfmws = LastFMTagger(album, metadata, release_node) lfmws.before_finalize.append(lfmws.process_album_tags) lfmws.request_album_toptags() lfmws.request_all_track_toptags() lfmws.request_all_artist_toptags() register_script_function(func_set2, "set2")
PLUGIN_NAME = 'NFC/NFD functions' PLUGIN_AUTHOR = '' PLUGIN_DESCRIPTION = 'Adds $nfc(text) and $nfd(text) functions for converting strings to NFC or NFD' PLUGIN_VERSION = "0.1" PLUGIN_API_VERSIONS = ["1.0"] from picard.script import register_script_function import unicodedata def nfc(parser, text, *prefixes): return unicodedata.normalize("NFC", text) def nfd(parser, text, *prefixes): return unicodedata.normalize("NFD", text) register_script_function(nfc) register_script_function(nfd)
PLUGIN_NAME = "$ne2" PLUGIN_AUTHOR = "Brian Schweitzer" PLUGIN_DESCRIPTION = "Adds an $ne2 function" PLUGIN_VERSION = "0.2" PLUGIN_API_VERSIONS = ["0.12", "0.13", "0.14", "0.15", "0.16"] from picard.script import register_script_function def func_ne2(parser, x, *args): for i in (i for i in args if i == x): return "" return "1" register_script_function(func_ne2, "ne2")
script_to_filename, script_to_filename_with_metadata, ) settings = { 'ascii_filenames': False, 'enabled_plugins': [], 'windows_compatibility': False, } def func_has_file(parser): return '1' if parser.file else '' register_script_function(lambda p: '1' if p.file else '', 'has_file') class ScriptToFilenameTest(PicardTestCase): def setUp(self): super().setUp() self.set_config_values(settings) def test_plain_filename(self): metadata = Metadata() filename = script_to_filename('AlbumArt', metadata) self.assertEqual('AlbumArt', filename) def test_simple_script(self): metadata = Metadata() metadata['artist'] = 'AC/DC'
PLUGIN_NAME = '$ne2' PLUGIN_AUTHOR = 'Brian Schweitzer' PLUGIN_DESCRIPTION = 'Adds an $ne2 function' PLUGIN_VERSION = "0.2" PLUGIN_API_VERSIONS = ["0.12", "0.13", "0.14", "0.15", "0.16"] from picard.script import register_script_function def func_ne2(parser, x, *args): for i in (i for i in args if i == x): return "" return "1" register_script_function(func_ne2, "ne2")
def test_optional_kwonly_parameters(self): def func(a, *, optional_kwarg=1): pass register_script_function(func)
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. PLUGIN_NAME = 'Video tools' PLUGIN_AUTHOR = 'Philipp Wolfer' PLUGIN_DESCRIPTION = 'Improves the video support in Picard by adding support for Matroska, WebM, AVI, QuickTime and MPEG files (renaming and fingerprinting only, no tagging) and providing $is_audio() and $is_video() scripting functions.' PLUGIN_VERSION = "0.3" PLUGIN_API_VERSIONS = ["1.3.0", "2.0"] PLUGIN_LICENSE = "GPL-2.0-or-later" PLUGIN_LICENSE_URL = "https://www.gnu.org/licenses/gpl-2.0.html" from picard.formats import register_format from picard.script import register_script_function from picard.plugins.videotools.formats import MatroskaFile, MpegFile, QuickTimeFile, RiffFile from picard.plugins.videotools.script import is_audio, is_video # Now this is kind of a hack, but Picard won't process registered objects that # are in a submodule of a plugin. I still want the code to be in separate files. MatroskaFile.__module__ = MpegFile.__module__ = QuickTimeFile.__module__ = \ RiffFile.__module__ = is_audio.__module__ = is_video.__module__ = \ __name__ register_format(MatroskaFile) register_format(MpegFile) register_format(QuickTimeFile) register_format(RiffFile) register_script_function(is_audio) register_script_function(is_video)
PLUGIN_NAME = 'swapprefix function' PLUGIN_AUTHOR = 'Philipp Wolfer' PLUGIN_DESCRIPTION = 'Moves the specified prefixes to the end of a string.' PLUGIN_VERSION = "0.1" PLUGIN_API_VERSIONS = ["0.9.0", "0.10", "0.11", "0.12", "0.15"] from picard.script import register_script_function import re def swapprefix(parser, text, *prefixes): """ Moves the specified prefixes to the end of text. If no prefix is specified 'A' and 'The' are taken as default. """ if not prefixes: prefixes = ('A', 'The') for prefix in prefixes: pattern = re.compile('^' + re.escape(prefix) + '\s') match = pattern.match(text) if match: rest = pattern.split(text)[1].strip() if rest: return ", ".join((rest, match.group(0).rstrip())) return text register_script_function(swapprefix)
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. PLUGIN_NAME = 'Video tools' PLUGIN_AUTHOR = 'Philipp Wolfer' PLUGIN_DESCRIPTION = 'Improves the video support in Picard by adding support for Matroska, WebM, AVI, QuickTime and MPEG files (renaming and fingerprinting only, no tagging) and providing $is_audio() and $is_video() scripting functions.' PLUGIN_VERSION = "0.1" PLUGIN_API_VERSIONS = ["1.3.0"] PLUGIN_LICENSE = "GPL-2.0" PLUGIN_LICENSE_URL = "https://www.gnu.org/licenses/gpl-2.0.html" from picard.formats import register_format from picard.script import register_script_function from picard.plugins.videotools.formats import MatroskaFile, MpegFile, QuickTimeFile, RiffFile from picard.plugins.videotools.script import is_audio, is_video # Now this is kind of a hack, but Picard won't process registered objects that # are in a submodule of a plugin. I still want the code to be in separate files. MatroskaFile.__module__ = MpegFile.__module__ = QuickTimeFile.__module__ = \ RiffFile.__module__ = is_audio.__module__ = is_video.__module__ = \ __name__ register_format(MatroskaFile) register_format(MpegFile) register_format(QuickTimeFile) register_format(RiffFile) register_script_function(is_audio) register_script_function(is_video)
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. PLUGIN_NAME = 'swapprefix function' PLUGIN_AUTHOR = 'Philipp Wolfer' PLUGIN_DESCRIPTION = 'Moves the specified prefixes to the end of a string.' PLUGIN_VERSION = "0.1" PLUGIN_API_VERSIONS = ["0.9.0", "0.10", "0.11", "0.12", "0.15"] from picard.script import register_script_function import re def swapprefix(parser, text, *prefixes): """ Moves the specified prefixes to the end of text. If no prefix is specified 'A' and 'The' are taken as default. """ if not prefixes: prefixes = ('A', 'The') for prefix in prefixes: pattern = re.compile('^' + re.escape(prefix) + '\s') match = pattern.match(text) if match: rest = pattern.split(text)[1].strip() if rest: return ", ".join((rest, match.group(0).rstrip())) return text register_script_function(swapprefix)
'regex' : re.compile(ur"[\uA000-\uA014\uA015\uA016-\uA48C\uA490-\uA4C6]")}, 'zarkhand' : { 'name' : u"Zarkhánd", 'official' : False, 'regex' : re.compile(ur"[\uE470-\uE48F]")}, 'zirinka' : { 'name' : u"Zírí:Nka", 'official' : False, 'regex' : re.compile(ur"[\uE340-\uE35F]")} } def func_p(parser, teststr, onlyofficial = False): try: if teststr is not None : testchar = teststr for script in scripts['scripts'] : match = scripts[script]['regex'].match(testchar) if match : if scripts[script]['official'] == False : if onlyofficial : return "Common or Unknown" else : return script else : return script except ValueError: pass return "Common or Unknown" register_script_function(func_p, "p")
from picard.script import register_script_function from picard.util.scripttofilename import script_to_filename settings = { 'ascii_filenames': False, 'enabled_plugins': [], 'windows_compatibility': False, } def func_has_file(parser): return '1' if parser.file else '' register_script_function(lambda p: '1' if p.file else '', 'has_file') class ScriptToFilenameTest(PicardTestCase): def setUp(self): super().setUp() config.setting = settings.copy() def test_plain_filename(self): metadata = Metadata() filename = script_to_filename('AlbumArt', metadata) self.assertEqual('AlbumArt', filename) def test_simple_script(self): metadata = Metadata()
PLUGIN_NAME = 'Add to collection' PLUGIN_AUTHOR = 'Wieland Hoffmann' PLUGIN_DESCRIPTION = 'Adds an $add_to_collection function' PLUGIN_VERSION = '0.1' PLUGIN_API_VERSIONS = ['2.0'] from picard import collection from picard.script import register_script_function def callback(*args, **kwargs): pass def add_to_collection(parser, collectionid): mbid = parser.context['musicbrainz_albumid'] try: thiscollection = collection.user_collections[collectionid] except KeyError: return '' if str(mbid) in thiscollection.releases or mbid in thiscollection.pending: return '' thiscollection.add_releases(set([mbid]), callback) return '' register_script_function(add_to_collection)
PLUGIN_NAME = '$eq2' PLUGIN_AUTHOR = 'Brian Schweitzer' PLUGIN_DESCRIPTION = 'Adds an $eq2 function' PLUGIN_VERSION = "0.2.2" PLUGIN_API_VERSIONS = ["0.12", "0.13", "0.14", "0.15", "0.16"] from picard.script import register_script_function def func_eq2(parser, x, *args): for i in (i for i in args if i == x): return "1" return '' register_script_function(func_eq2, "eq2")
>>> decade("2017-07-20") '2010s' >>> decade("2020") '2020s' >>> decade("992") '990s' >>> decade("992-01") '990s' >>> decade("") '' >>> decade(None) '' >>> decade("foo") '' """ try: year = int(date.split('-')[0]) except (AttributeError, ValueError): return "" decade = year // 10 * 10 if shorten and 1920 <= decade < 2000: decade -= 1900 return "%ds" % decade def script_decade(parser, value, shorten=True): return decade(value, shorten and shorten != '0') register_script_function(script_decade, name="decade")
PLUGIN_API_VERSIONS = [ "0.15.0", "0.15.1", "0.16.0", "1.0.0", "1.1.0", "1.2.0", "1.3.0", ] PLUGIN_LICENSE = "GPL-2.0" PLUGIN_LICENSE_URL = "https://www.gnu.org/licenses/gpl-2.0.html" from picard.script import register_script_function def transltag(tag): if tag.startswith("~"): return "_" + tag[1:] return tag def keep(parser, *keeptags): for tag in parser.context.keys(): if (transltag(tag) not in keeptags and not tag.startswith("musicbrainz_") and not tag[0] == "~"): parser.context.pop(tag, None) return "" register_script_function(keep)
PLUGIN_AUTHOR = "Wieland Hoffmann" PLUGIN_DESCRIPTION = """ Adds a $keep() function to delete all tags except the ones that you want. Tags beginning with `musicbrainz_` are kept automatically, as are tags beginning with `_`.""" PLUGIN_VERSION = "1.1" PLUGIN_API_VERSIONS = ["0.15.0", "0.15.1", "0.16.0", "1.0.0", "1.1.0", "1.2.0", "1.3.0", ] PLUGIN_LICENSE = "GPL-2.0" PLUGIN_LICENSE_URL = "https://www.gnu.org/licenses/gpl-2.0.html" from picard.script import register_script_function def transltag(tag): if tag.startswith("~"): return "_" + tag[1:] return tag def keep(parser, *keeptags): for tag in parser.context.keys(): if (transltag(tag) not in keeptags and not tag.startswith("musicbrainz_") and not tag[0] == "~"): parser.context.pop(tag, None) return "" register_script_function(keep)
from picard.script import register_script_function @register_track_metadata_processor def track_metadata_processor(album, metadata, track_node, release_node): """ Determine track metadata using track and artist last.fm tags """ lfmws = LastFMTagger(album, metadata, release_node) lfmws.before_finalize.append(lfmws.process_track_tags) lfmws.request_track_toptags() lfmws.request_artist_toptags() @register_album_metadata_processor def album_metadata_processor(album, metadata, release_node): """ Determine album metadata using album and all artist and all track last.fm tags in the album. """ lfmws = LastFMTagger(album, metadata, release_node) lfmws.before_finalize.append(lfmws.process_album_tags) lfmws.request_album_toptags() lfmws.request_all_track_toptags() lfmws.request_all_artist_toptags() register_script_function(func_set2, "set2")