Skip to content

Commit ce39b11

Browse files
Merge pull request #36 from Nesteo/data-export
Data export
2 parents e7c9b00 + 6f00b4e commit ce39b11

16 files changed

+368
-16
lines changed

Nesteo.Server.DataImport/Nesteo.Server.DataImport.csproj

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,4 @@
1414
<PackageReference Include="CsvHelper" Version="12.1.3" />
1515
</ItemGroup>
1616

17-
<ItemGroup>
18-
<None Remove="Data\kontrolldaten.csv" />
19-
</ItemGroup>
20-
21-
<ItemGroup>
22-
<Content Include="Data\Kontrolldaten.csv" />
23-
</ItemGroup>
24-
2517
</Project>

Nesteo.Server/Controllers/Api/InspectionsController.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.IO;
4+
using System.Linq;
45
using System.Threading.Tasks;
56
using Microsoft.AspNetCore.Http;
67
using Microsoft.AspNetCore.Mvc;
@@ -9,6 +10,7 @@
910
using Nesteo.Server.Filters;
1011
using Nesteo.Server.Models;
1112
using Nesteo.Server.Options;
13+
using Nesteo.Server.Result;
1214
using Nesteo.Server.Services;
1315

1416
namespace Nesteo.Server.Controllers.Api
@@ -164,5 +166,17 @@ public async Task<ActionResult<InspectionPreview>> GetInspectionPreviewByIdAsync
164166

165167
return inspectionPreview;
166168
}
169+
170+
/// <summary>
171+
/// Download inspections csv
172+
/// </summary>
173+
[HttpGet("csv")]
174+
[ProducesResponseType(StatusCodes.Status200OK)]
175+
public Task<IActionResult> ExportInspectionsAsync()
176+
{
177+
string fileDownloadName = $"inspections-export-{DateTime.Now}.csv";
178+
IAsyncEnumerable<string> records = _inspectionService.ExportAllRowsAsync();
179+
180+
return Task.FromResult<IActionResult>(new CsvFileResult(records, fileDownloadName)); }
167181
}
168182
}

Nesteo.Server/Controllers/Api/NestingBoxesController.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using Nesteo.Server.Filters;
1111
using Nesteo.Server.Models;
1212
using Nesteo.Server.Options;
13+
using Nesteo.Server.Result;
1314
using Nesteo.Server.Services;
1415

1516
namespace Nesteo.Server.Controllers.Api
@@ -197,5 +198,18 @@ public IAsyncEnumerable<InspectionPreview> GetInspectionPreviewsByNestingBoxIdAs
197198
{
198199
return _inspectionService.GetAllPreviewsForNestingBoxIdAsync(id);
199200
}
201+
202+
/// <summary>
203+
/// Download nesting boxes csv
204+
/// </summary>
205+
[HttpGet("csv")]
206+
[ProducesResponseType(StatusCodes.Status200OK)]
207+
public Task<IActionResult> ExportNestingBoxAsync()
208+
{
209+
string fileDownloadName = $"nesting-boxes-export-{DateTime.Now}.csv";
210+
IAsyncEnumerable<string> records = _nestingBoxService.ExportAllRowsAsync();
211+
212+
return Task.FromResult<IActionResult>(new CsvFileResult(records, fileDownloadName));
213+
}
200214
}
201215
}

