mirror of
https://github.com/samuelclay/NewsBlur.git
synced 2025-09-18 21:50:56 +00:00
Merge branch 'master' into feed_settings
* master: Revert "Switching to requests from urllib2/httplib. Bring on the page errors." Fixing #41: Adding REDIS to local_settings.py.template. Revert "Revert "Switching to requests from urllib2/httplib. Bring on the page errors."" Revert "Switching to requests from urllib2/httplib. Bring on the page errors." Switching to requests from urllib2/httplib. Bring on the page errors. Adding a bunch fo keyboard shortcuts. Adding elapsed time field to river and feed view. Fixing autolinking of text links to no longer indiscriminately replace text, causing double encoding of html entities. Fixing the space bar key to not queue, so it's actually useful now! Refining media enclosures by adding all types and linking to their source. Refining media enclosure detection.
This commit is contained in:
commit
36105bf851
10 changed files with 88 additions and 43 deletions
|
@ -432,7 +432,8 @@ def load_single_feed(request, feed_id):
|
|||
feed_authors=feed_authors,
|
||||
classifiers=classifiers,
|
||||
last_update=last_update,
|
||||
feed_id=feed.pk)
|
||||
feed_id=feed.pk,
|
||||
elapsed_time=round(float(timediff), 2))
|
||||
|
||||
if dupe_feed_id: data['dupe_feed_id'] = dupe_feed_id
|
||||
if not usersub:
|
||||
|
@ -486,13 +487,12 @@ def load_starred_stories(request):
|
|||
def load_river_stories(request):
|
||||
limit = 18
|
||||
offset = 0
|
||||
start = datetime.datetime.utcnow()
|
||||
start = time.time()
|
||||
user = get_user(request)
|
||||
feed_ids = [int(feed_id) for feed_id in request.REQUEST.getlist('feeds') if feed_id]
|
||||
original_feed_ids = list(feed_ids)
|
||||
page = int(request.REQUEST.get('page', 1))
|
||||
read_stories_count = int(request.REQUEST.get('read_stories_count', 0))
|
||||
new_flag = request.REQUEST.get('new_flag', False)
|
||||
bottom_delta = datetime.timedelta(days=settings.DAYS_OF_UNREAD)
|
||||
|
||||
if not feed_ids:
|
||||
|
@ -615,19 +615,15 @@ def load_river_stories(request):
|
|||
'tags': apply_classifier_tags(classifier_tags[story['story_feed_id']], story),
|
||||
'title': apply_classifier_titles(classifier_titles[story['story_feed_id']], story),
|
||||
}
|
||||
|
||||
diff = datetime.datetime.utcnow() - start
|
||||
timediff = float("%s.%.2s" % (diff.seconds, (diff.microseconds / 1000)))
|
||||
|
||||
diff = time.time() - start
|
||||
timediff = round(float(diff), 2)
|
||||
logging.user(request, "~FCLoading river stories: page %s - ~SB%s/%s "
|
||||
"stories ~SN(%s/%s/%s feeds) ~FB(%s seconds)" %
|
||||
(page, len(stories), len(mstories), len(found_feed_ids),
|
||||
len(feed_ids), len(original_feed_ids), timediff))
|
||||
|
||||
if new_flag:
|
||||
return dict(stories=stories, classifiers=classifiers)
|
||||
else:
|
||||
logging.user(request, "~BR~FCNo new flag on river")
|
||||
return dict(stories=stories)
|
||||
return dict(stories=stories, classifiers=classifiers, elapsed_time=timediff)
|
||||
|
||||
|
||||
@ajax_login_required
|
||||
|
|
|
@ -619,13 +619,8 @@ class Feed(models.Model):
|
|||
story = pre_process_story(story)
|
||||
|
||||
if story.get('title'):
|
||||
story_contents = story.get('content')
|
||||
story_content = story.get('story_content')
|
||||
story_tags = self.get_tags(story)
|
||||
|
||||
if story_contents is not None:
|
||||
story_content = story_contents[0]['value']
|
||||
else:
|
||||
story_content = story.get('summary')
|
||||
|
||||
existing_story, story_has_changed = self._exists_story(story, story_content, existing_stories)
|
||||
if existing_story is None:
|
||||
|
|
2
fabfile.py
vendored
2
fabfile.py
vendored
|
@ -289,7 +289,7 @@ def setup_psycopg():
|
|||
|
||||
def setup_python():
|
||||
sudo('easy_install pip')
|
||||
sudo('easy_install fabric django celery django-celery django-compress South django-extensions pymongo BeautifulSoup pyyaml nltk==0.9.9 lxml oauth2 pytz boto seacucumber django_ses mongoengine redis')
|
||||
sudo('easy_install fabric django celery django-celery django-compress South django-extensions pymongo BeautifulSoup pyyaml nltk==0.9.9 lxml oauth2 pytz boto seacucumber django_ses mongoengine redis requests')
|
||||
|
||||
put('config/pystartup.py', '.pystartup')
|
||||
with cd(os.path.join(env.NEWSBLUR_PATH, 'vendor/cjson')):
|
||||
|
|
|
@ -42,6 +42,14 @@ OAUTH_SECRET = 'SECRET_KEY_FROM_GOOGLE'
|
|||
# Celery RabbitMQ Broker
|
||||
BROKER_HOST = "127.0.0.1"
|
||||
|
||||
REDIS = {
|
||||
'host': '127.0.0.1',
|
||||
}
|
||||
|
||||
# ===========
|
||||
# = Logging =
|
||||
# ===========
|
||||
|
||||
# Logging (setup for development)
|
||||
LOG_TO_STREAM = True
|
||||
|
||||
|
|
|
@ -35,13 +35,16 @@ NEWSBLUR.log = function(msg) {
|
|||
|
||||
autolink: function() {
|
||||
return this.each(function(){
|
||||
var desc = $(this);
|
||||
desc.textNodes().each(function(){
|
||||
var $desc = $(this);
|
||||
$desc.textNodes().each(function(){
|
||||
var text = $(this);
|
||||
if(text && text.parent() && text.parent()[0] && text.parent()[0].nodeName != 'A') {
|
||||
text.replaceWith(this.data.replace(URL_REGEX, function($0, $1) {
|
||||
return '<a href="' + $0 +'">' + $0 + '</a>';
|
||||
}));
|
||||
if (this.data.indexOf('http') != -1) {
|
||||
text.replaceWith(this.data.replace(URL_REGEX, function($0, $1) {
|
||||
console.log(["Replacing text link", $0]);
|
||||
return '<a href="' + $0 +'">' + $0 + '</a>';
|
||||
}));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -405,9 +405,7 @@ NEWSBLUR.AssetModel.Reader.prototype = {
|
|||
this.make_request('/reader/river_stories', {
|
||||
feeds: feeds,
|
||||
page: page,
|
||||
read_stories_count: this.read_stories_river_count,
|
||||
// TODO: Remove new flag
|
||||
new_flag: true
|
||||
read_stories_count: this.read_stories_river_count
|
||||
}, pre_callback, error_callback, {
|
||||
'ajax_group': (page ? 'feed_page' : 'feed'),
|
||||
'request_type': 'GET'
|
||||
|
|
|
@ -974,9 +974,9 @@
|
|||
}
|
||||
// NEWSBLUR.log(['page_in_story', this.$s.$story_pane, direction, page_height, scroll_height]);
|
||||
if (this.story_view == 'page') {
|
||||
this.$s.$feed_iframe.scrollTo({top:dir+'='+scroll_height, left:'+=0'}, 260);
|
||||
this.$s.$feed_iframe.scrollTo({top:dir+'='+scroll_height, left:'+=0'}, 230, {queue: false});
|
||||
} else if (this.story_view == 'feed') {
|
||||
this.$s.$feed_stories.scrollTo({top:dir+'='+scroll_height, left:'+=0'}, 370);
|
||||
this.$s.$feed_stories.scrollTo({top:dir+'='+scroll_height, left:'+=0'}, 340, {queue: false});
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -6649,7 +6649,7 @@
|
|||
});
|
||||
$document.bind('keydown', 'shift+space', function(e) {
|
||||
e.preventDefault();
|
||||
self.page_in_story(0.6, -1);
|
||||
self.page_in_story(0.65, -1);
|
||||
});
|
||||
$document.bind('keydown', 'u', function(e) {
|
||||
e.preventDefault();
|
||||
|
|
|
@ -88,7 +88,7 @@ NEWSBLUR.ReaderKeyboard.prototype = {
|
|||
])
|
||||
]),
|
||||
$.make('div', { className: 'NB-keyboard-shortcut NB-last' }, [
|
||||
$.make('div', { className: 'NB-keyboard-shortcut-explanation' }, 'Open Site'),
|
||||
$.make('div', { className: 'NB-keyboard-shortcut-explanation' }, 'Open in Story view'),
|
||||
$.make('div', { className: 'NB-keyboard-shortcut-key' }, [
|
||||
'enter'
|
||||
]),
|
||||
|
@ -166,13 +166,43 @@ NEWSBLUR.ReaderKeyboard.prototype = {
|
|||
])
|
||||
]),
|
||||
$.make('div', { className: 'NB-keyboard-shortcut NB-last' }, [
|
||||
$.make('div', { className: 'NB-keyboard-shortcut-explanation' }, 'Mark site/folder as read'),
|
||||
$.make('div', { className: 'NB-keyboard-shortcut-explanation' }, 'Mark all as read'),
|
||||
$.make('div', { className: 'NB-keyboard-shortcut-key' }, [
|
||||
'shift',
|
||||
$.make('span', '+'),
|
||||
'a'
|
||||
])
|
||||
])
|
||||
]),
|
||||
$.make('div', { className: 'NB-keyboard-group' }, [
|
||||
$.make('div', { className: 'NB-keyboard-shortcut' }, [
|
||||
$.make('div', { className: 'NB-keyboard-shortcut-explanation' }, 'Return to dashboard'),
|
||||
$.make('div', { className: 'NB-keyboard-shortcut-key' }, [
|
||||
'd'
|
||||
])
|
||||
]),
|
||||
$.make('div', { className: 'NB-keyboard-shortcut NB-last' }, [
|
||||
$.make('div', { className: 'NB-keyboard-shortcut-explanation' }, 'Open Everything'),
|
||||
$.make('div', { className: 'NB-keyboard-shortcut-key' }, [
|
||||
'shift',
|
||||
$.make('span', '+'),
|
||||
'e'
|
||||
])
|
||||
])
|
||||
]),
|
||||
$.make('div', { className: 'NB-keyboard-group' }, [
|
||||
$.make('div', { className: 'NB-keyboard-shortcut' }, [
|
||||
$.make('div', { className: 'NB-keyboard-shortcut-explanation' }, 'View keyboard shortcuts'),
|
||||
$.make('div', { className: 'NB-keyboard-shortcut-key' }, [
|
||||
'?'
|
||||
])
|
||||
]),
|
||||
$.make('div', { className: 'NB-keyboard-shortcut NB-last' }, [
|
||||
$.make('div', { className: 'NB-keyboard-shortcut-explanation' }, 'Find oldest unread story'),
|
||||
$.make('div', { className: 'NB-keyboard-shortcut-key' }, [
|
||||
'm'
|
||||
])
|
||||
])
|
||||
])
|
||||
]);
|
||||
},
|
||||
|
|
|
@ -247,7 +247,7 @@ class ProcessFeed:
|
|||
# ).order_by('-story_date')
|
||||
ret_values = self.feed.add_update_stories(self.fpf.entries, existing_stories, verbose=self.options['verbose'])
|
||||
|
||||
logging.debug(u' ---> [%-30s] ~FYParsed Feed: new~FG=~FG~SB%s~SN~FY up~FG=~FY~SB%s~SN same~FG=~FY%s err~FG=~FR~SB%s' % (
|
||||
logging.debug(u' ---> [%-30s] ~FYParsed Feed: new=~FG~SB%s~SN~FY up=~FY~SB%s~SN same=~FY%s err=~FR~SB%s' % (
|
||||
unicode(self.feed)[:30],
|
||||
ret_values[ENTRY_NEW], ret_values[ENTRY_UPDATED], ret_values[ENTRY_SAME], ret_values[ENTRY_ERR]))
|
||||
self.feed.update_all_statistics()
|
||||
|
|
|
@ -67,18 +67,33 @@ def pre_process_story(entry):
|
|||
entry['link'] = urlquote(entry_link)
|
||||
if isinstance(entry.get('guid'), dict):
|
||||
entry['guid'] = unicode(entry['guid'])
|
||||
entry_content = ""
|
||||
|
||||
# Normalize story content/summary
|
||||
if entry.get('content'):
|
||||
entry_content = entry['content'][0]['value']
|
||||
if entry.get('media_content') and 'audio controls' not in entry_content:
|
||||
media_url = entry['media_content'][0].get('url') and entry['media_content'][0]['url']
|
||||
media_type = entry['media_content'][0].get('type') and entry['media_content'][0]['type']
|
||||
if media_url and media_type:
|
||||
entry['content'][0]['value'] += """<br><br>
|
||||
<audio controls="controls">
|
||||
<source src="%(media_url)s" type="%(media_type)s" />
|
||||
<a href="%(media_url)s">%(media_url)s</a>
|
||||
</audio>""" % {'media_url': media_url, 'media_type': media_type}
|
||||
entry['story_content'] = entry['content'][0].get('value', '')
|
||||
else:
|
||||
entry['story_content'] = entry.get('summary', '')
|
||||
|
||||
# Add each media enclosure as a Download link
|
||||
for media_content in entry.get('media_content', []):
|
||||
media_url = media_content.get('url', '')
|
||||
media_type = media_content.get('type', '')
|
||||
if media_url and media_type and media_url not in entry['story_content']:
|
||||
if 'audio' in media_type and media_url:
|
||||
entry['story_content'] += """<br><br>
|
||||
<audio controls="controls">
|
||||
<source src="%(media_url)s" type="%(media_type)s" />
|
||||
</audio>""" % {
|
||||
'media_url': media_url,
|
||||
'media_type': media_type
|
||||
}
|
||||
elif 'image' in media_type and media_url:
|
||||
entry['story_content'] += """<br><br><img src="%s" />""" % media_url
|
||||
entry['story_content'] += """<br><br>
|
||||
Download %(media_type)s: <a href="%(media_url)s">%(media_url)s</a>""" % {
|
||||
'media_url': media_url,
|
||||
'media_type': media_type.split('/')[0]
|
||||
}
|
||||
|
||||
entry['guid'] = entry.get('guid') or entry.get('id') or entry.get('link') or str(entry.get('published'))
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue