mirror of
https://github.com/samuelclay/NewsBlur.git
synced 2025-09-18 21:50:56 +00:00
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:
commit
5b71327531
9 changed files with 66 additions and 18 deletions
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 |
|
@ -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];
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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' })
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue