+
Skip to content
This repository was archived by the owner on Sep 17, 2024. It is now read-only.

add support for townlong-yak addons #529

Merged
merged 3 commits into from
Feb 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and `Removed`.

### Added

- Townlong Yak addons has been added to the Catalog.
- Optional 'Categories' column for Catalog.
- Optional 'Summary' column for My Addons.
- New languages added to Ajour:
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 20 additions & 1 deletion crates/core/src/addon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,8 @@ impl Addon {
RepositoryKind::WowI => {
self.repository_id() == f.repository_identifiers.wowi.as_deref()
}
// For git sources, prioritize the folder that has a version in it
// For git & townlong sources, prioritize the folder that has a version in it
RepositoryKind::TownlongYak => f.version.is_some(),
RepositoryKind::Git(_) => f.version.is_some(),
}
} else {
Expand Down Expand Up @@ -274,6 +275,13 @@ impl Addon {
}
}

/// Sets the file id of the addon
pub fn set_file_id(&mut self, file_id: i64) {
if let Some(metadata) = self.repository.as_mut().map(|r| &mut r.metadata) {
metadata.file_id = Some(file_id);
}
}

/// Returns the title of the addon.
pub fn title(&self) -> &str {
let meta_title = self.metadata().map(|m| m.title.as_deref()).flatten();
Expand Down Expand Up @@ -413,6 +421,17 @@ impl Addon {
}
}

/// Returns the hub id of the addon, if applicable.
pub fn hub_id(&self) -> Option<i32> {
if self.repository_kind() == Some(RepositoryKind::TownlongYak) {
self.repository()
.map(|r| r.id.parse::<i32>().ok())
.flatten()
} else {
None
}
}

pub fn remote_packages(&self) -> HashMap<ReleaseChannel, RemotePackage> {
self.metadata()
.map(|m| &m.remote_packages)
Expand Down
18 changes: 18 additions & 0 deletions crates/core/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ pub struct AddonCacheEntry {
pub primary_folder_id: String,
pub folder_names: Vec<String>,
pub modified: DateTime<Utc>,
pub external_release_id: Option<ExternalReleaseId>,
}

impl TryFrom<&Addon> for AddonCacheEntry {
Expand All @@ -207,13 +208,23 @@ impl TryFrom<&Addon> for AddonCacheEntry {
let mut folder_names: Vec<_> = addon.folders.iter().map(|a| a.id.clone()).collect();
folder_names.sort();

let external_release_id = if repository == RepositoryKind::TownlongYak {
addon.file_id().map(ExternalReleaseId::FileId)
} else {
addon
.version()
.map(str::to_string)
.map(ExternalReleaseId::Version)
};

Comment on lines +211 to +219
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is how we cache the version that was just installed / updated. When we reload the addon from the cache, it'll use this as the version / file_id to check against the remote API. This resolves issues where the addon .toc version is not comparable to the remote version on the API

Ok(AddonCacheEntry {
title: addon.title().to_owned(),
repository,
repository_id: repository_id.to_owned(),
primary_folder_id: addon.primary_folder_id.clone(),
folder_names,
modified: Utc::now(),
external_release_id,
})
} else {
Err(CacheError::AddonMissingRepo {
Expand All @@ -223,6 +234,12 @@ impl TryFrom<&Addon> for AddonCacheEntry {
}
}

#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum ExternalReleaseId {
FileId(i64),
Version(String),
}

#[derive(Serialize, Deserialize, Debug)]
pub struct CatalogCache {
etag: String,
Expand Down Expand Up @@ -307,6 +324,7 @@ mod test {
primary_folder_id: folders.first().map(|f| f.id.clone()).unwrap(),
folder_names: folders.iter().map(|f| f.id.clone()).collect(),
modified: Utc::now(),
external_release_id: None,
}
}));

Expand Down
5 changes: 4 additions & 1 deletion crates/core/src/catalog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use chrono::prelude::*;
use isahc::ResponseExt;
use serde::{Deserialize, Serialize};

const CATALOG_URL: &str = "https://github.com/ajour/ajour-catalog/raw/master/catalog.json";
const CATALOG_URL: &str = "https://raw.githubusercontent.com/ajour/ajour-catalog/3ce1414498adbc7167f11fe0dac7cd58e7b55391/catalog.json";
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure we change this back before merging. I switched over to test.


type Etag = Option<String>;

Expand Down Expand Up @@ -65,6 +65,8 @@ pub enum Source {
Tukui,
#[serde(alias = "wowi")]
WowI,
#[serde(alias = "townlong-yak")]
TownlongYak,
}

impl std::fmt::Display for Source {
Expand All @@ -73,6 +75,7 @@ impl std::fmt::Display for Source {
Source::Curse => "Curse",
Source::Tukui => "Tukui",
Source::WowI => "WowInterface",
Source::TownlongYak => "TownlongYak",
};
write!(f, "{}", s)
}
Expand Down
8 changes: 8 additions & 0 deletions crates/core/src/config/wow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ impl Flavor {
}
}

/// Returns flavor `String` in WowUp.Hub format
pub(crate) fn hub_format(self) -> String {
match self {
Flavor::Retail | Flavor::RetailPTR | Flavor::RetailBeta => "retail".to_owned(),
Flavor::Classic | Flavor::ClassicPTR => "classic".to_owned(),
}
}

