NotesDXLExporter to export a database - xpages

I wrote this SSJS in a button on an XPage. I want to export the current database to a dxl file.
var stream:NotesStream = session.createStream();
var fileName:String = "c:\\Export\\exportedDB.dxl";
dBar.info(fileName,"Start Try");
try{
if(stream.open(fileName)){
dBar.info("File Opened");
stream.truncate();
dBar.info("stream Truncate");
exporter:NotesDxlExporter = session.createDxlExporter();
dBar.info("Exporter Created");
stream.writeText(exporter.exportDxl(database));
dBar.info("Export Completed");
stream.close();
dBar.info("Stream Closed")
}else{
dBar.info("Could Not Open File");
}
}catch(e){
dBar.info("try failed");
}
I get the message "Exporter Created" in the debug toolbar but the stream.write fails and goes to the "try failed". I have manager rights to the current database so I don't see it as a rights issue. According to the examples that I have been able to locate this should work. Anyone see an issue with my code?

Try adding "var" to the 1st exporter statement:
var exporter:NotesDxlExporter = session.createDxlExporter();
Even better: do this using Java. It makes it much easier to catch errors like this.

Exporting a whole database as DXL can be a little tricky. One design element with a problem and your whole export fails. So this is nothing you can 100% rely on.
I learned that lesson the hard way when I wrote DXLMagic (source is on OpenNTF). Dxl handling has gotten better with later Notes versions, but isn't "end-user ready"
I would for starters follow Per's suggestion and do this in Java. Secondly, reuse the code of DXLMagic. There I export one element after the other (and stitch it into one result) to avoid failure if one element isn't clean.
Dxl isn't very good with XPages stuff and you might be better off using an OnDisk project (code only and requires a designer on the other end)

Related

Fluid clients get out of sync when server is rebooted

I got the HelloWorld example to run fine. But once I stopped & restarted the server the clients got out of sync--even when I set a consistent document (i.e. location.hash = "12345").
Setting createNew=false broke the app (no dice--literally).
And I get a lot of repeating errors:
[start:server] error: Connect Document error: {} {"messageMetaData":{"documentId":"1608237690408","tenantId":"tinylicious"},"label":"winston","timestamp":"2020-12-17T20:45:13.160Z"}
[start:server] info: Disconnect of 60c72737-3e05-4bc7-bf9b-f7ca6439a431 from room {"messageMetaData":{"documentId":"1608237690408","tenantId":"tinylicious"},"label":"winston","timestamp":"2020-12-17T20:45:13.161Z"}
Does Fluid support this scenario? Or am I doing something wrong?
The tinylicious service could support turning off & on with durable data, but it's really meant to be a test service. When you restart the service, you'll probably want to pick a new documentID.
createNew is a more interesting story. The Hello World application is somewhat contrived example. In general, the app developer will get a signal from the user that a new document should be created. Think about Google Docs.
"Create New Google Doc" -> createNew === true
"Open existing Google Doc" -> createNew === false
However, for the Hello World scenario, we want to have as little code as possible. We certainly don't want to write out a whole document management schema. So we rely on a nifty little trick: If you paste in a URL with a specific documentID we assume you are loading an existing document, otherwise we will make a new one for you.
That's what the below is doing!
You'll see the effects in the URLs, which look something like this: http://localhost:8080/#1608592296522
let createNew = false;
if (location.hash.length === 0) {
createNew = true;
location.hash = Date.now().toString();
}
const documentId = location.hash.substring(1);
document.title = documentId;

Can't get range from a defined name

