mirror of
https://github.com/samuelclay/NewsBlur.git
synced 2025-09-18 21:50:56 +00:00
Stars now save to the new StarredStory mongo model. THey are also persistent on the client-side. Now to just make a special starred stories view and counter.
This commit is contained in:
parent
316010882a
commit
4507f7286a
6 changed files with 126 additions and 24 deletions
|
@ -14,6 +14,8 @@ urlpatterns = patterns('',
|
|||
url(r'^refresh_feeds', views.refresh_feeds, name='refresh-feeds'),
|
||||
url(r'^mark_all_as_read', views.mark_all_as_read, name='mark-all-as-read'),
|
||||
url(r'^mark_story_as_read', views.mark_story_as_read),
|
||||
url(r'^mark_story_as_starred', views.mark_story_as_starred),
|
||||
url(r'^mark_story_as_unstarred', views.mark_story_as_unstarred),
|
||||
url(r'^mark_feed_as_read', views.mark_feed_as_read),
|
||||
url(r'^delete_feed', views.delete_feed, name='delete-feed'),
|
||||
url(r'^delete_folder', views.delete_folder, name='delete-folder'),
|
||||
|
|
|
@ -20,7 +20,7 @@ from apps.analyzer.models import get_classifiers_for_user
|
|||
from apps.reader.models import UserSubscription, UserSubscriptionFolders, MUserStory, Feature
|
||||
from apps.reader.forms import SignupForm, LoginForm, FeatureForm
|
||||
try:
|
||||
from apps.rss_feeds.models import Feed, MFeedPage, DuplicateFeed, MStory, FeedLoadtime
|
||||
from apps.rss_feeds.models import Feed, MFeedPage, DuplicateFeed, MStory, MStarredStory, FeedLoadtime
|
||||
except:
|
||||
pass
|
||||
from utils import json_functions as json, urlnorm
|
||||
|
@ -291,6 +291,9 @@ def load_single_feed(request):
|
|||
userstories_db = MUserStory.objects(user_id=user.pk,
|
||||
feed_id=feed.pk,
|
||||
read_date__gte=usersub.mark_read_date)
|
||||
starred_stories = MStarredStory.objects(user_id=request.user.pk, story_feed_id=feed_id).only('story_guid')
|
||||
starred_stories = [story.story_guid for story in starred_stories]
|
||||
|
||||
for us in userstories_db:
|
||||
if hasattr(us.story, 'story_guid') and isinstance(us.story.story_guid, unicode):
|
||||
userstories.append(us.story.story_guid)
|
||||
|
@ -311,6 +314,8 @@ def load_single_feed(request):
|
|||
story['read_status'] = 1
|
||||
elif not story.get('read_status') and story['story_date'] > usersub.last_read_date:
|
||||
story['read_status'] = 0
|
||||
if story['id'] in starred_stories:
|
||||
story['starred'] = True
|
||||
story['intelligence'] = {
|
||||
'feed': apply_classifier_feeds(classifier_feeds, feed),
|
||||
'author': apply_classifier_authors(classifier_authors, story),
|
||||
|
@ -715,4 +720,37 @@ def login_as(request):
|
|||
|
||||
def iframe_buster(request):
|
||||
logging.info(" ---> [%s] iFrame bust!" % (request.user,))
|
||||
return HttpResponse(status=204)
|
||||
return HttpResponse(status=204)
|
||||
|
||||
@ajax_login_required
|
||||
@json.json_view
|
||||
def mark_story_as_starred(request):
|
||||
code = 1
|
||||
feed_id = int(request.POST['feed_id'])
|
||||
story_id = request.POST['story_id']
|
||||
|
||||
story = MStory.objects(story_feed_id=feed_id, story_guid=story_id).limit(1)
|
||||
if story:
|
||||
story_db = dict([(k, v) for k, v in story[0]._data.items()
|
||||
if k is not None and v is not None])
|
||||
story_values = dict(user_id=request.user.pk, **story_db)
|
||||
MStarredStory.objects.create(**story_values)
|
||||
else:
|
||||
code = -1
|
||||
|
||||
return {'code': code}
|
||||
|
||||
@ajax_login_required
|
||||
@json.json_view
|
||||
def mark_story_as_unstarred(request):
|
||||
code = 1
|
||||
feed_id = int(request.POST['feed_id'])
|
||||
story_id = request.POST['story_id']
|
||||
|
||||
starred_story = MStarredStory.objects(user_id=request.user.pk, story_guid=story_id, story_feed_id=feed_id)
|
||||
if starred_story:
|
||||
starred_story.delete()
|
||||
else:
|
||||
code = -1
|
||||
|
||||
return {'code': code}
|
|
@ -761,20 +761,22 @@ class Story(models.Model):
|
|||
self.story_title = self.story_title[:255]
|
||||
super(Story, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
class MStory(mongo.Document):
|
||||
'''A feed item'''
|
||||
story_feed_id = mongo.IntField()
|
||||
story_date = mongo.DateTimeField()
|
||||
story_title = mongo.StringField(max_length=1024)
|
||||
story_content = mongo.StringField()
|
||||
story_content_z = mongo.BinaryField()
|
||||
story_original_content = mongo.StringField()
|
||||
story_feed_id = mongo.IntField()
|
||||
story_date = mongo.DateTimeField()
|
||||
story_title = mongo.StringField(max_length=1024)
|
||||
story_content = mongo.StringField()
|
||||
story_content_z = mongo.BinaryField()
|
||||
story_original_content = mongo.StringField()
|
||||
story_original_content_z = mongo.BinaryField()
|
||||
story_content_type = mongo.StringField(max_length=255)
|
||||
story_author_name = mongo.StringField()
|
||||
story_permalink = mongo.StringField()
|
||||
story_guid = mongo.StringField()
|
||||
story_tags = mongo.ListField(mongo.StringField(max_length=250))
|
||||
story_content_type = mongo.StringField(max_length=255)
|
||||
story_author_name = mongo.StringField()
|
||||
story_permalink = mongo.StringField()
|
||||
story_guid = mongo.StringField()
|
||||
story_tags = mongo.ListField(mongo.StringField(max_length=250))
|
||||
|
||||
|
||||
meta = {
|
||||
'collection': 'stories',
|
||||
|
@ -791,7 +793,42 @@ class MStory(mongo.Document):
|
|||
self.story_original_content_z = zlib.compress(self.story_original_content)
|
||||
self.story_original_content = None
|
||||
super(MStory, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
|
||||
class MStarredStory(mongo.Document):
|
||||
"""Like MStory, but not inherited due to large overhead of _cls and _type in
|
||||
mongoengine's inheritance model on every single row."""
|
||||
user_id = mongo.IntField()
|
||||
story_feed_id = mongo.IntField()
|
||||
story_date = mongo.DateTimeField()
|
||||
story_title = mongo.StringField(max_length=1024)
|
||||
story_content = mongo.StringField()
|
||||
story_content_z = mongo.BinaryField()
|
||||
story_original_content = mongo.StringField()
|
||||
story_original_content_z = mongo.BinaryField()
|
||||
story_content_type = mongo.StringField(max_length=255)
|
||||
story_author_name = mongo.StringField()
|
||||
story_permalink = mongo.StringField()
|
||||
story_guid = mongo.StringField(unique_with=('user_id',))
|
||||
story_tags = mongo.ListField(mongo.StringField(max_length=250))
|
||||
|
||||
meta = {
|
||||
'collection': 'starred_stories',
|
||||
'indexes': [('user_id', '-story_date'), 'story_feed_id'],
|
||||
'ordering': ['-story_date'],
|
||||
'allow_inheritance': False,
|
||||
}
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.story_content:
|
||||
self.story_content_z = zlib.compress(self.story_content)
|
||||
self.story_content = None
|
||||
if self.story_original_content:
|
||||
self.story_original_content_z = zlib.compress(self.story_original_content)
|
||||
self.story_original_content = None
|
||||
super(MStarredStory, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
class FeedUpdateHistory(models.Model):
|
||||
fetch_date = models.DateTimeField(auto_now=True)
|
||||
number_of_feeds = models.IntegerField()
|
||||
|
@ -809,6 +846,7 @@ class FeedUpdateHistory(models.Model):
|
|||
self.average_per_feed = str(self.seconds_taken / float(max(1.0,self.number_of_feeds)))
|
||||
super(FeedUpdateHistory, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
class FeedFetchHistory(models.Model):
|
||||
feed = models.ForeignKey(Feed, related_name='feed_fetch_history')
|
||||
status_code = models.CharField(max_length=10, null=True, blank=True)
|
||||
|
@ -826,6 +864,7 @@ class FeedFetchHistory(models.Model):
|
|||
self.exception and self.exception[:50]
|
||||
)
|
||||
|
||||
|
||||
class MFeedFetchHistory(mongo.Document):
|
||||
feed_id = mongo.IntField()
|
||||
status_code = mongo.IntField()
|
||||
|
@ -844,6 +883,7 @@ class MFeedFetchHistory(mongo.Document):
|
|||
self.exception = unicode(self.exception)
|
||||
super(MFeedFetchHistory, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
class PageFetchHistory(models.Model):
|
||||
feed = models.ForeignKey(Feed, related_name='page_fetch_history')
|
||||
status_code = models.CharField(max_length=10, null=True, blank=True)
|
||||
|
@ -861,6 +901,7 @@ class PageFetchHistory(models.Model):
|
|||
self.exception and self.exception[:50]
|
||||
)
|
||||
|
||||
|
||||
class MPageFetchHistory(mongo.Document):
|
||||
feed_id = mongo.IntField()
|
||||
status_code = mongo.IntField()
|
||||
|
|
|
@ -1056,8 +1056,10 @@ background: transparent;
|
|||
background: transparent url('../img/reader/star_blue.png') no-repeat 4px 0px;
|
||||
opacity: .25;
|
||||
}
|
||||
#story_titles .NB-story-star:hover {
|
||||
#story_titles .NB-story-star:hover,
|
||||
#story_titles .NB-story-starred .NB-story-star {
|
||||
opacity: 1;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#story_titles .story.read {
|
||||
|
|
|
@ -21,6 +21,7 @@ NEWSBLUR.AssetModel.Reader = function() {
|
|||
this.stories = {};
|
||||
this.read_stories = {};
|
||||
this.classifiers = {};
|
||||
this.starred_stories = [];
|
||||
|
||||
this.DEFAULT_VIEW = NEWSBLUR.Preferences.default_view || 'page';
|
||||
};
|
||||
|
@ -122,17 +123,23 @@ NEWSBLUR.AssetModel.Reader.prototype = {
|
|||
$.isFunction(callback) && callback(read);
|
||||
},
|
||||
|
||||
mark_story_as_starred: function(story_id, feed_id, callback) {
|
||||
var self = this;
|
||||
this.make_request('/reader/mark_story_as_starred', {
|
||||
story_id: story_id,
|
||||
feed_id: feed_id
|
||||
}, callback);
|
||||
},
|
||||
|
||||
mark_feed_as_read: function(feed_id, callback) {
|
||||
var self = this;
|
||||
var feed_ids = _.isArray(feed_id)
|
||||
? _.select(feed_id, function(f) { return f; })
|
||||
: [feed_id];
|
||||
|
||||
this.make_request('/reader/mark_feed_as_read',
|
||||
{
|
||||
feed_id: feed_ids
|
||||
}, callback
|
||||
);
|
||||
this.make_request('/reader/mark_feed_as_read', {
|
||||
feed_id: feed_ids
|
||||
}, callback);
|
||||
},
|
||||
|
||||
load_feeds: function(callback, error_callback) {
|
||||
|
@ -191,6 +198,7 @@ NEWSBLUR.AssetModel.Reader.prototype = {
|
|||
this.feed_authors = data.feed_authors;
|
||||
this.feed_id = feed_id;
|
||||
this.classifiers = data.classifiers;
|
||||
this.starred_stories = data.starred_stories;
|
||||
this.story_keys = [];
|
||||
for (var s in data.stories) {
|
||||
this.story_keys.push(data.stories[s].id);
|
||||
|
|
|
@ -1697,6 +1697,16 @@
|
|||
NEWSBLUR.classifier = new NEWSBLUR.ReaderClassifierStory(story_id, feed_id, {'score': -1});
|
||||
},
|
||||
|
||||
mark_story_as_starred: function(story_id, $button) {
|
||||
// $button.attr({'title': 'Saving...'});
|
||||
$button.tipsy({'title': 'Saving...'});
|
||||
$button.closest('.story').addClass('NB-story-starred');
|
||||
this.model.mark_story_as_starred(story_id, this.active_feed, function() {
|
||||
// $button.attr({'title': 'Saved!'});
|
||||
$button.tipsy({'title': 'Saved!'});
|
||||
});
|
||||
},
|
||||
|
||||
// =====================
|
||||
// = Story Titles Pane =
|
||||
// =====================
|
||||
|
@ -1745,10 +1755,11 @@
|
|||
make_story_title: function(story) {
|
||||
var unread_view = this.model.preference('unread_view');
|
||||
var read = story.read_status
|
||||
? 'read'
|
||||
? ' read '
|
||||
: '';
|
||||
var score = this.compute_story_score(story);
|
||||
var score_color = 'neutral';
|
||||
var starred = story.starred ? ' NB-story-starred ' : '';
|
||||
if (score > 0) score_color = 'positive';
|
||||
if (score < 0) score_color = 'negative';
|
||||
var $story_tags = $.make('span', { className: 'NB-storytitles-tags'});
|
||||
|
@ -1759,7 +1770,7 @@
|
|||
$story_tags.append($tag);
|
||||
break;
|
||||
}
|
||||
var $story_title = $.make('div', { className: 'story ' + read + ' NB-story-' + score_color }, [
|
||||
var $story_title = $.make('div', { className: 'story' + read + starred + 'NB-story-' + score_color }, [
|
||||
$.make('a', { href: story.story_permalink, className: 'story_title' }, [
|
||||
$.make('span', { className: 'NB-storytitles-title' }, story.story_title),
|
||||
$.make('span', { className: 'NB-storytitles-author' }, story.story_authors),
|
||||
|
@ -3498,10 +3509,10 @@
|
|||
self.mark_story_as_like(story_id, $t);
|
||||
story_prevent_bubbling = true;
|
||||
});
|
||||
$.targetIs(e, { tagSelector: '.NB-story-dislike' }, function($t, $p){
|
||||
$.targetIs(e, { tagSelector: '.NB-story-star' }, function($t, $p){
|
||||
e.preventDefault();
|
||||
var story_id = $t.parents('.story').data('story_id');
|
||||
self.mark_story_as_dislike(story_id, $t);
|
||||
self.mark_story_as_starred(story_id, $t);
|
||||
story_prevent_bubbling = true;
|
||||
});
|
||||
$.targetIs(e, { tagSelector: 'a.button.like' }, function($t, $p){
|
||||
|
|
Loading…
Add table
Reference in a new issue