/
DiscordEventsTemplateBase.tt
154 lines (138 loc) · 11.5 KB
/
DiscordEventsTemplateBase.tt
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Text" #>
<#@ assembly name="Newtonsoft.Json" #>
<#@ import namespace="Newtonsoft.Json" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<#@ import namespace="System.Collections.ObjectModel" #>
<#@ assembly name="System.Net.Http" #>
<#@ import namespace="System.Net.Http" #>
<#@ import namespace="System.Collections.Generic" #>
<#+
public static string AutomaticNamespaceLine => $"namespace {AutomaticNamespace};";
public static string AutomaticNamespace => System.Runtime.Remoting.Messaging.CallContext.LogicalGetData("NamespaceHint")?.ToString() ?? throw new InvalidProgramException("No SolutionDirectoryAvailable!");
#nullable enable
private static readonly TimeSpan maxFileAge = TimeSpan.FromHours(6);
private const string cacheName = "DiscordClientEventsCache.json";
public static string CacheDirectory => @"C:\Users\ruhoffman\source\repos\BetterHosting";
//public static string CacheDirectory => @"C:\Users\ruhoffman\source\repos\BetterHosting\";
private static string CacheFilePath => Path.Combine(CacheDirectory, cacheName);
public static EventNaming FirstEvent => EventsList[0];
public static EventNaming LastEvent
{
get
{
var localList = EventsList;
return localList[localList.Count - 1];
}
}
public static IEnumerable<EventNaming> SkipFirst => EventsList.Skip(1);
public static IEnumerable<EventNaming> MiddleEvents => SkipLast.Skip(1);
public static IEnumerable<EventNaming> SkipLast
{
get
{
var localList = EventsList;
return localList.Take(localList.Count - 1);
}
}
private static List<EventNaming>? eventsList;
public static List<EventNaming> EventsList
{
get
{
try
{
if(eventsList != null) return eventsList;
string cacheFilePath = CacheFilePath;
FileInfo file_info = new(cacheFilePath);
if(file_info.Exists)
{
if(file_info.CreationTime < DateTime.Now && (DateTime.Now - file_info.CreationTime) > maxFileAge)
{
return eventsList = LoadEventsFromFile(cacheFilePath);
}
}
var newResult = DownloadAndParse();
SerializeToFile(newResult, cacheFilePath);
eventsList = newResult;
return newResult;
}
catch(Exception ex)
{
throw new InvalidProgramException("Oops!", ex);
}
}
}
private static List<EventNaming> LoadEventsFromFile(string cacheFilePath)
{
try
{
string json;
using (FileStream fs = File.OpenRead(cacheFilePath))
using (StreamReader reader = new(fs))
{
json = reader.ReadToEnd();
}
return Newtonsoft.Json.JsonConvert.DeserializeObject<List<EventNaming>>(json)!;
}
catch(Exception ex)
{
throw new InvalidProgramException("Oops!", ex);
}
}
private static void SerializeToFile(List<EventNaming> events, string cacheFilePath)
{
try
{
string json = Newtonsoft.Json.JsonConvert.SerializeObject(events, Formatting.Indented)!;
File.WriteAllText(json, cacheFilePath);
}
catch(Exception ex)
{
throw new InvalidProgramException("Oops!", ex);
}
}
private static readonly Regex regex = new("^ *public event AsyncEventHandler<DiscordClient, (?<EventArgType>.+?)> (?<EventName>.+?)$", RegexOptions.ExplicitCapture | RegexOptions.Multiline);
private static List<EventNaming> DownloadAndParse()
{
const string downloadURL = "https://raw.githubusercontent.com/DSharpPlus/DSharpPlus/master/DSharpPlus/Clients/DiscordClient.Events.cs";
using HttpClient client = new();
#if false
Stream stream = client.GetStreamAsync(downloadURL).GetAwaiter().GetResult();
IEnumerable<string> lines = StreamToLines(stream);
IEnumerable<Match> matches = lines.Select(l => regex.Match(l)).Where(m => m.Success);
return matches.Select(m => new EventNaming(m.Groups["EventName"].Value, m.Groups["EventArgType"].Value)).ToList().AsReadOnly();
static IEnumerable<string> StreamToLines(Stream input)
{
using System.IO.StreamReader reader = new System.IO.StreamReader(input);
string? line;
while ((line = reader.ReadLine()) != null)
yield return line;
}
#endif
string sourceString = client.GetStringAsync(downloadURL).GetAwaiter().GetResult();
MatchCollection matchResults = regex.Matches(sourceString);
List<EventNaming> resultList = new();
foreach (Match m in matchResults)
{
if(!m.Success) continue;
resultList.Add(new EventNaming(m.Groups["EventName"].Value, m.Groups["EventArgType"].Value));
}
return resultList;
}
public partial class EventNaming
{
public EventNaming(string eventName, string argumentType)
{
EventName = eventName;
ArgumentType = argumentType;
}
public readonly string EventName;
public readonly string ArgumentType;
public string MethodName => $"On{EventName}";
public string InterfaceName => $"I{EventName}EventHandler";
public string WithHandlerSuffix => $"{EventName}Handler";
}
#>