aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/java/org
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java/org')
-rw-r--r--app/src/main/java/org/rssin/android/FilterActivity.java139
-rw-r--r--app/src/main/java/org/rssin/android/FiltersActivity.java8
-rw-r--r--app/src/main/java/org/rssin/android/VolleyFetcher.java59
-rw-r--r--app/src/main/java/org/rssin/http/Fetcher.java13
-rw-r--r--app/src/main/java/org/rssin/http/Request.java20
-rw-r--r--app/src/main/java/org/rssin/listener/DismissListener.java15
-rw-r--r--app/src/main/java/org/rssin/listener/ErrorListener.java8
-rw-r--r--app/src/main/java/org/rssin/listener/FallibleListener.java7
-rw-r--r--app/src/main/java/org/rssin/listener/Listener.java8
-rw-r--r--app/src/main/java/org/rssin/listener/RealtimeListener.java8
-rwxr-xr-xapp/src/main/java/org/rssin/neurons/SentenceSplitter.java5
-rw-r--r--app/src/main/java/org/rssin/rss/FeedLoader.java49
-rwxr-xr-xapp/src/main/java/org/rssin/rssin/FeedLoaderAndSorter.java68
-rwxr-xr-xapp/src/main/java/org/rssin/rssin/Filter.java2
14 files changed, 371 insertions, 38 deletions
diff --git a/app/src/main/java/org/rssin/android/FilterActivity.java b/app/src/main/java/org/rssin/android/FilterActivity.java
new file mode 100644
index 0000000..145a60b
--- /dev/null
+++ b/app/src/main/java/org/rssin/android/FilterActivity.java
@@ -0,0 +1,139 @@
+package org.rssin.android;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.support.v7.app.ActionBarActivity;
+import android.os.Bundle;
+import android.text.Html;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.android.volley.VolleyError;
+
+import org.rssin.listener.FallibleListener;
+import org.rssin.rss.FeedItem;
+import org.rssin.rssin.FeedLoaderAndSorter;
+import org.rssin.rssin.Filter;
+import org.rssin.rssin.Keyword;
+import org.rssin.rssin.R;
+
+import java.io.IOException;
+import java.util.List;
+
+public class FilterActivity extends ActionBarActivity {
+
+ private FiltersList filtersList;
+ private Filter filter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_filter);
+
+ try {
+ filtersList = FiltersList.getInstance(this);
+ } catch (IOException e) {
+ Toast.makeText(this, getResources().getString(R.string.error_load_filters), Toast.LENGTH_SHORT).show();
+ }
+
+ Intent intent = getIntent();
+ int filterHashCode = intent.getIntExtra("filter", -1);
+
+ // @todo Check on -1? Shouldn't happen anyway.
+ filter = filtersList.getFilterFromHashCode(filterHashCode);
+
+ final Activity activity = this;
+ final ListView itemsListView = (ListView) findViewById(R.id.filter_items_list);
+ FeedLoaderAndSorter loaderAndSorter = new FeedLoaderAndSorter(filter);
+ loaderAndSorter.getFilteredFeedItems(new VolleyFetcher(this), new FallibleListener<List<FeedItem>,VolleyError>() {
+ @Override
+ public void onReceive(List<FeedItem> data) {
+ FeedItemAdapter feedItemAdapter = new FeedItemAdapter(activity, R.layout.item_feeditem, data);
+ itemsListView.setAdapter(feedItemAdapter);
+ }
+
+ @Override
+ public void onError(VolleyError error) {
+ Log.e("FA", "VolleyError", error);
+ }
+ });
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_filter, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ int id = item.getItemId();
+
+ if (id == R.id.action_settings) {
+ Intent intent = new Intent(getApplicationContext(), FilterSettingsActivity.class);
+ intent.putExtra("filter", filter.hashCode());
+ startActivity(intent);
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ /**
+ * Custom ArrayAdapter to display Keywords
+ */
+ private static class FeedItemAdapter extends ArrayAdapter<FeedItem> {
+ Context context;
+ int layoutResourceId;
+ List<FeedItem> feedItems;
+
+ public FeedItemAdapter(Context context, int resource, List<FeedItem> objects) {
+ super(context, resource, objects);
+ this.context = context;
+ layoutResourceId = resource;
+ feedItems = objects;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View row = convertView;
+ KeywordHolder holder = null;
+
+ if (row == null) {
+ LayoutInflater inflater = ((Activity) context).getLayoutInflater();
+ row = inflater.inflate(layoutResourceId, parent, false);
+
+ holder = new KeywordHolder();
+ holder.title = (TextView) row.findViewById(R.id.feeditem_title);
+ holder.summary = (TextView) row.findViewById(R.id.feeditem_summary);
+
+ row.setTag(holder);
+ } else {
+ holder = (KeywordHolder) row.getTag();
+ }
+
+ FeedItem feedItem = feedItems.get(position);
+ holder.title.setText(feedItem.getTitle());
+ holder.summary.setText(Html.fromHtml(feedItem.getDescription()));
+
+ return row;
+ }
+
+ /**
+ * TextViews holder
+ */
+ private static class KeywordHolder {
+ TextView title;
+ TextView summary;
+ }
+ }
+}
diff --git a/app/src/main/java/org/rssin/android/FiltersActivity.java b/app/src/main/java/org/rssin/android/FiltersActivity.java
index b7de210..b5f8760 100644
--- a/app/src/main/java/org/rssin/android/FiltersActivity.java
+++ b/app/src/main/java/org/rssin/android/FiltersActivity.java
@@ -102,7 +102,7 @@ public class FiltersActivity extends ActionBarActivity {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Filter item = (Filter) parent.getItemAtPosition(position);
- // @Todo open filter
+ openFilter(item);
}
};
onFilterLongClickListener = new AdapterView.OnItemLongClickListener() {
@@ -175,6 +175,12 @@ public class FiltersActivity extends ActionBarActivity {
startActivity(intent);
}
+ public void openFilter(Filter f) {
+ Intent intent = new Intent(getApplicationContext(), FilterActivity.class);
+ intent.putExtra("filter", f.hashCode());
+ startActivity(intent);
+ }
+
/**
* Custom ArrayAdapter to display filters with our own menu item
*/
diff --git a/app/src/main/java/org/rssin/android/VolleyFetcher.java b/app/src/main/java/org/rssin/android/VolleyFetcher.java
new file mode 100644
index 0000000..d853255
--- /dev/null
+++ b/app/src/main/java/org/rssin/android/VolleyFetcher.java
@@ -0,0 +1,59 @@
+package org.rssin.android;
+
+import android.content.Context;
+
+import com.android.volley.Request.Method;
+import com.android.volley.RequestQueue;
+import com.android.volley.VolleyError;
+import com.android.volley.toolbox.StringRequest;
+import com.android.volley.toolbox.Volley;
+
+import org.rssin.http.Fetcher;
+import org.rssin.http.Request;
+import org.rssin.listener.ErrorListener;
+import org.rssin.listener.Listener;
+
+/**
+ * Created by camilstaps on 21-5-15.
+ */
+public class VolleyFetcher implements Fetcher {
+
+ private final Context context;
+ private final RequestQueue requestQueue;
+
+ public VolleyFetcher(Context context) {
+ this.context = context;
+ requestQueue = Volley.newRequestQueue(context);
+ }
+
+ @Override
+ public void fetch(Request request) {
+ fetch(request, null);
+ }
+
+ @Override
+ public void fetch(Request request, final Listener listener) {
+ StringRequest stringRequest = new StringRequest(
+ Method.GET,
+ request.getURL().toString(),
+ new com.android.volley.Response.Listener<String>() {
+ @Override
+ public void onResponse(String s) {
+ try {
+ listener.onReceive(s);
+ } catch (ClassCastException e) {}
+ }
+ },
+ new com.android.volley.Response.ErrorListener() {
+ @Override
+ public void onErrorResponse(VolleyError volleyError) {
+ try {
+ ((ErrorListener<VolleyError>) listener).onError(volleyError);
+ } catch (ClassCastException e) {}
+ }
+ });
+
+ requestQueue.add(stringRequest);
+ }
+
+}
diff --git a/app/src/main/java/org/rssin/http/Fetcher.java b/app/src/main/java/org/rssin/http/Fetcher.java
new file mode 100644
index 0000000..0052e38
--- /dev/null
+++ b/app/src/main/java/org/rssin/http/Fetcher.java
@@ -0,0 +1,13 @@
+package org.rssin.http;
+
+import org.rssin.listener.Listener;
+
+/**
+ * Load an HTTP request
+ */
+public interface Fetcher {
+
+ void fetch(Request request);
+ void fetch(Request request, Listener listener);
+
+}
diff --git a/app/src/main/java/org/rssin/http/Request.java b/app/src/main/java/org/rssin/http/Request.java
new file mode 100644
index 0000000..b9861a5
--- /dev/null
+++ b/app/src/main/java/org/rssin/http/Request.java
@@ -0,0 +1,20 @@
+package org.rssin.http;
+
+import java.net.URL;
+
+/**
+ * Created by camilstaps on 21-5-15.
+ */
+public class Request {
+
+ URL url;
+
+ public Request(URL url) {
+ this.url = url;
+ }
+
+ public URL getURL() {
+ return url;
+ }
+
+}
diff --git a/app/src/main/java/org/rssin/listener/DismissListener.java b/app/src/main/java/org/rssin/listener/DismissListener.java
new file mode 100644
index 0000000..cfdc51d
--- /dev/null
+++ b/app/src/main/java/org/rssin/listener/DismissListener.java
@@ -0,0 +1,15 @@
+package org.rssin.listener;
+
+/**
+ * Created by camilstaps on 21-5-15.
+ */
+public class DismissListener implements Listener, RealtimeListener, ErrorListener, FallibleListener {
+ @Override
+ public void onError(Object error) {}
+
+ @Override
+ public void finish() {}
+
+ @Override
+ public void onReceive(Object data) {}
+}
diff --git a/app/src/main/java/org/rssin/listener/ErrorListener.java b/app/src/main/java/org/rssin/listener/ErrorListener.java
new file mode 100644
index 0000000..5ad4f1b
--- /dev/null
+++ b/app/src/main/java/org/rssin/listener/ErrorListener.java
@@ -0,0 +1,8 @@
+package org.rssin.listener;
+
+/**
+ * Created by camilstaps on 21-5-15.
+ */
+public interface ErrorListener<T> {
+ void onError(T error);
+}
diff --git a/app/src/main/java/org/rssin/listener/FallibleListener.java b/app/src/main/java/org/rssin/listener/FallibleListener.java
new file mode 100644
index 0000000..4e1d113
--- /dev/null
+++ b/app/src/main/java/org/rssin/listener/FallibleListener.java
@@ -0,0 +1,7 @@
+package org.rssin.listener;
+
+/**
+ * Created by camilstaps on 21-5-15.
+ */
+public interface FallibleListener<T,E> extends Listener<T>, ErrorListener<E> {
+}
diff --git a/app/src/main/java/org/rssin/listener/Listener.java b/app/src/main/java/org/rssin/listener/Listener.java
new file mode 100644
index 0000000..db1764c
--- /dev/null
+++ b/app/src/main/java/org/rssin/listener/Listener.java
@@ -0,0 +1,8 @@
+package org.rssin.listener;
+
+/**
+ * Created by camilstaps on 21-5-15.
+ */
+public interface Listener<T> {
+ void onReceive(T data);
+}
diff --git a/app/src/main/java/org/rssin/listener/RealtimeListener.java b/app/src/main/java/org/rssin/listener/RealtimeListener.java
new file mode 100644
index 0000000..82a4c91
--- /dev/null
+++ b/app/src/main/java/org/rssin/listener/RealtimeListener.java
@@ -0,0 +1,8 @@
+package org.rssin.listener;
+
+/**
+ * Created by camilstaps on 21-5-15.
+ */
+public interface RealtimeListener extends Listener {
+ void finish();
+}
diff --git a/app/src/main/java/org/rssin/neurons/SentenceSplitter.java b/app/src/main/java/org/rssin/neurons/SentenceSplitter.java
index 887439d..29e34bc 100755
--- a/app/src/main/java/org/rssin/neurons/SentenceSplitter.java
+++ b/app/src/main/java/org/rssin/neurons/SentenceSplitter.java
@@ -1,5 +1,6 @@
package org.rssin.neurons;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
@@ -8,7 +9,9 @@ import java.util.regex.Pattern;
/**
* @author Jos.
*/
-public class SentenceSplitter {
+public class SentenceSplitter implements Serializable {
+ private static final long serialVersionUID = 0;
+
private final Pattern wordMatch = Pattern.compile("[\\w-]+");//For unicode support, add the Pattern.UNICODE_CHARACTER_CLASS flag. Works only in Java 7+.
public SentenceSplitter() {
diff --git a/app/src/main/java/org/rssin/rss/FeedLoader.java b/app/src/main/java/org/rssin/rss/FeedLoader.java
index eabfebd..3220826 100644
--- a/app/src/main/java/org/rssin/rss/FeedLoader.java
+++ b/app/src/main/java/org/rssin/rss/FeedLoader.java
@@ -1,11 +1,13 @@
package org.rssin.rss;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
+import java.io.ByteArrayInputStream;
import java.net.URL;
import java.util.Date;
import java.util.LinkedList;
+import org.rssin.http.Fetcher;
+import org.rssin.http.Request;
+import org.rssin.listener.FallibleListener;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
@@ -214,25 +216,29 @@ public class FeedLoader {
/**
* Retrieves the XML and parses it.
*/
- public void fetchXML() {
- try {
- URL url = urlString;
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setReadTimeout(10000 /* milliseconds */);
- conn.setConnectTimeout(15000 /* milliseconds */);
- conn.setRequestMethod("GET");
- conn.setDoInput(true);
- // Starts the query
- conn.connect();
- InputStream stream = conn.getInputStream();
- xmlFactoryObject = XmlPullParserFactory.newInstance();
- XmlPullParser myparser = xmlFactoryObject.newPullParser();
- myparser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
- myparser.setInput(stream, null);
- parseXMLAndStoreIt(myparser);
- stream.close();
- } catch (Exception ignored) {
- }
+ public void fetchXML(Fetcher fetcher, final FallibleListener<?,Object> listener) {
+ fetcher.fetch(
+ new Request(urlString),
+ new FallibleListener<String,Object>() {
+ @Override
+ public void onReceive(String data) {
+ try {
+ xmlFactoryObject = XmlPullParserFactory.newInstance();
+ XmlPullParser parser = xmlFactoryObject.newPullParser();
+ parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
+ parser.setInput(new ByteArrayInputStream(data.getBytes()), null);
+ parseXMLAndStoreIt(parser);
+ listener.onReceive(null);
+ } catch (XmlPullParserException e) {
+ listener.onError(e);
+ }
+ }
+
+ @Override
+ public void onError(Object error) {
+ listener.onError(error);
+ }
+ });
}
public void setFeed(Feed feed) {
@@ -246,4 +252,5 @@ public class FeedLoader {
public void setUrlString(URL urlString) {
this.urlString = urlString;
}
+
}
diff --git a/app/src/main/java/org/rssin/rssin/FeedLoaderAndSorter.java b/app/src/main/java/org/rssin/rssin/FeedLoaderAndSorter.java
index e9d3e5d..0739e52 100755
--- a/app/src/main/java/org/rssin/rssin/FeedLoaderAndSorter.java
+++ b/app/src/main/java/org/rssin/rssin/FeedLoaderAndSorter.java
@@ -1,5 +1,9 @@
package org.rssin.rssin;
+import org.rssin.http.Fetcher;
+import org.rssin.listener.FallibleListener;
+import org.rssin.listener.Listener;
+import org.rssin.listener.RealtimeListener;
import org.rssin.neurons.FeedSorter;
import org.rssin.rss.FeedItem;
import org.rssin.rss.FeedLoader;
@@ -19,26 +23,62 @@ public class FeedLoaderAndSorter {
/**
* Loads the feed(s), filters it, sorts it, and returns the result.
+ * @param fetcher
+ * @param listener
* @return The filtered & sorted list of feedtems.
*/
- public List<FeedItem> getFilteredFeedItems()
+ public void getFilteredFeedItems(Fetcher fetcher, final Listener<List<FeedItem>> listener)
{
- List<FeedItem> resultingItems = new ArrayList<FeedItem>();
- for(Feed feed : filter.getFeeds())
- {
- FeedLoader loader = new FeedLoader(feed.getURL());
- loader.fetchXML();
- for(FeedItem item : loader.getFeed().getPosts())
- {
- if(matchesKeyword(item))
- {
- resultingItems.add(item);
+ final List<FeedItem> resultingItems = new ArrayList<>();
+ final Counter counter = new Counter(filter.getFeeds().size());
+ final FeedSorter sorter = filter.getSorter();
+
+ for (Feed feed : filter.getFeeds()) {
+ final FeedLoader loader = new FeedLoader(feed.getURL());
+ loader.fetchXML(fetcher, new FallibleListener<Object, Object>() {
+ @Override
+ public void onReceive(Object data) {
+ for (FeedItem item : loader.getFeed().getPosts()) {
+ if(matchesKeyword(item)) {
+ resultingItems.add(item);
+ }
+ }
+
+ sorter.sortItems(resultingItems);
+
+ if (counter.decr().isZero() || listener.getClass() == RealtimeListener.class) {
+ listener.onReceive(resultingItems);
+ if (counter.decr().isZero() && listener.getClass() == RealtimeListener.class) {
+ ((RealtimeListener) listener).finish();
+ }
+ }
}
- }
+
+ @Override
+ public void onError(Object error) {
+ try {
+ ((FallibleListener) listener).onError(error);
+ } catch (ClassCastException e) {}
+ }
+ });
+ }
+ }
+
+ private static class Counter {
+ int count;
+
+ Counter (int initial) {
+ count = initial;
}
- FeedSorter sorter = filter.getSorter();
- return sorter.sortItems(resultingItems);
+ public Counter decr() {
+ count--;
+ return this;
+ }
+
+ public boolean isZero() {
+ return count == 0;
+ }
}
private boolean matchesKeyword(FeedItem item)
diff --git a/app/src/main/java/org/rssin/rssin/Filter.java b/app/src/main/java/org/rssin/rssin/Filter.java
index 271b67d..50e3351 100755
--- a/app/src/main/java/org/rssin/rssin/Filter.java
+++ b/app/src/main/java/org/rssin/rssin/Filter.java
@@ -22,7 +22,7 @@ public class Filter implements Serializable {
private final List<Feed> feeds;
private final List<Keyword> keywords;
private String title = "";
- private FeedSorter sorter;
+ private FeedSorter sorter = new FeedSorter();
public Filter() {
feeds = new ArrayList<>();