diff --git a/app/src/main/java/com/akdev/nofbeventscraper/FbEvent.java b/app/src/main/java/com/akdev/nofbeventscraper/FbEvent.java index 717b12c..fa2d1eb 100644 --- a/app/src/main/java/com/akdev/nofbeventscraper/FbEvent.java +++ b/app/src/main/java/com/akdev/nofbeventscraper/FbEvent.java @@ -4,6 +4,10 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.format.FormatStyle; +/** + * Objects of this class store immutable information about + * a single event that was created by the FbScraper. + */ public class FbEvent { public final String url; @@ -26,18 +30,31 @@ public class FbEvent { this.image_url = image_url; } - - static Long dateTimeToEpoch(ZonedDateTime datetime) { + /** + * Converts datetime to epoch. + * + * @param zoned_date_time ZonedDateTime object + * @return Event begin time in milliseconds from the epoch for calendar intent or null + */ + static Long dateTimeToEpoch(ZonedDateTime zoned_date_time) { try { - return datetime.toEpochSecond() * 1000; + return zoned_date_time.toEpochSecond() * 1000; } catch (Exception e) { return null; } } - static String dateTimeToString(ZonedDateTime datetime) { + /** + * Returns a String representation of a ZonedDateTime + * + * @param zoned_date_time + * @return Locally formatted String of zoned_date_time or empty String + */ + static String dateTimeToString(ZonedDateTime zoned_date_time) { try { - return DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).format(datetime); + return DateTimeFormatter + .ofLocalizedDateTime(FormatStyle.LONG) + .format(zoned_date_time); } catch (Exception e) { return ""; } diff --git a/app/src/main/java/com/akdev/nofbeventscraper/FbScraper.java b/app/src/main/java/com/akdev/nofbeventscraper/FbScraper.java index a4f0dfc..6835c0d 100644 --- a/app/src/main/java/com/akdev/nofbeventscraper/FbScraper.java +++ b/app/src/main/java/com/akdev/nofbeventscraper/FbScraper.java @@ -19,35 +19,59 @@ import java.time.format.DateTimeFormatter; import java.util.regex.Matcher; import java.util.regex.Pattern; +/** + * This class can asynchronously scrape public facebook events + * and gather the most important information. It is stored in a FbEvent object. + */ public class FbScraper extends AsyncTask { private String error; - private String input_str; + private String input_url; private WeakReference main; // no context leak with WeakReference private FbEvent event; - FbScraper(WeakReference main, String str) { + /** + * Constructor with WeakReference to the main activity, to update it's text fields. + * + * @param main WeakReference of main activity to prevent context leak + * @param input_url Input url to scrape from + */ + FbScraper(WeakReference main, String input_url) { this.main = main; - this.input_str = str; + this.input_url = input_url; } - protected String fixURI(String str) throws URISyntaxException, MalformedURLException { + /** + * Strips the facebook event link of the input url. + * + * @param url input url + * @return facebook event url String if one was found + * @throws URISyntaxException if event not found + * @throws MalformedURLException + */ + protected String fixURI(String url) throws URISyntaxException, MalformedURLException { // check for url format - new URL(str).toURI(); + new URL(url).toURI(); Pattern pattern = Pattern.compile("(facebook.com/events/[0-9]*)"); - Matcher matcher = pattern.matcher(str); + Matcher matcher = pattern.matcher(url); if (matcher.find()) { // rewrite url to m.facebook and dismiss any query strings or referrals return "https://m." + matcher.group(1); } else { - throw new URISyntaxException(str, "Does not contain event."); + throw new URISyntaxException(url, "Does not contain event."); } } + /** + * Strips the event location from the json string. + * This can be a name only or a complete postal address. + * @param location_json JSON formatted string + * @return String representation of the location. + */ protected String fixLocation(String location_json) { String location_name = ""; @@ -67,7 +91,6 @@ public class FbScraper extends AsyncTask { // included in locality //String address_country = address.getString("addressCountry"); - return location_name + ", " + street_address + ", " + postal_code + " " @@ -82,6 +105,13 @@ public class FbScraper extends AsyncTask { } } + /** + * Parses a time string from the facebook event. + * Corrects format to ISO date time and parse into ZonedDateTime + * + * @param time_in time string from the event + * @return ZonedDateTime parsed from input or null + */ protected ZonedDateTime toZonedDateTime(String time_in) { try { @@ -98,6 +128,13 @@ public class FbScraper extends AsyncTask { } } + /** + * Replaces all occurrences of a facebook internal links in + * an event description into an actual URL. + * + * @param description_in description string from the event + * @return corrected String with internal links resolved + */ protected String fixDescriptionLinks(String description_in) { try { /* @[152580919265:274:SiteDescription] @@ -113,6 +150,12 @@ public class FbScraper extends AsyncTask { } } + /** + * Read a single field from a JSONObject + * @param reader JSONObject to read from + * @param field Which field to read + * @return String of the value of the field or empty string + */ private String readFromJson(JSONObject reader, String field) { try { return reader.getString(field); @@ -122,11 +165,17 @@ public class FbScraper extends AsyncTask { } } + /** + * Started by scraper.execute(). + * Gets the HTML doc from the input string and scrapes the event information from it. + * @param voids + * @return + */ @Override protected Void doInBackground(Void... voids) { try { - String url = fixURI(input_str); + String url = fixURI(input_url); // useragent needed with Jsoup > 1.12 Document document = Jsoup.connect(url).userAgent("Mozilla").get(); String json = document @@ -164,6 +213,11 @@ public class FbScraper extends AsyncTask { super.onPreExecute(); } + /** + * When scraping is finished, main activity will be updated. + * If an error occurred, main activity is given an error string. + * @param aVoid + */ protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); diff --git a/app/src/main/java/com/akdev/nofbeventscraper/MainActivity.java b/app/src/main/java/com/akdev/nofbeventscraper/MainActivity.java index e9c8a97..f1e9ed0 100644 --- a/app/src/main/java/com/akdev/nofbeventscraper/MainActivity.java +++ b/app/src/main/java/com/akdev/nofbeventscraper/MainActivity.java @@ -209,6 +209,9 @@ public class MainActivity extends AppCompatActivity { } + /** + * launch the FbScraper asynchronous task with the current text in the input text field. + */ public void startScraping() { error(null); @@ -222,6 +225,12 @@ public class MainActivity extends AppCompatActivity { layout_uri_input.setError(str); } + /** + * Clears all event text field strings and errors and also the input field depending if wanted. + * Loads the default banner into the toolbar image view and disables unneeded buttons. + * + * @param clear_uri Choose whether to clear the input uri field, too + */ public void clear(boolean clear_uri) { if (clear_uri) { @@ -235,7 +244,7 @@ public class MainActivity extends AppCompatActivity { edit_text_event_description.setText(""); edit_text_event_name.setError(null); -// edit_text_event_start.setError(null); + edit_text_event_start.setError(null); edit_text_event_end.setError(null); edit_text_event_location.setError(null); edit_text_event_description.setError(null); @@ -253,6 +262,12 @@ public class MainActivity extends AppCompatActivity { image_view_toolbar.setImageResource(R.drawable.ic_banner_foreground); } + /** + * Updates the text fields with the event information provided. + * If something is missing, the corresponding test field will show an error. + * + * @param scraped_event the event information that was scraped by FbScraper + */ public void update(FbEvent scraped_event) { this.event = scraped_event;