Skip to main content

tail_fin_pcc/
lib.rs

1pub mod parsing;
2pub mod site;
3pub mod types;
4
5use tail_fin_common::page::{browser_origin_fetch, ensure_on_domain};
6use tail_fin_common::BrowserSession;
7use tail_fin_common::TailFinError;
8
9pub use site::PccSite;
10pub use types::*;
11
12const PCC_DOMAINS: &[&str] = &["pcc.g0v.ronny.tw", "pcc-api.openfun.app"];
13
14pub struct PccClient {
15    session: BrowserSession,
16}
17
18impl PccClient {
19    pub fn new(session: BrowserSession) -> Self {
20        Self { session }
21    }
22
23    async fn api_get(&self, path: &str) -> Result<serde_json::Value, TailFinError> {
24        ensure_on_domain(&self.session, PCC_DOMAINS).await?;
25        browser_origin_fetch(&self.session, path, None).await
26    }
27
28    pub async fn info(&self) -> Result<PccInfo, TailFinError> {
29        let data = self.api_get("/api/getinfo").await?;
30        parsing::parse_info(&data)
31    }
32
33    pub async fn search(&self, query: &str, page: u32) -> Result<SearchResult, TailFinError> {
34        let q = urlencoding::encode(query);
35        let data = self
36            .api_get(&format!("/api/searchbytitle?query={}&page={}", q, page))
37            .await?;
38        parsing::parse_search_result(&data)
39    }
40
41    pub async fn search_company(
42        &self,
43        query: &str,
44        page: u32,
45    ) -> Result<SearchResult, TailFinError> {
46        let q = urlencoding::encode(query);
47        let data = self
48            .api_get(&format!(
49                "/api/searchbycompanyname?query={}&page={}",
50                q, page
51            ))
52            .await?;
53        parsing::parse_search_result(&data)
54    }
55
56    pub async fn search_id(&self, query: &str, page: u32) -> Result<SearchResult, TailFinError> {
57        let q = urlencoding::encode(query);
58        let data = self
59            .api_get(&format!("/api/searchbycompanyid?query={}&page={}", q, page))
60            .await?;
61        parsing::parse_search_result(&data)
62    }
63
64    pub async fn search_budget(
65        &self,
66        query: &str,
67        page: u32,
68    ) -> Result<SearchResult, TailFinError> {
69        let q = urlencoding::encode(query);
70        let data = self
71            .api_get(&format!(
72                "/api/searchbyspecialbudget?query={}&page={}",
73                q, page
74            ))
75            .await?;
76        parsing::parse_search_result(&data)
77    }
78
79    pub async fn budgets(&self) -> Result<Vec<SpecialBudget>, TailFinError> {
80        let data = self.api_get("/api/searchallspecialbudget").await?;
81        Ok(parsing::parse_budgets(&data))
82    }
83
84    pub async fn date(&self, date: &str) -> Result<SearchResult, TailFinError> {
85        let data = self
86            .api_get(&format!("/api/listbydate?date={}", date))
87            .await?;
88        parsing::parse_search_result(&data)
89    }
90
91    pub async fn units(&self) -> Result<Vec<Unit>, TailFinError> {
92        let data = self.api_get("/api/unit").await?;
93        Ok(parsing::parse_units(&data))
94    }
95
96    pub async fn unit(&self, unit_id: &str, page: u32) -> Result<SearchResult, TailFinError> {
97        let data = self
98            .api_get(&format!(
99                "/api/listbyunit?unit_id={}&page={}",
100                unit_id, page
101            ))
102            .await?;
103        parsing::parse_search_result(&data)
104    }
105
106    pub async fn tender(
107        &self,
108        unit_id: &str,
109        job_number: &str,
110    ) -> Result<serde_json::Value, TailFinError> {
111        self.api_get(&format!(
112            "/api/tender?unit_id={}&job_number={}",
113            unit_id, job_number
114        ))
115        .await
116    }
117}