|
1 | | -import json |
2 | | -import rand |
3 | 1 | import net.http |
| 2 | +import os |
| 3 | +import rand |
| 4 | +import x.json2 |
| 5 | +import x.json2.decoder2 as json |
4 | 6 |
|
5 | 7 | struct Weather { |
6 | | - status string @[skip] // drop this field |
7 | | - api_version string @[skip] |
8 | | - api_status string @[skip] |
9 | | - lang string @[skip] |
10 | | - unit string @[skip] |
11 | | - tzshift int @[skip] |
12 | | - timezone string @[skip] |
13 | | - server_time u32 @[skip] |
14 | | - location []f32 @[skip] |
15 | | - result Result //@[json: result] if the field name is different in JSON, it can be specified |
| 8 | + lang string |
| 9 | + result Result |
16 | 10 | } |
17 | 11 |
|
18 | 12 | struct Result { |
19 | | - realtime Realtime @[skip] |
20 | | - minutely Minutely @[skip] |
21 | | - hourly Hourly @[skip] |
22 | | - daily Daily @[skip] |
23 | | - primary int @[skip] |
24 | 13 | forecast_keypoint string |
25 | 14 | } |
26 | 15 |
|
27 | | -struct Realtime {} |
28 | | - |
29 | | -struct Minutely {} |
30 | | - |
31 | | -struct Hourly {} |
32 | | - |
33 | | -struct Daily {} |
| 16 | +const config = http.FetchConfig{ |
| 17 | + user_agent: 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.0' |
| 18 | +} |
34 | 19 |
|
35 | 20 | fn main() { |
36 | | - config := http.FetchConfig{ |
37 | | - user_agent: 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.0' |
38 | | - } |
39 | | - |
| 21 | + dest_lang := if os.args.len > 1 { os.args[1] } else { 'en' } |
40 | 22 | rnd := rand.f32() |
41 | 23 | url := 'https://api.caiyunapp.com/v2.5/96Ly7wgKGq6FhllM/116.391912,40.010711/weather.jsonp?hourlysteps=120&random=${rnd}' |
42 | | - // println(url) |
43 | 24 |
|
44 | 25 | resp := http.fetch(http.FetchConfig{ ...config, url: url }) or { |
45 | 26 | println('failed to fetch data from the server') |
46 | 27 | return |
47 | 28 | } |
48 | 29 |
|
49 | | - weather := json.decode(Weather, resp.body) or { |
| 30 | + weather := json.decode[Weather](resp.body) or { |
50 | 31 | println('failed to decode weather json') |
51 | 32 | return |
52 | 33 | } |
53 | 34 |
|
54 | | - println('未来两小时天气:\n${weather.result.forecast_keypoint}.') |
| 35 | + for ch in ['未来两小时天气', weather.result.forecast_keypoint] { |
| 36 | + println('${weather.lang:8}: ${ch}') |
| 37 | + t := translate(ch, weather.lang, dest_lang) or { |
| 38 | + println('failed to translate ${ch}: ${err}') |
| 39 | + continue |
| 40 | + } |
| 41 | + println('${dest_lang:8}: ${t}') |
| 42 | + } |
| 43 | +} |
| 44 | + |
| 45 | +// translate fetch google to print translate text `q` in languate `sl` into language `tl`. |
| 46 | +// A translation typical response json is like: `[[["Weather in the next two hours", |
| 47 | +// "未来两小时天气",null,null,3,null,null,[[null,"offline"]], |
| 48 | +// [[["61549914d65604307a34fd1855292577","offline_launch_doc.md"],null,null,null,null, |
| 49 | +// [[[6,8,0]]]]]]],null,"zh-CN",null,null,null,null,[]]` |
| 50 | +// where translated text is located at position `json_resp[0][0][0]`. |
| 51 | +fn translate(q string, sl string, tl string) !string { |
| 52 | + url := 'https://translate.googleapis.com/translate_a/single?client=gtx&sl=${sl}&tl=${tl}&dt=t&q=${q}' |
| 53 | + |
| 54 | + resp := http.fetch(http.FetchConfig{ ...config, url: url })! |
| 55 | + |
| 56 | + json_resp := json.decode[json2.Any](resp.body)! |
| 57 | + |
| 58 | + a := json_resp.arr() |
| 59 | + if a.len > 0 { |
| 60 | + a0 := a[0].arr() |
| 61 | + if a0.len > 0 { |
| 62 | + a00 := a0[0].arr() |
| 63 | + if a00.len > 0 { |
| 64 | + return a00[0].str() |
| 65 | + } |
| 66 | + } |
| 67 | + } |
| 68 | + return error('invalid translation response') |
55 | 69 | } |
0 commit comments