Skip to content

Commit aec1e51

Browse files
misaochanneslihanturan
authored andcommitted
Javadocs and minor refactoring for Nearby package (#2188)
* Add Traceur for getting meaningful RxJava stack traces (#1832) * Hotfix for overwrite issue in 2.8.0 (#1838) * This solution is an hotfix for overrite issue came back on 2.8.0 version. What I did is checking the extension, and if it is null, adding .jpg suffix. Because commons files always have suffixes, and we should compare file names after adding suffixes. Othervise overrides are possible. * Check if file title includes an extension already, by checking if is there any dot in it. * Fix logic error * Add uncovered tests * Remove unecessary line breaks * Make Javadocs more explicit * Versioning and changelog for v2.8.2 (#1842) * Versioning for v2.8.2 * Changelog for v2.8.2 * Delete unused MaterialShowcase class * Add Javadocs and fix lint errors for DirectUpload.java * Fix whitespace and add docs * Replace fragment.getActivity() with the parentActivity var * Rename unnecessarily-overloaded method getFromWikidataQuery(), add Javadocs * Javadocs and whitespaces for NearbyPlaces.java * Use local vars where possible instead of class fields. Non-constants should not be in all caps * Missed one unnecessary class field * Remove unnecessary whitespaces that don't improve readability * Add class summary * Optimize imports * Fix access modifiers in Place.java * Clearer Javadocs * Add Javadocs to Place.java * Remove residual conflict * Fix lint issues in Sitelinks * Javadocs for Sitelinks.java * DirectUpload: Replace nested conditionals with guard clauses
1 parent 4b58f16 commit aec1e51

File tree

5 files changed

+186
-100
lines changed

5 files changed

+186
-100
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
package fr.free.nrw.commons.nearby;
22

3+
import android.app.Activity;
34
import android.os.Build;
45
import android.support.v4.app.Fragment;
56
import android.support.v4.content.ContextCompat;
67
import android.support.v7.app.AlertDialog;
7-
import android.util.Log;
88

99
import fr.free.nrw.commons.R;
1010
import fr.free.nrw.commons.contributions.ContributionController;
1111
import fr.free.nrw.commons.utils.PermissionUtils;
12-
import timber.log.Timber;
1312

1413
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
1514
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
1615
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
1716

17+
/**
18+
* Initiates the uploads made from a Nearby Place, in both the list and map views.
19+
*/
1820
class DirectUpload {
1921

2022
private ContributionController controller;
@@ -25,59 +27,85 @@ class DirectUpload {
2527
this.controller = controller;
2628
}
2729

28-
// These permission requests will be handled by the Fragments.
29-
// Do not use requestCode 1 as it will conflict with NearbyFragment's requestCodes
30+
/**
31+
* Initiates the upload if user selects the Gallery FAB.
32+
* The permission requests will be handled by the Fragments.
33+
* Do not use requestCode 1 as it will conflict with NearbyFragment's requestCodes.
34+
*/
3035
void initiateGalleryUpload() {
31-
Log.d("deneme7","initiateGalleryUpload");
32-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
33-
if (ContextCompat.checkSelfPermission(fragment.getActivity(), READ_EXTERNAL_STORAGE) != PERMISSION_GRANTED) {
34-
if (fragment.shouldShowRequestPermissionRationale(READ_EXTERNAL_STORAGE)) {
35-
new AlertDialog.Builder(fragment.getActivity())
36-
.setMessage(fragment.getActivity().getString(R.string.read_storage_permission_rationale))
37-
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
38-
Timber.d("Requesting permissions for read external storage");
39-
fragment.getActivity().requestPermissions
40-
(new String[]{READ_EXTERNAL_STORAGE}, PermissionUtils.GALLERY_PERMISSION_FROM_NEARBY_MAP);
41-
dialog.dismiss();
42-
})
43-
.setNegativeButton(android.R.string.cancel, null)
44-
.create()
45-
.show();
46-
} else {
47-
fragment.getActivity().requestPermissions(new String[]{READ_EXTERNAL_STORAGE}, PermissionUtils.GALLERY_PERMISSION_FROM_NEARBY_MAP);
48-
}
49-
} else {
50-
controller.startSingleGalleryPick();
51-
}
36+
// Only need to handle permissions for Marshmallow and above
37+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
38+
return;
5239
}
53-
else {
40+
41+
Activity parentActivity = fragment.getActivity();
42+
if (parentActivity == null) {
43+
controller.startSingleGalleryPick();
44+
return;
45+
}
46+
47+
// If we have permission, go ahead
48+
if (ContextCompat.checkSelfPermission(parentActivity, READ_EXTERNAL_STORAGE) == PERMISSION_GRANTED) {
5449
controller.startSingleGalleryPick();
50+
return;
5551
}
52+
53+
// If we don't have permission, and we need to show the rationale, show the rationale
54+
if (fragment.shouldShowRequestPermissionRationale(READ_EXTERNAL_STORAGE)) {
55+
new AlertDialog.Builder(parentActivity)
56+
.setMessage(parentActivity.getString(R.string.read_storage_permission_rationale))
57+
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
58+
parentActivity.requestPermissions(new String[]{READ_EXTERNAL_STORAGE}, PermissionUtils.GALLERY_PERMISSION_FROM_NEARBY_MAP);
59+
dialog.dismiss();
60+
})
61+
.setNegativeButton(android.R.string.cancel, null)
62+
.create()
63+
.show();
64+
return;
65+
}
66+
67+
// If we don't have permission, and we don't need to show rationale just request permission
68+
parentActivity.requestPermissions(new String[]{READ_EXTERNAL_STORAGE}, PermissionUtils.GALLERY_PERMISSION_FROM_NEARBY_MAP);
5669
}
5770

