[jscript] call python code for selected folders


I've been learning jscript and the interface to dopus objects on the help and support board (thanks tbone & leo), and I've just modified the script from handling a single folder to handling multiple folders by adding a while loop and doing some shuffling about.

The script invokes a python routine to scan selected music folders one by one to update the database used by sonospy to deliver music for my sonos music system. In effect sonospy simulates a remote music service. It is fantastic.

You will have gathered by now that I'm not a programmer and I think it's quite difficult for those who are to understand the difficulty of grasping the dopus object interface and jscript at the same time. I haven't found any mention of my dumping technigue but maybe it is mentioned somewhere, or you've found your own way to break through the barrier, or there's some stuff I haven't found yet. Looking through examples starts to become more of an option as you know more.

My questions are:

  1. I made a personal breakthrough when I realised I could dump out the contents of the dopus Item object and there's more to do here for other objects. Am I reinventing the wheel here though? Is there a built in or external way via an "object explorer or dumper"?

  2. Item.attr shows 16 for each folder but this is not documented in the Item help page, and attr_text shows nothing at all. What does this flag mean and why isn't attr_text showing it?

  3. How would I define the variable folderPath before the while loop and then use it, as I'm currently defining it for every folder selected.

  4. tbone did a fantastic job with the regex to handle adding escape characters but I do find this difficult to understand. Is there a more long winded but easier to understand option?

@script jscript
// somehow when the script button is clicked, data contains something useful
function OnClick(data) 
   var debug=false
   var tab = data.func.sourcetab; //create a more handy sourcetab reference
   var cmd = data.func.command; //create a more handy command reference

   cmd.deselect = false; //do not deselect affected folder
   cmd.SetType("msdos"); //set "button" type to msdos

   cmd.AddLine('echo on');
   cmd.AddLine('prompt $D_$T_$G');
   cmd.AddLine('cd /D "C:\\Users\\xxx\\Downloads\\SonospyReleases\\sonospy-current\\sonospy"');
   cmd.AddLine('dir sonospy.db >>nrscan3.log');
   enumFiles = new Enumerator(tab.selected_dirs);
   while (enumFiles.atEnd() == false)
   if (debug == true)
   DOpus.Output('access ' + enumFiles.item().access);
   DOpus.Output('access_utc ' + enumFiles.item().access_utc);
   DOpus.Output('attr ' + enumFiles.item().attr);
   DOpus.Output('attr_text ' + enumFiles.item().attr_text);
   DOpus.Output('checked ' + enumFiles.item().checked);
   DOpus.Output('create ' + enumFiles.item().create);
   DOpus.Output('create_utc ' + enumFiles.item().create_utc);   
   DOpus.Output('display_name ' + enumFiles.item().display_name);
   DOpus.Output('ext ' + enumFiles.item().ext);
   DOpus.Output('failed ' + enumFiles.item().failed);
   DOpus.Output('got_size ' + enumFiles.item().got_size);
   DOpus.Output('groups ' + enumFiles.item().groups);
   DOpus.Output('id ' + enumFiles.item().id);
   DOpus.Output('is_dir ' + enumFiles.item().is_dir);
   DOpus.Output('metadata ' + enumFiles.item().metadata);
   DOpus.Output('modify ' + enumFiles.item().modify);
   DOpus.Output('modify_utc ' + enumFiles.item().modify_utc);
   DOpus.Output('name ' + enumFiles.item().name);
   DOpus.Output('name_stem ' + enumFiles.item().name_stem);
   DOpus.Output('path ' + enumFiles.item().path);
   DOpus.Output('realpath ' + enumFiles.item().realpath);
   DOpus.Output('selected ' + enumFiles.item().selected);
   DOpus.Output('size ' + enumFiles.item().size);
   DOpus.Output('size.cy ' + enumFiles.item().size.cy);
   DOpus.Output('size.fmt ' + enumFiles.item().size.fmt);
   DOpus.Output('size.high ' + enumFiles.item().size.high);
   DOpus.Output('size.low ' + enumFiles.item().size.low);
// not sure how to define folderpath outside the while loop and use it inside

   var folderPath = new String(enumFiles.item().realpath); //get folderpath as jscript string
   folderPath = folderPath.replace(/(\\|\ |\%|\-|\+|\')/g,'\\$1'); //' replace/escape chars

   if (folderPath.toUpperCase().indexOf("SYN-DS215J-A") != -1) 
      DOpus.Output("Do not use the BACKUP NAS");

   DOpus.Output('folderPath ' + folderPath);
   cmd.AddLine('echo ----------  start scan  ---------- >>nrscan3.log');
   cmd.AddLine('C:\\Python27\\python.exe scan.py -d sonospy.db '+folderPath+' >>nrscan3.log 2>&1'); //build cmdline
   cmd.AddLine('echo ----------  end scan  ---------- >>nrscan3.log');
   cmd.AddLine('type logs\\scanlog.txt');

   cmd.Run(); //run


(Separate posts for each question is generally better.)

  1. No, there's no built-in method to dump everything in an object to the log. What you're doing is the way to do it if you want to see all that info at once.

  2. 16 on its own is FILE_ATTRIBUTE_DIRECTORY. File Attribute Constants lists the possible values. Note that they can be combined, so FILE_ATTRIBUTE_DIRECTORY (16) + FILE_ATTRIBUTE_HIDDEN (2) would give you 18.

  3. Looks like attr_text is not filled in for directories. We'll look at that as it probably should be.

  4. Yes, there are a million ways to skin a cat. TBone's method is actually quite simple though, if you break it down. It's just a regular expression that looks for certain characters and puts a \ before them. You could do the same thing without using regular expressions at all, or you could use a slightly more compact regular expression.

Part of why the regex looks complex is that many of the characters it is searching for need to be escaped in regular expressions as well. If you think of it as (a|b|c|d) -> x\1 (which adds an "x" before any a, b, c or d), it is a lot easier to understand. The other complexity is just simple things added on top, once you understand the essentials of what it is doing.

I think I did something wrong when I came to that conclusion, maybe using a script that had a bug in it, as I've come back to this to fix it and found it works fine (even in the version that was current at the time).

Simple test script:

[code]@script jscript
function OnClick(data)
tab = data.func.sourcetab;

for (enumFiles = new Enumerator(tab.all); !enumFiles.atEnd(); enumFiles.moveNext())
	item = enumFiles.item();
	DOpus.Output(item.attr_text + " " + item.attr + " " + item.name);



I also tried with something based on your original script, and that works OK as well, so I guess I had an error in the script I was using before, or there's more to it than I thought.