diff --git a/app/src/main/java/fr/free/nrw/commons/category/CategorizationFragment.java b/app/src/main/java/fr/free/nrw/commons/category/CategorizationFragment.java index d8f5cef48..ca8300172 100644 --- a/app/src/main/java/fr/free/nrw/commons/category/CategorizationFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/category/CategorizationFragment.java @@ -41,6 +41,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -217,11 +218,11 @@ public class CategorizationFragment extends Fragment { Log.d(TAG, "Adding title items: " + titleItems); mergedItems.addAll(recentItems); Log.d(TAG, "Adding recent items: " + recentItems); - + //Needs to be an ArrayList and not a List unless we want to modify a big portion of preexisting code ArrayList mergedItemsList = new ArrayList(mergedItems); - Log.d(TAG, "Merged item list: " + mergedItemsList); + Log.d(TAG, "Merged item list: " + mergedItemsList); return mergedItemsList; } diff --git a/app/src/main/java/fr/free/nrw/commons/category/MethodAUpdater.java b/app/src/main/java/fr/free/nrw/commons/category/MethodAUpdater.java index 5ac3f3bf2..32f8660bf 100644 --- a/app/src/main/java/fr/free/nrw/commons/category/MethodAUpdater.java +++ b/app/src/main/java/fr/free/nrw/commons/category/MethodAUpdater.java @@ -10,6 +10,8 @@ import org.mediawiki.api.MWApi; import java.io.IOException; import java.util.ArrayList; +import java.util.Calendar; +import java.util.Iterator; import fr.free.nrw.commons.CommonsApplication; @@ -38,16 +40,59 @@ public class MethodAUpdater extends AsyncTask> { catFragment.categoriesSkip.setVisibility(View.GONE); } + /** + * Remove categories that contain a year in them (starting with 19__ or 20__), except for this year + * and previous year + * Rationale: https://github.com/commons-app/apps-android-commons/issues/47 + * @param items Unfiltered list of categories + * @return Filtered category list + */ + private ArrayList filterYears(ArrayList items) { + + Iterator iterator; + + //Check for current and previous year to exclude these categories from removal + Calendar now = Calendar.getInstance(); + int year = now.get(Calendar.YEAR); + String yearInString = String.valueOf(year); + Log.d(TAG, "Year: " + yearInString); + + int prevYear = year - 1; + String prevYearInString = String.valueOf(prevYear); + Log.d(TAG, "Previous year: " + prevYearInString); + + //Copy to Iterator to prevent ConcurrentModificationException when removing item + for(iterator = items.iterator(); iterator.hasNext();) { + String s = iterator.next(); + + //Check if s contains a 4-digit word anywhere within the string (.* is wildcard) + //And that s does not equal the current year or previous year + if(s.matches(".*(19|20)\\d{2}.*") && !s.contains(yearInString) && !s.contains(prevYearInString)) { + Log.d(TAG, "Filtering out year " + s); + iterator.remove(); + } + } + + Log.d(TAG, "Items: " + items.toString()); + return items; + } + @Override protected ArrayList doInBackground(Void... voids) { //If user hasn't typed anything in yet, get GPS and recent items if(TextUtils.isEmpty(filter)) { - return catFragment.mergeItems(); + ArrayList mergedItems = new ArrayList(catFragment.mergeItems()); + Log.d(TAG, "Merged items, waiting for filter"); + ArrayList filteredItems = new ArrayList(filterYears(mergedItems)); + return filteredItems; } //if user types in something that is in cache, return cached category if(catFragment.categoriesCache.containsKey(filter)) { - return catFragment.categoriesCache.get(filter); + ArrayList cachedItems = new ArrayList(catFragment.categoriesCache.get(filter)); + Log.d(TAG, "Found cache items, waiting for filter"); + ArrayList filteredItems = new ArrayList(filterYears(cachedItems)); + return filteredItems; } //otherwise if user has typed something in that isn't in cache, search API for matching categories @@ -79,6 +124,8 @@ public class MethodAUpdater extends AsyncTask> { categories.add(catString); } - return categories; + Log.d(TAG, "Found categories from Method A search, waiting for filter"); + ArrayList filteredItems = new ArrayList(filterYears(categories)); + return filteredItems; } } diff --git a/app/src/main/java/fr/free/nrw/commons/category/PrefixUpdater.java b/app/src/main/java/fr/free/nrw/commons/category/PrefixUpdater.java index b095bfe6a..39acc0385 100644 --- a/app/src/main/java/fr/free/nrw/commons/category/PrefixUpdater.java +++ b/app/src/main/java/fr/free/nrw/commons/category/PrefixUpdater.java @@ -10,11 +10,16 @@ import org.mediawiki.api.MWApi; import java.io.IOException; import java.util.ArrayList; +import java.util.Calendar; +import java.util.Iterator; +import java.util.List; import javax.net.ssl.SSLPeerUnverifiedException; import fr.free.nrw.commons.CommonsApplication; +import static android.R.id.list; + /** * Sends asynchronous queries to the Commons MediaWiki API to retrieve categories that share the * same prefix as the keyword typed in by the user. The 'acprefix' action-specific parameter is used @@ -41,16 +46,59 @@ public class PrefixUpdater extends AsyncTask> { catFragment.categoriesSkip.setVisibility(View.GONE); } + /** + * Remove categories that contain a year in them (starting with 19__ or 20__), except for this year + * and previous year + * Rationale: https://github.com/commons-app/apps-android-commons/issues/47 + * @param items Unfiltered list of categories + * @return Filtered category list + */ + private ArrayList filterYears(ArrayList items) { + + Iterator iterator; + + //Check for current and previous year to exclude these categories from removal + Calendar now = Calendar.getInstance(); + int year = now.get(Calendar.YEAR); + String yearInString = String.valueOf(year); + Log.d(TAG, "Year: " + yearInString); + + int prevYear = year - 1; + String prevYearInString = String.valueOf(prevYear); + Log.d(TAG, "Previous year: " + prevYearInString); + + //Copy to Iterator to prevent ConcurrentModificationException when removing item + for(iterator = items.iterator(); iterator.hasNext();) { + String s = iterator.next(); + + //Check if s contains a 4-digit word anywhere within the string (.* is wildcard) + //And that s does not equal the current year or previous year + if(s.matches(".*(19|20)\\d{2}.*") && !s.contains(yearInString) && !s.contains(prevYearInString)) { + Log.d(TAG, "Filtering out year " + s); + iterator.remove(); + } + } + + Log.d(TAG, "Items: " + items.toString()); + return items; + } + @Override protected ArrayList doInBackground(Void... voids) { //If user hasn't typed anything in yet, get GPS and recent items if(TextUtils.isEmpty(filter)) { - return catFragment.mergeItems(); + ArrayList mergedItems = new ArrayList(catFragment.mergeItems()); + Log.d(TAG, "Merged items, waiting for filter"); + ArrayList filteredItems = new ArrayList(filterYears(mergedItems)); + return filteredItems; } //if user types in something that is in cache, return cached category if(catFragment.categoriesCache.containsKey(filter)) { - return catFragment.categoriesCache.get(filter); + ArrayList cachedItems = new ArrayList(catFragment.categoriesCache.get(filter)); + Log.d(TAG, "Found cache items, waiting for filter"); + ArrayList filteredItems = new ArrayList(filterYears(cachedItems)); + return filteredItems; } //otherwise if user has typed something in that isn't in cache, search API for matching categories @@ -76,6 +124,8 @@ public class PrefixUpdater extends AsyncTask> { categories.add(categoryNode.getDocument().getTextContent()); } - return categories; + Log.d(TAG, "Found categories from Prefix search, waiting for filter"); + ArrayList filteredItems = new ArrayList(filterYears(categories)); + return filteredItems; } } diff --git a/find-broken-strings-variables.sh b/find-broken-strings-variables.sh index 7110fb4ab..f5f3cee66 100755 --- a/find-broken-strings-variables.sh +++ b/find-broken-strings-variables.sh @@ -2,11 +2,13 @@ # Spot malformed string replacement patterns in Android localization files. # First install Lint from the Android SDK -grep -R "%1$ s" res/values* -grep -R "%1$ d" res/values* -grep -R "%1" res/values* | grep -v "%1\\$" +VALUES=app/src/main/res/values -grep -RH '%' res/values* | +grep -R "%1$ s" $VALUES* +grep -R "%1$ d" $VALUES* +grep -R "%1" $VALUES* | grep -v "%1\\$" + +grep -RH '%' $VALUES* | sed -e 's/%/\n%/g' | # Split lines that contain several expressions grep '%' | # Filter out lines that do not contain expressions grep -v ' % ' | # Lone % character, not a variable @@ -23,10 +25,10 @@ grep -RH '%' res/values* | grep -v '%20' # Ignore URL whitespace exit # Double-width percent sign -grep -R '%' res/values* +grep -R '%' $VALUES* # Broken CDATA syntax -grep -R "CDATA " res/values* +grep -R "CDATA " $VALUES* # Android SDK Lint (does not detect most syntax errors) lint --check StringFormatInvalid commons