- 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:
Samuel Clay 2010-01-24 22:53:46 -05:00
parent 98d4762735
commit 1180100e37
10 changed files with 77 additions and 81 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
logs/*.log
*.pyc

View file

@ -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

View file

@ -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),

View file

@ -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'))

View file

@ -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
);
},

View file

@ -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) {

View file

@ -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',

View file

@ -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 }}

View file

@ -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')),

View file

@ -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()