commit 9547fd4a32cdda2ba4baa8411fb742b8f079a2ad
Author: Eliška Mourycová <eliska.mourycova@seznam.cz>
Date:   Fri May 28 09:11:12 2021 +0200

    Refs #9008, #8919. Data directory path should now be ok on linux + added interface for DataDownloader + changed time span of default downloaded data.

diff --git a/Server/ServerApp/Connection/ConnectionListener.cs b/Server/ServerApp/Connection/ConnectionListener.cs
index dda9313..5ee0a1f 100644
--- a/Server/ServerApp/Connection/ConnectionListener.cs
+++ b/Server/ServerApp/Connection/ConnectionListener.cs
@@ -24,7 +24,6 @@ namespace ServerApp.Connection
 	{
 		private readonly int PORT;
 		private IPredictionController predictionController;
-		//HttpListener listener;
 
 		public ConnectionListenerAsync(int port, IPredictionController predictionController)
 		{
@@ -38,7 +37,6 @@ namespace ServerApp.Connection
 			string ip = GetLocalIPAddress();
 			Console.WriteLine("ip : " + ip);
 			HttpListener listener = new HttpListener();
-            //HttpListener server = new HttpListener();
             listener.Prefixes.Add($"https://*:{PORT}/");
             //listener.Prefixes.Add($"http://*:{PORT}/");
 
@@ -58,6 +56,89 @@ namespace ServerApp.Connection
 
 			var result = listener.BeginGetContext(ListenerCallback, listener);
 			// result.AsyncWaitHandle.WaitOne(); // ????
+
+			// ------- Synchronous listening -----
+			//while (true)
+			//{
+			//	Console.WriteLine("Waiting for a client request...");
+			//	HttpListenerContext context = listener.GetContext();
+			//	HandleRequest(context);
+			//}
+		}
+
+
+		private void HandleRequest(HttpListenerContext context)
+		{
+
+			Console.WriteLine("Handling request.");
+			// Obtain a request object.
+			HttpListenerRequest request = context.Request;
+			// Obtain a response object.
+			HttpListenerResponse response = context.Response;
+
+
+
+			// add the headers and everything:
+			response.AddHeader("Access-Control-Allow-Credentials", "true");
+			response.AddHeader("Access-Control-Expose-Headers", "ETag");
+			response.AddHeader("Access-Control-Allow-Headers", "Accept, X-Access-Token, X-Application-Name, X-Request-Sent-Time");
+			response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
+			response.AddHeader("Access-Control-Allow-Origin", "*");
+
+			string responseString = "";
+			// Construct a response.
+			if (context.Request.HttpMethod == "GET") // when client says download
+			{
+				Console.WriteLine("received GET request");
+
+				string text;
+				using (var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding))
+					text = reader.ReadToEnd();
+				string requestString = HttpUtility.UrlDecode(text);
+
+				responseString = ConstructGETResponse(requestString);
+
+			}
+			else if (context.Request.HttpMethod == "POST") // when client says upload
+			{
+				Console.WriteLine("received POST request");
+				string text;
+				using (var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding))
+					text = reader.ReadToEnd();
+				string requestString = HttpUtility.UrlDecode(text);
+
+				responseString = ConstructPOSTResponse(requestString);
+
+
+			}
+			else
+			{
+				Console.WriteLine("received request other than GET or POST");
+
+			}
+
+
+			System.IO.Stream output = response.OutputStream;
+			if (!string.IsNullOrEmpty(responseString))
+			{
+				Console.WriteLine("Response is not null or empty, sending it to the client.");
+				byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
+
+				// Get a response stream and write the response to it.
+				response.ContentLength64 = buffer.Length;
+				output.Write(buffer, 0, buffer.Length);
+			}
+			else
+			{
+				Console.WriteLine("Response was null or empty, not sending anything.");
+			}
+
+
+			// Close the output stream.
+			//output.Close();
+			response.Close();
+
+			Console.WriteLine("At the end of HandleRequest");
 		}
 
 
@@ -119,7 +200,6 @@ namespace ServerApp.Connection
 			else
 			{
 				Console.WriteLine("received request other than GET or POST");
-
 			}
 
 
@@ -280,7 +360,7 @@ namespace ServerApp.Connection
 
 
 
-
+		// TODO clean this up --->
 		// -----------------------------------------------------------------------------
 
 		public class ConnectionListener
