Skip to content

[Plugin] Introduce merge_tags subroutine for plugins #1186

@psilabs-dev

Description

@psilabs-dev

This came up when I tried looking for a solution to #1140.

Currently, the method of tagging archives via metadata plugins goes through two stages: exec_metadata_plugin and set_tags. When exec_metadata_plugin is called, it finds tags for an archive which are not already in the archive, and this is done by logic in the subroutine.

For example, if existing tags are [a, b, c, d, e] and new tags are [c, d, e, f, g], then the tags returned by exec_metadata_plugin will be the set difference, [f, g].

set_tags then appends these new tags onto the old tags. Although its default behavior is to replace the archive's tags with its arguments completely, this append option is true in all calls accompanying exec_metadata_plugin.

Under this current code, the "merge policy" of metadata plugin calls is "append if not exists". For example, if existing tags are [a, b, artist_name:c, d, e] and new tags are [artist_name:f], then calling a metadata plugin will lead to the archive with tags [a, b, artist_name:c, d, e, artist_name:f]. Deletions will never occur with this policy.

While there is nothing unintended with the above feature, certain data sources have strict constraints. For instance in Pixiv, artist names and upload dates may change, but there can only be one artist name/upload date.

Although I can add logic to handle this specifically for Pixiv, such logic would be outside the scope of namespace-specific plugin contributions. I believe this logic can be added to all namespaced metadata code. Also, other plugins may benefit from being able to implement their own tag constraints.

Proposed is a low-impact, low-difficulty refactoring to add something like the following to all custom plugin files,

# Plugin ABC

sub get_tags {
    # get_tags logic
}

sub merge_tags($old_tags, $new_tags) {
    # plugin-specific tag merging logic, or fall back to "append if not exists" merging
    return $merged_tags;
}

...

Notice that actively implementing a merge_tags subroutine is not necessary; by default, "append if not exists" will be used. This subroutine should be offered in a common module.

Then, for setting tags, we have something like this:

%plugin_result = exec_metadata_plugin( $plugin, $id, %args );
my $old_tags = $redis->hget( $id, "tags" );
my $new_tags = $plugin_result{new_tags};
my $merged_tags = $plugin->merge_tags($old_tags, $new_tags);
set_tags( $id, $merged_tags ); # no need to append, replace with these tags.

In the case of Pixiv, the merge policy will look like this:

sub merge_tags($old_tags, $new_tags) {
    my @merged_tags;
    foreach my $tagtoadd (@tagarray) {
        # check if tag starts with "artist:" or "upload_date:", then check and remove from old tags
        # do usual check to see if tag is not in old tags
    }
}

We may also choose to include arguments in merge_tags which arise from plugin settings, that's up for separate discussion.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions