From d7ccad3b551c411666eec71859cb1bf592bc987f Mon Sep 17 00:00:00 2001 From: Samuel Clay Date: Mon, 8 Apr 2013 17:02:03 -0700 Subject: [PATCH 01/17] Using pipeline for syncing redis user stories. --- apps/reader/models.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/reader/models.py b/apps/reader/models.py index 90e19d727..e575ac256 100644 --- a/apps/reader/models.py +++ b/apps/reader/models.py @@ -660,10 +660,12 @@ class MUserStory(mongo.Document): return story.id - def sync_redis(self, r=None): - if not r: + def sync_redis(self, r=None, pipeline=None): + if pipeline: + r = pipeline + elif not r: r = redis.Redis(connection_pool=settings.REDIS_STORY_POOL) - + if self.story_db_id: all_read_stories_key = 'RS:%s' % (self.user_id) r.sadd(all_read_stories_key, self.story_db_id) @@ -705,9 +707,11 @@ class MUserStory(mongo.Document): total = read_stories.count() print " ---> Syncing %s stories (%s)" % (total, user_id or feed_id) for i, read_story in enumerate(read_stories): + pipeline = r.pipeline() if (i+1) % 1000 == 0: print " ---> %s/%s" % (i+1, total) - read_story.sync_redis(r) + read_story.sync_redis(r, pipeline=pipeline) + pipeline.execute() class UserSubscriptionFolders(models.Model): """ From d90f5fb6a97a492f582afbd197fbb314c81d17b7 Mon Sep 17 00:00:00 2001 From: Samuel Clay Date: Mon, 8 Apr 2013 17:04:23 -0700 Subject: [PATCH 02/17] Fixing pipeline. --- apps/reader/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/reader/models.py b/apps/reader/models.py index e575ac256..b9123efb5 100644 --- a/apps/reader/models.py +++ b/apps/reader/models.py @@ -706,12 +706,12 @@ class MUserStory(mongo.Document): total = read_stories.count() print " ---> Syncing %s stories (%s)" % (total, user_id or feed_id) + pipeline = r.pipeline() for i, read_story in enumerate(read_stories): - pipeline = r.pipeline() if (i+1) % 1000 == 0: print " ---> %s/%s" % (i+1, total) read_story.sync_redis(r, pipeline=pipeline) - pipeline.execute() + pipeline.execute() class UserSubscriptionFolders(models.Model): """ From a6837724e34a5cdab8aa39a36a8f35c74ad40f08 Mon Sep 17 00:00:00 2001 From: Samuel Clay Date: Mon, 8 Apr 2013 17:11:40 -0700 Subject: [PATCH 03/17] Increasing task queue size. --- apps/rss_feeds/tasks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/rss_feeds/tasks.py b/apps/rss_feeds/tasks.py index 53be0b686..23a7d82cd 100644 --- a/apps/rss_feeds/tasks.py +++ b/apps/rss_feeds/tasks.py @@ -33,8 +33,8 @@ class TaskFeeds(Task): r.zcard('scheduled_updates'))) # Regular feeds - if tasked_feeds_size < 1000: - feeds = r.srandmember('queued_feeds', 1000) + if tasked_feeds_size < 2000: + feeds = r.srandmember('queued_feeds', 1500) Feed.task_feeds(feeds, verbose=True) active_count = len(feeds) else: From 6fe74872020853d08d311898b0d44f41a31ed01a Mon Sep 17 00:00:00 2001 From: Samuel Clay Date: Mon, 8 Apr 2013 17:17:51 -0700 Subject: [PATCH 04/17] Forcing pipeline to flush every 1000 stories. --- apps/reader/models.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/reader/models.py b/apps/reader/models.py index b9123efb5..ed6a5dd2e 100644 --- a/apps/reader/models.py +++ b/apps/reader/models.py @@ -706,12 +706,17 @@ class MUserStory(mongo.Document): total = read_stories.count() print " ---> Syncing %s stories (%s)" % (total, user_id or feed_id) - pipeline = r.pipeline() + pipeline = None for i, read_story in enumerate(read_stories): + if not pipeline: + pipeline = r.pipeline() if (i+1) % 1000 == 0: print " ---> %s/%s" % (i+1, total) + pipeline.execute() + pipeline = r.pipeline() read_story.sync_redis(r, pipeline=pipeline) - pipeline.execute() + if pipeline: + pipeline.execute() class UserSubscriptionFolders(models.Model): """ From ede93d21175bc81ee944e44b3434a764e9765025 Mon Sep 17 00:00:00 2001 From: Samuel Clay Date: Mon, 8 Apr 2013 17:43:19 -0700 Subject: [PATCH 05/17] Adding user+feed user story sync, to be used soon on feed requests to clean out users read stories. --- apps/reader/models.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/apps/reader/models.py b/apps/reader/models.py index ed6a5dd2e..c5262dbdb 100644 --- a/apps/reader/models.py +++ b/apps/reader/models.py @@ -685,8 +685,14 @@ class MUserStory(mongo.Document): def sync_all_redis(cls, user_id=None, feed_id=None, force=False): r = redis.Redis(connection_pool=settings.REDIS_STORY_POOL) UNREAD_CUTOFF = datetime.datetime.utcnow() - datetime.timedelta(days=settings.DAYS_OF_UNREAD*2) - - if feed_id: + + if feed_id and user_id: + read_stories = cls.objects.filter(user_id=user_id, + feed_id=feed_id, + read_date__gte=UNREAD_CUTOFF) + key = "RS:%s:%s" % (user_id, feed_id) + r.delete(key) + elif feed_id: read_stories = cls.objects.filter(feed_id=feed_id, read_date__gte=UNREAD_CUTOFF) keys = r.keys("RS:*:%s" % feed_id) print " ---> Deleting %s redis keys: %s" % (len(keys), keys) @@ -705,7 +711,7 @@ class MUserStory(mongo.Document): raise "Specify user_id, feed_id, or force." total = read_stories.count() - print " ---> Syncing %s stories (%s)" % (total, user_id or feed_id) + logging.debug(" ---> ~SN~FMSyncing ~SB%s~SN stories (%s/%s)" % (total, user_id, feed_id)) pipeline = None for i, read_story in enumerate(read_stories): if not pipeline: From 38b7ca8f124066bb2bd5a56eb66dd03b86197700 Mon Sep 17 00:00:00 2001 From: Samuel Clay Date: Mon, 8 Apr 2013 18:22:04 -0700 Subject: [PATCH 06/17] Adding pipeline for redis sync on usersub. --- apps/reader/models.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/reader/models.py b/apps/reader/models.py index c5262dbdb..cc8dfb5f0 100644 --- a/apps/reader/models.py +++ b/apps/reader/models.py @@ -101,8 +101,13 @@ class UserSubscription(models.Model): self.feed.sync_redis() userstories = MUserStory.objects.filter(feed_id=self.feed_id, user_id=self.user_id) + total = userstories.count() + logging.debug(" ---> ~SN~FMSyncing ~SB%s~SN stories (%s)" % (total, self)) + + pipeline = r.pipeline() for userstory in userstories: - userstory.sync_redis(r=r) + userstory.sync_redis(pipeline=pipeline) + pipeline.execute() def get_stories(self, offset=0, limit=6, order='newest', read_filter='all', withscores=False): r = redis.Redis(connection_pool=settings.REDIS_STORY_POOL) From 42b867ebe560acca8a7deeedf05a2d66936e0bc3 Mon Sep 17 00:00:00 2001 From: Samuel Clay Date: Mon, 8 Apr 2013 18:24:45 -0700 Subject: [PATCH 07/17] Cutting off syncable stories. --- apps/reader/models.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/reader/models.py b/apps/reader/models.py index cc8dfb5f0..79bbcc036 100644 --- a/apps/reader/models.py +++ b/apps/reader/models.py @@ -96,11 +96,10 @@ class UserSubscription(models.Model): def sync_redis(self, skip_feed=False): r = redis.Redis(connection_pool=settings.REDIS_STORY_POOL) + UNREAD_CUTOFF = datetime.datetime.utcnow() - datetime.timedelta(days=settings.DAYS_OF_UNREAD+1) - if not skip_feed: - self.feed.sync_redis() - - userstories = MUserStory.objects.filter(feed_id=self.feed_id, user_id=self.user_id) + userstories = MUserStory.objects.filter(feed_id=self.feed_id, user_id=self.user_id, + read_date__gte=UNREAD_CUTOFF) total = userstories.count() logging.debug(" ---> ~SN~FMSyncing ~SB%s~SN stories (%s)" % (total, self)) @@ -689,7 +688,7 @@ class MUserStory(mongo.Document): @classmethod def sync_all_redis(cls, user_id=None, feed_id=None, force=False): r = redis.Redis(connection_pool=settings.REDIS_STORY_POOL) - UNREAD_CUTOFF = datetime.datetime.utcnow() - datetime.timedelta(days=settings.DAYS_OF_UNREAD*2) + UNREAD_CUTOFF = datetime.datetime.utcnow() - datetime.timedelta(days=settings.DAYS_OF_UNREAD+1) if feed_id and user_id: read_stories = cls.objects.filter(user_id=user_id, From 1f51941027c9d774280dde547983997063603ba0 Mon Sep 17 00:00:00 2001 From: Samuel Clay Date: Mon, 8 Apr 2013 18:40:05 -0700 Subject: [PATCH 08/17] Syncing redis on 1% of feed loads. --- apps/reader/views.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/reader/views.py b/apps/reader/views.py index cb117f60f..31fbaf66a 100644 --- a/apps/reader/views.py +++ b/apps/reader/views.py @@ -3,6 +3,7 @@ import time import boto import redis import requests +import random from django.shortcuts import get_object_or_404 from django.shortcuts import render from django.contrib.auth.decorators import login_required @@ -494,6 +495,9 @@ def load_single_feed(request, feed_id): except UserSubscription.DoesNotExist: usersub = None + if usersub and random.random() < 0.01: + usersub.sync_redis() + if query: stories = feed.find_stories(query, offset=offset, limit=limit) elif usersub and (read_filter == 'unread' or order == 'oldest'): From 35a55fd6f3527ab9bc77652622f6b9f2de6c2f5d Mon Sep 17 00:00:00 2001 From: Caleb Eggensperger Date: Tue, 9 Apr 2013 13:21:44 -0500 Subject: [PATCH 09/17] Fix issue where selection within stories was hidden Applied only to list view on dev. --- media/css/reader.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/media/css/reader.css b/media/css/reader.css index 45d9d2450..fde302028 100644 --- a/media/css/reader.css +++ b/media/css/reader.css @@ -999,11 +999,11 @@ body { /* ================ */ -#story_titles ::-moz-selection { +.NB-feed-story-header-info ::-moz-selection { background: transparent; } -#story_titles ::selection { +.NB-feed-story-header-info ::selection { background: transparent; } @@ -9108,4 +9108,4 @@ form.opml_import_form input { } .NB-static-feedchooser .NB-feedchooser-premium-bullets li { background-color: rgba(255, 255, 255, .4); -} \ No newline at end of file +} From d5b33f68fe02869025859eac764baf2767b77cfd Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Tue, 9 Apr 2013 22:45:27 +0100 Subject: [PATCH 10/17] Fix #140. Delete feed now works and confirmation dialog has been added. --- media/android/NewsBlur/res/values/strings.xml | 2 +- .../com/newsblur/activity/FeedItemsList.java | 18 ++- .../src/com/newsblur/activity/Main.java | 9 -- .../newsblur/fragment/DeleteFeedFragment.java | 121 ++++++++++++++++++ .../newsblur/fragment/FolderListFragment.java | 17 ++- .../src/com/newsblur/network/APIClient.java | 1 + 6 files changed, 148 insertions(+), 20 deletions(-) create mode 100644 media/android/NewsBlur/src/com/newsblur/fragment/DeleteFeedFragment.java diff --git a/media/android/NewsBlur/res/values/strings.xml b/media/android/NewsBlur/res/values/strings.xml index 39946183e..a5220a487 100644 --- a/media/android/NewsBlur/res/values/strings.xml +++ b/media/android/NewsBlur/res/values/strings.xml @@ -1,4 +1,3 @@ - NewsBlur @@ -147,4 +146,5 @@ %d COMMENTS All stories marked as read Unknown User + Delete feed \"%s\"? diff --git a/media/android/NewsBlur/src/com/newsblur/activity/FeedItemsList.java b/media/android/NewsBlur/src/com/newsblur/activity/FeedItemsList.java index cd8eac60c..11858630c 100644 --- a/media/android/NewsBlur/src/com/newsblur/activity/FeedItemsList.java +++ b/media/android/NewsBlur/src/com/newsblur/activity/FeedItemsList.java @@ -5,6 +5,7 @@ import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; +import android.support.v4.app.DialogFragment; import android.support.v4.app.FragmentTransaction; import android.widget.Toast; @@ -15,6 +16,7 @@ import com.newsblur.R; import com.newsblur.database.DatabaseConstants; import com.newsblur.database.FeedProvider; import com.newsblur.domain.Feed; +import com.newsblur.fragment.DeleteFeedFragment; import com.newsblur.fragment.FeedItemListFragment; import com.newsblur.fragment.SyncUpdateFragment; import com.newsblur.network.APIManager; @@ -24,7 +26,11 @@ import com.newsblur.service.SyncService; public class FeedItemsList extends ItemsList { public static final String EXTRA_FEED = "feedId"; + public static final String EXTRA_FEED_TITLE = "feedTitle"; + public static final String EXTRA_FOLDER_NAME = "folderName"; private String feedId; + private String feedTitle; + private String folderName; private APIManager apiManager; private boolean stopLoading = false; @@ -33,7 +39,9 @@ public class FeedItemsList extends ItemsList { super.onCreate(bundle); apiManager = new APIManager(this); feedId = getIntent().getStringExtra(EXTRA_FEED); - + feedTitle = getIntent().getStringExtra(EXTRA_FEED_TITLE); + folderName = getIntent().getStringExtra(EXTRA_FOLDER_NAME); + final Uri feedUri = FeedProvider.FEEDS_URI.buildUpon().appendPath(feedId).build(); Cursor cursor = getContentResolver().query(feedUri, null, FeedProvider.getStorySelectionFromState(currentState), null, null); cursor.moveToFirst(); @@ -58,12 +66,8 @@ public class FeedItemsList extends ItemsList { } public void deleteFeed() { - setSupportProgressBarIndeterminateVisibility(true); - final Intent intent = new Intent(Intent.ACTION_SYNC, null, this, SyncService.class); - intent.putExtra(SyncService.EXTRA_STATUS_RECEIVER, syncFragment.receiver); - intent.putExtra(SyncService.SYNCSERVICE_TASK, SyncService.EXTRA_TASK_DELETE_FEED); - intent.putExtra(SyncService.EXTRA_TASK_FEED_ID, Long.parseLong(feedId)); - startService(intent); + DialogFragment deleteFeedFragment = DeleteFeedFragment.newInstance(Long.parseLong(feedId), feedTitle, folderName); + deleteFeedFragment.show(fragmentManager, "dialog"); } @Override diff --git a/media/android/NewsBlur/src/com/newsblur/activity/Main.java b/media/android/NewsBlur/src/com/newsblur/activity/Main.java index 520b692e6..5f4b7d1ef 100644 --- a/media/android/NewsBlur/src/com/newsblur/activity/Main.java +++ b/media/android/NewsBlur/src/com/newsblur/activity/Main.java @@ -115,15 +115,6 @@ public class Main extends NbFragmentActivity implements StateChangedListener, Sy return super.onOptionsItemSelected(item); } - public void deleteFeed(long id, String foldername) { - setSupportProgressBarIndeterminateVisibility(true); - final Intent intent = new Intent(Intent.ACTION_SYNC, null, this, SyncService.class); - intent.putExtra(SyncService.EXTRA_STATUS_RECEIVER, syncFragment.receiver); - intent.putExtra(SyncService.SYNCSERVICE_TASK, SyncService.EXTRA_TASK_DELETE_FEED); - intent.putExtra(SyncService.EXTRA_TASK_FEED_ID, id); - startService(intent); - } - @Override public void changedState(int state) { folderFeedList.changeState(state); diff --git a/media/android/NewsBlur/src/com/newsblur/fragment/DeleteFeedFragment.java b/media/android/NewsBlur/src/com/newsblur/fragment/DeleteFeedFragment.java new file mode 100644 index 000000000..4b525709c --- /dev/null +++ b/media/android/NewsBlur/src/com/newsblur/fragment/DeleteFeedFragment.java @@ -0,0 +1,121 @@ +package com.newsblur.fragment; + +import com.newsblur.R; +import com.newsblur.activity.Main; +import com.newsblur.database.FeedProvider; +import com.newsblur.network.APIManager; + +import android.app.Activity; +import android.net.Uri; +import android.os.AsyncTask; +import android.os.Bundle; +import android.support.v4.app.DialogFragment; +import android.support.v4.app.FragmentManager; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.TextView; +import android.widget.Toast; + +public class DeleteFeedFragment extends DialogFragment { + private static final String FEED_ID = "feed_url"; + private static final String FEED_NAME = "feed_name"; + private static final String FOLDER_NAME = "folder_name"; + + private APIManager apiManager; + + public static DeleteFeedFragment newInstance(final long feedId, final String feedName, final String folderName) { + DeleteFeedFragment frag = new DeleteFeedFragment(); + Bundle args = new Bundle(); + args.putLong(FEED_ID, feedId); + args.putString(FEED_NAME, feedName); + args.putString(FOLDER_NAME, folderName); + frag.setArguments(args); + return frag; + } + + private FragmentManager fragmentManager; + private SyncUpdateFragment syncFragment; + + @Override + public void onCreate(Bundle savedInstanceState) { + setStyle(DialogFragment.STYLE_NO_TITLE, R.style.dialog); + super.onCreate(savedInstanceState); + + fragmentManager = super.getFragmentManager(); + + syncFragment = (SyncUpdateFragment) fragmentManager.findFragmentByTag(SyncUpdateFragment.TAG); + if (syncFragment == null) { + syncFragment = new SyncUpdateFragment(); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + final String deleteFeedString = getResources().getString(R.string.delete_feed_message); + + apiManager = new APIManager(getActivity()); + View v = inflater.inflate(R.layout.fragment_confirm_dialog, null); + TextView messageView = (TextView) v.findViewById(R.id.dialog_message); + messageView.setText(String.format(deleteFeedString, getArguments().getString(FEED_NAME))); + + Button okayButton = (Button) v.findViewById(R.id.dialog_button_okay); + okayButton.setOnClickListener(new OnClickListener() { + public void onClick(final View v) { + v.setEnabled(false); + + new AsyncTask() { + @Override + protected Boolean doInBackground(Void... arg) { + long feedId = getArguments().getLong(FEED_ID); + String folderName = getArguments().getString(FOLDER_NAME); + Log.w("mark", "feedID = " + feedId); + if (apiManager.deleteFeed(feedId, folderName)) { + Uri feedUri = FeedProvider.FEEDS_URI.buildUpon().appendPath(Long.toString(feedId)).build(); + DeleteFeedFragment.this.getActivity().getContentResolver().delete(feedUri, null, null); + return true; + } + else { + return false; + } + } + + @Override + protected void onPostExecute(Boolean result) { + Activity activity = DeleteFeedFragment.this.getActivity(); + if (result) { + Toast.makeText(activity, "Deleted feed", Toast.LENGTH_SHORT).show(); + DeleteFeedFragment.this.dismiss(); + // if called from main view then refresh otherwise it was + // called from the feed view so finish + if (activity instanceof Main) { + ((Main)activity).updateAfterSync(); + } + else { + activity.finish(); + } + } else { + Toast.makeText(activity, getResources().getString(R.string.error_deleting_feed), Toast.LENGTH_LONG).show(); + DeleteFeedFragment.this.dismiss(); + } + }; + }.execute(); + + } + }); + + Button cancelButton = (Button) v.findViewById(R.id.dialog_button_cancel); + cancelButton.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + DeleteFeedFragment.this.dismiss(); + } + }); + + return v; + } + +} diff --git a/media/android/NewsBlur/src/com/newsblur/fragment/FolderListFragment.java b/media/android/NewsBlur/src/com/newsblur/fragment/FolderListFragment.java index 3d3e254f7..a517ff102 100644 --- a/media/android/NewsBlur/src/com/newsblur/fragment/FolderListFragment.java +++ b/media/android/NewsBlur/src/com/newsblur/fragment/FolderListFragment.java @@ -11,6 +11,7 @@ import android.content.SharedPreferences; import android.database.Cursor; import android.os.AsyncTask; import android.os.Bundle; +import android.support.v4.app.DialogFragment; import android.support.v4.app.Fragment; import android.util.Log; import android.view.ContextMenu; @@ -31,7 +32,6 @@ import com.newsblur.R; import com.newsblur.activity.AllStoriesItemsList; import com.newsblur.activity.FeedItemsList; import com.newsblur.activity.ItemsList; -import com.newsblur.activity.Main; import com.newsblur.activity.NewsBlurApplication; import com.newsblur.activity.SocialFeedItemsList; import com.newsblur.database.DatabaseConstants; @@ -183,8 +183,14 @@ public class FolderListFragment extends Fragment implements OnGroupClickListener }.execute(Long.toString(info.id)); return true; } else if (item.getItemId() == R.id.menu_delete_feed) { - Toast.makeText(getActivity(), "Deleted feed", Toast.LENGTH_SHORT).show(); - ((Main) getActivity()).deleteFeed(info.id, null); + int childPosition = ExpandableListView.getPackedPositionChild(info.packedPosition); + int groupPosition = ExpandableListView.getPackedPositionGroup(info.packedPosition); + Cursor childCursor = folderAdapter.getChild(groupPosition, childPosition); + String feedTitle = childCursor.getString(childCursor.getColumnIndex(DatabaseConstants.FEED_TITLE)); + Cursor folderCursor = ((MixedExpandableListAdapter) list.getExpandableListAdapter()).getGroup(groupPosition); + String folderName = folderCursor.getString(folderCursor.getColumnIndex(DatabaseConstants.FOLDER_NAME)); + DialogFragment deleteFeedFragment = DeleteFeedFragment.newInstance(info.id, feedTitle, folderName); + deleteFeedFragment.show(getFragmentManager(), "dialog"); return true; } else if (item.getItemId() == R.id.menu_mark_folder_as_read) { int groupPosition = ExpandableListView.getPackedPositionGroup(info.packedPosition); @@ -329,7 +335,12 @@ public class FolderListFragment extends Fragment implements OnGroupClickListener final Intent intent = new Intent(getActivity(), FeedItemsList.class); Cursor childCursor = folderAdapter.getChild(groupPosition, childPosition); String feedId = childCursor.getString(childCursor.getColumnIndex(DatabaseConstants.FEED_ID)); + String feedTitle = childCursor.getString(childCursor.getColumnIndex(DatabaseConstants.FEED_TITLE)); + final Cursor folderCursor = ((MixedExpandableListAdapter) list.getExpandableListAdapter()).getGroup(groupPosition); + String folderName = folderCursor.getString(folderCursor.getColumnIndex(DatabaseConstants.FOLDER_NAME)); intent.putExtra(FeedItemsList.EXTRA_FEED, feedId); + intent.putExtra(FeedItemsList.EXTRA_FEED_TITLE, feedTitle); + intent.putExtra(FeedItemsList.EXTRA_FOLDER_NAME, folderName); intent.putExtra(ItemsList.EXTRA_STATE, currentState); getActivity().startActivityForResult(intent, FEEDCHECK ); } diff --git a/media/android/NewsBlur/src/com/newsblur/network/APIClient.java b/media/android/NewsBlur/src/com/newsblur/network/APIClient.java index a97d2d943..1cdf1aa75 100644 --- a/media/android/NewsBlur/src/com/newsblur/network/APIClient.java +++ b/media/android/NewsBlur/src/com/newsblur/network/APIClient.java @@ -173,6 +173,7 @@ public class APIClient { } final PrintWriter printWriter = new PrintWriter(connection.getOutputStream()); + Log.d(this.getClass().getName(), "parameterString = " + parameterString); printWriter.print(parameterString); printWriter.close(); From 1dced9d1bd296acde9427d34c435542ec1c0736b Mon Sep 17 00:00:00 2001 From: Mark Anderson Date: Tue, 9 Apr 2013 22:48:23 +0100 Subject: [PATCH 11/17] Remove log call from DeleteFeedFragment --- .../NewsBlur/src/com/newsblur/fragment/DeleteFeedFragment.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/media/android/NewsBlur/src/com/newsblur/fragment/DeleteFeedFragment.java b/media/android/NewsBlur/src/com/newsblur/fragment/DeleteFeedFragment.java index 4b525709c..5b19f99a8 100644 --- a/media/android/NewsBlur/src/com/newsblur/fragment/DeleteFeedFragment.java +++ b/media/android/NewsBlur/src/com/newsblur/fragment/DeleteFeedFragment.java @@ -11,7 +11,6 @@ import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.DialogFragment; import android.support.v4.app.FragmentManager; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -73,7 +72,6 @@ public class DeleteFeedFragment extends DialogFragment { protected Boolean doInBackground(Void... arg) { long feedId = getArguments().getLong(FEED_ID); String folderName = getArguments().getString(FOLDER_NAME); - Log.w("mark", "feedID = " + feedId); if (apiManager.deleteFeed(feedId, folderName)) { Uri feedUri = FeedProvider.FEEDS_URI.buildUpon().appendPath(Long.toString(feedId)).build(); DeleteFeedFragment.this.getActivity().getContentResolver().delete(feedUri, null, null); From b245754710a8a9af792c466cf5de6bc435d6fa56 Mon Sep 17 00:00:00 2001 From: Lance Johnson Date: Tue, 9 Apr 2013 22:09:08 -0500 Subject: [PATCH 12/17] Fix for #159 force close during add feed (auto complete) now that is is enabled again --- .../src/com/newsblur/network/APIManager.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/media/android/NewsBlur/src/com/newsblur/network/APIManager.java b/media/android/NewsBlur/src/com/newsblur/network/APIManager.java index d46e31fbc..c936e4698 100644 --- a/media/android/NewsBlur/src/com/newsblur/network/APIManager.java +++ b/media/android/NewsBlur/src/com/newsblur/network/APIManager.java @@ -700,12 +700,15 @@ public class APIManager { // TODO find a better way to identify these failed responses boolean isServerMessage = false; JsonParser parser = new JsonParser(); - JsonObject asJsonObject = parser.parse(json).getAsJsonObject(); - if(asJsonObject.has("code")) { - JsonElement codeItem = asJsonObject.get("code"); - int code = codeItem.getAsInt(); - if(code == -1) - isServerMessage = true; + JsonElement jsonElement = parser.parse(json); + if(jsonElement.isJsonObject()) { + JsonObject asJsonObject = jsonElement.getAsJsonObject(); + if(asJsonObject.has("code")) { + JsonElement codeItem = asJsonObject.get("code"); + int code = codeItem.getAsInt(); + if(code == -1) + isServerMessage = true; + } } return isServerMessage; } From 0d71c8ac59bb46e0c6b8e5fe918672de8d908212 Mon Sep 17 00:00:00 2001 From: Lance Johnson Date: Tue, 9 Apr 2013 23:16:02 -0500 Subject: [PATCH 13/17] Fix registration regression bug caused by #151 --- .../NewsBlur/src/com/newsblur/activity/RegisterProgress.java | 3 ++- .../src/com/newsblur/fragment/RegisterProgressFragment.java | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/media/android/NewsBlur/src/com/newsblur/activity/RegisterProgress.java b/media/android/NewsBlur/src/com/newsblur/activity/RegisterProgress.java index b6603e008..37555d7e6 100644 --- a/media/android/NewsBlur/src/com/newsblur/activity/RegisterProgress.java +++ b/media/android/NewsBlur/src/com/newsblur/activity/RegisterProgress.java @@ -4,10 +4,11 @@ import android.os.Bundle; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; +import com.actionbarsherlock.app.SherlockFragmentActivity; import com.newsblur.R; import com.newsblur.fragment.RegisterProgressFragment; -public class RegisterProgress extends NbFragmentActivity { +public class RegisterProgress extends SherlockFragmentActivity { private FragmentManager fragmentManager; private String currentTag = "fragment"; diff --git a/media/android/NewsBlur/src/com/newsblur/fragment/RegisterProgressFragment.java b/media/android/NewsBlur/src/com/newsblur/fragment/RegisterProgressFragment.java index 3ffd851cb..cc0e6bb71 100644 --- a/media/android/NewsBlur/src/com/newsblur/fragment/RegisterProgressFragment.java +++ b/media/android/NewsBlur/src/com/newsblur/fragment/RegisterProgressFragment.java @@ -79,6 +79,7 @@ public class RegisterProgressFragment extends Fragment { public void onClick(View arg0) { Intent i = new Intent(getActivity(), AddSites.class); startActivity(i); + getActivity().finish(); } }); @@ -111,10 +112,12 @@ public class RegisterProgressFragment extends Fragment { i.putExtra("username", username); i.putExtra("password", password); startActivity(i); + getActivity().finish(); } } else { Toast.makeText(getActivity(), extractErrorMessage(response), Toast.LENGTH_LONG).show(); startActivity(new Intent(getActivity(), Login.class)); + getActivity().finish(); } } From a77f22da106b14c632db57da35d96d62d83a22ff Mon Sep 17 00:00:00 2001 From: Lance Johnson Date: Tue, 9 Apr 2013 23:38:00 -0500 Subject: [PATCH 14/17] Have RegisterProgressFragment finished via noHistory Manifest option rather than hackish finish with Fragment. Improve comments --- media/android/NewsBlur/AndroidManifest.xml | 1 + .../src/com/newsblur/activity/RegisterProgress.java | 6 +++++- .../src/com/newsblur/fragment/RegisterProgressFragment.java | 3 --- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/media/android/NewsBlur/AndroidManifest.xml b/media/android/NewsBlur/AndroidManifest.xml index 893692046..6ba0ed9f5 100644 --- a/media/android/NewsBlur/AndroidManifest.xml +++ b/media/android/NewsBlur/AndroidManifest.xml @@ -36,6 +36,7 @@ Date: Wed, 10 Apr 2013 11:23:03 -0700 Subject: [PATCH 15/17] Rejiggering autocomplete to only include > 10 subs. --- apps/rss_feeds/models.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/rss_feeds/models.py b/apps/rss_feeds/models.py index 856440ed1..313d78c1b 100644 --- a/apps/rss_feeds/models.py +++ b/apps/rss_feeds/models.py @@ -228,18 +228,18 @@ class Feed(models.Model): return MStory.sync_all_redis(self.pk) def sync_autocompletion(self): - if self.num_subscribers <= 1: return + if self.num_subscribers <= 10: return if self.branch_from_feed: return if any(t in self.feed_address for t in ['token', 'private']): return engine = RedisEngine(prefix="FT", connection_pool=settings.REDIS_AUTOCOMPLETE_POOL) engine.store(self.pk, title=self.feed_title) - engine.boost(self.pk, self.num_subscribers) + engine.boost(self.pk, min(1, self.num_subscribers / 10000.)) parts = urlparse(self.feed_address) engine = RedisEngine(prefix="FA", connection_pool=settings.REDIS_AUTOCOMPLETE_POOL) engine.store(self.pk, title=parts.hostname) - engine.boost(self.pk, self.num_subscribers) + engine.boost(self.pk, min(1, self.num_subscribers / 10000.)) @classmethod def autocomplete(self, prefix, limit=5): From 92b74a834689d53a8dd2fe5dc7a34a691b47b827 Mon Sep 17 00:00:00 2001 From: Samuel Clay Date: Wed, 10 Apr 2013 13:14:04 -0700 Subject: [PATCH 16/17] Removing logo from shared stories sent by email. It *was* too intrusive. --- templates/mail/email_base.xhtml | 2 ++ templates/mail/email_story_html.xhtml | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/templates/mail/email_base.xhtml b/templates/mail/email_base.xhtml index 5b0563f78..7de23f217 100644 --- a/templates/mail/email_base.xhtml +++ b/templates/mail/email_base.xhtml @@ -14,7 +14,9 @@ diff --git a/templates/mail/email_story_html.xhtml b/templates/mail/email_story_html.xhtml index a099875ad..01fb6369d 100644 --- a/templates/mail/email_story_html.xhtml +++ b/templates/mail/email_story_html.xhtml @@ -1,10 +1,12 @@ {% extends "mail/email_base.xhtml" %} {% load social_tags %} +{% block header %}{% endblock %} + {% block body %} -

