Add composer if title matches from text file?

I'm not sure if there is a way to do this, but it would be a great feature. I'll explain:

I have a list of titles composed by a single person. (example: copied list from wikipedia)

And I have several music files that do and don't match the titles

My goal is to add the composer name to files that match, so

If [Line from text file] = OR is contained in %title%,
Then Add [Name of Composer] to %composer% to MATCH

If this is not remotely possible with the current release, please consider adding such a feature. I don't care if this is a several step process, it would save time if this is possible in any way.

Not to be picky or to ask too much... it would be great preferably with liberal matching- ignore case, partial match (as in "Babik" from text file will match a file with a title of "Babik [demo]").

An idea for do-it-yourself:
Put your list of titles into a temporary tag field TEMPLIST.
Do a search into this field by TITLE string using scripting function $strstr(x,y), which returns the value zero (not found) or a value greater than zero (found).
If target is found, then format COMPOSER with the name of the related composer, otherwise do nothing.
Afterwards remove the temporary tag field TEMPLIST.

DD.20071030.1355.CET

This sounds like what I need but I don't follow how to accomplish this exactly. You say to do a search, you mean with a filter or do a Format Value?

I'm really lousy at scripting and have no idea what I am doing. I tried this but it returns "Django" to all files no matter what.

Action type: Format value
Field: COMPOSER
Formatstring: $ifgreater($strstr(%title%,%templist%),0,%composer%,Django)

I should mention that templist is line by line. Do I need to separate each value in %templist% with commas instead of line breaks?

Your were so near, now try this instead:
Because your templist is ordered line by line I recommend to use the 'carriage return' and 'linefeed' characters as special delimiters. Make sure that your templist begins and ends with an empty line.

Action type: Format value
Field: COMPOSER
Formatstring: $ifgreater($strstr(%templist%,$char(10)%TITLE%$char(13)),0,'Django',%COMPOSER%)

DD.20071030.2308.CET

You are brilliant! Thanks ever so much- it's almost perfect. I also got this working for case INSENSITIVITY:

Action type: Format value
Field: COMPOSER
Formatstring: $ifgreater($strstr($lower(%templist%),$char(10)$lower(%title%)$char(13)),0,Django,%composer%)

Now if only I could find a way that a line in %templist% of "Babik" would be counted as a match for a %title% of "Babik (Bi-Bop)" ... or templist-LINE "Nuages" is caught in title: "Nuages - Hot Club De France Quintet" ...This is the opposite of what the current action does (without delimiter). If anyone has suggestions they will be accepted with the utmost gratitude.

You can try to evaluate only a specific amount of chars from the left side of the strings by using $left(). Or maybe you can find out how to isolate the first 'word'?

DD.20071031.1748.CET

I don't know if this warrants a separate thread, but it's along the lines of what I'm trying to achieve with the previous workaround. I've got a text list of songs with the appropriate music composer beside it and I'd like to add corresponding composer tag to matching titles in files. This is a step beyond what I'm able to accomplish with the previous script.

The list looks like this:

    * "Lazybones"  (music by Hoagy Carmichael)
    * "P.S. I Love You"  (music by Gordon Jenkins)
    * "Goody Goody"  (music by Matty Maineck)
    * "I'm an Old Cowhand from the Rio Grande" 
    * "Hooray for Hollywood"  (music by Richard A. Whiting)
    * "Too Marvelous for Words"  (music by Richard A. Whiting)

and I want my music files to add COMPOSER "Hoagy Carmichael" if TITLE is "Lazybones"

Making a templist like I've been doing can match titles, but it won't output the (music by unique COMPOSER).

On a side note, it'd be great if there is a database or some script that could add composer to songs. All I know of is allmusic which sometimes lists composer, and wikipedia will list writers of songs on most albums.

Detailed step by step action group:

Action #1:
Action type: Format value
Field: FFOLKE_TITLE
Formatstring: %TITLE%

Action #2:
Action type: Format value
Field: FFOLKE_TITLE
Formatstring: $char(34)%FFOLKE_TITLE%$char(34)

Action #3:
Action type: Text File Import
Field: FFOLKE_TEXT_IMPORT
Formatstring: Your Filepath

Action #4:
Action type: Format value
Field: FFOLKE_TEXT_IMPORT
Formatstring: $replace(%FFOLKE_TEXT_IMPORT%,' * ',)

Action #5:
Action type: Format value
Field: FFOLKE_TEXT_IMPORT
Formatstring: $replace(%FFOLKE_TEXT_IMPORT%,' '$char(40)'music by ',)

Action #6:
Action type: Format value
Field: FFOLKE_TEXT_IMPORT
Formatstring: $replace(%FFOLKE_TEXT_IMPORT%,$char(41)$char(13),$char(13))

Action #7:
Action type: Format value
Field: FFOLKE_TEXT_IMPORT
Formatstring: $replace(%FFOLKE_TEXT_IMPORT%,$char(32)$char(13),$char(13))

Action #8:
Action type: Format value
Field: FFOLKE_POS
Formatstring: $strstr(%FFOLKE_TEXT_IMPORT%,%FFOLKE_TITLE%)

Action #9:
Action type: Format value
Field: FFOLKE_LEN
Formatstring: $sub($len(%FFOLKE_TEXT_IMPORT%),$sub(%FFOLKE_POS%,1))

Action #10:
Action type: Format value
Field: FFOLKE_TEXT_IMPORT
Formatstring: $right(%FFOLKE_TEXT_IMPORT%,%FFOLKE_LEN%)

Action #11:
Action type: Format value
Field: FFOLKE_POS
Formatstring: $strstr(%FFOLKE_TEXT_IMPORT%,$char(13))

Action #12:
Action type: Format value
Field: FFOLKE_LEN
Formatstring: $sub(%FFOLKE_POS%,1)

