Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: Watching tag edits to update metadb hashes (Read 1152 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Watching tag edits to update metadb hashes

So thanks to Peter's help I've been able to get my plugin working correctly with creating a metadb, and storing values in it based on a hash.  Now what I need is a way to move the data in the metadb from the old to new hash when tag content changes (I'm trying to emulate foo_playcount's behavior).

I'm using metadb_io_edit_callback because I need before and after values. Here's what I've got so far:

Code: [Select]
	class metadb_io_edit_callback_impl : public metadb_io_edit_callback {
public:
typedef const pfc::list_base_const_t<const file_info*> & t_infosref;
void on_edited(metadb_handle_list_cref items, t_infosref before, t_infosref after) {
for (size_t t = 0; t < items.get_count(); t++) {
metadb_handle_ptr p_item = items[t];
file_info_impl info;
if (p_item->get_info(info)) {
pfc::string8 artist;
pfc::string8 album;
pfc::string8 title;
artist = info.meta_get("ARTIST", 0);
album = info.meta_get("ALBUM", 0);
title = info.meta_get("TITLE", 0);
metadb_index_hash hash;
g_client->hashHandle(p_item, hash);
FB2K_console_formatter() << artist << " - " << album << " - " << title << " - " << hash;

artist = after[t]->meta_get("ARTIST", 0);
album = after[t]->meta_get("ALBUM", 0);
title = after[t]->meta_get("TITLE", 0);
FB2K_console_formatter() << "after: " << artist << " - " << album << " - " << title;
}
}
}
};

static service_factory_single_t<metadb_io_edit_callback_impl> g_my_metadb_io;

This works great so far. Calling meta_get on the entries in metadb_handle_list_cref spits out the old pre-edit values just fine, and because it's the old values I can only assume that the hash is the pre-edit hash. Calling meta_get() on the after[t] also returns the post-edit values. I'm logging to the console for sanity purposes and it all looks correct.

Where I'm stuck now is I'm not sure how to actually take the file_info* I get from after[t] and turn that into the new hash. Maybe I have to do this manually the same way it's done in the metadb_index_client::transform() I have?

I obviously also need to figure out how to copy the value at the old hash and store it at the new hash, but I assume that's mostly trivial once I know what the post change hash is going to be.

Any help you guys can provide would be much appreciated.

Re: Watching tag edits to update metadb hashes

Reply #1
In case anyone was having the same issue I was, I figured out how to do it. I'm not 100% sure if this is the BEST way to do it, and I really hate being forced to use individual meta_get's instead of a single title format, but unless I'm missing something meta_get is the only option on a file_info*.

Code: [Select]
	class metadb_io_edit_callback_impl : public metadb_io_edit_callback {
public:
typedef const pfc::list_base_const_t<const file_info*> & t_infosref;
void on_edited(metadb_handle_list_cref items, t_infosref before, t_infosref after) {
static static_api_ptr_t<metadb_index_manager> api; // initialized once here
for (size_t t = 0; t < items.get_count(); t++) {
metadb_index_hash hashOld, hashNew;

g_client->hashHandle(items[t], hashOld);

// my hash is pinned to "%artist% %album% $if2(%discnumber%,1) %tracknumber% %title%
pfc::string8 artist = meta_get_if_exists(after[t], "ARTIST", "");
pfc::string8 album = meta_get_if_exists(after[t], "ALBUM", "");
pfc::string8 discnum = meta_get_if_exists(after[t], "DISCNUMBER", "1");
pfc::string8 tracknum = meta_get_if_exists(after[t], "TRACKNUMBER", "");
pfc::string8 title = meta_get_if_exists(after[t], "TITLE", "");

pfc::string_formatter strAfter;
strAfter << artist << " " << album << " " << discnum << " " << tracknum << " " << title;

hashNew = static_api_ptr_t<hasher_md5>()->process_single_string(strAfter).xorHalve();
if (hashOld != hashNew) {
record_t record = getRecord(hashOld, api); // this is my function for retrieving the data structure from metadb
record_t newRecord = getRecord(hashNew, api);
// use whatever logic you want to determine if a record at the old hash exists and whether to overwrite a record at the new hash
}
}
}
};

static service_factory_single_t<metadb_io_edit_callback_impl> g_my_metadb_io;

// helper function to get meta value or return default if not found. equivalent to $if2
pfc::string8 meta_get_if_exists(const file_info * info, const char* key, const char* default) {
if (info->meta_exists(key)) {
return info->meta_get(key, 0);
}
return default;
}