Files
Facilitor/UTILS/Exchange/exchange.js
Jos Groot Lipman 43234adf41 Merge 2015.3 Gold A patches
svn path=/Website/trunk/; revision=27605
2016-01-05 12:58:18 +00:00

221 lines
10 KiB
JavaScript

/*
$Revision$
$Id$
File: Exchange.js
Description: Exchange EWS koppeling
Dit bestand maakt voor één ruimte-mailbox Arguments(0) de xml-bestanden
met calenderitems aan sinds de laatste sync-actie, Arguments(1)
*/
var fso = new ActiveXObject("Scripting.FileSystemObject");
var zaalemail = WScript.Arguments(0);
var zaalsync = WScript.Arguments(1);
var inifile = ".\\exchange.config.js";
var f = fso.OpenTextFile(inifile, 1); // ForReading
var config = eval('(' + f.ReadAll() + ')')
f.Close();
WScript.Echo("Connecting to " + config.endpointurl)
// ---
// kunnen we niets mee doExchange(config.endpointurl, "<m:GetRoomLists />", "roomlist.xml");
var oCrypto = new ActiveXObject("SLNKDWF.Crypto");
var sha = oCrypto.hex_sha1(zaalsync); // Gemakkelijker verschillen te zien
WScript.Echo("\n\n==== Room: " + zaalemail + "\nOld sync hash: " + sha);
var soapRequest = '<m:SyncFolderItems'
+ ' xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" '
+ ' xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">'
+ ' <m:ItemShape>'
+ ' <t:BaseShape>IdOnly</t:BaseShape>'
+ ' <t:AdditionalProperties>'
+ ' <t:FieldURI FieldURI="calendar:CalendarItemType" />'
+ ' <t:FieldURI FieldURI="calendar:Start" />'
// + ' <t:ExtendedFieldURI DistinguishedPropertySetId="Meeting" PropertyId="3" PropertyType="Binary" />' // 3=PidLidGlobalObjectId
// + ' <t:ExtendedFieldURI DistinguishedPropertySetId="Meeting" PropertyId="35" PropertyType="Binary" />' // 35=PidLidCleanGlobalObjectId
// + ' <t:ExtendedFieldURI DistinguishedPropertySetId="Meeting" PropertyId="40" PropertyType="Binary" />' // 40=PidLidOldLocation
// + ' <t:ExtendedFieldURI DistinguishedPropertySetId="Meeting" PropertyId="98" PropertyType="Binary" />' // 98=PidTagOwnerAppointmentId
// + ' <t:FieldURI FieldURI="calendar:Subject" />'
+ ' </t:AdditionalProperties>'
+ ' </m:ItemShape>'
+ ' <m:SyncFolderId>'
+ ' <t:DistinguishedFolderId Id="calendar">'
+ ' <t:Mailbox>'
+ ' <t:EmailAddress>' + zaalemail + '</t:EmailAddress>'
+ ' </t:Mailbox>'
+ ' </t:DistinguishedFolderId>'
+ ' </m:SyncFolderId>'
+ ' <m:SyncState>' + zaalsync + '</m:SyncState> '
+ ' <m:MaxChangesReturned>' + config.maxchange + '</m:MaxChangesReturned>'
+ ' <m:SyncScope>NormalItems</m:SyncScope>'
+ '</m:SyncFolderItems>';
var room_id = safefilename(zaalemail);
var exch = doExchange(config.endpointurl, soapRequest, "Sync_" + room_id + ".xml");
if (!exch)
WScript.Quit(1);
var xmlDoc = exch.doc;
var rescode = exch.response;
if (exch.response != 'NoError')
{
WScript.Echo("Geen NoError responsecode in response: " + exch.response);
WScript.Quit(1);
}
var newsyncstate = xmlDoc.selectSingleNode("//m:SyncState");
var sha = oCrypto.hex_sha1(newsyncstate.text); // Gemakkelijker verschillen te zien
WScript.Echo("New syncstate: " + newsyncstate.text + "\nHash: " + sha + "\nlength: " + newsyncstate.text.length);
var calItems = xmlDoc.selectNodes("//t:CalendarItem");
WScript.Echo("Fetching " + calItems.length + " calendar items");
for (var i = 0; i < calItems.length; i++)
{
var calItem = calItems[i];
var Id = calItem.selectSingleNode("t:ItemId").getAttribute("Id");
var ChangeKey = calItem.selectSingleNode("t:ItemId").getAttribute("ChangeKey");
var start = calItem.selectSingleNode("t:Start").text;
var type = calItem.selectSingleNode("t:CalendarItemType").text;
//var subject = calItem.selectSingleNode("t:CalendarItemType").text;
var cal_id = room_id + "_" + i;
WScript.Echo(" " + cal_id + ": " + start + " type: " + type);
if (type == "Single")
{
var fname = "CalItem_" + cal_id + ".xml";
getCalenderItem('<t:ItemId Id="' + Id + '" ChangeKey="' + ChangeKey + '" />', fname);
}
else if (type == "RecurringMaster") // Haal Occurences en Exceptions op
{
getCalenderItem('<t:ItemId Id="' + Id + '" ChangeKey="' + ChangeKey + '" />', "receiveMasterItem_" + cal_id + ".xml");
// However the compromise with CalendarView is NO restrictions are permitted besides Start and End Date. None.
// Dat zou nog redelijk zijn als je het tot een specifieke Recurring master kon beperken. Dat kan echter niet.
// Dan maar op index ophalen
for (var j = 1; j <= config.maxrecurring; j++)
{
var rec_id = cal_id + "_" + j;
var fname = "CalItem_" + rec_id + ".xml";
var exch = getCalenderItem('<t:OccurrenceItemId RecurringMasterId="' + Id + '" InstanceIndex="' + j + '" />', fname);
var xmlDoc = exch.doc;
WScript.Echo(" Child: " + rec_id + " " + exch.response);
if (exch.response == 'ErrorCalendarOccurrenceIndexIsOutOfRecurrenceRange')
{
WScript.Echo(" Tijd om te stoppen");
fso.DeleteFile(config.xmlfolder + fname);
break;
}
if (exch.response == 'ErrorCalendarOccurrenceIsDeletedFromRecurrence')
{
WScript.Echo(" Deleted negeren we");
fso.DeleteFile(config.xmlfolder + fname);
continue;
}
var start = xmlDoc.selectSingleNode("//t:Start").text;
var type = xmlDoc.selectSingleNode("//t:CalendarItemType").text;
WScript.Echo(" Start: " + start + " " + type);
}
}
}
function getCalenderItem(filter, fname)
{
var soapRequest = '<m:GetItem xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" '
+ ' xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">'
+ ' <m:ItemShape>'
+ ' <t:BaseShape>AllProperties</t:BaseShape>' // TODO: Dit kan heel traag zijn. Alleen opvragen wat gewenst is
+ ' <t:AdditionalProperties>'
+ ' <t:ExtendedFieldURI DistinguishedPropertySetId="Meeting" PropertyId="35" PropertyType="Binary" />' // 35=PidLidCleanGlobalObjectId
+ ' <t:ExtendedFieldURI DistinguishedPropertySetId="Meeting" PropertyId="3" PropertyType="Binary" />' // 3=PidLidGlobalObjectId
+ ' <t:ExtendedFieldURI DistinguishedPropertySetId="Meeting" PropertyId="40" PropertyType="String" />' // 40=PidLidOldLocation
+ ' </t:AdditionalProperties>'
+ ' </m:ItemShape>'
+ ' <m:ItemIds>'
+ filter // Dit schijnen er ook meer te mogen zijn
+ ' </m:ItemIds>'
+ '</m:GetItem>';
return exch = doExchange(config.endpointurl, soapRequest, fname);
}
function doExchange(url, body, fname)
{
var xmlDoc = doSOAP(url, body, fname);
if (!xmlDoc)
return null;
var strQuery = "s:Envelope/s:Body/m:ResponseMessages/m:SyncFolderItemsResponseMessage/m:ResponseCode";
var strQuery = "//m:ResponseCode";
var rescode = xmlDoc.selectSingleNode(strQuery);
if (!rescode)
{
WScript.Echo("Geen responsecode in response");
WScript.Quit(1);
}
return { response: rescode.text, doc: xmlDoc };
}
function doSOAP(url, body, fname)
{
var envsoap = '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" '
+ ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" '
+ ' xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" '
+ ' xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" '
+ ' xmlns:wsi="http://ws-i.org/schemas/conformanceClaim/">'
+ ' <soap:Header>'
+ ' <t:RequestServerVersion Version=\"Exchange2010\" />'
+ ' </soap:Header>'
+ ' <soap:Body>'
+ body
+ ' </soap:Body>'
+ '</soap:Envelope>';
var res = doHTTP("POST", url, envsoap);
if (!res)
return null;
__Log2File(fname, res.responseText);
var xmlDoc = new ActiveXObject("MSXML2.DOMDocument.6.0");
xmlDoc.loadXML(res.responseText);
xmlDoc.setProperty("SelectionLanguage", "XPath");
xmlDoc.setProperty("SelectionNamespaces", 'xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"');
return xmlDoc;
}
function doHTTP(method, url, body)
{
var SXH_PROXY_SET_PROXY = 2;
var SXH_OPTION_IGNORE_SERVER_SSL_CERT_ERROR_FLAGS = 2;
var SXH_SERVER_CERT_IGNORE_ALL_SERVER_ERRORS = 0x3300;
var objXMLHTTP = new ActiveXObject("MSXML2.ServerXMLHTTP.6.0");
// objXMLHTTP.setProxy(SXH_PROXY_SET_PROXY, "127.0.0.1:8888");
objXMLHTTP.open(method, url, false, config.username, config.password);
objXMLHTTP.setRequestHeader("Content-Type", "text/xml; charset=utf-8")
objXMLHTTP.setOption(SXH_OPTION_IGNORE_SERVER_SSL_CERT_ERROR_FLAGS, SXH_SERVER_CERT_IGNORE_ALL_SERVER_ERRORS);
__Log2File("request.xml", body);
objXMLHTTP.send(body);
if (objXMLHTTP.status >= 200 && objXMLHTTP.status <= 299)
{
return objXMLHTTP;
}
__Log2File("response.xml", objXMLHTTP.responseText);
WScript.Echo(objXMLHTTP.status);
WScript.Echo(objXMLHTTP.statusText);
WScript.Echo(objXMLHTTP.responseText);
return null;
}
function safefilename (naam) // geen 'lage' karakters en geen (back)slashes, *,%,<,>, '"', ':', ';' '?' and '|' of '+'
{
return naam.replace(/[\x00-\x1F|\/|\\|\*|\%\<\>\"\:\;\?\|\+]+/g, "_"); // " syntax highlight correctie
}
function __Log2File(log_file, data)
{
var fs = new ActiveXObject("Scripting.FileSystemObject");
var ts = fs.CreateTextFile(config.xmlfolder + safefilename(log_file), true); // overwrite
ts.WriteLine (data);
ts.Close();
}