mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-04-02 05:23:14 +00:00
working setup flow + manifest localization
This commit is contained in:
@@ -44,28 +44,44 @@ impl DeviceInfo {
|
||||
impl DeviceInfo {
|
||||
pub fn to_header_value(&self) -> HeaderValue {
|
||||
let mut url: Url = "http://localhost".parse().unwrap();
|
||||
url.query_pairs_mut()
|
||||
.append_pair("os.version", &self.os.version.to_string())
|
||||
let mut qp = url.query_pairs_mut();
|
||||
qp.append_pair("os.version", &self.os.version.to_string())
|
||||
.append_pair("os.compat", &self.os.compat.to_string())
|
||||
.append_pair("os.platform", &*self.os.platform);
|
||||
if let Some(lang) = self.os.language.as_deref() {
|
||||
qp.append_pair("os.language", lang);
|
||||
}
|
||||
drop(qp);
|
||||
|
||||
HeaderValue::from_str(url.query().unwrap_or_default()).unwrap()
|
||||
}
|
||||
pub fn from_header_value(header: &HeaderValue) -> Result<Self, Error> {
|
||||
let query: BTreeMap<_, _> = form_urlencoded::parse(header.as_bytes()).collect();
|
||||
let has_hw_info = query.keys().any(|k| k.starts_with("hardware."));
|
||||
let version = query
|
||||
.get("os.version")
|
||||
.or_not_found("os.version")?
|
||||
.parse()?;
|
||||
Ok(Self {
|
||||
os: OsInfo {
|
||||
version: query
|
||||
.get("os.version")
|
||||
.or_not_found("os.version")?
|
||||
.parse()?,
|
||||
compat: query.get("os.compat").or_not_found("os.compat")?.parse()?,
|
||||
platform: query
|
||||
.get("os.platform")
|
||||
.or_not_found("os.platform")?
|
||||
.deref()
|
||||
.into(),
|
||||
language: query
|
||||
.get("os.language")
|
||||
.map(|v| v.deref())
|
||||
.map(InternedString::intern)
|
||||
.or_else(|| {
|
||||
if version < "0.4.0-alpha.18".parse().ok()? {
|
||||
Some(rust_i18n::locale().deref().into())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}),
|
||||
version,
|
||||
},
|
||||
hardware: has_hw_info
|
||||
.then(|| {
|
||||
@@ -190,8 +206,8 @@ pub struct OsInfo {
|
||||
pub version: Version,
|
||||
#[ts(type = "string")]
|
||||
pub compat: VersionRange,
|
||||
#[ts(type = "string")]
|
||||
pub platform: InternedString,
|
||||
pub language: Option<InternedString>,
|
||||
}
|
||||
impl From<&RpcContext> for OsInfo {
|
||||
fn from(_: &RpcContext) -> Self {
|
||||
@@ -199,6 +215,7 @@ impl From<&RpcContext> for OsInfo {
|
||||
version: crate::version::Current::default().semver(),
|
||||
compat: crate::version::Current::default().compat().clone(),
|
||||
platform: InternedString::intern(&*crate::PLATFORM),
|
||||
language: Some(InternedString::intern(&*rust_i18n::locale())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ use crate::context::CliContext;
|
||||
use crate::prelude::*;
|
||||
use crate::registry::context::RegistryContext;
|
||||
use crate::registry::package::index::Category;
|
||||
use crate::s9pk::manifest::LocaleString;
|
||||
use crate::util::serde::{HandlerExtSerde, WithIoFormat, display_serializable};
|
||||
|
||||
pub fn category_api<C: Context>() -> ParentHandler<C> {
|
||||
@@ -66,7 +67,7 @@ pub fn category_api<C: Context>() -> ParentHandler<C> {
|
||||
pub struct AddCategoryParams {
|
||||
#[ts(type = "string")]
|
||||
pub id: InternedString,
|
||||
pub name: String,
|
||||
pub name: LocaleString,
|
||||
}
|
||||
|
||||
pub async fn add_category(
|
||||
@@ -196,7 +197,7 @@ pub fn display_categories<T>(
|
||||
"NAME",
|
||||
]);
|
||||
for (id, info) in categories {
|
||||
table.add_row(row![&*id, &info.name]);
|
||||
table.add_row(row![&*id, &info.name.localized()]);
|
||||
}
|
||||
table.print_tty(false)?;
|
||||
Ok(())
|
||||
|
||||
@@ -79,20 +79,20 @@ pub struct GetPackageResponse {
|
||||
pub other_versions: Option<BTreeMap<VersionString, PackageInfoShort>>,
|
||||
}
|
||||
impl GetPackageResponse {
|
||||
pub fn tables(&self) -> Vec<prettytable::Table> {
|
||||
pub fn tables(self) -> Vec<prettytable::Table> {
|
||||
use prettytable::*;
|
||||
|
||||
let mut res = Vec::with_capacity(self.best.len());
|
||||
|
||||
for (version, info) in &self.best {
|
||||
let mut table = info.table(version);
|
||||
for (version, info) in self.best {
|
||||
let mut table = info.table(&version);
|
||||
|
||||
let lesser_versions: BTreeMap<_, _> = self
|
||||
.other_versions
|
||||
.as_ref()
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.filter(|(v, _)| ***v < **version)
|
||||
.filter(|(v, _)| ***v < *version)
|
||||
.collect();
|
||||
|
||||
if !lesser_versions.is_empty() {
|
||||
@@ -121,13 +121,17 @@ pub struct GetPackageResponseFull {
|
||||
pub other_versions: BTreeMap<VersionString, PackageVersionInfo>,
|
||||
}
|
||||
impl GetPackageResponseFull {
|
||||
pub fn tables(&self) -> Vec<prettytable::Table> {
|
||||
pub fn tables(self) -> Vec<prettytable::Table> {
|
||||
let mut res = Vec::with_capacity(self.best.len());
|
||||
|
||||
let all: BTreeMap<_, _> = self.best.iter().chain(self.other_versions.iter()).collect();
|
||||
let all: BTreeMap<_, _> = self
|
||||
.best
|
||||
.into_iter()
|
||||
.chain(self.other_versions.into_iter())
|
||||
.collect();
|
||||
|
||||
for (version, info) in all {
|
||||
res.push(info.table(version));
|
||||
res.push(info.table(&version));
|
||||
}
|
||||
|
||||
res
|
||||
@@ -444,7 +448,11 @@ pub async fn cli_download(
|
||||
return Err(Error::new(
|
||||
eyre!(
|
||||
"{}",
|
||||
t!("registry.package.get.version-not-found", id = id, version = target_version.unwrap_or(VersionRange::Any))
|
||||
t!(
|
||||
"registry.package.get.version-not-found",
|
||||
id = id,
|
||||
version = target_version.unwrap_or(VersionRange::Any)
|
||||
)
|
||||
),
|
||||
ErrorKind::NotFound,
|
||||
));
|
||||
@@ -465,7 +473,11 @@ pub async fn cli_download(
|
||||
return Err(Error::new(
|
||||
eyre!(
|
||||
"{}",
|
||||
t!("registry.package.get.version-not-found", id = id, version = target_version.unwrap_or(VersionRange::Any))
|
||||
t!(
|
||||
"registry.package.get.version-not-found",
|
||||
id = id,
|
||||
version = target_version.unwrap_or(VersionRange::Any)
|
||||
)
|
||||
),
|
||||
ErrorKind::NotFound,
|
||||
));
|
||||
|
||||
@@ -17,7 +17,7 @@ use crate::registry::device_info::DeviceInfo;
|
||||
use crate::rpc_continuations::Guid;
|
||||
use crate::s9pk::S9pk;
|
||||
use crate::s9pk::git_hash::GitHash;
|
||||
use crate::s9pk::manifest::{Alerts, Description, HardwareRequirements};
|
||||
use crate::s9pk::manifest::{Alerts, Description, HardwareRequirements, LocaleString};
|
||||
use crate::s9pk::merkle_archive::source::FileSource;
|
||||
use crate::sign::commitment::merkle_archive::MerkleArchiveCommitment;
|
||||
use crate::sign::{AnySignature, AnyVerifyingKey};
|
||||
@@ -49,22 +49,27 @@ pub struct PackageInfo {
|
||||
#[model = "Model<Self>"]
|
||||
#[ts(export)]
|
||||
pub struct Category {
|
||||
pub name: String,
|
||||
pub name: LocaleString,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, HasModel, TS, PartialEq, Eq)]
|
||||
#[derive(Debug, Deserialize, Serialize, HasModel, TS, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[model = "Model<Self>"]
|
||||
#[ts(export)]
|
||||
pub struct DependencyMetadata {
|
||||
#[ts(type = "string | null")]
|
||||
pub title: Option<InternedString>,
|
||||
pub title: Option<LocaleString>,
|
||||
pub icon: Option<DataUrl<'static>>,
|
||||
pub description: Option<String>,
|
||||
pub description: Option<LocaleString>,
|
||||
pub optional: bool,
|
||||
}
|
||||
impl DependencyMetadata {
|
||||
pub fn localize_for(&mut self, locale: &str) {
|
||||
self.title.as_mut().map(|t| t.localize_for(locale));
|
||||
self.description.as_mut().map(|d| d.localize_for(locale));
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, HasModel, TS, PartialEq, Eq)]
|
||||
#[derive(Debug, Deserialize, Serialize, HasModel, TS, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[model = "Model<Self>"]
|
||||
pub struct PackageMetadata {
|
||||
@@ -72,7 +77,7 @@ pub struct PackageMetadata {
|
||||
pub title: InternedString,
|
||||
pub icon: DataUrl<'static>,
|
||||
pub description: Description,
|
||||
pub release_notes: String,
|
||||
pub release_notes: LocaleString,
|
||||
pub git_hash: Option<GitHash>,
|
||||
#[ts(type = "string")]
|
||||
pub license: InternedString,
|
||||
@@ -199,20 +204,20 @@ impl PackageVersionInfo {
|
||||
self.s9pks.sort_by_key(|(h, _)| h.specificity_desc());
|
||||
Ok(())
|
||||
}
|
||||
pub fn table(&self, version: &VersionString) -> prettytable::Table {
|
||||
pub fn table(self, version: &VersionString) -> prettytable::Table {
|
||||
use prettytable::*;
|
||||
|
||||
let mut table = Table::new();
|
||||
|
||||
table.add_row(row![bc => &self.metadata.title]);
|
||||
table.add_row(row![br -> "VERSION", AsRef::<str>::as_ref(version)]);
|
||||
table.add_row(row![br -> "RELEASE NOTES", &self.metadata.release_notes]);
|
||||
table.add_row(row![br -> "RELEASE NOTES", &self.metadata.release_notes.localized()]);
|
||||
table.add_row(
|
||||
row![br -> "ABOUT", &textwrap::wrap(&self.metadata.description.short, 80).join("\n")],
|
||||
row![br -> "ABOUT", &textwrap::wrap(&self.metadata.description.short.localized(), 80).join("\n")],
|
||||
);
|
||||
table.add_row(row![
|
||||
br -> "DESCRIPTION",
|
||||
&textwrap::wrap(&self.metadata.description.long, 80).join("\n")
|
||||
&textwrap::wrap(&self.metadata.description.long.localized(), 80).join("\n")
|
||||
]);
|
||||
table.add_row(row![br -> "GIT HASH", self.metadata.git_hash.as_deref().unwrap_or("N/A")]);
|
||||
table.add_row(row![br -> "LICENSE", &self.metadata.license]);
|
||||
@@ -280,6 +285,24 @@ impl Model<PackageVersionInfo> {
|
||||
{
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
if let Some(locale) = device_info.os.language.as_deref() {
|
||||
let metadata = self.as_metadata_mut();
|
||||
metadata
|
||||
.as_alerts_mut()
|
||||
.mutate(|a| Ok(a.localize_for(locale)));
|
||||
metadata
|
||||
.as_dependency_metadata_mut()
|
||||
.as_entries_mut()?
|
||||
.into_iter()
|
||||
.try_for_each(|(_, d)| d.mutate(|d| Ok(d.localize_for(locale))));
|
||||
metadata
|
||||
.as_description_mut()
|
||||
.mutate(|d| Ok(d.localize_for(locale)))?;
|
||||
metadata
|
||||
.as_release_notes_mut()
|
||||
.mutate(|r| Ok(r.localize_for(locale)))?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(true)
|
||||
|
||||
Reference in New Issue
Block a user