mirror of
https://github.com/samuelclay/NewsBlur.git
synced 2025-09-18 21:50:56 +00:00
Saving and fetching social feed classifiers.
This commit is contained in:
parent
581c52ff9a
commit
af4a92a266
5 changed files with 107 additions and 63 deletions
|
@ -25,8 +25,8 @@ class Category(models.Model):
|
|||
|
||||
class MClassifierTitle(mongo.Document):
|
||||
user_id = mongo.IntField()
|
||||
feed_id = mongo.IntField()
|
||||
social_user_id = mongo.IntField()
|
||||
feed_id = mongo.IntField(required=False)
|
||||
social_user_id = mongo.IntField(required=False)
|
||||
title = mongo.StringField(max_length=255)
|
||||
score = mongo.IntField()
|
||||
creation_date = mongo.DateTimeField()
|
||||
|
@ -38,10 +38,10 @@ class MClassifierTitle(mongo.Document):
|
|||
}
|
||||
|
||||
class MClassifierAuthor(mongo.Document):
|
||||
user_id = mongo.IntField()
|
||||
feed_id = mongo.IntField()
|
||||
social_user_id = mongo.IntField()
|
||||
author = mongo.StringField(max_length=255, unique_with=('user_id', 'feed_id', 'social_user_id'))
|
||||
user_id = mongo.IntField(unique_with=('feed_id', 'social_user_id', 'author'))
|
||||
feed_id = mongo.IntField(required=False)
|
||||
social_user_id = mongo.IntField(required=False)
|
||||
author = mongo.StringField(max_length=255)
|
||||
score = mongo.IntField()
|
||||
creation_date = mongo.DateTimeField()
|
||||
|
||||
|
@ -50,27 +50,13 @@ class MClassifierAuthor(mongo.Document):
|
|||
'indexes': [('user_id', 'feed_id'), 'feed_id', ('user_id', 'social_user_id'), 'social_user_id'],
|
||||
'allow_inheritance': False,
|
||||
}
|
||||
|
||||
|
||||
class MClassifierFeed(mongo.Document):
|
||||
user_id = mongo.IntField()
|
||||
feed_id = mongo.IntField(unique_with=('user_id', 'social_user_id'))
|
||||
social_user_id = mongo.IntField()
|
||||
score = mongo.IntField()
|
||||
creation_date = mongo.DateTimeField()
|
||||
|
||||
meta = {
|
||||
'collection': 'classifier_feed',
|
||||
'indexes': [('user_id', 'feed_id'), 'feed_id', ('user_id', 'social_user_id'), 'social_user_id'],
|
||||
'allow_inheritance': False,
|
||||
}
|
||||
|
||||
|
||||
|
||||
class MClassifierTag(mongo.Document):
|
||||
user_id = mongo.IntField()
|
||||
feed_id = mongo.IntField()
|
||||
social_user_id = mongo.IntField()
|
||||
tag = mongo.StringField(max_length=255, unique_with=('user_id', 'feed_id', 'social_user_id'))
|
||||
user_id = mongo.IntField(unique_with=('feed_id', 'social_user_id', 'tag'))
|
||||
feed_id = mongo.IntField(required=False)
|
||||
social_user_id = mongo.IntField(required=False)
|
||||
tag = mongo.StringField(max_length=255)
|
||||
score = mongo.IntField()
|
||||
creation_date = mongo.DateTimeField()
|
||||
|
||||
|
@ -80,6 +66,20 @@ class MClassifierTag(mongo.Document):
|
|||
'allow_inheritance': False,
|
||||
}
|
||||
|
||||
|
||||
class MClassifierFeed(mongo.Document):
|
||||
user_id = mongo.IntField(unique_with=('feed_id', 'social_user_id'))
|
||||
feed_id = mongo.IntField(required=False)
|
||||
social_user_id = mongo.IntField(required=False)
|
||||
score = mongo.IntField()
|
||||
creation_date = mongo.DateTimeField()
|
||||
|
||||
meta = {
|
||||
'collection': 'classifier_feed',
|
||||
'indexes': [('user_id', 'feed_id'), 'feed_id', ('user_id', 'social_user_id'), 'social_user_id'],
|
||||
'allow_inheritance': False,
|
||||
}
|
||||
|
||||
|
||||
def apply_classifier_titles(classifiers, story):
|
||||
score = 0
|
||||
|
@ -116,18 +116,36 @@ def apply_classifier_tags(classifiers, story):
|
|||
if score > 0: return classifier.score
|
||||
return score
|
||||
|
||||
def get_classifiers_for_user(user, feed_id, classifier_feeds=None, classifier_authors=None, classifier_titles=None, classifier_tags=None):
|
||||
def get_classifiers_for_user(user, feed_id=None, social_user_id=None, classifier_feeds=None, classifier_authors=None,
|
||||
classifier_titles=None, classifier_tags=None):
|
||||
params = dict(user_id=user.pk)
|
||||
if isinstance(feed_id, int):
|
||||
params['feed_id'] = feed_id
|
||||
elif isinstance(feed_id, list):
|
||||
params['feed_id__in'] = feed_id
|
||||
if social_user_id:
|
||||
params['social_user_id'] = int(social_user_id.replace('social:', ''))
|
||||
else:
|
||||
params['social_user_id'] = 0
|
||||
|
||||
if classifier_feeds is None:
|
||||
classifier_feeds = list(MClassifierFeed.objects(user_id=user.pk, feed_id=feed_id))
|
||||
classifier_feeds = list(MClassifierFeed.objects(**params))
|
||||
if classifier_authors is None:
|
||||
classifier_authors = list(MClassifierAuthor.objects(user_id=user.pk, feed_id=feed_id))
|
||||
classifier_authors = list(MClassifierAuthor.objects(**params))
|
||||
if classifier_titles is None:
|
||||
classifier_titles = list(MClassifierTitle.objects(user_id=user.pk, feed_id=feed_id))
|
||||
classifier_titles = list(MClassifierTitle.objects(**params))
|
||||
if classifier_tags is None:
|
||||
classifier_tags = list(MClassifierTag.objects(user_id=user.pk, feed_id=feed_id))
|
||||
|
||||
classifier_tags = list(MClassifierTag.objects(**params))
|
||||
|
||||
feeds = []
|
||||
for f in classifier_feeds:
|
||||
if f.social_user_id and not f.feed_id:
|
||||
feeds.append(('social:%s' % f.social_user_id, f.score))
|
||||
else:
|
||||
feeds.append((f.feed_id, f.score))
|
||||
|
||||
payload = {
|
||||
'feeds': dict([(f.feed_id, f.score) for f in classifier_feeds]),
|
||||
'feeds': dict(feeds),
|
||||
'authors': dict([(a.author, a.score) for a in classifier_authors]),
|
||||
'titles': dict([(t.title, t.score) for t in classifier_titles]),
|
||||
'tags': dict([(t.tag, t.score) for t in classifier_tags]),
|
||||
|
|
|
@ -6,6 +6,7 @@ from apps.rss_feeds.models import Feed
|
|||
from apps.reader.models import UserSubscription
|
||||
from apps.analyzer.models import MClassifierTitle, MClassifierAuthor, MClassifierFeed, MClassifierTag
|
||||
from apps.analyzer.models import get_classifiers_for_user
|
||||
from apps.social.models import MSocialSubscription
|
||||
from utils import json_functions as json
|
||||
from utils.user_functions import get_user
|
||||
from utils.user_functions import ajax_login_required
|
||||
|
@ -18,8 +19,15 @@ def index(requst):
|
|||
@json.json_view
|
||||
def save_classifier(request):
|
||||
post = request.POST
|
||||
feed_id = int(post['feed_id'])
|
||||
feed = get_object_or_404(Feed, pk=feed_id)
|
||||
feed_id = post['feed_id']
|
||||
feed = None
|
||||
social_user_id = None
|
||||
if feed_id.startswith('social:'):
|
||||
social_user_id = int(feed_id.replace('social:', ''))
|
||||
feed_id = None
|
||||
else:
|
||||
feed_id = int(feed_id)
|
||||
feed = get_object_or_404(Feed, pk=feed_id)
|
||||
code = 0
|
||||
message = 'OK'
|
||||
payload = {}
|
||||
|
@ -27,14 +35,22 @@ def save_classifier(request):
|
|||
logging.user(request, "~FGSaving classifier: ~SB%s~SN ~FW%s" % (feed, post))
|
||||
|
||||
# Mark subscription as dirty, so unread counts can be recalculated
|
||||
try:
|
||||
usersub = UserSubscription.objects.get(user=request.user, feed=feed)
|
||||
except UserSubscription.DoesNotExist:
|
||||
usersub = None
|
||||
if usersub and (not usersub.needs_unread_recalc or not usersub.is_trained):
|
||||
usersub.needs_unread_recalc = True
|
||||
usersub.is_trained = True
|
||||
usersub.save()
|
||||
usersub = None
|
||||
socialsub = None
|
||||
if social_user_id:
|
||||
socialsub = MSocialSubscription.objects.get(user_id=request.user.pk, subscription_user_id=social_user_id)
|
||||
if not socialsub.needs_unread_recalc:
|
||||
socialsub.needs_unread_recalc = True
|
||||
socialsub.save()
|
||||
else:
|
||||
try:
|
||||
usersub = UserSubscription.objects.get(user=request.user, feed=feed)
|
||||
except UserSubscription.DoesNotExist:
|
||||
pass
|
||||
if usersub and (not usersub.needs_unread_recalc or not usersub.is_trained):
|
||||
usersub.needs_unread_recalc = True
|
||||
usersub.is_trained = True
|
||||
usersub.save()
|
||||
|
||||
|
||||
def _save_classifier(ClassifierCls, content_type):
|
||||
|
@ -51,17 +67,22 @@ def save_classifier(request):
|
|||
if not post_content: continue
|
||||
classifier_dict = {
|
||||
'user_id': request.user.pk,
|
||||
'feed_id': feed_id,
|
||||
'feed_id': feed_id or 0,
|
||||
'social_user_id': social_user_id or 0,
|
||||
'defaults': {
|
||||
'score': score
|
||||
}
|
||||
}
|
||||
if content_type in ('author', 'tag', 'title'):
|
||||
classifier_dict.update({content_type: post_content})
|
||||
try:
|
||||
classifier, created = ClassifierCls.objects.get_or_create(**classifier_dict)
|
||||
except OperationError:
|
||||
continue
|
||||
if content_type == 'feed':
|
||||
if not post_content.startswith('social:'):
|
||||
classifier_dict['feed_id'] = post_content
|
||||
print classifier_dict
|
||||
# try:
|
||||
classifier, created = ClassifierCls.objects.get_or_create(**classifier_dict)
|
||||
# except OperationError:
|
||||
# continue
|
||||
if score == 0:
|
||||
classifier.delete()
|
||||
elif classifier.score != score:
|
||||
|
|
|
@ -325,7 +325,7 @@ def social_feed_trainer(request):
|
|||
|
||||
social_profile.count_stories()
|
||||
classifier = social_profile.to_json()
|
||||
classifier['classifiers'] = get_classifiers_for_user(user, social_user_id)
|
||||
classifier['classifiers'] = get_classifiers_for_user(user, social_user_id=classifier['id'])
|
||||
classifier['num_subscribers'] = social_profile.follower_count
|
||||
classifier['feed_tags'] = []
|
||||
classifier['feed_authors'] = []
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
|
||||
(function($) {
|
||||
|
||||
NEWSBLUR.Reader = function() {
|
||||
var self = this;
|
||||
|
||||
// ===========
|
||||
// = Globals =
|
||||
// ===========
|
||||
|
@ -500,12 +498,14 @@
|
|||
|
||||
var $feed_list = this.$s.$feed_list.parent();
|
||||
var $feeds = $([]);
|
||||
$('.feed', $feed_list).each(function() {
|
||||
var data_id = $(this).data('id');
|
||||
if (data_id == feed_id || parseInt(data_id, 10) == feed_id) {
|
||||
$feeds.push($(this).get(0));
|
||||
}
|
||||
});
|
||||
if (feed_id) {
|
||||
$('.feed', $feed_list).each(function() {
|
||||
var data_id = $(this).data('id');
|
||||
if (data_id == feed_id || parseInt(data_id, 10) == feed_id) {
|
||||
$feeds.push($(this).get(0));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.cache.$feed_in_feed_list[feed_id] = $feeds;
|
||||
return $feeds;
|
||||
|
@ -6392,9 +6392,11 @@
|
|||
setup_dashboard_graphs: function() {
|
||||
// Reload dashboard graphs every 10 minutes.
|
||||
clearInterval(this.locks.load_dashboard_graphs);
|
||||
this.locks.load_dashboard_graphs = setInterval(_.bind(function() {
|
||||
this.load_dashboard_graphs();
|
||||
}, this), NEWSBLUR.Globals.is_staff ? 60*1000 : 10*60*1000);
|
||||
if (!NEWSBLUR.Globals.debug) {
|
||||
this.locks.load_dashboard_graphs = setInterval(_.bind(function() {
|
||||
this.load_dashboard_graphs();
|
||||
}, this), NEWSBLUR.Globals.is_staff ? 60*1000 : 10*60*1000);
|
||||
}
|
||||
},
|
||||
|
||||
load_dashboard_graphs: function() {
|
||||
|
@ -6414,9 +6416,11 @@
|
|||
setup_feedback_table: function() {
|
||||
// Reload feedback module every 10 minutes.
|
||||
clearInterval(this.locks.load_feedback_table);
|
||||
this.locks.load_feedback_table = setInterval(_.bind(function() {
|
||||
this.load_feedback_table();
|
||||
}, this), NEWSBLUR.Globals.is_staff ? 60*1000 : 10*60*1000);
|
||||
if (!NEWSBLUR.Globals.debug) {
|
||||
this.locks.load_feedback_table = setInterval(_.bind(function() {
|
||||
this.load_feedback_table();
|
||||
}, this), NEWSBLUR.Globals.is_staff ? 60*1000 : 10*60*1000);
|
||||
}
|
||||
},
|
||||
|
||||
load_feedback_table: function() {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
'username' : "{{ user.username|safe }}",
|
||||
'email' : "{{ user.email|safe }}",
|
||||
'google_favicon_url' : 'http://www.google.com/s2/favicons?domain_url=',
|
||||
'debug' : {{ debug|yesno:"true,false" }},
|
||||
'MEDIA_URL' : "{{ MEDIA_URL }}"
|
||||
};
|
||||
NEWSBLUR.Flags = {
|
||||
|
|
Loading…
Add table
Reference in a new issue