- {{ from_name }} is sharing a story with you entitled "{{ story.story_title }}"{% if feed %} from {{ feed.feed_title }}{% endif %}: +

+ {{ from_name }} is sharing a story with you entitled "{{ story.story_title }}"{% if feed %} from {{ feed.feed_title }}{% endif %}

{% if comments %} @@ -12,7 +14,7 @@ {{ comments }}

{% endif %} -
+

{{ story.story_title }}

From ccb6d38fa3bac63512398716702bd543935a89ba Mon Sep 17 00:00:00 2001 From: Samuel Clay Date: Wed, 10 Apr 2013 19:14:19 -0700 Subject: [PATCH 17/17] Adding support for automatically converting google alerts. --- apps/rss_feeds/models.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/apps/rss_feeds/models.py b/apps/rss_feeds/models.py index 313d78c1b..5e80a975b 100644 --- a/apps/rss_feeds/models.py +++ b/apps/rss_feeds/models.py @@ -177,6 +177,8 @@ class Feed(models.Model): self.next_scheduled_update = datetime.datetime.utcnow() if not self.queued_date: self.queued_date = datetime.datetime.utcnow() + self.fix_google_alerts_urls() + feed_address = self.feed_address or "" feed_link = self.feed_link or "" self.hash_address_and_link = hashlib.sha1(feed_address+feed_link).hexdigest() @@ -269,6 +271,14 @@ class Feed(models.Model): def merge_feeds(cls, *args, **kwargs): return merge_feeds(*args, **kwargs) + def fix_google_alerts_urls(self): + if (self.feed_address.startswith('http://user/') and + '/state/com.google/alerts/' in self.feed_address): + match = re.match(r"http://user/(\d+)/state/com.google/alerts/(\d+)", self.feed_address) + if match: + user_id, alert_id = match.groups() + self.feed_address = "http://www.google.com/alerts/feeds/%s/%s" % (user_id, alert_id) + @classmethod def schedule_feed_fetches_immediately(cls, feed_ids): logging.info(" ---> ~SN~FMScheduling immediate fetch of ~SB%s~SN feeds..." %
+ {% block header %} NewsBlur + {% endblock header %}