rsget_lib 0.3.0

Library to get information about and download livestreams
Documentation
use crate::Streamable;
use regex::Regex;

use crate::utils::error::StreamError;

use chrono::prelude::*;

use stream_lib::StreamType;

use crate::utils::downloaders::DownloadClient;

#[allow(dead_code)]
#[allow(non_snake_case)]
#[derive(Clone, Debug, Deserialize)]
pub struct InkeUser {
    uid: usize,
    nick: String,
    gender: usize,
    city: String,
    level: usize,
    pic: String,
    isfollow: usize,
}

#[allow(dead_code)]
#[allow(non_snake_case)]
#[derive(Clone, Debug, Deserialize)]
pub struct InkeAddr {
    liveid: String,
    stream_addr: String,
    hls_stream_addr: String,
    rtmp_stream_addr: String,
}

#[allow(dead_code)]
#[allow(non_snake_case)]
#[derive(Clone, Debug, Deserialize)]
pub struct InkeLiveInfo {
    slot: usize,
    user: InkeUser,
    online_users: usize,
    name: String,
    city: String,
    pub_stat: usize,
    landscape: usize,
    rotate: usize,
    live_type: String,
    cover_img: String,
    image: String,
    points: usize,
    liveid: usize,
    status: usize,
}

#[allow(dead_code)]
#[allow(non_snake_case)]
#[derive(Clone, Debug, Deserialize)]
pub struct InkeData {
    live_info: InkeLiveInfo,
    room_type: String,
    public_live_info: Option<String>,
    live_addr: Vec<InkeAddr>,
    lived_addr: Vec<InkeAddr>,
}

#[allow(dead_code)]
#[allow(non_snake_case)]
#[derive(Clone, Debug, Deserialize)]
pub struct InkeStruct {
    error_code: usize,
    message: String,
    data: InkeData,
}

#[derive(Clone, Debug)]
pub struct Inke {
    pub url: String,
    pub room_id: String,
    pub inke_info: InkeStruct,
    client: DownloadClient,
}

impl Streamable for Inke {
    fn new(url: String) -> Result<Box<Inke>, StreamError> {
        let dc = DownloadClient::new()?;
        let re_inke: Regex =
            Regex::new(r"^(?:https?://)?(?:www\.)?inke\.cn/live\.html\?uid=([0-9]+)").unwrap();
        let cap = re_inke.captures(&url).unwrap();
        let json_url = format!("http://baseapi.busi.inke.cn/live/LiveInfo?uid={}", &cap[1]);
        let json_req = dc.make_request(&json_url, None)?;
        let jres = dc.download_and_de::<InkeStruct>(json_req);
        match jres {
            Ok(jre) => {
                let ik = Inke {
                    url: String::from(url.as_str()),
                    room_id: String::from(&cap[1]),
                    inke_info: jre,
                    client: dc,
                };
                debug!("{:#?}", ik);
                Ok(Box::new(ik))
            }
            Err(why) => Err(why),
        }
    }

    fn get_title(&self) -> Option<String> {
        Some(self.inke_info.data.live_info.name.clone())
    }

    fn get_author(&self) -> Option<String> {
        Some(self.inke_info.data.live_info.user.nick.clone())
    }

    fn is_online(&self) -> bool {
        self.inke_info.error_code == 0
    }

    fn get_stream(&self) -> Result<StreamType, StreamError> {
        Ok(StreamType::Chuncked(
            self.client
                .rclient
                .get(&self.inke_info.data.live_addr[0].stream_addr)
                .build()?,
        ))
    }

    fn get_ext(&self) -> String {
        String::from("flv")
    }

    fn get_default_name(&self) -> String {
        let local: DateTime<Local> = Local::now();
        format!(
            "{}-{:04}-{:02}-{:02}-{:02}-{:02}-{}-{}.{}",
            self.room_id,
            local.year(),
            local.month(),
            local.day(),
            local.hour(),
            local.minute(),
            self.get_author().unwrap(),
            self.get_title().unwrap(),
            self.get_ext()
        )
    }
    fn get_reqwest_client(&self) -> &reqwest::Client {
        &self.client.rclient
    }
}