about summary refs log tree commit diff stats
path: root/src/select/selection_file/display.rs
blob: 0714015af91a029d484afe7507cdb1cb0343e54b (plain) (blame)
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
// 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::fmt::Write;

use anyhow::{Context, Result};
use chrono::DateTime;
use log::debug;

use crate::{
    app::App,
    select::selection_file::duration::Duration,
    storage::video_database::{getters::get_video_opts, Video},
};

macro_rules! c {
    ($color:expr, $format:expr) => {
        format!("\x1b[{}m{}\x1b[0m", $color, $format)
    };
}

impl Video {
    pub async fn to_select_file_display(&self, app: &App) -> Result<String> {
        let mut f = String::new();

        let opts = get_video_opts(app, &self.extractor_hash)
            .await
            .with_context(|| format!("Failed to get video options for video: '{}'", self.title))?
            .to_cli_flags(app);
        let opts_white = if !opts.is_empty() { " " } else { "" };

        let publish_date = if let Some(date) = self.publish_date {
            DateTime::from_timestamp(date, 0)
                .expect("This should not fail")
                .format("%Y-%m-%d")
                .to_string()
        } else {
            "[No release date]".to_owned()
        };

        let parent_subscription_name = if let Some(sub) = &self.parent_subscription_name {
            sub.replace('"', "'")
        } else {
            "[No author]".to_owned()
        };

        debug!("Formatting video for selection file: {}", self.title);
        write!(
            f,
            r#"{}{}{} {} "{}" "{}" "{}" "{}" "{}"{}"#,
            self.status.as_command().trim(),
            opts_white,
            opts,
            self.extractor_hash.into_short_hash(app).await?,
            self.title.replace(['"', '„', '”'], "'"),
            publish_date,
            parent_subscription_name,
            Duration::from(self.duration),
            self.url.as_str().replace('"', "\\\""),
            "\n"
        )?;

        Ok(f)
    }

    pub async fn to_color_display_owned(self, app: &App) -> Result<String> {
        self.to_color_display(app).await
    }
    pub async fn to_color_display(&self, app: &App) -> Result<String> {
        let mut f = String::new();

        let publish_date = if let Some(date) = self.publish_date {
            DateTime::from_timestamp(date, 0)
                .expect("This should not fail")
                .format("%Y-%m-%d")
                .to_string()
        } else {
            "[No release date]".to_owned()
        };

        let parent_subscription_name = if let Some(sub) = &self.parent_subscription_name {
            sub.replace('"', "'")
        } else {
            "[No author]".to_owned()
        };

        write!(
            f,
            r#"{} {} {} {} {} {}"#,
            c!("31;1", self.status.as_command()),
            c!("95;3", self.extractor_hash.into_short_hash(app).await?),
            c!("32;1", self.title.replace(['"', '„', '”'], "'")),
            c!("37;1", publish_date),
            c!("34;1", parent_subscription_name),
            c!("35;1", Duration::from(self.duration)),
        )
        .expect("This write should always work");

        Ok(f)
    }
}