71+
/**
72+
* Initiates the upload if user selects the Camera FAB.
73+
* The permission requests will be handled by the Fragments.
74+
* Do not use requestCode 1 as it will conflict with NearbyFragment's requestCodes.
75+
*/
5876
void initiateCameraUpload() {
59-
Log.d("deneme7","initiateCameraUpload");
60-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
61-
if (ContextCompat.checkSelfPermission(fragment.getActivity(), WRITE_EXTERNAL_STORAGE) != PERMISSION_GRANTED) {
62-
if (fragment.shouldShowRequestPermissionRationale(WRITE_EXTERNAL_STORAGE)) {
63-
new AlertDialog.Builder(fragment.getActivity())
64-
.setMessage(fragment.getActivity().getString(R.string.write_storage_permission_rationale))
65-
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
66-
fragment.getActivity().requestPermissions
67-
(new String[]{WRITE_EXTERNAL_STORAGE}, PermissionUtils.CAMERA_PERMISSION_FROM_NEARBY_MAP);
68-
dialog.dismiss();
69-
})
70-
.setNegativeButton(android.R.string.cancel, null)
71-
.create()
72-
.show();
73-
} else {
74-
fragment.getActivity().requestPermissions(new String[]{WRITE_EXTERNAL_STORAGE}, PermissionUtils.CAMERA_PERMISSION_FROM_NEARBY_MAP);
75-
}
76-
} else {
77-
controller.startCameraCapture();
78-
}
79-
} else {
77+
// Only need to handle permissions for Marshmallow and above
78+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
79+
return;
80+
}
81+
82+
Activity parentActivity = fragment.getActivity();
83+
if (parentActivity == null) {
84+
controller.startCameraCapture();
85+
return;
86+
}
87+
88+
// If we have permission, go ahead
89+
if (ContextCompat.checkSelfPermission(parentActivity, WRITE_EXTERNAL_STORAGE) == PERMISSION_GRANTED) {
8090
controller.startCameraCapture();
91+
return;
8192
}
93+
94+
// If we don't have permission, and we need to show the rationale, show the rationale
95+
if (fragment.shouldShowRequestPermissionRationale(WRITE_EXTERNAL_STORAGE)) {
96+
new AlertDialog.Builder(parentActivity)
97+
.setMessage(parentActivity.getString(R.string.write_storage_permission_rationale))
98+
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
99+
parentActivity.requestPermissions(new String[]{WRITE_EXTERNAL_STORAGE}, PermissionUtils.CAMERA_PERMISSION_FROM_NEARBY_MAP);
100+
dialog.dismiss();
101+
})
102+
.setNegativeButton(android.R.string.cancel, null)
103+
.create()
104+
.show();
105+
return;
106+
}
107+
108+
// If we don't have permission, and we don't need to show rationale just request permission
109+
parentActivity.requestPermissions(new String[]{WRITE_EXTERNAL_STORAGE}, PermissionUtils.CAMERA_PERMISSION_FROM_NEARBY_MAP);
82110
}
83111
}

