diff options
author | Camil Staps | 2015-06-10 13:13:35 +0200 |
---|---|---|
committer | Camil Staps | 2015-06-10 13:13:35 +0200 |
commit | 797d7a62c782e4cc141c0c434047dd3fa2fdeff5 (patch) | |
tree | 8c202276615ba6deff33fc858a976d0c40d05e59 /app/src | |
parent | Fix ConcurrentModificationException; cleaner drawer layout (diff) |
IT WORKS
Diffstat (limited to 'app/src')
18 files changed, 171 insertions, 211 deletions
diff --git a/app/src/main/java/org/rssin/android/FeedSorterProvider.java b/app/src/main/java/org/rssin/android/FeedSorterProvider.java index 0f0748d..fcdeca2 100755 --- a/app/src/main/java/org/rssin/android/FeedSorterProvider.java +++ b/app/src/main/java/org/rssin/android/FeedSorterProvider.java @@ -15,11 +15,11 @@ public class FeedSorterProvider { private static FeedSorterProvider instance;
private FeedSorter sorter = null;
private final String storageKey = "FeedSorter";
- private InternalStorageProvider storageProvider;
+ private final StorageProvider storageProvider;
private FeedSorterProvider(Context context)
{
- storageProvider = InternalStorageProvider.getInstance(context);
+ storageProvider = SharedPreferencesStorageProvider.getInstance(context);
}
public synchronized static FeedSorterProvider getInstance()
@@ -43,8 +43,9 @@ public class FeedSorterProvider { {
try {
sorter = (FeedSorter) storageProvider.fetch(storageKey, FeedSorter.class);
- } catch (IOException e) {
+ } catch (Exception e) {
sorter = new FeedSorter();
+ Log.v("FST", "Saving new empty sorterProvider", e);
this.save();
}
}
@@ -52,7 +53,7 @@ public class FeedSorterProvider { return sorter;
}
- public synchronized void save()
+ public void save()
{
FeedSorterStorer storer = new FeedSorterStorer(storageKey, storageProvider, sorter);
new Thread(storer).start();
@@ -72,7 +73,9 @@ public class FeedSorterProvider { @Override
public void run() {
try {
- storageProvider.store(storageKey, feedSorter);
+ synchronized (feedSorter) {
+ storageProvider.store(storageKey, feedSorter);
+ }
} catch (Exception e) {
Log.e("Filter", "Failed to store FeedSorter", e);
}
diff --git a/app/src/main/java/org/rssin/android/FeedSorterTrainer.java b/app/src/main/java/org/rssin/android/FeedSorterTrainer.java index 1f88a3e..9704fc7 100755 --- a/app/src/main/java/org/rssin/android/FeedSorterTrainer.java +++ b/app/src/main/java/org/rssin/android/FeedSorterTrainer.java @@ -24,6 +24,7 @@ public class FeedSorterTrainer implements Runnable { }
}
+ Log.v("FST", "Saving sorterProvider");
sorterProvider.save();
}
}
diff --git a/app/src/main/java/org/rssin/android/FeedsList.java b/app/src/main/java/org/rssin/android/FeedsList.java index 72a56d1..1036ad3 100644 --- a/app/src/main/java/org/rssin/android/FeedsList.java +++ b/app/src/main/java/org/rssin/android/FeedsList.java @@ -1,8 +1,11 @@ package org.rssin.android; import android.content.Context; +import android.preference.PreferenceManager; +import android.util.Log; import org.rssin.rssin.Feed; +import org.rssin.rssin.R; import java.io.IOException; import java.util.Collections; @@ -16,18 +19,39 @@ class FeedsList { private static FeedsList instance; - private final List<Feed> feeds; + private List<Feed> feeds; private final DefaultStorageProvider storageProvider; + public static final boolean USE_DEFAULT_LIST = true; + /** * Fetch from storage provider * @param context needed to get the storageprovider * @throws IOException if data is corrupted, and deserializing fails */ + @SuppressWarnings("all") protected FeedsList(Context context) throws IOException { storageProvider = DefaultStorageProvider.getInstance(context); feeds = storageProvider.allFeeds(); sort(); + + if (USE_DEFAULT_LIST && + feeds.isEmpty() && + !PreferenceManager.getDefaultSharedPreferences(context).getBoolean("firstload", false)) { + String[] feedsList = context.getResources().getStringArray(R.array.default_feeds); + for (String url : feedsList) { + try { + Feed f = new Feed(url); + f.store(storageProvider); + } catch (Exception e) { + Log.w("SPSP", "Couldn't add " + url, e); + } + } + PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean("firstload", true).apply(); + + feeds = storageProvider.allFeeds(); + sort(); + } } public static FeedsList getInstance(Context context) throws IOException { diff --git a/app/src/main/java/org/rssin/android/FiltersList.java b/app/src/main/java/org/rssin/android/FiltersList.java index 6b53186..b555e5e 100755 --- a/app/src/main/java/org/rssin/android/FiltersList.java +++ b/app/src/main/java/org/rssin/android/FiltersList.java @@ -12,7 +12,7 @@ import java.util.List; * A list of filters that can be saved using the DefaultStorageProvider * @author Camil Staps */ -public class FiltersList { +class FiltersList { private static FiltersList instance; diff --git a/app/src/main/java/org/rssin/android/InternalStorageProvider.java b/app/src/main/java/org/rssin/android/InternalStorageProvider.java index c5a7bc1..b6787b4 100644 --- a/app/src/main/java/org/rssin/android/InternalStorageProvider.java +++ b/app/src/main/java/org/rssin/android/InternalStorageProvider.java @@ -1,6 +1,7 @@ package org.rssin.android; import android.content.Context; +import android.util.Log; import org.rssin.neurons.FeedSorter; import org.rssin.rssin.Filter; @@ -8,6 +9,7 @@ import org.rssin.storage.FilterStorageProvider; import org.rssin.storage.Storable; import org.rssin.storage.StorageProvider; +import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; @@ -21,14 +23,15 @@ import java.util.List; * A way to store data in internal storage * @author Camil Staps */ -class InternalStorageProvider implements StorageProvider<String, Storable>, FilterStorageProvider<String> { +class InternalStorageProvider implements StorageProvider<String, FeedSorter>, FilterStorageProvider<String> { protected static final String PREFIX = "storage_", PREFIX_FILTER = "f_", PREFIX_FEEDSORTER = "fs_"; private static InternalStorageProvider instance; private final Context context; - private InternalStorageProvider(Context context) { + // @todo redo singleton + public InternalStorageProvider(Context context) { this.context = context; } @@ -43,7 +46,7 @@ class InternalStorageProvider implements StorageProvider<String, Storable>, Filt } @Override - public synchronized void store(String key, Storable element) throws FileNotFoundException, IOException { + public synchronized void store(String key, FeedSorter element) throws FileNotFoundException, IOException { FileOutputStream fos = context.openFileOutput(getFilename(key, element), Context.MODE_PRIVATE); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(element); @@ -52,7 +55,7 @@ class InternalStorageProvider implements StorageProvider<String, Storable>, Filt } @Override - public Storable fetch(String key, Class className) throws ClassCastException, FileNotFoundException, IOException { + public FeedSorter fetch(String key, Class className) throws ClassCastException, FileNotFoundException, IOException { return fetchFromFilename(getFilename(key, className)); } @@ -61,11 +64,11 @@ class InternalStorageProvider implements StorageProvider<String, Storable>, Filt throw new UnsupportedOperationException("Not implemented yet."); } - public Storable fetchFromFilename(String fileName) throws ClassCastException, FileNotFoundException, IOException { + public FeedSorter fetchFromFilename(String fileName) throws ClassCastException, FileNotFoundException, IOException { FileInputStream fis = context.openFileInput(fileName); ObjectInputStream ois = new ObjectInputStream(fis); try { - return (Storable) ois.readObject(); + return (FeedSorter) ois.readObject(); } catch (ClassNotFoundException e) { return null; } @@ -114,11 +117,11 @@ class InternalStorageProvider implements StorageProvider<String, Storable>, Filt @Override public List<Filter> allFilters() { List<Filter> filters = new ArrayList<>(); - for (String fileName : context.fileList()) { - try { - filters.add((Filter) fetchFromFilename(fileName)); - } catch (ClassCastException | IOException e) {} - } +// for (String fileName : context.fileList()) { +// try { +// filters.add((Filter) fetchFromFilename(fileName)); +// } catch (ClassCastException | IOException e) {} +// } return filters; } @@ -129,11 +132,11 @@ class InternalStorageProvider implements StorageProvider<String, Storable>, Filt @Override public Filter getFilter(String key) { - try { - return (Filter) fetch(key, Filter.class); - } catch (ClassCastException | IOException e) { +// try { +// return (Filter) fetch(key, Filter.class); +// } catch (ClassCastException | IOException e) { return null; - } +// } } @Override diff --git a/app/src/main/java/org/rssin/android/NavigationDrawerAllFeedsFragment.java b/app/src/main/java/org/rssin/android/NavigationDrawerAllFeedsFragment.java index b7a0d73..e32b7e6 100755 --- a/app/src/main/java/org/rssin/android/NavigationDrawerAllFeedsFragment.java +++ b/app/src/main/java/org/rssin/android/NavigationDrawerAllFeedsFragment.java @@ -10,13 +10,12 @@ import android.view.LayoutInflater; import android.view.View;
import android.view.ViewGroup;
-import com.android.volley.VolleyError;
-
-import org.rssin.listener.FallibleListener;
+import org.rssin.listener.RealtimeListener;
import org.rssin.rssin.FeedLoaderAndSorter;
import org.rssin.rssin.R;
import org.rssin.rssin.SortedFeedItemContainer;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -42,24 +41,30 @@ public class NavigationDrawerAllFeedsFragment extends Fragment { RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(context);
mRecyclerView.setLayoutManager(mLayoutManager);
+ final FeedItemAdapter feedItemAdapter = new FeedItemAdapter(new ArrayList<SortedFeedItemContainer>());
+ mRecyclerView.setAdapter(feedItemAdapter);
+ mRecyclerView.setHasFixedSize(true);
+
/**
- * @todo Load feeds in separate thread so that the UI is immediately available
- *
* @todo Now, feed items are only returned after *all* feeds have been loaded. With many
* filters that may take a while, so it would be preferable to return intermediate
* results. We could do this for example with {@link org.rssin.listener.RealtimeListener}
*/
FeedLoaderAndSorter loaderAndSorter = new FeedLoaderAndSorter(FeedsList.getInstance().getFeeds());
- loaderAndSorter.getFilteredFeedItems(context, new VolleyFetcher(context), new FallibleListener<List<SortedFeedItemContainer>, VolleyError>() {
+ loaderAndSorter.getFilteredFeedItems(context, VolleyFetcher.getInstance(context), new RealtimeListener<List<SortedFeedItemContainer>, Object>() {
+ @Override
+ public void finish() {
+ // @todo finish
+ }
+
@Override
public void onReceive(List<SortedFeedItemContainer> data) {
- FeedItemAdapter feedItemAdapter = new FeedItemAdapter(data);
- mRecyclerView.setAdapter(feedItemAdapter);
- mRecyclerView.setHasFixedSize(true);
+ feedItemAdapter.feedItems = data;
+ feedItemAdapter.notifyDataSetChanged();
}
@Override
- public void onError(VolleyError error) {
+ public void onError(Object error) {
Frontend.error(context, R.string.error_net_load);
}
});
diff --git a/app/src/main/java/org/rssin/android/NavigationDrawerFeedFragment.java b/app/src/main/java/org/rssin/android/NavigationDrawerFeedFragment.java index 0f33aca..66b808b 100755 --- a/app/src/main/java/org/rssin/android/NavigationDrawerFeedFragment.java +++ b/app/src/main/java/org/rssin/android/NavigationDrawerFeedFragment.java @@ -13,6 +13,7 @@ import android.view.ViewGroup; import com.android.volley.VolleyError;
import org.rssin.listener.FallibleListener;
+import org.rssin.listener.RealtimeListener;
import org.rssin.rssin.Feed;
import org.rssin.rssin.FeedLoaderAndSorter;
import org.rssin.rssin.R;
@@ -67,24 +68,30 @@ public class NavigationDrawerFeedFragment extends Fragment { List<Feed> singleFeedList = new ArrayList<Feed>();
singleFeedList.add(feed);
+ final FeedItemAdapter feedItemAdapter = new FeedItemAdapter(new ArrayList<SortedFeedItemContainer>());
+ mRecyclerView.setAdapter(feedItemAdapter);
+ mRecyclerView.setHasFixedSize(true);
+
/**
- * @todo Load feeds in separate thread so that the UI is immediately available
- *
* @todo Now, feed items are only returned after *all* feeds have been loaded. With many
* filters that may take a while, so it would be preferable to return intermediate
* results. We could do this for example with {@link org.rssin.listener.RealtimeListener}
*/
FeedLoaderAndSorter loaderAndSorter = new FeedLoaderAndSorter(singleFeedList);
- loaderAndSorter.getFilteredFeedItems(context, new VolleyFetcher(context), new FallibleListener<List<SortedFeedItemContainer>, VolleyError>() {
+ loaderAndSorter.getFilteredFeedItems(context, VolleyFetcher.getInstance(context), new RealtimeListener<List<SortedFeedItemContainer>, Object>() {
+ @Override
+ public void finish() {
+ // @todo finish
+ }
+
@Override
public void onReceive(List<SortedFeedItemContainer> data) {
- FeedItemAdapter feedItemAdapter = new FeedItemAdapter(data);
- mRecyclerView.setAdapter(feedItemAdapter);
- mRecyclerView.setHasFixedSize(true);
+ feedItemAdapter.feedItems = data;
+ feedItemAdapter.notifyDataSetChanged();
}
@Override
- public void onError(VolleyError error) {
+ public void onError(Object error) {
Frontend.error(context, R.string.error_net_load);
}
});
diff --git a/app/src/main/java/org/rssin/android/NavigationDrawerFilterFragment.java b/app/src/main/java/org/rssin/android/NavigationDrawerFilterFragment.java index 74be14a..ececd81 100755 --- a/app/src/main/java/org/rssin/android/NavigationDrawerFilterFragment.java +++ b/app/src/main/java/org/rssin/android/NavigationDrawerFilterFragment.java @@ -13,12 +13,14 @@ import android.view.ViewGroup; import com.android.volley.VolleyError;
import org.rssin.listener.FallibleListener;
+import org.rssin.listener.RealtimeListener;
import org.rssin.rssin.FeedLoaderAndSorter;
import org.rssin.rssin.Filter;
import org.rssin.rssin.R;
import org.rssin.rssin.SortedFeedItemContainer;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -66,24 +68,30 @@ public class NavigationDrawerFilterFragment extends Fragment { filter.ensureFeeds(DefaultStorageProvider.getInstance(context));
+ final FeedItemAdapter feedItemAdapter = new FeedItemAdapter(new ArrayList<SortedFeedItemContainer>());
+ mRecyclerView.setAdapter(feedItemAdapter);
+ mRecyclerView.setHasFixedSize(true);
+
/**
- * @todo Load feeds in separate thread so that the UI is immediately available
- *
* @todo Now, feed items are only returned after *all* feeds have been loaded. With many
* filters that may take a while, so it would be preferable to return intermediate
* results. We could do this for example with {@link org.rssin.listener.RealtimeListener}
*/
FeedLoaderAndSorter loaderAndSorter = new FeedLoaderAndSorter(filter.getFeeds());
- loaderAndSorter.getFilteredFeedItems(context, new VolleyFetcher(context), new FallibleListener<List<SortedFeedItemContainer>, VolleyError>() {
+ loaderAndSorter.getFilteredFeedItems(context, VolleyFetcher.getInstance(context), new RealtimeListener<List<SortedFeedItemContainer>, Object>() {
+ @Override
+ public void finish() {
+ // @todo finish
+ }
+
@Override
public void onReceive(List<SortedFeedItemContainer> data) {
- FeedItemAdapter feedItemAdapter = new FeedItemAdapter(data);
- mRecyclerView.setAdapter(feedItemAdapter);
- mRecyclerView.setHasFixedSize(true);
+ feedItemAdapter.feedItems = data;
+ feedItemAdapter.notifyDataSetChanged();
}
@Override
- public void onError(VolleyError error) {
+ public void onError(Object error) {
Frontend.error(context, R.string.error_net_load);
}
});
diff --git a/app/src/main/java/org/rssin/android/SharedPreferencesStorageProvider.java b/app/src/main/java/org/rssin/android/SharedPreferencesStorageProvider.java index dbfcc9a..ffcf0e1 100755 --- a/app/src/main/java/org/rssin/android/SharedPreferencesStorageProvider.java +++ b/app/src/main/java/org/rssin/android/SharedPreferencesStorageProvider.java @@ -168,19 +168,6 @@ class SharedPreferencesStorageProvider implements StorageProvider, FilterStorage @Override public List<Feed> allFeeds() { Set<String> names = context.getSharedPreferences(ADMIN_PREF_KEY, Context.MODE_PRIVATE).getStringSet("feeds", new HashSet<String>()); - if (names.isEmpty() && !context.getSharedPreferences(ADMIN_PREF_KEY, Context.MODE_PRIVATE).getBoolean("firstload", false)) { - String[] feedsList = context.getResources().getStringArray(R.array.default_feeds); - /*for (String url : feedsList) { - try { - Feed f = new Feed(url); - f.store(this); - } catch (Exception e) { - Log.w("SPSP", "Couldn't add " + url, e); - } - }*/ - context.getSharedPreferences(ADMIN_PREF_KEY, Context.MODE_PRIVATE).edit().putBoolean("firstload", true).apply(); - names = context.getSharedPreferences(ADMIN_PREF_KEY, Context.MODE_PRIVATE).getStringSet("feeds", new HashSet<String>()); - } List<Feed> feeds = new ArrayList<>(); for (String name : names) { Feed feed = getFeed(name); diff --git a/app/src/main/java/org/rssin/android/VolleyFetcher.java b/app/src/main/java/org/rssin/android/VolleyFetcher.java index af6895e..9aa7c03 100644 --- a/app/src/main/java/org/rssin/android/VolleyFetcher.java +++ b/app/src/main/java/org/rssin/android/VolleyFetcher.java @@ -19,14 +19,22 @@ import org.rssin.listener.Listener; */ class VolleyFetcher implements Fetcher { - private final Context context; + private static VolleyFetcher instance; + private final RequestQueue requestQueue; - public VolleyFetcher(Context context) { - this.context = context; + private VolleyFetcher(Context context) { requestQueue = Volley.newRequestQueue(context); } + public static VolleyFetcher getInstance(Context context) { + if (instance == null) { + instance = new VolleyFetcher(context); + } + + return instance; + } + @Override public void fetch(Request request) { fetch(request, null); diff --git a/app/src/main/java/org/rssin/listener/RealtimeListener.java b/app/src/main/java/org/rssin/listener/RealtimeListener.java index 4a2ac3e..cb63b33 100644 --- a/app/src/main/java/org/rssin/listener/RealtimeListener.java +++ b/app/src/main/java/org/rssin/listener/RealtimeListener.java @@ -4,6 +4,6 @@ package org.rssin.listener; * The RealtimeListener lets you call onReceive() multiple times. * When all data has been sent, call finish(). */ -public interface RealtimeListener extends Listener { +public interface RealtimeListener<T,E> extends FallibleListener<T,E> { void finish(); } diff --git a/app/src/main/java/org/rssin/neurons/FeedSorter.java b/app/src/main/java/org/rssin/neurons/FeedSorter.java index 0af57ae..d2605f1 100755 --- a/app/src/main/java/org/rssin/neurons/FeedSorter.java +++ b/app/src/main/java/org/rssin/neurons/FeedSorter.java @@ -24,7 +24,7 @@ public class FeedSorter implements Storable { private static final long serialVersionUID = 0;
private final SentenceSplitter splitter = new SentenceSplitter();
- private MultiNeuralNetwork nn = new MultiNeuralNetwork(25, 50);
+ private MultiNeuralNetwork nn = new MultiNeuralNetwork(10, 50);
private List<TrainingCase> trainingCases = new ArrayList<>();
private int[] isNthMonthInput = new int[12];
@@ -34,36 +34,6 @@ public class FeedSorter implements Storable { private Hashtable<String, Integer> wordInputs = new Hashtable<>();
private Hashtable<String, Integer> authorInputs = new Hashtable<>();
- private synchronized void writeObject(java.io.ObjectOutputStream stream) throws IOException {
- stream.writeObject(nn);
- SerializationTools.writeList(trainingCases, stream);
- SerializationTools.writeArray(isNthMonthInput, stream);
- SerializationTools.writeArray(isNthWeekDayInput, stream);
- stream.writeInt(isMorning);
- stream.writeInt(isAfternoon);
- stream.writeInt(isEvening);
- stream.writeInt(isNight);
- stream.writeInt(biasInput);
- stream.writeObject(categoryInputs);
- stream.writeObject(wordInputs);
- stream.writeObject(authorInputs);
- }
-
- private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
- nn = (MultiNeuralNetwork) stream.readObject();
- trainingCases = SerializationTools.readList(stream);
- isNthMonthInput = SerializationTools.readArrayInt(stream);
- isNthWeekDayInput = SerializationTools.readArrayInt(stream);
- isMorning = stream.readInt();
- isAfternoon = stream.readInt();
- isEvening = stream.readInt();
- isNight = stream.readInt();
- biasInput = stream.readInt();
- categoryInputs = (Hashtable<String, Integer>) stream.readObject();
- wordInputs = (Hashtable<String, Integer>) stream.readObject();
- authorInputs = (Hashtable<String, Integer>) stream.readObject();
- }
-
public FeedSorter() {
biasInput = nn.addInput();
for (int i = 0; i < 12; i++) {
@@ -189,16 +159,16 @@ public class FeedSorter implements Storable { * @param items The list of items.
* @return A new, sorted, list of items.
*/
- public List<SortedFeedItemContainer> sortItems(List<SortedFeedItemContainer> items) {
+ public synchronized void sortItems(List<SortedFeedItemContainer> items) {
final int SECONDS_IN_DAY = 24 * 60 * 60;
for (SortedFeedItemContainer item : items) {
- PredictionInterface prediction = getPrediction(item.getFeeditem());
- item.setScore((long) (item.getFeeditem().getPubDate().getTime() / 1000 + prediction.getOutput() * SECONDS_IN_DAY));
+ if (!item.hasScore()) {
+ PredictionInterface prediction = getPrediction(item.getFeeditem());
+ item.setScore((long) (item.getFeeditem().getPubDate().getTime() / 1000 + prediction.getOutput() * SECONDS_IN_DAY));
+ }
}
Collections.sort(items);
-
- return items;
}
}
diff --git a/app/src/main/java/org/rssin/neurons/MultiNeuralNetwork.java b/app/src/main/java/org/rssin/neurons/MultiNeuralNetwork.java index 9ba40e0..420f43d 100755 --- a/app/src/main/java/org/rssin/neurons/MultiNeuralNetwork.java +++ b/app/src/main/java/org/rssin/neurons/MultiNeuralNetwork.java @@ -13,14 +13,6 @@ class MultiNeuralNetwork implements Serializable { private static final long serialVersionUID = 0;
private NeuralNetwork[] networks;
- private synchronized void writeObject(java.io.ObjectOutputStream stream) throws IOException {
- SerializationTools.writeArray(networks, stream);
- }
-
- private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
- networks = SerializationTools.readArray(stream, NeuralNetwork.class);
- }
-
public MultiNeuralNetwork(int numNetworks, int numHiddenNodes) {
networks = new NeuralNetwork[numNetworks];
for (int i = 0; i < networks.length; i++) {
diff --git a/app/src/main/java/org/rssin/neurons/NeuralNetwork.java b/app/src/main/java/org/rssin/neurons/NeuralNetwork.java index 972f9de..e050145 100755 --- a/app/src/main/java/org/rssin/neurons/NeuralNetwork.java +++ b/app/src/main/java/org/rssin/neurons/NeuralNetwork.java @@ -15,16 +15,6 @@ class NeuralNetwork implements Serializable { private Neuron[] hiddenNodes;
private Neuron outputNode;
- private synchronized void writeObject(java.io.ObjectOutputStream stream) throws IOException {
- SerializationTools.writeArray(hiddenNodes, stream);
- stream.writeObject(outputNode);
- }
-
- private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
- hiddenNodes = SerializationTools.readArray(stream, Neuron.class);
- outputNode = (Neuron) stream.readObject();
- }
-
NeuralNetwork(int numHiddenNodes) {
if (numHiddenNodes < 1) {
throw new IllegalArgumentException("numHiddenNodes must be > 0");
diff --git a/app/src/main/java/org/rssin/neurons/Neuron.java b/app/src/main/java/org/rssin/neurons/Neuron.java index da0e4ca..e29e218 100755 --- a/app/src/main/java/org/rssin/neurons/Neuron.java +++ b/app/src/main/java/org/rssin/neurons/Neuron.java @@ -17,15 +17,6 @@ class Neuron implements Serializable { private List<Double> weights = new ArrayList<>();
- private synchronized void writeObject(java.io.ObjectOutputStream stream) throws IOException {
- SerializationTools.writeList(weights, stream);
- }
-
- private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
- weights = SerializationTools.readList(stream);
- }
-
-
public Neuron() {
}
diff --git a/app/src/main/java/org/rssin/rssin/FeedLoaderAndSorter.java b/app/src/main/java/org/rssin/rssin/FeedLoaderAndSorter.java index a317a27..5e9a05a 100755 --- a/app/src/main/java/org/rssin/rssin/FeedLoaderAndSorter.java +++ b/app/src/main/java/org/rssin/rssin/FeedLoaderAndSorter.java @@ -30,25 +30,68 @@ public class FeedLoaderAndSorter { * @param fetcher HTTP Fetcher
* @param listener Listener for when the fetcher finishes
*/
- public void getFilteredFeedItems(Context context, Fetcher fetcher, final Listener<List<SortedFeedItemContainer>> listener)
- {
+ public void getFilteredFeedItems(
+ Context context,
+ Fetcher fetcher,
+ final RealtimeListener<List<SortedFeedItemContainer>, Object> listener) {
final List<SortedFeedItemContainer> resultingItems = new ArrayList<>();
final Counter counter = new Counter(feeds.size());
final FeedSorter sorter = FeedSorterProvider.getInstance(context).getFeedSorter();
for (Feed feed : feeds) {
+ Loader loader = new Loader(
+ feed,
+ fetcher,
+ listener,
+ resultingItems,
+ counter,
+ sorter
+ );
+ Thread thread = new Thread(loader);
+ thread.start();
+ }
+ }
+
+ private static class Loader implements Runnable {
+
+ final private Feed feed;
+ final private Fetcher fetcher;
+ final private RealtimeListener<List<SortedFeedItemContainer>,Object> listener;
+ final private List<SortedFeedItemContainer> resultingItems;
+ final private Counter counter;
+ final private FeedSorter feedSorter;
+
+ public Loader(
+ Feed feed,
+ Fetcher fetcher,
+ RealtimeListener<List<SortedFeedItemContainer>,Object> listener,
+ List<SortedFeedItemContainer> resultingItems,
+ Counter counter,
+ FeedSorter feedSorter) {
+ this.feed = feed;
+ this.fetcher = fetcher;
+ this.listener = listener;
+ this.resultingItems = resultingItems;
+ this.counter = counter;
+ this.feedSorter = feedSorter;
+ }
+
+ @Override
+ public void run() {
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()) {
- resultingItems.add(new SortedFeedItemContainer(item));
+ List<FeedItem> feedItems = loader.getFeed().getPosts();
+ synchronized (resultingItems) {
+ for (FeedItem item : feedItems) {
+ resultingItems.add(new SortedFeedItemContainer(item));
+ }
+ feedSorter.sortItems(resultingItems);
}
- List<SortedFeedItemContainer> sorted = sorter.sortItems(resultingItems);
-
if (counter.decr().isZero() || listener.getClass() == RealtimeListener.class) {
- listener.onReceive(sorted);
+ listener.onReceive(resultingItems);
if (counter.decr().isZero() && listener.getClass() == RealtimeListener.class) {
((RealtimeListener) listener).finish();
}
@@ -57,9 +100,7 @@ public class FeedLoaderAndSorter { @Override
public void onError(Object error) {
- try {
- ((FallibleListener) listener).onError(error);
- } catch (ClassCastException e) {}
+ listener.onError(error);
}
});
}
diff --git a/app/src/main/java/org/rssin/rssin/SortedFeedItemContainer.java b/app/src/main/java/org/rssin/rssin/SortedFeedItemContainer.java index 2a69bfa..384f43c 100755 --- a/app/src/main/java/org/rssin/rssin/SortedFeedItemContainer.java +++ b/app/src/main/java/org/rssin/rssin/SortedFeedItemContainer.java @@ -3,8 +3,6 @@ package org.rssin.rssin; import android.content.Context;
import org.rssin.android.FeedSorterProvider;
-import org.rssin.android.FiltersList;
-import org.rssin.neurons.FeedSorter;
import org.rssin.neurons.Feedback;
import org.rssin.rss.FeedItem;
@@ -15,24 +13,22 @@ import java.io.Serializable; */
public class SortedFeedItemContainer implements Comparable<SortedFeedItemContainer>, Serializable {
private FeedItem feeditem;
- private long score;
+ private long score = -1;
public SortedFeedItemContainer(FeedItem feeditem)
{
this.feeditem = feeditem;
- this.setScore(-1);
}
public FeedItem getFeeditem() {
return feeditem;
}
- public long getScore() {
- if(score == -1)
- {
- throw new UnsupportedOperationException("score not set");
- }
+ public boolean hasScore() {
+ return score != 0;
+ }
+ public long getScore() {
return score;
}
diff --git a/app/src/main/res/values/feeds.xml b/app/src/main/res/values/feeds.xml index e4ae386..384739b 100644 --- a/app/src/main/res/values/feeds.xml +++ b/app/src/main/res/values/feeds.xml @@ -1,86 +1,20 @@ <?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="default_feeds"> - <item>http://feeds.bbci.co.uk/news/business/rss.xml</item> - <item>http://feeds.bbci.co.uk/news/entertainment_and_arts/rss.xml</item> - <item>http://feeds.bbci.co.uk/news/health/rss.xml</item> <item>http://feeds.bbci.co.uk/news/politics/rss.xml</item> <item>http://feeds.bbci.co.uk/news/science_and_environment/rss.xml</item> <item>http://feeds.bbci.co.uk/news/technology/rss.xml</item> - <item>http://feeds.bbci.co.uk/news/uk/rss.xml</item> <item>http://feeds.bbci.co.uk/news/world/rss.xml</item> <item>http://feeds.bbci.co.uk/sport/0/rss.xml</item> - <item>http://feeds.foxnews.com/foxnews/internal/travel/mixed</item> - <item>http://feeds.foxnews.com/foxnews/opinion</item> <item>http://feeds.foxnews.com/foxnews/politics</item> <item>http://feeds.foxnews.com/foxnews/science</item> - <item>http://feeds.foxnews.com/foxnews/section/lifestyle</item> <item>http://feeds.foxnews.com/foxnews/sports</item> <item>http://feeds.foxnews.com/foxnews/tech</item> - <item>http://feeds.mashable.com/mashable/business</item> - <item>http://feeds.mashable.com/mashable/entertainment</item> - <item>http://feeds.mashable.com/mashable/socialmedia</item> - <item>http://feeds.mashable.com/mashable/tech</item> - <item>http://feeds.reuters.com/news/artsculture</item> - <item>http://feeds.reuters.com/news/economy</item> - <item>http://feeds.reuters.com/news/reutersmedia</item> - <item>http://feeds.reuters.com/news/wealth</item> - <item>http://feeds.reuters.com/reuters/businessNews</item> - <item>http://feeds.reuters.com/reuters/entertainment</item> <item>http://feeds.reuters.com/reuters/environment</item> <item>http://feeds.reuters.com/reuters/financialsNews</item> - <item>http://feeds.reuters.com/reuters/healthNews</item> - <item>http://feeds.reuters.com/reuters/hotStocksNews</item> - <item>http://feeds.reuters.com/reuters/lifestyle</item> - <item>http://feeds.reuters.com/reuters/oddlyEnoughNews</item> - <item>http://feeds.reuters.com/Reuters/PoliticsNews</item> - <item>http://feeds.reuters.com/reuters/scienceNews</item> - <item>http://feeds.reuters.com/reuters/sportsNews</item> - <item>http://feeds.reuters.com/reuters/technologyNews</item> - <item>http://feeds.reuters.com/reuters/technologysectorNews</item> - <item>http://feeds.reuters.com/reuters/UShealthcareNews</item> <item>http://feeds.reuters.com/reuters/worldNews</item> - <item>http://rss.cnn.com/rss/edition_entertainment.rss</item> - <item>http://rss.cnn.com/rss/edition_space.rss</item> - <item>http://rss.cnn.com/rss/edition_sport.rss</item> - <item>http://rss.cnn.com/rss/edition_technology.rss</item> - <item>http://rss.cnn.com/rss/money_news_international.rss</item> - <item>http://rss.cnn.com/rss/si_topstories.rss</item> - <item>http://rss.nytimes.com/services/xml/rss/nyt/Books.xml</item> - <item>http://rss.nytimes.com/services/xml/rss/nyt/Business.xml</item> - <item>http://rss.nytimes.com/services/xml/rss/nyt/Dance.xml</item> - <item>http://rss.nytimes.com/services/xml/rss/nyt/Economy.xml</item> <item>http://rss.nytimes.com/services/xml/rss/nyt/Environment.xml</item> - <item>http://rss.nytimes.com/services/xml/rss/nyt/FashionandStyle.xml</item> - <item>http://rss.nytimes.com/services/xml/rss/nyt/MediaandAdvertising.xml</item> - <item>http://rss.nytimes.com/services/xml/rss/nyt/Movies.xml</item> <item>http://rss.nytimes.com/services/xml/rss/nyt/Music.xml</item> - <item>http://rss.nytimes.com/services/xml/rss/nyt/Science.xml</item> - <item>http://rss.nytimes.com/services/xml/rss/nyt/Sports.xml</item> - <item>http://rss.nytimes.com/services/xml/rss/nyt/Technology.xml</item> <item>http://rss.nytimes.com/services/xml/rss/nyt/Travel.xml</item> - <item>http://www.cnet.com/rss/news/</item> - <item>http://www.dailymail.co.uk/health/index.rss</item> - <item>http://www.dailymail.co.uk/money/index.rss</item> - <item>http://www.dailymail.co.uk/sciencetech/index.rss</item> - <item>http://www.dailymail.co.uk/sport/index.rss</item> - <item>http://www.dailymail.co.uk/tvshowbiz/index.rss</item> - <item>http://www.thesundaily.my/rss/business</item> - <item>http://www.thesundaily.my/rss/lifestyle/food</item> - <item>http://www.thesundaily.my/rss/lifestyle/health</item> - <item>http://www.thesundaily.my/rss/lifestyle/tech</item> - <item>http://www.thesundaily.my/rss/lifestyle/travel</item> - <item>http://www.thesundaily.my/rss/media-marketing</item> - <item>http://www.thesundaily.my/rss/opinion</item> - <item>http://www.thesundaily.my/rss/showbiz</item> - <item>http://www.thesundaily.my/rss/sports</item> - <item>http://www.thesundaily.my/rss/style</item> - <item>http://www.washingtontimes.com/rss/headlines/culture/autos/</item> - <item>http://www.washingtontimes.com/rss/headlines/culture/entertainment/</item> - <item>http://www.washingtontimes.com/rss/headlines/culture/health/</item> - <item>http://www.washingtontimes.com/rss/headlines/culture/travel/</item> - <item>http://www.washingtontimes.com/rss/headlines/news/politics/</item> - <item>http://www.washingtontimes.com/rss/headlines/opinion/</item> - <item>http://www.washingtontimes.com/rss/headlines/sports/</item> </string-array> </resources>
\ No newline at end of file |