179 lines
7.2 KiB
C#
179 lines
7.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Threading.Tasks;
|
|
using FarmmapsApi;
|
|
using FarmmapsApi.Models;
|
|
using FarmmapsApi.Services;
|
|
using FarmmapsDownloadCL.Models;
|
|
using Microsoft.Extensions.Logging;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
using static FarmmapsApiSamples.Constants;
|
|
|
|
namespace FarmmapsDownloadCL
|
|
{
|
|
public class DownloadCLApplication : IApplication
|
|
{
|
|
|
|
private readonly ILogger<DownloadCLApplication> _logger;
|
|
private readonly FarmmapsApiService _farmmapsApiService;
|
|
private readonly DownloadCLService _DownloadCLService;
|
|
private readonly GeneralService _generalService;
|
|
public readonly Dictionary<string, List<string>> _dictCl;
|
|
string _itemcode;
|
|
public DownloadCLApplication(ILogger<DownloadCLApplication> logger, FarmmapsApiService farmmapsApiService,
|
|
GeneralService generalService, DownloadCLService DownloadCLService)
|
|
{
|
|
_logger = logger;
|
|
_farmmapsApiService = farmmapsApiService;
|
|
_generalService = generalService;
|
|
_DownloadCLService = DownloadCLService;
|
|
CodelistsClasses clc = new CodelistsClasses();
|
|
_itemcode = clc.itemcode;
|
|
_dictCl = clc.dictCl;
|
|
}
|
|
|
|
public async Task RunAsync()
|
|
{
|
|
var fieldsInputJson = File.ReadAllText("DownloadCLInput.json");
|
|
|
|
|
|
DownloadCLInput clInput = JsonConvert.DeserializeObject<DownloadCLInput>(fieldsInputJson);
|
|
|
|
// !! this call is needed the first time an api is called with a fresh clientid and secret !!
|
|
await _farmmapsApiService.GetCurrentUserCodeAsync();
|
|
var roots = await _farmmapsApiService.GetCurrentUserRootsAsync();
|
|
|
|
//Where to write the output
|
|
string downloadFolder = clInput.DownloadFolder;
|
|
if (string.IsNullOrEmpty(downloadFolder))
|
|
{
|
|
downloadFolder = "Downloads";
|
|
}
|
|
if (!Directory.Exists(downloadFolder))
|
|
Directory.CreateDirectory(downloadFolder);
|
|
|
|
//Get the most recent codelists
|
|
foreach (string codelist in clInput.codelists)
|
|
{
|
|
try
|
|
{
|
|
await Process(roots, codelist, downloadFolder);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex.Message);
|
|
}
|
|
}
|
|
}
|
|
|
|
private async Task Process(List<UserRoot> roots, string codelistname, string downloadFolder)
|
|
{
|
|
List<Item> codelist;
|
|
string itemtype;
|
|
string className;
|
|
string body;
|
|
string header;
|
|
string value;
|
|
string[] aboutArray = null;
|
|
string[] headerArray = null;
|
|
PropertyInfo[] props;
|
|
PropertyInfo prop;
|
|
List<string> dataList;
|
|
string clJson = Path.Combine(downloadFolder, $"{codelistname}.json");
|
|
string clCsv = Path.Combine(downloadFolder, $"{codelistname}.csv");
|
|
|
|
try
|
|
{
|
|
itemtype = _dictCl[codelistname][0];
|
|
className = _dictCl[codelistname][1];
|
|
codelist = await _farmmapsApiService.GetItemChildrenAsync(_itemcode, itemtype);
|
|
|
|
//Write full codelist in json format to clJson.
|
|
body = JsonConvert.SerializeObject(codelist);
|
|
File.WriteAllText(clJson, body);
|
|
_logger.LogInformation($"Downloaded file {clJson}");
|
|
|
|
//Write full list in csv format to clCsv.
|
|
StreamWriter sw = new StreamWriter(clCsv);
|
|
//Write metadata in top: when downloaded
|
|
sw.WriteLine($"Editeelt codelist {codelistname} downloaded on {DateTime.Now} with the FarmmapsDownloadCL application by Pepijn van Oort (WPR)");
|
|
|
|
//Generic, for any Codelist as long as it is also defined in FarmmapsDownloadCL.Models in
|
|
string typerequest = "FarmmapsDownloadCL.Models." + className + ", FarmmapsDownloadCL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
|
|
Type objType = Type.GetType(typerequest);
|
|
object clitem = Activator.CreateInstance(objType);
|
|
props = clitem.GetType().GetProperties();
|
|
|
|
//Lookup about info and write to top
|
|
foreach (PropertyInfo pi in props)
|
|
{
|
|
if (pi.Name == "about")
|
|
{
|
|
aboutArray = (string[])pi.GetValue(clitem);
|
|
foreach (string about in aboutArray)
|
|
{
|
|
//Add quotes
|
|
value = "\"" + about + "\"";
|
|
//Write each about to a separate line in the csv file
|
|
sw.WriteLine(value);
|
|
}
|
|
|
|
}
|
|
}
|
|
//Write an empty line
|
|
sw.WriteLine();
|
|
|
|
//Look up the headerArray and write the header comma separated
|
|
int i = 0;
|
|
while (headerArray == null)
|
|
{
|
|
prop = props[i];
|
|
if (prop.Name == "headers")
|
|
{
|
|
headerArray = (string[])prop.GetValue(clitem);
|
|
}
|
|
i++;
|
|
}
|
|
header = string.Join(",", headerArray);
|
|
sw.WriteLine(header);
|
|
|
|
//Add quotes because a value for field 'description' could be '21% Cl, 16.5%CaO, 1330 g/l' and without the quotes that
|
|
//would show up as separate columns. So per definition we will add quotes, except if we have a fieldname in the listNotToQuote, then value for that fieldname will not be given quotes
|
|
//e.g. not code "3" but code 3.
|
|
List<string> listNotToQuote = new List<string>() { "code", "n", "p", "k", "quantity", "cropGroupCode", "cultivationGroupCode" };
|
|
//Loop through all items in the codelist
|
|
foreach (Item item in codelist)
|
|
{
|
|
dataList = new List<string> { };
|
|
clitem = JsonConvert.DeserializeObject(item.Data.ToString(), objType);
|
|
|
|
//Add values of the cLitem to the dataList in the same order as the header
|
|
foreach (string h in headerArray)
|
|
{
|
|
value = (string)clitem.GetType().GetProperty(h).GetValue(clitem, null);
|
|
if(listNotToQuote.Contains(h) == false)
|
|
value = "\"" +value + "\"";
|
|
|
|
dataList.Add(value);
|
|
}
|
|
string dataLine = string.Join(",", dataList);
|
|
sw.WriteLine(string.Join(",", dataList));
|
|
}
|
|
|
|
sw.Close();
|
|
_logger.LogInformation($"Downloaded file {clCsv}");
|
|
|
|
}
|
|
catch
|
|
{
|
|
_logger.LogWarning($"Missing lookup information on codelist {codelistname}");
|
|
}
|
|
}
|
|
}
|
|
}
|