aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/java')
-rw-r--r--app/src/main/java/org/rssin/android/FilterActivity.java95
-rwxr-xr-xapp/src/main/java/org/rssin/neurons/FeedSorter.java13
-rwxr-xr-xapp/src/main/java/org/rssin/neurons/Feedback.java3
-rwxr-xr-x[-rw-r--r--]app/src/main/java/org/rssin/rss/FeedItem.java64
-rwxr-xr-xapp/src/main/java/org/rssin/rssin/FeedLoaderAndSorter.java14
-rwxr-xr-xapp/src/main/java/org/rssin/rssin/UnifiedFilterLoader.java84
6 files changed, 225 insertions, 48 deletions
diff --git a/app/src/main/java/org/rssin/android/FilterActivity.java b/app/src/main/java/org/rssin/android/FilterActivity.java
index b1be925..6c827d1 100644
--- a/app/src/main/java/org/rssin/android/FilterActivity.java
+++ b/app/src/main/java/org/rssin/android/FilterActivity.java
@@ -5,6 +5,8 @@ import android.content.Context;
import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -31,10 +33,17 @@ public class FilterActivity extends ActionBarActivity {
private FiltersList filtersList;
private Filter filter;
+ private RecyclerView mRecyclerView;
+ private RecyclerView.Adapter mAdapter;
+ private RecyclerView.LayoutManager mLayoutManager;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_filter);
+ mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
+ mLayoutManager = new LinearLayoutManager(this);
+ mRecyclerView.setLayoutManager(mLayoutManager);
try {
filtersList = FiltersList.getInstance(this);
@@ -52,13 +61,14 @@ public class FilterActivity extends ActionBarActivity {
setTitle(filter.getTitle());
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);
+
+ FeedItemAdapter feedItemAdapter = new FeedItemAdapter(data);
+ mRecyclerView.setAdapter(feedItemAdapter);
+ mRecyclerView.setHasFixedSize(true);
}
@Override
@@ -101,49 +111,72 @@ public class FilterActivity extends ActionBarActivity {
/**
* Custom ArrayAdapter to display Keywords
*/
- private static class FeedItemAdapter extends ArrayAdapter<FeedItem> {
- Context context;
- int layoutResourceId;
+ private static class FeedItemAdapter extends RecyclerView.Adapter<FeedItemAdapter.KeywordHolder> {
List<FeedItem> feedItems;
- public FeedItemAdapter(Context context, int resource, List<FeedItem> objects) {
- super(context, resource, objects);
- this.context = context;
- layoutResourceId = resource;
+ public FeedItemAdapter(List<FeedItem> objects) {
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);
+// @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;
+// }
- 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();
- }
+ @Override
+ public KeywordHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ View itemView = LayoutInflater.
+ from(parent.getContext()).
+ inflate(R.layout.item_feeditem, parent, false);
+ return new KeywordHolder(itemView);
+ }
- FeedItem feedItem = feedItems.get(position);
- holder.title.setText(feedItem.getTitle());
- holder.summary.setText(Html.fromHtml(feedItem.getDescription()));
+ @Override
+ public void onBindViewHolder(KeywordHolder holder, int position) {
+ FeedItem item = feedItems.get(position);
+ holder.title.setText(item.getTitle());
+ holder.summary.setText(item.getDescription());
+ }
- return row;
+ @Override
+ public int getItemCount() {
+ return feedItems.size();
}
/**
* TextViews holder
*/
- private static class KeywordHolder {
+ static class KeywordHolder extends RecyclerView.ViewHolder {
TextView title;
TextView summary;
+
+ public KeywordHolder(View itemView) {
+ super(itemView);
+ title = (TextView) itemView.findViewById(R.id.feeditem_title);
+ summary = (TextView) itemView.findViewById(R.id.feeditem_summary);
+ }
}
+
+
}
}
diff --git a/app/src/main/java/org/rssin/neurons/FeedSorter.java b/app/src/main/java/org/rssin/neurons/FeedSorter.java
index 910057f..fe1e998 100755
--- a/app/src/main/java/org/rssin/neurons/FeedSorter.java
+++ b/app/src/main/java/org/rssin/neurons/FeedSorter.java
@@ -33,7 +33,7 @@ public class FeedSorter implements Storable {
private void writeObject(java.io.ObjectOutputStream stream) throws IOException {
stream.writeObject(nn);
- stream.writeObject(trainingCases);
+ SerializationTools.writeList(trainingCases, stream);
SerializationTools.writeArray(isNthMonthInput, stream);
SerializationTools.writeArray(isNthWeekDayInput, stream);
stream.writeInt(isMorning);
@@ -48,7 +48,7 @@ public class FeedSorter implements Storable {
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
nn = (MultiNeuralNetwork) stream.readObject();
- trainingCases = (List<TrainingCase>) stream.readObject();
+ trainingCases = SerializationTools.readList(stream);
isNthMonthInput = SerializationTools.readArrayInt(stream);
isNthWeekDayInput = SerializationTools.readArrayInt(stream);
isMorning = stream.readInt();
@@ -183,22 +183,17 @@ public class FeedSorter implements Storable {
*/
public List<FeedItem> sortItems(List<FeedItem> items) {
final int SECONDS_IN_DAY = 24 * 60 * 60;
-
final List<FeedItem> newItems = new ArrayList<>(items);
- final Hashtable<FeedItem, Long> predictions = new Hashtable<>();
for (FeedItem item : newItems) {
PredictionInterface prediction = getPrediction(item);
- predictions.put(item, (long) (prediction.getOutput() * SECONDS_IN_DAY));
+ item.setScore((long) (item.getPubDate().getTime() / 1000 + prediction.getOutput() * SECONDS_IN_DAY));
}
Collections.sort(newItems, new Comparator<FeedItem>() {
@Override
public int compare(FeedItem lhs, FeedItem rhs) {
- long lhsScore = lhs.getPubDate().getTime() / 1000 + predictions.get(lhs);
- long rhsScore = rhs.getPubDate().getTime() / 1000 + predictions.get(rhs);
-
- return (int) Math.signum(rhsScore - lhsScore);
+ return (int) Math.signum(rhs.getScore() - lhs.getScore());
}
});
diff --git a/app/src/main/java/org/rssin/neurons/Feedback.java b/app/src/main/java/org/rssin/neurons/Feedback.java
index fe59b1b..59d3246 100755
--- a/app/src/main/java/org/rssin/neurons/Feedback.java
+++ b/app/src/main/java/org/rssin/neurons/Feedback.java
@@ -2,13 +2,14 @@ package org.rssin.neurons;
/**
* @author Jos.
+ * Feedback for the Neural Network.
*/
public enum Feedback {
Like(1.0d), Dislike(-1.0d);
private final double expectedOutput;
- private Feedback(double expectedOutput) {
+ Feedback(double expectedOutput) {
this.expectedOutput = expectedOutput;
}
diff --git a/app/src/main/java/org/rssin/rss/FeedItem.java b/app/src/main/java/org/rssin/rss/FeedItem.java
index bb074cd..f7805d8 100644..100755
--- a/app/src/main/java/org/rssin/rss/FeedItem.java
+++ b/app/src/main/java/org/rssin/rss/FeedItem.java
@@ -15,11 +15,11 @@ public class FeedItem {
private String description;
private String link;
private String author;
- private List<String> category = new LinkedList<>();
private String comments;
private String enclosure;
private String source;
- private boolean isRead;
+ private List<String> category = new LinkedList<>();
+ private transient long score = -1;
public FeedItem(String guid, Date pubDate, String title, String description, String link,
String author, List<String> category, String comments, String enclosure, String source)
@@ -123,11 +123,63 @@ public class FeedItem {
return title + "\n" + description + " - " + author;
}
- public boolean isRead() {
- return isRead;
+ @Override
+ public int hashCode() {
+ int hash = 17;
+
+ if(guid != null)
+ {
+ hash = hash * 23 + guid.hashCode();
+ }
+
+ if(link != null)
+ {
+ hash = hash * 23 + link.hashCode();
+ }
+
+ if(title != null)
+ {
+ hash = hash * 23 + title.hashCode();
+ }
+
+ if(pubDate != null)
+ {
+ hash = hash * 23 + pubDate.hashCode();
+ }
+
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof FeedItem))
+ return false;
+
+ if (obj == this)
+ return true;
+
+ FeedItem other = (FeedItem) obj;
+ return (guid == null && other.guid == null) || (guid != null && guid.equals(other.guid))
+ && (pubDate == null && other.pubDate == null) || (pubDate != null && pubDate.equals(other.pubDate))
+ && (title == null && other.title == null) || (title != null && title.equals(other.title))
+ && (description == null && other.description == null) || (description != null && description.equals(other.description))
+ && (link == null && other.link == null) || (link != null && link.equals(other.link))
+ && (author == null && other.author == null) || (author != null && author.equals(other.author))
+ && (comments == null && other.comments == null) || (comments != null && comments.equals(other.comments))
+ && (enclosure == null && other.enclosure == null) || (enclosure != null && enclosure.equals(other.enclosure))
+ && (source == null && other.source == null) || (source != null && source.equals(other.source));
+ }
+
+ public long getScore() {
+ if(score == -1)
+ {
+ throw new UnsupportedOperationException("score not set");
+ }
+
+ return score;
}
- public void setIsRead(boolean isRead) {
- this.isRead = isRead;
+ public void setScore(long score) {
+ this.score = score;
}
}
diff --git a/app/src/main/java/org/rssin/rssin/FeedLoaderAndSorter.java b/app/src/main/java/org/rssin/rssin/FeedLoaderAndSorter.java
index 2ec3cfd..e1fbbab 100755
--- a/app/src/main/java/org/rssin/rssin/FeedLoaderAndSorter.java
+++ b/app/src/main/java/org/rssin/rssin/FeedLoaderAndSorter.java
@@ -85,10 +85,22 @@ public class FeedLoaderAndSorter {
{
for(Keyword keyword : filter.getKeywords())
{
- if(contains(item.getTitle(), keyword.getKeyword()))
+ String word = keyword.getKeyword();
+ if(contains(item.getTitle(), word)
+ || contains(item.getAuthor(), word))
{
return true;
}
+
+
+
+ for(String category : item.getCategory())
+ {
+ if(contains(category, word))
+ {
+ return true;
+ }
+ }
}
return filter.getKeywords().size() == 0;
diff --git a/app/src/main/java/org/rssin/rssin/UnifiedFilterLoader.java b/app/src/main/java/org/rssin/rssin/UnifiedFilterLoader.java
new file mode 100755
index 0000000..9740380
--- /dev/null
+++ b/app/src/main/java/org/rssin/rssin/UnifiedFilterLoader.java
@@ -0,0 +1,84 @@
+package org.rssin.rssin;
+
+import org.rssin.http.Fetcher;
+import org.rssin.listener.Listener;
+import org.rssin.listener.RealtimeListener;
+import org.rssin.rss.FeedItem;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+
+/**
+ * @author Jos.
+ * This class merges the FeedItems from multiple Filters together into one list of FeedItems.
+ */
+public class UnifiedFilterLoader {
+
+ private List<Filter> filters;
+ public UnifiedFilterLoader(List<Filter> filters)
+ {
+ this.filters = filters;
+ }
+
+ /**
+ * Loads the feed(s), filters it, sorts it, and returns the result.
+ * @param fetcher HTTP Fetcher
+ * @param listener Listener for when the fetcher finishes
+ */
+ public void getFilteredFeedItems(Fetcher fetcher, final Listener<List<FeedItem>> listener) {
+ // HashSet to make sure that there are no duplicates when merging multiple filters, since different filters
+ // may contain the same feed.
+ final HashSet<FeedItem> resultingItems = new HashSet<>();
+ final Counter counter = new Counter(filters.size());
+
+ for (Filter filter : filters) {
+ // Load the sorted FeedItems from the filters, and combine them.
+ FeedLoaderAndSorter loaderAndSorter = new FeedLoaderAndSorter(filter);
+ loaderAndSorter.getFilteredFeedItems(fetcher, new Listener<List<FeedItem>>() {
+ @Override
+ public void onReceive(List<FeedItem> data) {
+ resultingItems.addAll(data);
+
+ if (counter.decr().isZero() || listener.getClass() == RealtimeListener.class) {
+ ArrayList<FeedItem> newItems = new ArrayList<FeedItem>(resultingItems);
+
+ // Do another sort to make sure the items are still in the correct order.
+ // this uses the score set by the FeedSorter class, which is called
+ // in the Filter class. The Unified inbox does not have a separate network.
+ Collections.sort(newItems, new Comparator<FeedItem>() {
+ @Override
+ public int compare(FeedItem lhs, FeedItem rhs) {
+ return (int) Math.signum(rhs.getScore() - lhs.getScore());
+ }
+ });
+
+ listener.onReceive(newItems);
+ if (counter.decr().isZero() && listener.getClass() == RealtimeListener.class) {
+ ((RealtimeListener) listener).finish();
+ }
+ }
+ }
+ });
+ }
+ }
+
+ private static class Counter {
+ int count;
+
+ Counter (int initial) {
+ count = initial;
+ }
+
+ public Counter decr() {
+ count--;
+ return this;
+ }
+
+ public boolean isZero() {
+ return count == 0;
+ }
+ }
+}