File tree 17 files changed +186
-121
lines changed
17 files changed +186
-121
lines changed Original file line number Diff line number Diff line change
1
+ {
2
+ "version" : 1 ,
3
+ "isRoot" : true ,
4
+ "tools" : {
5
+ "swashbuckle.aspnetcore.cli" : {
6
+ "version" : " 6.6.1" ,
7
+ "commands" : [
8
+ " swagger"
9
+ ]
10
+ }
11
+ }
12
+ }
Original file line number Diff line number Diff line change 12
12
steps :
13
13
- uses : actions/checkout@v3
14
14
- run : make test-e2e
15
+
16
+ check-api-reference :
17
+ runs-on : ubuntu-22.04
18
+ steps :
19
+ - uses : actions/checkout@v3
20
+ - run : make check-api-reference
Original file line number Diff line number Diff line change @@ -33,7 +33,14 @@ public ActionResult<CalculatorInfo> GetInfo()
33
33
[ HttpGet ( "calculation" ) ]
34
34
public async Task < ActionResult < TCalculation > > GetCalculation ( [ FromQuery ] TScore score )
35
35
{
36
- return Ok ( await calculatorService . GetCalculation ( score ) ) ;
36
+ try
37
+ {
38
+ return Ok ( await calculatorService . GetCalculation ( score ) ) ;
39
+ }
40
+ catch ( BeatmapNotFoundException e )
41
+ {
42
+ return BadRequest ( new { error = e . Message } ) ;
43
+ }
37
44
}
38
45
39
46
/// <summary>
@@ -43,7 +50,14 @@ public async Task<ActionResult<TCalculation>> GetCalculation([FromQuery] TScore
43
50
[ Consumes ( "application/json" ) ]
44
51
public async Task < ActionResult < TCalculation [ ] > > GetCalculationBatch ( [ FromBody ] TScore [ ] scores )
45
52
{
46
- return Ok ( await Task . WhenAll ( scores . Select ( score => calculatorService . GetCalculation ( score ) ) ) ) ;
53
+ try
54
+ {
55
+ return Ok ( await Task . WhenAll ( scores . Select ( calculatorService . GetCalculation ) ) ) ;
56
+ }
57
+ catch ( BeatmapNotFoundException e )
58
+ {
59
+ return BadRequest ( new { error = e . Message } ) ;
60
+ }
47
61
}
48
62
}
49
63
}
Original file line number Diff line number Diff line change
1
+ using System ;
2
+
3
+ namespace Difficalcy . Services
4
+ {
5
+ public class BeatmapNotFoundException ( string beatmapId ) : Exception ( $ "Beatmap { beatmapId } not found")
6
+ {
7
+ }
8
+ }
Original file line number Diff line number Diff line change 1
- using System ;
2
1
using System . IO ;
3
2
using System . Reflection ;
4
3
using System . Threading . Tasks ;
5
- using Microsoft . AspNetCore . Http ;
6
4
7
5
namespace Difficalcy . Services
8
6
{
@@ -11,7 +9,7 @@ public class TestBeatmapProvider(string resourceAssemblyName) : IBeatmapProvider
11
9
public Task EnsureBeatmap ( string beatmapId )
12
10
{
13
11
var resourceName = GetResourceName ( beatmapId ) ;
14
- _ = ResourceAssembly . GetManifestResourceInfo ( resourceName ) ?? throw new BadHttpRequestException ( $ "Beatmap not found: { beatmapId } " ) ;
12
+ _ = ResourceAssembly . GetManifestResourceInfo ( resourceName ) ?? throw new BeatmapNotFoundException ( beatmapId ) ;
15
13
return Task . CompletedTask ;
16
14
}
17
15
Original file line number Diff line number Diff line change 1
1
using System . IO ;
2
2
using System . Net . Http ;
3
3
using System . Threading . Tasks ;
4
- using Microsoft . AspNetCore . Http ;
5
4
using Microsoft . Extensions . Configuration ;
6
5
7
6
namespace Difficalcy . Services
8
7
{
9
8
public class WebBeatmapProvider ( IConfiguration configuration ) : IBeatmapProvider
10
9
{
11
10
private readonly string _beatmapDirectory = configuration [ "BEATMAP_DIRECTORY" ] ;
11
+ private readonly string _downloadMissingBeatmaps = configuration [ "DOWNLOAD_MISSING_BEATMAPS" ] ;
12
12
private readonly HttpClient _httpClient = new ( ) ;
13
13
14
14
public async Task EnsureBeatmap ( string beatmapId )
15
15
{
16
16
var beatmapPath = GetBeatmapPath ( beatmapId ) ;
17
17
if ( ! File . Exists ( beatmapPath ) )
18
18
{
19
+ if ( _downloadMissingBeatmaps != "true" )
20
+ throw new BeatmapNotFoundException ( beatmapId ) ;
21
+
19
22
using var response = await _httpClient . GetAsync ( $ "https://osu.ppy.sh/osu/{ beatmapId } ") ;
20
- if ( ! response . IsSuccessStatusCode )
21
- throw new BadHttpRequestException ( "Beatmap not found" ) ;
23
+ if ( ! response . IsSuccessStatusCode || response . Content . Headers . ContentLength == 0 )
24
+ throw new BeatmapNotFoundException ( beatmapId ) ;
22
25
23
26
using var fs = new FileStream ( beatmapPath , FileMode . CreateNew ) ;
24
- if ( fs . Length == 0 )
25
- throw new BadHttpRequestException ( "Beatmap not found" ) ;
26
-
27
27
await response . Content . CopyToAsync ( fs ) ;
28
+ if ( fs . Length == 0 )
29
+ {
30
+ fs . Close ( ) ;
31
+ File . Delete ( beatmapPath ) ;
32
+ throw new BeatmapNotFoundException ( beatmapId ) ;
33
+ }
28
34
}
29
35
}
30
36
Original file line number Diff line number Diff line change @@ -4,9 +4,10 @@ LABEL org.opencontainers.image.source https://github.com/Syriiin/difficalcy
4
4
5
5
WORKDIR /app
6
6
EXPOSE 80
7
- ENV ASPNETCORE_URLS=http://+:80
8
- ENV ASPNETCORE_ENVIRONMENT=Production
9
- ENV BEATMAP_DIRECTORY=/beatmaps
7
+ ENV ASPNETCORE_URLS="http://+:80"
8
+ ENV ASPNETCORE_ENVIRONMENT="Production"
9
+ ENV BEATMAP_DIRECTORY="/beatmaps"
10
+ ENV DOWNLOAD_MISSING_BEATMAPS="true"
10
11
11
12
VOLUME ${BEATMAP_DIRECTORY}
12
13
# chmod 777 so that this volume can be read/written by other containers that might use different uids
Original file line number Diff line number Diff line change @@ -27,11 +27,11 @@ start-dev: build-dev ## Starts development environment
27
27
clean-dev : # # Cleans development environment
28
28
$(COMPOSE_APP_DEV ) down --remove-orphans
29
29
30
- update-openapi-schemas : # # Updates OpenAPI schemas in docs site
31
- curl localhost:5000/swagger/v1/swagger.json -o docs/docs/ api-reference/difficalcy-osu.json
32
- curl localhost:5001/swagger/v1/swagger.json -o docs/docs/api-reference/difficalcy-taiko.json
33
- curl localhost:5002/swagger/v1/swagger.json -o docs/docs/ api-reference/difficalcy-catch.json
34
- curl localhost:5003/swagger/v1/swagger.json -o docs/docs/ api-reference/difficalcy-mania.json
30
+ update-api-reference : # # Updates OpenAPI schemas in docs site
31
+ $( COMPOSE_TOOLING_RUN ) scripts/update- api-reference.sh
32
+
33
+ check- api-reference: # # Checks OpenAPI schemas are updated
34
+ $( COMPOSE_TOOLING_RUN ) scripts/check- api-reference.sh
35
35
36
36
build-docs : # # Builds documentation site
37
37
$(COMPOSE_RUN_DOCS ) build --strict --clean
Original file line number Diff line number Diff line change @@ -3,3 +3,5 @@ services:
3
3
build :
4
4
context : .
5
5
dockerfile : ./tooling.Dockerfile
6
+ volumes :
7
+ - .:/app
Original file line number Diff line number Diff line change 12
12
],
13
13
"responses" : {
14
14
"200" : {
15
- "description" : " Success " ,
15
+ "description" : " OK " ,
16
16
"content" : {
17
17
"application/json" : {
18
18
"schema" : {
37
37
"maximum" : 2147483647 ,
38
38
"minimum" : 0 ,
39
39
"type" : " integer" ,
40
- "format" : " int32" ,
41
- "nullable" : true
40
+ "format" : " int32"
42
41
}
43
42
},
44
43
{
58
57
"maximum" : 2147483647 ,
59
58
"minimum" : 0 ,
60
59
"type" : " integer" ,
61
- "format" : " int32" ,
62
- "nullable" : true
60
+ "format" : " int32"
63
61
}
64
62
},
65
63
{
69
67
"maximum" : 2147483647 ,
70
68
"minimum" : 0 ,
71
69
"type" : " integer" ,
72
- "format" : " int32" ,
73
- "nullable" : true
70
+ "format" : " int32"
74
71
}
75
72
},
76
73
{
94
91
],
95
92
"responses" : {
96
93
"200" : {
97
- "description" : " Success " ,
94
+ "description" : " OK " ,
98
95
"content" : {
99
96
"application/json" : {
100
97
"schema" : {
118
115
"type" : " array" ,
119
116
"items" : {
120
117
"$ref" : " #/components/schemas/CatchScore"
121
- },
122
- "nullable" : true
118
+ }
123
119
}
124
120
}
125
121
}
126
122
},
127
123
"responses" : {
128
124
"200" : {
129
- "description" : " Success " ,
125
+ "description" : " OK " ,
130
126
"content" : {
131
127
"application/json" : {
132
128
"schema" : {
170
166
},
171
167
"additionalProperties" : false
172
168
},
173
- "CatchDifficulty " : {
169
+ "CatchCalculation " : {
174
170
"type" : " object" ,
175
171
"properties" : {
176
- "total" : {
172
+ "difficulty" : {
173
+ "$ref" : " #/components/schemas/CatchDifficulty"
174
+ },
175
+ "performance" : {
176
+ "$ref" : " #/components/schemas/CatchPerformance"
177
+ },
178
+ "accuracy" : {
179
+ "type" : " number" ,
180
+ "format" : " double"
181
+ },
182
+ "combo" : {
177
183
"type" : " number" ,
178
184
"format" : " double"
179
185
}
180
186
},
181
187
"additionalProperties" : false
182
188
},
183
- "CatchPerformance " : {
189
+ "CatchDifficulty " : {
184
190
"type" : " object" ,
185
191
"properties" : {
186
192
"total" : {
190
196
},
191
197
"additionalProperties" : false
192
198
},
193
- "CatchCalculation " : {
199
+ "CatchPerformance " : {
194
200
"type" : " object" ,
195
201
"properties" : {
196
- "difficulty" : {
197
- "$ref" : " #/components/schemas/CatchDifficulty"
198
- },
199
- "performance" : {
200
- "$ref" : " #/components/schemas/CatchPerformance"
201
- },
202
- "accuracy" : {
203
- "type" : " number" ,
204
- "format" : " double"
205
- },
206
- "combo" : {
202
+ "total" : {
207
203
"type" : " number" ,
208
204
"format" : " double"
209
205
}
217
213
"type" : " object" ,
218
214
"properties" : {
219
215
"beatmapId" : {
216
+ "minLength" : 1 ,
220
217
"type" : " string"
221
218
},
222
219
"mods" : {
Original file line number Diff line number Diff line change 12
12
],
13
13
"responses" : {
14
14
"200" : {
15
- "description" : " Success " ,
15
+ "description" : " OK " ,
16
16
"content" : {
17
17
"application/json" : {
18
18
"schema" : {
101
101
],
102
102
"responses" : {
103
103
"200" : {
104
- "description" : " Success " ,
104
+ "description" : " OK " ,
105
105
"content" : {
106
106
"application/json" : {
107
107
"schema" : {
125
125
"type" : " array" ,
126
126
"items" : {
127
127
"$ref" : " #/components/schemas/ManiaScore"
128
- },
129
- "nullable" : true
128
+ }
130
129
}
131
130
}
132
131
}
133
132
},
134
133
"responses" : {
135
134
"200" : {
136
- "description" : " Success " ,
135
+ "description" : " OK " ,
137
136
"content" : {
138
137
"application/json" : {
139
138
"schema" : {
177
176
},
178
177
"additionalProperties" : false
179
178
},
180
- "ManiaDifficulty " : {
179
+ "ManiaCalculation " : {
181
180
"type" : " object" ,
182
181
"properties" : {
183
- "total" : {
182
+ "difficulty" : {
183
+ "$ref" : " #/components/schemas/ManiaDifficulty"
184
+ },
185
+ "performance" : {
186
+ "$ref" : " #/components/schemas/ManiaPerformance"
187
+ },
188
+ "accuracy" : {
184
189
"type" : " number" ,
185
190
"format" : " double"
186
191
}
187
192
},
188
193
"additionalProperties" : false
189
194
},
190
- "ManiaPerformance " : {
195
+ "ManiaDifficulty " : {
191
196
"type" : " object" ,
192
197
"properties" : {
193
198
"total" : {
194
199
"type" : " number" ,
195
200
"format" : " double"
196
- },
197
- "difficulty" : {
198
- "type" : " number" ,
199
- "format" : " double"
200
201
}
201
202
},
202
203
"additionalProperties" : false
203
204
},
204
- "ManiaCalculation " : {
205
+ "ManiaPerformance " : {
205
206
"type" : " object" ,
206
207
"properties" : {
207
- "difficulty" : {
208
- "$ref" : " #/components/schemas/ManiaDifficulty"
209
- },
210
- "performance" : {
211
- "$ref" : " #/components/schemas/ManiaPerformance"
208
+ "total" : {
209
+ "type" : " number" ,
210
+ "format" : " double"
212
211
},
213
- "accuracy " : {
212
+ "difficulty " : {
214
213
"type" : " number" ,
215
214
"format" : " double"
216
215
}
224
223
"type" : " object" ,
225
224
"properties" : {
226
225
"beatmapId" : {
226
+ "minLength" : 1 ,
227
227
"type" : " string"
228
228
},
229
229
"mods" : {
You can’t perform that action at this time.
0 commit comments