Merge branch 'master' into social

* master:
  Error handling in orphan detection.
  Collecting orphaned feeds for users. These somehow got lost, and I'm not sure how. Eventually I'd like to run this on every user account.
  Fixing issue around feed titles that disappear. This just confirms that the new feed title is substantive.
  Uncommenting Readability sharing. This was written a loooong time ago, but their API is finally ready.
  Fixing an issue around mal-formed requests aginst WordPress's Bad Behavior plugin, which checks for the 'Accept: *' header.
  Fixing missing folder issue in iOS app. Occurs when user has no feeds in top level, when the Everything psuedo-folder obscures the top folder.

Conflicts:
	apps/reader/models.py
This commit is contained in:
Samuel Clay 2012-03-20 10:33:15 -07:00
commit 5b71327531
9 changed files with 66 additions and 18 deletions

View file

@ -367,8 +367,41 @@ class UserSubscription(models.Model):
switch_feed_for_classifier(MClassifierAuthor)
switch_feed_for_classifier(MClassifierFeed)
switch_feed_for_classifier(MClassifierTag)
@classmethod
def collect_orphan_feeds(cls, user):
us = cls.objects.filter(user=user)
try:
usf = UserSubscriptionFolders.objects.get(user=user)
except UserSubscriptionFolders.DoesNotExist:
return
us_feed_ids = set([sub.feed_id for sub in us])
folders = json.decode(usf.folders)
def collect_ids(folders, found_ids):
for item in folders:
# print ' --> %s' % item
if isinstance(item, int):
# print ' --> Adding feed: %s' % item
found_ids.add(item)
elif isinstance(item, dict):
# print ' --> Descending folder dict: %s' % item.values()
found_ids.update(collect_ids(item.values(), found_ids))
elif isinstance(item, list):
# print ' --> Descending folder list: %s' % len(item)
found_ids.update(collect_ids(item, found_ids))
# print ' --> Returning: %s' % found_ids
return found_ids
found_ids = collect_ids(folders, set())
diff = len(us_feed_ids) - len(found_ids)
if diff > 0:
logging.info(" ---> Collecting orphans on %s. %s feeds with %s orphans" % (user.username, len(us_feed_ids), diff))
orphan_ids = us_feed_ids - found_ids
folders.extend(list(orphan_ids))
usf.folders = json.encode(folders)
usf.save()
class MUserStory(mongo.Document):
"""
Stories read by the user. These are deleted as the mark_read_date for the

View file

@ -268,7 +268,7 @@ def load_feeds_flat(request):
feeds[sub.feed_id] = sub.canonical(include_favicon=include_favicons)
folders = json.decode(folders.folders)
flat_folders = {}
flat_folders = {" ": []}
def make_feeds_folder(items, parent_folder="", depth=0):
for item in items:

View file

@ -21,7 +21,7 @@ from mongoengine.base import ValidationError
from apps.rss_feeds.tasks import UpdateFeeds
from celery.task import Task
from utils import json_functions as json
from utils import feedfinder
from utils import feedfinder, feedparser
from utils import urlnorm
from utils import log as logging
from utils.fields import AutoOneToOneField
@ -203,7 +203,15 @@ class Feed(models.Model):
if feed and len(feed) > offset:
feed = feed[offset]
elif create:
create_okay = False
if feedfinder.isFeed(url):
create_okay = True
elif aggressive:
# Could still be a feed. Just check if there are entries
fp = feedparser.parse(url)
if len(fp.entries):
create_okay = True
if create_okay:
feed = cls.objects.create(feed_address=url)
feed = feed.update()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 539 B

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -237,15 +237,20 @@
[appDelegate.dictFoldersArray addObject:f];
NSArray *folder = [appDelegate.dictFolders objectForKey:f];
sortedArray = [folder sortedArrayUsingComparator:^NSComparisonResult(id id1, id id2) {
return [[[appDelegate.dictFeeds objectForKey:[NSString stringWithFormat:@"%@", id1]] objectForKey:@"feed_title"]
caseInsensitiveCompare:[[appDelegate.dictFeeds objectForKey:[NSString stringWithFormat:@"%@", id2]] objectForKey:@"feed_title"]];
NSString *feedTitleA = [[appDelegate.dictFeeds
objectForKey:[NSString stringWithFormat:@"%@", id1]]
objectForKey:@"feed_title"];
NSString *feedTitleB = [[appDelegate.dictFeeds
objectForKey:[NSString stringWithFormat:@"%@", id2]]
objectForKey:@"feed_title"];
return [feedTitleA caseInsensitiveCompare:feedTitleB];
}];
[sortedFolders setValue:sortedArray forKey:f];
}
appDelegate.dictFolders = sortedFolders;
[appDelegate.dictFoldersArray sortUsingSelector:@selector(caseInsensitiveCompare:)];
NSLog(@"Folders: %@, Array: %@", appDelegate.dictFolders, appDelegate.dictFoldersArray);
[self calculateFeedLocations:YES];
[self.feedTitlesTable reloadData];

View file

@ -3121,7 +3121,7 @@
send_story_to_readability: function(story_id) {
var story = this.model.get_story(story_id);
var url = 'https://readability.com/save';
var url = 'http://www.readability.com/save';
var readability_url = [
url,
'?url=',
@ -5020,11 +5020,11 @@
}, this)).bind('mouseleave', _.bind(function(e) {
$(e.target).siblings('.NB-menu-manage-title').text('Email story').parent().removeClass('NB-menu-manage-highlight-instapaper');
}, this))),
// (NEWSBLUR.Preferences['story_share_readability'] && $.make('div', { className: 'NB-menu-manage-thirdparty-icon NB-menu-manage-thirdparty-readability'}).bind('mouseenter', _.bind(function(e) {
// $(e.target).siblings('.NB-menu-manage-title').text('Readability').parent().addClass('NB-menu-manage-highlight-readability');
// }, this)).bind('mouseleave', _.bind(function(e) {
// $(e.target).siblings('.NB-menu-manage-title').text('Email story').parent().removeClass('NB-menu-manage-highlight-readability');
// }, this))),
(NEWSBLUR.Preferences['story_share_readability'] && $.make('div', { className: 'NB-menu-manage-thirdparty-icon NB-menu-manage-thirdparty-readability'}).bind('mouseenter', _.bind(function(e) {
$(e.target).siblings('.NB-menu-manage-title').text('Readability').parent().addClass('NB-menu-manage-highlight-readability');
}, this)).bind('mouseleave', _.bind(function(e) {
$(e.target).siblings('.NB-menu-manage-title').text('Email story').parent().removeClass('NB-menu-manage-highlight-readability');
}, this))),
$.make('div', { className: 'NB-menu-manage-image' }),
$.make('div', { className: 'NB-menu-manage-title' }, 'Email story')
]).bind('click', _.bind(function(e) {

View file

@ -450,10 +450,10 @@ _.extend(NEWSBLUR.ReaderPreferences.prototype, {
$.make('input', { type: 'checkbox', id: 'NB-preference-story-share-facebook', name: 'story_share_facebook' }),
$.make('label', { 'for': 'NB-preference-story-share-facebook' })
]),
// $.make('div', { className: 'NB-preference-option', title: 'Readability' }, [
// $.make('input', { type: 'checkbox', id: 'NB-preference-story-share-readability', name: 'story_share_readability' }),
// $.make('label', { 'for': 'NB-preference-story-share-readability' })
// ]),
$.make('div', { className: 'NB-preference-option', title: 'Readability' }, [
$.make('input', { type: 'checkbox', id: 'NB-preference-story-share-readability', name: 'story_share_readability' }),
$.make('label', { 'for': 'NB-preference-story-share-readability' })
]),
$.make('div', { className: 'NB-preference-option', title: 'Instapaper' }, [
$.make('input', { type: 'checkbox', id: 'NB-preference-story-share-instapaper', name: 'story_share_instapaper' }),
$.make('label', { 'for': 'NB-preference-story-share-instapaper' })

View file

@ -179,7 +179,8 @@ class ProcessFeed:
self.fpf.entries = self.fpf.entries[:50]
self.feed.feed_title = self.fpf.feed.get('title', self.feed.feed_title)
if self.fpf.feed.get('title'):
self.feed.feed_title = self.fpf.feed['title']
tagline = self.fpf.feed.get('tagline', self.feed.data.feed_tagline)
if tagline:
self.feed.data.feed_tagline = utf8encode(tagline)

View file

@ -75,7 +75,7 @@ class URLGatekeeper:
self.urlopener = urllib.FancyURLopener()
self.urlopener.version = "NewsBlur Feed Finder (Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_1) AppleWebKit/534.48.3 (KHTML, like Gecko) Version/5.1 Safari/534.48.3)"
_debuglog(self.urlopener.version)
self.urlopener.addheaders = [('User-agent', self.urlopener.version)]
self.urlopener.addheaders = [('User-agent', self.urlopener.version), ('Accept', '*')]
robotparser.URLopener.version = self.urlopener.version
robotparser.URLopener.addheaders = self.urlopener.addheaders
@ -292,6 +292,7 @@ def feeds(uri, all=False, querySyndic8=False, _recurs=None):
if all or not outfeeds:
_debuglog('no A tags, guessing')
suffixes = [ # filenames used by popular software:
'feed/', # obvious
'atom.xml', # blogger, TypePad
'index.atom', # MT, apparently
'index.rdf', # MT