Modifying MediaMonkey Playlists with SQLite Data Browser and Python

To discuss development of addons / skins / customization of MediaMonkey.

Moderators: jiri, drakinite, Addon Administrators

TobiasDax
Posts: 5
Joined: Wed Dec 20, 2023 3:58 am

Modifying MediaMonkey Playlists with SQLite Data Browser and Python

Post by TobiasDax »

So, i opend this Topic window to ask for help with tome SQL stuff i was trying to do but then i figgured it out on my own ;)

So to not forget it i am posting this here as some sort of tutorial if anyone ever googles for that kind of stuff sicne i did not find anything.

What i was trying to do is add a huge list of Artists to a AutoPlaylist, so build some sort of Genre playlists.
since i wanted to add a few hundred artists to multiple Plalists the manual way was not really an option. So this is what i did:

(you need python3 to run this in the end)

1. Download SQLite Data Browser (Portable) to view and Edit the MediaMonkey.DB file
https://sqlitebrowser .org/dl/

2. Made a backup of my Database... Cant stress that enough. just copy it to some different location

3. Made Sure MediaMonkey was closed and opened the MM5.DB file with SQLiteBrowser
This gives you an overview over all the Database Tables. The Scructure can be ignored, we need to switch to the second Tab. Should be called View/Search Data (sorry mine is in german so not sure how the UI translates)

Over the Fields you can find a Dropdown Menu where it should start at Albums, but you need to switch to "Playlists"

4. When you have the Playlists table opened up you should see a spreadsheet like view of the Table contents, it should be easy for you to identify the Playlist you want to edit by their names.
Open up some sort of Text Editor (Windows one is fine, but something like VS Code gives you a bit of Highlighting colors and stuff)

copy and paste the contents of QueryData into the text editor, should look somethink like

Code: Select all

[Common]
QueryVersion=1
QueryType=2
CollectionID=-1
QuickSearch=0

[Basic]
SongTitle=
Artist=
Composer=
Album=
Genre=
Comment=
Lyrics=
AnyField=
YearFrom=0
YearTo=0
LevelFrom=-999999
LevelTo=-999999
Unleveled=0
SortOrder1=
SortOrder2=
SortOrder3=

[Adv]
ConditionsCount=239
OrdersCount=0
LimitTop=0
Top=50
LimitMB=0
MaxMB=650
LimitLen=0
MaxLen=74
LimitOrderIndex=7
UseORcon=1
RandomSortNumber=0.56

[AdvCond1]
DBField=Artists.Artist
DBFieldPerType=1
Condition=2
Value=Enzo
Value2=
nestOperator=or
nestLevel=0
isOperator=0
bypass=0

[AdvCond2]
DBField=Artists.Artist
DBFieldPerType=1
Condition=2
Value=KAYAN
Value2=
nestOperator=or
nestLevel=0
isOperator=0
bypass=0
This is a list of all the Conditions that the Playlist is build of in my example we have two conditions for two Artists.
but if you look at the lines:

Code: Select all

[Adv]
ConditionsCount=239
you can see that my playlist contains a lot more. Make note of this number, since you will have to manually change it at the end for everything to work.

In a second text editor window do the same for the field
QueryDataJSON

Code: Select all

{
    "collection": "Gesamtes Archiv",
    "conditions": {
        "autoSortString": "",
        "data": [
            {
                "field": "artist",
                "operator": "contains",
                "value": "Enzo"
            },
            {
                "field": "artist",
                "operator": "contains",
                "value": "KAYAN"
            }
        ]
    },
    "matchAllCriteria": false
}
This is essentially the same thing as the first field, but formatted differently. i am not really sure if you need to change this one too, but keeping them in sync should not hurt.

So now th fun part.

5. You need a list of artists for that, just a simple list where you have one artist per line,
save that as a file called input.txt

6. if you don't have it installed, now is a gut time to install python3 on your system since you will need it for the script:

