aboutsummaryrefslogtreecommitdiff
path: root/app/src
diff options
context:
space:
mode:
Diffstat (limited to 'app/src')
-rwxr-xr-xapp/src/main/java/org/rssin/neurons/FeedSorter.java133
-rwxr-xr-xapp/src/main/java/org/rssin/neurons/Feedback.java16
-rwxr-xr-xapp/src/main/java/org/rssin/neurons/MultiNeuralNetwork.java5
-rwxr-xr-xapp/src/main/java/org/rssin/neurons/MultiNeuralNetworkPrediction.java10
-rwxr-xr-xapp/src/main/java/org/rssin/neurons/NeuralNetwork.java5
-rwxr-xr-xapp/src/main/java/org/rssin/neurons/NeuralNetworkPrediction.java4
-rwxr-xr-xapp/src/main/java/org/rssin/neurons/Neuron.java1
-rwxr-xr-xapp/src/main/java/org/rssin/neurons/PredictionInterface.java1
-rwxr-xr-xapp/src/main/java/org/rssin/neurons/TrainingCase.java26
-rw-r--r--app/src/main/java/org/rssin/rss/Feed.java223
-rw-r--r--app/src/main/java/org/rssin/rss/FeedItem.java8
-rw-r--r--app/src/main/java/org/rssin/rss/FeedLoader.java224
-rwxr-xr-xapp/src/main/java/org/rssin/rssin/FeedLoaderAndSorter.java64
-rwxr-xr-x[-rw-r--r--]app/src/main/java/org/rssin/rssin/Filter.java9
14 files changed, 582 insertions, 147 deletions
diff --git a/app/src/main/java/org/rssin/neurons/FeedSorter.java b/app/src/main/java/org/rssin/neurons/FeedSorter.java
index 550d9e5..157a8f7 100755
--- a/app/src/main/java/org/rssin/neurons/FeedSorter.java
+++ b/app/src/main/java/org/rssin/neurons/FeedSorter.java
@@ -5,7 +5,9 @@ import android.gesture.Prediction;
import org.rssin.rss.FeedItem;
import java.io.IOException;
+import java.io.Serializable;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
@@ -18,39 +20,43 @@ import java.util.TimeZone;
/**
* Created by Jos on 14-5-2015.
*/
-public class FeedSorter {
+public class FeedSorter implements Serializable{
+ private static final long serialVersionUID = 0;
+
+ private final int MAX_TRAINING_HISTORY = 250;
private final int SECONDS_IN_DAY = 24 * 60 * 60;
private MultiNeuralNetwork nn = new MultiNeuralNetwork(25, 50);
+ private List<TrainingCase> trainingCases = new ArrayList<>();
+
private int[] isNthMonthInput = new int[12];
private int[] isNthWeekDayInput = new int[7];
private int isMorning, isAfternoon, isEvening, isNight, biasInput;
private Hashtable<String, Integer> categoryInputs = new Hashtable<String, Integer>();
- private Hashtable<String, Integer> wordInputs = new Hashtable<String, Integer>();
- private Hashtable<String, Integer> feedSourceInputs = new Hashtable<String, Integer>();
+ //private Hashtable<String, Integer> wordInputs = new Hashtable<String, Integer>();
+ //private Hashtable<String, Integer> feedSourceInputs = new Hashtable<String, Integer>();
public FeedSorter() {
- //TODO: Load Neural Network
createNewNetwork();
}
private void createNewNetwork() {
biasInput = nn.addInput();
-// for(int i = 0; i < 12; i++)
-// {
-// isNthMonthInput[i] = nn.addInput();
-// }
-//
-// for(int i = 0; i < 7; i++)
-// {
-// isNthWeekDayInput[i] = nn.addInput();
-// }
-//
-// isMorning = nn.addInput();
-// isAfternoon = nn.addInput();
-// isEvening = nn.addInput();
-// isNight = nn.addInput();
+ for(int i = 0; i < 12; i++)
+ {
+ isNthMonthInput[i] = nn.addInput();
+ }
+
+ for(int i = 0; i < 7; i++)
+ {
+ isNthWeekDayInput[i] = nn.addInput();
+ }
+
+ isMorning = nn.addInput();
+ isAfternoon = nn.addInput();
+ isEvening = nn.addInput();
+ isNight = nn.addInput();
}
private PredictionInterface getPrediction(FeedItem item) {
@@ -75,39 +81,39 @@ public class FeedSorter {
}
//Set month
-// Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
-// for(int i = 0; i < isNthMonthInput.length; i++)
-// {
-// if(cal.get(Calendar.MONTH) - cal.getMinimum(Calendar.MONTH) == i)
-// {
-// inputs[isNthMonthInput[i]] = 1;
-// }
-// }
+ Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+ for(int i = 0; i < isNthMonthInput.length; i++)
+ {
+ if(cal.get(Calendar.MONTH) - cal.getMinimum(Calendar.MONTH) == i)
+ {
+ inputs[isNthMonthInput[i]] = 1;
+ }
+ }
//Set weekday
-// for(int i = 0; i < isNthWeekDayInput.length; i++)
-// {
-// if(cal.get(Calendar.DAY_OF_WEEK) - cal.getMinimum(Calendar.DAY_OF_WEEK) == i)
-// {
-// inputs[isNthMonthInput[i]] = 1;
-// }
-// }
+ for(int i = 0; i < isNthWeekDayInput.length; i++)
+ {
+ if(cal.get(Calendar.DAY_OF_WEEK) - cal.getMinimum(Calendar.DAY_OF_WEEK) == i)
+ {
+ inputs[isNthMonthInput[i]] = 1;
+ }
+ }
//Set day
-// int hourOfDay = cal.get(Calendar.HOUR_OF_DAY);
-// if(hourOfDay > 6 && hourOfDay < 12)
-// {
-// inputs[isMorning] = 1;
-// }else if(hourOfDay >= 12 && hourOfDay <= 6)
-// {
-// inputs[isAfternoon] = 1;
-// }else if(hourOfDay >= 6 && hourOfDay < 23)
-// {
-// inputs[isEvening] = 1;
-// }else if(hourOfDay >= 23 || hourOfDay <= 6)
-// {
-// inputs[isNight] = 1;
-// }
+ int hourOfDay = cal.get(Calendar.HOUR_OF_DAY);
+ if(hourOfDay > 6 && hourOfDay < 12)
+ {
+ inputs[isMorning] = 1;
+ }else if(hourOfDay >= 12 && hourOfDay <= 6)
+ {
+ inputs[isAfternoon] = 1;
+ }else if(hourOfDay >= 6 && hourOfDay < 23)
+ {
+ inputs[isEvening] = 1;
+ }else if(hourOfDay >= 23 || hourOfDay <= 6)
+ {
+ inputs[isNight] = 1;
+ }
for(String category : item.getCategory())
{
@@ -126,16 +132,31 @@ public class FeedSorter {
public void feedback(FeedItem item, Feedback feedback)
{
PredictionInterface prediction = getPrediction(item);
- switch(feedback)
+ prediction.learn(feedback.toExpectedOutput());
+ trainingCases.add(new TrainingCase(prediction.getInputs(), feedback));
+
+ while(trainingCases.size() > MAX_TRAINING_HISTORY)
+ {
+ trainingCases.remove(0);
+ }
+ }
+
+ /**
+ * Runs an iteration of training, using feedback that was provided previously using FeedSorter.feedback(...).
+ */
+ public void train()
+ {
+ for(TrainingCase t : trainingCases)
{
- case Like:
- prediction.learn(1);
- break;
- case Dislike:
- prediction.learn(-1);
- break;
- default:
- throw new IllegalArgumentException("feedback");
+ double[] inputs = t.getInputs();
+ if(inputs.length < nn.getInputCount())
+ {
+ // Resize array to fit new input size
+ inputs = Arrays.copyOf(inputs, nn.getInputCount());
+ }
+
+ PredictionInterface prediction = nn.computeOutput(inputs);
+ prediction.learn(t.getFeedback().toExpectedOutput());
}
}
diff --git a/app/src/main/java/org/rssin/neurons/Feedback.java b/app/src/main/java/org/rssin/neurons/Feedback.java
index af5f1b3..9652b2b 100755
--- a/app/src/main/java/org/rssin/neurons/Feedback.java
+++ b/app/src/main/java/org/rssin/neurons/Feedback.java
@@ -4,6 +4,18 @@ package org.rssin.neurons;
* Created by Jos on 19-5-2015.
*/
public enum Feedback {
- Like,
- Dislike
+ Like, Dislike;
+
+ double toExpectedOutput()
+ {
+ switch(this)
+ {
+ case Like:
+ return 1;
+ case Dislike:
+ return -1;
+ default:
+ throw new IllegalArgumentException();
+ }
+ }
}
diff --git a/app/src/main/java/org/rssin/neurons/MultiNeuralNetwork.java b/app/src/main/java/org/rssin/neurons/MultiNeuralNetwork.java
index 50fa707..a2f06eb 100755
--- a/app/src/main/java/org/rssin/neurons/MultiNeuralNetwork.java
+++ b/app/src/main/java/org/rssin/neurons/MultiNeuralNetwork.java
@@ -1,9 +1,12 @@
package org.rssin.neurons;
+import java.io.Serializable;
+
/**
* Created by Jos on 14-5-2015.
*/
-class MultiNeuralNetwork {
+class MultiNeuralNetwork implements Serializable{
+ private static final long serialVersionUID = 0;
private NeuralNetwork[] networks;
public MultiNeuralNetwork(int numNetworks, int numHiddenNodes) {
diff --git a/app/src/main/java/org/rssin/neurons/MultiNeuralNetworkPrediction.java b/app/src/main/java/org/rssin/neurons/MultiNeuralNetworkPrediction.java
index 8df99e5..dc85261 100755
--- a/app/src/main/java/org/rssin/neurons/MultiNeuralNetworkPrediction.java
+++ b/app/src/main/java/org/rssin/neurons/MultiNeuralNetworkPrediction.java
@@ -7,6 +7,11 @@ class MultiNeuralNetworkPrediction implements PredictionInterface {
private PredictionInterface[] predictions;
MultiNeuralNetworkPrediction(PredictionInterface[] predictions)
{
+ if(predictions.length <= 0)
+ {
+ throw new IllegalArgumentException("predictions");
+ }
+
this.predictions = predictions;
}
@@ -27,4 +32,9 @@ class MultiNeuralNetworkPrediction implements PredictionInterface {
prediction.learn(expectedOutput);
}
}
+
+ public double[] getInputs()
+ {
+ return predictions[0].getInputs();
+ }
}
diff --git a/app/src/main/java/org/rssin/neurons/NeuralNetwork.java b/app/src/main/java/org/rssin/neurons/NeuralNetwork.java
index 7c2e447..620d5bd 100755
--- a/app/src/main/java/org/rssin/neurons/NeuralNetwork.java
+++ b/app/src/main/java/org/rssin/neurons/NeuralNetwork.java
@@ -1,9 +1,12 @@
package org.rssin.neurons;
+import java.io.Serializable;
+
/**
* Created by Jos on 14-5-2015.
*/
-class NeuralNetwork {
+class NeuralNetwork implements Serializable{
+ private static final long serialVersionUID = 0;
private Neuron[] hiddenNodes;
private Neuron outputNode;
diff --git a/app/src/main/java/org/rssin/neurons/NeuralNetworkPrediction.java b/app/src/main/java/org/rssin/neurons/NeuralNetworkPrediction.java
index 162ba21..9d6fc89 100755
--- a/app/src/main/java/org/rssin/neurons/NeuralNetworkPrediction.java
+++ b/app/src/main/java/org/rssin/neurons/NeuralNetworkPrediction.java
@@ -16,11 +16,11 @@ class NeuralNetworkPrediction implements PredictionInterface {
this.nn = nn;
}
- double[] getInputs() {
+ public double[] getInputs() {
return inputs;
}
- double[] getIntermediateValues() {
+ public double[] getIntermediateValues() {
return intermediateValues;
}
diff --git a/app/src/main/java/org/rssin/neurons/Neuron.java b/app/src/main/java/org/rssin/neurons/Neuron.java
index 5df9d47..724732d 100755
--- a/app/src/main/java/org/rssin/neurons/Neuron.java
+++ b/app/src/main/java/org/rssin/neurons/Neuron.java
@@ -8,6 +8,7 @@ import java.util.Random;
* Created by Jos on 14-5-2015.
*/
class Neuron {
+ private static final long serialVersionUID = 0;
private static Random r = new Random();
private List<Double> weights = new ArrayList<Double>();
diff --git a/app/src/main/java/org/rssin/neurons/PredictionInterface.java b/app/src/main/java/org/rssin/neurons/PredictionInterface.java
index e130f4d..27a214f 100755
--- a/app/src/main/java/org/rssin/neurons/PredictionInterface.java
+++ b/app/src/main/java/org/rssin/neurons/PredictionInterface.java
@@ -6,4 +6,5 @@ package org.rssin.neurons;
interface PredictionInterface {
public double getOutput();
public void learn(double expectedOutput);
+ public double[] getInputs();
}
diff --git a/app/src/main/java/org/rssin/neurons/TrainingCase.java b/app/src/main/java/org/rssin/neurons/TrainingCase.java
new file mode 100755
index 0000000..77162be
--- /dev/null
+++ b/app/src/main/java/org/rssin/neurons/TrainingCase.java
@@ -0,0 +1,26 @@
+package org.rssin.neurons;
+
+import java.io.Serializable;
+
+/**
+ * Created by Jos on 20-5-2015.
+ */
+class TrainingCase implements Serializable {
+ private static long serialVersionID;
+ private double[] inputs;
+ private Feedback feedback;
+
+ public TrainingCase(double[] inputs, Feedback feedback)
+ {
+ this.inputs = inputs;
+ this.feedback = feedback;
+ }
+
+ public double[] getInputs() {
+ return inputs;
+ }
+
+ public Feedback getFeedback() {
+ return feedback;
+ }
+}
diff --git a/app/src/main/java/org/rssin/rss/Feed.java b/app/src/main/java/org/rssin/rss/Feed.java
index b48f036..3718af2 100644
--- a/app/src/main/java/org/rssin/rss/Feed.java
+++ b/app/src/main/java/org/rssin/rss/Feed.java
@@ -13,32 +13,54 @@ import java.util.List;
public class Feed implements Serializable {
private static final long serialVersionUID = 2;
- private String guid;
- private Date pubDate;
- private String title;
+ private List<String> category = new LinkedList<>();
+ private String cloud;
+ private String copyright;
private String description;
+ private String docs;
+ private String generator;
+ private String imageurl;
+ private String imagetitle;
+ private String imagelink;
+ private String language;
+ private Date lastBuildDate;
private String link;
- private String author;
- private List<String> category = new LinkedList<>();
- private String comments;
- private String enclosure;
- private String source;
+ private String managingEditor;
+ private Date pubDate;
+ private String rating;
+ private String skipDays;
+ private String skipHours;
+ private String textInput;
+ private String title;
+ private String ttl;
+ private String webMaster;
private List<FeedItem> posts = new ArrayList<>();
- public Feed (String guid, Date pubDate, String title, String description, String link,
- String author, List<String> category, String comments, String enclosure, String source)
- {
- this.guid = guid;
- this.pubDate = pubDate;
- this.title = title;
- this.description = description;
- this.link = link;
- this.author = author;
+ public Feed(List<String> category, String cloud, String copyright, String generator,
+ String imageurl, String imagetitle, String imagelink, String language,
+ Date lastBuildDate, String link, String managingEditor, Date pubDate,
+ String rating, String skipDays, String skipHours, String textInput,
+ String title, String ttl, String webMaster) {
this.category = category;
- this.comments = comments;
- this.enclosure = enclosure;
- this.source = source;
+ this.setCloud(cloud);
+ this.setCopyright(copyright);
+ this.setGenerator(generator);
+ this.setImageurl(imageurl);
+ this.setImagetitle(imagetitle);
+ this.setImagelink(imagelink);
+ this.setLanguage(language);
+ this.setLastBuildDate(lastBuildDate);
+ this.setLink(link);
+ this.setManagingEditor(managingEditor);
+ this.setPubDate(pubDate);
+ this.setRating(rating);
+ this.setSkipDays(skipDays);
+ this.setSkipHours(skipHours);
+ this.setTextInput(textInput);
+ this.setTitle(title);
+ this.setTtl(ttl);
+ this.setWebMaster(webMaster);
}
public void addPost(FeedItem post) {
@@ -49,42 +71,171 @@ public class Feed implements Serializable {
return posts;
}
- public String getGuid() {
- return guid;
+ public String getCloud() {
+ return cloud;
}
- public Date getPubDate() {
- return pubDate;
+ public void setCloud(String cloud) {
+ this.cloud = cloud;
}
- public String getTitle() {
- return title;
+ public List<String> getCategory() {
+ return category;
+ }
+
+ public void setCategory(String category) {
+ this.category.add(category);
+ }
+
+ public String getCopyright() {
+ return copyright;
+ }
+
+ public void setCopyright(String copyright) {
+ this.copyright = copyright;
}
public String getDescription() {
return description;
}
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getDocs() {
+ return docs;
+ }
+
+ public void setDocs(String docs) {
+ this.docs = docs;
+ }
+
+ public String getGenerator() {
+ return generator;
+ }
+
+ public void setGenerator(String generator) {
+ this.generator = generator;
+ }
+
+ public String getImageurl() {
+ return imageurl;
+ }
+
+ public void setImageurl(String imageurl) {
+ this.imageurl = imageurl;
+ }
+
+ public String getImagetitle() {
+ return imagetitle;
+ }
+
+ public void setImagetitle(String imagetitle) {
+ this.imagetitle = imagetitle;
+ }
+
+ public String getImagelink() {
+ return imagelink;
+ }
+
+ public void setImagelink(String imagelink) {
+ this.imagelink = imagelink;
+ }
+
+ public String getLanguage() {
+ return language;
+ }
+
+ public void setLanguage(String language) {
+ this.language = language;
+ }
+
+ public Date getLastBuildDate() {
+ return lastBuildDate;
+ }
+
+ public void setLastBuildDate(Date lastBuildDate) {
+ this.lastBuildDate = lastBuildDate;
+ }
+
public String getLink() {
return link;
}
- public String getAuthor() {
- return author;
+ public void setLink(String link) {
+ this.link = link;
}
- public List<String> getCategory() {
- return category;
+ public String getManagingEditor() {
+ return managingEditor;
}
- public String getComments() { return comments; }
+ public void setManagingEditor(String managingEditor) {
+ this.managingEditor = managingEditor;
+ }
+
+ public Date getPubDate() {
+ return pubDate;
+ }
+
+ public void setPubDate(Date pubDate) {
+ this.pubDate = pubDate;
+ }
+
+ public String getRating() {
+ return rating;
+ }
+
+ public void setRating(String rating) {
+ this.rating = rating;
+ }
- public String getEnclosure() {
- return enclosure;
+ public String getSkipDays() {
+ return skipDays;
}
- public String getSource() {
- return source;
+ public void setSkipDays(String skipDays) {
+ this.skipDays = skipDays;
}
-}
+ public String getSkipHours() {
+ return skipHours;
+ }
+
+ public void setSkipHours(String skipHours) {
+ this.skipHours = skipHours;
+ }
+
+ public String getTextInput() {
+ return textInput;
+ }
+
+ public void setTextInput(String textInput) {
+ this.textInput = textInput;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getTtl() {
+ return ttl;
+ }
+
+ public void setTtl(String ttl) {
+ this.ttl = ttl;
+ }
+
+ public String getWebMaster() {
+ return webMaster;
+ }
+
+ public void setWebMaster(String webMaster) {
+ this.webMaster = webMaster;
+ }
+} \ No newline at end of file
diff --git a/app/src/main/java/org/rssin/rss/FeedItem.java b/app/src/main/java/org/rssin/rss/FeedItem.java
index 1c5348e..bb074cd 100644
--- a/app/src/main/java/org/rssin/rss/FeedItem.java
+++ b/app/src/main/java/org/rssin/rss/FeedItem.java
@@ -19,6 +19,7 @@ public class FeedItem {
private String comments;
private String enclosure;
private String source;
+ private boolean isRead;
public FeedItem(String guid, Date pubDate, String title, String description, String link,
String author, List<String> category, String comments, String enclosure, String source)
@@ -122,4 +123,11 @@ public class FeedItem {
return title + "\n" + description + " - " + author;
}
+ public boolean isRead() {
+ return isRead;
+ }
+
+ public void setIsRead(boolean isRead) {
+ this.isRead = isRead;
+ }
}
diff --git a/app/src/main/java/org/rssin/rss/FeedLoader.java b/app/src/main/java/org/rssin/rss/FeedLoader.java
index db0f1db..726cbac 100644
--- a/app/src/main/java/org/rssin/rss/FeedLoader.java
+++ b/app/src/main/java/org/rssin/rss/FeedLoader.java
@@ -7,6 +7,7 @@ import java.util.Date;
import java.util.LinkedList;
import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
@@ -17,29 +18,47 @@ public class FeedLoader {
private Feed feed;
- private String urlString = null;
+ private URL urlString = null;
private XmlPullParserFactory xmlFactoryObject;
public volatile boolean parsingComplete = true;
- public FeedLoader(Feed feed, String url){
- this.setFeed(feed);
+ private String text;
+
+ public FeedLoader(URL url){
this.urlString = url;
}
+ /**
+ * parses an XML file and saves all information in the feed.
+ * @param myParser the parser in question.
+ */
public void parseXMLAndStoreIt(XmlPullParser myParser) {
int event;
- String text=null;
FeedItem post = null;
+ boolean chan = true; //as long as the first item hasn't been reached, all
+ //information is saved in the feed itself, rather than
+ //in separate items.
try {
event = myParser.getEventType();
while (event != XmlPullParser.END_DOCUMENT) {
- String name=myParser.getName();
+ String name = myParser.getName();
switch (event) {
case XmlPullParser.START_TAG:
- if(name.equals("item"))
- {
- post = new FeedItem(null, null, null, null, null,
- null, new LinkedList<String>(), null, null, null);
+ switch (name) {
+ case "item":
+ post = new FeedItem(null, null, null, null, null,
+ null, new LinkedList<String>(), null, null, null);
+ chan = false; //this starts collection information for the
+ //separate items.
+ break;
+ case "image":
+ imageTagParse(myParser);
+ case "channel":
+ feed = new Feed(new LinkedList<String>(), null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null);
+ chan = true;
+ break;
}
break;
case XmlPullParser.TEXT:
@@ -47,55 +66,160 @@ public class FeedLoader {
break;
case XmlPullParser.END_TAG:
assert post != null;
- if(name.equals("guid")) {
-
- post.setGuid(text);
- }
- else if(name.equals("pubDate")) {
- post.setPubDate(new Date(text));
- }
- else if(name.equals("title")) {
- post.setTitle(text);
- }
- else if(name.equals("description")) {
- post.setDescription(text);
- }
- else if(name.equals("link")) {
- post.setLink(text);
- }
- else if(name.equals("author")) {
- post.setAuthor(text);
- }
- else if(name.equals("category")) {
- post.setCategory(text);
- }
- else if(name.equals("comments")) {
- post.setComments(text);
- }
- else if(name.equals("enclosure")) {
- post.setEnclosure(text);
- }
- else if(name.equals("source")) {
- post.setSource(text);
- }
- else if(name.equals("item")) {
- feed.addPost(post);
+ if (!chan) { //this saves all the item-related information.
+ switch (name) {
+ case "guid":
+ post.setGuid(text);
+ break;
+ case "pubDate":
+ post.setPubDate(new Date(text));
+ break;
+ case "title":
+ post.setTitle(text);
+ break;
+ case "description":
+ post.setDescription(text);
+ break;
+ case "link":
+ post.setLink(text);
+ break;
+ case "author":
+ post.setAuthor(text);
+ break;
+ case "category":
+ post.setCategory(text);
+ break;
+ case "comments":
+ post.setComments(text);
+ break;
+ case "enclosure":
+ post.setEnclosure(text);
+ break;
+ case "source":
+ post.setSource(text);
+ break;
+ case "item":
+ getFeed().addPost(post);
+ break;
+ }
+ } else { //this saves all the feed-related information.
+ switch (name) {
+ case "category":
+ getFeed().setCategory(text);
+ break;
+ case "cloud":
+ getFeed().setCloud(text);
+ break;
+ case "copyright":
+ getFeed().setCopyright(text);
+ break;
+ case "description":
+ getFeed().setDescription(text);
+ break;
+ case "docs":
+ getFeed().setDocs(text);
+ break;
+ case "generator":
+ getFeed().setGenerator(text);
+ break;
+ case "image":
+ break;
+ case "language":
+ getFeed().setLanguage(text);
+ break;
+ case "lastBuildDate":
+ getFeed().setLastBuildDate(new Date(text));
+ break;
+ case "link":
+ getFeed().setLink(text);
+ break;
+ case "managingEditor":
+ getFeed().setManagingEditor(text);
+ break;
+ case "pubDate":
+ getFeed().setPubDate(new Date(text));
+ break;
+ case "rating":
+ getFeed().setRating(text);
+ break;
+ case "skipDays":
+ getFeed().setSkipDays(text);
+ break;
+ case "skipHours":
+ getFeed().setSkipHours(text);
+ break;
+ case "textInput":
+ getFeed().setTextInput(text);
+ break;
+ case "title":
+ getFeed().setTitle(text);
+ break;
+ case "ttl":
+ getFeed().setTtl(text);
+ break;
+ case "webMaster":
+ getFeed().setWebMaster(text);
+ break;
+ case "item":
+ getFeed().addPost(post);
+ break;
+ }
}
break;
}
- event = myParser.next();
- }
- parsingComplete = false;
- } catch (Exception e) {
- e.printStackTrace();
+ event = myParser.next();
}
+ parsingComplete = false;
+ } catch (Exception e) {
+ e.printStackTrace();
}
+ }
+
+ /**
+ * This function parses the child elements of the <image>tag.
+ * @param myParser XML parser.
+ * @throws XmlPullParserException
+ */
+ public void imageTagParse(XmlPullParser myParser) throws XmlPullParserException {
+ int event;
+ boolean imageloop = true;
+ event = myParser.getEventType();
+ while (imageloop) {
+ String name = myParser.getName();
+ switch (event) {
+ case XmlPullParser.START_TAG:
+ break;
+ case XmlPullParser.TEXT:
+ text = myParser.getText();
+ break;
+ case XmlPullParser.END_TAG:
+ switch (name) {
+ case "url":
+ getFeed().setImageurl(text);
+ break;
+ case "title":
+ getFeed().setImagetitle(text);
+ break;
+ case "link":
+ getFeed().setImagelink(text);
+ break;
+ case "image":
+ imageloop = false;
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Retrieves the XML and parses it.
+ */
public void fetchXML(){
Thread thread = new Thread(new Runnable(){
@Override
public void run() {
try {
- URL url = new URL(urlString);
+ URL url = urlString;
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
@@ -120,4 +244,8 @@ public class FeedLoader {
public void setFeed(Feed feed) {
this.feed = feed;
}
+
+ public Feed getFeed() {
+ return feed;
+ }
}
diff --git a/app/src/main/java/org/rssin/rssin/FeedLoaderAndSorter.java b/app/src/main/java/org/rssin/rssin/FeedLoaderAndSorter.java
new file mode 100755
index 0000000..eda0526
--- /dev/null
+++ b/app/src/main/java/org/rssin/rssin/FeedLoaderAndSorter.java
@@ -0,0 +1,64 @@
+package org.rssin.rssin;
+
+import org.rssin.neurons.FeedSorter;
+import org.rssin.rss.FeedItem;
+import org.rssin.rss.FeedLoader;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by Jos on 20-5-2015.
+ */
+public class FeedLoaderAndSorter {
+ private Filter filter;
+
+ public FeedLoaderAndSorter(Filter filter) {
+ this.filter = filter;
+ }
+
+ /**
+ * Loads the feed(s), filters it, sorts it, and returns the result.
+ * @return The filtered & sorted list of feedtems.
+ */
+ public List<FeedItem> getFilteredFeedItems()
+ {
+ List<FeedItem> resultingItems = new ArrayList<FeedItem>();
+ for(Feed feed : filter.getFeeds())
+ {
+ FeedLoader loader = new FeedLoader(feed.getURL());
+ loader.fetchXML();
+ org.rssin.rss.Feed loadedFeed = loader.getFeed();
+ for(FeedItem item : loadedFeed.getPosts())
+ {
+ if(matchesKeyword(item))
+ {
+ resultingItems.add(item);
+ }
+ }
+ }
+
+ FeedSorter sorter = filter.getSorter();
+ return sorter.sortItems(resultingItems);
+ }
+
+ private boolean matchesKeyword(FeedItem item)
+ {
+ for(Keyword keyword : filter.getKeywords())
+ {
+ if(contains(item.getTitle(), keyword.getKeyword()))
+ {
+ return true;
+ }
+ }
+
+ return filter.getKeywords().size() == 0;
+ }
+
+ private static boolean contains( String haystack, String needle ) {
+ haystack = haystack == null ? "" : haystack;
+ needle = needle == null ? "" : needle;
+
+ return haystack.toLowerCase().contains(needle.toLowerCase());
+ }
+}
diff --git a/app/src/main/java/org/rssin/rssin/Filter.java b/app/src/main/java/org/rssin/rssin/Filter.java
index a5a4cd9..e0e05d0 100644..100755
--- a/app/src/main/java/org/rssin/rssin/Filter.java
+++ b/app/src/main/java/org/rssin/rssin/Filter.java
@@ -2,6 +2,9 @@ package org.rssin.rssin;
import android.text.TextUtils;
+import org.rssin.neurons.FeedSorter;
+import org.rssin.rss.FeedItem;
+
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@@ -15,7 +18,8 @@ public class Filter implements Serializable {
private final List<Feed> feeds;
private final List<Keyword> keywords;
- private String title = new String("");
+ private String title = "";
+ private FeedSorter sorter;
public Filter() {
feeds = new ArrayList<>();
@@ -65,4 +69,7 @@ public class Filter implements Serializable {
this.title = title;
}
+ public FeedSorter getSorter() {
+ return sorter;
+ }
}