Batch file conversion and usage - javascript

I'm having a problem with a small batch script that I'm writing. The point of the batch script is to run a Javascript file that converts an XML file to a csv file and then run a Python script which will analyze the just created csv file and create another csv file.
The batch script is below.
start XML-CSV_Converter.js
python CSV_ANALYZER.py
exit
I didn't write the XML-CSV converter;
It can be found here. (http://gotochriswest.com/blog/2011/05/05/excel-batch-convert-xls-to-csv/) The only thing I changed was I removed all of the alerts and input prompts so it doesn't wait on any user input. Simply put, all it does it look at every XML file in the current directory and produces a csv file in the same directory.
Whenever I run the batch script, I keep getting an IO error in my Python script because even though it can see the created file, it isn't able to open the file.
The exact error is:
"IOError: [Errno 2] No such file or directory: 'NAME_OF_FILE.csv'"
The part of the Python script which is causing errors is listed below.
dirList = os.listdir("C:\FOLDER")
for fname in dirList:
if fname.find(".csv") != -1:
inputFile = open(fname,'r') <---- Script halts here
Anybody know what could be causing the file not being opened in the Python script?
If I run the JavaScript file manually, and then the Python script manually, it works perfectly. But when I try to chain them together in a batch file it breaks. I would appreciate any and all ideas!
Thanks in advance!

The start command launches a program (or, in your case, a file) and immediately returns, without waiting for the program to exit. This means that when Python tries to open the file, the JS script is probably still running and has the file open exclusively for writing.
You should run the JS file by directly calling the Windows Scripting Host (cscript.exe). Just replace the start command with:
cscript //nologo XML-CSV_Converter.js
This will ensure that when the Python command is run, the JS script will have completed its job and safely terminated.

You forgot to add the folder name to the file name in the open() call. listdir() returns only the file names, so unless its path argument matches the current directory, you'll have to add it to the returned file names to properly identify them.
As a side note, you should also avoid using backward slashes in normal strings. In this case "C:\FOLDER" happens to work, but "C:\folder" wouldn't, because \f would be converted to \x0c (the linefeed character). You should use either a raw string (r'C:\FOLDER' which doesn't convert escaped characters), an escaped backslash ('C:\\FOLDER'), or the more portable 'C:/FOLDER' (on Windows '/' is the alternative path separator).
Also a simpler way to check for the extension is to test whether the name ends with it (the s.find(t) == -1 is not very Pythonic). All in all, the modified code could look something like this:
folder = "C:/FOLDER"
for fname in os.listdir(folder):
if fname.endswith(".csv"):
inputFile = open(os.path.join(folder, fname),'r')

