game_manager_lib/services/integration/pcgamingwiki/
fetch.rs1use crate::errors::AppError;
9use crate::models::{GameExtras, PcgwScrapedData};
10use crate::services::integration::pcgamingwiki::client::{build_http_client, cargo_query};
11use crate::services::integration::pcgamingwiki::parsers::{
12 extract_field, normalize_bool_field, parse_l10n_rows,
13};
14use crate::services::integration::pcgamingwiki::scraper::scrape_pcgw_page;
15use chrono::Utc;
16use tracing::info;
17
18pub async fn fetch_pcgw_data(
28 steam_app_id: &str,
29) -> Result<(GameExtras, Option<PcgwScrapedData>), AppError> {
30 let client = build_http_client()?;
31
32 let infobox_rows = cargo_query(
36 &client,
37 "Infobox_game",
38 "Infobox_game._pageID=pageID,\
39 Infobox_game._pageName=pageName,\
40 Infobox_game.Engines=engine, \
41 Infobox_game.Available_on=available_on",
42 &format!("Infobox_game.Steam_AppID HOLDS \"{}\"", steam_app_id),
43 3, )
45 .await?;
46
47 if infobox_rows.is_empty() {
48 return Err(AppError::NotFound(format!(
49 "Jogo com Steam AppID {} não encontrado no PCGamingWiki",
50 steam_app_id
51 )));
52 }
53
54 let page_id = extract_field(&infobox_rows, "pageID").ok_or_else(|| {
55 AppError::ParseError("pageID ausente na resposta da Infobox_game".to_string())
56 })?;
57
58 let page_name = extract_field(&infobox_rows, "pageName");
59 let engine = extract_field(&infobox_rows, "engine");
60
61 info!(
62 "PCGW: jogo encontrado — page_id={}, name={:?}",
63 page_id, page_name
64 );
65
66 let page_filter = format!("_pageID=\"{}\"", page_id);
68
69 let scraped = scrape_pcgw_page(&client, &page_id, steam_app_id).await.ok();
72
73 let api_rows = cargo_query(
77 &client,
78 "API",
79 "API.Direct3D_versions=dx_versions,\
80 API.Vulkan_versions=vulkan_versions,\
81 API.OpenGL_versions=opengl_versions,\
82 API.Windows_64bit_executable=win64,\
83 API.Linux_64bit_executable=linux64,\
84 API.macOS_ARM_app=macos_arm,\
85 API.macOS_Intel_64bit_app=macos_intel64",
86 &page_filter,
87 3,
88 )
89 .await?;
90
91 let available_on = extract_field(&infobox_rows, "available_on");
92 let dx_versions = extract_field(&api_rows, "dx_versions");
93 let vulkan_versions = extract_field(&api_rows, "vulkan_versions");
94 let opengl_versions = extract_field(&api_rows, "opengl_versions");
95 let win64 = normalize_bool_field(extract_field(&api_rows, "win64"));
96 let linux64 = normalize_bool_field(extract_field(&api_rows, "linux64"));
97 let macos_arm = normalize_bool_field(extract_field(&api_rows, "macos_arm"));
98 let macos_intel64 = normalize_bool_field(extract_field(&api_rows, "macos_intel64"));
99
100 let video_rows = cargo_query(
104 &client,
105 "Video",
106 "Video.Ray_tracing=ray_tracing,\
107 Video.Upscaling=upscaling,\
108 Video.Frame_gen=frame_gen,\
109 Video.Ultrawidescreen=ultrawide,\
110 Video.4K_Ultra_HD=four_k,\
111 Video.HDR=hdr,\
112 Video.120_FPS=high_fps,\
113 Video.Field_of_view=fov,\
114 Video.Borderless_fullscreen_windowed=borderless,\
115 Video.Color_blind=color_blind",
116 &page_filter,
117 3,
118 )
119 .await?;
120
121 let ray_tracing = normalize_bool_field(extract_field(&video_rows, "ray_tracing"));
122 let upscaling = extract_field(&video_rows, "upscaling");
123 let frame_gen = extract_field(&video_rows, "frame_gen");
124 let ultrawidescreen = normalize_bool_field(extract_field(&video_rows, "ultrawide"));
125 let four_k_support = normalize_bool_field(extract_field(&video_rows, "four_k"));
126 let hdr = normalize_bool_field(extract_field(&video_rows, "hdr"));
127 let high_fps = normalize_bool_field(extract_field(&video_rows, "high_fps"));
128 let fov = normalize_bool_field(extract_field(&video_rows, "fov"));
129 let borderless_windowed = normalize_bool_field(extract_field(&video_rows, "borderless"));
130 let color_blind = normalize_bool_field(extract_field(&video_rows, "color_blind"));
131
132 let input_rows = cargo_query(
136 &client,
137 "Input",
138 "Input.Controller_support=ctrl_support,\
139 Input.Full_controller_support=full_ctrl,\
140 Input.Playstation_controller_support=ps_ctrl,\
141 Input.XInput_controller_support=xinput",
142 &page_filter,
143 3,
144 )
145 .await?;
146
147 let controller_support = normalize_bool_field(extract_field(&input_rows, "ctrl_support"));
148 let full_controller = normalize_bool_field(extract_field(&input_rows, "full_ctrl"));
149 let playstation_controllers = normalize_bool_field(extract_field(&input_rows, "ps_ctrl"));
150 let xinput_controllers = normalize_bool_field(extract_field(&input_rows, "xinput"));
151
152 let audio_rows = cargo_query(
156 &client,
157 "Audio",
158 "Audio.Surround_sound=surround,\
159 Audio.Subtitles=subtitles,\
160 Audio.Closed_captions=closed_captions",
161 &page_filter,
162 3,
163 )
164 .await?;
165
166 let surround_sound = normalize_bool_field(extract_field(&audio_rows, "surround"));
167 let subtitles = normalize_bool_field(extract_field(&audio_rows, "subtitles"));
168 let closed_captions = normalize_bool_field(extract_field(&audio_rows, "closed_captions"));
169
170 let l10n_rows = cargo_query(
174 &client,
175 "L10n",
176 "L10n.Language=language,\
177 L10n.Interface=interface,\
178 L10n.Audio=audio,\
179 L10n.Subtitles=subtitles",
180 &page_filter,
181 50, )
183 .await?;
184
185 let (languages_interface, languages_audio, languages_subtitles) = parse_l10n_rows(&l10n_rows);
186
187 let tags_rows = cargo_query(
191 &client,
192 "Tags",
193 "Tags.Save_data=save_data,\
194 Tags.Config_data=config_data",
195 &page_filter,
196 3,
197 )
198 .await?;
199
200 let has_save_data = normalize_bool_field(extract_field(&tags_rows, "save_data"));
201 let has_config_data = normalize_bool_field(extract_field(&tags_rows, "config_data"));
202
203 let fetched_at = Utc::now().to_rfc3339();
207
208 Ok((
209 GameExtras {
210 steam_app_id: steam_app_id.to_string(),
211 pcgw_page_id: Some(page_id),
212 pcgw_page_name: page_name,
213 engine,
214 available_on,
215 dx_versions,
217 vulkan_versions,
218 opengl_versions,
219 win64,
220 linux64,
221 macos_arm,
222 macos_intel64,
223 ray_tracing,
225 upscaling,
226 frame_gen,
227 ultrawidescreen,
228 four_k_support,
229 hdr,
230 high_fps,
231 fov,
232 borderless_windowed,
233 color_blind,
234 controller_support,
236 full_controller,
237 playstation_controllers,
238 xinput_controllers,
239 surround_sound,
241 subtitles,
242 closed_captions,
243 has_save_data,
245 has_config_data,
246 languages_interface,
248 languages_audio,
249 languages_subtitles,
250 fetched_at: Some(fetched_at),
251 },
252 scraped,
253 ))
254}