@@ -477,12 +557,6 @@ namespace ServerApp.Connection
 	// ---------------------------------------------------------------------------
 
 
-
-
-
-
-
-
 	class ClientService
 	{
 		public static readonly int MAX_IDS = 1000000; // ??
diff --git a/Server/ServerApp/DataDownload/DataDownloader.cs b/Server/ServerApp/DataDownload/DataDownloader.cs
index 8426930..7d2b59f 100644
--- a/Server/ServerApp/DataDownload/DataDownloader.cs
+++ b/Server/ServerApp/DataDownload/DataDownloader.cs
@@ -31,7 +31,7 @@ namespace ServerApp.DataDownload
 	/// <summary>
 	/// This class takes care of downloading of data. Download happens from http://openstore.zcu.cz/.
 	/// </summary>
-	public class DataDownloader
+	public class DataDownloader : IDataDownloader
 	{
 		/// <summary>
 		/// The root directory containing all downloaded data
@@ -332,8 +332,8 @@ namespace ServerApp.DataDownload
 		/// <param name="format">The data format</param>
 		/// <param name="startDate">The start date</param>
 		/// <param name="endDate">The end date</param>
-		/// <returns></returns>
-		public List<string> DownloadData(DataType type, DataFormat format, Date startDate, Date endDate/*int startYear, int endYear, int startMonth, int endMonth*/)
+		/// <returns>A list of full paths to all saved files</returns>
+		public List<string> DownloadData(DataType type, DataFormat format, Date startDate, Date endDate)
 		{
 			if (startDate > endDate)
 				throw new ArgumentException("startDate must be the same as or before the endDate.");
@@ -394,11 +394,12 @@ namespace ServerApp.DataDownload
 		/// <summary>
 		/// Retrieves all data files with dates falling within the specified range. If not all data for the specified range is found
 		/// then returns also file/s with month 0 if exists.
+		/// If startDate and/or endDate are null, then returns all files from the given subdirectory.
 		/// </summary>
 		/// <param name="subDirectory">The subdirectory to search</param>
 		/// <param name="startDate">The start date</param>
 		/// <param name="endDate">The end date</param>
-		/// <returns></returns>
+		/// <returns>A list of all retrieved data files from the requested time span</returns>
 		public List<string> GetData(string subDirectory, Date startDate, Date endDate)
 		{
 			if (startDate == null || endDate == null)
@@ -489,50 +490,5 @@ namespace ServerApp.DataDownload
 
 			return relevantFiles;
 		}
-
-
-		#region UNUSED
-		//public string GetDirectoryListingRegexForUrl(string url)
-		//{
-		//	if (url.Equals(site))
-		//	{
-		//		//return "\\\"([^\"]*)\\\"";
-		//		return @"\bOD_ZCU_\w*\b";
-		//		//return @"\A[OD_ZCU_]";
-		//	}
-		//	else return null;
-		//}
-		//public void ListDirectory()
-		//{
-		//	string url = site;
-		//	HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
-		//	using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
-		//	{
-		//		using (StreamReader reader = new StreamReader(response.GetResponseStream()))
-		//		{
-		//			string html = reader.ReadToEnd();
-
-
-
-		//			Regex regex = new Regex(GetDirectoryListingRegexForUrl(url));
-		//			MatchCollection matches = regex.Matches(html);
-		//			Console.WriteLine(matches.Count);
-
-		//			if (matches.Count > 0)
-		//			{
-		//				foreach (Match match in matches)
-		//				{
-		//					//if (match.Success)
-		//					//{
-		//						Console.WriteLine(match.ToString());
-		//					//}
-		//				}
-		//			}
-		//		}
-		//		Console.ReadLine();
-		//	}
-		//}
-
-		#endregion
 	}
 }
diff --git a/Server/ServerApp/DataDownload/IDataDownloader.cs b/Server/ServerApp/DataDownload/IDataDownloader.cs
new file mode 100644
index 0000000..63b9a32
--- /dev/null
+++ b/Server/ServerApp/DataDownload/IDataDownloader.cs
@@ -0,0 +1,39 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ServerApp.DataDownload
+{
+	interface IDataDownloader
+	{
+		/// <summary>
+		/// Downloads json file - returns contents of said file
+		/// </summary>
+		/// <returns> Path to file </returns>
+		public string DownloadWeatherPrediction();
+
+		/// <summary>
+		/// Downloads selected type and time span of data in the desired format, returns a list of full paths to all successfully saved files. 
+		/// If some of the files already existed and were not overwritten, then the returned List contains paths to these files also.
+		/// </summary>
+		/// <param name="type">The requested data type</param>
+		/// <param name="format">The data format</param>
+		/// <param name="startDate">The start date</param>
+		/// <param name="endDate">The end date</param>
+		/// <returns>A list of full paths to all saved files</returns>
+		public List<string> DownloadData(DataType type, DataFormat format, Date startDate, Date endDate);
+
+		/// <summary>
+		/// Retrieves all data files with dates falling within the specified range. If not all data for the specified range is found
+		/// then returns also file/s with month 0 if exists.
+		/// If startDate and/or endDate are null, then returns all files from the given subdirectory.
+		/// </summary>
+		/// <param name="subDirectory">The subdirectory to search</param>
+		/// <param name="startDate">The start date</param>
+		/// <param name="endDate">The end date</param>
+		/// <returns>A list of all retrieved data files from the requested time span</returns>
+		public List<string> GetData(string subDirectory, Date startDate, Date endDate);
+	}
+}
diff --git a/Server/ServerApp/Program.cs b/Server/ServerApp/Program.cs
index a686d49..e81493e 100644
--- a/Server/ServerApp/Program.cs
+++ b/Server/ServerApp/Program.cs
@@ -99,9 +99,11 @@ namespace ServerApp
 			DataDownloader dd = new DataDownloader(config.DataRootDir, config.DataWebsite, config.DownloadedFilesNaming);
 			dd.OverwriteExisting = false;
 			List<string> savedFiles = new List<string>();
-			savedFiles.AddRange(dd.DownloadData(DataType.JIS, DataFormat.CSV, new DataDownload.Date(1, 2019), new DataDownload.Date(12, 2020)));
-			savedFiles.AddRange(dd.DownloadData(DataType.STROJE, DataFormat.CSV, new DataDownload.Date(1, 2017), new DataDownload.Date(12, 2020)));
-			savedFiles.AddRange(dd.DownloadData(DataType.POCASI, DataFormat.CSV, new DataDownload.Date(1, 2017), new DataDownload.Date(12, 2020)));
+
+			// -> 12-2019 to exclude corona? But we lose a lot of data
+			savedFiles.AddRange(dd.DownloadData(DataType.JIS, DataFormat.CSV, new DataDownload.Date(1, 2017), new DataDownload.Date(12, 2019)));
+			savedFiles.AddRange(dd.DownloadData(DataType.STROJE, DataFormat.CSV, new DataDownload.Date(1, 2017), new DataDownload.Date(12, 2019)));
+			savedFiles.AddRange(dd.DownloadData(DataType.POCASI, DataFormat.CSV, new DataDownload.Date(1, 2017), new DataDownload.Date(12, 2019)));
 
 
 
@@ -205,6 +207,7 @@ namespace ServerApp
 			Config extractedConfigInfo = new Config();
 
 			Console.WriteLine(Directory.GetCurrentDirectory());
+			Console.WriteLine("Parsing configuration file...");
 			
 			if (args.Length != 1)
 				Console.WriteLine("Wrong usage of parameters, pass the path to a config file."); // todo better explanation?
@@ -223,7 +226,7 @@ namespace ServerApp
 			for (var i = 0; i < lines.Length; i += 1)
 			{
 				string line = lines[i];
-				Console.WriteLine(line);
+				//Console.WriteLine(line);
 				if (line.Length == 0 || line == null || line.StartsWith("#"))
 					continue;
 
@@ -236,10 +239,12 @@ namespace ServerApp
 						extractedConfigInfo.DownloadedFilesNaming = lines[++i].Trim();
 						break;
 					case "!data_root_dir!":
+						//string rootDir = lines[++i];
+						//rootDir = rootDir.Replace('\\', Path.DirectorySeparatorChar);
 						string dirWithConfig = Path.GetDirectoryName(fullPathConfig);
 						string rootPath = dirWithConfig + Path.DirectorySeparatorChar + lines[++i].Trim();
+						rootPath = Path.GetFullPath(rootPath);
 						extractedConfigInfo.DataRootDir = rootPath;
-						
 						break;
 					case "!port!":
 						extractedConfigInfo.Port = lines[++i].Trim();
