Remove Magisk-Modules-Repo life support.

pull/55/head
Fox2Code 2 years ago
parent 5ee90a1b4e
commit f3a1e63dce

@ -34,12 +34,10 @@ The app currently use these two repo as it's module sources, with it's benefits
- Officially supported by Fox's mmm - Officially supported by Fox's mmm
[https://github.com/Magisk-Modules-Repo](https://github.com/Magisk-Modules-Repo) [https://github.com/Magisk-Modules-Repo](https://github.com/Magisk-Modules-Repo)
- No longer accept new modules or update to existing modules - No longer accept new modules or receive update to existing modules
(Fox's MMM use a workaround to get latest version of modules, because the
method used by the official Magisk app give outdated versions of the modules)
- May be shut down at any moment - May be shut down at any moment
- Official app dropped support for it - Official app dropped support for it
- Officially supported by Fox's mmm - End of life support by Fox's mmm
As the main repo may shutting down due to the main app no longer supporting it, As the main repo may shutting down due to the main app no longer supporting it,
and also stopped accepting new modules, it is recommended to submit your modules and also stopped accepting new modules, it is recommended to submit your modules

@ -1,16 +1,11 @@
package com.fox2code.mmm.repo; package com.fox2code.mmm.repo;
import android.annotation.SuppressLint;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.util.Log;
import androidx.annotation.NonNull;
import com.fox2code.mmm.MainApplication; import com.fox2code.mmm.MainApplication;
import com.fox2code.mmm.R; import com.fox2code.mmm.R;
import com.fox2code.mmm.manager.ModuleInfo; import com.fox2code.mmm.manager.ModuleInfo;
import com.fox2code.mmm.utils.Files; import com.fox2code.mmm.utils.Files;
import com.fox2code.mmm.utils.Http;
import com.fox2code.mmm.utils.PropUtils; import com.fox2code.mmm.utils.PropUtils;
import org.json.JSONArray; import org.json.JSONArray;
@ -20,15 +15,10 @@ import org.json.JSONObject;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Objects;
public class RepoData { public class RepoData {
private static final String TAG = "RepoData"; private static final String TAG = "RepoData";
@ -38,59 +28,24 @@ public class RepoData {
public final File cacheRoot; public final File cacheRoot;
public final SharedPreferences cachedPreferences; public final SharedPreferences cachedPreferences;
public final File metaDataCache; public final File metaDataCache;
public final boolean special;
public final HashMap<String, RepoModule> moduleHashMap; public final HashMap<String, RepoModule> moduleHashMap;
public long lastUpdate; public long lastUpdate;
public String name; public String name;
private boolean enabled; // Cache for speed private boolean enabled; // Cache for speed
private final Map<String, SpecialData> specialData;
private long specialLastUpdate;
protected RepoData(String url, File cacheRoot, SharedPreferences cachedPreferences) { protected RepoData(String url, File cacheRoot, SharedPreferences cachedPreferences) {
this(url, cacheRoot, cachedPreferences, false);
}
RepoData(String url, File cacheRoot, SharedPreferences cachedPreferences,boolean special) {
this.url = url; this.url = url;
this.id = RepoManager.internalIdOfUrl(url); this.id = RepoManager.internalIdOfUrl(url);
this.cacheRoot = cacheRoot; this.cacheRoot = cacheRoot;
this.cachedPreferences = cachedPreferences; this.cachedPreferences = cachedPreferences;
this.metaDataCache = new File(cacheRoot, "modules.json"); this.metaDataCache = new File(cacheRoot, "modules.json");
this.special = special;
this.moduleHashMap = new HashMap<>(); this.moduleHashMap = new HashMap<>();
this.name = this.url; // Set url as default name this.name = this.url; // Set url as default name
this.enabled = MainApplication.getSharedPreferences() this.enabled = MainApplication.getSharedPreferences()
.getBoolean("pref_" + this.id + "_enabled", true); .getBoolean("pref_" + this.id + "_enabled", true);
this.specialData = special ? new HashMap<>() : Collections.emptyMap();
if (!this.cacheRoot.isDirectory()) { if (!this.cacheRoot.isDirectory()) {
this.cacheRoot.mkdirs(); this.cacheRoot.mkdirs();
} else { } else {
if (special) { // Special times need to be loaded before populate
File metaDataCacheSpecial = new File(cacheRoot, "modules_times.json");
if (metaDataCacheSpecial.exists()) {
try {
JSONArray jsonArray = new JSONArray(new String(
Files.read(this.metaDataCache), StandardCharsets.UTF_8));
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
this.specialData.put(
jsonObject.getString("name"), new SpecialData(
Objects.requireNonNull(ISO_OFFSET_DATE_TIME.parse(
jsonObject.getString(
"pushed_at"))).getTime(),
jsonObject.optInt("stargazers_count")));
Log.d(TAG, "Got " +
jsonObject.getString("name") + " from local storage!");
}
this.specialLastUpdate = metaDataCacheSpecial.lastModified();
if (this.specialLastUpdate > System.currentTimeMillis()) {
this.specialLastUpdate = 0; // Don't allow time travel
}
} catch (Exception e) {
metaDataCacheSpecial.delete();
}
}
}
if (this.metaDataCache.exists()) { if (this.metaDataCache.exists()) {
this.lastUpdate = metaDataCache.lastModified(); this.lastUpdate = metaDataCache.lastModified();
if (this.lastUpdate > System.currentTimeMillis()) { if (this.lastUpdate > System.currentTimeMillis()) {
@ -132,19 +87,12 @@ public class RepoData {
String moduleId = module.getString("id"); String moduleId = module.getString("id");
// Deny remote modules ids shorter than 3 chars long or that start with a digit // Deny remote modules ids shorter than 3 chars long or that start with a digit
if (moduleId.length() < 3 || Character.isDigit(moduleId.charAt(0))) continue; if (moduleId.length() < 3 || Character.isDigit(moduleId.charAt(0))) continue;
SpecialData moduleSpecialData = this.specialData.get(moduleId);
long moduleLastUpdate = module.getLong("last_update"); long moduleLastUpdate = module.getLong("last_update");
String moduleNotesUrl = module.getString("notes_url"); String moduleNotesUrl = module.getString("notes_url");
String modulePropsUrl = module.getString("prop_url"); String modulePropsUrl = module.getString("prop_url");
String moduleZipUrl = module.getString("zip_url"); String moduleZipUrl = module.getString("zip_url");
String moduleChecksum = module.optString("checksum"); String moduleChecksum = module.optString("checksum");
String moduleStars = module.optString("stars"); String moduleStars = module.optString("stars");
if (moduleSpecialData != null) { // Fix last update time
moduleLastUpdate = Math.max(moduleLastUpdate, moduleSpecialData.time);
moduleNotesUrl = Http.updateLink(moduleNotesUrl);
modulePropsUrl = Http.updateLink(modulePropsUrl);
moduleZipUrl = Http.updateLink(moduleZipUrl);
}
RepoModule repoModule = this.moduleHashMap.get(moduleId); RepoModule repoModule = this.moduleHashMap.get(moduleId);
if (repoModule == null) { if (repoModule == null) {
repoModule = new RepoModule(this, moduleId); repoModule = new RepoModule(this, moduleId);
@ -163,10 +111,7 @@ public class RepoData {
repoModule.propUrl = modulePropsUrl; repoModule.propUrl = modulePropsUrl;
repoModule.zipUrl = moduleZipUrl; repoModule.zipUrl = moduleZipUrl;
repoModule.checksum = moduleChecksum; repoModule.checksum = moduleChecksum;
if (moduleSpecialData != null) { if (!moduleStars.isEmpty()) {
repoModule.qualityValue = moduleSpecialData.stars;
repoModule.qualityText = R.string.module_stars;
} else if (!moduleStars.isEmpty()) {
try { try {
repoModule.qualityValue = Integer.parseInt(moduleStars); repoModule.qualityValue = Integer.parseInt(moduleStars);
repoModule.qualityText = R.string.module_stars; repoModule.qualityText = R.string.module_stars;
@ -204,12 +149,6 @@ public class RepoData {
if (moduleInfo.version == null) { if (moduleInfo.version == null) {
moduleInfo.version = "v" + moduleInfo.versionCode; moduleInfo.version = "v" + moduleInfo.versionCode;
} }
SpecialData moduleSpecialData =
this.specialData.get(repoModule.id);
if (moduleSpecialData != null) {
repoModule.qualityValue = moduleSpecialData.stars;
repoModule.qualityText = R.string.module_stars;
}
return true; return true;
} catch (Exception ignored) { } catch (Exception ignored) {
file.delete(); file.delete();
@ -219,41 +158,6 @@ public class RepoData {
return false; return false;
} }
@SuppressLint("SimpleDateFormat")
private static final SimpleDateFormat ISO_OFFSET_DATE_TIME =
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
public void updateSpecialTimes(boolean force) throws IOException, JSONException {
if (!this.special) return;
synchronized (this.populateLock) {
if (this.specialLastUpdate == 0L || (force && (this.specialData.isEmpty() ||
this.specialLastUpdate < System.currentTimeMillis() - 60000L))) {
File metaDataCacheSpecial = new File(cacheRoot, "modules_times.json");
this.specialData.clear();
try {
// Requesting only 32 most recently pushed repos
byte[] data = Http.doHttpGet(
"https://api.github.com/users/Magisk-Modules-Repo/" +
"repos?sort=pushed&per_page=32", false);
JSONArray jsonArray = new JSONArray(new String(data, StandardCharsets.UTF_8));
for (int i = 0;i < jsonArray.length();i++) {
JSONObject jsonObject = jsonArray.optJSONObject(i);
this.specialData.put(
jsonObject.getString("name"), new SpecialData(
Objects.requireNonNull(ISO_OFFSET_DATE_TIME.parse(
jsonObject.getString(
"pushed_at"))).getTime(),
jsonObject.optInt("stargazers_count")));
}
Files.write(metaDataCacheSpecial, data);
this.specialLastUpdate = System.currentTimeMillis();
} catch (ParseException e) {
throw new IOException(e);
}
}
}
}
public String getNameOrFallback(String fallback) { public String getNameOrFallback(String fallback) {
return this.name == null || return this.name == null ||
this.name.equals(this.url) ? this.name.equals(this.url) ?
@ -274,22 +178,4 @@ public class RepoData {
this.enabled = MainApplication.getSharedPreferences() this.enabled = MainApplication.getSharedPreferences()
.getBoolean("pref_" + this.id + "_enabled", true); .getBoolean("pref_" + this.id + "_enabled", true);
} }
private static class SpecialData {
SpecialData(long time, int stars) {
this.time = time; this.stars = stars;
}
final long time;
final int stars;
@NonNull
@Override
public String toString() {
return "SpecialData{" +
"time=" + time +
", stars=" + stars +
'}';
}
}
} }

@ -68,9 +68,9 @@ public final class RepoManager {
this.repoData = new LinkedHashMap<>(); this.repoData = new LinkedHashMap<>();
this.modules = new HashMap<>(); this.modules = new HashMap<>();
// We do not have repo list config yet. // We do not have repo list config yet.
this.addRepoData(MAGISK_REPO);
this.addRepoData(MAGISK_ALT_REPO); this.addRepoData(MAGISK_ALT_REPO);
this.addAndroidacyRepoData(); this.addAndroidacyRepoData();
this.addRepoData(MAGISK_REPO);
// Populate default cache // Populate default cache
for (RepoData repoData:this.repoData.values()) { for (RepoData repoData:this.repoData.values()) {
for (RepoModule repoModule:repoData.moduleHashMap.values()) { for (RepoModule repoModule:repoData.moduleHashMap.values()) {
@ -264,8 +264,7 @@ public final class RepoManager {
File cacheRoot = new File(this.mainApplication.getCacheDir(), id); File cacheRoot = new File(this.mainApplication.getCacheDir(), id);
SharedPreferences sharedPreferences = this.mainApplication SharedPreferences sharedPreferences = this.mainApplication
.getSharedPreferences("mmm_" + id, Context.MODE_PRIVATE); .getSharedPreferences("mmm_" + id, Context.MODE_PRIVATE);
RepoData repoData = new RepoData(url, cacheRoot, RepoData repoData = new RepoData(url, cacheRoot, sharedPreferences);
sharedPreferences, id.equals("magisk_repo"));
this.repoData.put(url, repoData); this.repoData.put(url, repoData);
return repoData; return repoData;
} }

@ -37,7 +37,6 @@ public class RepoUpdater {
return 0; return 0;
} }
this.indexRaw = Http.doHttpGet(this.repoData.url, false); this.indexRaw = Http.doHttpGet(this.repoData.url, false);
if (this.repoData.special) this.repoData.updateSpecialTimes(true);
this.toUpdate = this.repoData.populate(new JSONObject( this.toUpdate = this.repoData.populate(new JSONObject(
new String(this.indexRaw, StandardCharsets.UTF_8))); new String(this.indexRaw, StandardCharsets.UTF_8)));
// Since we reuse instances this should work // Since we reuse instances this should work

Loading…
Cancel
Save