PageRenderTime 52ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/dotNet/dotNetWrapper/RestServiceClient.cs

https://github.com/tamisoft/ocrsdk.com
C# | 664 lines | 462 code | 101 blank | 101 comment | 29 complexity | 215569716d04a62b376aaab5ecb63ff8 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Net;
  7. using System.Text;
  8. using System.Xml;
  9. using System.Xml.Linq;
  10. namespace Abbyy.CloudOcrSdk
  11. {
  12. public class ProcessingErrorException : System.Net.WebException
  13. {
  14. public ProcessingErrorException(string message, System.Net.WebException e)
  15. : base(message, e)
  16. {
  17. }
  18. }
  19. public class Task
  20. {
  21. public TaskId Id;
  22. public TaskStatus Status;
  23. /// <summary>
  24. /// When task was created. Can be null if no information
  25. /// </summary>
  26. public DateTime RegistrationTime;
  27. /// <summary>
  28. /// Last activity time. Can be null if no information
  29. /// </summary>
  30. public DateTime StatusChangeTime;
  31. /// <summary>
  32. /// Number of pages in task
  33. /// </summary>
  34. public int PagesCount = 1;
  35. /// <summary>
  36. /// Task cost in credits
  37. /// </summary>
  38. public int Credits = 0;
  39. /// <summary>
  40. /// Task description provided by user
  41. /// </summary>
  42. public string Description = null;
  43. /// <summary>
  44. /// Url to download processed tasks
  45. /// </summary>
  46. public List<string> DownloadUrls = null;
  47. /// <summary>
  48. /// Error description when task processing failed
  49. /// </summary>
  50. public string Error = null;
  51. public Task()
  52. {
  53. Status = TaskStatus.Unknown;
  54. Id = new TaskId("<unknown>");
  55. }
  56. public Task(TaskId id, TaskStatus status)
  57. {
  58. Id = id;
  59. Status = status;
  60. }
  61. public bool IsTaskActive()
  62. {
  63. return IsTaskActive(Status);
  64. }
  65. // Task is submitted or is processing
  66. public static bool IsTaskActive( TaskStatus status )
  67. {
  68. switch (status)
  69. {
  70. case TaskStatus.Submitted:
  71. case TaskStatus.Queued:
  72. case TaskStatus.InProgress:
  73. return true;
  74. default:
  75. return false;
  76. }
  77. }
  78. }
  79. public enum TaskStatus
  80. {
  81. Unknown,
  82. Submitted,
  83. Queued,
  84. InProgress,
  85. Completed,
  86. ProcessingFailed,
  87. Deleted,
  88. NotEnoughCredits
  89. }
  90. public class TaskId : IEquatable<TaskId>
  91. {
  92. public TaskId(string id)
  93. {
  94. _id = id;
  95. }
  96. public override string ToString()
  97. {
  98. return _id;
  99. }
  100. public override int GetHashCode()
  101. {
  102. return _id.GetHashCode();
  103. }
  104. public bool Equals(TaskId b)
  105. {
  106. return b._id == _id;
  107. }
  108. private readonly string _id;
  109. }
  110. public interface IRequestAuthSetup {
  111. void Run( WebRequest request, String username, String password );
  112. }
  113. public class BasicRequestAuthSetup : IRequestAuthSetup {
  114. public void Run( WebRequest request, String username, String password )
  115. {
  116. Encoding encoding = Encoding.GetEncoding("iso-8859-1");
  117. string toEncode = username + ":" + password;
  118. string baseEncoded = Convert.ToBase64String(encoding.GetBytes(toEncode));
  119. request.Headers.Add( "Authorization", "Basic: " + baseEncoded );
  120. }
  121. }
  122. public class RestServiceClient
  123. {
  124. public RestServiceClient()
  125. {
  126. ServerUrl = "http://cloud.ocrsdk.com/";
  127. IsSecureConnection = false;
  128. Proxy = WebRequest.DefaultWebProxy;
  129. RequestAuthSetup = new BasicRequestAuthSetup();
  130. }
  131. /// <summary>
  132. /// Url of the server
  133. /// On set, IsSecureConnection property is changed url contains protocol (http:// or https://)
  134. /// </summary>
  135. public string ServerUrl
  136. {
  137. get
  138. {
  139. if (IsSecureConnection)
  140. return "https://" + _serverAddress;
  141. else
  142. return "http://" + _serverAddress;
  143. }
  144. set
  145. {
  146. if (value.StartsWith("http://", StringComparison.InvariantCultureIgnoreCase))
  147. {
  148. IsSecureConnection = false;
  149. }
  150. else if (value.StartsWith("https://", StringComparison.InvariantCultureIgnoreCase))
  151. {
  152. IsSecureConnection = true;
  153. }
  154. // Trim http(s):// from the beginning
  155. _serverAddress = System.Text.RegularExpressions.Regex.Replace(value, "^https?://", "");
  156. }
  157. }
  158. public string ApplicationId { get; set; }
  159. public string Password { get; set; }
  160. public IWebProxy Proxy { get; set; }
  161. public IRequestAuthSetup RequestAuthSetup { get; set; }
  162. /// <summary>
  163. /// Does the connection use SSL or not. Set this property after ServerUrl
  164. /// </summary>
  165. public bool IsSecureConnection { get; set; }
  166. /// <summary>
  167. /// Upload a file to service synchronously and start processing
  168. /// </summary>
  169. /// <param name="filePath">Path to an image to process</param>
  170. /// <param name="settings">Language and output format</param>
  171. /// <returns>Id of the task. Check task status to see if you have enough units to process the task</returns>
  172. /// <exception cref="ProcessingErrorException">thrown when something goes wrong</exception>
  173. public Task ProcessImage(string filePath, ProcessingSettings settings)
  174. {
  175. string url = String.Format("{0}/processImage?{1}", ServerUrl, settings.AsUrlParams);
  176. if (!String.IsNullOrEmpty(settings.Description))
  177. {
  178. url = url + "&description=" + Uri.EscapeDataString(settings.Description);
  179. }
  180. try
  181. {
  182. // Build post request
  183. WebRequest request = WebRequest.Create(url);
  184. setupPostRequest(url, request);
  185. writeFileToRequest(filePath, request);
  186. XDocument response = performRequest(request);
  187. Task task = ServerXml.GetTaskStatus(response);
  188. return task;
  189. }
  190. catch (System.Net.WebException e )
  191. {
  192. String friendlyMessage = retrieveFriendlyMessage( e );
  193. if (friendlyMessage != null)
  194. {
  195. throw new ProcessingErrorException(friendlyMessage, e);
  196. }
  197. throw new ProcessingErrorException("Cannot upload file", e);
  198. }
  199. }
  200. private string retrieveFriendlyMessage( System.Net.WebException fromException )
  201. {
  202. try
  203. {
  204. using (HttpWebResponse result = (HttpWebResponse)fromException.Response)
  205. {
  206. // try extract the user-friendly text that might have been supplied
  207. // by the service.
  208. try
  209. {
  210. using (Stream stream = result.GetResponseStream())
  211. {
  212. XDocument responseXml = XDocument.Load( new XmlTextReader( stream ) );
  213. XElement messageElement = responseXml.Root.Element("message");
  214. String serviceMessage = messageElement.Value;
  215. if (!String.IsNullOrEmpty(serviceMessage))
  216. {
  217. return serviceMessage;
  218. }
  219. }
  220. } catch
  221. {
  222. }
  223. try
  224. {
  225. String protocolMessage = result.StatusDescription;
  226. if (!String.IsNullOrEmpty(protocolMessage))
  227. {
  228. return protocolMessage;
  229. }
  230. }
  231. catch
  232. {
  233. }
  234. }
  235. } catch
  236. {
  237. }
  238. return null;
  239. }
  240. /// <summary>
  241. /// Upload image of a multipage document to server.
  242. /// </summary>
  243. /// <param name="filePath">Path to an image to process</param>
  244. /// <param name="taskToAddFile">Id of multipage document. If null, a new document is created</param>
  245. /// <returns>Id of document to which image was added</returns>
  246. public Task UploadAndAddFileToTask(string filePath, TaskId taskToAddFile )
  247. {
  248. string url = String.Format("{0}/submitImage", ServerUrl );
  249. if (taskToAddFile != null)
  250. url = url + "?taskId=" + Uri.EscapeDataString(taskToAddFile.ToString());
  251. // Build post request
  252. WebRequest request = WebRequest.Create(url);
  253. setupPostRequest(url, request);
  254. writeFileToRequest(filePath, request);
  255. XDocument response = performRequest(request);
  256. Task task = ServerXml.GetTaskStatus(response);
  257. return task;
  258. }
  259. public Task StartProcessingTask(TaskId taskId, ProcessingSettings settings)
  260. {
  261. string url = String.Format("{0}/processDocument?taskId={1}&{2}", ServerUrl,
  262. Uri.EscapeDataString( taskId.ToString() ),
  263. settings.AsUrlParams);
  264. if (!String.IsNullOrEmpty(settings.Description))
  265. {
  266. url = url + "&description=" + Uri.EscapeDataString(settings.Description);
  267. }
  268. // Build get request
  269. WebRequest request = WebRequest.Create(url);
  270. setupGetRequest(url, request);
  271. XDocument response = performRequest(request);
  272. Task serverTask = ServerXml.GetTaskStatus(response);
  273. return serverTask;
  274. }
  275. /// <summary>
  276. /// Perform text recognition of a field
  277. /// Throws an exception if something goes wrong
  278. /// </summary>
  279. /// <returns>Id of created task</returns>
  280. public Task ProcessTextField(string filePath, TextFieldProcessingSettings settings)
  281. {
  282. string url = String.Format("{0}/processTextField{1}", ServerUrl, settings.AsUrlParams);
  283. // Build post request
  284. WebRequest request = WebRequest.Create(url);
  285. setupPostRequest(url, request);
  286. writeFileToRequest(filePath, request);
  287. XDocument response = performRequest(request);
  288. Task task = ServerXml.GetTaskStatus(response);
  289. return task;
  290. }
  291. /// <summary>
  292. /// Perform barcode recognition of a field
  293. /// Throws an exception if something goes wrong
  294. /// </summary>
  295. /// <returns>Id of created task</returns>
  296. public Task ProcessBarcodeField(string filePath, BarcodeFieldProcessingSettings settings)
  297. {
  298. string url = String.Format("{0}/processBarcodeField{1}", ServerUrl, settings.AsUrlParams);
  299. // Build post request
  300. WebRequest request = WebRequest.Create(url);
  301. setupPostRequest(url, request);
  302. writeFileToRequest(filePath, request);
  303. XDocument response = performRequest(request);
  304. Task task = ServerXml.GetTaskStatus(response);
  305. return task;
  306. }
  307. public Task ProcessCheckmarkField(string filePath, CheckmarkFieldProcessingSettings settings)
  308. {
  309. string url = String.Format("{0}/processCheckmarkField{1}", ServerUrl, settings.AsUrlParams);
  310. // Build post request
  311. WebRequest request = WebRequest.Create(url);
  312. setupPostRequest(url, request);
  313. writeFileToRequest(filePath, request);
  314. XDocument response = performRequest(request);
  315. Task task = ServerXml.GetTaskStatus(response);
  316. return task;
  317. }
  318. public Task ProcessBusinessCard(string filePath, BusCardProcessingSettings settings)
  319. {
  320. string url = String.Format("{0}/processBusinessCard?{1}", ServerUrl, settings.AsUrlParams);
  321. // Build post request
  322. WebRequest request = WebRequest.Create(url);
  323. setupPostRequest(url, request);
  324. writeFileToRequest(filePath, request);
  325. XDocument response = performRequest(request);
  326. Task serverTask = ServerXml.GetTaskStatus(response);
  327. return serverTask;
  328. }
  329. /// <summary>
  330. /// Perform fields recognition of uploaded document.
  331. /// </summary>
  332. /// <param name="task">Task created by UploadAndAddFileToTask method</param>
  333. /// <param name="settingsPath">Path to file with xml processing settings.</param>
  334. public Task ProcessFields(Task task, string settingsPath)
  335. {
  336. if (!File.Exists(settingsPath))
  337. throw new FileNotFoundException("Settings file doesn't exist.", settingsPath);
  338. string url = String.Format("{0}/processFields?taskId={1}", ServerUrl, task.Id);
  339. WebRequest request = WebRequest.Create(url);
  340. setupPostRequest(url, request);
  341. writeFileToRequest(settingsPath, request);
  342. XDocument response = performRequest(request);
  343. Task result = ServerXml.GetTaskStatus(response);
  344. return result;
  345. }
  346. /// <summary>
  347. /// Recognize Machine-Readable Zone of an official document (Passport, ID, Visa etc)
  348. /// </summary>
  349. public Task ProcessMrz(string filePath)
  350. {
  351. string url = String.Format("{0}/processMRZ", ServerUrl);
  352. WebRequest request = WebRequest.Create(url);
  353. setupPostRequest(url, request);
  354. writeFileToRequest(filePath, request);
  355. XDocument response = performRequest(request);
  356. Task serverTask = ServerXml.GetTaskStatus(response);
  357. return serverTask;
  358. }
  359. public Task CaptureData(string filePath, string templateName)
  360. {
  361. string url = String.Format("{0}/captureData?template={1}", ServerUrl, templateName);
  362. // Build post request
  363. WebRequest request = WebRequest.Create(url);
  364. setupPostRequest(url, request);
  365. writeFileToRequest(filePath, request);
  366. XDocument response = performRequest(request);
  367. Task serverTask = ServerXml.GetTaskStatus(response);
  368. return serverTask;
  369. }
  370. public void DownloadUrl(string url, string outputFile)
  371. {
  372. try
  373. {
  374. WebRequest request = WebRequest.Create(url);
  375. setupGetRequest(url, request);
  376. using (HttpWebResponse result = (HttpWebResponse) request.GetResponse())
  377. {
  378. using (Stream stream = result.GetResponseStream())
  379. {
  380. // Write result directly to file
  381. using (Stream file = File.OpenWrite(outputFile))
  382. {
  383. copyStream(stream, file);
  384. }
  385. }
  386. }
  387. }
  388. catch (System.Net.WebException e)
  389. {
  390. throw new ProcessingErrorException(e.Message, e);
  391. }
  392. }
  393. /// <summary>
  394. /// Download task that has finished processing and save it to given path
  395. /// </summary>
  396. /// <param name="task">Id of a task</param>
  397. /// <param name="outputFile">Path to save a file</param>
  398. public void DownloadResult(Task task, string outputFile)
  399. {
  400. if (task.Status != TaskStatus.Completed)
  401. {
  402. throw new ArgumentException("Cannot download result for not completed task");
  403. }
  404. try
  405. {
  406. if (File.Exists(outputFile))
  407. File.Delete(outputFile);
  408. if (task.DownloadUrls == null || task.DownloadUrls.Count == 0)
  409. {
  410. throw new ArgumentException("Cannot download task without download url");
  411. }
  412. string url = task.DownloadUrls[0];
  413. DownloadUrl(url, outputFile);
  414. }
  415. catch (System.Net.WebException e)
  416. {
  417. throw new ProcessingErrorException(e.Message, e);
  418. }
  419. }
  420. public Task GetTaskStatus(TaskId task)
  421. {
  422. string url = String.Format("{0}/getTaskStatus?taskId={1}", ServerUrl,
  423. Uri.EscapeDataString(task.ToString()));
  424. WebRequest request = WebRequest.Create(url);
  425. setupGetRequest(url, request);
  426. XDocument response = performRequest(request);
  427. Task serverTask = ServerXml.GetTaskStatus(response);
  428. return serverTask;
  429. }
  430. /// <summary>
  431. /// List all tasks modified within last 7 days
  432. /// </summary>
  433. public Task[] ListTasks()
  434. {
  435. DateTime now = DateTime.UtcNow;
  436. return ListTasks(now.AddDays(-7));
  437. }
  438. /// <summary>
  439. /// List all tasks which status changed since given UTC timestamp
  440. /// </summary>
  441. public Task[] ListTasks( DateTime changedSince )
  442. {
  443. string url = String.Format("{0}/listTasks?fromDate={1}", ServerUrl,
  444. Uri.EscapeDataString(changedSince.ToUniversalTime().ToString("s")+"Z"));
  445. WebRequest request = WebRequest.Create(url);
  446. setupGetRequest(url, request);
  447. XDocument response = performRequest(request);
  448. Task[] tasks = ServerXml.GetAllTasks(response);
  449. return tasks;
  450. }
  451. /// <summary>
  452. /// Get list of tasks that are no more queued on a server.
  453. /// The tasks can be processed, failed, or not started becuase there is
  454. /// not enough credits to process them.
  455. /// </summary>
  456. public Task[] ListFinishedTasks()
  457. {
  458. string url = String.Format("{0}/listFinishedTasks", ServerUrl);
  459. WebRequest request = WebRequest.Create(url);
  460. setupGetRequest(url, request);
  461. XDocument response = performRequest(request);
  462. Task[] tasks = ServerXml.GetAllTasks(response);
  463. return tasks;
  464. }
  465. /// <summary>
  466. /// Delete task on a server. This function cannot delete tasks that are being processed.
  467. /// </summary>
  468. public Task DeleteTask(Task task)
  469. {
  470. switch (task.Status)
  471. {
  472. case TaskStatus.Deleted:
  473. case TaskStatus.InProgress:
  474. case TaskStatus.Unknown:
  475. throw new ArgumentException("Invalid task status: " + task.Status + ". Cannot delete");
  476. }
  477. string url = String.Format("{0}/deleteTask?taskId={1}", ServerUrl, Uri.EscapeDataString(task.Id.ToString()));
  478. WebRequest request = WebRequest.Create(url);
  479. setupGetRequest(url, request);
  480. XDocument response = performRequest(request);
  481. Task serverTask = ServerXml.GetTaskStatus(response);
  482. return serverTask;
  483. }
  484. /// <summary>
  485. /// Activate application on a new mobile device
  486. /// </summary>
  487. /// <param name="deviceId">string that uniquely identifies current device</param>
  488. /// <returns>string that should be added to application id for all API calls</returns>
  489. public string ActivateNewInstallation(string deviceId)
  490. {
  491. string url = String.Format("{0}/activateNewInstallation?deviceId={1}", ServerUrl, Uri.EscapeDataString(deviceId));
  492. WebRequest request = WebRequest.Create(url);
  493. setupGetRequest(url, request);
  494. XDocument response = performRequest(request);
  495. string installationId = response.Root.Elements().First().Value;
  496. return installationId;
  497. }
  498. #region Request management functions
  499. private static void copyStream(Stream input, Stream output)
  500. {
  501. byte[] buffer = new byte[8 * 1024];
  502. int len;
  503. while ((len = input.Read(buffer, 0, buffer.Length)) > 0)
  504. {
  505. output.Write(buffer, 0, len);
  506. }
  507. }
  508. private XDocument performRequest(WebRequest request)
  509. {
  510. using (HttpWebResponse result = (HttpWebResponse)request.GetResponse())
  511. {
  512. using (Stream stream = result.GetResponseStream())
  513. {
  514. return XDocument.Load( new XmlTextReader( stream ) );
  515. }
  516. }
  517. }
  518. private void setupRequest(string serverUrl, WebRequest request)
  519. {
  520. if (Proxy != null)
  521. request.Proxy = Proxy;
  522. // Support authentication in case url is ABBYY SDK
  523. if (serverUrl.StartsWith(ServerUrl, StringComparison.InvariantCultureIgnoreCase))
  524. {
  525. RequestAuthSetup.Run(request, ApplicationId, Password);
  526. }
  527. // Set user agent string so that server is able to collect statistics
  528. ((HttpWebRequest)request).UserAgent = ".Net Cloud OCR SDK client";
  529. }
  530. private void setupPostRequest(string serverUrl, WebRequest request)
  531. {
  532. setupRequest(serverUrl, request);
  533. request.Method = "POST";
  534. request.ContentType = "application/octet-stream";
  535. }
  536. private void setupGetRequest(string serverUrl, WebRequest request)
  537. {
  538. setupRequest(serverUrl, request);
  539. request.Method = "GET";
  540. }
  541. private void writeFileToRequest( string filePath, WebRequest request )
  542. {
  543. using( BinaryReader reader = new BinaryReader( File.OpenRead( filePath ) ) ) {
  544. request.ContentLength = reader.BaseStream.Length;
  545. using( Stream stream = request.GetRequestStream() ) {
  546. byte[] buf = new byte[reader.BaseStream.Length];
  547. while( true ) {
  548. int bytesRead = reader.Read( buf, 0, buf.Length );
  549. if( bytesRead == 0 ) {
  550. break;
  551. }
  552. stream.Write( buf, 0, bytesRead );
  553. }
  554. }
  555. }
  556. }
  557. #endregion
  558. /// <summary>
  559. /// Address of the server excluding protocol
  560. /// </summary>
  561. private string _serverAddress;
  562. }
  563. }