save the following script as generator .py inside the same folder where you have saved your input.txt file

Code: Select all

import json

def generate_json_file(field, operator, values):
    conditions = []
    for value in values:
        condition = {"field": field, "operator": operator, "value": value.strip()}
        conditions.append(condition)

    with open('output.json', 'w') as json_file:
        json.dump(conditions, json_file, indent=2)

def generate_text_file(starting_number, field, operator, values):
    with open('output.txt', 'w') as text_file:
        for i, value in enumerate(values):
            text_file.write(f'[AdvCond{starting_number + i}]\n')
            text_file.write(f'DBField={field}\n')
            text_file.write('DBFieldPerType=1\n')
            text_file.write('Condition=2\n')
            text_file.write(f'Value={value.strip()}\n')
            text_file.write('Value2=\n')
            text_file.write('nestOperator=or\n')
            text_file.write('nestLevel=0\n')
            text_file.write('isOperator=0\n')
            text_file.write('bypass=0\n\n')

def main():
    field = input('Enter the field: ')
    operator = input('Enter the operator: ')

    with open('input.txt', 'r') as input_file:
        values = input_file.readlines()

    starting_number = int(input('Enter the starting number for text file: '))

    generate_json_file(field, operator, values)
    generate_text_file(starting_number, 'Artists.Artist', operator, values)

if __name__ == "__main__":
    main()
when you run the script it will ask you for the field value (artist) the operator (contains) and a starting number.
Remember QueryData? If you have already popupated the palylist like in my example and want to add artists to it you need to start with the next number after the [AdvCondX] that is already present. In my example the starting number would be 3

when you run the script it will generate a output.json file and a output.txt file.

7. Open the output.txt file in a text editor and copy the content at the end of the file you created with the content of the QueryData Field and change the line:

Code: Select all

[Adv]
ConditionsCount=239
to reflect your total conditions count

8. open the output.json file, it starts and ends with [Brackets], those need to be deleted.
Check out your QueryDataJSON file that cou created before, copy the content of output.json to the existing data but beware to place it just after the last existing value before the cloing bracket] and add a comma to the existing value before you copy the rest

9. copy the changed content back into the fields inside SQLiteDataBrowser and write the cahnges. now you should be able to open mediamonkey again and see the changes.


I am aware that this is not a well written tutorial and might be a bit problematic to follow, it might even cause demage to your MediaMonkey installation, so please check that you created a backup of your database and roll back to that if anything strange happens.

And if anyone has some suggestions to make this easier pleas post them ;) Also if this is the wrong froum or bad content just delete it ;)
IanRTaylorUK
Posts: 558
Joined: Fri Dec 27, 2019 4:41 pm

Re: Modifying MediaMonkey Playlists with SQLite Data Browser and Python

Post by IanRTaylorUK »

Hi Tobias,

Interesting topic. I am wondering if this code would handle the following:

1). Auto Playlists
2). Playlist Hierarchies

If I recall correctly Auto Playlists can be problematic when restoring a backup of MM5.DB from another machine. Also, Auto-Playlist are "exported" as plain-vanilla M3Us using the "Export All Playlists" option (as you might expect).

In order to simplify the Playlist "view" on Android device, you might resort to a Playlist Hierarchy. For example:

a). Album Artist / Album i.e. an "empty" placeholder Playlist at the top level for the Album Artist with the Albums sitting one level below.
b). Album Artist / Grouping / Album e.g.
Creedence Clearwater Revival
===> CD Boxed Set
===>===> CCR
===>===>Bayou County
===>===>Green River
===>===> Willy and the Poor Boys
===>===> Cosmo's Factory
===>===> Pendulum
===>===> Mardi Gras
===> CCR The Concert

Will see if I can install Python and work with your code in the new year!

A way to backup / restore Auto-Playlist would be great. Also code to point to Album Playlists missing a track (compared to the library or actual files) might be useful.

Thanks for posting.
Ian Taylor
Post Reply