Action #13:
Action type: Format value
Field: FFOLKE_TEXT_IMPORT
Formatstring: $left(%FFOLKE_TEXT_IMPORT%,%FFOLKE_LEN%)

Action #14:
Action type: Format value
Field: FFOLKE_TEXT_IMPORT
Formatstring: $replace(%FFOLKE_TEXT_IMPORT%,%FFOLKE_TITLE%,)

Action #15:
Action type: Format value
Field: FFOLKE_COMPOSER
Formatstring: %FFOLKE_TEXT_IMPORT%

Action #16:
Action type: Format value
Field: COMPOSER
Formatstring: %FFOLKE_COMPOSER%

Action #17:
Action type: Remove fields
Fields to remove (semicolon-separated): FFOLKE_TITLE;FFOLKE_TEXT_IMPORT;FFOLKE_POS;FFOLKE_LEN;FFOLKE_COMPOSER

DD.20071117.1033.CET

Detlev, could you post the actual action file text? I'd like to try this but don't rate my chances of filling those 17 dialog boxes without error! Thanks.

As usual you can use Copy&Paste to minimize edit errors :-), but here comes the complete ready to use mta file:
Test_ffolke_2.mta (1.41 KB)
And the input file:
FFOLKE_TEXT_IMPORT.txt (321 Bytes)
I hope you are able to understand what I have done there, if not, then feel free to ask.

DD.20071122.1822.CET

Test_ffolke_2.mta (1.41 KB)

FFOLKE_TEXT_IMPORT.txt (321 Bytes)

Here comes a more generic version of a lookup action:

mta file: Lookup.mta (794 Bytes)
sample input file: Lookup.txt (215 Bytes)

The input file must be a normal text file of following format (first and last line empty, unique entries):

@CR@LF
Lazybones|Hoagy Carmichael@CR@LF
P.S. I Love You|Gordon Jenkins@CR@LF
Goody Goody|Matty Maineck@CR@LF
I'm an Old Cowhand from the Rio Grande|@CR@LF
Hooray for Hollywood|Richard A. Whiting@CR@LF
Too Marvelous for Words|Richard A. Whiting@CR@LF

"@CR@LF" stands for the unvisible CarriageReturn-LineFeed sequence at end of each line of text.

This is the lookup table.
The pipe symbol "|" is used as a delimiter between the two columns "search item|result item".
@CR = $char(13), @LF = $char(10), | = $char(124)

Changing the view a little bit our lookup table looks like:

@CR
@LFLazybones|Hoagy Carmichael@CR
@LFP.S. I Love You|Gordon Jenkins@CR
@LFGoody Goody|Matty Maineck@CR
@LFI'm an Old Cowhand from the Rio Grande|@CR
@LFHooray for Hollywood|Richard A. Whiting@CR
@LFToo Marvelous for Words|Richard A. Whiting@CR
@LF

Each row opens with the @LF symbol as the begin-of-row marker and closes with the @CR symbol as the end-of-row marker.

Finding a title is easy, just search for a string of "$char(10)%TITLE%$char(124)"
Additional scripting returns the corresponding string from the result column.

DD.20071123.1656.CET

Lookup.txt (215 Bytes)

Lookup.mta (794 Bytes)

Or maybe you can find out how to isolate the first 'word'?

$regexp(%title%, .*,$1) works here.

Thanks for that Detlev. I think it would be neat to use tab rather than | at the separater. Also, perhaps rather than require the input file to have a blank line, you could add it with an action.

Well, I do like to use the "|" character as a delimiter symbol more than a TAB character, because it is better visuable, often TAB and SPACE are mixed up.
You may use any other delimiter character that is unique to the lookup data.

Yes, Chris, I thought too short, your suggestion is good!
At the end it is a question of the runtime, because the actiongroup runs against each track file. Adding a CRLF before and perhaps behind a large lookup file will slow down the process for many track files entirely, therefore you can prepare the lookup file to make the process a little bit quicker. This should be evaluated by experiment.

DD.20071126.0847.CET

Detlev

Adding a CRLF before and perhaps behind a large lookup
file will slow down the process for many track files entirely

Yes, indeed. Writing and a big lookup file and then deleting it to hundreds of tracks could take a long time. Perhpas it would be worth Mp3tag having %actiontemp1%, %actiontemp2% and %actiontemp3% stored in memory not the file, and globally not for each track.

Hmm, I'm not sure how the tag manipulating process works when an action runs against a track file.

  1. Is it a physical process that alters the content of the track file each time when a single action is done?
  2. Is it a virtual process that does all actions of an actiongroup in memory and at last writes the altered tag container completely back to trackfile?

The second method gives the chance for having a good runtime speed in relation to CPU speed and available RAM. And we could create a nearly full automatical lookup actiongroup saving the user from prepending/appending manually a CRLF to the lookup file.

Maybe Florian can post a statement regarding the action featured manipulating process of tag fields or tag field container.

DD.20071126.1239.CET

Good question. I was only assuming that it was a physical process, since regular tag updates are very physical - on a single mp3 tag write, Mp3tag does six file open operations.

Is it a virtual process that does all actions of an actiongroup in memory and at last writes the
altered tag container completely back to trackfile?

That would be good. Far better than my suggested %actiontemp% placeholders.

Mp3tag uses the second approach. The first one wouldn't scale with many changes in the tag.

Kind regards,
Florian

Here comes another approach, maybe tricky, maybe lower performing.

The mta file: Lookup_2.mta (781 Bytes)
The sample input file: Lookup_2.txt (211 Bytes)

DD.20071128.0110

Lookup_2.mta (781 Bytes)

Lookup_2.txt (211 Bytes)

Is it possible to make it match with 2 items in tag and if it matches add the third item into tag?