Skip to content

Commit 0ec3f96

Browse files
committed
fix(service): send romnom and romtaille on screenscraper hash lookups
1 parent 1e0a003 commit 0ec3f96

3 files changed

Lines changed: 86 additions & 52 deletions

File tree

service/src/providers/screenscraper/cache.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ pub async fn get_ss_game_by_md5_cached(
151151
client: &ScreenScraperClient,
152152
redis_conn: &mut MultiplexedConnection,
153153
system_id: i32,
154+
rom_name: String,
155+
rom_size: Option<i64>,
154156
md5: String,
155157
) -> anyhow::Result<Option<SsGame>> {
156158
let lower = md5.to_lowercase();
@@ -160,7 +162,11 @@ pub async fn get_ss_game_by_md5_cached(
160162
cache_key,
161163
SS_CACHE_LIFETIME_GAME,
162164
"Game by MD5",
163-
|| async { client.get_game_by_md5(system_id, &lower).await },
165+
|| async {
166+
client
167+
.get_game_by_md5(system_id, &rom_name, rom_size, &lower)
168+
.await
169+
},
164170
)
165171
.await
166172
}
@@ -169,6 +175,8 @@ pub async fn get_ss_game_by_sha1_cached(
169175
client: &ScreenScraperClient,
170176
redis_conn: &mut MultiplexedConnection,
171177
system_id: i32,
178+
rom_name: String,
179+
rom_size: Option<i64>,
172180
sha1: String,
173181
) -> anyhow::Result<Option<SsGame>> {
174182
let lower = sha1.to_lowercase();
@@ -179,7 +187,11 @@ pub async fn get_ss_game_by_sha1_cached(
179187
cache_key,
180188
SS_CACHE_LIFETIME_GAME,
181189
"Game by SHA1",
182-
|| async { client.get_game_by_sha1(system_id, &lower).await },
190+
|| async {
191+
client
192+
.get_game_by_sha1(system_id, &rom_name, rom_size, &lower)
193+
.await
194+
},
183195
)
184196
.await
185197
}
@@ -188,6 +200,8 @@ pub async fn get_ss_game_by_crc_cached(
188200
client: &ScreenScraperClient,
189201
redis_conn: &mut MultiplexedConnection,
190202
system_id: i32,
203+
rom_name: String,
204+
rom_size: Option<i64>,
191205
crc: String,
192206
) -> anyhow::Result<Option<SsGame>> {
193207
let lower = crc.to_lowercase();
@@ -197,7 +211,11 @@ pub async fn get_ss_game_by_crc_cached(
197211
cache_key,
198212
SS_CACHE_LIFETIME_GAME,
199213
"Game by CRC",
200-
|| async { client.get_game_by_crc(system_id, &lower).await },
214+
|| async {
215+
client
216+
.get_game_by_crc(system_id, &rom_name, rom_size, &lower)
217+
.await
218+
},
201219
)
202220
.await
203221
}

