mirror of
https://github.com/viq/NewsBlur.git
synced 2025-09-18 21:43:31 +00:00
Intelligence Trainer. A whopper of a commit.
This commit is contained in:
parent
543384ed84
commit
66eae41e2d
17 changed files with 574 additions and 153 deletions
|
@ -21,10 +21,12 @@ def save_classifier(request):
|
|||
|
||||
# Make subscription as dirty, so unread counts can be recalculated
|
||||
usersub = UserSubscription.objects.get(user=request.user, feed=feed)
|
||||
if not usersub.needs_unread_recalc:
|
||||
if 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, ContentCls=None, post_content_field=None):
|
||||
classifiers = {
|
||||
'like_'+content_type: 1,
|
||||
|
@ -87,4 +89,5 @@ def get_classifiers_feed(request):
|
|||
|
||||
response = dict(code=code, payload=payload)
|
||||
|
||||
return response
|
||||
return response
|
||||
|
149
apps/reader/migrations/0004_is_trained.py
Normal file
149
apps/reader/migrations/0004_is_trained.py
Normal file
|
@ -0,0 +1,149 @@
|
|||
# encoding: utf-8
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding field 'UserSubscription.is_trained'
|
||||
db.add_column('reader_usersubscription', 'is_trained', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True), keep_default=False)
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Deleting field 'UserSubscription.is_trained'
|
||||
db.delete_column('reader_usersubscription', 'is_trained')
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'auth.permission': {
|
||||
'Meta': {'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||
},
|
||||
'contenttypes.contenttype': {
|
||||
'Meta': {'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'reader.feature': {
|
||||
'Meta': {'object_name': 'Feature'},
|
||||
'date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'description': ('django.db.models.fields.TextField', [], {'default': "''"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||
},
|
||||
'reader.userstory': {
|
||||
'Meta': {'unique_together': "(('user', 'feed', 'story'),)", 'object_name': 'UserStory'},
|
||||
'feed': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rss_feeds.Feed']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'opinion': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'read_date': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
||||
'story': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rss_feeds.Story']"}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
|
||||
},
|
||||
'reader.usersubscription': {
|
||||
'Meta': {'unique_together': "(('user', 'feed'),)", 'object_name': 'UserSubscription'},
|
||||
'feed': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rss_feeds.Feed']"}),
|
||||
'feed_opens': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_trained': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
||||
'last_read_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2010, 7, 17, 13, 2, 23, 54046)'}),
|
||||
'mark_read_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2010, 7, 17, 13, 2, 23, 54155)'}),
|
||||
'needs_unread_recalc': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
||||
'unread_count_negative': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'unread_count_neutral': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'unread_count_positive': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'unread_count_updated': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2000, 1, 1, 0, 0)'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
|
||||
},
|
||||
'reader.usersubscriptionfolders': {
|
||||
'Meta': {'object_name': 'UserSubscriptionFolders'},
|
||||
'folders': ('django.db.models.fields.TextField', [], {'default': "'[]'"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
|
||||
},
|
||||
'rss_feeds.feed': {
|
||||
'Meta': {'object_name': 'Feed', 'db_table': "'feeds'"},
|
||||
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
|
||||
'average_stories_per_month': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'creation': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'days_to_trim': ('django.db.models.fields.IntegerField', [], {'default': '90'}),
|
||||
'etag': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
|
||||
'feed_address': ('django.db.models.fields.URLField', [], {'unique': 'True', 'max_length': '255'}),
|
||||
'feed_link': ('django.db.models.fields.URLField', [], {'default': "''", 'max_length': '1000', 'null': 'True', 'blank': 'True'}),
|
||||
'feed_tagline': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '1024', 'null': 'True', 'blank': 'True'}),
|
||||
'feed_title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'last_load_time': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'last_modified': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'last_update': ('django.db.models.fields.DateTimeField', [], {'default': '0', 'auto_now': 'True', 'blank': 'True'}),
|
||||
'min_to_decay': ('django.db.models.fields.IntegerField', [], {'default': '15'}),
|
||||
'next_scheduled_update': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'num_subscribers': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'popular_authors': ('django.db.models.fields.CharField', [], {'max_length': '2048', 'null': 'True', 'blank': 'True'}),
|
||||
'popular_tags': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
|
||||
'stories_last_month': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||
'stories_last_year': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'rss_feeds.story': {
|
||||
'Meta': {'unique_together': "(('story_feed', 'story_guid_hash'),)", 'object_name': 'Story', 'db_table': "'stories'"},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'story_author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rss_feeds.StoryAuthor']"}),
|
||||
'story_author_name': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True', 'blank': 'True'}),
|
||||
'story_content': ('utils.compressed_textfield.StoryField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'story_content_type': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
||||
'story_date': ('django.db.models.fields.DateTimeField', [], {}),
|
||||
'story_feed': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'stories'", 'to': "orm['rss_feeds.Feed']"}),
|
||||
'story_guid': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
|
||||
'story_guid_hash': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
|
||||
'story_original_content': ('utils.compressed_textfield.StoryField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'story_past_trim_date': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
|
||||
'story_permalink': ('django.db.models.fields.CharField', [], {'max_length': '1000'}),
|
||||
'story_tags': ('django.db.models.fields.CharField', [], {'max_length': '2000', 'null': 'True', 'blank': 'True'}),
|
||||
'story_title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['rss_feeds.Tag']", 'symmetrical': 'False'})
|
||||
},
|
||||
'rss_feeds.storyauthor': {
|
||||
'Meta': {'object_name': 'StoryAuthor'},
|
||||
'author_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
||||
'feed': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rss_feeds.Feed']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||
},
|
||||
'rss_feeds.tag': {
|
||||
'Meta': {'object_name': 'Tag'},
|
||||
'feed': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['rss_feeds.Feed']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['reader']
|
|
@ -29,6 +29,7 @@ class UserSubscription(models.Model):
|
|||
unread_count_updated = models.DateTimeField(default=datetime.datetime(2000,1,1))
|
||||
needs_unread_recalc = models.BooleanField(default=False)
|
||||
feed_opens = models.IntegerField(default=0)
|
||||
is_trained = models.BooleanField(default=False)
|
||||
|
||||
def __unicode__(self):
|
||||
return '[' + self.feed.feed_title + '] '
|
||||
|
|
|
@ -23,4 +23,5 @@ urlpatterns = patterns('',
|
|||
url(r'^add_feature', views.add_feature, name='add-feature'),
|
||||
url(r'^load_features', views.load_features, name='load-features'),
|
||||
url(r'^save_feed_order', views.save_feed_order, name='save-feed-order'),
|
||||
url(r'^get_feeds_trainer', views.get_feeds_trainer, name='get-feeds-trainer'),
|
||||
)
|
||||
|
|
|
@ -534,6 +534,25 @@ def save_feed_order(request):
|
|||
|
||||
return {}
|
||||
|
||||
@json.json_view
|
||||
def get_feeds_trainer(request):
|
||||
classifiers = []
|
||||
|
||||
usersubs = UserSubscription.objects.filter(user=request.user).select_related('feed')\
|
||||
.order_by('-feed__stories_last_month')
|
||||
|
||||
for us in usersubs:
|
||||
if not us.is_trained and us.feed.stories_last_month > 0:
|
||||
classifier = dict()
|
||||
classifier['classifiers'] = get_classifiers_for_user(request.user, us.feed)
|
||||
classifier['feed_id'] = us.feed.pk
|
||||
classifier['stories_last_month'] = us.feed.stories_last_month
|
||||
classifier['feed_tags'] = json.decode(us.feed.popular_tags) if us.feed.popular_tags else []
|
||||
classifier['feed_authors'] = json.decode(us.feed.popular_authors) if us.feed.popular_authors else []
|
||||
classifiers.append(classifier)
|
||||
|
||||
return classifiers
|
||||
|
||||
@login_required
|
||||
def login_as(request):
|
||||
if not request.user.is_staff:
|
||||
|
|
|
@ -35,7 +35,7 @@ class Migration(SchemaMigration):
|
|||
db.alter_column('stories', 'story_tags', self.gf('django.db.models.fields.CharField')(max_length=2000, null=True, blank=True))
|
||||
|
||||
# Adding unique constraint on 'Story', fields ['story_feed', 'story_guid_hash']
|
||||
db.create_unique('stories', ['story_feed_id', 'story_guid_hash'])
|
||||
# db.create_unique('stories', ['story_feed_id', 'story_guid_hash'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
|
|
@ -1474,17 +1474,72 @@ a.NB-splash-link:hover {
|
|||
text-shadow: 1px 1px 0px #e0e0e0;
|
||||
}
|
||||
|
||||
.NB-disabled {
|
||||
color: #A0A0A0;
|
||||
.NB-modal .NB-modal-subtitle {
|
||||
margin:10px 0 0;
|
||||
padding:8px 12px;
|
||||
font-size: 14px;
|
||||
position: relative;
|
||||
background-color: #F6F6F6;
|
||||
}
|
||||
.NB-modal .NB-modal-feed-title {
|
||||
display: block;
|
||||
margin: 0 40px 0 23px;
|
||||
text-decoration: none;
|
||||
color: #272727;
|
||||
overflow: hidden;
|
||||
text-shadow: 0 1px 0 #EBF3FA;
|
||||
}
|
||||
|
||||
.NB-modal .NB-modal-feed-image {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.NB-modal .NB-modal-submit input[type=submit],
|
||||
.NB-modal .NB-modal-submit .NB-modal-submit-button {
|
||||
border: 1px solid #606060;
|
||||
font-size: 12px;
|
||||
padding: 4px 8px;
|
||||
text-transform: uppercase;
|
||||
margin: 2px 4px 2px;
|
||||
border: 1px solid #606060;
|
||||
-moz-box-shadow:2px 2px 0 #D0D0D0;
|
||||
-webkit-box-shadow:2px 2px 0 #D0D0D0;
|
||||
box-shadow:2px 2px 0 #D0D0D0;
|
||||
border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.NB-modal .NB-modal-submit .NB-modal-submit-back {
|
||||
background-color: #d5d4dB;
|
||||
color: #909090;
|
||||
|
||||
}
|
||||
.NB-modal .NB-modal-submit .NB-modal-submit-close {
|
||||
background-color: #d5d4dB;
|
||||
color: #909090;
|
||||
font-weight: bold;
|
||||
}
|
||||
.NB-modal .NB-modal-submit .NB-modal-submit-save {
|
||||
background-color: #217412;
|
||||
font-weight: bold;
|
||||
color: #FCFCFC;
|
||||
}
|
||||
|
||||
.NB-modal .NB-modal-submit .NB-disabled {
|
||||
background-color: #d5d4dB;
|
||||
color: #909090;
|
||||
border: 1px solid #A0A0A0;
|
||||
-moz-box-shadow:2px 2px 0 #E6E6E6;
|
||||
-webkit-box-shadow:2px 2px 0 #E6E6E6;
|
||||
box-shadow:2px 2px 0 #E6E6E6;
|
||||
}
|
||||
|
||||
.NB-modal .NB-modal-submit {
|
||||
margin: 16px 0 0 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.NB-modal .NB-modal-submit input[type=submit] {
|
||||
font-size: 14px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.NB-modal img.feed_favicon {
|
||||
|
@ -1518,6 +1573,11 @@ a.NB-splash-link:hover {
|
|||
/* = Classifier = */
|
||||
/* ============== */
|
||||
|
||||
.NB-classifier {
|
||||
border-radius: 14px;
|
||||
-moz-border-radius: 14px;
|
||||
}
|
||||
|
||||
.NB-classifier h2.NB-like {
|
||||
color: #007000;
|
||||
}
|
||||
|
@ -1592,6 +1652,27 @@ a.NB-splash-link:hover {
|
|||
.NB-classifiers {
|
||||
}
|
||||
|
||||
.NB-classifier .NB-modal-submit .NB-modal-submit-back {
|
||||
float: left;
|
||||
color: #FFF;
|
||||
background-color: #b5b4bB;
|
||||
}
|
||||
.NB-classifier .NB-modal-submit .NB-modal-submit-close {
|
||||
float: right;
|
||||
color: #FFF;
|
||||
background-color: #b5b4bB;
|
||||
}
|
||||
.NB-classifier .NB-modal-submit .NB-modal-submit-save {
|
||||
float: right;
|
||||
padding-left: 12px !important;
|
||||
padding-right: 12px !important;
|
||||
}
|
||||
.NB-classifier-trainer-counts {
|
||||
float: right;
|
||||
color: #606060;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
/* ======================= */
|
||||
/* = Intelligence Slider = */
|
||||
/* ======================= */
|
||||
|
@ -1644,10 +1725,12 @@ a.NB-splash-link:hover {
|
|||
|
||||
.NB-add .NB-add-danger {
|
||||
display: block;
|
||||
clear: both;
|
||||
font-size: 12px;
|
||||
color: #535558;
|
||||
font-weight: bold;
|
||||
margin: 8px 0 0;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.NB-add .NB-add-danger img {
|
||||
|
@ -1714,6 +1797,12 @@ a.NB-splash-link:hover {
|
|||
margin: 0 4px;
|
||||
}
|
||||
|
||||
.NB-add .NB-opml-reader-oauth {
|
||||
margin: 4px 0 6px 0;
|
||||
text-decoration: none;
|
||||
float: left;
|
||||
display: block;
|
||||
}
|
||||
/* ================ */
|
||||
/* = Manage Feeds = */
|
||||
/* ================ */
|
||||
|
@ -1847,20 +1936,23 @@ background: transparent;
|
|||
display: block;
|
||||
margin: 2px 6px 6px 0;
|
||||
cursor: pointer;
|
||||
padding: 2px 9px 2px 4px;
|
||||
padding: 0 9px 0 4px;
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.NB-classifiers .NB-classifier input[type=checkbox] {
|
||||
margin: 0 6px 0 4px;
|
||||
float: none;
|
||||
margin: 3px 6px 2px 4px;
|
||||
cursor: pointer;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.NB-classifiers .NB-classifier label {
|
||||
cursor: pointer;
|
||||
color: black;
|
||||
float: left;
|
||||
display: block;
|
||||
padding: 2px 0;
|
||||
}
|
||||
|
||||
.NB-classifiers .NB-classifier label b {
|
||||
|
@ -2243,7 +2335,7 @@ background: transparent;
|
|||
|
||||
.NB-menu-manage .NB-menu-manage-subtitle {
|
||||
font-size: 12px;
|
||||
color: #617C4B;
|
||||
color: #718C7B;
|
||||
}
|
||||
|
||||
.NB-menu-manage li:hover .NB-menu-manage-subtitle {
|
||||
|
@ -2342,26 +2434,6 @@ background: transparent;
|
|||
.NB-modal-statistics {
|
||||
}
|
||||
|
||||
.NB-modal-statistics .NB-modal-subtitle {
|
||||
border-bottom: 3px solid #E0E0E0;
|
||||
font-size: 14px;
|
||||
margin-bottom: 6px;
|
||||
padding-bottom: 6px;
|
||||
position: relative;
|
||||
}
|
||||
.NB-modal-statistics .NB-modal-statistics-feed-title {
|
||||
display: block;
|
||||
margin: 4px 40px 2px 23px;
|
||||
text-decoration: none;
|
||||
color: #272727;
|
||||
overflow: hidden;
|
||||
text-shadow: 0 1px 0 #EBF3FA;
|
||||
}
|
||||
|
||||
.NB-modal-statistics .NB-modal-statistics-feed-image {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.NB-modal-statistics .NB-statistics-stat {
|
||||
background-color: #E0FFE0;
|
||||
clear: both;
|
||||
|
|
|
@ -129,6 +129,14 @@ NEWSBLUR.log = function(msg) {
|
|||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
entity: function(str) {
|
||||
var e = document.createElement('div');
|
||||
|
||||
e.innerHTML = String(str);
|
||||
|
||||
return e.innerHTML;
|
||||
},
|
||||
|
||||
make: function(){
|
||||
var $elem, text, children, type, name, props;
|
||||
|
|
|
@ -141,7 +141,7 @@
|
|||
minWidth: null,
|
||||
maxHeight: null,
|
||||
maxWidth: null,
|
||||
autoResize: false,
|
||||
autoResize: true,
|
||||
autoPosition: true,
|
||||
zIndex: 1000,
|
||||
close: true,
|
||||
|
@ -446,6 +446,13 @@
|
|||
|
||||
return [h, el.width()];
|
||||
},
|
||||
resize: function(data) {
|
||||
if (data) {
|
||||
this.d.data = data;
|
||||
}
|
||||
w = this.getDimensions();
|
||||
this.setContainerDimensions();
|
||||
},
|
||||
getVal: function (v) {
|
||||
return v == 'auto' ? 0
|
||||
: v.indexOf('%') > 0 ? v
|
||||
|
@ -459,34 +466,21 @@
|
|||
var ch = $.browser.opera ? s.d.container.height() : s.getVal(s.d.container.css('height')),
|
||||
cw = $.browser.opera ? s.d.container.width() : s.getVal(s.d.container.css('width')),
|
||||
dh = s.d.data.outerHeight(true), dw = s.d.data.outerWidth(true);
|
||||
|
||||
var mh = s.o.maxHeight && s.o.maxHeight < w[0] ? s.o.maxHeight : w[0],
|
||||
w = s.getDimensions();
|
||||
var mh = (s.o.maxHeight && s.o.maxHeight < w[0] ? s.o.maxHeight : w[0]) - 80,
|
||||
mw = s.o.maxWidth && s.o.maxWidth < w[1] ? s.o.maxWidth : w[1];
|
||||
|
||||
// NEWSBLUR.log(['heights', ch, dh, mh, w]);
|
||||
|
||||
// height
|
||||
if (!ch) {
|
||||
if (!dh) {ch = s.o.minHeight;}
|
||||
else {
|
||||
if (dh > mh) {ch = mh;}
|
||||
else if (dh < s.o.minHeight) {ch = s.o.minHeight;}
|
||||
else {ch = dh;}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ch = ch > mh ? mh : ch;
|
||||
}
|
||||
if (dh > mh) {ch = mh;}
|
||||
else if (dh < s.o.minHeight) {ch = s.o.minHeight;}
|
||||
else {ch = dh;}
|
||||
|
||||
// width
|
||||
if (!cw) {
|
||||
if (!dw) {cw = s.o.minWidth;}
|
||||
else {
|
||||
if (dw > mw) {cw = mw;}
|
||||
else if (dw < s.o.minWidth) {cw = s.o.minWidth;}
|
||||
else {cw = dw;}
|
||||
}
|
||||
}
|
||||
else {
|
||||
cw = cw > mw ? mw : cw;
|
||||
}
|
||||
if (dw > mw) {cw = mw;}
|
||||
else if (dw < s.o.minWidth) {cw = s.o.minWidth;}
|
||||
else {cw = dw;}
|
||||
|
||||
s.d.container.css({height: ch, width: cw});
|
||||
if (dh > ch || dw > cw) {
|
||||
|
|
|
@ -244,6 +244,13 @@ NEWSBLUR.AssetModel.Reader.prototype = {
|
|||
$.isFunction(callback) && callback(data, first_load);
|
||||
},
|
||||
|
||||
get_feeds_trainer: function(callback) {
|
||||
var self = this;
|
||||
|
||||
this.make_request('/reader/get_feeds_trainer', {}, callback,
|
||||
null, {'ajax_group': 'feed'});
|
||||
},
|
||||
|
||||
refresh_feeds: function(callback) {
|
||||
var self = this;
|
||||
|
||||
|
|
|
@ -1149,13 +1149,13 @@
|
|||
mark_story_as_like: function(story_id, $button) {
|
||||
var feed_id = this.active_feed;
|
||||
|
||||
NEWSBLUR.classifier = new NEWSBLUR.ReaderClassifierStory(story_id, feed_id, 1);
|
||||
NEWSBLUR.classifier = new NEWSBLUR.ReaderClassifierStory(story_id, feed_id, {'score': 1});
|
||||
},
|
||||
|
||||
mark_story_as_dislike: function(story_id, $button) {
|
||||
var feed_id = this.active_feed;
|
||||
|
||||
NEWSBLUR.classifier = new NEWSBLUR.ReaderClassifierStory(story_id, feed_id, -1);
|
||||
NEWSBLUR.classifier = new NEWSBLUR.ReaderClassifierStory(story_id, feed_id, {'score': -1});
|
||||
},
|
||||
|
||||
// =====================
|
||||
|
@ -1518,7 +1518,8 @@
|
|||
open_feed_intelligence_modal: function(score) {
|
||||
var feed_id = this.active_feed;
|
||||
|
||||
NEWSBLUR.classifier = new NEWSBLUR.ReaderClassifierFeed(feed_id, score);
|
||||
// NEWSBLUR.classifier = new NEWSBLUR.ReaderClassifierFeed(feed_id, {'score': score});
|
||||
NEWSBLUR.classifier = new NEWSBLUR.ReaderClassifierTrainer({'score': score});
|
||||
},
|
||||
|
||||
// ==========================
|
||||
|
@ -1855,6 +1856,11 @@
|
|||
$.make('div', { className: 'NB-menu-manage-title' }, 'Mark all feeds as read'),
|
||||
$.make('div', { className: 'NB-menu-manage-subtitle' }, 'Choose how many days back.')
|
||||
]),
|
||||
$.make('li', { className: 'NB-menu-manage-feed NB-menu-manage-feed-train' }, [
|
||||
$.make('div', { className: 'NB-menu-manage-image' }),
|
||||
$.make('div', { className: 'NB-menu-manage-title' }, 'Train intelligence'),
|
||||
$.make('div', { className: 'NB-menu-manage-subtitle' }, 'Accurate filters are happy filters.')
|
||||
]),
|
||||
$.make('li', { className: 'NB-menu-manage-preferences' }, [
|
||||
$.make('div', { className: 'NB-menu-manage-image' }),
|
||||
$.make('div', { className: 'NB-menu-manage-title' }, 'Preferences'),
|
||||
|
@ -1883,7 +1889,7 @@
|
|||
$.make('li', { className: 'NB-menu-manage-feed NB-menu-manage-feed-train' }, [
|
||||
$.make('div', { className: 'NB-menu-manage-image' }),
|
||||
$.make('div', { className: 'NB-menu-manage-title' }, 'Train intelligence'),
|
||||
$.make('div', { className: 'NB-menu-manage-subtitle' }, 'Accurate filters are happy filters.')
|
||||
$.make('div', { className: 'NB-menu-manage-subtitle' }, 'Choose classifiers for this site.')
|
||||
]),
|
||||
$.make('li', { className: 'NB-menu-manage-feed NB-menu-manage-feed-stats' }, [
|
||||
$.make('div', { className: 'NB-menu-manage-image' }),
|
||||
|
|
|
@ -24,7 +24,7 @@ NEWSBLUR.ReaderAddFeed.prototype = {
|
|||
this.$add = $.make('div', { className: 'NB-add NB-modal' }, [
|
||||
$.make('h2', { className: 'NB-modal-title' }, 'Add feeds and folders'),
|
||||
$.make('div', { className: 'NB-add-form' }, [
|
||||
$.make('div', { className: 'NB-fieldset NB-add-add-url' }, [
|
||||
$.make('div', { className: 'NB-fieldset NB-add-add-url NB-modal-submit' }, [
|
||||
$.make('h5', [
|
||||
$.make('div', { className: 'NB-add-folders' }, this.make_folders()),
|
||||
'Add a new feed'
|
||||
|
@ -34,12 +34,12 @@ NEWSBLUR.ReaderAddFeed.prototype = {
|
|||
$.make('div', { className: 'NB-loading' }),
|
||||
$.make('label', { 'for': 'NB-add-url' }, 'RSS or URL: '),
|
||||
$.make('input', { type: 'text', id: 'NB-add-url', className: 'NB-add-url', name: 'url' }),
|
||||
$.make('input', { type: 'submit', value: 'Add it', className: 'NB-add-url-submit' }),
|
||||
$.make('input', { type: 'submit', value: 'Add it', className: 'NB-modal-submit-save NB-add-url-submit' }),
|
||||
$.make('div', { className: 'NB-error' })
|
||||
])
|
||||
])
|
||||
]),
|
||||
$.make('div', { className: 'NB-fieldset NB-add-add-folder' }, [
|
||||
$.make('div', { className: 'NB-fieldset NB-add-add-folder NB-modal-submit' }, [
|
||||
$.make('h5', [
|
||||
$.make('div', { className: 'NB-add-folders' }, this.make_folders()),
|
||||
'Add a new folder'
|
||||
|
@ -51,18 +51,18 @@ NEWSBLUR.ReaderAddFeed.prototype = {
|
|||
$.make('div', { className: 'NB-folder-icon' })
|
||||
]),
|
||||
$.make('input', { type: 'text', id: 'NB-add-folder', className: 'NB-add-folder', name: 'url' }),
|
||||
$.make('input', { type: 'submit', value: 'Add folder', className: 'NB-add-folder-submit' }),
|
||||
$.make('input', { type: 'submit', value: 'Add folder', className: 'NB-add-folder-submit NB-modal-submit-save' }),
|
||||
$.make('div', { className: 'NB-error' })
|
||||
])
|
||||
])
|
||||
]),
|
||||
$.make('div', { className: 'NB-fieldset NB-anonymous-ok' }, [
|
||||
$.make('div', { className: 'NB-fieldset NB-anonymous-ok NB-modal-submit' }, [
|
||||
$.make('h5', [
|
||||
'Import from Google Reader'
|
||||
'Import feeds'
|
||||
]),
|
||||
$.make('div', { className: 'NB-fieldset-fields' }, [
|
||||
$.make('a', { href: NEWSBLUR.URLs['opml-reader-authorize'], className: 'NB-opml-reader-oauth NB-splash-link' }, [
|
||||
'Import everything from Google Reader (OAuth)',
|
||||
$.make('a', { href: NEWSBLUR.URLs['opml-reader-authorize'], className: 'NB-opml-reader-oauth NB-modal-submit-save NB-modal-submit-button' }, [
|
||||
'Import from Google Reader',
|
||||
$.make('img', { className: 'NB-add-google-reader-arrow', src: NEWSBLUR.Globals['MEDIA_URL']+'img/icons/silk/arrow_right.png' })
|
||||
]),
|
||||
$.make('div', { className: 'NB-add-danger' }, [
|
||||
|
@ -71,13 +71,13 @@ NEWSBLUR.ReaderAddFeed.prototype = {
|
|||
])
|
||||
])
|
||||
]),
|
||||
$.make('div', { className: 'NB-fieldset NB-add-opml' }, [
|
||||
$.make('div', { className: 'NB-fieldset NB-add-opml NB-modal-submit' }, [
|
||||
$.make('h5', 'Upload OPML'),
|
||||
$.make('div', { className: 'NB-fieldset-fields' }, [
|
||||
$.make('form', { method: 'post', enctype: 'multipart/form-data', className: 'NB-add-form' }, [
|
||||
$.make('div', { className: 'NB-loading' }),
|
||||
$.make('input', { type: 'file', name: 'file', id: 'opml_file_input' }),
|
||||
$.make('input', { type: 'submit', className: 'NB-add-opml-button', value: 'Upload OPML File' }).click(function(e) {
|
||||
$.make('input', { type: 'submit', className: 'NB-add-opml-button NB-modal-submit-save', value: 'Upload OPML File' }).click(function(e) {
|
||||
e.preventDefault();
|
||||
self.handle_opml_upload();
|
||||
return false;
|
||||
|
@ -142,17 +142,17 @@ NEWSBLUR.ReaderAddFeed.prototype = {
|
|||
|
||||
this.$add.modal({
|
||||
'minWidth': 600,
|
||||
'maxHeight': height,
|
||||
'overlayClose': true,
|
||||
'onOpen': function (dialog) {
|
||||
dialog.overlay.fadeIn(200, function () {
|
||||
dialog.container.fadeIn(200);
|
||||
dialog.data.fadeIn(200);
|
||||
dialog.data.fadeIn(200, function() {
|
||||
$.modal.impl.setContainerDimensions();
|
||||
});
|
||||
});
|
||||
},
|
||||
'onShow': function(dialog) {
|
||||
$('#simplemodal-container').corner('6px').css({'width': 600, 'height': height});
|
||||
$.modal.impl.setPosition();
|
||||
},
|
||||
'onClose': function(dialog) {
|
||||
dialog.data.hide().empty().remove();
|
||||
|
|
|
@ -1,21 +1,46 @@
|
|||
NEWSBLUR.ReaderClassifierFeed = function(feed_id, score, options) {
|
||||
var defaults = {};
|
||||
NEWSBLUR.ReaderClassifierTrainer = function(options) {
|
||||
var defaults = {
|
||||
'score': 1,
|
||||
'training': true
|
||||
};
|
||||
|
||||
this.flags = {
|
||||
'publisher': true,
|
||||
'story': false
|
||||
};
|
||||
this.cache = {};
|
||||
this.trainer_iterator = 0;
|
||||
this.feed_id = null;
|
||||
this.options = $.extend({}, defaults, options);
|
||||
this.score = this.options['score'];
|
||||
this.model = NEWSBLUR.AssetModel.reader();
|
||||
this.google_favicon_url = 'http://www.google.com/s2/favicons?domain_url=';
|
||||
this.runner_trainer();
|
||||
};
|
||||
|
||||
NEWSBLUR.ReaderClassifierFeed = function(feed_id, options) {
|
||||
var defaults = {
|
||||
'score': 1,
|
||||
'training': false
|
||||
};
|
||||
|
||||
this.flags = {
|
||||
'publisher': true,
|
||||
'story': false
|
||||
};
|
||||
this.feed_id = feed_id;
|
||||
this.score = score;
|
||||
this.options = $.extend({}, defaults, options);
|
||||
this.score = this.options['score'];
|
||||
this.model = NEWSBLUR.AssetModel.reader();
|
||||
this.google_favicon_url = 'http://www.google.com/s2/favicons?domain_url=';
|
||||
this.runner_feed();
|
||||
};
|
||||
|
||||
|
||||
NEWSBLUR.ReaderClassifierStory = function(story_id, feed_id, score, options) {
|
||||
var defaults = {};
|
||||
NEWSBLUR.ReaderClassifierStory = function(story_id, feed_id, options) {
|
||||
var defaults = {
|
||||
'score': 1
|
||||
};
|
||||
|
||||
this.flags = {
|
||||
'publisher': false,
|
||||
|
@ -23,8 +48,8 @@ NEWSBLUR.ReaderClassifierStory = function(story_id, feed_id, score, options) {
|
|||
};
|
||||
this.story_id = story_id;
|
||||
this.feed_id = feed_id;
|
||||
this.score = score;
|
||||
this.options = $.extend({}, defaults, options);
|
||||
this.score = this.options['score'];
|
||||
this.model = NEWSBLUR.AssetModel.reader();
|
||||
this.google_favicon_url = 'http://www.google.com/s2/favicons?domain_url=';
|
||||
this.runner_story();
|
||||
|
@ -32,19 +57,37 @@ NEWSBLUR.ReaderClassifierStory = function(story_id, feed_id, score, options) {
|
|||
|
||||
var classifier = {
|
||||
|
||||
runner_feed: function() {
|
||||
this.find_story_and_feed();
|
||||
this.make_modal_feed();
|
||||
this.make_modal_title();
|
||||
this.make_modal_intelligence_slider();
|
||||
this.handle_text_highlight();
|
||||
runner_trainer: function() {
|
||||
this.user_classifiers = {};
|
||||
|
||||
this.make_trainer_intro();
|
||||
this.get_feeds_trainer();
|
||||
this.handle_select_checkboxes();
|
||||
this.handle_cancel();
|
||||
this.handle_select_title();
|
||||
this.open_modal();
|
||||
|
||||
this.$modal.parent().bind('click.reader_classifer', $.rescope(this.handle_clicks, this));
|
||||
},
|
||||
|
||||
runner_feed: function() {
|
||||
this.user_classifiers = this.model.classifiers;
|
||||
|
||||
this.find_story_and_feed();
|
||||
this.make_modal_feed();
|
||||
this.make_modal_title();
|
||||
this.make_modal_intelligence_slider();
|
||||
this.handle_select_checkboxes();
|
||||
this.handle_cancel();
|
||||
this.handle_select_title();
|
||||
this.open_modal();
|
||||
|
||||
this.$modal.bind('submit.reader_classifer', $.rescope(this.handle_submit, this));
|
||||
},
|
||||
|
||||
runner_story: function() {
|
||||
this.user_classifiers = this.model.classifiers;
|
||||
|
||||
this.find_story_and_feed();
|
||||
this.make_modal_story();
|
||||
this.make_modal_title();
|
||||
|
@ -55,6 +98,49 @@ var classifier = {
|
|||
this.open_modal();
|
||||
},
|
||||
|
||||
load_next_feed_in_trainer: function(backwards) {
|
||||
if (backwards) {
|
||||
this.trainer_iterator = Math.max(1, this.trainer_iterator - 1);
|
||||
} else {
|
||||
this.trainer_iterator = Math.min(this.trainer_data.length, this.trainer_iterator + 1);
|
||||
}
|
||||
var trainer_data = this.trainer_data[this.trainer_iterator-1];
|
||||
this.feed_id = trainer_data['feed_id'];
|
||||
this.feed = this.model.get_feed(this.feed_id);
|
||||
this.feed_tags = trainer_data['feed_tags'];
|
||||
this.feed_authors = trainer_data['feed_authors'];
|
||||
this.user_classifiers = trainer_data['classifiers'];
|
||||
|
||||
this.make_modal_feed();
|
||||
this.make_modal_title();
|
||||
this.make_modal_trainer_count();
|
||||
|
||||
if (backwards || this.feed_id in this.cache) {
|
||||
this.$modal = this.cache[this.feed_id];
|
||||
}
|
||||
$('.NB-modal').replaceWith(this.$modal);
|
||||
|
||||
|
||||
|
||||
// var height = this.$modal.outerHeight(true);
|
||||
$.modal.impl.resize(this.$modal);
|
||||
},
|
||||
|
||||
get_feeds_trainer: function() {
|
||||
this.model.get_feeds_trainer($.rescope(this.load_feeds_trainer, this));
|
||||
},
|
||||
|
||||
load_feeds_trainer: function(e, data) {
|
||||
var $begin = $('.NB-modal-submit-begin', this.$modal);
|
||||
|
||||
NEWSBLUR.log(['data', data]);
|
||||
this.trainer_data = data;
|
||||
|
||||
$begin.text('Begin Training')
|
||||
.addClass('NB-modal-submit-save')
|
||||
.removeClass('NB-disabled');
|
||||
},
|
||||
|
||||
find_story_and_feed: function() {
|
||||
if (this.story_id) {
|
||||
this.story = this.model.get_story(this.story_id);
|
||||
|
@ -62,6 +148,22 @@ var classifier = {
|
|||
this.feed = this.model.get_feed(this.feed_id);
|
||||
this.feed_tags = this.model.get_feed_tags();
|
||||
this.feed_authors = this.model.get_feed_authors();
|
||||
|
||||
$('.NB-modal-subtitle .NB-modal-feed-image', this.$modal).attr('src', this.google_favicon_url + this.feed['feed_link']);
|
||||
$('.NB-modal-subtitle .NB-modal-feed-title', this.$modal).html(this.feed['feed_title']);
|
||||
},
|
||||
|
||||
make_trainer_intro: function() {
|
||||
var self = this;
|
||||
|
||||
this.$modal = $.make('div', { className: 'NB-classifier NB-modal NB-trainer'}, [
|
||||
$.make('h2', { className: 'NB-modal-title' }, 'Intelligence Trainer'),
|
||||
$.make('h2', { className: 'NB-modal-title' }, 'Trained feed are happy feeds'),
|
||||
$.make('div', { className: 'NB-modal-submit' }, [
|
||||
$.make('a', { href: '#', className: 'NB-modal-submit-save NB-modal-submit-begin NB-modal-submit-button NB-disabled' }, 'Loading Training...')
|
||||
])
|
||||
]);
|
||||
|
||||
},
|
||||
|
||||
make_modal_feed: function() {
|
||||
|
@ -69,11 +171,17 @@ var classifier = {
|
|||
var feed = this.feed;
|
||||
var opinion = (this.score == 1 ? 'like_' : 'dislike_');
|
||||
|
||||
NEWSBLUR.log(['Make feed', feed, this.feed_authors, this.feed_tags]);
|
||||
// NEWSBLUR.log(['Make feed', feed, this.feed_authors, this.feed_tags]);
|
||||
|
||||
this.$classifier = $.make('div', { className: 'NB-classifier NB-modal' }, [
|
||||
this.make_modal_intelligence_slider(),
|
||||
this.$modal = $.make('div', { className: 'NB-classifier NB-modal' }, [
|
||||
$.make('div', { className: 'NB-modal-loading' }),
|
||||
(!this.options['training'] && this.make_modal_intelligence_slider()),
|
||||
(this.options['training'] && $.make('div', { className: 'NB-classifier-trainer-counts' })),
|
||||
$.make('h2', { className: 'NB-modal-title' }),
|
||||
$.make('h2', { className: 'NB-modal-subtitle' }, [
|
||||
$.make('img', { className: 'NB-modal-feed-image feed_favicon', src: this.google_favicon_url + this.feed.feed_link }),
|
||||
$.make('span', { className: 'NB-modal-feed-title' }, this.feed.feed_title)
|
||||
]),
|
||||
$.make('form', { method: 'post', className: 'NB-publisher' }, [
|
||||
(this.feed_authors.length && $.make('div', { className: 'NB-modal-field NB-fieldset NB-classifiers' }, [
|
||||
$.make('h5', 'Authors'),
|
||||
|
@ -93,19 +201,22 @@ var classifier = {
|
|||
this.make_publisher(feed, opinion)
|
||||
)
|
||||
]),
|
||||
$.make('div', { className: 'NB-modal-submit' }, [
|
||||
(this.options['training'] && $.make('div', { className: 'NB-modal-submit' }, [
|
||||
$.make('input', { name: 'score', value: this.score, type: 'hidden' }),
|
||||
$.make('input', { name: 'feed_id', value: this.feed_id, type: 'hidden' }),
|
||||
$.make('a', { href: '#', className: 'NB-modal-submit-button NB-modal-submit-back' }, $.entity('«') + ' Back'),
|
||||
$.make('a', { href: '#', className: 'NB-modal-submit-button NB-modal-submit-save' }, 'Save & Next '+$.entity('»')),
|
||||
$.make('a', { href: '#', className: 'NB-modal-submit-button NB-modal-submit-close' }, 'Close')
|
||||
])),
|
||||
(!this.options['training'] && $.make('div', { className: 'NB-modal-submit' }, [
|
||||
$.make('input', { name: 'score', value: this.score, type: 'hidden' }),
|
||||
$.make('input', { name: 'story_id', value: this.story_id, type: 'hidden' }),
|
||||
$.make('input', { type: 'submit', disabled: 'true', className: 'NB-disabled', value: 'Check what you like above...' }),
|
||||
$.make('input', { name: 'feed_id', value: this.feed_id, type: 'hidden' }),
|
||||
$.make('input', { type: 'submit', disabled: 'true', className: 'NB-modal-submit-save NB-disabled', value: 'Check what you like above...' }),
|
||||
' or ',
|
||||
$.make('a', { href: '#', className: 'NB-modal-cancel' }, 'cancel')
|
||||
])
|
||||
]).bind('submit', function(e) {
|
||||
e.preventDefault();
|
||||
self.save_publisher();
|
||||
return false;
|
||||
})
|
||||
]))
|
||||
])
|
||||
]);
|
||||
},
|
||||
|
||||
|
@ -120,7 +231,7 @@ var classifier = {
|
|||
// HTML entities decoding.
|
||||
story.story_title = $('<div/>').html(story.story_title).text();
|
||||
|
||||
this.$classifier = $.make('div', { className: 'NB-classifier NB-modal' }, [
|
||||
this.$modal = $.make('div', { className: 'NB-classifier NB-modal' }, [
|
||||
this.make_modal_intelligence_slider(),
|
||||
$.make('h2', { className: 'NB-modal-title' }),
|
||||
$.make('form', { method: 'post' }, [
|
||||
|
@ -157,9 +268,9 @@ var classifier = {
|
|||
]),
|
||||
$.make('div', { className: 'NB-modal-submit' }, [
|
||||
$.make('input', { name: 'score', value: this.score, type: 'hidden' }),
|
||||
$.make('input', { name: 'feed_id', value: this.feed_id, type: 'hidden' }),
|
||||
$.make('input', { name: 'story_id', value: this.story_id, type: 'hidden' }),
|
||||
$.make('input', { type: 'submit', disabled: 'true', className: 'NB-disabled', value: 'Check what you like above...' }),
|
||||
$.make('input', { name: 'feed_id', value: this.feed_id, type: 'hidden' }),
|
||||
$.make('input', { type: 'submit', disabled: 'true', className: 'NB-modal-submit-save NB-disabled', value: 'Check what you like above...' }),
|
||||
' or ',
|
||||
$.make('a', { href: '#', className: 'NB-modal-cancel' }, 'cancel')
|
||||
])
|
||||
|
@ -172,7 +283,7 @@ var classifier = {
|
|||
},
|
||||
|
||||
make_modal_title: function() {
|
||||
var $modal_title = $('.NB-modal-title', this.$classifier);
|
||||
var $modal_title = $('.NB-modal-title', this.$modal);
|
||||
|
||||
if (this.flags['publisher']) {
|
||||
if (this.score == 1) {
|
||||
|
@ -189,6 +300,13 @@ var classifier = {
|
|||
}
|
||||
},
|
||||
|
||||
make_modal_trainer_count: function() {
|
||||
var $count = $('.NB-classifier-trainer-counts', this.$modal);
|
||||
var count = this.trainer_iterator;
|
||||
var total = this.trainer_data.length;
|
||||
$count.html(count + '/' + total);
|
||||
},
|
||||
|
||||
make_modal_intelligence_slider: function() {
|
||||
var self = this;
|
||||
var $slider = $.make('div', { className: 'NB-taskbar-intelligence NB-modal-slider' }, [
|
||||
|
@ -208,14 +326,14 @@ var classifier = {
|
|||
// self.switch_feed_view_unread_view(ui.value);
|
||||
self.score = ui.value - 1;
|
||||
self.make_modal_title();
|
||||
$('input[name^=like],input[name^=dislike]', self.$classifier).attr('name', function(i, current_name) {
|
||||
$('input[name^=like],input[name^=dislike]', self.$modal).attr('name', function(i, current_name) {
|
||||
if (self.score == -1) {
|
||||
return 'dis' + current_name.substr(current_name.indexOf('like_'));
|
||||
} else if (self.score == 1) {
|
||||
return current_name.substr(current_name.indexOf('like_'));
|
||||
}
|
||||
});
|
||||
var $submit = $('input[type=submit]', self.$classifier);
|
||||
var $submit = $('input[type=submit]', self.$modal);
|
||||
$submit.removeClass("NB-disabled").removeAttr('disabled').attr('value', 'Save');
|
||||
}
|
||||
});
|
||||
|
@ -245,8 +363,8 @@ var classifier = {
|
|||
id: 'classifier_author_'+a
|
||||
};
|
||||
|
||||
if (author in this.model.classifiers.authors
|
||||
&& this.model.classifiers.authors[author] == this.score) {
|
||||
if (author in this.user_classifiers.authors
|
||||
&& this.user_classifiers.authors[author] == this.score) {
|
||||
input_attrs['checked'] = 'checked';
|
||||
}
|
||||
|
||||
|
@ -290,7 +408,7 @@ var classifier = {
|
|||
id: 'classifier_tag_'+t
|
||||
};
|
||||
|
||||
if (tag in this.model.classifiers.tags && this.model.classifiers.tags[tag] == this.score) {
|
||||
if (tag in this.user_classifiers.tags && this.user_classifiers.tags[tag] == this.score) {
|
||||
input_attrs['checked'] = 'checked';
|
||||
}
|
||||
|
||||
|
@ -321,8 +439,8 @@ var classifier = {
|
|||
id: 'classifier_publisher',
|
||||
checked: false
|
||||
};
|
||||
if (this.feed.feed_link in this.model.classifiers.feeds
|
||||
&& this.model.classifiers.feeds[this.feed.feed_link].score == this.score) {
|
||||
if (this.feed.feed_link in this.user_classifiers.feeds
|
||||
&& this.user_classifiers.feeds[this.feed.feed_link].score == this.score) {
|
||||
input_attrs['checked'] = true;
|
||||
}
|
||||
|
||||
|
@ -354,7 +472,7 @@ var classifier = {
|
|||
var self = this;
|
||||
|
||||
var $holder = $.make('div', { className: 'NB-modal-holder' })
|
||||
.append(this.$classifier)
|
||||
.append(this.$modal)
|
||||
.appendTo('body')
|
||||
.css({'visibility': 'hidden', 'display': 'block', 'width': 600});
|
||||
var height = $('.NB-classifier', $holder).outerHeight(true);
|
||||
|
@ -364,11 +482,11 @@ var classifier = {
|
|||
height = w[0] - 70;
|
||||
}
|
||||
|
||||
this.$classifier.modal({
|
||||
this.$modal.modal({
|
||||
'minWidth': 600,
|
||||
'maxHeight': height,
|
||||
'overlayClose': true,
|
||||
'autoResize': true,
|
||||
'position': [40, 0],
|
||||
'onOpen': function (dialog) {
|
||||
dialog.overlay.fadeIn(200, function () {
|
||||
dialog.container.fadeIn(200);
|
||||
|
@ -377,7 +495,7 @@ var classifier = {
|
|||
},
|
||||
'onShow': function(dialog) {
|
||||
$('#simplemodal-container').corner('6px').css({'width': 600, 'height': height});
|
||||
$('.NB-classifier', self.$classifier).corner('14px');
|
||||
$('.NB-classifier', self.$modal).corner('14px');
|
||||
$.modal.impl.setPosition();
|
||||
},
|
||||
'onClose': function(dialog) {
|
||||
|
@ -393,9 +511,9 @@ var classifier = {
|
|||
},
|
||||
|
||||
handle_text_highlight: function() {
|
||||
var $title_highlight = $('.NB-classifier-title-highlight', this.$classifier);
|
||||
var $title = $('.NB-classifier-title-text', this.$classifier);
|
||||
var $title_checkbox = $('#classifier_title', this.$classifier);
|
||||
var $title_highlight = $('.NB-classifier-title-highlight', this.$modal);
|
||||
var $title = $('.NB-classifier-title-text', this.$modal);
|
||||
var $title_checkbox = $('#classifier_title', this.$modal);
|
||||
|
||||
var update = function() {
|
||||
var text = $.trim($(this).getSelection().text);
|
||||
|
@ -415,9 +533,9 @@ var classifier = {
|
|||
},
|
||||
|
||||
handle_select_title: function() {
|
||||
var $title_checkbox = $('#classifier_title', this.$classifier);
|
||||
var $title = $('.NB-classifier-title-text', this.$classifier);
|
||||
var $title_highlight = $('.NB-classifier-title-highlight', this.$classifier);
|
||||
var $title_checkbox = $('#classifier_title', this.$modal);
|
||||
var $title = $('.NB-classifier-title-text', this.$modal);
|
||||
var $title_highlight = $('.NB-classifier-title-highlight', this.$modal);
|
||||
|
||||
$title_checkbox.change(function() {;
|
||||
if ($title.parents('.NB-classifier-facet-disabled').length) {
|
||||
|
@ -432,16 +550,22 @@ var classifier = {
|
|||
|
||||
handle_select_checkboxes: function() {
|
||||
var self = this;
|
||||
var $submit = $('input[type=submit]', this.$classifier);
|
||||
var $save = $('.NB-modal-submit-save', this.$modal);
|
||||
var $close = $('.NB-modal-submit-close', this.$modal);
|
||||
var $back = $('.NB-modal-submit-back', this.$modal);
|
||||
|
||||
$('input', this.$classifier).change(function() {
|
||||
// var count = $('input:checked', self.$classifier).length;
|
||||
$submit.removeClass("NB-disabled").removeAttr('disabled').attr('value', 'Save');
|
||||
$('input', this.$modal).change(function() {
|
||||
// var count = $('input:checked', self.$modal).length;
|
||||
if (self.options['training']) {
|
||||
$close.val('Save & Close');
|
||||
} else {
|
||||
$submit.removeClass("NB-disabled").removeAttr('disabled').attr('value', 'Save');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
handle_cancel: function() {
|
||||
var $cancel = $('.NB-modal-cancel', this.$classifier);
|
||||
var $cancel = $('.NB-modal-cancel', this.$modal);
|
||||
|
||||
$cancel.click(function(e) {
|
||||
e.preventDefault();
|
||||
|
@ -449,10 +573,44 @@ var classifier = {
|
|||
});
|
||||
},
|
||||
|
||||
handle_submit: function(elem, e) {
|
||||
var self = this;
|
||||
|
||||
$.targetIs(e, { tagSelector: '.NB-modal-submit-save' }, function($t, $p){
|
||||
e.preventDefault();
|
||||
self.save_publisher();
|
||||
});
|
||||
},
|
||||
|
||||
handle_clicks: function(elem, e) {
|
||||
var self = this;
|
||||
|
||||
$.targetIs(e, { tagSelector: '.NB-modal-submit-begin' }, function($t, $p){
|
||||
e.preventDefault();
|
||||
self.load_next_feed_in_trainer();
|
||||
});
|
||||
|
||||
$.targetIs(e, { tagSelector: '.NB-modal-submit-save:not(.NB-modal-submit-begin)' }, function($t, $p){
|
||||
e.preventDefault();
|
||||
self.save_publisher(true);
|
||||
self.load_next_feed_in_trainer();
|
||||
});
|
||||
|
||||
$.targetIs(e, { tagSelector: '.NB-modal-submit-back' }, function($t, $p){
|
||||
e.preventDefault();
|
||||
self.load_next_feed_in_trainer(true);
|
||||
});
|
||||
|
||||
$.targetIs(e, { tagSelector: '.NB-modal-submit-close' }, function($t, $p){
|
||||
e.preventDefault();
|
||||
self.save_publisher();
|
||||
});
|
||||
},
|
||||
|
||||
serialize_classifier: function() {
|
||||
var checked_data = $('input', this.$classifier).serialize();
|
||||
var checked_data = $('input', this.$modal).serialize();
|
||||
|
||||
var $unchecked = $('input[type=checkbox]:not(:checked)', this.$classifier);
|
||||
var $unchecked = $('input[type=checkbox]:not(:checked)', this.$modal);
|
||||
$unchecked.attr('checked', true);
|
||||
$unchecked.each(function() {
|
||||
$(this).attr('name', 'remove_' + $(this).attr('name'));
|
||||
|
@ -468,26 +626,31 @@ var classifier = {
|
|||
return data;
|
||||
},
|
||||
|
||||
save_publisher: function() {
|
||||
var $save = $('.NB-classifier input[type=submit]');
|
||||
save_publisher: function(keep_modal_open) {
|
||||
var $save = $('.NB-modal-submit-save', this.$modal);
|
||||
var story_id = this.story_id;
|
||||
var data = this.serialize_classifier();
|
||||
|
||||
NEWSBLUR.reader.update_opinions(this.$classifier, this.feed_id);
|
||||
NEWSBLUR.reader.update_opinions(this.$modal, this.feed_id);
|
||||
|
||||
if (this.options['training']) {
|
||||
this.cache[this.feed_id] = this.$modal.clone();
|
||||
}
|
||||
$save.text('Saving...').addClass('NB-disabled').attr('disabled', true);
|
||||
this.model.save_classifier_publisher(data, function() {
|
||||
NEWSBLUR.reader.force_feed_refresh();
|
||||
$.modal.close();
|
||||
if (!keep_modal_open) {
|
||||
NEWSBLUR.reader.force_feed_refresh();
|
||||
$.modal.close();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
save_story: function() {
|
||||
var $save = $('.NB-classifier input[type=submit]');
|
||||
var $save = $('.NB-modal-submit-save', this.$modal);
|
||||
var story_id = this.story_id;
|
||||
var data = this.serialize_classifier();
|
||||
|
||||
NEWSBLUR.reader.update_opinions(this.$classifier, this.feed_id);
|
||||
NEWSBLUR.reader.update_opinions(this.$modal, this.feed_id);
|
||||
|
||||
$save.text('Saving...').addClass('NB-disabled').attr('disabled', true);
|
||||
this.model.save_classifier_story(story_id, data, function() {
|
||||
|
@ -500,3 +663,4 @@ var classifier = {
|
|||
|
||||
NEWSBLUR.ReaderClassifierStory.prototype = classifier;
|
||||
NEWSBLUR.ReaderClassifierFeed.prototype = classifier;
|
||||
NEWSBLUR.ReaderClassifierTrainer.prototype = classifier;
|
||||
|
|
|
@ -255,19 +255,9 @@ NEWSBLUR.ReaderManageFeed.prototype = {
|
|||
|
||||
open_modal: function() {
|
||||
var self = this;
|
||||
|
||||
var $holder = $.make('div', { className: 'NB-modal-holder' }).append(this.$manage).appendTo('body').css({'visibility': 'hidden', 'display': 'block', 'width': 600});
|
||||
var height = $('.NB-manage', $holder).outerHeight(true);
|
||||
$holder.css({'visibility': 'visible', 'display': 'none'});
|
||||
|
||||
var w = $.modal.impl.getDimensions();
|
||||
if (height > w[0] - 70) {
|
||||
height = w[0] - 70;
|
||||
}
|
||||
|
||||
this.$manage.modal({
|
||||
'minWidth': 600,
|
||||
'maxHeight': height,
|
||||
'overlayClose': true,
|
||||
'onOpen': function (dialog) {
|
||||
dialog.overlay.fadeIn(200, function () {
|
||||
|
|
|
@ -30,7 +30,7 @@ NEWSBLUR.ReaderMarkRead.prototype = {
|
|||
$.make('div', { className: 'NB-markread-slider'}),
|
||||
$.make('div', { className: 'NB-markread-explanation'}),
|
||||
$.make('div', { className: 'NB-modal-submit' }, [
|
||||
$.make('input', { type: 'submit', className: '', value: 'Do it' }),
|
||||
$.make('input', { type: 'submit', className: 'NB-modal-submit-save', value: 'Do it' }),
|
||||
' or ',
|
||||
$.make('a', { href: '#', className: 'NB-modal-cancel' }, 'cancel')
|
||||
])
|
||||
|
@ -125,11 +125,15 @@ NEWSBLUR.ReaderMarkRead.prototype = {
|
|||
var days = $slider.slider('option', 'value');
|
||||
|
||||
$save.attr('value', 'Marking as read...').addClass('NB-disabled').attr('disabled', true);
|
||||
this.model.save_mark_read(days, function() {
|
||||
NEWSBLUR.reader.force_feed_refresh(function() {
|
||||
$.modal.close();
|
||||
if (NEWSBLUR.Globals.is_authenticated) {
|
||||
this.model.save_mark_read(days, function() {
|
||||
NEWSBLUR.reader.force_feed_refresh(function() {
|
||||
$.modal.close();
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
$.modal.close();
|
||||
}
|
||||
},
|
||||
|
||||
// ===========
|
||||
|
|
|
@ -28,8 +28,8 @@ NEWSBLUR.ReaderStatistics.prototype = {
|
|||
$.make('div', { className: 'NB-modal-loading' }),
|
||||
$.make('h2', { className: 'NB-modal-title' }, 'Statistics & History'),
|
||||
$.make('h2', { className: 'NB-modal-subtitle' }, [
|
||||
$.make('img', { className: 'NB-modal-statistics-feed-image feed_favicon', src: this.google_favicon_url + this.feed.feed_link }),
|
||||
$.make('span', { className: 'NB-modal-statistics-feed-title' }, this.feed.feed_title)
|
||||
$.make('img', { className: 'NB-modal-feed-image feed_favicon', src: this.google_favicon_url + this.feed.feed_link }),
|
||||
$.make('span', { className: 'NB-modal-feed-title' }, this.feed.feed_title)
|
||||
]),
|
||||
$.make('div', { className: 'NB-modal-statistics-info' }),
|
||||
$.make('div', { className: 'NB-modal-feed-chooser-container'}, [
|
||||
|
@ -42,8 +42,8 @@ NEWSBLUR.ReaderStatistics.prototype = {
|
|||
this.feed_id = feed_id;
|
||||
this.feed = this.model.get_feed(feed_id);
|
||||
|
||||
$('.NB-modal-subtitle .NB-modal-statistics-feed-image', this.$manage).attr('src', this.google_favicon_url + this.feed['feed_link']);
|
||||
$('.NB-modal-subtitle .NB-modal-statistics-feed-title', this.$manage).html(this.feed['feed_title']);
|
||||
$('.NB-modal-subtitle .NB-modal-feed-image', this.$modal).attr('src', this.google_favicon_url + this.feed['feed_link']);
|
||||
$('.NB-modal-subtitle .NB-modal-feed-title', this.$modal).html(this.feed['feed_title']);
|
||||
},
|
||||
|
||||
open_modal: function() {
|
||||
|
|
|
@ -11,13 +11,16 @@ graph_config = {
|
|||
'graph_vlabel' : 'users',
|
||||
'all.label': 'all',
|
||||
'monthly.label': 'monthly',
|
||||
'daily.label': 'daily',
|
||||
}
|
||||
|
||||
last_month = datetime.datetime.now() - datetime.timedelta(days=30)
|
||||
last_day = datetime.datetime.now() - datetime.timedelta(minutes=60*24)
|
||||
|
||||
metrics = {
|
||||
'all': User.objects.count(),
|
||||
'monthly': Profile.objects.filter(last_seen_on__gte=last_month).count()
|
||||
'monthly': Profile.objects.filter(last_seen_on__gte=last_month).count(),
|
||||
'daily': Profile.objects.filter(last_seen_on__gte=last_day).count(),
|
||||
}
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
Loading…
Add table
Reference in a new issue