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
use crate::prompt::prompt;
use log::info;
use serde::{Deserialize, Serialize};
use serde_json;
use std::error::Error;
use std::fs::{self, DirBuilder};
use std::path::Path;

const DATA_DIR: &str = "./data";
const CACHE_DIR: &str = "./data/cache";
const DB_PATH: &str = "./data/telepAIr.json";

// Define your application data structure
#[derive(Serialize, Deserialize, Default)]
struct AppData {
    api_id: i32,
    api_hash: String,
    chat_ids: Vec<i64>,
    #[serde(default = "default_whisper_model")]
    whisper_model: String,
}

fn default_whisper_model() -> String {
    "BaseEn".to_string()
}

impl AppData {
    // CRUD operations for chat IDs
    fn add_chat_id(&mut self, chat_id: i64) {
        self.chat_ids.push(chat_id);
    }

    fn remove_chat_id(&mut self, chat_id: i64) {
        self.chat_ids.retain(|&id| id != chat_id);
    }

    fn update_chat_id(&mut self, old_id: i64, new_id: i64) {
        if let Some(pos) = self.chat_ids.iter().position(|&id| id == old_id) {
            self.chat_ids[pos] = new_id;
        }
    }

    fn get_chat_ids(&self) -> Vec<i64> {
        self.chat_ids.clone()
    }
}

// Public interface for interacting with the data store
pub struct Database {
    data: AppData,
}

impl Database {
    pub fn new() -> Self {
        if Path::new(DB_PATH).exists() {
            Database {
                data: serde_json::from_str(&fs::read_to_string(DB_PATH).unwrap()).unwrap(),
            }
        } else {
            info!("Create Telegram Application Credentials: ");
            info!("https://core.telegram.org/api/obtaining_api_id");
            if !Path::new(DATA_DIR).exists() || !Path::new(CACHE_DIR).exists() {
                Database::create_data_dirs();
            }

            let api_id: i32 = std::env::var("TELEGRAM_API_ID")
                .or_else(|_| prompt("Telegram api_id: ").map_err(|e| Box::new(e) as Box<dyn Error>))
                .expect("Unable to continue without a Telegram api_id.")
                .parse::<i32>()
                .unwrap();

            let api_hash = std::env::var("TELEGRAM_API_HASH")
                .or_else(|_| {
                    prompt("Telegram api_hash: ").map_err(|e| Box::new(e) as Box<dyn Error>)
                })
                .expect("Unable to continue without a Telegram api_hash.");

            // Add chat_ids environment variable and parse it into a vector of i64
            let chat_ids_str = std::env::var("CHAT_IDS")
                .ok()
                .unwrap_or_else(|| String::new());

            let chat_ids: Vec<i64> = if chat_ids_str.is_empty() {
                Vec::new()
            } else {
                chat_ids_str
                    .split(',')
                    .map(|s| s.trim().parse::<i64>().unwrap())
                    .collect()
            };

            let whisper_model = std::env::var("WHISPER_MODEL")
                .ok()
                .unwrap_or_else(|| "BaseEn".to_owned());

            Database {
                data: AppData {
                    api_id,
                    api_hash,
                    chat_ids,
                    whisper_model,
                },
            }
        }
    }

    pub fn create_data_dirs() {
        DirBuilder::new().recursive(true).create(CACHE_DIR).unwrap();
    }

    // Save data to file
    pub fn save(&self) {
        fs::write(DB_PATH, serde_json::to_string(&self.data).unwrap()).unwrap();
    }

    pub fn add_chat_id(&mut self, chat_id: i64) {
        self.data.add_chat_id(chat_id);
        self.save();
    }

    pub fn remove_chat_id(&mut self, chat_id: i64) {
        self.data.remove_chat_id(chat_id);
        self.save();
    }

    pub fn update_chat_id(&mut self, old_id: i64, new_id: i64) {
        self.data.update_chat_id(old_id, new_id);
        self.save();
    }

    pub fn get_chat_ids(&self) -> Vec<i64> {
        self.data.get_chat_ids()
    }

    pub fn chat_id_exists(&self, id: &i64) -> bool {
        self.data.chat_ids.contains(id)
    }

    pub fn get_api_id(&self) -> i32 {
        self.data.api_id
    }

    pub fn get_api_hash(&self) -> &String {
        &self.data.api_hash
    }

    pub fn get_whisper_model(&self) -> &String {
        &self.data.whisper_model
    }

    pub fn set_whisper_model(&mut self, new_model: &str) -> String {
        self.data.whisper_model = new_model.to_owned();
        self.save();

        format!("Set whisper model to: {}", new_model)
    }
}