diff --git a/src/lib.rs b/src/lib.rs index 11e0732..7cff664 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,12 @@ use reqwest::{Client, Response}; use scraper::{Html, Selector}; use std::error::Error; use std::io; -use std::thread; +use std::ops::Index; +use std::time::Duration; +use tokio::sync::{Mutex}; +use std::sync::Arc; +use tokio::{task, time}; +use std::collections::{BTreeMap, VecDeque}; extern crate log; pub mod wclip; @@ -27,6 +32,23 @@ pub struct ClipboardMsgs { pub msgs: Vec, } +async fn msg_sync(ctx:Arc>){ + let mut ctx = ctx.lock().await; + loop{ + let _ = ctx.update_msg().await; + time::sleep(Duration::new(10, 0)).await; + } +} +pub async fn start_msg_sync(ctx:Arc>) -> Result, Box>{ + let handle = task::spawn(msg_sync(ctx)); + Ok(handle) +} + +enum Msg <'a>{ + Msg(&'a str), + Sub((i8, i8, i8, &'a str)), +} + impl ClipboardSync { pub fn new(ip: &str, user_name: &str, password: &str) -> ClipboardSync { ClipboardSync { @@ -39,20 +61,6 @@ impl ClipboardSync { } } - pub async fn run(&mut self) Result<(), Box>{ - self.login()?; - let arctx = Arc::new(Mutex::new(self)); - let ctx = arctx.clone(); - let handle = thread::spawn(move || { - let mut ctx = ctx.lock().unwrap() - loop{ - ctx.update_msg().await; - - } - }) - thread::join(handle).unwrap(); - Ok(()) - } async fn verify(&self) -> Result> { // 开始验证 @@ -124,14 +132,14 @@ impl ClipboardSync { log::trace!("verify Response: {}", resp); } if resp.contains("Copy & Paste") { - self.parse_msg(&resp).await; + self.msg2clip(&resp).await; Ok(()) } else { Err(Box::new(io::Error::new(io::ErrorKind::Other, "登录失败"))) } } - pub asyn fn update_msg(&mut self) -> Result<(), Box> { + pub async fn update_msg(&mut self) -> Result<(), Box> { //http://ssweb/SSWeb/rd/copy_paste.jsp?d-16544-p=1&d-16544-s=2 //d-16544-s 2:时间从靠近现在开始排序 1:时间从最早开始排序 //d-16544-o mesage排序,不要设置 @@ -149,26 +157,81 @@ impl ClipboardSync { headers.insert("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6".parse().unwrap()); let response = self.web.get(url).headers(headers).send().await?; let resp = response.text().await?; - self.parse_msg(&resp).await; + self.msg2clip(&resp).await; Ok(()) } + fn parse_msg<'a>(msg: &'a str) -> Msg { + //x|x|x| -> index|total|magic| + let head = &msg[0..7]; + let body = &msg[7..]; + let text = head.split('|').collect::>(); + if text.len() == 3 && text[0].len() == 1 && text[1].len() == 1 && text[2].len() == 1{ - pub async fn parse_msg(&mut self, html: &str) -> Result> { + let check = head.split('|').filter(|text| { + let text = text.as_bytes(); + if text.len() == 1 { + let text = text[0] as i8; + if text < '!' as i8 && text >= '|' as i8 { + true + } else { + false + } + } else { + false + } + }).collect::>(); + + let index = text[0].as_bytes()[0] as i8; + if index < '!' as i8 && index >= '|' as i8 { + return Msg::Msg(msg) + } + let total = text[1].as_bytes()[1] as i8; + if total < '!' as i8 && total >= '|' as i8 { + return Msg::Msg(msg) + } + let magic = text[2].as_bytes()[1] as i8; + if magic < '!' as i8 && magic >= '|' as i8 { + return Msg::Msg(msg) + } + return Msg::Sub((index, total, magic, body)); + } + return Msg::Msg(msg) + } + pub async fn msg2clip(&mut self, html: &str) { // log::info!("html: {}", html); let document = Html::parse_document(html); let selector = Selector::parse("code").unwrap(); - for element in document.select(&selector) { + let mut clip_text = String::new(); + let mut msg_map = BTreeMap::new(); + let mut magic_ref = 0; + for element in document.select(&selector).into_iter() { //let text = element.text().collect::>().concat(); let text = element.text().collect::(); log::info!("Found: [{}]", text); - if text[0] == '@' && text[6] == '@' { - items = text.split('@').map(|x| x.trim()).collect::>(); - index = items.next(); - index = items.next(); + let msg = ClipboardSync::parse_msg(text.as_str()); + match msg { + Msg::Msg(msg) => { + if magic_ref == 0 { + self.clip.set(&msg); + break; + } + }, + Msg::Sub((index, total, magic, body)) => { + if magic_ref == 0{ + magic_ref = magic; + } else if magic_ref == magic { + msg_map.insert(index, element); + if msg_map.len() == (total - 'a' as i8) as usize { + } + // clip_text.push_str(body); + } else { + break; + } + } } - self.clip.set(&text); - break; } - Ok(ClipboardMsgs { msgs: vec![] }) + if clip_text.len() != 0 { + self.clip.set(&clip_text); + } } } diff --git a/src/main.rs b/src/main.rs index 32e27a3..ed029d3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,8 @@ use trust_dns_resolver::{ config::{ResolverConfig, ResolverOpts}, Resolver, }; +use tokio::sync::{Mutex}; +use std::sync::Arc; #[tokio::main] async fn main() -> Result<(), Box> { @@ -35,6 +37,9 @@ async fn main() -> Result<(), Box> { log::error!("登录失败: {}", e); } } + let ctx = Arc::new(Mutex::new(ins)); + let handle = clipboard_sync::start_msg_sync(ctx.clone()).await.unwrap(); + let _ = handle.await; // 获取 Cookies //if let Some(cookies) = response.headers().get(COOKIE) { // println!("Cookies: {:?}", cookies);