mirror of
https://github.com/samuelclay/NewsBlur.git
synced 2025-09-18 21:50:56 +00:00
- Fixing caching of feeds and users.
- Added loading indicator on new feed. - Cleaned up numerous bugs around showing/hiding out-of-score stories.
This commit is contained in:
parent
98d4762735
commit
1180100e37
10 changed files with 77 additions and 81 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
logs/*.log
|
||||
*.pyc
|
|
@ -83,7 +83,7 @@ class ClassifierTag(models.Model):
|
|||
|
||||
def apply_classifier_titles(classifiers, story):
|
||||
for classifier in classifiers:
|
||||
if classifier.title in story['story_title']:
|
||||
if classifier.title.lower() in story['story_title'].lower():
|
||||
# print 'Titles: (%s) %s -- %s' % (classifier.title in story['story_title'], classifier.title, story['story_title'])
|
||||
return classifier.score
|
||||
return 0
|
||||
|
|
|
@ -2,11 +2,12 @@ from django.conf.urls.defaults import *
|
|||
from apps.reader import views
|
||||
|
||||
urlpatterns = patterns('',
|
||||
url(r'^$', views.index, name='index'),
|
||||
url(r'^$', views.index),
|
||||
url(r'^logout', views.logout, name='logout'),
|
||||
url(r'^login', views.login, name='login'),
|
||||
(r'^load_single_feed', views.load_single_feed),
|
||||
(r'^load_feed_page', views.load_feed_page),
|
||||
(r'^load_feeds', views.load_feeds),
|
||||
(r'^refresh_feed', views.refresh_feed),
|
||||
(r'^mark_story_as_read', views.mark_story_as_read),
|
||||
(r'^mark_story_as_like', views.mark_story_as_like),
|
||||
(r'^mark_story_as_dislike', views.mark_story_as_dislike),
|
||||
|
|
|
@ -7,17 +7,18 @@ try:
|
|||
except:
|
||||
pass
|
||||
from django.core.cache import cache
|
||||
from django.views.decorators.cache import never_cache
|
||||
from django.db.models.aggregates import Count
|
||||
from apps.reader.models import UserSubscription, UserSubscriptionFolders, UserStory
|
||||
from utils import json
|
||||
from utils.user_functions import get_user
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth.forms import AuthenticationForm
|
||||
from django.contrib.auth import authenticate, login
|
||||
from django.http import HttpResponse, HttpRequest, HttpResponseRedirect
|
||||
from django.core import serializers
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.views.decorators.cache import cache_page
|
||||
from djangologging.decorators import suppress_logging_output
|
||||
from apps.analyzer.models import ClassifierFeed, ClassifierAuthor, ClassifierTag, ClassifierTitle
|
||||
from apps.analyzer.models import apply_classifier_titles, apply_classifier_feeds, apply_classifier_authors, apply_classifier_tags
|
||||
|
@ -28,29 +29,32 @@ import random
|
|||
|
||||
SINGLE_DAY = 60*60*24
|
||||
|
||||
@never_cache
|
||||
def index(request):
|
||||
# feeds = Feed.objects.filter(usersubscription__user=request.user)
|
||||
# for f in feeds:
|
||||
# f.update()
|
||||
|
||||
# context = feeds
|
||||
context = {}
|
||||
print request.user
|
||||
print "User: %s" % request.user
|
||||
form = AuthenticationForm(request.POST)
|
||||
user = request.user
|
||||
user_info = _parse_user_info(user)
|
||||
return render_to_response('reader/feeds.xhtml', {'form': form},
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
@never_cache
|
||||
def login(request):
|
||||
username = request.POST['username']
|
||||
password = request.POST['password']
|
||||
user = authenticate(username=username, password=password)
|
||||
if user is not None:
|
||||
if user.is_active:
|
||||
login(request, user)
|
||||
return HttpResponseRedirect(reverse('index'))
|
||||
if request.method == "POST":
|
||||
form = AuthenticationForm(data=request.POST)
|
||||
if form.is_valid():
|
||||
from django.contrib.auth import login
|
||||
login(request, form.get_user())
|
||||
return HttpResponseRedirect(reverse('index'))
|
||||
|
||||
return index(request)
|
||||
|
||||
@never_cache
|
||||
def logout(request):
|
||||
print "Logout: %s" % request.user
|
||||
from django.contrib.auth import logout
|
||||
logout(request)
|
||||
|
||||
return HttpResponseRedirect(reverse('index'))
|
||||
|
||||
def load_feeds(request):
|
||||
user = get_user(request)
|
||||
|
||||
|
@ -158,35 +162,6 @@ def load_single_feed(request):
|
|||
data = json.encode(context)
|
||||
return HttpResponse(data, mimetype='application/json')
|
||||
|
||||
def refresh_feed(request):
|
||||
feed_id = request.REQUEST['feed_id']
|
||||
force_update = request.GET.get('force', False)
|
||||
feeds = Feed.objects.filter(id=feed_id)
|
||||
|
||||
feeds = refresh_feeds(feeds, force_update)
|
||||
|
||||
context = {}
|
||||
|
||||
user = request.user
|
||||
user_info = _parse_user_info(user)
|
||||
context.update(user_info)
|
||||
|
||||
return render_to_response('reader/feeds.xhtml', context,
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
def refresh_feeds(feeds, force=False):
|
||||
for f in feeds:
|
||||
logging.debug('Feed Updating: %s' % f)
|
||||
f.update(force)
|
||||
usersubs = UserSubscription.objects.filter(
|
||||
feed=f.id
|
||||
)
|
||||
for us in usersubs:
|
||||
us.count_unread()
|
||||
logging.info('Deleteing user sub cache: %s' % us.user_id)
|
||||
cache.delete('usersub:%s' % us.user_id)
|
||||
return
|
||||
|
||||
@suppress_logging_output
|
||||
def load_feed_page(request):
|
||||
feed = Feed.objects.get(id=request.REQUEST.get('feed_id'))
|
||||
|
|
|
@ -34,7 +34,7 @@ NEWSBLUR.AssetModel.Reader.prototype = {
|
|||
return;
|
||||
},
|
||||
|
||||
make_request: function(url, data, callback) {
|
||||
make_request: function(url, data, callback, error_callback) {
|
||||
$.ajax({
|
||||
url: url,
|
||||
data: data,
|
||||
|
@ -71,6 +71,7 @@ NEWSBLUR.AssetModel.Reader.prototype = {
|
|||
},
|
||||
error: function(e) {
|
||||
NEWSBLUR.log(['AJAX Error', e]);
|
||||
error_callback();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@ -87,13 +88,15 @@ NEWSBLUR.AssetModel.Reader.prototype = {
|
|||
}
|
||||
}
|
||||
|
||||
if (!read) {
|
||||
if (!read && NEWSBLUR.Globals.is_authenticated) {
|
||||
this.make_request('/reader/mark_story_as_read',
|
||||
{
|
||||
story_id: story_id,
|
||||
feed_id: feed_id
|
||||
}, callback
|
||||
);
|
||||
} else {
|
||||
callback(read);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -161,7 +164,7 @@ NEWSBLUR.AssetModel.Reader.prototype = {
|
|||
this.make_request('/reader/load_feeds', {}, pre_callback);
|
||||
},
|
||||
|
||||
load_feed: function(feed_id, page, first_load, callback) {
|
||||
load_feed: function(feed_id, page, first_load, callback, error_callback) {
|
||||
var self = this;
|
||||
|
||||
var pre_callback = function(data) {
|
||||
|
@ -182,7 +185,8 @@ NEWSBLUR.AssetModel.Reader.prototype = {
|
|||
{
|
||||
feed_id: feed_id,
|
||||
page: page
|
||||
}, pre_callback
|
||||
}, pre_callback,
|
||||
error_callback
|
||||
);
|
||||
},
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
// =================
|
||||
|
||||
make_story_title: function(story) {
|
||||
var unread_view = NEWSBLUR.Globals.unread_view;
|
||||
var read = story.read_status
|
||||
? 'read'
|
||||
: '';
|
||||
|
@ -75,6 +76,10 @@
|
|||
$.make('div', { className: 'NB-story-sentiment NB-story-dislike' })
|
||||
]).data('story_id', story.id);
|
||||
|
||||
if (unread_view > score) {
|
||||
$story_title.css({'display': 'none'});
|
||||
}
|
||||
|
||||
return $story_title;
|
||||
},
|
||||
|
||||
|
@ -411,6 +416,7 @@
|
|||
|
||||
this.show_feed_title_in_stories($story_titles, feed_id);
|
||||
this.mark_feed_as_selected(feed_id, $feed_link);
|
||||
this.show_feedbar_loading();
|
||||
this.model.load_feed(feed_id, 0, true, $.rescope(this.post_open_feed, this));
|
||||
// this.model.load_feed_page(feed_id, 0, $.rescope(this.show_feed_page_contents, this));
|
||||
this.show_feed_page_contents(feed_id);
|
||||
|
@ -631,22 +637,35 @@
|
|||
},
|
||||
|
||||
load_page_of_feed_stories: function() {
|
||||
var $feedbar;
|
||||
var $story_titles = this.$story_titles;
|
||||
var feed_id = $story_titles.data('feed_id');
|
||||
var page = $story_titles.data('page');
|
||||
|
||||
var $feedbar = $.make('div', { className: 'NB-story-titles-end-stories-line' });
|
||||
$feedbar.css({'background': '#E1EBFF'});
|
||||
$story_titles.append($feedbar);
|
||||
$feedbar.animate({'backgroundColor': '#5C89C9'}, {'duration': 750})
|
||||
.animate({'backgroundColor': '#E1EBFF'}, 750);
|
||||
this.feed_stories_loading = setInterval(function() {
|
||||
$feedbar.animate({'backgroundColor': '#5C89C9'}, {'duration': 750})
|
||||
.animate({'backgroundColor': '#E1EBFF'}, 750);
|
||||
}, 1500);
|
||||
this.show_feedbar_loading();
|
||||
|
||||
$story_titles.data('page', page+1);
|
||||
this.model.load_feed(feed_id, page+1, false, $.rescope(this.post_open_feed, this));
|
||||
this.model.load_feed(feed_id, page+1, false,
|
||||
$.rescope(this.post_open_feed, this),
|
||||
$.rescope(this.load_page_of_feed_stories, this));
|
||||
},
|
||||
|
||||
show_feedbar_loading: function() {
|
||||
var $story_titles = this.$story_titles;
|
||||
var $feedbar = $('.NB-story-titles-end-stories-line');
|
||||
|
||||
if (!$feedbar.length) {
|
||||
$feedbar = $.make('div', { className: 'NB-story-titles-end-stories-line' });
|
||||
}
|
||||
$feedbar.css({'background': '#E1EBFF'});
|
||||
$story_titles.append($feedbar);
|
||||
|
||||
$feedbar.animate({'backgroundColor': '#5C89C9'}, {'duration': 750})
|
||||
.animate({'backgroundColor': '#E1EBFF'}, 750);
|
||||
this.feed_stories_loading = setInterval(function() {
|
||||
$feedbar.animate({'backgroundColor': '#5C89C9'}, {'duration': 750})
|
||||
.animate({'backgroundColor': '#E1EBFF'}, 750);
|
||||
}, 1500);
|
||||
},
|
||||
|
||||
hover_over_story_titles: function() {
|
||||
|
@ -881,7 +900,7 @@
|
|||
if (story) {
|
||||
var self = this;
|
||||
var $story = this.find_story_in_story_frame(story);
|
||||
// NEWSBLUR.log(['Prefetching story', s, story, $story]);
|
||||
NEWSBLUR.log(['Prefetching story', s, story, $story]);
|
||||
|
||||
setTimeout(function() {
|
||||
// NEWSBLUR.log(['Fetching next story', s]);
|
||||
|
@ -1070,16 +1089,16 @@
|
|||
var $feed_list = this.$feed_list;
|
||||
var $feed = $('.feed.selected', $feed_list);
|
||||
|
||||
var callback = function() {
|
||||
var callback = function(read) {
|
||||
if (read) return;
|
||||
|
||||
var unread_count_positive = parseInt($('.unread_count_positive', $feed).text(), 10);
|
||||
var unread_count_neutral = parseInt($('.unread_count_neutral', $feed).text(), 10);
|
||||
var unread_count_negative = parseInt($('.unread_count_negative', $feed).text(), 10);
|
||||
NEWSBLUR.log(['marked read', unread_count_positive, unread_count_neutral, unread_count_negative, $story_title.is('.NB-story-positive'), $story_title.is('.NB-story-neutral'), $story_title.is('.NB-story-negative')]);
|
||||
// NEWSBLUR.log(['marked read', unread_count_positive, unread_count_neutral, unread_count_negative, $story_title.is('.NB-story-positive'), $story_title.is('.NB-story-neutral'), $story_title.is('.NB-story-negative')]);
|
||||
|
||||
if ($story_title.is('.NB-story-positive')) {
|
||||
$('.unread_count_positive', $feed).text(unread_count_positive-1);
|
||||
$('.unread_count_neutral', $feed).text(unread_count_neutral-1);
|
||||
$('.unread_count_negative', $feed).text(unread_count_negative-1);
|
||||
if (unread_count_positive == 1) {
|
||||
$feed.removeClass('unread_positive');
|
||||
} else {
|
||||
|
@ -1087,9 +1106,7 @@
|
|||
}
|
||||
} else if ($story_title.is('.NB-story-neutral')) {
|
||||
$('.unread_count_neutral', $feed).text(unread_count_neutral-1);
|
||||
$('.unread_count_negative', $feed).text(unread_count_negative-1);
|
||||
if (unread_count_neutral == 1) {
|
||||
$feed.removeClass('unread_positive');
|
||||
$feed.removeClass('unread_neutral');
|
||||
} else {
|
||||
$feed.addClass('unread_neutral');
|
||||
|
@ -1097,8 +1114,6 @@
|
|||
} else if ($story_title.is('.NB-story-negative')) {
|
||||
$('.unread_count_negative', $feed).text(unread_count_negative-1);
|
||||
if (unread_count_negative == 1) {
|
||||
$feed.removeClass('unread_positive');
|
||||
$feed.removeClass('unread_neutral');
|
||||
$feed.removeClass('unread_negative');
|
||||
} else {
|
||||
$feed.addClass('unread_negative');
|
||||
|
@ -1110,9 +1125,7 @@
|
|||
|
||||
$story_title.addClass('read');
|
||||
|
||||
if (NEWSBLUR.Globals.is_authenticated) {
|
||||
this.model.mark_story_as_read(story_id, feed_id, callback);
|
||||
}
|
||||
this.model.mark_story_as_read(story_id, feed_id, callback);
|
||||
},
|
||||
|
||||
mark_feed_as_read: function(feed_id) {
|
||||
|
|
|
@ -104,7 +104,7 @@ elif DEV_SERVER1:
|
|||
# Example: "/Users/media/media.lawrence.com/"
|
||||
MEDIA_URL = '/media/'
|
||||
DEBUG = True
|
||||
CACHE_BACKEND = 'dummy:///'
|
||||
CACHE_BACKEND = 'locmem:///'
|
||||
logging.basicConfig(level=logging.DEBUG,
|
||||
format='%(asctime)s %(levelname)s %(message)s',
|
||||
filename=LOG_FILE,
|
||||
|
@ -121,7 +121,7 @@ elif DEV_SERVER2:
|
|||
# Example: "/Users/media/media.lawrence.com/"
|
||||
MEDIA_URL = '/media/'
|
||||
DEBUG = True
|
||||
CACHE_BACKEND = 'dummy:///'
|
||||
CACHE_BACKEND = 'locmem:///'
|
||||
# CACHE_BACKEND = 'locmem:///'
|
||||
logging.basicConfig(level=logging.DEBUG,
|
||||
format='%(asctime)s %(levelname)s %(message)s',
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
{% if user.is_authenticated %}
|
||||
<div class="NB-user">
|
||||
Welcome, {{ user.username}}.
|
||||
(<a href="{% url auth_logout %}?next=/">Logout</a>)
|
||||
(<a href="{% url logout %}?next=/">Logout</a>)
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if not user.is_authenticated %}
|
||||
|
@ -39,7 +39,7 @@
|
|||
<div class="NB-login-label">Want an account?</div>
|
||||
<div class="NB-login-text">Talk to <a href="http://twitter.com/samuelclay">@samuelclay</a>.</div>
|
||||
|
||||
<form method="post" action="{% url auth_login %}">
|
||||
<form method="post" action="{% url login %}">
|
||||
<div>
|
||||
{{ form.username.label_tag }}
|
||||
{{ form.username }}
|
||||
|
|
4
urls.py
4
urls.py
|
@ -1,12 +1,12 @@
|
|||
from django.conf.urls.defaults import *
|
||||
from django.conf import settings
|
||||
|
||||
from apps.reader import views as reader_views
|
||||
# Uncomment the next two lines to enable the admin:
|
||||
from django.contrib import admin
|
||||
admin.autodiscover()
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'^$', include('apps.reader.urls')),
|
||||
url(r'^$', reader_views.index, name='index'),
|
||||
(r'^accounts/', include('apps.registration.urls')),
|
||||
(r'^reader/', include('apps.reader.urls')),
|
||||
(r'^classifier/', include('apps.analyzer.urls')),
|
||||
|
|
|
@ -259,6 +259,8 @@ class Dispatcher:
|
|||
if ENTRY_NEW in ret_entries and ret_entries[ENTRY_NEW]:
|
||||
user_subs = UserSubscription.objects.filter(feed=feed)
|
||||
for sub in user_subs:
|
||||
logging.info('Deleteing user sub cache: %s' % sub.user_id)
|
||||
cache.delete('usersub:%s' % sub.user_id)
|
||||
sub.calculate_feed_scores()
|
||||
except:
|
||||
(etype, eobj, etb) = sys.exc_info()
|
||||
|
|
Loading…
Add table
Reference in a new issue