The root cause is "python CSV_ANALYZER.py" got executed while the XML-CSV_Converter.js was not finished.
By type "start XML-CSV_Converter.js", it won't wait for this command to finish before executing the next command.
If you have installed js interpreter, you can remove the `start' in the first line, an then it should work.

Related

Issues with synchronously downloading a file in Node

With multiple methods to download the file and write it synchronously in my local application (currently using a module called download-file-sync), I am having issues with the file written using writeFileSync.
Here is my code:
var downloadFileSync = require('download-file-sync');
fs.writeFileSync("twc.mp4", downloadFileSync(sourceURLEncoded));
Now this technically writes something, and opening the file in Notepad++ shows at least the start of the file is identical to the same file downloaded via Chrome, with the same amount of lines. However, the file size is around doubled:
The Node download will not play, while the Chrome download does.
How am I able to achieve a successful synchronous file download in Node?
The reason is that download-file-sync calls curl and encodes the result as a string when you want "pure" bytes.
If the string isn't valid UTF-8 some characters may be expanded resulting in a different size and content than the original binary file.
To fix you can simply replace the module with the code it uses and make a new function where you use buffer (the default) for encoding:
function downloadFileSync(url) {
return require('child_process')
.execFileSync('curl', ['--silent', '-L', url]); // remove options {encoding: 'utf8'}
}
And try with that instead.

How to run "the super tiny compiler"?

https://github.com/jamiebuilds/the-super-tiny-compiler
I've imported this project in Eclipse. When I compile and run "the-super-tiny-compiler.js", it gets terminated instantly. Why doesn't it asks us to input the source code, and why doesn't it show the compiled output? Is something missing in this code?
There's no "main" code in there or any code to read a source file (or read from stdin). Only a function that takes the source as a string.
So it looks like it's meant as a library and you'll have to write your own IO code if you want to turn it into a command line application.
Alternatively you could use it from an HTML page and get the source from a textarea.

How to Run Javascript code/script by itself like php bots?

i am reading websocket data in javascript and doing further procedures like inserting data in mysql database.
but all this happens when i open .html page containing javascript code in it.
How can i run the javascript program/code all by itself from lets say command line ?
like the php codes/programmes/bot does , invoking from shell and it can keep doing what its been coded to do, without stopping.
so i can set it as a cron job and it will do its thing on time, instead of me opening .html file every time.
This is exactly what node.js is for. Instead of putting a <script> tag in an HTML file, you would just run your JS file ala $ node myscript.js.
Installe nodejs and you can run .js files by
$ node myscript.js
if you want your script to run forever then you can use https://www.npmjs.com/package/forever like this
$ forever start myscript.js

Using the `runScript` function to run a JXA script does not allow parameters

I use JXA to script workflows for Alfred 2 and recently tried to run a script from within another script. I need to pass some text between the scripts, so I decided to use parameters, but whenever I try to pass a string, a number, an array or anything else that isn't an object to it, it gives the error "Error on line 4: Error: An error occurred.". If I do pass an object, the second script (the one being run by the first script) receives an empty object rather than the one passed to it. The same happens when the first script is an AppleScript, but if the second script is an AppleScript, it all works perfectly. Passing arguments through osascript from the command line also works. Is the API broken or is there something that I'm doing wrong?
First script:
var app = Application.currentApplication();
app.includeStandardAdditions = true;
app.runScript(new Path("/path/to/second/script.scpt"), { withParameters: "Hello World!" });
Second script:
function run(args) {
return args;
}
Edit:
If the second script is edited as below, the dialogue is displayed but the runScript method of the first script still returns an error.
function run(args) {
var app = Application.currentApplication();
app.includeStandardAdditions = true;
app.displayDialog(args.toString());
return args;
}
Edit 2:
The runScript function actually seems to be working perfectly other than the problem with the parameters. The error isn't actually being thrown, just displayed by the Script Editor, and execution continues after the call to runScript as if nothing had happened. The returned value also work perfectly, despite the parameters not working.
A note about Alfred 2 workflows
To run some code in Alfred 2 (triggered by a search, keyboard command, etc.), it must be typed into a box in the app, not in a file.
The box to enter code in is very small and does not provide syntax highlighting, and this makes editing code difficult and annoying. For smaller files, it is okay, but for larger files it is easier to use a short script to run a script file. I've tried Bash, which would be the simplest option, but Alfred 2 does not provide an option to escape single quotes. I also cannot use script libraries (to my knowledge, correct me if I'm wrong), as the code is not in a script bundle and all of the required files need to be within the same folder (for exportation reasons).
I don't know how to avoid the runScript error, but I can suggest an alternative approach: load the script as a script library.
Using a script library
Turning a script into a library can be as simple as saving the script to ~/Library/Script Libraries. If your script file is named script.scpt and has a run handler, and you save it to the Script Libraries folder, then you can then invoke it from another script like so:
Library("script").run(["Hello, world!"])
Script libraries are documented in the JXA release notes for OS X 10.10, in the WWDC 2014 session video introducing JXA, and in the AppleScript Language Guide.
Embedding a script library inside of a script bundle
According to the AppleScript Language Guide documentation for script libraries, there is a search policy for finding Script Libraries folders. The first place it searches is:
If the script that references the library is a bundle, the script’s bundle Resources directory. This means that scripts may be packaged and distributed with the libraries they use.
To apply this to the example given in the question, you would need to re-save the first script as a script bundle, and then embed the second script inside of the first script.
For example, if you re-save the first script as script.scptd, then you could save the second script embedded.scpt to script.scptd/Resources/Script Libraries/embedded.scpt. You should then be able to use Library('embedded') to access the script library.
To re-save an existing script as a script bundle, you can either use the File > Export... menu item in Script Editor, or you can hold down option while selecting the File menu to reveal the File > Save As... menu item. The File Format pop-up menu lets you choose the Script bundle format.
Once you have a script bundle open, you can reveal the bundle content panel by using the Show Bundle Contents menu item or toolbar button. You can then use the gear menu to create the Script Libraries folder inside of the Resources folder, and then you can drag a script into that folder.

Webpage with Javascript executing Python script with arguments

I have three files in the same directory. One is a python script, which takes argumenet. One is a html page with javascript. And the last one is a source .wav file.
./myfolder/sound_manipulation.py
./myfolder/volume_slider.html
./myfolder/the_song.wav
The sound_manipulation.py file can be executed like:
python sound_manipulation.py -v 50
and it generates a new wav file, new_song.wav, based on the_song.wav, but only has 50% of the original volume level.
On the other hand, the volume_slider.html contains a slider goes from 0 to 100%, and a button calling an onclick javascript function, update_vol();
So far, the update_vol() alerts the value of the slider, and that's all.
function update_vol() {
var vol = document.getElementById('vol_slider').value;
alert(vol);
}
But I want the update_vol() to actually execute the python script using the vol.
How can I make that happen?
Also, when the "python sound_manipulation.py -v 50" is executed, how can I return the location of the new_song.wav back to volume_slider.html?
Please help. Thanks!
the simplest and crudest one-time cgi script might solve your problem.
set up a cgi script/environment to just get volume value from user / then use subprocess module to process the .wav file and send it back to user. if you need anything more than that, build your own web app.
import cgi
import subprocess
import sys
form = cgi.FieldStorage()
volume = form.getfirst('volume') #read from form 'volume'
subprocess.call(['python', 'sound_manipulation.py', '-v', volume])
with open('new_song.wav', 'rb') as wav_file:
print("Content-Type: audio/wav\n")
sys.stdout.write(wav_file.read())
Hm, well, I guess you're out of luck. Browser scripts can't execute anything (so no Python script) on your system. As I'm sure you can imagine, this could present a huge security risk -- that's exactly how much trouble Microsoft's ActiveX got into.
I'm assuming you want to create a graphical interface for that script, so alternatively you could :
Do a JavaScript equivalent of your Python script if you absolutely need HTML
Or create an interface in QT, GTK or the like. Python can easily do that, by the way!

Categories