368 lines
14 KiB
C#
368 lines
14 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using SimpleHttp;
|
|
using System.Xml.Linq;
|
|
using Newtonsoft;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
using RomeOnlinePartner.Models;
|
|
using ToastNotifications.Messages;
|
|
using System.Threading;
|
|
using System.Reflection;
|
|
|
|
namespace RomeOnlinePartner.Utils
|
|
{
|
|
public static class HTTPServer
|
|
{
|
|
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
|
public delegate void HttpLogger(string s);
|
|
private static HttpLogger hlog;
|
|
public static CancellationTokenSource tokenSource = new CancellationTokenSource();
|
|
public static CancellationToken token = tokenSource.Token;
|
|
|
|
public static void InitHttpServer(HttpLogger HttpLogger)
|
|
{
|
|
//Adding local routes.
|
|
//QuickBooks Execution Routes.
|
|
Route.Add("/qb/", (req, res, props) =>
|
|
{
|
|
hlog("Received a QuickBooks request from Rome Online");
|
|
res.WithCORS();
|
|
res.Close();
|
|
}, "OPTIONS");
|
|
|
|
Route.Add("/qb/",
|
|
(req, res, props) => { HandleQbPost(req, res); }
|
|
, "POST");
|
|
|
|
//Pinging based routes.
|
|
Route.Add("/ping/", (req, res, props) =>
|
|
{
|
|
hlog("Received a ping from Rome Online");
|
|
res.WithCORS();
|
|
res.Close();
|
|
}, "OPTIONS");
|
|
Route.Add("/ping/",
|
|
(req, res, props) => { HandlePing(req, res); }
|
|
, "POST");
|
|
|
|
//FileScanning Routes
|
|
Route.Add("/scan/", (req, res, props) =>
|
|
{
|
|
hlog("Received a scan request from Rome Online");
|
|
res.WithCORS();
|
|
res.Close();
|
|
}, "OPTIONS");
|
|
Route.Add("/scan/",
|
|
(req, res, props) => { HandleScan(req, res); }
|
|
, "POST");
|
|
Route.Add("/import/", (req, res, props) =>
|
|
{
|
|
hlog("Received an import request from Rome Online");
|
|
res.WithCORS();
|
|
res.Close();
|
|
}, "OPTIONS");
|
|
Route.Add("/import/",
|
|
(req, res, props) => { HandleImport(req, res); }
|
|
, "POST");
|
|
|
|
Route.Add("/oec/", (req, res, props) =>
|
|
{
|
|
hlog("Received an OEC from Rome Online");
|
|
res.WithCORS();
|
|
res.Close();
|
|
}, "OPTIONS");
|
|
Route.Add("/oec/",
|
|
(req, res, props) => { HandleOec(req, res); }
|
|
, "POST");
|
|
|
|
Route.Add("/ppc/", (req, res, props) =>
|
|
{
|
|
hlog("Received an PPC from Rome Online");
|
|
res.WithCORS();
|
|
res.Close();
|
|
}, "OPTIONS");
|
|
Route.Add("/ppc/",
|
|
(req, res, props) => { HandlePpc(req, res); }
|
|
, "POST");
|
|
|
|
Route.Add("/paintscale/export/", (req, res, props) =>
|
|
{
|
|
hlog("Received a Paint Scale Export Request");
|
|
res.WithCORS();
|
|
res.Close();
|
|
}, "OPTIONS");
|
|
Route.Add("/paintscale/export/",
|
|
(req, res, props) => {
|
|
hlog("Received a Paint Scale Export Request");
|
|
HandlePaintScaleExport(req, res); }
|
|
, "POST");
|
|
|
|
Route.Add("/arms/rodata/", (req, res, props) =>
|
|
{
|
|
hlog("Received an ARMS RO Data Export Request");
|
|
res.WithCORS();
|
|
res.Close();
|
|
}, "OPTIONS");
|
|
Route.Add("/arms/rodata/",
|
|
(req, res, props) => {
|
|
hlog("Received an ARMS RO Data Export Request");
|
|
HandleArmsRODataExtract(req, res);
|
|
}
|
|
, "POST");
|
|
|
|
logger.Trace("Starting HTTP server...");
|
|
hlog = HttpLogger;
|
|
try
|
|
{
|
|
hlog("Rome Online connection server starting...");
|
|
HttpServer.ListenAsync(1337, token, Route.OnHttpRequestAsync).Wait();
|
|
|
|
}
|
|
catch (Exception Ex)
|
|
{
|
|
logger.Fatal("Unable to start HTTP server. " + Ex.ToString());
|
|
hlog("Rome Online connection server could not start. Please restart the partner to try again.");
|
|
App.Current.Dispatcher.Invoke(() =>
|
|
{
|
|
string msg = "Unable to connect to Rome Online Web App. Please ensure your firewall allows the connection.";
|
|
Utils.Notifications.notifier.ShowError(msg);
|
|
});
|
|
Utils.SquirrelAwareHelper.AddHttpExcetion();
|
|
HttpServer.ListenAsync(1337, token, Route.OnHttpRequestAsync).Wait();
|
|
}
|
|
}
|
|
|
|
private static void HandleOec(System.Net.HttpListenerRequest req, System.Net.HttpListenerResponse res)
|
|
{
|
|
logger.Trace("/oec/ - POST");
|
|
//Input will be an array of objects containing XMLs.
|
|
|
|
var requestBody = ParseBody(req);
|
|
JObject HttpResponse = new JObject();
|
|
try
|
|
{
|
|
Utils.OEConnection.SendToOEConnection(requestBody);
|
|
HttpResponse.Add("success", true);
|
|
}
|
|
catch (Exception Ex)
|
|
{
|
|
logger.Error(Ex, "Error encountered while handling import requests.");
|
|
hlog("Error encountered while handling import requests.");
|
|
HttpResponse.Add("success", false);
|
|
HttpResponse.Add("error", Ex.ToString());
|
|
}
|
|
res.WithCORS().AsText(JsonConvert.SerializeObject(HttpResponse));
|
|
}
|
|
|
|
private static void HandlePpc(System.Net.HttpListenerRequest req, System.Net.HttpListenerResponse res)
|
|
{
|
|
logger.Trace("/ppc/ - POST");
|
|
//Input will be an array of objects containing XMLs.
|
|
|
|
var requestBody = ParseBody(req);
|
|
JObject HttpResponse = new JObject();
|
|
try
|
|
{
|
|
Utils.CCCPartsPriceChange.SendPartsPriceChange(requestBody);
|
|
HttpResponse.Add("success", true);
|
|
}
|
|
catch (Exception Ex)
|
|
{
|
|
logger.Error(Ex, "Error encountered while handling import requests.");
|
|
hlog("Error encountered while handling import requests.");
|
|
HttpResponse.Add("success", false);
|
|
HttpResponse.Add("error", Ex.ToString());
|
|
}
|
|
res.WithCORS().AsText(JsonConvert.SerializeObject(HttpResponse));
|
|
}
|
|
|
|
private static void HandleQbPost(System.Net.HttpListenerRequest req, System.Net.HttpListenerResponse res)
|
|
{
|
|
logger.Trace("/qb/ - POST");
|
|
hlog("Received QuickBooks Receivable request.");
|
|
//Input will be an array of objects containing XMLs.
|
|
|
|
List<QbRequestItem> AllRequests = ParseRequest(req);
|
|
List<QbResponseItem> HttpResponse = new List<QbResponseItem>();
|
|
try
|
|
{
|
|
hlog("Connecting to QuickBooks. This may take a moment...");
|
|
QuickBooksInterop.ConnectToQuickBooks();
|
|
|
|
foreach (QbRequestItem request in AllRequests)
|
|
{
|
|
try
|
|
{
|
|
hlog("Processing QuickBooks request. Rome Online Record ID:" + request.Id);
|
|
XDocument response = XDocument.Parse(QuickBooksInterop.ProcessQBXmlRequestUnManaged(request.QbXML));
|
|
QbXmlResponse ResponseStatus = QuickBooksInterop.ParseResponseXml(response);
|
|
|
|
logger.Trace(response.ToString());
|
|
logger.Debug(ResponseStatus.ToString());
|
|
hlog(ResponseStatus.ToString());
|
|
|
|
QbResponseItem r = new QbResponseItem()
|
|
{
|
|
Id = request.Id,
|
|
Success = ResponseStatus.StatusCode == "0" || request.OkStatusCodes.Contains(ResponseStatus.StatusCode),
|
|
ErrorMessage = ResponseStatus.StatusMessage
|
|
};
|
|
|
|
HttpResponse.Add(r);
|
|
}
|
|
catch (Exception Ex)
|
|
{
|
|
//Shouldn't really get here unless something is malformed.
|
|
logger.Error(Ex, "Error encountered when processing QbXML Request.\n {0}", request.QbXML);
|
|
QbResponseItem r = new QbResponseItem()
|
|
{
|
|
Id = request.Id,
|
|
Success = false,
|
|
ErrorMessage = Ex.Message
|
|
};
|
|
|
|
HttpResponse.Add(r);
|
|
}
|
|
|
|
}
|
|
QuickBooksInterop.DisconnectFromQuickBooks();
|
|
|
|
hlog("Completed QuickBooks requests.");
|
|
|
|
}
|
|
catch (Exception Ex)
|
|
{
|
|
logger.Error(Ex, "Error encountered while processing QuickBooks requests.");
|
|
hlog("Error encountered while processing QuickBooks requests.");
|
|
HttpResponse.Add(new QbResponseItem() { Id = "-1", Success = false, ErrorMessage = Ex.Message });
|
|
}
|
|
res.WithCORS().AsText(JsonConvert.SerializeObject(HttpResponse));
|
|
|
|
}
|
|
|
|
|
|
private static async void HandleScan(System.Net.HttpListenerRequest req, System.Net.HttpListenerResponse res)
|
|
{
|
|
logger.Trace("/scan/ - POST");
|
|
//Input will be an array of objects containing XMLs.
|
|
|
|
List<ScanResponseItem> HttpResponse = new List<ScanResponseItem>();
|
|
try
|
|
{
|
|
//Do the scan
|
|
//Add the items to the response list.
|
|
HttpResponse = await Utils.DiskScan.ScanDiskForEstimates();
|
|
}
|
|
catch (Exception Ex)
|
|
{
|
|
logger.Error(Ex, "Error encountered while scanning for estimates on disk.", Ex.ToString());
|
|
hlog("Error encountered while scanning for estimates on disk. " + Ex.Message);
|
|
HttpResponse.Add(new ScanResponseItem() { Id = "-1", Success = false, ErrorMessage = Ex.Message });
|
|
}
|
|
res.WithCORS().AsText(JsonConvert.SerializeObject(HttpResponse));
|
|
}
|
|
|
|
|
|
private static async void HandleImport(System.Net.HttpListenerRequest req, System.Net.HttpListenerResponse res)
|
|
{
|
|
logger.Trace("/import/ - POST");
|
|
//Input will be an array of objects containing XMLs.
|
|
|
|
var requestBody = ParseBody(req);
|
|
JObject HttpResponse = new JObject();
|
|
try
|
|
{
|
|
//Do the scan
|
|
//Add the items to the response list.
|
|
await JobProcessingQueue.UploadJob(new DTO_QueueItem() { FilePath = requestBody.filepath });
|
|
HttpResponse.Add("success", true);
|
|
}
|
|
catch (Exception Ex)
|
|
{
|
|
logger.Error(Ex, "Error encountered while handling import requests.");
|
|
hlog("Error encountered while handling import requests.");
|
|
HttpResponse.Add("success", false);
|
|
HttpResponse.Add("error", Ex.ToString());
|
|
}
|
|
res.WithCORS().AsText(JsonConvert.SerializeObject(HttpResponse));
|
|
}
|
|
|
|
|
|
private static void HandlePing(System.Net.HttpListenerRequest req, System.Net.HttpListenerResponse res)
|
|
{
|
|
logger.Trace("/ping/ - POST");
|
|
dynamic response = new JObject();
|
|
response.appver = Assembly.GetExecutingAssembly().GetName().Version.ToString();
|
|
response.qbpath = Properties.Settings.Default.QuickBooksFilePath;
|
|
var t = JsonConvert.SerializeObject(response);
|
|
res.WithCORS().AsText((string)t.ToString());
|
|
}
|
|
|
|
public static dynamic ParseBody(System.Net.HttpListenerRequest req)
|
|
{
|
|
System.IO.Stream body = req.InputStream;
|
|
System.Text.Encoding encoding = req.ContentEncoding;
|
|
System.IO.StreamReader reader = new System.IO.StreamReader(body, encoding);
|
|
string s = reader.ReadToEnd();
|
|
body.Close();
|
|
reader.Close();
|
|
|
|
return JsonConvert.DeserializeObject(s);
|
|
}
|
|
|
|
public static List<QbRequestItem> ParseRequest(System.Net.HttpListenerRequest req)
|
|
{
|
|
System.IO.Stream body = req.InputStream;
|
|
System.Text.Encoding encoding = req.ContentEncoding;
|
|
System.IO.StreamReader reader = new System.IO.StreamReader(body, encoding);
|
|
string s = reader.ReadToEnd();
|
|
body.Close();
|
|
reader.Close();
|
|
|
|
return JsonConvert.DeserializeObject<List<QbRequestItem>>(s);
|
|
}
|
|
|
|
public static string[] ParseBodyToArray(System.Net.HttpListenerRequest req)
|
|
{
|
|
System.IO.Stream body = req.InputStream;
|
|
System.Text.Encoding encoding = req.ContentEncoding;
|
|
System.IO.StreamReader reader = new System.IO.StreamReader(body, encoding);
|
|
string s = reader.ReadToEnd();
|
|
body.Close();
|
|
reader.Close();
|
|
|
|
return JArray.Parse(s).Select(jv => jv.ToString()).ToArray();
|
|
}
|
|
|
|
public static string ParseBodyToString(System.Net.HttpListenerRequest req)
|
|
{
|
|
System.IO.Stream body = req.InputStream;
|
|
System.Text.Encoding encoding = req.ContentEncoding;
|
|
System.IO.StreamReader reader = new System.IO.StreamReader(body, encoding);
|
|
string s = reader.ReadToEnd();
|
|
body.Close();
|
|
return s;
|
|
}
|
|
|
|
public static XDocument ParseStringToXml(string input)
|
|
{
|
|
return XDocument.Parse(input);
|
|
}
|
|
|
|
private static async void HandlePaintScaleExport(System.Net.HttpListenerRequest req, System.Net.HttpListenerResponse res)
|
|
{
|
|
await Utils.PPGMixData.PushDataToPPG();
|
|
res.WithCORS().AsText("OK");
|
|
}
|
|
private static async void HandleArmsRODataExtract(System.Net.HttpListenerRequest req, System.Net.HttpListenerResponse res)
|
|
{
|
|
await Utils.ARMSRoData.GenerateArmsROData();
|
|
res.WithCORS().AsText("OK");
|
|
}
|
|
}
|
|
}
|