mirror of
https://github.com/TeamPiped/sponsorblock-mirror.git
synced 2024-08-14 23:57:05 +00:00
Add support to remove overlaps.
This commit is contained in:
parent
1b9c18ea31
commit
e00d754521
2 changed files with 104 additions and 14 deletions
108
src/routes.rs
108
src/routes.rs
|
@ -28,9 +28,9 @@ pub async fn skip_segments(
|
||||||
|
|
||||||
let hc = hash.clone();
|
let hc = hash.clone();
|
||||||
|
|
||||||
let cat: Vec<String> = serde_json::from_str(categories.unwrap_or("[]")).unwrap();
|
let cat: Vec<String> = serde_json::from_str(categories.unwrap_or("[\"sponsor\"]")).unwrap();
|
||||||
|
|
||||||
if cat.is_empty() && categories.is_some() {
|
if cat.is_empty() {
|
||||||
return content::RawJson(
|
return content::RawJson(
|
||||||
"[]".to_string(),
|
"[]".to_string(),
|
||||||
);
|
);
|
||||||
|
@ -62,26 +62,51 @@ pub async fn skip_segments(
|
||||||
// Create map of Sponsors - Hash, Sponsor
|
// Create map of Sponsors - Hash, Sponsor
|
||||||
let mut sponsors: HashMap<String, Sponsor> = HashMap::new();
|
let mut sponsors: HashMap<String, Sponsor> = HashMap::new();
|
||||||
|
|
||||||
for result in results {
|
for result in &results {
|
||||||
let sponsor = {
|
let sponsor = {
|
||||||
sponsors.entry(result.hashed_video_id.clone()).or_insert(Sponsor {
|
sponsors.entry(result.hashed_video_id.clone()).or_insert(Sponsor {
|
||||||
hash: result.hashed_video_id,
|
hash: result.hashed_video_id.clone(),
|
||||||
video_id: result.video_id,
|
video_id: result.video_id.clone(),
|
||||||
segments: Vec::new(),
|
segments: Vec::new(),
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
sponsor.segments.push(Segment {
|
let segment = Segment {
|
||||||
uuid: result.uuid,
|
uuid: result.uuid.clone(),
|
||||||
action_type: result.action_type,
|
action_type: result.action_type.clone(),
|
||||||
category: result.category,
|
category: result.category.clone(),
|
||||||
description: result.description,
|
description: result.description.clone(),
|
||||||
locked: result.locked,
|
locked: result.locked,
|
||||||
segment: vec![result.start_time, result.end_time],
|
segment: vec![result.start_time, result.end_time],
|
||||||
user_id: result.user_id,
|
user_id: result.user_id.clone(),
|
||||||
video_duration: result.video_duration,
|
video_duration: result.video_duration,
|
||||||
votes: result.votes,
|
votes: result.votes,
|
||||||
});
|
};
|
||||||
|
|
||||||
|
let hash = result.hashed_video_id.clone();
|
||||||
|
|
||||||
|
let mut found_similar = false;
|
||||||
|
|
||||||
|
for seg in &sponsor.segments {
|
||||||
|
if is_overlap(&segment, &seg.category, seg.segment[0], seg.segment[1]) {
|
||||||
|
found_similar = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if found_similar {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut similar_segments = similar_segments(&segment, &hash, &results);
|
||||||
|
similar_segments.push(segment.clone());
|
||||||
|
|
||||||
|
let best_segment = best_segment(&similar_segments);
|
||||||
|
|
||||||
|
// Add if not already in sponsor
|
||||||
|
if !sponsor.segments.contains(&best_segment) {
|
||||||
|
sponsor.segments.push(best_segment);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !sponsors.is_empty() {
|
if !sponsors.is_empty() {
|
||||||
|
@ -102,3 +127,62 @@ pub async fn skip_segments(
|
||||||
|
|
||||||
return content::RawJson(resp);
|
return content::RawJson(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn similar_segments(segment: &Segment, hash: &str, segments: &Vec<SponsorTime>) -> Vec<Segment> {
|
||||||
|
let mut similar_segments: Vec<Segment> = Vec::new();
|
||||||
|
|
||||||
|
for seg in segments {
|
||||||
|
if seg.uuid == segment.uuid {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if seg.hashed_video_id != hash {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let is_similar = is_overlap(segment, &seg.category, seg.start_time, seg.end_time);
|
||||||
|
|
||||||
|
if is_similar {
|
||||||
|
similar_segments.push(Segment {
|
||||||
|
uuid: seg.uuid.clone(),
|
||||||
|
action_type: seg.action_type.clone(),
|
||||||
|
category: seg.category.clone(),
|
||||||
|
description: seg.description.clone(),
|
||||||
|
locked: seg.locked,
|
||||||
|
segment: vec![seg.start_time, seg.end_time],
|
||||||
|
user_id: seg.user_id.clone(),
|
||||||
|
video_duration: seg.video_duration,
|
||||||
|
votes: seg.votes,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
similar_segments
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_overlap(seg: &Segment, cat: &str, start: f32, end: f32) -> bool {
|
||||||
|
if seg.category != cat {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if seg.segment[0] > start && seg.segment[1] < end {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
let overlap = f32::min(seg.segment[1], end) - f32::max(seg.segment[0], start);
|
||||||
|
let duration = f32::max(seg.segment[1], end) - f32::min(seg.segment[0], start);
|
||||||
|
overlap / duration > 0.1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn best_segment(segments: &Vec<Segment>) -> Segment {
|
||||||
|
let mut best_segment = segments[0].clone();
|
||||||
|
let mut best_votes = segments[0].votes;
|
||||||
|
|
||||||
|
for segment in segments {
|
||||||
|
if segment.votes > best_votes {
|
||||||
|
best_segment = segment.clone();
|
||||||
|
best_votes = segment.votes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
best_segment
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
pub struct Sponsor {
|
pub struct Sponsor {
|
||||||
pub hash: String,
|
pub hash: String,
|
||||||
#[serde(rename = "videoID")]
|
#[serde(rename = "videoID")]
|
||||||
|
@ -8,7 +8,7 @@ pub struct Sponsor {
|
||||||
pub segments: Vec<Segment>,
|
pub segments: Vec<Segment>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
pub struct Segment {
|
pub struct Segment {
|
||||||
#[serde(rename = "UUID")]
|
#[serde(rename = "UUID")]
|
||||||
pub uuid: String,
|
pub uuid: String,
|
||||||
|
@ -24,3 +24,9 @@ pub struct Segment {
|
||||||
pub video_duration: f32,
|
pub video_duration: f32,
|
||||||
pub votes: i32,
|
pub votes: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq for Segment {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.uuid == other.uuid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue