aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSize432015-05-28 14:19:07 +0200
committerSize432015-05-28 14:19:07 +0200
commitc3a5f8282e89893fa6da51fdeff90e4fe796169b (patch)
tree93ac00f147919546eea4cce4cc96f8e8fd464c9b
parentcomments, cleanup (diff)
Loader for unified inbox
-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
5 files changed, 161 insertions, 17 deletions
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;
+ }
+ }
+}