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
// settings_data.rs
//
// Copyright 2020-2024 nee <nee-git@hidamari.blue>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-3.0-or-later
use crate::booru::Booru;
use crate::data::*;
use serde::{Deserialize, Serialize};
use std::collections::HashSet;
// TODO rename to Booru and rename the old Booru to BooruDriver
#[derive(Debug)]
pub struct BooruData {
pub booru: Box<dyn Booru>,
pub settings: BooruSettings,
}
impl BooruData {
pub fn clone_data(&self) -> BooruData {
BooruData {
booru: self.booru.clone_booru(),
settings: self.settings.clone(),
}
}
}
// Size for the gtk Ui Image Element
// 360 is the pinephone/librem5 default window width
// 360 / 4, 3, 2
// = 90, 120, 180
// - 2 pixels for borders
pub const DEFAULT_THUMB_SIZE_UI: i32 = 118;
// Size for the texture image, and how it is saved for local
pub const DEFAULT_THUMB_SIZE_IMAGE: i32 = DEFAULT_THUMB_SIZE_UI * 2;
#[derive(Deserialize, Serialize, Debug, Clone)]
#[serde(default)]
pub struct Preferences {
// prefs
pub infinite_scroll: bool,
pub fetch_on_startup: bool,
pub thumb_size: u32,
pub save_new_tags_to_tagdb: bool,
}
impl Default for Preferences {
fn default() -> Self {
Self {
infinite_scroll: false,
fetch_on_startup: false,
thumb_size: DEFAULT_THUMB_SIZE_UI as u32,
save_new_tags_to_tagdb: false,
}
}
}
#[derive(Deserialize, Serialize)]
pub struct SettingsFile {
pub boorus: Vec<(String, BooruSettings)>,
pub active_booru: Option<String>,
pub used_tags: Vec<String>,
pub favourite_tags: Vec<String>,
pub muted_tags: Vec<String>,
pub saved_searches: Vec<SavedSearch>,
#[serde(default)]
pub preferences: Preferences,
}
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
// decides how viewed images are saved
pub enum ViewStorage {
ByDate(u32), // mark everything before the date as viewed
#[default]
Individual, // store every post-id that was viewed
No, // don't track viewed posts
}
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct BooruSettings {
pub view_storage: ViewStorage,
pub viewed: HashSet<u64>,
pub max_search_tags: u32,
pub additional_requests: AdditionRequestSettings,
}
// Wether additional automatic requests should be done
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct AdditionRequestSettings {
unknown_tags: bool,
web_source: bool,
}
fn default_true() -> bool {
true
}
#[derive(Debug, Clone, Default, Deserialize, Serialize)]
pub struct SavedSearch {
pub search: String,
pub booru_allowlist: Vec<String>, // empty = no allowlist
#[serde(default = "default_true")]
pub auto_load: bool,
}
pub fn read_settings() -> Option<SettingsFile> {
let mut path = gtk::glib::user_config_dir();
path.push("boorus/settings.json");
let buffer = std::fs::File::open(path.as_path()).ok()?;
let mut settings: SettingsFile = serde_json::from_reader(buffer).ok()?;
// force validate the thumb size
settings.preferences.thumb_size = validate_thumb_size(settings.preferences.thumb_size);
Some(settings)
}
pub fn validate_thumb_size(thumb_size_arg: u32) -> u32 {
(thumb_size_arg as i32).clamp(MIN_THUMB_SIZE, MAX_THUMB_SIZE) as u32
}
pub fn write_settings(state: &State) -> Option<SettingsFile> {
let mut path = gtk::glib::user_config_dir();
path.push("boorus");
std::fs::create_dir_all(&path).ok()?;
path.push("settings.json");
let buffer = std::fs::File::create(path.as_path()).ok()?;
let settings = SettingsFile {
boorus: state
.boorus
.iter()
.filter(|b| b.booru.get_domain() != "__builtin_localbooru")
.map(|b| (b.booru.get_domain().clone(), b.settings.clone()))
.collect(),
active_booru: state.active_booru.clone(),
used_tags: vec![],
favourite_tags: vec![],
muted_tags: vec![],
saved_searches: state.saved_searches.clone(),
preferences: state.preferences.clone(),
};
serde_json::to_writer_pretty(buffer, &settings).ok()?;
Some(settings)
}