LogikalServer.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. using InABox.Logikal;
  2. using Ofcas.Lk.Api.Client.Core;
  3. using Ofcas.Lk.Api.Client.Ui;
  4. using Ofcas.Lk.Api.Shared;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Data.SQLite;
  8. using System.Diagnostics;
  9. using System.IO;
  10. using System.Linq;
  11. namespace PRSLogikal
  12. {
  13. public class LogikalLogArguments
  14. {
  15. public String Message { get; private set; }
  16. public LogikalLogArguments(string message)
  17. {
  18. Message = message;
  19. }
  20. }
  21. public delegate void LogikalLogEvent(object sender, LogikalLogArguments args);
  22. public class LogikalServer : IDisposable
  23. {
  24. public event LogikalLogEvent Log;
  25. private void DoLog(String message) => Log?.Invoke(this, new LogikalLogArguments(message));
  26. private IServiceProxyUiResult _proxy;
  27. private ICoreObjectResult<ILoginScope> _login;
  28. public IntPtr WindowHandle { get; private set; }
  29. public LogikalServer(IntPtr windowHandle)
  30. {
  31. WindowHandle = windowHandle;
  32. }
  33. public LogikalResponse Connect(LogikalConnectRequest request)
  34. {
  35. if (_proxy != null)
  36. return new LogikalConnectResponse();
  37. // Check that LogiKal is actually running from the folder we have specified
  38. var _driveLetter = Path.GetPathRoot(request.Path)?.Split(':').FirstOrDefault()?.ToLower() ?? "c";
  39. var _processes = Process.GetProcessesByName("LogiKal");
  40. var _running = _processes.Any(x => x.MainModule?.FileName.ToLower().Contains($"{_driveLetter}\\common\\bin\\logikal.exe") == true);
  41. if (!_running)
  42. {
  43. return new LogikalErrorResponse()
  44. {
  45. Status = LogikalStatus.NotRunning,
  46. Message = $"LogiKal is not running at [{request.Path}]"
  47. };
  48. }
  49. var _p = ServiceProxyUiFactory.CreateServiceProxy(request.Path, "erp");
  50. var _status = _p.ServiceProxyUi.Start();
  51. if (_status.OperationCode != OperationCode.Accepted)
  52. {
  53. return new LogikalErrorResponse()
  54. {
  55. Status = LogikalStatus.CannotConnect,
  56. Message = $"Unable to connect to LogiKal at [{request.Path}]: {_status}"
  57. };
  58. }
  59. _proxy = _p;
  60. return new LogikalConnectResponse();
  61. }
  62. public LogikalResponse Disconnect()
  63. {
  64. if (_login != null)
  65. Logout();
  66. if (_proxy != null)
  67. {
  68. _proxy.ServiceProxyUi.Stop();
  69. _proxy.Dispose();
  70. }
  71. _proxy = null;
  72. return new LogikalDisconnectResponse();
  73. }
  74. private void DoOnDisconnecting()
  75. {
  76. }
  77. public LogikalResponse Login(LogikalLoginRequest request)
  78. {
  79. Dictionary<string, object> _parameters = new Dictionary<string, object>()
  80. {
  81. { WellKnownParameterKey.Login.ProgramMode, "erp" },
  82. { WellKnownParameterKey.Login.ApplicationHandle, WindowHandle },
  83. //{ WellKnownParameterKey.Login.UserName, username },
  84. //{ WellKnownParameterKey.Login.Password, password },
  85. };
  86. if (_proxy == null)
  87. {
  88. return new LogikalErrorResponse()
  89. {
  90. Status = LogikalStatus.Disconnected,
  91. Message = $"LogiKal is not connected"
  92. };
  93. }
  94. if (_login != null)
  95. return new LogikalLoginResponse();
  96. var _check = _proxy.ServiceProxyUi.CanLogin(_parameters);
  97. if (!_check.CanExecute)
  98. {
  99. return new LogikalErrorResponse()
  100. {
  101. Status = LogikalStatus.Restricted,
  102. Message = $"Login not allowed: {_check}!"
  103. };
  104. }
  105. try
  106. {
  107. var _l = _proxy.ServiceProxyUi.Login(_parameters);
  108. if (_l.OperationCode != OperationCode.Accepted)
  109. {
  110. _login = null;
  111. return new LogikalErrorResponse()
  112. {
  113. Status = LogikalStatus.Failed,
  114. Message = $"Login failed: {_l}"
  115. };
  116. }
  117. else
  118. {
  119. _login = _l;
  120. return new LogikalLoginResponse();
  121. }
  122. }
  123. catch (Exception e)
  124. {
  125. return new LogikalErrorResponse()
  126. {
  127. Status = LogikalStatus.Error,
  128. Message = $"{e.Message}\n{e.StackTrace}"
  129. };
  130. }
  131. }
  132. public LogikalResponse Logout()
  133. {
  134. if (_login != null)
  135. _login.Dispose();
  136. _login = null;
  137. return new LogikalLogoutResponse();
  138. }
  139. public bool IsLoggedIn() => _login != null;
  140. public LogikalResponse GetProjects(LogikalProjectsRequest request)
  141. {
  142. if (_proxy == null)
  143. {
  144. return new LogikalErrorResponse()
  145. {
  146. Status = LogikalStatus.Disconnected,
  147. Message = $"LogiKal is not connected"
  148. };
  149. }
  150. if (_login == null)
  151. {
  152. return new LogikalErrorResponse()
  153. {
  154. Status = LogikalStatus.NotLoggedIn,
  155. Message = $"Not Logged In"
  156. };
  157. }
  158. List<LogikalProject> _result = null;
  159. IProjectCenterInfo _info = _login.CoreObject.ProjectCenterInfos.FirstOrDefault();
  160. if (_info != null)
  161. {
  162. _result = new List<LogikalProject>();
  163. using (ICoreObjectResult<IProjectCenter> _center = _login.CoreObject.GetProjectCenter(_info))
  164. {
  165. IList<IBaseProjectInfo> _projects = _center.CoreObject.ChildrenInfos;
  166. foreach (var _project in _projects)
  167. {
  168. var _summary = new LogikalProject()
  169. {
  170. ID = _project.Guid,
  171. Name = _project.Name,
  172. PersonInCharge = _project.PersonInCharge,
  173. Path = _project.Path,
  174. LastUpdated = _project.LastChangedDateTime,
  175. Created = _project.CreatedDateTime
  176. };
  177. _result.Add(_summary);
  178. }
  179. return new LogikalProjectsResponse<LogikalProject,LogikalElevation,LogikalPart>() { Projects = _result.ToArray() };
  180. }
  181. }
  182. else
  183. {
  184. return new LogikalErrorResponse()
  185. {
  186. Status = LogikalStatus.NoProjectCenter,
  187. Message = $"Cannot Retrieve Project List: No ProjectCenterInfo available"
  188. };
  189. }
  190. }
  191. public LogikalResponse GetProject(LogikalProjectRequest request)
  192. {
  193. if (_proxy == null)
  194. {
  195. return new LogikalErrorResponse()
  196. {
  197. Status = LogikalStatus.Disconnected,
  198. Message = $"LogiKal is not connected"
  199. };
  200. }
  201. if (_login == null)
  202. {
  203. return new LogikalErrorResponse()
  204. {
  205. Status = LogikalStatus.NotLoggedIn,
  206. Message = $"Not Logged In"
  207. };
  208. }
  209. LogikalProject _result = null;
  210. var _project = _login.CoreObject.GetProjectByGuid(request.ID);
  211. if (_project != null)
  212. {
  213. _result = new LogikalProject()
  214. {
  215. ID = _project.CoreObject.Id,
  216. Name = _project.CoreObject.Info.Name
  217. };
  218. List<LogikalElevation> _elevations = new List<LogikalElevation>();
  219. ICoreObjectListResult<IPhase> phases = _project.CoreObject.GetChildren();
  220. foreach (ICoreObjectResult<IPhase> phase in phases.CoreObjectResults)
  221. {
  222. ICoreObjectListResult<IElevation> elevations = phase.CoreObject.GetChildren();
  223. foreach (ICoreObjectResult<IElevation> elevation in elevations.CoreObjectResults)
  224. {
  225. var _summary = new LogikalElevation()
  226. {
  227. ID = elevation.CoreObject.Id,
  228. Name = elevation.CoreObject.Info.Name,
  229. Phase = phase.CoreObject.Info.Name
  230. };
  231. using (var ms = new MemoryStream())
  232. {
  233. IStreamResult thumbnail =
  234. elevation.CoreObject.GetThumbnail(new Dictionary<string, object>() { });
  235. thumbnail.Stream.CopyTo(ms);
  236. _summary.Thumbnail = ms.GetBuffer();
  237. }
  238. _elevations.Add(_summary);
  239. }
  240. }
  241. return new LogikalProjectResponse<LogikalProject,LogikalElevation,LogikalPart>() { Project = _result };
  242. }
  243. else
  244. {
  245. return new LogikalErrorResponse()
  246. {
  247. Status = LogikalStatus.InvalidProjectID,
  248. Message = $"Cannot Load Project {request.ID}"
  249. };
  250. }
  251. }
  252. public LogikalResponse GetElevation(LogikalElevationRequest request)
  253. {
  254. if (_proxy == null)
  255. {
  256. return new LogikalErrorResponse()
  257. {
  258. Status = LogikalStatus.Disconnected,
  259. Message = $"LogiKal is not connected"
  260. };
  261. }
  262. if (_login == null)
  263. {
  264. return new LogikalErrorResponse()
  265. {
  266. Status = LogikalStatus.NotLoggedIn,
  267. Message = $"Not Logged In"
  268. };
  269. }
  270. LogikalElevation _result = null;
  271. var _project = _login.CoreObject.GetProjectFromElevation(request.ID);
  272. if (_project != null)
  273. {
  274. ICoreObjectListResult<IPhase> children = _project.CoreObject.GetChildren();
  275. foreach (ICoreObjectResult<IPhase> child in children.CoreObjectResults)
  276. {
  277. ICoreObjectResult<IElevation> elevation = child.CoreObject.GetChildren().CoreObjectResults.FirstOrDefault(x => x.CoreObject.Id == request.ID);
  278. if (elevation != null)
  279. {
  280. _result = new LogikalElevation()
  281. {
  282. ID = elevation.CoreObject.Id,
  283. Name = elevation.CoreObject.Info.Name
  284. };
  285. using (var ms = new MemoryStream())
  286. {
  287. IDrawingResult thumbnail =
  288. elevation.CoreObject.GetDrawing(new Dictionary<string, object>() { });
  289. thumbnail.Stream.CopyTo(ms);
  290. _result.Drawing = ms.GetBuffer();
  291. }
  292. IStreamResult parts = elevation.CoreObject.GetPartsList();
  293. var file = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
  294. using (var fs = new FileStream(file, FileMode.OpenOrCreate))
  295. parts.Stream.CopyTo(fs);
  296. var sb = new SQLiteConnectionStringBuilder();
  297. sb.DataSource = file;
  298. var _connection = new SQLiteConnection(sb.ToString());
  299. _connection.Open();
  300. // Parse the file here
  301. _connection.Close();
  302. File.Delete(file);
  303. return new LogikalElevationResponse<LogikalElevation,LogikalPart>() { Elevation = _result };
  304. }
  305. }
  306. return new LogikalErrorResponse()
  307. {
  308. Status = LogikalStatus.ElevationNotFound,
  309. Message = $"Elevation Not Found {request.ID}"
  310. };
  311. }
  312. else
  313. {
  314. return new LogikalErrorResponse()
  315. {
  316. Status = LogikalStatus.InvalidElevationID,
  317. Message = $"Cannot Load Project from Elevation {request.ID}"
  318. };
  319. }
  320. }
  321. public void Dispose()
  322. {
  323. Disconnect();
  324. }
  325. }
  326. }