using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using FarmmapsApi.Models; using Google.Apis.Upload; using Microsoft.Extensions.Logging; using Newtonsoft.Json.Linq; using static FarmmapsApi.Extensions; using static FarmmapsApiSamples.Constants; namespace FarmmapsApi.Services { public class GeneralService { private readonly ILogger _logger; private readonly FarmmapsApiService _farmmapsApiService; public GeneralService(ILogger logger, FarmmapsApiService farmmapsApiService) { _logger = logger; _farmmapsApiService = farmmapsApiService; } public async Task CreateCropfieldItemAsync(string parentItemCode, string name, int year, string fieldGeomJson) { var currentYear = new DateTime(year, 1, 1); var cropfieldItemRequest = new ItemRequest() { ParentCode = parentItemCode, ItemType = CROPFIELD_ITEMTYPE, Name = name, DataDate = currentYear, DataEndDate = currentYear.AddYears(1).AddDays(-1), Data = JObject.Parse("{}"), Geometry = JObject.Parse(fieldGeomJson) }; return await _farmmapsApiService.CreateItemAsync(cropfieldItemRequest); } public async Task UploadDataAsync(UserRoot root, string itemType, string filePath, string itemName) { var startUpload = DateTime.UtcNow; var result = await _farmmapsApiService.UploadFile(filePath, root.Code, progress => _logger.LogInformation($"Status: {progress.Status} - BytesSent: {progress.BytesSent}")); if (result.Progress.Status == UploadStatus.Failed) return null; return await FindChildItemAsync(root.Code, itemType, itemName, i => i.Created >= startUpload && i.Name.ToLower().Contains(itemName.ToLower())); } public async Task UploadZipWithShapeAsync(UserRoot root, string filePath, string itemName) { var startUpload = DateTime.UtcNow; var result = await _farmmapsApiService.UploadFile(filePath, root.Code, progress => _logger.LogInformation($"Status: {progress.Status} - BytesSent: {progress.BytesSent}")); if (result.Progress.Status == UploadStatus.Failed) return null; var zipName = Path.GetFileName(filePath); Item shapeItem = null; await PollTask(TimeSpan.FromSeconds(3), async source => { _logger.LogInformation($"Searching for {itemName} item"); var uploadedFilesChildren = await _farmmapsApiService.GetItemChildrenAsync(root.Code); var zipItems = uploadedFilesChildren.Where(i => i.Name.Contains(zipName)); foreach (var zipItem in zipItems) { List items = await _farmmapsApiService.GetItemChildrenAsync(zipItem.Code, SHAPE_PROCESSED_ITEMTYPE); items = items.Where(i => i.Created >= startUpload).OrderByDescending(i => i.Created).ToList(); if (items.Any()) { shapeItem = items.First(i => i.Name.Contains(itemName)); if(shapeItem != null) { source.Cancel(); break; } } } }); return shapeItem; } public async Task ShapeToGeotiff(Item shapeItem) { var shapeToGeotiffRequest = new TaskRequest() { TaskType = "vnd.farmmaps.task.shapetogeotiff" }; var taskCode = await _farmmapsApiService.QueueTaskAsync(shapeItem.Code, shapeToGeotiffRequest); await PollTask(TimeSpan.FromSeconds(3), async (tokenSource) => { _logger.LogInformation("Checking shapetogeotiff task status"); var itemTaskStatus = await _farmmapsApiService.GetTaskStatusAsync(shapeItem.Code, taskCode); if (itemTaskStatus.IsFinished) tokenSource.Cancel(); }); _logger.LogInformation("Data shape converted to geotiff"); // the parent of the shape item is now the tiff item shapeItem = await _farmmapsApiService.GetItemAsync(shapeItem.Code); return await _farmmapsApiService.GetItemAsync(shapeItem.ParentCode); } public async Task FindChildItemAsync(string parentCode, string itemType, string containsName, Func filter = null, int maxTries = 10) { Item dataItem = null; int tries = 0; await PollTask(TimeSpan.FromSeconds(3), async source => { _logger.LogInformation($"Trying to get {containsName} data"); var uploadedFilesChildren = await _farmmapsApiService.GetItemChildrenAsync(parentCode, itemType); if (uploadedFilesChildren.Count > 0) { Func func = filter ?? (i => i.Name.ToLower().Contains(containsName.ToLower())); dataItem = uploadedFilesChildren.FirstOrDefault(func); source.Cancel(); } else if (tries == maxTries) { source.Cancel(); } tries++; }); if (dataItem == null) { _logger.LogError("dataItem not found"); return null; } _logger.LogInformation($"Found {containsName} item"); return dataItem; } } }