You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
203 lines
7.7 KiB
Java
203 lines
7.7 KiB
Java
package com.fox2code.mmm.repo;
|
|
|
|
import com.fox2code.mmm.MainApplication;
|
|
import com.fox2code.mmm.utils.io.Hashes;
|
|
import com.fox2code.mmm.utils.io.PropUtils;
|
|
import com.fox2code.mmm.utils.io.net.Http;
|
|
import com.fox2code.mmm.utils.realm.ReposList;
|
|
|
|
import org.json.JSONObject;
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
import io.realm.Realm;
|
|
import io.realm.RealmConfiguration;
|
|
import timber.log.Timber;
|
|
|
|
public class CustomRepoManager {
|
|
public static final int MAX_CUSTOM_REPOS = 5;
|
|
private static final boolean AUTO_RECOMPILE = true;
|
|
private final RepoManager repoManager;
|
|
private final String[] customRepos;
|
|
boolean dirty;
|
|
private int customReposCount;
|
|
|
|
@SuppressWarnings("unused")
|
|
CustomRepoManager(MainApplication mainApplication, RepoManager repoManager) {
|
|
this.repoManager = repoManager;
|
|
this.customRepos = new String[MAX_CUSTOM_REPOS];
|
|
this.customReposCount = 0;
|
|
// refuse to load if setup is not complete
|
|
if (MainApplication.getSharedPreferences("mmm").getString("last_shown_setup", "").equals("")) {
|
|
return;
|
|
}
|
|
RealmConfiguration realmConfiguration = new RealmConfiguration.Builder().name("ReposList.realm").encryptionKey(MainApplication.getINSTANCE().getKey()).allowQueriesOnUiThread(true).allowWritesOnUiThread(true).directory(MainApplication.getINSTANCE().getDataDirWithPath("realms")).schemaVersion(1).build();
|
|
Realm realm = Realm.getInstance(realmConfiguration);
|
|
if (realm.isInTransaction()) {
|
|
realm.commitTransaction();
|
|
}
|
|
int i = 0;
|
|
@SuppressWarnings("MismatchedReadAndWriteOfArray") final int[] lastFilled = {0};
|
|
realm.executeTransaction(realm1 -> {
|
|
// find all repos that are not built-in
|
|
for (ReposList reposList : realm1.where(ReposList.class).notEqualTo("id", "androidacy_repo").and().notEqualTo("id", "magisk_alt_repo").and().notEqualTo("id", "magisk_official_repo").findAll()) {
|
|
String repo = reposList.getUrl();
|
|
if (!PropUtils.isNullString(repo) && !RepoManager.isBuiltInRepo(repo)) {
|
|
lastFilled[0] = i;
|
|
int index = AUTO_RECOMPILE ? this.customReposCount : i;
|
|
this.customRepos[index] = repo;
|
|
this.customReposCount++;
|
|
((CustomRepoData) this.repoManager.addOrGet(repo)).override = "custom_repo_" + index;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
public CustomRepoData addRepo(String repo) {
|
|
if (RepoManager.isBuiltInRepo(repo))
|
|
throw new IllegalArgumentException("Can't add built-in repo to custom repos");
|
|
for (String repoEntry : this.customRepos) {
|
|
if (repo.equals(repoEntry)) return (CustomRepoData) this.repoManager.get(repoEntry);
|
|
}
|
|
int i = 0;
|
|
while (customRepos[i] != null) i++;
|
|
customRepos[i] = repo;
|
|
// fetch that sweet sweet json
|
|
byte[] json;
|
|
try {
|
|
json = Http.doHttpGet(repo, false);
|
|
} catch (Exception e) {
|
|
Timber.e(e, "Failed to fetch json from repo");
|
|
return null;
|
|
}
|
|
// get website, support, donate, submitModule. all optional. name is required.
|
|
// parse json
|
|
JSONObject jsonObject;
|
|
try {
|
|
jsonObject = new JSONObject(new String(json));
|
|
} catch (Exception e) {
|
|
Timber.e(e, "Failed to parse json from repo");
|
|
return null;
|
|
}
|
|
// get name
|
|
String name;
|
|
try {
|
|
name = jsonObject.getString("name");
|
|
} catch (Exception e) {
|
|
Timber.e(e, "Failed to get name from json");
|
|
return null;
|
|
}
|
|
// get website
|
|
String website;
|
|
try {
|
|
website = jsonObject.getString("website");
|
|
} catch (Exception e) {
|
|
website = null;
|
|
}
|
|
// get support
|
|
String support;
|
|
try {
|
|
support = jsonObject.getString("support");
|
|
} catch (Exception e) {
|
|
support = null;
|
|
}
|
|
// get donate
|
|
String donate;
|
|
try {
|
|
donate = jsonObject.getString("donate");
|
|
} catch (Exception e) {
|
|
donate = null;
|
|
}
|
|
// get submitModule
|
|
String submitModule;
|
|
try {
|
|
submitModule = jsonObject.getString("submitModule");
|
|
} catch (Exception e) {
|
|
submitModule = null;
|
|
}
|
|
String id = "repo_" + Hashes.hashSha256(repo.getBytes(StandardCharsets.UTF_8));
|
|
RealmConfiguration realmConfiguration = new RealmConfiguration.Builder().name("ReposList.realm").encryptionKey(MainApplication.getINSTANCE().getKey()).allowQueriesOnUiThread(true).allowWritesOnUiThread(true).directory(MainApplication.getINSTANCE().getDataDirWithPath("realms")).schemaVersion(1).build();
|
|
Realm realm = Realm.getInstance(realmConfiguration);
|
|
String finalWebsite = website;
|
|
String finalSupport = support;
|
|
String finalDonate = donate;
|
|
String finalSubmitModule = submitModule;
|
|
realm.executeTransaction(realm1 -> {
|
|
// find the matching entry for repo_0, repo_1, etc.
|
|
ReposList reposList = realm1.where(ReposList.class).equalTo("id", id).findFirst();
|
|
if (reposList == null) {
|
|
reposList = realm1.createObject(ReposList.class, id);
|
|
}
|
|
reposList.setUrl(repo);
|
|
reposList.setName(name);
|
|
reposList.setWebsite(finalWebsite);
|
|
reposList.setSupport(finalSupport);
|
|
reposList.setDonate(finalDonate);
|
|
reposList.setSubmitModule(finalSubmitModule);
|
|
reposList.setEnabled(true);
|
|
// save the object
|
|
realm1.copyToRealmOrUpdate(reposList);
|
|
});
|
|
customReposCount++;
|
|
this.dirty = true;
|
|
CustomRepoData customRepoData = (CustomRepoData) this.repoManager.addOrGet(repo);
|
|
customRepoData.override = "repo_" + id;
|
|
customRepoData.id = id;
|
|
customRepoData.website = website;
|
|
customRepoData.support = support;
|
|
customRepoData.donate = donate;
|
|
customRepoData.submitModule = submitModule;
|
|
customRepoData.name = name;
|
|
// Set the enabled state to true
|
|
customRepoData.setEnabled(true);
|
|
customRepoData.updateEnabledState();
|
|
realm.close();
|
|
return customRepoData;
|
|
}
|
|
|
|
public CustomRepoData getRepo(String id) {
|
|
return (CustomRepoData) this.repoManager.get(id);
|
|
}
|
|
|
|
public void removeRepo(int index) {
|
|
String oldRepo = customRepos[index];
|
|
if (oldRepo != null) {
|
|
customRepos[index] = null;
|
|
customReposCount--;
|
|
CustomRepoData customRepoData = (CustomRepoData) this.repoManager.get(oldRepo);
|
|
if (customRepoData != null) {
|
|
customRepoData.setEnabled(false);
|
|
customRepoData.override = null;
|
|
}
|
|
this.dirty = true;
|
|
}
|
|
}
|
|
|
|
public boolean hasRepo(String repo) {
|
|
for (String repoEntry : this.customRepos) {
|
|
if (repo.equals(repoEntry)) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public boolean canAddRepo() {
|
|
return this.customReposCount < MAX_CUSTOM_REPOS;
|
|
}
|
|
|
|
public boolean canAddRepo(String repo) {
|
|
if (RepoManager.isBuiltInRepo(repo) || this.hasRepo(repo) || !this.canAddRepo())
|
|
return false;
|
|
return repo.startsWith("https://") && repo.indexOf('/', 9) != -1;
|
|
}
|
|
|
|
public int getRepoCount() {
|
|
return this.customReposCount;
|
|
}
|
|
|
|
public boolean needUpdate() {
|
|
boolean needUpdate = this.dirty;
|
|
if (needUpdate) this.dirty = false;
|
|
return needUpdate;
|
|
}
|
|
}
|