Excel 2016 (Office 365) 32 bits, 16.0.6965.2115, Visual Studio 14.0.25425.01 Update 3
I'm quite sure the statement below used to work, but now it doesn't work anymore:
var range = ctx.workbook.names.getItem("Countries").getRange();
I get an error stating that there is no support for getRange method, but it should be supported as documented here.
What am I'm doing wrong?
--- EDIT: this is the code I'm using ---
function paintRange() {
Excel.run(function (ctx) {
var range = ctx.workbook.names.getItem("Countries").getRange();
range.format.fill = "green";
return ctx.sync();
}).catch(function (error) {
app.showNotification("Error", error);
})
}
paintRange is attached to a button. There is a global scope defined name called Countries.
I don't have any more details of the error besides the one I mentioned, I also tried opening the quick watch window to get more clues.
UPDATE: The issue is fixed with an update to the CDN. You should be able to use namedItem.getRange() now. Thanks for reporting the issue, and allowing us to do a quick turn-around on it.
================
Felipe, looks like you're absolutely right. This is definitely a bug. Let me talk to the right folks to get this regression fixed as soon as we can. I'll see if we can put in some processes to avoid this in the future, as well.
From an immediate-workaround perspective, two options:
Use the BETA CDN (esp if it's for an in-development add-in, rather than a production one). That URL is: https://appsforoffice.microsoft.com/lib/beta/hosted/office.js
Do a temporarily filling in of the inadvertently-removed getRange functionality. Inside of Office.initialize, include the following code:
if (!Excel.NamedItem.prototype.getRange) {
Excel.NamedItem.prototype.getRange=function () {
return new Excel.Range(this.context,
OfficeExtension.ObjectPathFactory.createMethodObjectPath(
this.context, this, "GetRange",
OfficeExtension.OperationType.Read, [], false, true, null
)
);
};
}
The workaround in #2 should not cause harm even after the functionality is restored, but I would none-the-less recommend making a mental note to remove this after we've fixed the issue. I'll update this thread once we have fixed the underlying bug, hopefully within a weeks' time (as a very rough estimate, pending any complications that might delay it).
Thanks for bringing it to our attention -- both the individual bug, and the underlying process that let the regression to this one API go unnoticed.

Child Process exits abruptly while executing in node.js

So I have been working on a project and it requires me to convert the office files into PDFs and subsequently images. I've written and integrated everything into one single node.js script, but for some reason the script keeps on bypassing the synchronous child process creation. Here is the code:
down.download(parsed_url);
var f_name=obj.doc;
var ext=f_name.slice(f_name.length-4);
var w_path="C:\\Users\\Akshay\\Desktop\\conv_Scripts\\word_pdf.ps1";
var e_path="C:\\Users\\Akshay\\Desktop\\conv_Scripts\\excel_pdf.ps1";
var p_path="C:\\Users\\Akshay\\Desktop\\conv_Scripts\\power_pdf.ps1";
var file_name=f_name.slice(0,f_name.length-5);
console.log(ext);
console.log(f_name);
console.log(file_name);
if(ext==="docx"){
word.wordpdf(w_path);
}
else if(ext==="xlsx"){
excel.excelpdf(e_path);}
else if(ext==="pptx"){
ppt.pptpdf(p_path);
console.log("Done converting to PD");
}
else if(ext==".pdf"){
img.img(f_name);
}
else{
console.log("Can't convert to PDF");
}
crawlpdf.crawlpdf(file_name,function(collect){
collect.forEach(function(col){
img.img(col);
console.log('Done!');
});
the wordpdf,excelpdf and pptpdf functions are same in their structure. I'll write down the wordpdf module's code here:
var spawn=require('child_process').spawnSync,
child;
exports.wordpdf=function(filepath){
child=spawn("powershell.exe",[filepath]);
};
The trouble is that when I execute the script,it shows me "Done converting to PD" (since the downloaded file was a ppt) but I do not find any pdf of the downloaded file .The .ps1 scripts in the path are already tested and there is no issue with them. If you could shed some light it would be really a massive help to me.
Thanks.
Alright, In case anyone else runs into the same issue as this, here's the explanation for what went wrong:
The message coming from the RabbitMQ messsage queue is small.Hence when the message arrives it is rapidly consumed,leading to race conditions in the code. For better and more accurate performance try parsing and writing the message to a file and then use async module to do the necessary steps.

EXCEL.EXE Running even after i use excelObj.Quit(); in activexscripts

Since, I could not find any satifying answer on the web for this question, I put forth it in Stackoverflow. I use activexscript to manipulate Excel, Outlook. But, even after I runexcelobj.Quit() at the end, I see an EXCEL.EXE still running in the task manager.
I tried using excelobj.Application.Quit() (as mentioned by some post in stackoverflow)also did not resolve the problem.
Can somebody help me with this??
Here's one way the application goes away in JScript:
// WScript.CreateObject for cscript.exe or wscript.exe
var excel = new ActiveXObject("Excel.Application");
// ...
excel.Quit();
// null out EVERY reference to Excel objects
excel = null;
CollectGarbage();

Scraping URLs from a node.js data stream on the fly

I am working with a node.js project (using Wikistream as a basis, so not totally my own code) which streams real-time wikipedia edits. The code breaks each edit down into its component parts and stores it as an object (See the gist at https://gist.github.com/2770152). One of the parts is a URL. I am wondering if it is possible, when parsing each edit, to scrape the URL for each edit that shows the differences between the pre-edited and post edited wikipedia page, grab the difference (inside a span class called 'diffchange diffchange-inline', for example) and add that as another property of the object. Right not it could just be a string, does not have to be fully structured.
I've tried using nodeio and have some code like this (i am specifically trying to only scrape edits that have been marked in the comments (m[6]) as possible vandalism):
if (m[6].match(/vandal/) && namespace === "article"){
nodeio.scrape(function(){
this.getHtml(m[3], function(err, $){
//console.log('getting HTML, boss.');
console.log(err);
var output = [];
$('span.diffchange.diffchange-inline').each(function(scraped){
output.push(scraped.text);
});
vandalContent = output.toString();
});
});
} else {
vandalContent = "no content";
}
When it hits the conditional statement it scrapes one time and then the program closes out. It does not store the desired content as a property of the object. If the condition is not met, it does store a vandalContent property set to "no content".
What I am wondering is: Is it even possible to scrape like this on the fly? is the scraping bogging the program down? Are there other suggested ways to get a similar result?
I haven't used nodeio yet, but the signature looks to be an async callback, so from the program flow perspective, that happens in the background and therefore does not block the next statement from occurring (next statement being whatever is outside your if block).
It looks like you're trying to do it sequentially, which means you need to either rethink what you want your callback to do or else force it to be sequential by putting the whole thing in a while loop that exits only when you have vandalcontent (which I wouldn't recommend).
For a test, try doing a console.log on your vandalContent in the callback and see what it spits out.

Resources