client version check on api

This commit is contained in:
Simon
2025-06-10 08:42:16 +00:00
parent 2a912a4010
commit 8cd404d6b1

View File

@@ -1,3 +1,5 @@
use std::cmp::Ordering;
use htmlentity::types::Byte;
use ntex::http::header; use ntex::http::header;
use ntex::web; use ntex::web;
use ntex::web::HttpRequest; use ntex::web::HttpRequest;
@@ -8,6 +10,80 @@ use crate::providers::spankbang::SpankbangProvider;
use crate::util::cache::VideoCache; use crate::util::cache::VideoCache;
use crate::{providers::*, status::*, videos::*, DbPool}; use crate::{providers::*, status::*, videos::*, DbPool};
#[derive(Debug)]
struct ClientVersion{
version: u32,
subversion: u32,
name: String,
}
impl ClientVersion {
pub fn new(version: u32, subversion: u32, name: String) -> ClientVersion{
ClientVersion{
version,
subversion,
name
}
}
pub fn parse(input: &str) -> Option<Self> {
// Example input: "Hot%20Tub/22c CFNetwork/1494.0.7 Darwin/23.4.0 0.002478"
let parts: Vec<&str> = input.split_whitespace().collect();
if let Some(first) = parts.first() {
let name_version: Vec<&str> = first.split('/').collect();
let name = name_version[1];
// Extract version and optional subversion
let (version, subversion) = if let Some((v, c)) = name.split_at(name.len().saturating_sub(1)).into() {
match v.parse::<u32>() {
Ok(ver) => (ver, c.chars().next().map(|ch| ch as u32).unwrap_or(0)),
Err(_) => {
// Try parsing whole string if no subversion exists
match name.parse::<u32>() {
Ok(ver) => (ver, 0),
Err(_) => return None,
}
}
}
} else {
return None;
};
return Some(ClientVersion {
version: version,
subversion: subversion,
name: name.to_string(),
});
}
None
}
}
// Implement comparisons
impl PartialEq for ClientVersion {
fn eq(&self, other: &Self) -> bool {
self.name == other.name
}
}
impl Eq for ClientVersion {}
impl PartialOrd for ClientVersion {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for ClientVersion {
fn cmp(&self, other: &Self) -> Ordering {
self.version
.cmp(&other.version)
.then_with(|| self.subversion.cmp(&other.subversion))
}
}
pub fn config(cfg: &mut web::ServiceConfig) { pub fn config(cfg: &mut web::ServiceConfig) {
cfg.service( cfg.service(
web::resource("/status") web::resource("/status")
@@ -22,6 +98,16 @@ pub fn config(cfg: &mut web::ServiceConfig) {
} }
async fn status(req: HttpRequest) -> Result<impl web::Responder, web::Error> { async fn status(req: HttpRequest) -> Result<impl web::Responder, web::Error> {
let clientversion: ClientVersion = match req.headers().get("User-Agent"){
Some(v) => match v.to_str(){
Ok(useragent) => ClientVersion::parse(useragent).unwrap_or_else(|| ClientVersion::new(999, 0, "999".to_string())),
Err(_) => ClientVersion::new(999, 0, "999".to_string())
},
_=> ClientVersion::new(999, 0, "999".to_string())
};
let host = req let host = req
.headers() .headers()
.get(header::HOST) .get(header::HOST)
@@ -29,72 +115,76 @@ async fn status(req: HttpRequest) -> Result<impl web::Responder, web::Error> {
.unwrap_or_default() .unwrap_or_default()
.to_string(); .to_string();
let mut status = Status::new(); let mut status = Status::new();
status.add_channel(Channel {
id: "perverzija".to_string(), if clientversion >= ClientVersion::new(22,97,"22a".to_string()){
name: "Perverzija".to_string(), //add perverzija
description: "Free videos from Perverzija".to_string(), status.add_channel(Channel {
premium: false, id: "perverzija".to_string(),
favicon: "https://www.google.com/s2/favicons?sz=64&domain=tube.perverzija.com".to_string(), name: "Perverzija".to_string(),
status: "active".to_string(), description: "Free videos from Perverzija".to_string(),
categories: vec![], premium: false,
options: vec![ favicon: "https://www.google.com/s2/favicons?sz=64&domain=tube.perverzija.com".to_string(),
// ChannelOption { status: "active".to_string(),
// id: "sort".to_string(), categories: vec![],
// title: "Sort".to_string(), options: vec![
// description: "Sort the Videos".to_string(), //"Sort the videos by Date or Name.".to_string(), // ChannelOption {
// systemImage: "list.number".to_string(), // id: "sort".to_string(),
// colorName: "blue".to_string(), // title: "Sort".to_string(),
// options: vec![ // description: "Sort the Videos".to_string(), //"Sort the videos by Date or Name.".to_string(),
// FilterOption { // systemImage: "list.number".to_string(),
// id: "date".to_string(), // colorName: "blue".to_string(),
// title: "Date".to_string(), // options: vec![
// }, // FilterOption {
// FilterOption { // id: "date".to_string(),
// id: "name".to_string(), // title: "Date".to_string(),
// title: "Name".to_string(), // },
// }, // FilterOption {
// ], // id: "name".to_string(),
// multiSelect: false, // title: "Name".to_string(),
// }, // },
ChannelOption { // ],
id: "featured".to_string(), // multiSelect: false,
title: "Featured".to_string(), // },
description: "Filter Featured Videos.".to_string(), ChannelOption {
systemImage: "star".to_string(), id: "featured".to_string(),
colorName: "red".to_string(), title: "Featured".to_string(),
options: vec![ description: "Filter Featured Videos.".to_string(),
FilterOption { systemImage: "star".to_string(),
id: "all".to_string(), colorName: "red".to_string(),
title: "No".to_string(), options: vec![
}, FilterOption {
FilterOption { id: "all".to_string(),
id: "featured".to_string(), title: "No".to_string(),
title: "Yes".to_string(), },
}, FilterOption {
], id: "featured".to_string(),
multiSelect: false, title: "Yes".to_string(),
}, },
// ChannelOption { ],
// id: "duration".to_string(), multiSelect: false,
// title: "Duration".to_string(), },
// description: "Filter the videos by duration.".to_string(), // ChannelOption {
// systemImage: "timer".to_string(), // id: "duration".to_string(),
// colorName: "green".to_string(), // title: "Duration".to_string(),
// options: vec![ // description: "Filter the videos by duration.".to_string(),
// FilterOption { // systemImage: "timer".to_string(),
// id: "short".to_string(), // colorName: "green".to_string(),
// title: "< 1h".to_string(), // options: vec![
// }, // FilterOption {
// FilterOption { // id: "short".to_string(),
// id: "long".to_string(), // title: "< 1h".to_string(),
// title: "> 1h".to_string(), // },
// }, // FilterOption {
// ], // id: "long".to_string(),
// multiSelect: true, // title: "> 1h".to_string(),
// }, // },
], // ],
nsfw: true, // multiSelect: true,
}); // },
],
nsfw: true,
});
}
status.add_channel(Channel { status.add_channel(Channel {
id: "hanime".to_string(), id: "hanime".to_string(),
name: "Hanime".to_string(), name: "Hanime".to_string(),