mirror of
https://github.com/finos/SymphonyElectron.git
synced 2025-02-25 18:55:29 -06:00
Merge remote-tracking branch 'upstream/skynet' into SEARCH-116-GCM
# Conflicts: # package.json
This commit is contained in:
commit
0bc51c50b1
209
demo/search.html
Normal file
209
demo/search.html
Normal file
@ -0,0 +1,209 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Search</title>
|
||||
<style>
|
||||
table, th, td {
|
||||
border: 1px solid black;
|
||||
border-collapse: collapse;
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
input {
|
||||
padding: 5px;
|
||||
margin: 2px 0;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
label {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 10px;
|
||||
background-color: rgba(0, 64, 98, 0.7);
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div style="padding: 20px;">
|
||||
<h1>Symphony Electron Search API Demo</h1>
|
||||
<div>
|
||||
<p>Search</p>
|
||||
</div>
|
||||
<div>
|
||||
<label for="query">Query:</label><input id="query" size=60>
|
||||
</div>
|
||||
<br>
|
||||
<div>
|
||||
<label for="offset">Offset:</label><input id="offset" type="number" value="0" size=5>
|
||||
<label for="limit">Limit:</label><input id="limit" type="number" value="25" size=5>
|
||||
</div>
|
||||
<br>
|
||||
<div>
|
||||
<label for="start">Start:</label><input id="start" type="date">
|
||||
<label for="end">End:</label><input id="end" type="date">
|
||||
</div>
|
||||
<br>
|
||||
<div>
|
||||
<label for="senderId">SenderId:</label><input id="senderId" placeholder='["abc", "123"]'>
|
||||
</div>
|
||||
<br>
|
||||
<div>
|
||||
<label for="threadId">ThreadId:</label><input id="threadId" placeholder='["abc", "123"]'>
|
||||
</div>
|
||||
<br>
|
||||
<div>
|
||||
<button id='search'>Search</button>
|
||||
</div>
|
||||
<br>
|
||||
<div>
|
||||
<label for="var1">var1:</label><input id="var1" type="number" value="0" size=5>
|
||||
</div>
|
||||
<br>
|
||||
<div>
|
||||
<label for="realTimeIndexing">Real Time Indexing:</label><input placeholder="Pass array of messages:"
|
||||
id="realTimeIndexing">
|
||||
<button id='sendMessage'>Send</button>
|
||||
</div>
|
||||
<br>
|
||||
<div>
|
||||
<label for="batchNumber">Batch Number: </label><input placeholder="Ex: batch1, batch2" id="batchNumber">
|
||||
<button id='index'>Index Messages</button>
|
||||
<button id='merge'>Merge</button>
|
||||
</div>
|
||||
<br>
|
||||
<div>
|
||||
<label for="batchNumber">Get Latest Message Timestamp</label>
|
||||
<button id='getLatestMessageTimestamp'>Click</button>
|
||||
<div>
|
||||
<p>Results:</p>
|
||||
<p id="results"></p>
|
||||
<table id="table" class="hidden" style="width:100%">
|
||||
<tr>
|
||||
<th>ThreadId</th>
|
||||
<th>SenderId</th>
|
||||
<th>Text</th>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var search = new ssf.Search("testUser1");
|
||||
var buttonEl = document.getElementById('search');
|
||||
var merge = document.getElementById('merge');
|
||||
var buttonIndex = document.getElementById('index');
|
||||
var queryEl = document.getElementById('query');
|
||||
var offsetEl = document.getElementById('offset');
|
||||
var limitEl = document.getElementById('limit');
|
||||
var startEl = document.getElementById('start');
|
||||
var endEl = document.getElementById('end');
|
||||
var resultsEl = document.getElementById('results');
|
||||
var senderIdEl = document.getElementById('senderId');
|
||||
var threadIdEl = document.getElementById('threadId');
|
||||
var var1El = document.getElementById('var1');
|
||||
var table = document.getElementById('table');
|
||||
var sendMessage = document.getElementById('sendMessage');
|
||||
var realTimeIndexing = document.getElementById('realTimeIndexing');
|
||||
var batchNumber = document.getElementById('batchNumber');
|
||||
var timestamp = document.getElementById('getLatestMessageTimestamp');
|
||||
|
||||
|
||||
buttonIndex.addEventListener('click', function () {
|
||||
let batchIndex = batchNumber.value;
|
||||
search.readJson(batchIndex).then(function (res) {
|
||||
search.indexBatch(res).then(function () {
|
||||
resultsEl.innerHTML = "Index created";
|
||||
});
|
||||
}).catch(function (err) {
|
||||
console.log(err);
|
||||
});
|
||||
});
|
||||
|
||||
buttonEl.addEventListener('click', function () {
|
||||
if (!search.isLibInit()) {
|
||||
search.init();
|
||||
}
|
||||
let out;
|
||||
table.innerHTML = '';
|
||||
table.classList.remove('hidden');
|
||||
let startDate = new Date(startEl.value);
|
||||
let endDate = new Date(endEl.value);
|
||||
let threadIdObj, senderIdObj;
|
||||
if (senderIdEl.value && senderIdEl.value !== "" && senderIdEl.value.replace(/ /g, "").length > 0) {
|
||||
senderIdObj = JSON.parse(senderIdEl.value);
|
||||
}
|
||||
if (threadIdEl.value && threadIdEl.value !== "" && threadIdEl.value.replace(/ /g, "").length > 0) {
|
||||
threadIdObj = JSON.parse(threadIdEl.value);
|
||||
}
|
||||
search.searchQuery(queryEl.value, senderIdObj, threadIdObj, null, startDate, endDate, limitEl.value, offsetEl.value, 0).then(function (result) {
|
||||
if (result.messages.length < 1) {
|
||||
resultsEl.innerHTML = "No results found"
|
||||
}
|
||||
if (result.messages.length > 0) {
|
||||
out = result;
|
||||
var th = document.createElement('tr');
|
||||
var th1 = document.createElement('td');
|
||||
th1.innerText = "ThreadId";
|
||||
var th2 = document.createElement('td');
|
||||
th2.innerText = 'SenderId';
|
||||
var th3 = document.createElement('td');
|
||||
th3.innerText = 'Text';
|
||||
th.appendChild(th1);
|
||||
th.appendChild(th2);
|
||||
th.appendChild(th3);
|
||||
table.appendChild(th);
|
||||
out.messages.forEach(function (msg) {
|
||||
var tr = document.createElement('tr');
|
||||
var t1 = document.createElement('td');
|
||||
t1.innerText = msg.threadId;
|
||||
var t2 = document.createElement('td');
|
||||
t2.innerText = msg.senderId;
|
||||
var t3 = document.createElement('td');
|
||||
t3.innerText = msg.text;
|
||||
tr.appendChild(t1);
|
||||
tr.appendChild(t2);
|
||||
tr.appendChild(t3);
|
||||
table.appendChild(tr);
|
||||
});
|
||||
}
|
||||
}).catch(function (err) {
|
||||
resultsEl.innerHTML = 'Error: ' + err;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
sendMessage.addEventListener('click', function () {
|
||||
if (realTimeIndexing.value !== "") {
|
||||
let message = JSON.parse(realTimeIndexing.value);
|
||||
resultsEl.innerHTML = search.realTimeIndexing(message);
|
||||
} else {
|
||||
resultsEl.innerHTML = "Please check the entered value"
|
||||
}
|
||||
});
|
||||
|
||||
merge.addEventListener('click', function () {
|
||||
search.mergeIndexBatches();
|
||||
resultsEl.innerHTML = 'Merged';
|
||||
});
|
||||
|
||||
timestamp.addEventListener('click', function () {
|
||||
search.getLatestMessageTimestamp().then(function (res) {
|
||||
resultsEl.innerHTML = res;
|
||||
}).catch(function (err) {
|
||||
resultsEl.innerHTML = 'Error: ' + err;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -18,33 +18,10 @@ sed -i "" -E "s#\"minimizeOnClose\" ?: ?([Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee])#
|
||||
sed -i "" -E "s#\"alwaysOnTop\" ?: ?([Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee])#\"alwaysOnTop\":\ $always_on_top#g" $newPath
|
||||
sed -i "" -E "s#\"launchOnStartup\" ?: ?([Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee])#\"launchOnStartup\":\ $launch_on_startup#g" $newPath
|
||||
|
||||
## Add app to login items
|
||||
if [ $launch_on_startup == true ]; then
|
||||
mkdir ~/Library/LaunchAgents/
|
||||
cat > ~/Library/LaunchAgents/com.symphony.symphony-desktop.agent.plist << EOT
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>com.symphony.symphony-desktop.agent</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>$installPath/Symphony.app/Contents/MacOS/Symphony</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
EOT
|
||||
else
|
||||
launchctl unload ~/Library/LaunchAgents/com.symphony.symphony-desktop.agent.plist
|
||||
fi
|
||||
|
||||
## Remove the temp settings file created ##
|
||||
rm -f $tempFilePath
|
||||
|
||||
## For launching symphony with sandbox enabled, create a shell script that is used as the launch point for the app
|
||||
EXEC_PATH=$installPath/Symphony.app/Contents/MacOS
|
||||
exec $EXEC_PATH/Symphony --install $newPath
|
||||
exec $EXEC_PATH/Symphony --install $newPath $launch_on_startup
|
||||
chmod 755 $EXEC_PATH/Symphony
|
||||
|
@ -52,6 +52,7 @@
|
||||
<ROW Directory="config_Dir" Directory_Parent="APPDIR" DefaultDir="config"/>
|
||||
<ROW Directory="jobber_Dir" Directory_Parent="vendor_Dir" DefaultDir="jobber"/>
|
||||
<ROW Directory="lib_Dir" Directory_Parent="spawnrx_Dir" DefaultDir="lib"/>
|
||||
<ROW Directory="library_Dir" Directory_Parent="APPDIR" DefaultDir="library"/>
|
||||
<ROW Directory="locales_Dir" Directory_Parent="APPDIR" DefaultDir="locales"/>
|
||||
<ROW Directory="node_modules_Dir" Directory_Parent="app.asar.unpacked_Dir" DefaultDir="NODE_M~1|node_modules"/>
|
||||
<ROW Directory="paulcbetts_Dir" Directory_Parent="node_modules_Dir" DefaultDir="@PAULC~1|@paulcbetts"/>
|
||||
@ -118,8 +119,13 @@
|
||||
<ROW Component="d3dcompiler_47.dll" ComponentId="{C7B87C02-3116-43A8-A70B-3592B70E6AC8}" Directory_="APPDIR" Attributes="256" KeyPath="d3dcompiler_47.dll"/>
|
||||
<ROW Component="ffmpeg.dll" ComponentId="{A1C4A332-3490-44D8-A5C9-9523889B488B}" Directory_="APPDIR" Attributes="256" KeyPath="ffmpeg.dll"/>
|
||||
<ROW Component="index.d.ts" ComponentId="{FB146550-23F5-45DD-82E4-90609B0C6562}" Directory_="src_Dir" Attributes="0" KeyPath="index.d.ts" Type="0"/>
|
||||
<ROW Component="indexvalidator.exec" ComponentId="{BCBA8EF8-A2C0-4BB7-82DB-8B3C2AF655B3}" Directory_="library_Dir" Attributes="0" KeyPath="indexvalidator.exec" Type="0"/>
|
||||
<ROW Component="indexvalidatorx64.exe" ComponentId="{1BCA45C6-A281-4F96-AE91-2050DB312CD9}" Directory_="library_Dir" Attributes="256" KeyPath="indexvalidatorx64.exe"/>
|
||||
<ROW Component="indexvalidatorx86.exe" ComponentId="{8BE192B9-D6A3-4CD9-83E5-E77634A70648}" Directory_="library_Dir" Attributes="0" KeyPath="indexvalidatorx86.exe"/>
|
||||
<ROW Component="libEGL.dll" ComponentId="{8EEC76AB-3601-4D11-B13E-32EC2A38C539}" Directory_="APPDIR" Attributes="256" KeyPath="libEGL.dll"/>
|
||||
<ROW Component="libGLESv2.dll" ComponentId="{0E8B8B21-B4C0-45C9-95D3-637FD93A4EC0}" Directory_="APPDIR" Attributes="256" KeyPath="libGLESv2.dll"/>
|
||||
<ROW Component="libsymphonysearchx64.dll" ComponentId="{5C72E1E5-9808-4DC1-B864-3E6C3434F80B}" Directory_="library_Dir" Attributes="256" KeyPath="libsymphonysearchx64.dll"/>
|
||||
<ROW Component="libsymphonysearchx86.dll" ComponentId="{FEA12082-DA6F-467C-8B51-50AAAC318FA9}" Directory_="library_Dir" Attributes="0" KeyPath="libsymphonysearchx86.dll"/>
|
||||
<ROW Component="msvcp140.dll" ComponentId="{93A6289C-CF23-4BB8-A579-7FDDD1D15591}" Directory_="APPDIR" Attributes="256" KeyPath="msvcp140.dll"/>
|
||||
<ROW Component="node.dll" ComponentId="{C0972355-339E-438C-94A3-74174DE4C6B6}" Directory_="APPDIR" Attributes="256" KeyPath="node.dll"/>
|
||||
<ROW Component="npmignore_1" ComponentId="{3367B8BE-13CC-4957-B834-60B1574BCFDB}" Directory_="spawnrx_Dir" Attributes="0" KeyPath="npmignore_1" Type="0"/>
|
||||
@ -128,13 +134,13 @@
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiFeatsComponent">
|
||||
<ROW Feature="D564007E3BBE4F85950A09B470A7CA65" Title="Visual C++ Redistributable for Visual Studio 2013 x86" Description="Visual C++ Redistributable for Visual Studio 2013 x86" Display="3" Level="1" Attributes="0" Components="AI_CustomARPName"/>
|
||||
<ROW Feature="MainFeature" Title="MainFeature" Description="Description" Display="1" Level="1" Directory_="APPDIR" Attributes="0" Components="AI_CustomARPName Jobber.exe PodUrl ProductInformation ScreenSnippet.exe Symphony Symphony.config Symphony.exe am.pak ambient.d.ts apimswincoreconsolel110.dll apimswincoredatetimel110.dll apimswincoredebugl110.dll apimswincoreerrorhandlingl110.dll apimswincorefilel110.dll apimswincorefilel120.dll apimswincorefilel210.dll apimswincorehandlel110.dll apimswincoreheapl110.dll apimswincoreinterlockedl110.dll apimswincorelibraryloaderl110.dll apimswincorelocalizationl120.dll apimswincorememoryl110.dll apimswincorenamedpipel110.dll apimswincoreprocessenvironmentl110.dll apimswincoreprocessthreadsl110.dll apimswincoreprocessthreadsl111.dll apimswincoreprofilel110.dll apimswincorertlsupportl110.dll apimswincorestringl110.dll apimswincoresynchl110.dll apimswincoresynchl120.dll apimswincoresysinfol110.dll apimswincoretimezonel110.dll apimswincoreutill110.dll apimswincrtconiol110.dll apimswincrtconvertl110.dll apimswincrtenvironmentl110.dll apimswincrtfilesysteml110.dll apimswincrtheapl110.dll apimswincrtlocalel110.dll apimswincrtmathl110.dll apimswincrtmultibytel110.dll apimswincrtprivatel110.dll apimswincrtprocessl110.dll apimswincrtruntimel110.dll apimswincrtstdiol110.dll apimswincrtstringl110.dll apimswincrttimel110.dll apimswincrtutilityl110.dll appupdate.yml blink_image_resources_200_percent.pak cld.node d3dcompiler_47.dll ffmpeg.dll index.d.ts libEGL.dll libGLESv2.dll msvcp140.dll node.dll npmignore_1 ucrtbase.dll vcruntime140.dll"/>
|
||||
<ROW Feature="MainFeature" Title="MainFeature" Description="Description" Display="1" Level="1" Directory_="APPDIR" Attributes="0" Components="AI_CustomARPName Jobber.exe PodUrl ProductInformation ScreenSnippet.exe Symphony Symphony.config Symphony.exe am.pak ambient.d.ts apimswincoreconsolel110.dll apimswincoredatetimel110.dll apimswincoredebugl110.dll apimswincoreerrorhandlingl110.dll apimswincorefilel110.dll apimswincorefilel120.dll apimswincorefilel210.dll apimswincorehandlel110.dll apimswincoreheapl110.dll apimswincoreinterlockedl110.dll apimswincorelibraryloaderl110.dll apimswincorelocalizationl120.dll apimswincorememoryl110.dll apimswincorenamedpipel110.dll apimswincoreprocessenvironmentl110.dll apimswincoreprocessthreadsl110.dll apimswincoreprocessthreadsl111.dll apimswincoreprofilel110.dll apimswincorertlsupportl110.dll apimswincorestringl110.dll apimswincoresynchl110.dll apimswincoresynchl120.dll apimswincoresysinfol110.dll apimswincoretimezonel110.dll apimswincoreutill110.dll apimswincrtconiol110.dll apimswincrtconvertl110.dll apimswincrtenvironmentl110.dll apimswincrtfilesysteml110.dll apimswincrtheapl110.dll apimswincrtlocalel110.dll apimswincrtmathl110.dll apimswincrtmultibytel110.dll apimswincrtprivatel110.dll apimswincrtprocessl110.dll apimswincrtruntimel110.dll apimswincrtstdiol110.dll apimswincrtstringl110.dll apimswincrttimel110.dll apimswincrtutilityl110.dll appupdate.yml blink_image_resources_200_percent.pak cld.node d3dcompiler_47.dll ffmpeg.dll index.d.ts indexvalidator.exec indexvalidatorx64.exe indexvalidatorx86.exe libEGL.dll libGLESv2.dll libsymphonysearchx64.dll libsymphonysearchx86.dll msvcp140.dll node.dll npmignore_1 ucrtbase.dll vcruntime140.dll"/>
|
||||
<ATTRIBUTE name="CurrentFeature" value="MainFeature"/>
|
||||
</COMPONENT>
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiFilesComponent">
|
||||
<ROW File="CODE_OF_CONDUCT.md" Component_="npmignore_1" FileName="CODE_O~1.MD|CODE_OF_CONDUCT.md" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\CODE_OF_CONDUCT.md" SelfReg="false" NextFile="COPYING"/>
|
||||
<ROW File="COPYING" Component_="npmignore_1" FileName="COPYING" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\COPYING" SelfReg="false" NextFile="esdoc.json"/>
|
||||
<ROW File="Jobber.exe" Component_="Jobber.exe" FileName="Jobber.exe" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\vendor\jobber\Jobber.exe" SelfReg="false" DigSign="true"/>
|
||||
<ROW File="Jobber.exe" Component_="Jobber.exe" FileName="Jobber.exe" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\vendor\jobber\Jobber.exe" SelfReg="false" NextFile="indexvalidatorx64.exe" DigSign="true"/>
|
||||
<ROW File="LICENSE.electron.txt" Component_="blink_image_resources_200_percent.pak" FileName="LICENS~1.TXT|LICENSE.electron.txt" Attributes="0" SourcePath="..\..\dist\win-unpacked\LICENSE.electron.txt" SelfReg="false" NextFile="LICENSES.chromium.html"/>
|
||||
<ROW File="LICENSES.chromium.html" Component_="blink_image_resources_200_percent.pak" FileName="LICENS~1.HTM|LICENSES.chromium.html" Attributes="0" SourcePath="..\..\dist\win-unpacked\LICENSES.chromium.html" SelfReg="false" NextFile="natives_blob.bin"/>
|
||||
<ROW File="ScreenSnippet.exe" Component_="ScreenSnippet.exe" FileName="SCREEN~1.EXE|ScreenSnippet.exe" Attributes="0" SourcePath="..\..\node_modules\screen-snippet\bin\Release\ScreenSnippet.exe" SelfReg="false" NextFile="apimswincoreconsolel110.dll" DigSign="true"/>
|
||||
@ -223,12 +229,18 @@
|
||||
<ROW File="index.js" Component_="index.d.ts" FileName="index.js" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\lib\src\index.js" SelfReg="false" NextFile="index.js.map"/>
|
||||
<ROW File="index.js.map" Component_="index.d.ts" FileName="INDEXJ~1.MAP|index.js.map" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\lib\src\index.js.map" SelfReg="false" NextFile="package.json_1"/>
|
||||
<ROW File="index.ts" Component_="ambient.d.ts" FileName="index.ts" Attributes="0" SourcePath="..\..\dist\win-unpacked\resources\app.asar.unpacked\node_modules\spawn-rx\src\index.ts" SelfReg="false" NextFile="tsconfig.json"/>
|
||||
<ROW File="indexvalidator.exec" Component_="indexvalidator.exec" FileName="INDEXV~3.EXE|indexvalidator.exec" Attributes="0" SourcePath="..\..\library\indexvalidator.exec" SelfReg="false" NextFile="libsymphonysearchx64.dll"/>
|
||||
<ROW File="indexvalidatorx64.exe" Component_="indexvalidatorx64.exe" FileName="INDEXV~1.EXE|indexvalidator-x64.exe" Attributes="0" SourcePath="..\..\library\indexvalidator-x64.exe" SelfReg="false" NextFile="indexvalidatorx86.exe" DigSign="true"/>
|
||||
<ROW File="indexvalidatorx86.exe" Component_="indexvalidatorx86.exe" FileName="INDEXV~2.EXE|indexvalidator-x86.exe" Attributes="0" SourcePath="..\..\library\indexvalidator-x86.exe" SelfReg="false" NextFile="indexvalidator.exec" DigSign="true"/>
|
||||
<ROW File="it.pak" Component_="am.pak" FileName="it.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\it.pak" SelfReg="false" NextFile="ja.pak"/>
|
||||
<ROW File="ja.pak" Component_="am.pak" FileName="ja.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\ja.pak" SelfReg="false" NextFile="kn.pak"/>
|
||||
<ROW File="kn.pak" Component_="am.pak" FileName="kn.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\kn.pak" SelfReg="false" NextFile="ko.pak"/>
|
||||
<ROW File="ko.pak" Component_="am.pak" FileName="ko.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\ko.pak" SelfReg="false" NextFile="lt.pak"/>
|
||||
<ROW File="libEGL.dll" Component_="libEGL.dll" FileName="libEGL.dll" Attributes="0" SourcePath="..\..\dist\win-unpacked\libEGL.dll" SelfReg="false" NextFile="libGLESv2.dll"/>
|
||||
<ROW File="libGLESv2.dll" Component_="libGLESv2.dll" FileName="LIBGLE~1.DLL|libGLESv2.dll" Attributes="0" SourcePath="..\..\dist\win-unpacked\libGLESv2.dll" SelfReg="false" NextFile="LICENSE.electron.txt"/>
|
||||
<ROW File="libsymphonysearch.dylib" Component_="indexvalidator.exec" FileName="LIBSYM~1.DYL|libsymphonysearch.dylib" Attributes="0" SourcePath="..\..\library\libsymphonysearch.dylib" SelfReg="false"/>
|
||||
<ROW File="libsymphonysearchx64.dll" Component_="libsymphonysearchx64.dll" FileName="LIBSYM~1.DLL|libsymphonysearch-x64.dll" Attributes="0" SourcePath="..\..\library\libsymphonysearch-x64.dll" SelfReg="false" NextFile="libsymphonysearchx86.dll"/>
|
||||
<ROW File="libsymphonysearchx86.dll" Component_="libsymphonysearchx86.dll" FileName="LIBSYM~2.DLL|libsymphonysearch-x86.dll" Attributes="0" SourcePath="..\..\library\libsymphonysearch-x86.dll" SelfReg="false" NextFile="libsymphonysearch.dylib"/>
|
||||
<ROW File="lt.pak" Component_="am.pak" FileName="lt.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\lt.pak" SelfReg="false" NextFile="lv.pak"/>
|
||||
<ROW File="lv.pak" Component_="am.pak" FileName="lv.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\lv.pak" SelfReg="false" NextFile="ml.pak"/>
|
||||
<ROW File="ml.pak" Component_="am.pak" FileName="ml.pak" Attributes="0" SourcePath="..\..\dist\win-unpacked\locales\ml.pak" SelfReg="false" NextFile="mr.pak"/>
|
||||
@ -560,4 +572,4 @@
|
||||
<COMPONENT cid="caphyon.advinst.msicomp.TxtUpdateSetComponent">
|
||||
<ROW Key="Symphony.config" Component="am.pak" FileName="Symphony.config" Directory="config_Dir" Options="17"/>
|
||||
</COMPONENT>
|
||||
</DOCUMENT>
|
||||
</DOCUMENT>
|
||||
|
25
js/main.js
25
js/main.js
@ -54,10 +54,22 @@ if (!isDevEnv && shouldQuit) {
|
||||
app.quit();
|
||||
}
|
||||
|
||||
var symphonyAutoLauncher = new AutoLaunch({
|
||||
name: 'Symphony',
|
||||
path: process.execPath,
|
||||
});
|
||||
let symphonyAutoLauncher;
|
||||
|
||||
if (isMac) {
|
||||
symphonyAutoLauncher = new AutoLaunch({
|
||||
name: 'Symphony',
|
||||
mac: {
|
||||
useLaunchAgent: true,
|
||||
},
|
||||
path: process.execPath,
|
||||
});
|
||||
} else {
|
||||
symphonyAutoLauncher = new AutoLaunch({
|
||||
name: 'Symphony',
|
||||
path: process.execPath,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This is for demo purpose only
|
||||
@ -142,7 +154,12 @@ function setupThenOpenMainWindow() {
|
||||
|
||||
// allows mac installer to overwrite user config
|
||||
if (isMac && hasInstallFlag) {
|
||||
// This value is being sent from post install script
|
||||
// as the app is launched as a root user we don't get
|
||||
// access to the config file
|
||||
let launchOnStartup = process.argv[3];
|
||||
updateUserConfigMac()
|
||||
.then(setStartup(launchOnStartup))
|
||||
.then(app.quit)
|
||||
.catch(app.quit);
|
||||
return;
|
||||
|
@ -4,7 +4,6 @@ const electron = require('electron');
|
||||
const { getConfigField, updateConfigField } = require('../config.js');
|
||||
const AutoLaunch = require('auto-launch');
|
||||
const isMac = require('../utils/misc.js').isMac;
|
||||
const childProcess = require('child_process');
|
||||
const log = require('../log.js');
|
||||
const logLevels = require('../enums/logLevels.js');
|
||||
const eventEmitter = require('../eventEmitter');
|
||||
@ -15,11 +14,22 @@ var isAlwaysOnTop = false;
|
||||
|
||||
setCheckboxValues();
|
||||
|
||||
var symphonyAutoLauncher = new AutoLaunch({
|
||||
name: 'Symphony',
|
||||
path: process.execPath,
|
||||
});
|
||||
let launchAgentPath = '~/Library/LaunchAgents/com.symphony.symphony-desktop.agent.plist';
|
||||
let symphonyAutoLauncher;
|
||||
|
||||
if (isMac) {
|
||||
symphonyAutoLauncher = new AutoLaunch({
|
||||
name: 'Symphony',
|
||||
mac: {
|
||||
useLaunchAgent: true,
|
||||
},
|
||||
path: process.execPath,
|
||||
});
|
||||
} else {
|
||||
symphonyAutoLauncher = new AutoLaunch({
|
||||
name: 'Symphony',
|
||||
path: process.execPath,
|
||||
});
|
||||
}
|
||||
|
||||
const template = [
|
||||
{
|
||||
@ -190,43 +200,19 @@ function getTemplate(app) {
|
||||
checked: launchOnStartup,
|
||||
click: function (item) {
|
||||
if (item.checked){
|
||||
if (isMac){
|
||||
// TODO: Need to change this implementation to AutoLaunch once they fix this issue ->
|
||||
// https://github.com/Teamwork/node-auto-launch/issues/28
|
||||
childProcess.exec(`launchctl load ${launchAgentPath}`, (err) => {
|
||||
if (err){
|
||||
let title = 'Error setting AutoLaunch configuration';
|
||||
log.send(logLevels.ERROR, 'MenuTemplate: ' + title + ': process error ' + err);
|
||||
electron.dialog.showErrorBox(title, 'Please try reinstalling the application');
|
||||
}
|
||||
symphonyAutoLauncher.enable()
|
||||
.catch(function (err) {
|
||||
let title = 'Error setting AutoLaunch configuration';
|
||||
log.send(logLevels.ERROR, 'MenuTemplate: ' + title + ': auto launch error ' + err);
|
||||
electron.dialog.showErrorBox(title, title + ': ' + err);
|
||||
});
|
||||
} else {
|
||||
symphonyAutoLauncher.enable()
|
||||
.catch(function (err) {
|
||||
let title = 'Error setting AutoLaunch configuration';
|
||||
log.send(logLevels.ERROR, 'MenuTemplate: ' + title + ': auto launch error ' + err);
|
||||
electron.dialog.showErrorBox(title, title + ': ' + err);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (isMac){
|
||||
// TODO: Need to change this implementation to AutoLaunch once they fix this issue ->
|
||||
// https://github.com/Teamwork/node-auto-launch/issues/28
|
||||
childProcess.exec(`launchctl unload ${launchAgentPath}`, (err) => {
|
||||
if (err){
|
||||
let title = 'Error disabling AutoLaunch configuration';
|
||||
log.send(logLevels.ERROR, 'MenuTemplate: ' + title + ': process error ' + err);
|
||||
electron.dialog.showErrorBox(title, 'Please try reinstalling the application');
|
||||
}
|
||||
symphonyAutoLauncher.disable()
|
||||
.catch(function (err) {
|
||||
let title = 'Error setting AutoLaunch configuration';
|
||||
log.send(logLevels.ERROR, 'MenuTemplate: ' + title + ': auto launch error ' + err);
|
||||
electron.dialog.showErrorBox(title, title + ': ' + err);
|
||||
});
|
||||
} else {
|
||||
symphonyAutoLauncher.disable()
|
||||
.catch(function (err) {
|
||||
let title = 'Error setting AutoLaunch configuration';
|
||||
log.send(logLevels.ERROR, 'MenuTemplate: ' + title + ': auto launch error ' + err);
|
||||
electron.dialog.showErrorBox(title, title + ': ' + err);
|
||||
});
|
||||
}
|
||||
}
|
||||
launchOnStartup = item.checked;
|
||||
updateConfigField('launchOnStartup', launchOnStartup);
|
||||
|
@ -130,6 +130,13 @@ function createAPI() {
|
||||
*/
|
||||
ScreenSnippet: remote.require('./screenSnippet/ScreenSnippet.js').ScreenSnippet,
|
||||
|
||||
/**
|
||||
* Provides api for client side searching
|
||||
* using the SymphonySearchEngine library
|
||||
* details in ./search/search.js & ./search/searchLibrary.js
|
||||
*/
|
||||
Search: remote.require('./search/search.js').Search,
|
||||
|
||||
/**
|
||||
* Brings window forward and gives focus.
|
||||
* @param {String} windowName Name of window. Note: main window name is 'main'
|
||||
|
397
js/search/search.js
Normal file
397
js/search/search.js
Normal file
@ -0,0 +1,397 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const randomString = require('randomstring');
|
||||
const electron = require('electron');
|
||||
const childProcess = require('child_process');
|
||||
const app = electron.app;
|
||||
const path = require('path');
|
||||
const isDevEnv = require('../utils/misc.js').isDevEnv;
|
||||
const isMac = require('../utils/misc.js').isMac;
|
||||
|
||||
// Search library
|
||||
const libSymphonySearch = require('./searchLibrary');
|
||||
|
||||
// Path for the exec file and the user data folder
|
||||
const userData = path.join(app.getPath('userData'));
|
||||
const execPath = path.dirname(app.getPath('exe'));
|
||||
|
||||
// Constants paths for temp indexing folders
|
||||
const TEMP_BATCH_INDEX_FOLDER = isDevEnv ? './data/temp_batch_indexes' : path.join(userData, 'data/temp_batch_indexes');
|
||||
const TEMP_REAL_TIME_INDEX = isDevEnv ? './data/temp_realtime_index' : path.join(userData, 'data/temp_realtime_index');
|
||||
const INDEX_PREFIX = isDevEnv ? './data/search_index' : path.join(userData, 'data/search_index');
|
||||
const INDEX_DATA_FOLDER = isDevEnv ? './data' : path.join(userData, 'data');
|
||||
const SEARCH_PERIOD_SUBTRACTOR = 3 * 31 * 24 * 60 * 60 * 1000;//3 months
|
||||
const MINIMUM_DATE = '0000000000000';
|
||||
const MAXIMUM_DATE = '9999999999999';
|
||||
const INDEX_VERSION = 'v1';
|
||||
|
||||
const SORT_BY_SCORE = 0;
|
||||
const BATCH_RANDOM_INDEX_PATH_LENGTH = 20;
|
||||
|
||||
// library path contractor
|
||||
const winArchPath = process.arch === 'ia32' ? 'library/indexvalidator-x86.exe' : 'library/indexvalidator-x64.exe';
|
||||
const rootPath = isMac ? 'library/indexvalidator.exec' : winArchPath;
|
||||
const productionPath = path.join(execPath, isMac ? '..' : '', rootPath);
|
||||
const devPath = path.join(__dirname, '..', '..', rootPath);
|
||||
const INDEX_VALIDATOR = isDevEnv ? devPath : productionPath;
|
||||
|
||||
/**
|
||||
* This search class communicates with the SymphonySearchEngine C library via node-ffi.
|
||||
* There should be only 1 instance of this class in the Electron
|
||||
*/
|
||||
class Search {
|
||||
|
||||
/**
|
||||
* Constructor for the SymphonySearchEngine library
|
||||
* @param userId (for the index folder name)
|
||||
*/
|
||||
constructor(userId) {
|
||||
this.isInitialized = false;
|
||||
this.userId = userId;
|
||||
this.startIndexingFromDate = (new Date().getTime() - SEARCH_PERIOD_SUBTRACTOR).toString();
|
||||
this.indexFolderName = INDEX_PREFIX + '_' + userId + '_' + INDEX_VERSION;
|
||||
this.dataFolder = INDEX_DATA_FOLDER;
|
||||
this.realTimeIndex = TEMP_REAL_TIME_INDEX;
|
||||
this.batchIndex = TEMP_BATCH_INDEX_FOLDER;
|
||||
this.messageData = [];
|
||||
this.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* returns isInitialized boolean
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isLibInit() {
|
||||
return this.isInitialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* This init function
|
||||
* initialise the SymphonySearchEngine library
|
||||
* and creates a folder in the userData
|
||||
*/
|
||||
init() {
|
||||
libSymphonySearch.symSEInit();
|
||||
libSymphonySearch.symSEEnsureFolderExists(this.dataFolder);
|
||||
libSymphonySearch.symSERemoveFolder(this.realTimeIndex);
|
||||
libSymphonySearch.symSERemoveFolder(this.batchIndex);
|
||||
Search.indexValidator(this.indexFolderName);
|
||||
Search.indexValidator(this.realTimeIndex);
|
||||
let indexDateStartFrom = new Date().getTime() - SEARCH_PERIOD_SUBTRACTOR;
|
||||
libSymphonySearch.symSEDeleteMessages(this.indexFolderName, null,
|
||||
MINIMUM_DATE, indexDateStartFrom.toString());
|
||||
this.isInitialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* An array of messages is passed for indexing
|
||||
* it will be indexed in a temporary index folder
|
||||
* @param {Array} messages
|
||||
* @returns {Promise}
|
||||
*/
|
||||
indexBatch(messages) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!Array.isArray(messages)) {
|
||||
reject(new Error('Messages must be an array'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.isInitialized) {
|
||||
reject(new Error('Library not initialized'));
|
||||
return;
|
||||
}
|
||||
|
||||
const indexId = randomString.generate(BATCH_RANDOM_INDEX_PATH_LENGTH);
|
||||
libSymphonySearch.symSECreatePartialIndexAsync(this.batchIndex, indexId, JSON.stringify(messages), (err, res) => {
|
||||
if (err) {
|
||||
reject(new Error(err));
|
||||
}
|
||||
resolve(res);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Merging the temporary
|
||||
* created from indexBatch()
|
||||
*/
|
||||
mergeIndexBatches() {
|
||||
libSymphonySearch.symSEMergePartialIndexAsync(this.indexFolderName, this.batchIndex, (err) => {
|
||||
if (err) {
|
||||
throw new Error(err);
|
||||
}
|
||||
libSymphonySearch.symSERemoveFolder(this.batchIndex)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* An array of messages to be indexed
|
||||
* in real time
|
||||
* @param message
|
||||
*/
|
||||
realTimeIndexing(message) {
|
||||
if (!Array.isArray(message)) {
|
||||
return new Error('Messages should be an array');
|
||||
}
|
||||
|
||||
if (!this.isInitialized) {
|
||||
return new Error('Library not initialized');
|
||||
}
|
||||
|
||||
let result = libSymphonySearch.symSEIndexRealTime(this.realTimeIndex, JSON.stringify(message));
|
||||
return result === 0 ? "Successful" : result
|
||||
}
|
||||
|
||||
/**
|
||||
* Reading a json file
|
||||
* for the demo search app only
|
||||
* @param {String} batch
|
||||
* @returns {Promise}
|
||||
*/
|
||||
readJson(batch) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let dirPath = path.join(execPath, isMac ? '..' : '', 'msgsjson', batch);
|
||||
let messageFolderPath = isDevEnv ? path.join('./msgsjson', batch) : dirPath;
|
||||
let files = fs.readdirSync(messageFolderPath);
|
||||
this.messageData = [];
|
||||
files.forEach((file) => {
|
||||
let tempPath = path.join(messageFolderPath, file);
|
||||
let data = fs.readFileSync(tempPath, "utf8");
|
||||
if (data) {
|
||||
try {
|
||||
this.messageData.push(JSON.parse(data));
|
||||
} catch (err) {
|
||||
reject(new Error(err))
|
||||
}
|
||||
} else {
|
||||
reject(new Error('Error reading batch'))
|
||||
}
|
||||
});
|
||||
resolve(this.messageData);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the search results
|
||||
* which returns a char *
|
||||
* @param {String} query
|
||||
* @param {Array} senderIds
|
||||
* @param {Array} threadIds
|
||||
* @param {String} attachments
|
||||
* @param {String} startDate
|
||||
* @param {String} endDate
|
||||
* @param {Number} limit
|
||||
* @param {Number} offset
|
||||
* @param {Number} sortOrder
|
||||
* @returns {Promise}
|
||||
*/
|
||||
searchQuery(query, senderIds, threadIds, attachments, startDate,
|
||||
endDate, limit, offset, sortOrder) {
|
||||
|
||||
let _limit = limit;
|
||||
let _offset = offset;
|
||||
let _sortOrder = sortOrder;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.isInitialized) {
|
||||
reject(new Error('Library not initialized'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fs.existsSync(this.indexFolderName) || !fs.existsSync(this.realTimeIndex)) {
|
||||
reject('Index folder does not exist.');
|
||||
return;
|
||||
}
|
||||
|
||||
let q = Search.constructQuery(query, senderIds, threadIds);
|
||||
|
||||
if (q === undefined) {
|
||||
reject(new Error('Search query error'));
|
||||
return;
|
||||
}
|
||||
|
||||
let sd = new Date().getTime() - SEARCH_PERIOD_SUBTRACTOR;
|
||||
let sd_time = MINIMUM_DATE;
|
||||
if (startDate && startDate !== "" && typeof startDate === 'object') {
|
||||
sd_time = new Date(startDate).getTime();
|
||||
if (sd_time >= sd) {
|
||||
sd_time = sd;
|
||||
}
|
||||
}
|
||||
|
||||
let ed_time = MAXIMUM_DATE;
|
||||
if (endDate && endDate !== "" && typeof endDate === 'object') {
|
||||
ed_time = new Date(endDate).getTime();
|
||||
}
|
||||
|
||||
if (!_limit && _limit === "" && typeof _limit !== 'number' && Math.round(_limit) !== _limit) {
|
||||
_limit = 25;
|
||||
}
|
||||
|
||||
if (!_offset && _offset === "" && typeof _offset !== 'number' && Math.round(_offset) !== _offset) {
|
||||
_offset = 0
|
||||
}
|
||||
|
||||
if (!_sortOrder && _sortOrder === "" && typeof _sortOrder !== 'number' && Math.round(_sortOrder) !== _sortOrder) {
|
||||
_sortOrder = SORT_BY_SCORE;
|
||||
}
|
||||
|
||||
const returnedResult = libSymphonySearch.symSESearch(this.indexFolderName, this.realTimeIndex, q, sd_time.toString(), ed_time.toString(), _offset, _limit, _sortOrder);
|
||||
try {
|
||||
let ret = returnedResult.readCString();
|
||||
resolve(JSON.parse(ret));
|
||||
} finally {
|
||||
libSymphonySearch.symSEFreeResult(returnedResult);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the latest message timestamp
|
||||
* from the indexed data
|
||||
* @returns {Promise}
|
||||
*/
|
||||
getLatestMessageTimestamp() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.isInitialized) {
|
||||
reject('Not initialized');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fs.existsSync(this.indexFolderName)) {
|
||||
reject('Index folder does not exist.');
|
||||
return;
|
||||
}
|
||||
|
||||
libSymphonySearch.symSEGetLastMessageTimestampAsync(this.indexFolderName, (err, res) => {
|
||||
if (err) {
|
||||
reject(new Error(err));
|
||||
}
|
||||
const returnedResult = res;
|
||||
try {
|
||||
let ret = returnedResult.readCString();
|
||||
resolve(ret);
|
||||
} finally {
|
||||
libSymphonySearch.symSEFreeResult(returnedResult);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This the query constructor
|
||||
* for the search function
|
||||
* @param {String} searchQuery
|
||||
* @param {Array} senderId
|
||||
* @param {Array} threadId
|
||||
* @returns {string}
|
||||
*/
|
||||
static constructQuery(searchQuery, senderId, threadId) {
|
||||
|
||||
let query = "";
|
||||
if(searchQuery !== undefined) {
|
||||
query = searchQuery.trim().toLowerCase(); //to prevent injection of AND and ORs
|
||||
}
|
||||
let q = "";
|
||||
let hashTags = Search.getHashTags(query);
|
||||
let hashCashTagQuery = "";
|
||||
|
||||
if(hashTags.length > 0) {
|
||||
hashCashTagQuery = " OR tags:(";
|
||||
hashTags.forEach((item) => {
|
||||
hashCashTagQuery = hashCashTagQuery + "\"" + item + "\" "
|
||||
});
|
||||
hashCashTagQuery += ")";
|
||||
}
|
||||
|
||||
if (query.length > 0 ) {
|
||||
q = "(text:(" + query + ")" + hashCashTagQuery + ")";
|
||||
}
|
||||
|
||||
q = Search.appendFilterQuery(q, "senderId", senderId);
|
||||
q = Search.appendFilterQuery(q, "threadId", threadId);
|
||||
|
||||
if(q === "") {
|
||||
q = undefined; //will be handled in the search function
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
/**
|
||||
* appending the senderId and threadId for the query
|
||||
* @param {String} query
|
||||
* @param {String} fieldName
|
||||
* @param {Array} valueArray
|
||||
* @returns {string}
|
||||
*/
|
||||
static appendFilterQuery(query, fieldName, valueArray) {
|
||||
let q = "";
|
||||
if (valueArray && valueArray.length > 0 ) {
|
||||
|
||||
q += "(" + fieldName +":(";
|
||||
valueArray.forEach((item)=>{
|
||||
q+= "\"" + item + "\" ";
|
||||
});
|
||||
q += "))";
|
||||
if(query.length > 0 ) {
|
||||
q = query + " AND " + q;
|
||||
}
|
||||
|
||||
} else {
|
||||
q = query;
|
||||
}
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
// hashtags can have any characters(before the latest release it was
|
||||
// not like this). So the only regex is splitting the search query based on
|
||||
// whitespaces
|
||||
/**
|
||||
* return the hash cash
|
||||
* tags from the query
|
||||
* @param {String} query
|
||||
* @returns {Array}
|
||||
*/
|
||||
static getHashTags(query) {
|
||||
let hashTags = [];
|
||||
let tokens = query.toLowerCase()
|
||||
.trim()
|
||||
.replace(/\s\s+/g, ' ')
|
||||
.split(' ').filter((el) => {return el.length !== 0});
|
||||
tokens.forEach((item) => {
|
||||
if (item.startsWith('#') || item.startsWith('$')) {
|
||||
hashTags.push(item);
|
||||
}
|
||||
});
|
||||
return hashTags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the index folder exist or not
|
||||
* @param {String} file
|
||||
* @returns {*}
|
||||
*/
|
||||
static indexValidator(file) {
|
||||
let data;
|
||||
let result = childProcess.execFileSync(INDEX_VALIDATOR, [file]).toString();
|
||||
try {
|
||||
data = JSON.parse(result);
|
||||
if (data.status === 'OK') {
|
||||
return data;
|
||||
}
|
||||
return new Error('Unable validate index folder')
|
||||
} catch (err) {
|
||||
throw new Error(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exporting the search library
|
||||
* @type {{Search: Search}}
|
||||
*/
|
||||
module.exports = {
|
||||
Search: Search
|
||||
};
|
87
js/search/searchLibrary.js
Normal file
87
js/search/searchLibrary.js
Normal file
@ -0,0 +1,87 @@
|
||||
'use strict';
|
||||
|
||||
const ffi = require('ffi');
|
||||
const ref = require('ref');
|
||||
const electron = require('electron');
|
||||
const app = electron.app;
|
||||
const path = require('path');
|
||||
const isDevEnv = require('../utils/misc.js').isDevEnv;
|
||||
const isMac = require('../utils/misc.js').isMac;
|
||||
|
||||
// ref types
|
||||
const symLucyIndexer = ref.types.void;
|
||||
const symLucyIndexerPtr = ref.refType(symLucyIndexer);
|
||||
|
||||
// application execution path
|
||||
const execPath = path.dirname(app.getPath('exe'));
|
||||
|
||||
// library path contractor
|
||||
const winArchPath = process.arch === 'ia32' ? 'library/libsymphonysearch-x86.dll' : 'library/libsymphonysearch-x64.dll';
|
||||
const rootPath = isMac ? 'library/libsymphonysearch.dylib' : winArchPath;
|
||||
const productionPath = path.join(execPath, isMac ? '..' : '', rootPath);
|
||||
const devPath = path.join(__dirname, '..', '..', rootPath);
|
||||
const libraryPath = isDevEnv ? devPath : productionPath;
|
||||
|
||||
/**
|
||||
* Initializing the C SymphonySearchEngine library
|
||||
* using the node-ffi
|
||||
*/
|
||||
let libSymphonySearch = ffi.Library(libraryPath, {
|
||||
//init
|
||||
'symSE_init': ['void', []],
|
||||
'symSE_remove_folder': ['int', ['string']],
|
||||
'symSE_ensure_index_exists': ['int', ['string']],
|
||||
'symSE_ensure_folder_exists': ['int', ['string']],
|
||||
//first time indexing and delta indexing
|
||||
'symSE_get_indexer': [symLucyIndexerPtr, ['string']], //will be removed
|
||||
'symSE_create_partial_index': ['int', ['string', 'string', 'string']],
|
||||
'symSE_merge_partial_index': ['int', ['string', 'string']],
|
||||
//real time indexing
|
||||
'symSE_index_realtime': ['int', ['string', 'string']],
|
||||
'symSE_merge_temp_index': ['int', ['string', 'string']],
|
||||
'symSE_clear_temp_index': ['int', ['string']],
|
||||
//Search,
|
||||
'symSE_search': ['char *', ['string', 'string', 'string', 'string', 'string', 'int', 'int', 'int']],
|
||||
//Deletion
|
||||
'symSE_delete_messages': ['int', ['string', 'string', 'string', 'string']],
|
||||
//Index commit/optimize
|
||||
'symSE_commit_index': ['int', [symLucyIndexerPtr, 'int']], //will be removed
|
||||
//freePointer
|
||||
'symSE_free_results': ['int', ['char *']],
|
||||
|
||||
//Latest messages timestamp
|
||||
'symSE_get_last_message_timestamp': ['char *', ['string']]
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
symSEInit: libSymphonySearch.symSE_init,
|
||||
symSERemoveFolder: libSymphonySearch.symSE_remove_folder,
|
||||
symSEEnsureIndexExists: libSymphonySearch.symSE_ensure_index_exists,
|
||||
symSEEnsureFolderExists: libSymphonySearch.symSE_ensure_folder_exists,
|
||||
symSEGetIndexer: libSymphonySearch.symSE_get_indexer,
|
||||
symSECreatePartialIndex: libSymphonySearch.symSE_create_partial_index,
|
||||
symSEMergePartialIndex: libSymphonySearch.symSE_merge_partial_index,
|
||||
symSEIndexRealTime: libSymphonySearch.symSE_index_realtime,
|
||||
symSEMergeTempIndex: libSymphonySearch.symSE_merge_temp_index,
|
||||
symSEClearTempIndex: libSymphonySearch.symSE_clear_temp_index,
|
||||
symSESearch: libSymphonySearch.symSE_search,
|
||||
symSEDeleteMessages: libSymphonySearch.symSE_delete_messages,
|
||||
symSECommitIndex: libSymphonySearch.symSE_commit_index,
|
||||
symSEFreeResult: libSymphonySearch.symSE_free_results,
|
||||
symSEGetLastMessageTimestamp: libSymphonySearch.symSE_get_last_message_timestamp,
|
||||
symSEInitAsync: libSymphonySearch.symSE_init.async,
|
||||
symSERemoveFolderAsync: libSymphonySearch.symSE_remove_folder.async,
|
||||
symSEEnsureIndexExistsAsync: libSymphonySearch.symSE_ensure_index_exists.async,
|
||||
symSEEnsureFolderExistsAsync: libSymphonySearch.symSE_ensure_folder_exists.async,
|
||||
symSEGetIndexerAsync: libSymphonySearch.symSE_get_indexer.async,
|
||||
symSECreatePartialIndexAsync: libSymphonySearch.symSE_create_partial_index.async,
|
||||
symSEMergePartialIndexAsync: libSymphonySearch.symSE_merge_partial_index.async,
|
||||
symSEIndexRealTimeAsync: libSymphonySearch.symSE_index_realtime.async,
|
||||
symSEMergeTempIndexAsync: libSymphonySearch.symSE_merge_temp_index.async,
|
||||
symSEClearTempIndexAsync: libSymphonySearch.symSE_clear_temp_index.async,
|
||||
symSESearchAsync: libSymphonySearch.symSE_search.async,
|
||||
symSEDeleteMessagesAsync: libSymphonySearch.symSE_delete_messages.async,
|
||||
symSECommitIndexAsync: libSymphonySearch.symSE_commit_index.async,
|
||||
symSEFreeResultAsync: libSymphonySearch.symSE_free_results.async,
|
||||
symSEGetLastMessageTimestampAsync: libSymphonySearch.symSE_get_last_message_timestamp.async
|
||||
};
|
BIN
library/indexvalidator-x64.exe
Executable file
BIN
library/indexvalidator-x64.exe
Executable file
Binary file not shown.
BIN
library/indexvalidator-x86.exe
Executable file
BIN
library/indexvalidator-x86.exe
Executable file
Binary file not shown.
BIN
library/indexvalidator.exec
Executable file
BIN
library/indexvalidator.exec
Executable file
Binary file not shown.
BIN
library/libsymphonysearch-x64.dll
Executable file
BIN
library/libsymphonysearch-x64.dll
Executable file
Binary file not shown.
BIN
library/libsymphonysearch-x86.dll
Executable file
BIN
library/libsymphonysearch-x86.dll
Executable file
Binary file not shown.
BIN
library/libsymphonysearch.dylib
Executable file
BIN
library/libsymphonysearch.dylib
Executable file
Binary file not shown.
18
package.json
18
package.json
@ -9,10 +9,12 @@
|
||||
"dev": "npm run prebuild && cross-env ELECTRON_DEV=true electron .",
|
||||
"demo-win": "npm run prebuild && cross-env ELECTRON_DEV=true electron . --url=file:///demo/index.html",
|
||||
"demo-mac": "npm run prebuild && cross-env ELECTRON_DEV=true electron . --url=file://$(pwd)/demo/index.html",
|
||||
"search-win": "npm run prebuild && cross-env ELECTRON_DEV=true electron . --url=file:///demo/search.html",
|
||||
"search-mac": "npm run prebuild && cross-env ELECTRON_DEV=true electron . --url=file://$(pwd)/demo/search.html",
|
||||
"unpacked-mac": "npm run prebuild && npm run test && build --mac --dir",
|
||||
"packed-mac": "npm run unpacked-mac && packagesbuild -v installer/mac/symphony-mac-packager.pkgproj",
|
||||
"unpacked-win": "npm run prebuild && npm run test && build --win --x64 --dir",
|
||||
"unpacked-win-x86": "npm run prebuild && npm run test && build --win --ia32",
|
||||
"unpacked-win-x86": "npm run prebuild && npm run test && build --win --ia32 --dir",
|
||||
"prebuild": "npm run rebuild && npm run browserify-preload",
|
||||
"browserify-preload": "browserify -o js/preload/_preloadMain.js -x electron --insert-global-vars=__filename,__dirname js/preload/preloadMain.js --exclude electron-spellchecker",
|
||||
"rebuild": "electron-rebuild -f",
|
||||
@ -30,9 +32,16 @@
|
||||
"files": [
|
||||
"!coverage/*",
|
||||
"!installer/*",
|
||||
"!tests/*"
|
||||
"!tests/*",
|
||||
"!node_modules/@paulcbetts/cld/deps/cld${/*}",
|
||||
"!node_modules/@paulcbetts/cld/build/deps${/*}",
|
||||
"!node_modules/@paulcbetts/spellchecker/vendor${/*}"
|
||||
],
|
||||
"extraFiles": [
|
||||
"config/Symphony.config",
|
||||
"library/libsymphonysearch.dylib",
|
||||
"library/indexvalidator.exec"
|
||||
],
|
||||
"extraFiles": "config/Symphony.config",
|
||||
"appId": "symphony-electron-desktop",
|
||||
"mac": {
|
||||
"target": "dmg",
|
||||
@ -97,9 +106,12 @@
|
||||
"electron-spellchecker": "^1.2.0",
|
||||
"electron-squirrel-startup": "^1.0.0",
|
||||
"extract-zip": "^1.6.5",
|
||||
"ffi": "^2.2.0",
|
||||
"filesize": "^3.5.10",
|
||||
"keymirror": "0.1.1",
|
||||
"node-forge": "^0.7.1",
|
||||
"randomstring": "^1.1.5",
|
||||
"ref": "^1.3.4",
|
||||
"winreg": "^1.2.3"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
|
Loading…
Reference in New Issue
Block a user