@@ -36,13 +36,42 @@ pub struct SpaceInfo {
3636 pub achievement_count : i32 ,
3737}
3838
39+ fn cache_path ( language : & Language , uid : i32 ) -> String {
40+ format ! ( "mihomo/{}_{uid}.br" , language. mihomo( ) )
41+ }
42+
43+ fn load_cached ( language : & Language , uid : i32 ) -> Result < Option < Mihomo > > {
44+ let path = cache_path ( language, uid) ;
45+ if PathBuf :: from ( & path) . exists ( ) {
46+ let decompressor = brotli:: Decompressor :: new ( File :: open ( & path) ?, 4096 ) ;
47+ Ok ( Some ( serde_json:: from_reader ( decompressor) ?) )
48+ } else {
49+ Ok ( None )
50+ }
51+ }
52+
3953pub async fn get ( uid : i32 , language : Language , pool : & PgPool ) -> Result < Value > {
40- let path = format ! ( "mihomo/{}_{uid}.br" , language . mihomo ( ) ) ;
54+ let path = cache_path ( & language , uid ) ;
4155
4256 if PathBuf :: from ( & path) . exists ( ) {
4357 let decompressor = brotli:: Decompressor :: new ( File :: open ( & path) ?, 4096 ) ;
58+ let cached_json: Value = serde_json:: from_reader ( decompressor) ?;
59+ let cached: Mihomo = serde_json:: from_value ( cached_json. clone ( ) ) ?;
60+
61+ let should_update = if language == Language :: En {
62+ false
63+ } else {
64+ match load_cached ( & Language :: En , uid) ? {
65+ Some ( en) => cached. updated_at < en. updated_at ,
66+ None => true ,
67+ }
68+ } ;
4469
45- Ok ( serde_json:: from_reader ( decompressor) ?)
70+ if should_update {
71+ update_and_get ( uid, language, pool) . await
72+ } else {
73+ Ok ( cached_json)
74+ }
4675 } else {
4776 update_and_get ( uid, language, pool) . await
4877 }
@@ -61,15 +90,35 @@ pub async fn update_and_get(uid: i32, language: Language, pool: &PgPool) -> Resu
6190 o. insert ( "updated_at" . to_string ( ) , serde_json:: to_value ( now) ?) ;
6291 }
6392
93+ let ( en_json, is_english) = if language == Language :: En {
94+ ( json. clone ( ) , true )
95+ } else {
96+ let en_url = format ! ( "https://api.mihomo.me/sr_info_parsed/{uid}?lang=en&version=v2" , ) ;
97+
98+ let mut en_json: Value = reqwest:: get ( & en_url) . await ?. json ( ) . await ?;
99+ if let Some ( o) = en_json. as_object_mut ( ) {
100+ o. insert ( "updated_at" . to_string ( ) , serde_json:: to_value ( now) ?) ;
101+ }
102+ ( en_json, false )
103+ } ;
104+
64105 if serde_json:: from_value :: < Mihomo > ( json. clone ( ) ) . is_ok ( ) {
65- let file = File :: create ( format ! ( "mihomo/{}_{uid}.br" , language . mihomo ( ) ) ) ?;
106+ let file = File :: create ( cache_path ( & language , uid ) ) ?;
66107
67108 let writer = brotli:: CompressorWriter :: new ( file, 4096 , 4 , 22 ) ;
68109
69110 serde_json:: to_writer ( writer, & json) ?;
70111 }
71112
72- let mihomo: Mihomo = serde_json:: from_value ( json. clone ( ) ) ?;
113+ if !is_english && serde_json:: from_value :: < Mihomo > ( en_json. clone ( ) ) . is_ok ( ) {
114+ let file = File :: create ( cache_path ( & Language :: En , uid) ) ?;
115+
116+ let writer = brotli:: CompressorWriter :: new ( file, 4096 , 4 , 22 ) ;
117+
118+ serde_json:: to_writer ( writer, & en_json) ?;
119+ }
120+
121+ let mihomo: Mihomo = serde_json:: from_value ( en_json) ?;
73122
74123 let re = Regex :: new ( r"<[^>]*>" ) ?;
75124
0 commit comments