Nesteo.Server/IdGeneration/RegionPrefixedNestingBoxIdGenerator.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Diagnostics;
44
using System.Linq;
5+
using System.Runtime.CompilerServices;
56
using System.Threading;
67
using System.Threading.Tasks;
78
using Nesteo.Server.Models;
@@ -11,7 +12,10 @@ namespace Nesteo.Server.IdGeneration
1112
{
1213
public class RegionPrefixedNestingBoxIdGenerator : INestingBoxIdGenerator
1314
{
14-
public async IAsyncEnumerable<string> GetNextIdsAsync(INestingBoxService nestingBoxService, Region region, int count, CancellationToken cancellationToken = default)
15+
public async IAsyncEnumerable<string> GetNextIdsAsync(INestingBoxService nestingBoxService,
16+
Region region,
17+
int count,
18+
[EnumeratorCancellation] CancellationToken cancellationToken = default)
1519
{
1620
if (nestingBoxService == null)
1721
throw new ArgumentNullException(nameof(nestingBoxService));
@@ -33,7 +37,8 @@ public async IAsyncEnumerable<string> GetNextIdsAsync(INestingBoxService nesting
3337
cancellationToken.ThrowIfCancellationRequested();
3438

3539
// Query taken nesting box ids and get the enumerator for more efficient manual iteration
36-
await using IAsyncEnumerator<string> takenNestingBoxIds = nestingBoxService.GetAllTakenIdsWithPrefixAsync(region.NestingBoxIdPrefix).GetAsyncEnumerator(cancellationToken);
40+
await using IAsyncEnumerator<string> takenNestingBoxIds =
41+
nestingBoxService.GetAllTakenIdsWithPrefixAsync(region.NestingBoxIdPrefix).GetAsyncEnumerator(cancellationToken);
3742
await takenNestingBoxIds.MoveNextAsync().ConfigureAwait(false);
3843

3944
// Find next IDs

Nesteo.Server/MappingProfiles/ModelMappingProfile.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,11 @@ public ModelMappingProfile()
2626
.Inspections
2727
.OrderByDescending(inspection => inspection.InspectionDate)
2828
.FirstOrDefault().InspectionDate));
29+
CreateMap<NestingBoxEntity, NestingBoxExportRow>().ForMember(dest => dest.HangUpUserName, options => options.MapFrom(nestingBox => nestingBox.HangUpUser.UserName));
2930
CreateMap<InspectionEntity, Inspection>().ForMember(dest => dest.HasImage, options => options.MapFrom(inspection => inspection.ImageFileName != null));
3031
CreateMap<InspectionEntity, InspectionPreview>();
32+
CreateMap<InspectionEntity, InspectionExportRow>().ForMember(dest => dest.InspectedByUserName,
33+
options => options.MapFrom(inspection => inspection.InspectedByUser.UserName));
3134
}
3235
}
3336
}

Nesteo.Server/Models/Inspection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public class Inspection
101101
/// The bird species
102102
/// </summary>
103103
[Required]
104-
public Species? Species { get; set; }
104+
public Species Species { get; set; }
105105

106106
/// <summary>
107107
/// Comment
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
using System;
2+
using System.ComponentModel.DataAnnotations;
3+
using Nesteo.Server.Data.Enums;
4+
5+
namespace Nesteo.Server.Models
6+
{
7+
public class InspectionExportRow
8+
{
9+
/// <summary>
10+
/// Inspection-ID
11+
/// </summary>
12+
public int? Id { get; set; }
13+
14+
/// <summary>
15+
/// Id of the inspected nesting box
16+
/// </summary>
17+
[Required]
18+
public string NestingBoxId { get; set; }
19+
20+
/// <summary>
21+
/// Date and time of the inspection
22+
/// </summary>
23+
[Required]
24+
public DateTime? InspectionDate { get; set; }
25+
26+
/// <summary>
27+
/// The user who inspected the nesting box (if known)
28+
/// </summary>
29+
public string InspectedByUserName { get; set; }
30+
31+
/// <summary>
32+
/// Whether the nesting box has been cleaned during the inspection
33+
/// </summary>
34+
[Required]
35+
public bool? HasBeenCleaned { get; set; }
36+
37+
/// <summary>
38+
/// The condition in which the nesting box has been found
39+
/// </summary>
40+
[Required]
41+
[EnumDataType(typeof(Condition))]
42+
public Condition? Condition { get; set; }
43+
44+
/// <summary>
45+
/// Whether the nesting box has been repaired during the inspection
46+
/// </summary>
47+
[Required]
48+
public bool? JustRepaired { get; set; }
49+
50+
/// <summary>
51+
/// Was the nesting box occupied by any bird (if known)?
52+
/// </summary>
53+
public bool? Occupied { get; set; }
54+
55+
/// <summary>
56+
/// Were any eggs in there?
57+
/// </summary>
58+
[Required]
59+
public bool? ContainsEggs { get; set; }
60+
61+
/// <summary>
62+
/// Count of eggs (or null when unknown)
63+
/// </summary>
64+
[Range(0, 100)]
65+
public int? EggCount { get; set; }
66+
67+
/// <summary>
68+
/// Number of slipped chicks (or null when unknown)
69+
/// </summary>
70+
[Range(0, 100)]
71+
public int? ChickCount { get; set; }
72+
73+
/// <summary>
74+
/// Number of ringed chicks
75+
/// </summary>
76+
[Required]
77+
[Range(0, 100)]
78+
public int? RingedChickCount { get; set; }
79+
80+
/// <summary>
81+
/// Age of the chicks (or null when unknown)
82+
/// </summary>
83+
[Range(0, 100)]
84+
public int? AgeInDays { get; set; }
85+
86+
/// <summary>
87+
/// Information about the presence of the female parent bird
88+
/// </summary>
89+
[Required]
90+
[EnumDataType(typeof(ParentBirdDiscovery))]
91+
public ParentBirdDiscovery? FemaleParentBirdDiscovery { get; set; }
92+
93+
/// <summary>
94+
/// Information about the presence of the male parent bird
95+
/// </summary>
96+
[Required]
97+
[EnumDataType(typeof(ParentBirdDiscovery))]
98+
public ParentBirdDiscovery? MaleParentBirdDiscovery { get; set; }
99+
100+
/// <summary>
101+
/// The bird species
102+
/// </summary>
103+
[Required]
104+
public string SpeciesName { get; set; }
105+
106+
/// <summary>
107+
/// Image file name
108+
/// </summary>
109+
public string ImageFilename { get; set; }
110+
111+
/// <summary>
112+
/// Comment
113+
/// </summary>
114+
public string Comment { get; set; }
115+
116+
/// <summary>
117+
/// The time this data entry has last been updated
118+
/// </summary>
119+
public DateTime? LastUpdated { get; set; }
120+
}
121+
}

