44import android .content .SharedPreferences ;
55import android .util .Log ;
66
7+ import androidx .annotation .NonNull ;
8+
9+ import com .fox2code .mmm .R ;
710import com .fox2code .mmm .manager .ModuleInfo ;
811import com .fox2code .mmm .utils .Files ;
912import com .fox2code .mmm .utils .Http ;
2730import java .util .Objects ;
2831
2932public class RepoData {
33+ private static final String TAG = "RepoData" ;
3034 private final Object populateLock = new Object ();
3135 public final String url ;
3236 public final File cacheRoot ;
@@ -36,7 +40,7 @@ public class RepoData {
3640 public final HashMap <String , RepoModule > moduleHashMap ;
3741 public long lastUpdate ;
3842 public String name ;
39- private final Map <String , Long > specialTimes ;
43+ private final Map <String , SpecialData > specialData ;
4044 private long specialLastUpdate ;
4145
4246 protected RepoData (String url , File cacheRoot , SharedPreferences cachedPreferences ) {
@@ -51,7 +55,7 @@ protected RepoData(String url, File cacheRoot, SharedPreferences cachedPreferenc
5155 this .special = special ;
5256 this .moduleHashMap = new HashMap <>();
5357 this .name = this .url ; // Set url as default name
54- this .specialTimes = special ? new HashMap <>() : Collections .emptyMap ();
58+ this .specialData = special ? new HashMap <>() : Collections .emptyMap ();
5559 if (!this .cacheRoot .isDirectory ()) {
5660 this .cacheRoot .mkdirs ();
5761 } else {
@@ -63,10 +67,13 @@ protected RepoData(String url, File cacheRoot, SharedPreferences cachedPreferenc
6367 Files .read (this .metaDataCache ), StandardCharsets .UTF_8 ));
6468 for (int i = 0 ; i < jsonArray .length (); i ++) {
6569 JSONObject jsonObject = jsonArray .getJSONObject (i );
66- this .specialTimes .put (jsonObject .getString ("name" ),
67- Objects .requireNonNull (ISO_OFFSET_DATE_TIME .parse (
68- jsonObject .getString ("pushed_at" ))).getTime ());
69- Log .d ("RepoData" , "Got " +
70+ this .specialData .put (
71+ jsonObject .getString ("name" ), new SpecialData (
72+ Objects .requireNonNull (ISO_OFFSET_DATE_TIME .parse (
73+ jsonObject .getString (
74+ "pushed_at" ))).getTime (),
75+ jsonObject .optInt ("stargazers_count" )));
76+ Log .d (TAG , "Got " +
7077 jsonObject .getString ("name" ) + " from local storage!" );
7178 }
7279 this .specialLastUpdate = metaDataCacheSpecial .lastModified ();
@@ -79,6 +86,10 @@ protected RepoData(String url, File cacheRoot, SharedPreferences cachedPreferenc
7986 }
8087 }
8188 if (this .metaDataCache .exists ()) {
89+ this .lastUpdate = metaDataCache .lastModified ();
90+ if (this .lastUpdate > System .currentTimeMillis ()) {
91+ this .lastUpdate = 0 ; // Don't allow time travel
92+ }
8293 try {
8394 List <RepoModule > modules = this .populate (new JSONObject (
8495 new String (Files .read (this .metaDataCache ), StandardCharsets .UTF_8 )));
@@ -108,24 +119,22 @@ protected List<RepoModule> populate(JSONObject jsonObject) throws JSONException
108119 for (RepoModule repoModule : this .moduleHashMap .values ()) {
109120 repoModule .processed = false ;
110121 }
111- Log .d ("RepoData" , "Data: " + this .specialTimes .toString ());
112122 JSONArray array = jsonObject .getJSONArray ("modules" );
113123 int len = array .length ();
114124 for (int i = 0 ; i < len ; i ++) {
115125 JSONObject module = array .getJSONObject (i );
116126 String moduleId = module .getString ("id" );
117127 // Deny remote modules ids shorter than 3 chars long or that start with a digit
118128 if (moduleId .length () < 3 || Character .isDigit (moduleId .charAt (0 ))) continue ;
119- Long moduleLastUpdateSpecial = this .specialTimes .get (moduleId );
129+ SpecialData moduleSpecialData = this .specialData .get (moduleId );
120130 long moduleLastUpdate = module .getLong ("last_update" );
121131 String moduleNotesUrl = module .getString ("notes_url" );
122132 String modulePropsUrl = module .getString ("prop_url" );
123133 String moduleZipUrl = module .getString ("zip_url" );
124134 String moduleChecksum = module .optString ("checksum" );
125- if (moduleLastUpdateSpecial != null ) { // Fix last update time
126- Log .d ("RepoData" , "Data: " + moduleLastUpdate + " -> " +
127- moduleLastUpdateSpecial + " for " + moduleId );
128- moduleLastUpdate = Math .max (moduleLastUpdate , moduleLastUpdateSpecial );
135+ String moduleStars = module .optString ("stars" );
136+ if (moduleSpecialData != null ) { // Fix last update time
137+ moduleLastUpdate = Math .max (moduleLastUpdate , moduleSpecialData .time );
129138 moduleNotesUrl = Http .updateLink (moduleNotesUrl );
130139 modulePropsUrl = Http .updateLink (modulePropsUrl );
131140 moduleZipUrl = Http .updateLink (moduleZipUrl );
@@ -152,6 +161,15 @@ protected List<RepoModule> populate(JSONObject jsonObject) throws JSONException
152161 repoModule .propUrl = modulePropsUrl ;
153162 repoModule .zipUrl = moduleZipUrl ;
154163 repoModule .checksum = moduleChecksum ;
164+ if (moduleSpecialData != null ) {
165+ repoModule .qualityValue = moduleSpecialData .stars ;
166+ repoModule .qualityText = R .string .module_stars ;
167+ } else if (!moduleStars .isEmpty ()) {
168+ try {
169+ repoModule .qualityValue = Integer .parseInt (moduleStars );
170+ repoModule .qualityText = R .string .module_stars ;
171+ } catch (NumberFormatException ignored ) {}
172+ }
155173 }
156174 // Remove no longer existing modules
157175 Iterator <RepoModule > moduleInfoIterator = this .moduleHashMap .values ().iterator ();
@@ -184,6 +202,12 @@ public boolean tryLoadMetadata(RepoModule repoModule) {
184202 if (moduleInfo .version == null ) {
185203 moduleInfo .version = "v" + moduleInfo .versionCode ;
186204 }
205+ SpecialData moduleSpecialData =
206+ this .specialData .get (repoModule .id );
207+ if (moduleSpecialData != null ) {
208+ repoModule .qualityValue = moduleSpecialData .stars ;
209+ repoModule .qualityText = R .string .module_stars ;
210+ }
187211 return true ;
188212 } catch (Exception ignored ) {
189213 file .delete ();
@@ -200,20 +224,24 @@ public boolean tryLoadMetadata(RepoModule repoModule) {
200224 public void updateSpecialTimes (boolean force ) throws IOException , JSONException {
201225 if (!this .special ) return ;
202226 synchronized (this .populateLock ) {
203- if (this .specialLastUpdate == 0L ||
204- ( force && this .specialLastUpdate < System .currentTimeMillis () - 60000L )) {
227+ if (this .specialLastUpdate == 0L || ( force && ( this . specialData . isEmpty () ||
228+ this .specialLastUpdate < System .currentTimeMillis () - 60000L ) )) {
205229 File metaDataCacheSpecial = new File (cacheRoot , "modules_times.json" );
206- this .specialTimes .clear ();
230+ this .specialData .clear ();
207231 try {
232+ // Requesting only 32 most recently pushed repos
208233 byte [] data = Http .doHttpGet (
209- "https://api.github.com/users/Magisk-Modules-Repo/repos" ,
210- false );
234+ "https://api.github.com/users/Magisk-Modules-Repo/" +
235+ "repos?sort=pushed&per_page=32" , false );
211236 JSONArray jsonArray = new JSONArray (new String (data , StandardCharsets .UTF_8 ));
212237 for (int i = 0 ;i < jsonArray .length ();i ++) {
213238 JSONObject jsonObject = jsonArray .optJSONObject (i );
214- this .specialTimes .put (jsonObject .getString ("name" ),
215- Objects .requireNonNull (ISO_OFFSET_DATE_TIME .parse (
216- jsonObject .getString ("pushed_at" ))).getTime ());
239+ this .specialData .put (
240+ jsonObject .getString ("name" ), new SpecialData (
241+ Objects .requireNonNull (ISO_OFFSET_DATE_TIME .parse (
242+ jsonObject .getString (
243+ "pushed_at" ))).getTime (),
244+ jsonObject .optInt ("stargazers_count" )));
217245 }
218246 Files .write (metaDataCacheSpecial , data );
219247 this .specialLastUpdate = System .currentTimeMillis ();
@@ -229,4 +257,22 @@ public String getNameOrFallback(String fallback) {
229257 this .name .equals (this .url ) ?
230258 fallback : this .name ;
231259 }
260+
261+ private static class SpecialData {
262+ SpecialData (long time , int stars ) {
263+ this .time = time ; this .stars = stars ;
264+ }
265+
266+ final long time ;
267+ final int stars ;
268+
269+ @ NonNull
270+ @ Override
271+ public String toString () {
272+ return "SpecialData{" +
273+ "time=" + time +
274+ ", stars=" + stars +
275+ '}' ;
276+ }
277+ }
232278}
0 commit comments