mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-18 07:48:02 +08:00
* move nix flake to root * cargo run tool * use thiserror in third-party-licenses tool * prefere panic over exit * Add automatic dependency check to cargo run tool * Skip dependecies that are not needed for the current task * Fixup * Fixup * fix windows * Fixup * improve usage text * Fix linux bundle * add graphen-cli * fix build profile * fix * release profile should not include debug infos * Review * remove profiling profile was redundent with release * rename to cargo-run tool * improve consistency * rename deps to requirements * fix * return success when showing usage
93 lines
2.7 KiB
Rust
93 lines
2.7 KiB
Rust
use lzma_rust2::XzReader;
|
|
use scraper::{Html, Selector};
|
|
use std::fs;
|
|
use std::hash::Hash;
|
|
use std::io::Read;
|
|
use std::path::PathBuf;
|
|
|
|
use crate::{Error, LicenceSource, LicenseEntry, Package};
|
|
|
|
pub struct CefLicenseSource;
|
|
|
|
impl CefLicenseSource {
|
|
pub fn new() -> Self {
|
|
Self {}
|
|
}
|
|
}
|
|
|
|
impl LicenceSource for CefLicenseSource {
|
|
fn licenses(&self) -> Result<Vec<LicenseEntry>, Error> {
|
|
let html = read()?;
|
|
Ok(parse(&html))
|
|
}
|
|
}
|
|
|
|
impl Hash for CefLicenseSource {
|
|
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
|
read().unwrap().hash(state)
|
|
}
|
|
}
|
|
|
|
fn parse(html: &str) -> Vec<LicenseEntry> {
|
|
let document = Html::parse_document(html);
|
|
|
|
let product_sel = Selector::parse("div.product").unwrap();
|
|
let title_sel = Selector::parse("span.title").unwrap();
|
|
let homepage_sel = Selector::parse("span.homepage a").unwrap();
|
|
let license_sel = Selector::parse("div.license pre").unwrap();
|
|
|
|
document
|
|
.select(&product_sel)
|
|
.filter_map(|product| {
|
|
let name: String = product.select(&title_sel).next().map(|el| el.text().collect()).unwrap_or_default();
|
|
|
|
if name.is_empty() {
|
|
return None;
|
|
}
|
|
|
|
let homepage = product.select(&homepage_sel).next().and_then(|el| el.value().attr("href").map(String::from));
|
|
|
|
let license_text: String = product.select(&license_sel).next().map(|el| el.text().collect::<String>()).unwrap_or_default().trim().to_string();
|
|
|
|
let pkg = Package {
|
|
name,
|
|
url: homepage,
|
|
authors: Vec::new(),
|
|
};
|
|
|
|
Some(LicenseEntry {
|
|
name: None,
|
|
text: license_text,
|
|
packages: vec![pkg],
|
|
})
|
|
})
|
|
.collect()
|
|
}
|
|
|
|
fn read() -> Result<String, Error> {
|
|
let cef_path = PathBuf::from(env!("CEF_PATH"));
|
|
let cef_credits = std::fs::read_dir(&cef_path)
|
|
.map_err(|e| Error::Io(e, format!("Failed to read CEF_PATH directory {}", cef_path.display())))?
|
|
.filter_map(|entry| entry.ok())
|
|
.find(|entry| {
|
|
let name = entry.file_name();
|
|
name.eq_ignore_ascii_case("credits.html") || name.eq_ignore_ascii_case("credits.html.xz")
|
|
})
|
|
.map(|entry| entry.path())
|
|
.ok_or_else(|| Error::CefCreditsNotFound(cef_path.clone()))?;
|
|
|
|
let decompress_xz = cef_credits.extension().map(|ext| ext.eq_ignore_ascii_case("xz")).unwrap_or(false);
|
|
|
|
if decompress_xz {
|
|
let file = fs::File::open(&cef_credits).map_err(|e| Error::Io(e, format!("Failed to open CEF credits file {}", cef_credits.display())))?;
|
|
let mut reader = XzReader::new(file, false);
|
|
let mut html = String::new();
|
|
reader
|
|
.read_to_string(&mut html)
|
|
.map_err(|e| Error::Io(e, format!("Failed to decompress CEF credits file {}", cef_credits.display())))?;
|
|
Ok(html)
|
|
} else {
|
|
fs::read_to_string(&cef_credits).map_err(|e| Error::Io(e, format!("Failed to read CEF credits file {}", cef_credits.display())))
|
|
}
|
|
}
|