app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public NearbyPlacesInfo loadAttractionsFromLocation(LatLng curLatLng, LatLng lat
6060
Timber.d("Loading attractions neari, but curLatLng is null");
6161
return null;
6262
}
63-
List<Place> places = nearbyPlaces.getFromWikidataQuery(latLangToSearchAround, Locale.getDefault().getLanguage(), returnClosestResult);
63+
List<Place> places = nearbyPlaces.radiusExpander(latLangToSearchAround, Locale.getDefault().getLanguage(), returnClosestResult);
6464

6565
if (null != places && places.size() > 0) {
6666
LatLng[] boundaryCoordinates = {places.get(0).location, // south

app/src/main/java/fr/free/nrw/commons/nearby/NearbyPlaces.java

+34-46
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@
2121
import fr.free.nrw.commons.upload.FileUtils;
2222
import timber.log.Timber;
2323

24+
/**
25+
* Handles the Wikidata query to obtain Places around search location
26+
*/
2427
public class NearbyPlaces {
2528

26-
private static int MIN_RESULTS = 40;
2729
private static final double INITIAL_RADIUS = 1.0; // in kilometers
28-
private static double MAX_RADIUS = 300.0; // in kilometers
2930
private static final double RADIUS_MULTIPLIER = 1.618;
3031
private static final Uri WIKIDATA_QUERY_URL = Uri.parse("https://query.wikidata.org/sparql");
3132
private static final Uri WIKIDATA_QUERY_UI_URL = Uri.parse("https://query.wikidata.org/");
@@ -46,73 +47,63 @@ public NearbyPlaces() {
4647
}
4748

4849
/**
49-
* Returns list of nearby places around curLatLng or closest result near curLatLng. This decision
50-
* is made according to returnClosestResult variable. If returnClosestResult true, then our
51-
* number of min results set to 1, and max radius to search is set to 5. If there is no place
52-
* in 5 km radius, empty list will be returned. This method sets radius variable according to
53-
* search type (returnClosestResult or not), but search operation will be handled in overloaded
54-
* method below, which is called from this method.
55-
* @param curLatLng Our reference location
56-
* @param lang Language we will display results in
57-
* @param returnClosestResult If true, return only first result found, else found satisfactory
58-
* number of results
59-
* @return List of nearby places around, or closest nearby place
60-
* @throws IOException
50+
* Expands the radius as needed for the Wikidata query
51+
* @param curLatLng coordinates of search location
52+
* @param lang user's language
53+
* @param returnClosestResult true if only the nearest point is desired
54+
* @return list of places obtained
55+
* @throws IOException if query fails
6156
*/
62-
List<Place> getFromWikidataQuery(LatLng curLatLng, String lang, boolean returnClosestResult) throws IOException {
57+
List<Place> radiusExpander(LatLng curLatLng, String lang, boolean returnClosestResult) throws IOException {
58+
59+
int minResults;
60+
double maxRadius;
61+
6362
List<Place> places = Collections.emptyList();
6463

65-
/**
66-
* If returnClosestResult is true, then this means that we are trying to get closest point
67-
* to use in cardView above contributions list
68-
*/
64+
// If returnClosestResult is true, then this means that we are trying to get closest point
65+
// to use in cardView in Contributions fragment
6966
if (returnClosestResult) {
70-
MIN_RESULTS = 1; // Return closest nearby place
71-
MAX_RADIUS = 5; // Return places only in 5 km area
67+
minResults = 1; // Return closest nearby place
68+
maxRadius = 5; // Return places only in 5 km area
7269
radius = INITIAL_RADIUS; // refresh radius again, otherwise increased radius is grater than MAX_RADIUS, thus returns null
7370
} else {
74-
MIN_RESULTS = 40;
75-
MAX_RADIUS = 300.0; // in kilometers
71+
minResults = 40;
72+
maxRadius = 300.0; // in kilometers
7673
radius = INITIAL_RADIUS;
7774
}
7875

79-
// increase the radius gradually to find a satisfactory number of nearby places
80-
while (radius <= MAX_RADIUS) {
76+
// Increase the radius gradually to find a satisfactory number of nearby places
77+
while (radius <= maxRadius) {
8178
try {
8279
places = getFromWikidataQuery(curLatLng, lang, radius);
8380
} catch (InterruptedIOException e) {
8481
Timber.d("exception in fetching nearby places", e.getLocalizedMessage());
8582
return places;
8683
}
8784
Timber.d("%d results at radius: %f", places.size(), radius);
88-
if (places.size() >= MIN_RESULTS) {
85+
if (places.size() >= minResults) {
8986
break;
9087
} else {
9188
radius *= RADIUS_MULTIPLIER;
9289
}
9390
}
9491
// make sure we will be able to send at least one request next time
95-
if (radius > MAX_RADIUS) {
96-
radius = MAX_RADIUS;
92+
if (radius > maxRadius) {
93+
radius = maxRadius;
9794
}
98-
9995
return places;
10096
}
10197

10298
/**
103-
* Creates and sends query for nearby wikidata items needs picture.
104-
* Reads results from query and turns them into meaningful place variables.
105-
* Adds them to the list of places.
106-
* @param cur Our reference location to check around
107-
* @param lang Language we will display results in
108-
* @param radius Our query area is a circle, where cur is center and radius is radius
109-
* @return
110-
* @throws IOException
99+
* Runs the Wikidata query to populate the Places around search location
100+
* @param cur coordinates of search location
101+
* @param lang user's language
102+
* @param radius radius for search, as determined by radiusExpander()
103+
* @return list of places obtained
104+
* @throws IOException if query fails
111105
*/
112-
private List<Place> getFromWikidataQuery(LatLng cur,
113-
String lang,
114-
double radius)
115-
throws IOException {
106+
private List<Place> getFromWikidataQuery(LatLng cur, String lang, double radius) throws IOException {
116107
List<Place> places = new ArrayList<>();
117108

118109
String query = wikidataQuery
@@ -125,8 +116,7 @@ private List<Place> getFromWikidataQuery(LatLng cur,
125116

126117
// format as a URL
127118
Timber.d(WIKIDATA_QUERY_UI_URL.buildUpon().fragment(query).build().toString());
128-
String url = WIKIDATA_QUERY_URL.buildUpon()
129-
.appendQueryParameter("query", query).build().toString();
119+
String url = WIKIDATA_QUERY_URL.buildUpon().appendQueryParameter("query", query).build().toString();
130120
URLConnection conn = new URL(url).openConnection();
131121
conn.setRequestProperty("Accept", "text/tab-separated-values");
132122
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
@@ -162,8 +152,7 @@ private List<Place> getFromWikidataQuery(LatLng cur,
162152

163153
double latitude;
164154
double longitude;
165-
Matcher matcher =
166-
Pattern.compile("Point\\(([^ ]+) ([^ ]+)\\)").matcher(point);
155+
Matcher matcher = Pattern.compile("Point\\(([^ ]+) ([^ ]+)\\)").matcher(point);
167156
if (!matcher.find()) {
168157
continue;
169158
}
@@ -192,5 +181,4 @@ private List<Place> getFromWikidataQuery(LatLng cur,
192181

193182
return places;
194183
}
195-
196184
}

0 commit comments

Comments
 (0)