-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAPIClient.cs
153 lines (125 loc) · 6.21 KB
/
APIClient.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
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
using System.Threading.Tasks;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Text.Json.Serialization;
using Mercurius.Modrinth.Models;
using Mercurius.Configuration;
using Mercurius.Profiles;
using NLog;
namespace Mercurius.Modrinth {
public class APIClient {
private HttpClient client;
private const string BaseUrl = @"https://api.modrinth.com/v2/";
private ILogger logger;
public APIClient() {
logger = LogManager.GetCurrentClassLogger();
client = new HttpClient();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("user-agent", "Mercurius");
}
public async Task<SearchModel> SearchAsync(string query) {
logger.Debug($"Querying Labrynth with {query}...");
SearchModel deserializedRes;
try {
Stream responseStream = await client.GetStreamAsync(BaseUrl + $@"search?query={query}");
deserializedRes = await JsonSerializer.DeserializeAsync<SearchModel>(responseStream);
} catch (Exception e) {
logger.Warn(e.Message);
logger.Trace(e.StackTrace);
throw new ApiException("Connection Failed!");
}
if (deserializedRes.hits.Length <= 0) {
logger.Debug("No results found... Sorry");
throw new ApiException("No results found");
}
return deserializedRes;
}
public async Task<ProjectModel> GetProjectAsync(string projectId) {
logger.Debug($"Getting Project with ID {projectId}...");
ProjectModel deserializedRes = new ProjectModel();
try {
Stream responseStream = await client.GetStreamAsync(BaseUrl + $@"project/{projectId}");
deserializedRes = await JsonSerializer.DeserializeAsync<ProjectModel>(responseStream);
} catch (HttpRequestException e) {
if (e.StatusCode == HttpStatusCode.NotFound) {
throw new ProjectInvalidException($"Project ID {projectId} is invalid!");
} else {
throw new Exception($"Failed to connect...? {e.Message}");
}
}
return deserializedRes;
}
public async Task<VersionModel> GetVersionInfoAsync(string versionId) {
if (versionId is null) {
throw new ArgumentNullException();
}
logger.Debug($"Getting Project Version with ID {versionId}...");
VersionModel deserializedRes = new VersionModel();
try {
Stream responseStream = await client.GetStreamAsync(BaseUrl + $@"version/{versionId}");
deserializedRes = await JsonSerializer.DeserializeAsync<VersionModel>(responseStream);
} catch (HttpRequestException e) {
if (e.StatusCode == System.Net.HttpStatusCode.NotFound) {
throw new VersionInvalidException("Invalid version id");
} else {
throw new Exception($"failed to connect: {e.StatusCode}");
}
}
return deserializedRes;
}
public async Task<VersionModel[]> ListVersionsAsync(ProjectModel project) {
logger.Debug($"Getting List of Versions for {project.title}...");
VersionModel[] deserializedRes;
Stream responseStream = await client.GetStreamAsync(BaseUrl + $@"project/{project.id}/version");
deserializedRes = await JsonSerializer.DeserializeAsync<VersionModel[]>(responseStream);
return deserializedRes;
}
public async Task DownloadVersionAsync(Mod mod) {
if (mod.Title is null) {
throw new ArgumentNullException("Mod values are null!");
}
logger.Debug($"Starting Download of {mod.Title}: version {mod.ModVersion}");
HttpResponseMessage response;
response = await client.GetAsync(mod.DownloadURL, HttpCompletionOption.ResponseContentRead);
using Stream readStream = await response.Content.ReadAsStreamAsync();
using Stream writeStream = File.Open(@$"{SettingsManager.Settings.Minecraft_Directory}/mods/{mod.FileName}", FileMode.Create);
await readStream.CopyToAsync(writeStream);
readStream.Close();
writeStream.Close();
logger.Debug($"Completed Download of {mod.Title}: version {mod.ModVersion}");
//TODO Report download progress
//TODO Check download SHA256
}
}
public class ApiException : Exception {
public ApiException() { }
public ApiException(string message) : base(message) { }
public ApiException(string message, System.Exception inner) : base(message, inner) { }
protected ApiException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}
[System.Serializable]
public class VersionInvalidException : System.Exception
{
public VersionInvalidException() { }
public VersionInvalidException(string message) : base(message) { }
public VersionInvalidException(string message, System.Exception inner) : base(message, inner) { }
protected VersionInvalidException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}
[System.Serializable]
public class ProjectInvalidException : System.Exception
{
public ProjectInvalidException() { }
public ProjectInvalidException(string message) : base(message) { }
public ProjectInvalidException(string message, System.Exception inner) : base(message, inner) { }
protected ProjectInvalidException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}
}