diff options
author | Size43 | 2015-05-28 14:19:07 +0200 |
---|---|---|
committer | Size43 | 2015-05-28 14:19:07 +0200 |
commit | c3a5f8282e89893fa6da51fdeff90e4fe796169b (patch) | |
tree | 93ac00f147919546eea4cce4cc96f8e8fd464c9b | |
parent | comments, cleanup (diff) |
Loader for unified inbox
-rwxr-xr-x | app/src/main/java/org/rssin/neurons/FeedSorter.java | 13 | ||||
-rwxr-xr-x | app/src/main/java/org/rssin/neurons/Feedback.java | 3 | ||||
-rwxr-xr-x[-rw-r--r--] | app/src/main/java/org/rssin/rss/FeedItem.java | 64 | ||||
-rwxr-xr-x | app/src/main/java/org/rssin/rssin/FeedLoaderAndSorter.java | 14 | ||||
-rwxr-xr-x | app/src/main/java/org/rssin/rssin/UnifiedFilterLoader.java | 84 |
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;
+ }
+ }
+}
|