forked from TheDenSS14/TheDen
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProgram.cs
125 lines (108 loc) · 3.73 KB
/
Program.cs
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
using Content.PatreonParser;
using CsvHelper;
using CsvHelper.Configuration;
using static System.Environment;
var repository = new DirectoryInfo(Directory.GetCurrentDirectory()).Parent!.Parent!.Parent!.Parent!;
var patronsPath = Path.Combine(repository.FullName, "Resources/Credits/Patrons.yml");
if (!File.Exists(patronsPath))
{
Console.WriteLine($"File {patronsPath} not found.");
return;
}
Console.WriteLine($"Updating {patronsPath}");
Console.WriteLine("Is this correct? [Y/N]");
var response = Console.ReadLine()?.ToUpper();
if (response != "Y")
{
Console.WriteLine("Exiting");
return;
}
var delimiter = ",";
var hasHeaderRecord = false;
var mode = CsvMode.RFC4180;
var escape = '\'';
Console.WriteLine($"""
Delimiter: {delimiter}
HasHeaderRecord: {hasHeaderRecord}
Mode: {mode}
Escape Character: {escape}
""");
Console.WriteLine("Enter the full path to the .csv file containing the Patreon webhook data:");
var filePath = Console.ReadLine();
if (filePath == null)
{
Console.Write("No path given.");
return;
}
var file = File.OpenRead(filePath);
var csvConfig = new CsvConfiguration(CultureInfo.InvariantCulture)
{
Delimiter = delimiter,
HasHeaderRecord = hasHeaderRecord,
Mode = mode,
Escape = escape,
};
using var reader = new CsvReader(new StreamReader(file), csvConfig);
// This does not handle tier name changes, but we haven't had any yet
var patrons = new Dictionary<Guid, Patron>();
var jsonOptions = new JsonSerializerOptions
{
IncludeFields = true,
NumberHandling = JsonNumberHandling.AllowReadingFromString
};
// This assumes that the rows are already sorted by id
foreach (var record in reader.GetRecords<Row>())
{
if (record.Trigger == "members:create")
continue;
var content = JsonSerializer.Deserialize<Root>(record.ContentJson, jsonOptions)!;
var id = Guid.Parse(content.Data.Id);
patrons.Remove(id);
var tiers = content.Data.Relationships.CurrentlyEntitledTiers.Data;
if (tiers.Count == 0)
continue;
else if (tiers.Count > 1)
throw new ArgumentException("Found more than one tier");
var tier = tiers[0];
var tierName = content.Included.SingleOrDefault(i => i.Id == tier.Id && i.Type == tier.Type)?.Attributes.Title;
if (tierName == null || tierName == "Free")
continue;
if (record.Trigger == "members:delete")
continue;
var fullName = content.Data.Attributes.FullName.Trim();
var pledgeStart = content.Data.Attributes.PledgeRelationshipStart;
switch (record.Trigger)
{
case "members:create":
break;
case "members:delete":
break;
case "members:update":
patrons.Add(id, new Patron(fullName, tierName, pledgeStart!.Value));
break;
case "members:pledge:create":
if (pledgeStart == null)
continue;
patrons.Add(id, new Patron(fullName, tierName, pledgeStart.Value));
break;
case "members:pledge:delete":
// Deleted pledge but still not expired, expired is handled earlier
patrons.Add(id, new Patron(fullName, tierName, pledgeStart!.Value));
break;
case "members:pledge:update":
patrons.Add(id, new Patron(fullName, tierName, pledgeStart!.Value));
break;
}
}
var patronList = patrons.Values.ToList();
patronList.Sort((a, b) => a.Start.CompareTo(b.Start));
var yaml = patronList.Select(p => $"""
- Name: "{p.FullName.Replace("\"", "\\\"")}"
Tier: {p.TierName}
""");
var output = string.Join(NewLine, yaml) + NewLine;
File.WriteAllText(patronsPath, output);
Console.WriteLine($"Updated {patronsPath} with {patronList.Count} patrons.");