This repository was archived by the owner on Mar 31, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathPackageReadmeToCsvDriver.cs
More file actions
107 lines (92 loc) · 4.21 KB
/
PackageReadmeToCsvDriver.cs
File metadata and controls
107 lines (92 loc) · 4.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Security.Cryptography;
using CommunityToolkit.HighPerformance;
namespace NuGet.Insights.Worker.PackageReadmeToCsv
{
public class PackageReadmeToCsvDriver : ICatalogLeafToCsvDriver<PackageReadme>, ICsvResultStorage<PackageReadme>
{
private readonly CatalogClient _catalogClient;
private readonly PackageReadmeService _packageReadmeService;
private readonly IOptions<NuGetInsightsWorkerSettings> _options;
public PackageReadmeToCsvDriver(
CatalogClient catalogClient,
PackageReadmeService packageReadmeService,
IOptions<NuGetInsightsWorkerSettings> options)
{
_catalogClient = catalogClient;
_packageReadmeService = packageReadmeService;
_options = options;
}
public string ResultContainerName => _options.Value.PackageReadmeContainerName;
public bool SingleMessagePerId => false;
public async Task InitializeAsync()
{
await _packageReadmeService.InitializeAsync();
}
public Task DestroyAsync()
{
return Task.CompletedTask;
}
public async Task<DriverResult<IReadOnlyList<PackageReadme>>> ProcessLeafAsync(CatalogLeafScan leafScan)
{
var records = await ProcessLeafInternalAsync(leafScan);
return DriverResult.Success(records);
}
private async Task<IReadOnlyList<PackageReadme>> ProcessLeafInternalAsync(CatalogLeafScan leafItem)
{
var scanId = Guid.NewGuid();
var scanTimestamp = DateTimeOffset.UtcNow;
if (leafItem.LeafType == CatalogLeafType.PackageDelete)
{
var leaf = (PackageDeleteCatalogLeaf)await _catalogClient.GetCatalogLeafAsync(leafItem.LeafType, leafItem.Url);
return new List<PackageReadme> { new PackageReadme(scanId, scanTimestamp, leaf) };
}
else
{
var leaf = (PackageDetailsCatalogLeaf)await _catalogClient.GetCatalogLeafAsync(leafItem.LeafType, leafItem.Url);
var info = await _packageReadmeService.GetOrUpdateInfoFromLeafItemAsync(leafItem.ToPackageIdentityCommit());
return new List<PackageReadme> { GetRecord(scanId, scanTimestamp, leaf, info) };
}
}
private PackageReadme GetRecord(Guid scanId, DateTimeOffset scanTimestamp, PackageDetailsCatalogLeaf leaf, PackageReadmeService.PackageReadmeInfoV1 info)
{
PackageReadmeResultType resultType;
switch (info.ReadmeType)
{
case ReadmeType.None:
return new PackageReadme(scanId, scanTimestamp, leaf)
{
ResultType = PackageReadmeResultType.None,
};
case ReadmeType.Legacy:
resultType = PackageReadmeResultType.Legacy;
break;
case ReadmeType.Embedded:
resultType = PackageReadmeResultType.Embedded;
break;
default:
throw new NotImplementedException();
}
DateTimeOffset? lastModified = null;
var lastModifiedString = info.HttpHeaders["Last-Modified"].FirstOrDefault();
if (lastModifiedString is not null)
{
lastModified = DateTimeOffset.Parse(lastModifiedString, CultureInfo.InvariantCulture);
}
using var hasher = SHA256.Create();
var sha256 = hasher.ComputeHash(info.ReadmeBytes.AsStream()).ToBase64();
using var reader = new StreamReader(info.ReadmeBytes.AsStream());
var content = reader.ReadToEnd();
var record = new PackageReadme(scanId, scanTimestamp, leaf)
{
ResultType = resultType,
Size = info.ReadmeBytes.Length,
LastModified = lastModified,
SHA256 = sha256,
Content = content,
};
return record;
}
}
}