View | Details | Raw Unified | Return to bug 52839
Collapse All | Expand All

(-)a/src/online.rs (-133 / +219 lines)
Lines 11-16 Link Here
11
    pub name: String,
11
    pub name: String,
12
    pub version: Option<String>,
12
    pub version: Option<String>,
13
    pub url: String,
13
    pub url: String,
14
    pub variant: String
14
}
15
}
15
16
16
pub fn get_osinfodb_url() -> Option<String> {
17
pub fn get_osinfodb_url() -> Option<String> {
Lines 78-224 Link Here
78
82
79
    use rayon::prelude::*;
83
    use rayon::prelude::*;
80
84
81
    let (amd, arm): (Vec<Option<Distro>>, Vec<Option<Distro>>) = GOOD_DISTROS
85
    let distros: Vec<(Vec<Option<Distro>>, Vec<Option<Distro>>)> = GOOD_DISTROS
82
        .into_par_iter()
86
        .into_par_iter()
83
        .map(|(distro, distro_name, filter)| {
87
        .map(|(distro, _, filter)| {
84
            let files = std::fs::read_dir(temp_dir.join(distro)).unwrap();
88
        let files = std::fs::read_dir(temp_dir.join(distro)).unwrap();
85
89
86
            let y = files
90
        let y: (Vec<Option<Distro>>, Vec<Option<Distro>>) = files
87
                .flatten()
91
            .flatten()
88
                .flat_map(|file| {
92
            .flat_map(|file| {
89
                    let content = std::fs::read_to_string(file.path()).unwrap();
93
                let content = std::fs::read_to_string(file.path())
90
                    let doc = roxmltree::Document::parse(&content).unwrap();
94
                    .expect("Cannot read xml");
91
95
                let doc = roxmltree::Document::parse(&content)
92
                    let os_element = doc.descendants().find(|d| d.has_tag_name("os")).unwrap();
96
                    .expect("Cannot parse document");
93
97
94
                    let release_date = os_element
98
                let os_element = doc.descendants().find(|d| d.has_tag_name("os")).unwrap();
95
                        .children()
99
96
                        .find(|d| d.has_tag_name("release-date"))
100
                let release_date = os_element
97
                        .map(|rd| {
101
                    .children()
98
                            let (year, month, day) = rd
102
                    .find(|d| d.has_tag_name("release-date"))
103
                    .map(|rd| {
104
                        let (year, month, day) = rd
105
                            .text()
106
                            .unwrap()
107
                            .split('-')
108
                            .map(|x| x.parse::<u32>().unwrap())
109
                            .collect_tuple()
110
                            .unwrap();
111
                        chrono::NaiveDate::from_ymd_opt(year as i32, month, day).unwrap()
112
                    });
113
                let release_status = os_element
114
                    .children()
115
                    .find(|d| d.has_tag_name("release-status"))
116
                    .map(|rs| rs.text().unwrap().to_string());
117
118
                let name = os_element
119
                    .children()
120
                    .find(|d| d.has_tag_name("name"))
121
                    .unwrap()
122
                    .text()
123
                    .unwrap()
124
                    .to_string();
125
126
                let version = os_element
127
                    .children()
128
                    .find(|d| d.has_tag_name("version"))
129
                    .and_then(|x| x.text().map(|x| x.to_owned()));
130
131
                let variants = os_element
132
                    .children()
133
                    .filter(|d| d.has_tag_name("variant"))
134
                    .map(|d| {
135
                        (
136
                            d.attribute("id").unwrap().to_string(),
137
                            d.descendants()
138
                                .find(|n| n.has_tag_name("name"))
139
                                .map(|n| n.text().unwrap().to_string())
140
                                .unwrap_or(name.clone()),
141
                        )
142
                    })
143
                    .collect::<HashMap<_, _>>();
144
145
                let medias = os_element
146
                    .children()
147
                    .filter(|d| {
148
                        d.has_tag_name("media")
149
                            && (d.attribute("arch") == Some("x86_64")
150
                                || d.attribute("arch") == Some("aarch64"))
151
                            && d.descendants()
152
                            .any(|u| u.has_tag_name("url") && !u.text().unwrap().is_empty())
153
                    })
154
                    .map(|m| {
155
                        (
156
                            m.children()
157
                                .find(|d| d.has_tag_name("variant"))
158
                                .map(|n| {
159
                                    variants.get(n.attribute("id").unwrap()).unwrap().to_owned()
160
                                })
161
                                .unwrap_or(name.clone()),
162
                            m.attribute("arch").unwrap(),
163
                            m.descendants()
164
                                .find(|d| d.has_tag_name("url"))
165
                                .unwrap()
99
                                .text()
166
                                .text()
100
                                .unwrap()
167
                                .unwrap()
101
                                .split('-')
168
                                .to_string(),
102
                                .map(|x| x.parse::<u32>().unwrap())
169
                        )
103
                                .collect_tuple()
170
                    })
104
                                .unwrap();
171
                    .collect_vec();
105
                            chrono::NaiveDate::from_ymd_opt(year as i32, month, day).unwrap()
172
106
                        });
173
                let distros: Vec<(Option<Distro>, Option<Distro>)> = medias
107
                    let release_status = os_element
174
                    .into_iter()
108
                        .children()
175
                    .map(|media| {
109
                        .find(|d| d.has_tag_name("release-status"))
176
                        Some((
110
                        .map(|rs| rs.text().unwrap().to_string());
177
                            media.0,  // name
111
178
                            media.1,  // arch
112
                    let name = os_element
179
                            media.2,  // url
113
                        .children()
180
                            release_date.clone(),
114
                        .find(|d| d.has_tag_name("name"))
181
                            release_status.clone(),
115
                        .unwrap()
182
                            version.clone(),
116
                        .text()
183
                        ))
117
                        .unwrap()
184
                    })
118
                        .to_string();
185
                    .flatten()
119
186
                    .filter(|(_, _, _, date, status, _)| {
120
                    let version = os_element
187
                        !matches!(status, Some(x) if x == "prerelease")
121
                        .children()
188
                            && (date.is_some() || matches!(status, Some(x) if x == "rolling"))
122
                        .find(|d| d.has_tag_name("version"))
189
                            && (date.is_none()
123
                        .and_then(|x| x.text().map(|x| x.to_owned()));
190
                                || date.unwrap()
124
191
                                + chrono::Duration::try_days(365 * 2)
125
                    let variants = os_element
192
                                .expect("duration is overflow")
126
                        .children()
193
                                >= chrono::offset::Local::now().date_naive())
127
                        .filter(|d| d.has_tag_name("variant"))
194
                    })
128
                        .map(|d| {
195
                    .filter(|(name, _, _, _, _, _)| {
129
                            (
196
                        if let Some(filter) = filter {
130
                                d.attribute("id").unwrap().to_string(),
197
                            filter(name)
131
                                d.descendants()
198
                        } else {
132
                                    .find(|n| n.has_tag_name("name"))
199
                            true
133
                                    .map(|n| n.text().unwrap().to_string())
200
                        }
134
                                    .unwrap_or(name.clone()),
201
                    })
135
                            )
202
                    .filter(|(_, _, _, date, status, _)| {
136
                        })
203
                        !matches!(status, Some(x) if x == "prerelease")
137
                        .collect::<HashMap<_, _>>();
204
                            && (date.is_some() || matches!(status, Some(x) if x == "rolling"))
138
205
                            && (date.is_none()
139
                    let medias = os_element
206
                                || date.unwrap()
140
                        .children()
141
                        .filter(|d| {
142
                            d.has_tag_name("media")
143
                                && (d.attribute("arch") == Some("x86_64")
144
                                    || d.attribute("arch") == Some("aarch64"))
145
                                && d.descendants()
146
                                    .any(|u| u.has_tag_name("url") && !u.text().unwrap().is_empty())
147
                        })
148
                        .map(|m| {
149
                            (
150
                                m.children()
151
                                    .find(|d| d.has_tag_name("variant"))
152
                                    .map(|n| {
153
                                        variants.get(n.attribute("id").unwrap()).unwrap().to_owned()
154
                                    })
155
                                    .unwrap_or(name.clone()),
156
                                m.attribute("arch").unwrap(),
157
                                m.descendants()
158
                                    .find(|d| d.has_tag_name("url"))
159
                                    .unwrap()
160
                                    .text()
161
                                    .unwrap()
162
                                    .to_string(),
163
                            )
164
                        })
165
                        .collect_vec();
166
167
                    let (amd, arm): (Vec<_>, Vec<_>) =
168
                        medias.into_iter().partition_map(|(_, a, url)| match a {
169
                            "x86_64" => itertools::Either::Left(url),
170
                            _ => itertools::Either::Right(url),
171
                        });
172
173
                    Some((
174
                        name,
175
                        amd.into_iter().next()?,
176
                        arm.into_iter().next(),
177
                        release_date,
178
                        release_status,
179
                        version,
180
                    ))
181
                })
182
                .filter(|(_, _, _, date, status, _)| {
183
                    !matches!(status, Some(x) if x == "prerelease")
184
                        && (date.is_some() || matches!(status, Some(x) if x == "rolling"))
185
                        && (date.is_none()
186
                            || date.unwrap()
187
                                + chrono::Duration::try_days(365 * 2)
207
                                + chrono::Duration::try_days(365 * 2)
188
                                    .expect("duration is overflow")
208
                                    .expect("duration is overflow")
189
                                >= chrono::offset::Local::now().date_naive())
209
                                >= chrono::offset::Local::now().date_naive())
190
                })
210
                    })
191
                .filter(|(name, _, _, _, _, _)| {
211
                    .filter(|(name, _, _, _, _, _)| {
192
                    println!("{}", name);
212
                        if let Some(filter) = filter {
193
                    if let Some(filter) = filter {
213
                            filter(name)
194
                        filter(name)
214
                        } else {
195
                    } else {
215
                            true
196
                        true
216
                        }
197
                    }
217
                    })
198
                })
218
                    .map(|(name, arch, url, _, _, version)| {
199
                .max_by_key(|(_, _, _, date, _, _)| date.to_owned())
219
                        let mut variant = String::new();
200
                .map(|(_, amd, arm, _, _, version)| {
220
201
                    (
221
                        for (k, v) in &variants {
202
                        Distro {
222
                            if name == *v {
203
                            name: distro_name.to_owned(),
223
                                variant = k.to_string();
204
                            version: version.clone(),
224
                                break;
205
                            url: amd,
225
                            }
206
                        },
226
                        }
207
                        arm.map(|arm| Distro {
227
208
                            name: distro_name.to_owned(),
228
                        (
209
                            version: version.clone(),
229
                            arch,
210
                            url: arm,
230
                            Distro {
211
                        }),
231
                                name,
212
                    )
232
                                version,
213
                })
233
                                url,
214
                .unzip();
234
                                variant
215
235
                            }
216
            (y.0, y.1.flatten())
236
                        )
217
        })
237
                    })
218
        .unzip();
238
                    .map(|(arch, distro)| {
239
                        match arch {
240
                            "x86_64" => (Some(distro), None),
241
                            _ => (None, Some(distro))
242
                        }
243
                    }).collect();
244
245
                distros
246
            }).collect();
247
248
        let mut amd: HashMap<String, Distro> = HashMap::new();
249
        let mut arm: HashMap<String, Distro> = HashMap::new();
250
251
        for item in y.0 {
252
            if let Some(distro) = item {
253
                if !amd.contains_key(&distro.variant) {
254
                    amd.insert(distro.variant.to_owned(), distro);
255
                } else {
256
                    let ds = amd.get_mut(&distro.variant).unwrap();
257
                    *ds = distro;
258
                }
259
            }
260
        }
261
262
        for item in y.1 {
263
            if let Some(distro) = item {
264
                if !arm.contains_key(&distro.variant) {
265
                    arm.insert(distro.variant.to_owned(), distro);
266
                } else {
267
                    let ds = arm.get_mut(&distro.variant).unwrap();
268
                    *ds = distro;
269
                }
270
            }
271
        }
272
273
        let amd: Vec<Option<Distro>> = amd
274
            .into_iter()
275
            .map(|(_, v)|{
276
                Some(v)
277
            }).collect();
278
279
        let arm: Vec<Option<Distro>> = arm
280
            .into_iter()
281
            .map(|(_, v)|{
282
                Some(v)
283
            }).collect();
284
285
        (amd, arm)
286
    }).collect();
287
288
    let (amd, arm): (Vec<Vec<Distro>>, Vec<Vec<Distro>>) = distros
289
        .into_iter()
290
        .map(|distro| {
291
            let mut amd = Vec::<Distro>::new();
292
            let mut arm = Vec::<Distro>::new();
293
294
            for elem in distro.0 {
295
                if let Some(elem) = elem {
296
                    amd.push(elem);
297
                }
298
            }
299
300
            for elem in distro.1 {
301
                if let Some(elem) = elem {
302
                    arm.push(elem);
303
                }
304
            }
305
306
            (amd, arm)
307
        }).unzip();
219
308
220
    Some((
309
    Some((
221
        amd.into_iter().flatten().collect(),
310
        amd.into_iter().flatten().collect::<Vec<_>>(),
222
        arm.into_iter().flatten().collect(),
311
        arm.into_iter().flatten().collect::<Vec<_>>()
223
    ))
312
    ))
224
}
313
}
(-)a/src/window.rs (-1 / +1 lines)
Lines 641-646 Link Here
641
641
642
    fn load_distros(&self, target: &TemplateChild<gtk::ListBox>, distros: Vec<Distro>) {
642
    fn load_distros(&self, target: &TemplateChild<gtk::ListBox>, distros: Vec<Distro>) {
643
        target.remove_all();
643
        target.remove_all();
644
        for Distro { name, version, url } in distros {
644
        for Distro { name, version, url, .. } in distros {
645
            let action_row = adw::ActionRow::new();
645
            let action_row = adw::ActionRow::new();
646
            action_row.set_title(&name);
646
            action_row.set_title(&name);
647
            if let Some(subtitle) = version {
647
            if let Some(subtitle) = version {

Return to bug 52839