Script to fix dumb Zen MX playlist format

Download and get help for different MediaMonkey for Windows 4 Addons.

Moderators: Peke, Gurus

PawWriter
Posts: 11
Joined: Mon Jul 04, 2011 2:27 am

Re: Script to fix dumb Zen MX playlist format

Post by PawWriter »

Hi there,
Question: how do you run a Scriptconfiguration? Sorry for the ignorance. Prior to Media Monkey, I never really messed with Java at all.

Next question: how would I put in a sample pl?
stoffel

Re: Script to fix dumb Zen MX playlist format

Post by stoffel »

PawWriter wrote:Hi there,
Question: how do you run a Scriptconfiguration? Sorry for the ignorance. Prior to Media Monkey, I never really messed with Java at all.

Next question: how would I put in a sample pl?
Well, sorry maybe I did presume too much :D

First of all you don't have to mess with Java! JavaScript has nothing to do with Java, its a Scripting language more like VisualBasic for Applications (VBA) for C-Programmers.

In the script there is a configuration block. You answer shows me, that you didn't mess with the configuaration, so everything should be set to default.

Are you sure you're running the right script? Where did you place the new script version? Did you copy it under C:\<PROGDIR>\MediaMonkey4\Scripts ? Correct name: FixZenMXPlaylist.js
I think there something wrong with your infrastructure!
PawWriter
Posts: 11
Joined: Mon Jul 04, 2011 2:27 am

Re: Script to fix dumb Zen MX playlist format

Post by PawWriter »

Hi there!

The script I am running is the one I copied and pasted from the previous page of this thread in a file titled "FixZenMXPlaylist.js" in the scripts folder of my Media Monkey install.

I also have the following entry appended on the "Scripts.ini" file of the install:
[FixZenMXPlaylist]
FileName=FixZenMXPlaylist.js
ProcName=FixZenMXPlaylist
Order=1
DisplayName=Fix dumb ZEN MX playlist
;DisplayName=Korrektur von ZEN MX Playlisten
Description=Fix dumb ZEN MX playlist
;Description=Korrektur von ZEN MX Playlisten
Language=JScript
ScriptType=0

Thanks for the help!
stoffel

Re: Script to fix dumb Zen MX playlist format

Post by stoffel »

PawWriter wrote:Hi there!

The script I am running is the one I copied and pasted from the previous page of this thread in a file titled "FixZenMXPlaylist.js" in the scripts folder of my Media Monkey install.

I also have the following entry appended on the "Scripts.ini" file of the install:
[FixZenMXPlaylist]
FileName=FixZenMXPlaylist.js
ProcName=FixZenMXPlaylist
Order=1
DisplayName=Fix dumb ZEN MX playlist
;DisplayName=Korrektur von ZEN MX Playlisten
Description=Fix dumb ZEN MX playlist
;Description=Korrektur von ZEN MX Playlisten
Language=JScript
ScriptType=0

Thanks for the help!
Looks good! Maybe we should continue our communication via PM to speed up the solution process. You find my eMail in the sourcecode.
I'm still not quite sure about your problem
Orion

Re: Script to fix dumb Zen MX playlist format

Post by Orion »

Hi stoffel!


