Yet Another Youtube Down Loader

⌈⌋ branch:  yaydl


Check-in [cd315c668a]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:yaydl 0.14.0: preliminary support for VOE's thirdparty servers
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | trunk | release-0.14.0
Files: files | file ages | folders
SHA3-256: cd315c668ac3ded9f5f33f81425dd471eca75409a327f5be3736bb3739d38cd1
User & Date: Cthulhux 2024-02-25 00:45:33
Context
2024-02-25
00:45
yaydl 0.14.0: preliminary support for VOE's thirdparty servers Leaf check-in: cd315c668a user: Cthulhux tags: trunk, release-0.14.0
00:07
yaydl 0.13.1: updated dependencies, removed a warning check-in: 6c17873d8a user: Cthulhux tags: trunk, release-0.13.1
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Cargo.lock.

1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
name = "windows_x86_64_msvc"
version = "0.52.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6"

[[package]]
name = "yaydl"
version = "0.13.1"
dependencies = [
 "anyhow",
 "cienli",
 "clap",
 "env_proxy",
 "fantoccini",
 "indicatif",







|







1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
name = "windows_x86_64_msvc"
version = "0.52.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6"

[[package]]
name = "yaydl"
version = "0.14.0"
dependencies = [
 "anyhow",
 "cienli",
 "clap",
 "env_proxy",
 "fantoccini",
 "indicatif",

Changes to Cargo.toml.

1
2
3
4
5
6
7
8
9
10
11
[package]
name = "yaydl"
description = "yet another youtube (and more) down loader"
version = "0.13.1"
authors = ["Cthulhux <git@tuxproject.de>"]
edition = "2021"
license = "CDDL-1.0"
repository = "https://code.rosaelefanten.org/yaydl"
categories = ["command-line-utilities"]
keywords = ["youtube", "downloading", "video"]




|







1
2
3
4
5
6
7
8
9
10
11
[package]
name = "yaydl"
description = "yet another youtube (and more) down loader"
version = "0.14.0"
authors = ["Cthulhux <git@tuxproject.de>"]
edition = "2021"
license = "CDDL-1.0"
repository = "https://code.rosaelefanten.org/yaydl"
categories = ["command-line-utilities"]
keywords = ["youtube", "downloading", "video"]

Changes to src/handlers.rs.

18
19
20
21
22
23
24

25
26
27
28
29

mod porndoe;
mod spankbang;
mod vidoza;
mod vimeo;
mod vivo;
mod voe;

mod watchmdh;
mod xhamster;
mod youtube;

// Add your own modules here.







>





18
19
20
21
22
23
24
25
26
27
28
29
30

mod porndoe;
mod spankbang;
mod vidoza;
mod vimeo;
mod vivo;
mod voe;
mod voe_catchall;
mod watchmdh;
mod xhamster;
mod youtube;

// Add your own modules here.

Added src/handlers/voe_catchall.rs.



























































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * See the file LICENSE in this distribution for details.
 * A copy of the CDDL is also available via the Internet at
 * http://www.opensource.org/licenses/cddl1.txt
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the contents of the LICENSE file from this
 * distribution.
 */

// Yet Another Youtube Down Loader
// - VOE handler for several other domains. -
//
// Tried and implemented:
// - jayservicestuff.com

use crate::definitions::SiteDefinition;

use anyhow::{anyhow, Result};
use fantoccini::ClientBuilder;
use regex::Regex;
use scraper::{Html, Selector};
use std::{thread, time};
use tokio::runtime;

use crate::VIDEO;

fn get_video_info(video: &mut VIDEO, url: &str, webdriver_port: u16) -> Result<bool> {
    if video.info.is_empty() {
        // We need to fetch the video information first.
        // It will contain the whole body for now.
        let local_url = url.to_owned();

        let rt = runtime::Builder::new_current_thread()
            .enable_time()
            .enable_io()
            .build()
            .unwrap();
        rt.block_on(async move {
            let webdriver_url = format!("http://localhost:{}", webdriver_port);
            let c = ClientBuilder::native()
                .connect(&webdriver_url)
                .await
                .expect("failed to connect to web driver");
            
            c.goto(&local_url)
                .await
                .expect("could not go to the site URL");

            // Load the video:
            c.execute(
                "document.getElementsByClassName('voe-play')[0].click();",
                vec![],
            )
            .await
                .expect("could not load the video");

            // Wait for a while:
            thread::sleep(time::Duration::from_secs(6));

            let body = c.source().await.expect("could not read the site source");
            video.info.push_str(body.as_str());
            c.close_window().await.expect("could not close the window");
        });
    }

    Ok(true)
}

// Implement the site definition:
struct VoeCatchallHandler;
impl SiteDefinition for VoeCatchallHandler {
    fn can_handle_url<'a>(&'a self, url: &'a str) -> bool {
        Regex::new(r"(?:\.)?jayservicestuff.com/.+").unwrap().is_match(url)
    }

    fn is_playlist<'a>(&'a self, _url: &'a str, _webdriver_port: u16) -> Result<bool> {
        Ok(true)
    }

    fn find_video_title<'a>(
        &'a self,
        video: &'a mut VIDEO,
        url: &'a str,
        webdriver_port: u16,
    ) -> Result<String> {
        let _not_used = get_video_info(video, url, webdriver_port)?;
        let video_info_html = Html::parse_document(video.info.as_str());

        let title_selector = Selector::parse("title").unwrap();
        let text = video_info_html.select(&title_selector).next();

        let result = match text {
            Some(txt) => txt.text().collect(),
            None => return Err(anyhow!("Erroneous video site")),
        };

        Ok(result)
    }

    fn find_video_direct_url<'a>(
        &'a self,
        video: &'a mut VIDEO,
        url: &'a str,
        webdriver_port: u16,
        _onlyaudio: bool,
    ) -> Result<String> {
        let _not_used = get_video_info(video, url, webdriver_port)?;
        let video_info_html = Html::parse_document(video.info.as_str());

        let url_selector = Selector::parse(r#"source[type="application/x-mpegurl"]"#).unwrap();
        let url_elem = video_info_html.select(&url_selector).next().unwrap();
        let url_contents = url_elem.value().attr("src").unwrap();

        print!("{}", url_contents);

        Ok(url_contents.to_string())
    }
    
    fn does_video_exist<'a>(
        &'a self,
        video: &'a mut VIDEO,
        url: &'a str,
        webdriver_port: u16,
    ) -> Result<bool> {
        let _video_info = get_video_info(video, url, webdriver_port);
        Ok(!video.info.is_empty())
    }

    fn display_name<'a>(&'a self) -> String {
        "Voe (Catchall)".to_string()
    }

    fn find_video_file_extension<'a>(
        &'a self,
        _video: &'a mut VIDEO,
        _url: &'a str,
        _webdriver_port: u16,
        _onlyaudio: bool,
    ) -> Result<String> {
        Ok("mp4".to_string())
    }

    fn web_driver_required<'a>(&'a self) -> bool {
        true
    }
}

// Push the site definition to the list of known handlers:
inventory::submit! {
    &VoeCatchallHandler as &dyn SiteDefinition
}