/// Returns `Flavor` which self relates to.
pub fn base_flavor(self) -> Flavor {
match self {
Expand Down
2 changes: 2 additions & 0 deletions crates/core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ pub enum RepositoryError {
CurseMissingPackage { id: String },
#[error("No package found for WowI id {id}")]
WowIMissingPackage { id: String },
#[error("No package found for Hub id {id}")]
HubMissingPackage { id: String },
#[error("No remote package found for channel {channel}")]
MissingPackageChannel { channel: ReleaseChannel },
#[error("Git repo must be created with `from_source_url`")]
Expand Down
71 changes: 68 additions & 3 deletions crates/core/src/parse.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use crate::{
addon::{Addon, AddonFolder, AddonState},
cache::{self, AddonCache, AddonCacheEntry, FingerprintCache},
cache::{self, AddonCache, AddonCacheEntry, ExternalReleaseId, FingerprintCache},
config::Flavor,
error::{CacheError, DownloadError, ParseError, RepositoryError},
fs::PersistentData,
murmur2::calculate_hash,
repository::{curse, tukui, wowi, RepositoryIdentifiers, RepositoryKind, RepositoryPackage},
repository::{
curse, townlongyak, tukui, wowi, RepositoryIdentifiers, RepositoryKind, RepositoryPackage,
},
};
use async_std::sync::{Arc, Mutex};
use fancy_regex::Regex;
Expand Down Expand Up @@ -433,6 +435,7 @@ async fn get_all_repo_packages(
let mut curse_ids = vec![];
let mut tukui_ids = vec![];
let mut wowi_ids = vec![];
let mut townlong_ids = vec![];
let mut git_urls = vec![];

let cached_folder_names: Vec<_> = cache_entries
Expand Down Expand Up @@ -494,6 +497,17 @@ async fn get_all_repo_packages(
wowi_ids.dedup();
}

// Get all possible townlong_ids (hub) ids
{
townlong_ids.extend(
cache_entries
.iter()
.filter(|e| e.repository == RepositoryKind::TownlongYak)
.map(|e| e.repository_id.clone()),
);
townlong_ids.dedup();
}

// Get all possible git urls
{
git_urls.extend(
Expand Down Expand Up @@ -624,6 +638,34 @@ async fn get_all_repo_packages(
wowi_repo_packages.len()
);

// Get all townlong repo packages
let townlong_repo_packages = if !townlong_ids.is_empty() {
let townlong_packages = townlongyak::fetch_remote_packages(flavor, &townlong_ids).await?;

townlong_packages
.into_iter()
.map(|package| {
(
package.id.to_string(),
townlongyak::metadata_from_townlong_package(flavor, package),
)
})
.filter_map(|(id, metadata)| {
RepositoryPackage::from_repo_id(flavor, RepositoryKind::TownlongYak, id)
.ok()
.map(|r| r.with_metadata(metadata))
})
.collect::<Vec<_>>()
} else {
vec![]
};

log::debug!(
"{} - {} townlong packages fetched",
flavor,
townlong_repo_packages.len()
);

// Get all git repo packages
let git_repo_packages = if !git_urls.is_empty() {
let fetch_tasks = git_urls
Expand Down Expand Up @@ -670,6 +712,7 @@ async fn get_all_repo_packages(
&curse_repo_packages[..],
&tukui_repo_packages[..],
&wowi_repo_packages[..],
&townlong_repo_packages[..],
&git_repo_packages[..],
]
.concat())
Expand All @@ -688,7 +731,20 @@ fn build_addons(
let repo_idx = repo_packages
.iter()
.position(|r| r.id == e.repository_id && r.kind == e.repository)?;
let repo_package = repo_packages.remove(repo_idx);

let mut repo_package = repo_packages.remove(repo_idx);

// Set the file id / version from the cache entry. This is needed to properly
// validate the installed version against the remote version
match &e.external_release_id {
Some(ExternalReleaseId::FileId(file_id)) => {
repo_package.metadata.file_id = Some(*file_id)
}
Some(ExternalReleaseId::Version(version)) => {
repo_package.metadata.version = Some(version.clone())
}
None => {}
}
Comment on lines +737 to +747
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is where we apply that cached remote release version when building addon from cache entry


// Get and remove all matching addon folders
let folder_idxs: Vec<_> = addon_folders
Expand Down Expand Up @@ -832,6 +888,15 @@ fn build_addons(
.count()
);

log::debug!(
"{} - {} addons built from townlong-yak packages",
flavor,
concatenated_addons
.iter()
.filter(|a| a.repository_kind() == Some(RepositoryKind::TownlongYak))
.count()
);

log::debug!(
"{} - {} addons built from git packages",
flavor,
Expand Down
2 changes: 2 additions & 0 deletions crates/core/src/repository/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ use dyn_clone::{clone_trait_object, DynClone};

pub mod curse;
mod git;
pub mod townlongyak;
pub mod tukui;
pub mod wowi;

pub use curse::Curse;
pub use git::{Github, Gitlab};
pub use townlongyak::TownlongYak;
pub use tukui::Tukui;
pub use wowi::WowI;

Expand Down
Loading
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载