upgrades
This commit is contained in:
@@ -9,6 +9,8 @@ use crate::videos::{ServerOptions, VideoItem};
|
||||
use async_trait::async_trait;
|
||||
use error_chain::error_chain;
|
||||
use htmlentity::entity::{ICodedDataTrait, decode};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::vec;
|
||||
|
||||
pub const CHANNEL_METADATA: crate::providers::ProviderChannelMetadata =
|
||||
@@ -27,14 +29,66 @@ error_chain! {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PornhatProvider {
|
||||
url: String,
|
||||
tag_map: Arc<RwLock<HashMap<String, String>>>,
|
||||
}
|
||||
impl PornhatProvider {
|
||||
pub fn new() -> Self {
|
||||
PornhatProvider {
|
||||
url: "https://www.pornhat.com".to_string(),
|
||||
tag_map: Arc::new(RwLock::new(HashMap::new())),
|
||||
}
|
||||
}
|
||||
|
||||
fn normalize_key(value: &str) -> String {
|
||||
value
|
||||
.trim()
|
||||
.to_ascii_lowercase()
|
||||
.replace(['_', '-'], " ")
|
||||
.split_whitespace()
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ")
|
||||
}
|
||||
|
||||
fn humanize_slug(value: &str) -> String {
|
||||
value
|
||||
.trim_matches('/')
|
||||
.replace('-', " ")
|
||||
.split_whitespace()
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ")
|
||||
}
|
||||
|
||||
fn insert_tag_mapping(&self, kind: &str, slug: &str, title: Option<&str>) {
|
||||
let slug = slug.trim().trim_matches('/');
|
||||
if slug.is_empty() {
|
||||
return;
|
||||
}
|
||||
let path = format!("{kind}/{slug}");
|
||||
if let Ok(mut map) = self.tag_map.write() {
|
||||
map.insert(Self::normalize_key(slug), path.clone());
|
||||
let normalized_title = Self::normalize_key(title.unwrap_or(slug));
|
||||
if !normalized_title.is_empty() {
|
||||
map.insert(normalized_title, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_query_path(&self, query: &str) -> Option<String> {
|
||||
let trimmed = query.trim().trim_start_matches('@');
|
||||
if let Some((kind, raw_value)) = trimmed.split_once(':') {
|
||||
let kind = kind.trim().to_ascii_lowercase();
|
||||
let value = raw_value.trim().trim_matches('/').replace(' ', "-");
|
||||
if !value.is_empty() && matches!(kind.as_str(), "sites" | "models") {
|
||||
return Some(format!("{kind}/{value}"));
|
||||
}
|
||||
}
|
||||
let normalized = Self::normalize_key(trimmed);
|
||||
if normalized.is_empty() {
|
||||
return None;
|
||||
}
|
||||
self.tag_map.read().ok()?.get(&normalized).cloned()
|
||||
}
|
||||
|
||||
fn build_channel(&self, _clientversion: ClientVersion) -> Channel {
|
||||
Channel {
|
||||
id: "pornhat".to_string(),
|
||||
@@ -127,16 +181,8 @@ impl PornhatProvider {
|
||||
) -> Result<Vec<VideoItem>> {
|
||||
let search_string = query.to_lowercase().trim().replace(" ", "-");
|
||||
let mut video_url = format!("{}/search/{}/{}/", self.url, search_string, page);
|
||||
|
||||
if search_string.starts_with("@") {
|
||||
let url_part = search_string
|
||||
.split("@")
|
||||
.collect::<Vec<&str>>()
|
||||
.get(1)
|
||||
.copied()
|
||||
.unwrap_or_default()
|
||||
.replace(":", "/");
|
||||
video_url = format!("{}/{}/", self.url, url_part);
|
||||
if let Some(path) = self.resolve_query_path(query) {
|
||||
video_url = format!("{}/{}/{}/", self.url, path, page);
|
||||
}
|
||||
// Check our Video Cache. If the result is younger than 1 hour, we return it.
|
||||
let old_items = match cache.get(&video_url) {
|
||||
@@ -296,7 +342,8 @@ impl PornhatProvider {
|
||||
.collect::<Vec<String>>();
|
||||
for tag in raw_tags {
|
||||
if !tag.is_empty() {
|
||||
tags.push(format!("@sites:{}", tag));
|
||||
self.insert_tag_mapping("sites", &tag, None);
|
||||
tags.push(Self::humanize_slug(&tag));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -316,7 +363,8 @@ impl PornhatProvider {
|
||||
.collect::<Vec<String>>();
|
||||
for tag in raw_tags {
|
||||
if !tag.is_empty() {
|
||||
tags.push(format!("@models:{}", tag));
|
||||
self.insert_tag_mapping("models", &tag, None);
|
||||
tags.push(Self::humanize_slug(&tag));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user