1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
// yt - A fully featured command line YouTube client
//
// Copyright (C) 2024 Benedikt Peetz <benedikt.peetz@b-peetz.de>
// SPDX-License-Identifier: GPL-3.0-or-later
//
// This file is part of Yt.
//
// You should have received a copy of the License along with this program.
// If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>.
use std::collections::HashMap;
use anyhow::Result;
use libmpv2::{events::PlaylistEntryId, mpv_node::MpvNode, Mpv};
use crate::storage::video_database::extractor_hash::ExtractorHash;
#[derive(Debug, Default)]
pub struct PlaylistHandler {
/// A map of the original file paths to the videos extractor hashes.
/// Used to get the extractor hash from a video returned by mpv
playlist_cache: HashMap<String, ExtractorHash>,
/// A map of the playlist_entry_id field to their corresponding extractor hashes.
playlist_ids: HashMap<PlaylistEntryId, ExtractorHash>,
}
impl PlaylistHandler {
pub fn from_cache(cache: HashMap<String, ExtractorHash>) -> Self {
Self {
playlist_cache: cache,
playlist_ids: HashMap::new(),
}
}
pub fn reserve(&mut self, len: usize) {
self.playlist_cache.reserve(len)
}
pub fn add(&mut self, cache_path: String, extractor_hash: ExtractorHash) {
assert_eq!(
self.playlist_cache.insert(cache_path, extractor_hash),
None,
"Only new video should ever be added"
);
}
pub fn playlist_ids(&mut self, mpv: &Mpv) -> Result<&HashMap<PlaylistEntryId, ExtractorHash>> {
let mpv_playlist: Vec<(String, PlaylistEntryId)> = match mpv.get_property("playlist")? {
MpvNode::ArrayIter(array) => array
.map(|val| match val {
MpvNode::MapIter(map) => {
struct BuildPlaylistEntry {
filename: Option<String>,
id: Option<PlaylistEntryId>,
}
let mut entry = BuildPlaylistEntry {
filename: None,
id: None,
};
map.for_each(|(key, value)| match key.as_str() {
"filename" => {
entry.filename = Some(value.str().expect("work").to_owned())
}
"id" => {
entry.id = Some(PlaylistEntryId::new(value.i64().expect("Works")))
}
_ => (),
});
(entry.filename.expect("is some"), entry.id.expect("is some"))
}
_ => unreachable!(),
})
.collect(),
_ => unreachable!(),
};
let mut playlist: HashMap<PlaylistEntryId, ExtractorHash> =
HashMap::with_capacity(mpv_playlist.len());
for (path, key) in mpv_playlist {
let hash = self
.playlist_cache
.get(&path)
.expect("All path should also be stored in the cache")
.to_owned();
playlist.insert(key, hash);
}
for (id, hash) in playlist {
self.playlist_ids.entry(id).or_insert(hash);
}
Ok(&self.playlist_ids)
}
}
|