diff --git a/apps/push/models.py b/apps/push/models.py index 7e50ba8d8..d091f92e4 100644 --- a/apps/push/models.py +++ b/apps/push/models.py @@ -6,8 +6,6 @@ import requests import re from django.conf import settings -from django.contrib.sites.models import Site -from django.core.urlresolvers import reverse, Resolver404 from django.db import models from django.utils.hashcompat import sha_constructor @@ -48,12 +46,12 @@ class PushSubscriptionManager(models.Manager): callback = "http://push.newsblur.com/push/%s" % subscription.pk # + callback_path response = self._send_request(hub, { - 'hub.mode': 'subscribe', - 'hub.callback': callback, - 'hub.topic': topic, - 'hub.verify': ['async', 'sync'], - 'hub.verify_token': subscription.generate_token('subscribe'), - 'hub.lease_seconds': lease_seconds, + 'hub.mode' : 'subscribe', + 'hub.callback' : callback, + 'hub.topic' : topic, + 'hub.verify' : ['async', 'sync'], + 'hub.verify_token' : subscription.generate_token('subscribe'), + 'hub.lease_seconds' : lease_seconds, }) if response.status_code == 204: diff --git a/fabfile.py b/fabfile.py index 49df17543..7c8675d61 100644 --- a/fabfile.py +++ b/fabfile.py @@ -114,6 +114,10 @@ def deploy_code(copy_assets=False, full=False): run('kill -HUP `cat logs/gunicorn.pid`') run('curl -s http://%s > /dev/null' % env.host) run('curl -s http://%s/api/add_site_load_script/ABCDEF > /dev/null' % env.host) + +def deploy_node(): + with cd(env.NEWSBLUR_PATH): + run('sudo supervisorctl restart node') def restart_gunicorn(): with cd(env.NEWSBLUR_PATH): diff --git a/media/css/reader.css b/media/css/reader.css index f08150389..5d2255f63 100644 --- a/media/css/reader.css +++ b/media/css/reader.css @@ -3619,7 +3619,20 @@ background: transparent; margin-right: 12px; } - +.NB-module .NB-module-content-account-realtime { + background: transparent url('/media/img/reader/realtime_spinner.gif') no-repeat 0 1px; + font-size: 11px; + text-transform: uppercase; + color: #D8BD70; + font-weight: bold; + float: right; + width: 16px; + height: 16px; + margin: 0 4px 0 0; +} +.NB-module .NB-module-content-account-realtime.NB-error { + background: transparent url('/media/img/reader/realtime_spinner_error.gif') no-repeat 0 1px; +} .NB-module .NB-module-item { position: relative; min-height: 77px; diff --git a/media/img/reader/realtime_spinner.gif b/media/img/reader/realtime_spinner.gif new file mode 100644 index 000000000..5ae91069d Binary files /dev/null and b/media/img/reader/realtime_spinner.gif differ diff --git a/media/img/reader/realtime_spinner_error.gif b/media/img/reader/realtime_spinner_error.gif new file mode 100644 index 000000000..8556e1247 Binary files /dev/null and b/media/img/reader/realtime_spinner_error.gif differ diff --git a/media/js/newsblur/reader.js b/media/js/newsblur/reader.js index ed8e20bfe..c2edae2f1 100644 --- a/media/js/newsblur/reader.js +++ b/media/js/newsblur/reader.js @@ -299,6 +299,10 @@ $('.NB-task-add').tipsy('disable'); $('.NB-task-manage').tipsy('disable'); } + $('.NB-module-content-account-realtime').tipsy({ + gravity: 's', + delayIn: 0 + }); }, save_feed_pane_size: function(w, pane, $pane, state, options, name) { @@ -5257,10 +5261,12 @@ setup_socket_realtime_unread_counts: function(force) { if (!force && NEWSBLUR.Globals.is_anonymous) return; - if (!force && !NEWSBLUR.Globals.is_premium) return; - - if (force || !this.socket) { - this.socket = this.socket || io.connect('http://' + window.location.hostname + ':8888'); + // if (!force && !NEWSBLUR.Globals.is_premium) return; + if (this.socket && !this.socket.socket.connected) { + this.socket.socket.connect(); + } else if (force || !this.socket || !this.socket.socket.connected) { + var server = window.location.protocol + '//' + window.location.hostname + ':8888'; + this.socket = this.socket || io.connect(server); // this.socket.refresh_feeds = _.debounce(_.bind(this.force_feeds_refresh, this), 1000*10); this.socket.on('connect', _.bind(function() { @@ -5273,12 +5279,22 @@ this.flags.feed_refreshing_in_realtime = true; this.setup_feed_refresh(); + $('.NB-module-content-account-realtime').attr('title', 'Updating in real-time').removeClass('NB-error'); }, this)); this.socket.on('disconnect', _.bind(function() { console.log(["Lost connection to real-time pubsub. Falling back to polling."]); + this.flags.feed_refreshing_in_realtime = false; this.setup_feed_refresh(); + $('.NB-module-content-account-realtime').attr('title', 'Polling for updates...').addClass('NB-error'); + }, this)); + this.socket.on('error', _.bind(function() { + console.log(["Can't connect to real-time pubsub."]); + this.flags.feed_refreshing_in_realtime = false; + $('.NB-module-content-account-realtime').attr('title', 'Polling for updates...').addClass('NB-error'); + _.delay(_.bind(this.setup_socket_realtime_unread_counts, this), 60*1000); }, this)); } + }, send_socket_active_feeds: function() { @@ -5309,10 +5325,9 @@ if (feed_count > 500) { refresh_interval *= 1.5; } - if (this.flags['feed_refreshing_in_realtime'] && !this.flags['has_unfetched_feeds']) { - if (this.socket && this.socket.socket.connected) { - refresh_interval *= 20; - } + if (this.flags['feed_refreshing_in_realtime'] && !this.flags['has_unfetched_feeds'] && + this.socket && this.socket.socket.connected) { + refresh_interval *= 20; } if (new_feeds && feed_count < 250) { diff --git a/node/unread_counts.coffee b/node/unread_counts.coffee index d15cd78af..9579ddbea 100644 --- a/node/unread_counts.coffee +++ b/node/unread_counts.coffee @@ -6,7 +6,8 @@ REDIS_SERVER = if process.env.NODE_ENV == 'dev' then 'localhost' else 'db01' client = redis.createClient 6379, REDIS_SERVER io.sockets.on 'connection', (socket) -> - console.log " ---> New connection brings total to #{io.sockets.clients().length} consumers." + console.log " ---> New connection brings total to" + + " #{io.sockets.clients().length} consumers." socket.on 'subscribe:feeds', (feeds, username) -> socket.subscribe?.end() socket.subscribe = redis.createClient 6379, REDIS_SERVER @@ -20,5 +21,6 @@ io.sockets.on 'connection', (socket) -> socket.on 'disconnect', () -> socket.subscribe?.end() - console.log " ---> [] Disconnect, there are now #{io.sockets.clients().length-1} consumers." + console.log " ---> [] Disconnect, there are now" + + " #{io.sockets.clients().length-1} consumers." \ No newline at end of file diff --git a/node/unread_counts.js b/node/unread_counts.js index ef0f3712b..d088cedd6 100644 --- a/node/unread_counts.js +++ b/node/unread_counts.js @@ -12,7 +12,7 @@ client = redis.createClient(6379, REDIS_SERVER); io.sockets.on('connection', function(socket) { - console.log(" ---> New connection brings total to " + (io.sockets.clients().length) + " consumers."); + console.log(" ---> New connection brings total to" + (" " + (io.sockets.clients().length) + " consumers.")); socket.on('subscribe:feeds', function(feeds, username) { var _ref; if ((_ref = socket.subscribe) != null) _ref.end(); @@ -27,7 +27,7 @@ return socket.on('disconnect', function() { var _ref; if ((_ref = socket.subscribe) != null) _ref.end(); - return console.log(" ---> [] Disconnect, there are now " + (io.sockets.clients().length - 1) + " consumers."); + return console.log(" ---> [] Disconnect, there are now" + (" " + (io.sockets.clients().length - 1) + " consumers.")); }); }); diff --git a/templates/reader/feeds.xhtml b/templates/reader/feeds.xhtml index ad192cb36..7ce8dd6e1 100644 --- a/templates/reader/feeds.xhtml +++ b/templates/reader/feeds.xhtml @@ -280,8 +280,9 @@

{% if user.profile.is_premium %} - {{ active_count }} site{{ active_count|pluralize }} + {{ active_count }} site{{ active_count|pluralize }} +
Premium Account {% else %} @@ -292,7 +293,7 @@

{% if user.profile.is_premium %} - + {% else %}