service/src/providers/screenscraper/matching/game.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,12 @@ async fn try_match_by_hashes(
367367
if client.is_quota_exhausted() {
368368
return Ok(None);
369369
}
370+
let rom_name = file.file_name.as_str();
371+
let rom_size = file.file_size_in_bytes;
370372
if let Some(md5) = file.md5.as_deref().filter(|s| !s.is_empty())
371-
&& let Some(found) = client.get_game_by_md5(system_id, md5).await?
373+
&& let Some(found) = client
374+
.get_game_by_md5(system_id, rom_name, rom_size, md5)
375+
.await?
372376
{
373377
record_hash_match(
374378
game,
@@ -385,7 +389,9 @@ async fn try_match_by_hashes(
385389
return Ok(None);
386390
}
387391
if let Some(sha1) = file.sha1.as_deref().filter(|s| !s.is_empty())
388-
&& let Some(found) = client.get_game_by_sha1(system_id, sha1).await?
392+
&& let Some(found) = client
393+
.get_game_by_sha1(system_id, rom_name, rom_size, sha1)
394+
.await?
389395
{
390396
record_hash_match(
391397
game,
@@ -402,7 +408,9 @@ async fn try_match_by_hashes(
402408
return Ok(None);
403409
}
404410
if let Some(crc) = file.crc.as_deref().filter(|s| !s.is_empty())
405-
&& let Some(found) = client.get_game_by_crc(system_id, crc).await?
411+
&& let Some(found) = client
412+
.get_game_by_crc(system_id, rom_name, rom_size, crc)
413+
.await?
406414
{
407415
record_hash_match(
408416
game,

service/src/providers/screenscraper/mod.rs

Lines changed: 54 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -185,73 +185,81 @@ impl ScreenScraperClient {
185185
pub async fn get_game_by_md5(
186186
&self,
187187
system_id: i32,
188+
rom_name: &str,
189+
rom_size: Option<i64>,
188190
md5: &str,
189191
) -> anyhow::Result<Option<SsGame>> {
190-
if !valid_system_id(system_id) {
191-
debug!("screenscraper get_game_by_md5 skipped: invalid system_id ({system_id})");
192-
return Ok(None);
193-
}
194-
let trimmed = md5.trim();
195-
if trimmed.is_empty() {
196-
debug!("screenscraper get_game_by_md5 skipped: empty md5");
197-
return Ok(None);
198-
}
199-
let url = self.url(
200-
"jeuInfos.php",
201-
&[
202-
("systemeid", system_id.to_string()),
203-
("md5", trimmed.to_string()),
204-
],
205-
)?;
206-
self.fetch_optional_game("game_by_md5", url).await
192+
self.get_game_by_hash("game_by_md5", system_id, rom_name, rom_size, "md5", md5)
193+
.await
207194
}
208195

209196
pub async fn get_game_by_sha1(
210197
&self,
211198
system_id: i32,
199+
rom_name: &str,
200+
rom_size: Option<i64>,
212201
sha1: &str,
213202
) -> anyhow::Result<Option<SsGame>> {
214-
if !valid_system_id(system_id) {
215-
debug!("screenscraper get_game_by_sha1 skipped: invalid system_id ({system_id})");
216-
return Ok(None);
217-
}
218-
let trimmed = sha1.trim();
219-
if trimmed.is_empty() {
220-
debug!("screenscraper get_game_by_sha1 skipped: empty sha1");
221-
return Ok(None);
222-
}
223-
let url = self.url(
224-
"jeuInfos.php",
225-
&[
226-
("systemeid", system_id.to_string()),
227-
("sha1", trimmed.to_string()),
228-
],
229-
)?;
230-
self.fetch_optional_game("game_by_sha1", url).await
203+
self.get_game_by_hash(
204+
"game_by_sha1",
205+
system_id,
206+
rom_name,
207+
rom_size,
208+
"sha1",
209+
sha1,
210+
)
211+
.await
231212
}
232213

233214
pub async fn get_game_by_crc(
234215
&self,
235216
system_id: i32,
217+
rom_name: &str,
218+
rom_size: Option<i64>,
236219
crc: &str,
220+
) -> anyhow::Result<Option<SsGame>> {
221+
self.get_game_by_hash("game_by_crc", system_id, rom_name, rom_size, "crc", crc)
222+
.await
223+
}
224+
225+
/// `jeuInfos.php` hash lookups require `systemeid`, `romnom` and a hash;
226+
/// `romtaille` is optional but improves the hit rate. Calls without
227+
/// `romnom` come back as HTTP 400 "Il manque des champs obligatoires
228+
/// dans l'url", so guard for it here.
229+
async fn get_game_by_hash(
230+
&self,
231+
endpoint_label: &'static str,
232+
system_id: i32,
233+
rom_name: &str,
234+
rom_size: Option<i64>,
235+
hash_param: &'static str,
236+
hash_value: &str,
237237
) -> anyhow::Result<Option<SsGame>> {
238238
if !valid_system_id(system_id) {
239-
debug!("screenscraper get_game_by_crc skipped: invalid system_id ({system_id})");
239+
debug!("screenscraper {endpoint_label} skipped: invalid system_id ({system_id})");
240240
return Ok(None);
241241
}
242-
let trimmed = crc.trim();
243-
if trimmed.is_empty() {
244-
debug!("screenscraper get_game_by_crc skipped: empty crc");
242+
let trimmed_hash = hash_value.trim();
243+
if trimmed_hash.is_empty() {
244+
debug!("screenscraper {endpoint_label} skipped: empty {hash_param}");
245245
return Ok(None);
246246
}
247-
let url = self.url(
248-
"jeuInfos.php",
249-
&[
250-
("systemeid", system_id.to_string()),
251-
("crc", trimmed.to_string()),
252-
],
253-
)?;
254-
self.fetch_optional_game("game_by_crc", url).await
247+
let trimmed_name = rom_name.trim();
248+
if trimmed_name.is_empty() {
249+
debug!("screenscraper {endpoint_label} skipped: empty rom_name");
250+
return Ok(None);
251+
}
252+
let mut params: Vec<(&'static str, String)> = vec![
253+
("systemeid", system_id.to_string()),
254+
("romtype", "rom".to_string()),
255+
("romnom", trimmed_name.to_string()),
256+
(hash_param, trimmed_hash.to_string()),
257+
];
258+
if let Some(size) = rom_size.filter(|s| *s > 0) {
259+
params.push(("romtaille", size.to_string()));
260+
}
261+
let url = self.url("jeuInfos.php", &params)?;
262+
self.fetch_optional_game(endpoint_label, url).await
255263
}
256264

257265
async fn fetch_optional_game(

0 commit comments

Comments
 (0)