I cant get your script working on my zen style 100 :( Ive spent hours trying to remove the error msg, but I guess I need a pro.

This is the msg I keep getting, similar to pawriter:

error #53 - Microsoft jscript runtime error
file not found
File: 'C:\programefiles\mediamonkey\scripts\fixzenmxplaylist.js, line:139, Column 0

I have settled all your requirements, created the script, pasted it, changed the ini file, and changed the script from zenMX to zenstyle100.

Please help,


Thanks!

Orion
stoffel

Re: Script to fix dumb Zen MX playlist format

Post by stoffel »

Well, sorry I haven't been into Zen playlist business lately. What version of MM are you using?
It seems that:

line 290:
sn = getShortPath(OutDrive + l, true);

has a problem. Can you add a

messageBox(OutDrive + l, mtError, new Array(mbOk.toString()));

before the line 290, start again an report the output. Is it a valid Path? Maybe you should change the option "Force relative path" under External Device - Playlist to OFF

Please send the response of the output to stefan.skopnik@osnanet.de, because I do no look into this forum frequently!
stoffel

Re: Script to fix dumb Zen MX playlist format

Post by stoffel »

Here is another, probably last update of my script. It provides some more elaborate error handling in case of missing track files.
Tested with newest MM 4.0.7 under W7

Enjoy :D

Code: Select all

// Fix stupid ZEN MX Bug: Playlists must define their tracknames in 8.3 DOS style
// Convert every playlist '<name>.m3u' found in /playlist to '@ <name>.m3u' changing tracknames to 8.3 DOS style.
// By default original files are not changed
//
// (c) Stefan Skopnik (sskopnik(at)web(dot)de)
//
// 01.01.2010 fixes for W7, don't generate if newpl exists and is newer than orgpl, changed NewPlName
// 14.01.2010 scan for drive modified, test for dir exist, more detailed messages, change naming schema again to: '@ <name>.m3u'
// 08.09.2011 fixes for Zen Style 100 and MM4 (now works with MM3 and MM4)
// 12.09.2011 New Configsystem. New flags DeleteOrgPl and ReplaceOrgPl.
//            Now you can decide if you want to:
//            - delete the original pl-file after conversion (DeleteOrgPl=true) leaving only the converted @pl-file
//            - replace the old pl-file with the converted version (ReplaceOrgPl=true) preserving the original name.
//              (This may be the default in the future, Here only converted files are taken into account)
// 24.12.2012 More intelligent error handling in case of missing files
/*

Installation:
-------------
0.) IMPORTANT: Configure your ZEN device in MM : Under Playlist / Options: *Don't* use
    UTF8 Unicode Coding for .m3u playlists 

1.) Copy this file to <MediaMonkeyInstallDir>\Scripts\FixZenMXPlaylist.js
    (Windows7: This dir is write protected, you have to change this!)

2.) Append to file <MediaMonkeyInstallDir>\Scripts\scripts.ini:
< --- COPY AFTER THIS LINE --->
[FixZenMXPlaylist]
FileName=FixZenMXPlaylist.js
ProcName=FixZenMXPlaylist
Order=1
DisplayName=Fix dumb ZEN MX playlist
;DisplayName=Korrektur von ZEN MX Playlisten

Description=Fixes ZEN MX playlist by converting filepath into 8.3 DOS format
;Description=Korrektur von ZEN MX Playlisten durch konvertieren der Dateinamen/pfade in das 8.3 DOS Format
Language=JScript
ScriptType=0
<--- COPY BEFORE THIS LINE --->

3.) (Re)start MM

4.) Plugin Zen MX and create PLs in MediaMonkey

5.) Send PL to 'My ZEN'

6.) Run this Script from Extras / Scripts / Fix dumb ZEN MX playlist

7.) Unplug ZEN MX

8.) Enjoy your MM PL on ZEN MX. You find them under '@ <ORGNAME>.m3u


Configuration:
-------------

This script should work 'out of the box' with Zen MX Player using english language.
If you like you can configure the script in some aspects. See 'Config' for options

*/

var Config = {                              // All user changeable config settings go here
        Language     : 'en',                // Set your prefered language (Currently 'en' = English, 'de' = German is supported)
        DeleteOrgPl  : false,               // Set true if you want to delete original playlist files after conversion
        ReplaceOrgPl : false,               // Set true if you want to replace original playlist with converted version
        Device       : 'ZENMX',             // Define your player device here, see 'DeviceConfig' for possible devices (ZENMX,ZENSTYLE100)
        NewPlName    : "@ %1.%2",           // Mask for new Playlist filenames,
                                            // %1 is replaced with old filenameprefix, %2 is replaced with old filenamesuffix
        ReExclFn     : /@.*\.m3u$/          // RE for Filenames to be EXCLUDED from conversion (must match 'NewPlName')
    },
    
    re_inclfn    = /\.m3u$/,                // RE for Filenames to be INCLUDED into conversion
    re_ignoreln  = /^#/,                    // RE for lines to be ignored during conversion
    OutDrive     = "?",                     // Define your Zen MX Drive ('X:') or leave "?" to let script find device
    OutDir       = "\\Playlist",            // Define location of PL on device
    Scriptname   = "FixZenMXPlaylist.js",
    Version      = "1.05",
    FileComment  = "#!@ 8.3 DOS converted by %1 V%2",
    re_flag      = /^#!@ 8.3 DOS converted/,

    DeviceConfig = {                        // Deviceconfiguration. You have to look into the registry!
        'ZENMX'       : "USBSTOR\\Disk&Ven_Creative&Prod_ZEN_MX",
        'ZENSTYLE100' : "USBSTOR\\Disk&Ven_Creative&Prod_ZEN_Style_Series&Rev_0200"
    },

    Lang_rc = {
        'de' : {
            msg0 : "Es wurden keine Playlisten im Verzeichnis '%2' erstellt.",
            msg1 : "Folgende %1 neue Playlisten wurden im Verzeichnis '%2' erstellt:\n\n",
            msg2 : "Folgende neue Playliste wurde im Verzeichnis '%2' erstellt:\n\n",
            msg4 : "Kein Zen MX MP3-Player gefunden!",
            msg5 : "Zen MX MP3-Player in Laufwerk '%1' gefunden.\nPlaylisten konvertieren?",
            msg6 : "Unterverzeichnis '%1' auf Laufwerk '%2' nicht gefunden!",
            msg7 : "Zen MX MP3-Player gefunden, aber Unterverzeichnis '%1' fehlt!",
            msg8 : "Fehler in Playliste '%1':\nFehlender Titel '%2'!\n\nAbbrechen = Weiter mit der nächsten Playliste, Abbruch = Programmabbruch",
			msg9 : "Einige Titel konnten nicht gefunden werden!"
        },
        'en' : {
            msg0 : "No playlists created in directory '%2'.",
            msg1 : "%1 new playlists where created in directory '%2':\n\n",
            msg2 : "%1 new playlist was created in directory '%2':\n\n",
            msg4 : "No Zen MX MP3-Player found!",
            msg5 : "Found Zen MX MP3-Player in drive '%1'.\nConvert Playlists?",
            msg6 : "Subdirectory '%1' missing on drive '%2'!",
            msg7 : "Zen MX MP3-Player found, but subdirectory '%1' missing!",
			msg8 : "Error in playlist '%1':\nMissing title '%2'!\n\nCancel = Continue with next playlist, Abort = Exit program",
			msg9 : "Could't find some titles!"
        }
    },
    Lang = Lang_rc[Config.Language],
    
    objFso = new ActiveXObject("Scripting.FileSystemObject"),
    objDic = new ActiveXObject("Scripting.Dictionary"),
    C_ForReading = 1
;

// some utillity functions

function sprintf() {
var savearg = arguments;

    return savearg[0].replace(new RegExp("%(\\d+)","g"),
                function ($0, $1, $2) { return savearg[$1]; }
           );
}

function getDriveLetter(i) {
var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
    s;
    s = str.charAt(i);
    return(s + ":");
}

function JS2VBArray(objJSArray) {
    objDic.RemoveAll();
    for (var i = 0; i < objJSArray.length; i++ ) {
        objDic.add(i,objJSArray[i]);
    }
    return objDic.Items();
}

function getShortPath(filespec, nodrive) {
// messageBox("File: " + filespec, mtInformation, new Array(mbOk.toString()));
var f,
    ret;

	try {
		f = objFso.GetFile(filespec),
		ret = f.ShortPath;
	} catch (e) {
	 return undefined;
	}
	
    if (nodrive) ret = ret.substr(2);
    return(ret);
}

function convColltoArr(col) {
var ret = new Array();

    for (var e = new Enumerator(col), i = 0; !e.atEnd(); e.moveNext(), i++) {
        ret[i] = e.item();
    }
    return ret;
}

function stripDriveLetter(fn) {
var start = fn.indexOf(":");

    return fn.slice(++start);
}

function getPath(fn) {
var stop = fn.lastIndexOf("\\");

    if (stop==-1) return "";
    return fn.slice(0,stop);
}

function getFilename(fn) {
var start = fn.lastIndexOf("\\");

    return fn.slice(++start);
}

function getFilenamePrefix(fn) {
var ret = getFilename(fn),
    stop = ret.lastIndexOf(".");

    if (stop==-1) return ret;
    return ret.slice(0,stop);
}

function getFilenameSuffix(fn) {
var ret = getFilename(fn),
    start = ret.lastIndexOf(".");

    if (start==-1) return "";
    return ret.slice(++start);
}

function messageBox(s,t,barr) {
    return SDB.MessageBox(s, t, JS2VBArray(barr));
}

// ---

function FixZenMXPlaylist() {
var fc,
    fin,
    fout,
    orgfile,
    newfile,
    newfilearr = new Array(),
    nrfiles = 0,
	bufferline,
    ret,
	ret2,
	bIgnoreAll = false,
    devlist,
    i,
    f_org,
    f_new,
    actmsg,
	errmsg = '';

    /*
     * Find the Drive letter of Zen MX
     * Well, I have no real idea what ActiveDeviceList is supposed to return. XP and W7 return complety different FriendlyNames.
     * In W7 the second Drive is never returned.
     * So this is a rather dumb method:
     *
     * Scan all Drives with correct vendor&Product Name.
     *   If you find drive with existing subdir <OutDir> use it!
     *   else give up!
     *
     * This was tested with XP / W7 successfully
     */
    if (OutDrive == "?") {
        devlist = SDB.Device.ActiveDeviceList(DeviceConfig[Config.Device]); 
        for (i = 0; i < devlist.Count;i++) {
            OutDrive = "!";
            //messageBox(i + ": (" + devlist.DeviceID(i) + ") " + devlist.FriendlyName(i) + " " +
            //    devlist.DeviceInst(i) + " " + getDriveLetter(devlist.DriveLetterIndex(i)), mtInformation, new Array(mbOk) );
            TestOutDrive = getDriveLetter(devlist.DriveLetterIndex(i));
            // if (devlist.FriendlyName(i) == "Creative ZEN MX USB Device") break;
            if (objFso.FolderExists(TestOutDrive + OutDir)) {
                OutDrive = TestOutDrive;
                break;
            }
        }
    }
    switch (OutDrive) {
        case "?":   messageBox(Lang.msg4, mtError, new Array(mbOk.toString())); // single num arg to array constructor sets array size!
                    return(-1);
        case "!":   messageBox(sprintf(Lang.msg7, OutDir), mtError, new Array(mbOk.toString()));
                    return(-1);
        default:    ret = messageBox(sprintf(Lang.msg5, OutDrive), mtConfirmation, new Array(mbOk, mbCancel));
                    if (ret == mrCancel) return (-2);
    }

    // Ok, we want this folder! Else exit
    if (!objFso.FolderExists(OutDrive + OutDir)) {
        messageBox(sprintf(Lang.msg6, OutDir, OutDrive), mtError, new Array(mbOk.toString())); // single num arg to array constructor sets array size!
        return(-1);
    }

    objDir = objFso.GetFolder(OutDrive + OutDir);

    for (fc = new Enumerator(objDir.files); !fc.atEnd() && ret2 != mrAbort; fc.moveNext()) {
        ele = fc.item();
        if (re_inclfn.test(ele.Name) && !Config.ReExclFn.test(ele.Name)) {
            // WScript.Echo("File: " + ele.Path);

            orgfile = ele.Path;
            newfile = getPath(orgfile) + "\\" + sprintf (Config.NewPlName, getFilenamePrefix(orgfile), getFilenameSuffix(orgfile));

            // Don't generate if newfile already exists and is newer than oldfile
            if (objFso.FileExists(newfile)) {
                f_org = objFso.GetFile(orgfile);
                f_new = objFso.GetFile(newfile);
                if (f_new.DateLastModified > f_org.DateLastModified) continue;
            }

            fin = objFso.OpenTextFile(orgfile, C_ForReading, false);
            fout = objFso.CreateTextFile(newfile, true);

            l = fin.ReadLine();
            if (!l || re_flag.test(l)) { 			// was the file already converted? don't do it again
				fin.Close();
			    fout.Close();
			    objFso.DeleteFile(newfile, true);
				continue;
			}			
            bufferLine = l;                         // else buffer the first line

            nrfiles++;
            newfilearr.push(getFilename(Config.ReplaceOrgPl ? orgfile : newfile));

            fout.WriteLine(sprintf(FileComment, Scriptname, Version)); // mark new file as converted
            while (!fin.AtEndOfStream) {
				ret2 = undefined;

                if (bufferLine) {   
                    l = bufferLine;
                    bufferLine = undefined;
                } else {
                    l = fin.ReadLine();
                }

                if (!re_ignoreln.test(l)) {
                    l = stripDriveLetter(l);    // MM4 by default generates filepath with drive letters, we don't want them!
                    sn = getShortPath(OutDrive + l, true);
					if (sn == undefined) {
						if (bIgnoreAll) ret = mrIgnore;
						else {
							errmsg = '\n\n' + Lang['msg9'];
							ret2 = messageBox(sprintf(Lang['msg8'], orgfile, OutDrive + l),
								mtError, new Array(mbCancel.toString(), mbAbort.toString(), mbIgnore.toString(), mbIgnoreToAll.toString() )
								);
							if (ret2 == mrAbort || ret2 == mrCancel) break;	
							if (ret2 == mrIgnoreToAll) bIgnoreAll = true;
						}
					}
                    l = sn;
                }
                if (ret2 == undefined) fout.WriteLine(l);

            }
            fin.Close();
            fout.Close();

            if (Config.DeleteOrgPl || Config.ReplaceOrgPl)    objFso.DeleteFile(orgfile, true);
            if (Config.ReplaceOrgPl)                          objFso.MoveFile(newfile, orgfile);
        }
    }
    switch (nrfiles) {
        case 0:     actmsg = 'msg0'; break
        case 1:     actmsg = 'msg2'; break
        default:    actmsg = 'msg1';
    }
    messageBox(sprintf(Lang[actmsg], nrfiles, OutDrive + OutDir) + newfilearr.join(", ") + errmsg,
        errmsg ? mtError : mtInformation, new Array(mbOk.toString())
    );
    return (0);
}
rovingcowboy
Posts: 14163
Joined: Sat Oct 25, 2003 7:57 am
Location: (Texas)
Contact:

Re: Script to fix dumb Zen MX playlist format

Post by rovingcowboy »

Thanks for the christmas present. :)
roving cowboy / keith hall. My skins http://www.mediamonkey.com/forum/viewto ... =9&t=16724 for some help check on Monkey's helpful messages at http://www.mediamonkey.com/forum/viewto ... 4008#44008 MY SYSTEMS.1.Jukebox WinXp pro sp 3 version 3.5 gigabyte mb. 281 GHz amd athlon x2 240 built by me.) 2.WinXP pro sp3, vers 2.5.5 and vers 3.5 backup storage, shuttle 32a mb,734 MHz amd athlon put together by me.) 3.Dell demension, winxp pro sp3, mm3.5 spare jukebox.) 4.WinXp pro sp3, vers 3.5, dad's computer bought from computer store. )5. Samsung Galaxy A51 5G Android ) 6. amd a8-5600 apu 3.60ghz mm version 4 windows 7 pro bought from computer store.
Post Reply