Skip to content

Commit

Permalink
Add arch support for f-droid
Browse files Browse the repository at this point in the history
  • Loading branch information
BarbossHack committed Oct 3, 2024
1 parent 704af2e commit 04c9702
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 38 deletions.
6 changes: 6 additions & 0 deletions USAGE-fdroid.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,9 @@ A special option can also be used to skip verification of the repository index.
```shell
apkeep -a org.torproject.android -d f-droid -o repo=https://guardianproject.info/fdroid/repo,verify-index=false .
```

It is also possible to download a specific variant of an app with the `arch=` option:

```shell
apkeep -a [email protected] -d f-droid -o arch=arm64-v8a .
```
81 changes: 43 additions & 38 deletions src/fdroid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,9 @@ pub async fn download_apps(
let mp_index = Rc::clone(&mp);
let index = retrieve_index_or_exit(&options, mp_index).await;

let (fdroid_apps, repo_address) = match parse_json_for_download_information(index, apps) {
let app_arch = options.get("arch").map(|x| x.to_string());

let (fdroid_apps, repo_address) = match parse_json_for_download_information(index, apps, app_arch.as_ref()) {
Ok((fdroid_apps, repo_address)) => (fdroid_apps, repo_address),
Err(_) => {
println!("Could not parse JSON of F-Droid package index. Exiting.");
Expand All @@ -173,15 +175,24 @@ pub async fn download_apps(
let repo_address = Rc::clone(&repo_address);
let mp_log = Rc::clone(&mp);
let mp = Rc::clone(&mp);
let app_arch = app_arch.clone();
async move {
let app_string = match app_version {
Some(ref version) => {
let app_string = match (app_version, app_arch) {
(None, None) => {
mp_log.println(format!("Downloading {}...", app_id)).unwrap();
app_id.to_string()
},
(None, Some(arch)) => {
mp_log.println(format!("Downloading {} arch {}...", app_id, arch)).unwrap();
format!("{}@{}", app_id, arch)
},
(Some(version), None) => {
mp_log.println(format!("Downloading {} version {}...", app_id, version)).unwrap();
format!("{}@{}", app_id, version)
},
None => {
mp_log.println(format!("Downloading {}...", app_id)).unwrap();
app_id.to_string()
(Some(version), Some(arch)) => {
mp_log.println(format!("Downloading {} version {} arch {}...", app_id, version, arch)).unwrap();
format!("{}@{}@{}", app_id, version, arch)
},
};
let fname = format!("{}.apk", app_string);
Expand Down Expand Up @@ -242,7 +253,7 @@ pub async fn download_apps(
}

type DownloadInformation = (Vec<(String, Option<String>, String, Vec<u8>)>, String);
fn parse_json_for_download_information(index: Value, apps: Vec<(String, Option<String>)>) -> Result<DownloadInformation, FDroidError> {
fn parse_json_for_download_information(index: Value, apps: Vec<(String, Option<String>)>, app_arch: Option<&String>) -> Result<DownloadInformation, FDroidError> {
let index_map = index.as_object().ok_or(FDroidError::Dummy)?;
let repo_address = index_map
.get("repo").ok_or(FDroidError::Dummy)?
Expand All @@ -259,45 +270,39 @@ fn parse_json_for_download_information(index: Value, apps: Vec<(String, Option<S
let app_array_value = packages.get(&app_id).unwrap();
if app_array_value.is_array() {
let app_array = app_array_value.as_array().unwrap();
if app_version.is_none() {
if !app_array.is_empty() && app_array[0].is_object() {
let fdroid_app = app_array[0].as_object().unwrap();
if fdroid_app.contains_key("apkName") && fdroid_app.contains_key("hash") {
let filename_value = fdroid_app.get("apkName").unwrap();
let hash_value = fdroid_app.get("hash").unwrap();
if filename_value.is_string() && hash_value.is_string() {
let filename = filename_value.as_str().unwrap().to_string();
if let Ok(hash) = hex::decode(hash_value.as_str().unwrap().to_string()) {
return Some((app_id, app_version, filename, hash));
}
}
}
}
} else {
for single_app in app_array {
if single_app.is_object() {
let fdroid_app = single_app.as_object().unwrap();
if fdroid_app.contains_key("versionName") {
let version_name_value = fdroid_app.get("versionName").unwrap();
if version_name_value.is_string() {
let version_name = version_name_value.as_str().unwrap().to_string();
if version_name == *app_version.as_ref().unwrap() && fdroid_app.contains_key("apkName") && fdroid_app.contains_key("hash") {
let filename_value = fdroid_app.get("apkName").unwrap();
let hash_value = fdroid_app.get("hash").unwrap();
if filename_value.is_string() && hash_value.is_string() {
let filename = filename_value.as_str().unwrap().to_string();
if let Ok(hash) = hex::decode(hash_value.as_str().unwrap().to_string()) {
return Some((app_id, app_version, filename, hash));
for single_app in app_array {
if single_app.is_object() {
let fdroid_app = single_app.as_object().unwrap();
if fdroid_app.contains_key("versionName") {
let version_name_value = fdroid_app.get("versionName").unwrap();
if version_name_value.is_string() {
let version_name = version_name_value.as_str().unwrap().to_string();
if (app_version.is_none() || version_name == *app_version.as_ref().unwrap()) && fdroid_app.contains_key("apkName") && fdroid_app.contains_key("hash") {
if let Some(arch) = app_arch {
let nativecode_value = fdroid_app.get("nativecode").unwrap();
if nativecode_value.is_array() {
let nativecode_array = nativecode_value.as_array().unwrap();
if !nativecode_array.iter().any(|value| value.as_str().unwrap() == arch) {
continue;
}
}
}
let filename_value = fdroid_app.get("apkName").unwrap();
let hash_value = fdroid_app.get("hash").unwrap();
if filename_value.is_string() && hash_value.is_string() {
let filename = filename_value.as_str().unwrap().to_string();
if let Ok(hash) = hex::decode(hash_value.as_str().unwrap().to_string()) {
return Some((app_id, app_version, filename, hash));
}
}
}
}
}
}
println!("Could not find version {} of {}. Skipping...", app_version.unwrap(), app_id);
return None;
}
let arch_str = app_arch.as_ref().map_or("".to_string(), |x| format!(" {}", x));
println!("Could not find version {}{} of {}. Skipping...", app_version.unwrap(), arch_str, app_id);
return None;
}
} else {
println!("Could not find {} in package list. Skipping...", app_id);
Expand Down

0 comments on commit 04c9702

Please sign in to comment.