Manipulating scanned results

All my Chinese song collection are stored in simplified Chinese. The scanned results are in traditional Chinese though, so if I save tags, they will get converted, which is not what I wanted. I wonder if there is an easy way to manipulate the results, so I can convert them back into simplified Chinese. Can someone point me to the right direction if scripting is required?

MusicBrainz will usually provide the releases in the script that was actually used on the release.

There is not really an easy way to do this I guess. What could be done is adding an additional pseudo release to the release group with all titles in simplified Chinese. Pseudo releases are not actually available but are used to provide translated / transliterated track listings. So providing a track listing in Simplified Chinese would be a valid use case for this.

4 Likes

so that means a pseudo release has to be added to every collection manually. Sounds like a big task. I guess I’ll just stay with what I have for now. Thanks for the explanation.

Well, somewhere Picard needs to get the track listing from :smiley:

I am not really familiar with the Chinese script, how well does automatic conversion between the two scripts (simplified, traditional) work? There is a library called opencc that allows conversion between the two, which would actually allow to create a plugin handling this conversion.

2 Likes

What about something like this :smiley:

Peek%202019-07-10%2020-49

Let me clean this up a bit and I can give you this as a plugin. What operating system do you use? It might get a little bit difficult if I have to package this for Windows or macOS, but I can try.

4 Likes

So here we go, hacked together a quick plugin and packaged it for Windows :smiley:

If you are using Windows you can download the plugin at https://keybase.pub/phwolfer/picard-plugins/opencc-windows.zip . Extract the ZIP file and place the opencc folder in your Picard plugins folder. You can find the plugin folder by opening Options > Plugins and clicking on ā€œOpen plugin folderā€.

NOTE: Installing this plugin as ZIP file won’t work, you have to extract it. Otherwise the included opencc.dll won’t get found.

UPDATE: Fixed it, things got easier. Download the ZIP file from https://keybase.pub/phwolfer/picard-plugins/opencc.zip , then open Picard Options > Plugins, click on ā€œInstall pluginā€¦ā€ and select the downloaded opencc.zip. This should install and activate the plugin ā€œChinese script conversionā€.

Start (or restart) Picard. The plugin should now show up in Options > Plugins. Activate it. Once activated you can right click on any albums, tracks or files and choose Plugins -> Convert to … Chinese.

Let me know if this plugin works for you. If something in the conversion doesn’t work as expected it can probably be changed. OpenCC provides various configurations for the conversion, including conversion to and from Hong Kong and Taiwan variants of the traditional script. For now I have used what is labeled simply ā€œTraditional Chinese to Simplified Chineseā€ and ā€œSimplified Chinese to Traditional Chineseā€ conversion.

If you are not using Windows but Linux install the plugin exactly as above. But you need to separately install opencc.

If you are using macOS you are out of luck for now :frowning:

6 Likes

Could you please upload the plugin again? The download link is not valid.
Thank you very much!

The latest version is at picard-plugins/plugins/opencc at opencc Ā· phw/picard-plugins Ā· GitHub

But bundling the opencc DLL for Windows failed for me at some point, so I removed it. That means the plugin in its current form will only for sure work on Linux and you need to install opencc separately.

In theory it should also be possible to make it run on Windows with a proper opencc DLL, but last time I tried I couldn’t make it work.

1 Like

My system is Windows, and I’m a programming rookie.
Anyway, thanks a lot.

I’m currently traveling, but I’ll take a look at this again once I’m back. This is actually a really nice plugin, but the problems with bundling the required opencc library have so far prevented me from submitting the plugin to the official plugin list.

4 Likes

I took a roundabout way to use this plugin on Windows.Use this docker as a localhost services:https://hub.docker.com/r/giterhub/opencc, so I could use the OpenCC API for this plugin

post the code here

# -*- coding: utf-8 -*-
#
# Copyright 2019, 2021 Philipp Wolfer < ph.wolfer@gmail.com >
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files(the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

PLUGIN_NAME = 'Chinese script conversion'
PLUGIN_AUTHOR = 'Philipp Wolfer'
PLUGIN_DESCRIPTION = """
Convert track listings between Traditional Chinese and Simplified Chinese script.

The conversion can be done manually or with scripting. For manual use right click
on album, tracks, clusters or files and choose the "Convert to Simplified Chinese"
or "Convert to Simplified Chinese" action.

For scripting you can use the following tagger functions:

- `$convert_to_simplified_chinese(text)`
- `$convert_to_traditional_chinese(text)`
"""
PLUGIN_VERSION = "1.3"
PLUGIN_API_VERSIONS = ["2.0", "2.1", "2.2", "2.3", "2.4", "2.5", "2.6"]
PLUGIN_LICENSE = "MIT"
PLUGIN_LICENSE_URL = "https://opensource.org/licenses/MIT"


from urllib.request import urlopen, Request

from picard import log
from picard.album import Album
from picard.cluster import Cluster
from picard.script import register_script_function
from picard.track import Track
from picard.ui.itemviews import (
    BaseAction,
    register_album_action,
    register_cluster_action,
    register_file_action,
    register_track_action,
)

import json


class ConvertChineseAction(BaseAction):
    api_url = "http://127.0.0.1:8900/api" # ← Change this to your OpenCC API endpoint
    convert_type = "t2s"

    def __init__(self, type):
        super().__init__()
        self.convert_type = type

    def callback(self, objs):
        for obj in objs:
            self.convert_object_metadata(obj)

    def convert(self, text):
        # print(f"content:{text}")
        base_data = {"type": self.convert_type, 
                     "content": text}
    
        req = Request(self.api_url, 
                      data=json.dumps(base_data).encode("utf-8"),
                      headers={"Content-Type": "application/json"},
                      method="POST")
        ret = "Error"
        with urlopen(req, timeout=5) as response:
            resp = response.read().decode("utf-8")
            result = json.loads(resp)
            ret = result["result"]
        return ret

    def convert_metadata(self, m):
        for key, value in list(m.items()):
            m[key] = self.convert(value)

    def convert_object_metadata(self, obj):
        if hasattr(obj, 'metadata'):
            self.convert_metadata(obj.metadata)
            obj.update()

        if isinstance(obj, Album):
            for track in obj.tracks:
                self.convert_object_metadata(track)
        elif isinstance(obj, Cluster):
            for file in obj.files:
                self.convert_object_metadata(file)
        elif isinstance(obj, Track):
            for file in obj.linked_files:
                self.convert_object_metadata(file)


class SimplifiedChineseConverter(ConvertChineseAction):
    NAME = "Convert to Simplified Chinese"

    def __init__(self):
        super().__init__('t2s')


class TraditionalChineseConverter(ConvertChineseAction):
    NAME = "Convert to Traditional Chinese"

    def __init__(self):
        super().__init__('s2t')


simplified_converter = SimplifiedChineseConverter()
traditional_converter = TraditionalChineseConverter()


def convert_to_simplified_chinese(parser, text):
    if not text:
        return ""
    return simplified_converter.convert(text)


def convert_to_traditional_chinese(parser, text):
    if not text:
        return ""
    return traditional_converter.convert(text)


register_album_action(simplified_converter)
register_cluster_action(simplified_converter)
register_file_action(simplified_converter)
register_track_action(simplified_converter)

register_album_action(traditional_converter)
register_cluster_action(traditional_converter)
register_file_action(traditional_converter)
register_track_action(traditional_converter)

register_script_function(convert_to_simplified_chinese)
register_script_function(convert_to_traditional_chinese)