Nesteo.Server/Models/NestingBox.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class NestingBox
1616
/// Region, where the nesting box hangs
1717
/// </summary>
1818
[Required]
19-
public Region? Region { get; set; }
19+
public Region Region { get; set; }
2020

2121
/// <summary>
2222
/// The old ID (if any)
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using System;
2+
using System.ComponentModel.DataAnnotations;
3+
using Nesteo.Server.Data.Enums;
4+
5+
namespace Nesteo.Server.Models
6+
{
7+
public class NestingBoxExportRow
8+
{
9+
/// <summary>
10+
/// Nesting box ID
11+
/// </summary>
12+
[StringLength(Constants.NestingBoxIdLength, MinimumLength = Constants.NestingBoxIdLength)]
13+
public string Id { get; set; }
14+
15+
/// <summary>
16+
/// The old ID (if any)
17+
/// </summary>
18+
[StringLength(100, MinimumLength = 2)]
19+
public string OldId { get; set; }
20+
21+
/// <summary>
22+
/// The foreign ID (if any)
23+
/// </summary>
24+
[StringLength(100, MinimumLength = 2)]
25+
public string ForeignId { get; set; }
26+
27+
/// <summary>
28+
/// Region, where the nesting box hangs
29+
/// </summary>
30+
[Required]
31+
public string RegionName { get; set; }
32+
33+
/// <summary>
34+
/// Decimal coordinate longitude
35+
/// </summary>
36+
public double? CoordinateLongitude { get; set; }
37+
38+
/// <summary>
39+
/// Decimal coordinate latitude
40+
/// </summary>
41+
public double? CoordinateLatitude { get; set; }
42+
43+
/// <summary>
44+
/// Hang up date (if known)
45+
/// </summary>
46+
public DateTime? HangUpDate { get; set; }
47+
48+
/// <summary>
49+
/// Hang up user (if known)
50+
/// </summary>
51+
public string HangUpUserName { get; set; }
52+
53+
/// <summary>
54+
/// Owner of the nesting box
55+
/// </summary>
56+
[Required]
57+
public string OwnerName { get; set; }
58+
59+
/// <summary>
60+
/// Material
61+
/// </summary>
62+
[Required]
63+
[EnumDataType(typeof(Material))]
64+
public Material Material { get; set; }
65+
66+
/// <summary>
67+
/// Size of the hole
68+
/// </summary>
69+
[Required]
70+
[EnumDataType(typeof(HoleSize))]
71+
public HoleSize? HoleSize { get; set; }
72+
73+
/// <summary>
74+
/// Image file name
75+
/// </summary>
76+
public string ImageFilename { get; set; }
77+
78+
/// <summary>
79+
/// Comment
80+
/// </summary>
81+
public string Comment { get; set; }
82+
83+
/// <summary>
84+
/// The time this data entry has last been updated
85+
/// </summary>
86+
public DateTime? LastUpdated { get; set; }
87+
}
88+
}

Nesteo.Server/Models/NestingBoxPreview.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class NestingBoxPreview
1515
/// Region, where the nesting box hangs
1616
/// </summary>
1717
[Required]
18-
public Region? Region { get; set; }
18+
public Region Region { get; set; }
1919

2020
/// <summary>
2121
/// Decimal coordinate longitude

0 commit comments

Comments
 (0)