add type definition, basic request building

This commit is contained in:
YK committed 2025-04-12 22:05:51 +03:00
1 parent 5b911e216d
commit b59f18e358
4 files changed
+214 -2

No files matched your search

+164 -2
View File
@@ -1,3 +1,165 @@
fn main() {
println!("Hello, world!");
#![allow(non_upper_case_globals)]
use std::{ env, error::Error, fs::File, io::Read, sync::LazyLock, time::Duration };
use anyhow::Result;
use const_format::formatcp;
use serde::{ Serialize, Deserialize };
use ureq::{ http::Response, Agent, Body };
const MAX_USERS_PER_PAGE: u8 = 50;
const cookie_filename: &'static str = "cookie.txt";
const host: &'static str = "members.tilda.ru";
const project_id: u32 = 11795571;
const origin: &'static str = formatcp!("https://{host}");
const referer: &'static str = formatcp!("{origin}/{project_id}/");
const endpoint: &'static str = formatcp!("{origin}/api/getmembers/");
const user_agent: &'static str = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36";
#[derive(Debug, Clone, Deserialize, Serialize)]
enum RequestSort {
#[serde(rename = "nameAsc")]
NameAsc
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
struct Request {
pub page: u16,
pub page_size: u8,
pub sort: RequestSort,
pub project_id: u32,
}
impl Default for Request {
fn default () -> Self {
Self { page: 1, page_size: MAX_USERS_PER_PAGE, sort: RequestSort::NameAsc, project_id }
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(untagged)]
enum Resp {
Ok (OkResp),
Err (ErrResp),
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
struct OkResp {
pub status: String,
pub data: ResponseData
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
struct ErrResp {
pub status: String,
pub code: String
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
struct ResponseData {
pub total: u32,
pub total_active: u32,
pub pages: u32,
pub members: Vec<Member>,
pub page: u32,
pub page_size: u32,
pub login_url: String,
#[serde(rename = "singUpUrl")] // [sic]
pub sign_up_url: String,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Member {
pub id: u32,
pub name: String,
pub login: String,
pub added_date: String,
pub activity: bool,
pub avatar: Option<String>,
pub last_online_date: String,
pub groups: Vec<Group>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Group {
pub id: u32,
pub name: String
}
impl Request {
fn for_page (page: u16) -> Self {
let mut _self = Self::default();
_self.page = page;
_self
}
fn send (&self, cookie: &str) -> Result<Response<Body>> {
let agent: Agent = Agent::config_builder()
.timeout_global(Some(Duration::from_secs(5)))
.user_agent(user_agent)
.build()
.into();
let builder = agent.post(endpoint)
.content_type("text/plain;charset=UTF-8")
.header("Host", host)
.header("Origin", origin)
.header("Referer", referer)
.header("Cookie", cookie);
let body = serde_json::to_string(self)?;
Ok(builder.send(body)?)
}
}
/// @TODO
fn try_get_cookie () -> Result<()> {
Ok(())
}
fn read_cookie (filename: &str) -> Option<String> {
let mut cookie_file = File::open(filename).ok()?;
let mut cookie = String::new();
cookie_file.read_to_string(&mut cookie).ok()?;
cookie = cookie.trim().to_owned();
if cookie.is_empty() { return None; }
Some(cookie)
}
fn retrieve_users (cookie: &str) {
}
fn main () {
let cookie = read_cookie(cookie_filename).expect(&format!("Directory with executable should contain `{cookie_filename}` file containing a valid cookie for accessing Tilda control panel"));
let req = Request::default().send(&cookie);
if let Ok(mut req) = req {
let mut body = req.body_mut();
println!("{:?}", body.read_json::<Resp>());
}
// println!("{} {} {} {} {} {}", host, project_id, &*origin, &*referer, user_agent, cookie);
}