mirror of
https://github.com/viq/NewsBlur.git
synced 2025-09-18 21:43:31 +00:00
Merge branch 'master' into dashboard_tweaks
This commit is contained in:
commit
bc68345cc4
5 changed files with 105 additions and 34 deletions
|
@ -5,6 +5,7 @@ import re
|
|||
import mongoengine as mongo
|
||||
import zlib
|
||||
import urllib
|
||||
from pprint import pprint
|
||||
from collections import defaultdict
|
||||
from operator import itemgetter
|
||||
from BeautifulSoup import BeautifulStoneSoup
|
||||
|
@ -13,6 +14,7 @@ from django.db import models
|
|||
from django.db import IntegrityError
|
||||
from django.core.cache import cache
|
||||
from django.conf import settings
|
||||
from django.core.mail import mail_admins
|
||||
from mongoengine.queryset import OperationError
|
||||
from mongoengine.base import ValidationError
|
||||
from apps.rss_feeds.tasks import UpdateFeeds
|
||||
|
@ -195,6 +197,12 @@ class Feed(models.Model):
|
|||
feed_address = feed_address_from_link
|
||||
|
||||
if feed_address:
|
||||
if feed_address.endswith('feedburner.com/atom.xml'):
|
||||
message = """
|
||||
%s - %s
|
||||
""" % (feed_address, pprint(self.feed.__dict__))
|
||||
mail_admins('Wierdo alert', message, fail_silently=True)
|
||||
return False
|
||||
try:
|
||||
self.feed_address = feed_address
|
||||
self.next_scheduled_update = datetime.datetime.utcnow()
|
||||
|
@ -696,31 +704,32 @@ class Feed(models.Model):
|
|||
return self.min_to_decay, random_factor
|
||||
|
||||
# Use stories per month to calculate next feed update
|
||||
updates_per_day = self.stories_last_month / 30.0
|
||||
updates_per_month = self.stories_last_month
|
||||
# if updates_per_day < 1 and self.num_subscribers > 2:
|
||||
# updates_per_day = 1
|
||||
# 0 updates per day = 24 hours
|
||||
# 1 subscriber:
|
||||
# 1 update per day = 6 hours
|
||||
# 2 updates = 3.5 hours
|
||||
# 4 updates = 2 hours
|
||||
# 10 updates = 1 hour
|
||||
# 0 updates per month = 4 hours
|
||||
# 1 update = 2 hours
|
||||
# 2 updates = 1.5 hours
|
||||
# 4 updates = 1 hours
|
||||
# 10 updates = .5 hour
|
||||
# 2 subscribers:
|
||||
# 1 update per day = 4.5 hours
|
||||
# 10 updates = 55 minutes
|
||||
updates_per_day_delay = 3 * 60 / max(.25, ((max(0, self.active_subscribers)**.20)
|
||||
* (updates_per_day**1.5)))
|
||||
# 1 update per day = 1 hours
|
||||
# 10 updates = 20 minutes
|
||||
updates_per_day_delay = 2 * 60 / max(.25, ((max(0, self.active_subscribers)**.15)
|
||||
* (updates_per_month**1.5)))
|
||||
if self.premium_subscribers > 0:
|
||||
updates_per_day_delay /= 6
|
||||
updates_per_day_delay /= 5
|
||||
# Lots of subscribers = lots of updates
|
||||
# 144 hours for 0 subscribers.
|
||||
# 24 hours for 1 subscriber.
|
||||
# 7 hours for 2 subscribers.
|
||||
# 3 hours for 3 subscribers.
|
||||
# 25 min for 10 subscribers.
|
||||
# 24 hours for 0 subscribers.
|
||||
# 4 hours for 1 subscriber.
|
||||
# .5 hours for 2 subscribers.
|
||||
# .25 hours for 3 subscribers.
|
||||
# 1 min for 10 subscribers.
|
||||
subscriber_bonus = 4 * 60 / max(.167, max(0, self.active_subscribers)**3)
|
||||
if self.premium_subscribers > 0:
|
||||
subscriber_bonus /= 6
|
||||
subscriber_bonus /= 5
|
||||
|
||||
slow_punishment = 0
|
||||
if self.num_subscribers <= 1:
|
||||
|
@ -730,7 +739,7 @@ class Feed(models.Model):
|
|||
slow_punishment = 2 * self.last_load_time
|
||||
elif self.last_load_time >= 200:
|
||||
slow_punishment = 6 * self.last_load_time
|
||||
total = max(6, int(updates_per_day_delay + subscriber_bonus + slow_punishment))
|
||||
total = max(4, int(updates_per_day_delay + subscriber_bonus + slow_punishment))
|
||||
# print "[%s] %s (%s-%s), %s, %s: %s" % (self, updates_per_day_delay, updates_per_day, self.num_subscribers, subscriber_bonus, slow_punishment, total)
|
||||
random_factor = random.randint(0, total) / 4
|
||||
|
||||
|
|
7
config/ssh.conf
Normal file
7
config/ssh.conf
Normal file
|
@ -0,0 +1,7 @@
|
|||
AddressFamily inet
|
||||
TCPKeepAlive=yes
|
||||
ServerAliveInterval=15
|
||||
ServerAliveCountMax=6
|
||||
StrictHostKeyChecking=no
|
||||
Compression=yes
|
||||
ForwardAgent=yes
|
19
fabfile.py
vendored
19
fabfile.py
vendored
|
@ -16,6 +16,7 @@ from django.conf import settings as django_settings
|
|||
env.user = 'sclay'
|
||||
env.roledefs ={
|
||||
'app': ['app01.newsblur.com'],
|
||||
'web': ['www.newsblur.com'],
|
||||
'db': ['db01.newsblur.com', 'db02.newsblur.com', 'db03.newsblur.com'],
|
||||
'task': ['task01.newsblur.com', 'task02.newsblur.com'],
|
||||
}
|
||||
|
@ -26,6 +27,8 @@ env.roledefs ={
|
|||
|
||||
def app():
|
||||
env.roles = ['app']
|
||||
def web():
|
||||
env.roles = ['web']
|
||||
def db():
|
||||
env.roles = ['db']
|
||||
def task():
|
||||
|
@ -35,26 +38,33 @@ def task():
|
|||
# = Deploy =
|
||||
# ==========
|
||||
|
||||
@roles('app')
|
||||
@roles('web')
|
||||
def deploy():
|
||||
with cd('~/newsblur'):
|
||||
run('git pull')
|
||||
run('kill -HUP `cat logs/gunicorn.pid`')
|
||||
run('curl -s http://www.newsblur.com > /dev/null')
|
||||
with cd('media/js'):
|
||||
run('rm *.gz')
|
||||
run('for js in *-compressed-*.js; do gzip -9 $js -c > $js.gz; done;')
|
||||
with cd('media/css'):
|
||||
run('rm *.gz')
|
||||
run('for css in *-compressed-*.css; do gzip -9 $css -c > $css.gz; done;')
|
||||
|
||||
@roles('app')
|
||||
@roles('web')
|
||||
def deploy_full():
|
||||
with cd('~/newsblur'):
|
||||
run('git pull')
|
||||
run('./manage.py migrate')
|
||||
run('sudo supervisorctl restart gunicorn')
|
||||
|
||||
@roles('app')
|
||||
@roles('web')
|
||||
def staging():
|
||||
with cd('~/staging'):
|
||||
run('git pull')
|
||||
run('kill -HUP `cat /var/run/gunicorn/gunicorn_staging.pid`')
|
||||
|
||||
@roles('app')
|
||||
@roles('web')
|
||||
def staging_full():
|
||||
with cd('~/staging'):
|
||||
run('git pull')
|
||||
|
@ -177,6 +187,7 @@ def setup_local_files():
|
|||
put("config/toprc", "./.toprc")
|
||||
put("config/zshrc", "./.zshrc")
|
||||
put('config/gitconfig.txt', './.gitconfig')
|
||||
put('config/ssh.conf', './.ssh/config')
|
||||
|
||||
def setup_libxml():
|
||||
sudo('apt-get -y install libxml2-dev libxslt1-dev python-lxml')
|
||||
|
|
|
@ -1004,6 +1004,34 @@ background: transparent;
|
|||
background-color: #00609f;
|
||||
}
|
||||
|
||||
#story_titles .NB-feedbar .feed .NB-feedlist-manage-icon {
|
||||
opacity: 0;
|
||||
display: none;
|
||||
position: absolute;
|
||||
left: 4px;
|
||||
top: 0px;
|
||||
width: 20px;
|
||||
height: 22px;
|
||||
cursor: pointer;
|
||||
background: transparent url('../img/icons/silk/bullet_arrow_right.png') no-repeat 3px 4px;
|
||||
}
|
||||
|
||||
#story_titles .NB-feedbar .feed:hover .NB-feedlist-manage-icon {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#story_titles .NB-feedbar .feed:hover .feed_favicon {
|
||||
display: none;
|
||||
}
|
||||
#story_titles .NB-feedbar .folder_title .NB-feedlist-manage-icon {
|
||||
background-position: 3px 5px;
|
||||
}
|
||||
|
||||
#story_titles .NB-feedbar .feed .NB-feedlist-manage-icon:hover {
|
||||
background: transparent url('../img/icons/silk/bullet_arrow_up.png') no-repeat 3px 4px;
|
||||
}
|
||||
|
||||
#story_titles .NB-feedbar .feed .feed_counts {
|
||||
width: 200px;
|
||||
position: absolute;
|
||||
|
|
|
@ -272,7 +272,10 @@
|
|||
this.locks.iframe_buster_buster = setInterval(function() {
|
||||
if (prevent_bust > 0) {
|
||||
prevent_bust -= 2;
|
||||
if (!self.flags['iframe_view_loaded'] && !self.flags['iframe_view_not_busting'] && self.story_view == 'page' && self.active_feed) {
|
||||
if (!self.flags['iframe_view_loaded'] &&
|
||||
!self.flags['iframe_view_not_busting'] &&
|
||||
_.contains(['page', 'story'], self.story_view) &&
|
||||
self.active_feed) {
|
||||
$('.task_view_feed').click();
|
||||
$('.NB-feed-frame').attr('src', '');
|
||||
window.top.location = '/reader/buster';
|
||||
|
@ -2713,14 +2716,14 @@
|
|||
}, 1000);
|
||||
},
|
||||
|
||||
load_page_of_feed_stories: function() {
|
||||
load_page_of_feed_stories: function(hide_loading) {
|
||||
var $story_titles = this.$s.$story_titles;
|
||||
var feed_id = $story_titles.data('feed_id');
|
||||
var page = $story_titles.data('page');
|
||||
|
||||
if (!this.flags['opening_feed']) {
|
||||
|
||||
this.show_feedbar_loading();
|
||||
|
||||
if (!hide_loading) this.show_feedbar_loading();
|
||||
$story_titles.data('page', page+1);
|
||||
if (this.active_feed == 'starred') {
|
||||
this.model.fetch_starred_stories(page+1,
|
||||
|
@ -2743,10 +2746,10 @@
|
|||
if (!$feedbar.length &&
|
||||
($last.length == 0 ||
|
||||
($('#story_titles').scrollTop() == 0 &&
|
||||
$last.position().top + $last.height() < container_height))) {
|
||||
if (this.counts['page_fill_outs'] < 8) {
|
||||
$last.position().top + $last.height() + 13 < container_height))) {
|
||||
if (this.counts['page_fill_outs'] < 6) {
|
||||
this.counts['page_fill_outs'] += 1;
|
||||
_.delay(_.bind(this.load_page_of_feed_stories, this), 250);
|
||||
_.delay(_.bind(this.load_page_of_feed_stories, this, true), 250);
|
||||
} else {
|
||||
this.append_story_titles_endbar();
|
||||
}
|
||||
|
@ -3760,8 +3763,12 @@
|
|||
return $manage_menu;
|
||||
},
|
||||
|
||||
show_manage_menu: function(type, $item) {
|
||||
show_manage_menu: function(type, $item, options) {
|
||||
var self = this;
|
||||
var options = _.extend({
|
||||
'toplevel': false,
|
||||
'inverse': false
|
||||
}, options);
|
||||
var $manage_menu_container = $('.NB-menu-manage-container');
|
||||
// NEWSBLUR.log(['show_manage_menu', type, $item, $manage_menu_container.data('item'), $item && $item[0] == $manage_menu_container.data('item')]);
|
||||
clearTimeout(this.flags.closed_manage_menu);
|
||||
|
@ -3784,10 +3791,10 @@
|
|||
var feed_id, inverse, story_id;
|
||||
if (type == 'folder') {
|
||||
feed_id = $('.folder_title_text', $item).eq(0).text();
|
||||
inverse = $('.folder_title', $item).hasClass("NB-hover-inverse");
|
||||
inverse = options.inverse || $('.folder_title', $item).hasClass("NB-hover-inverse");
|
||||
} else if (type == 'feed') {
|
||||
feed_id = $item && parseInt($item.attr('data-id'), 10);
|
||||
inverse = $item.hasClass("NB-hover-inverse");
|
||||
inverse = options.inverse || $item.hasClass("NB-hover-inverse");
|
||||
} else if (type == 'story') {
|
||||
story_id = $item.data('story_id') || $item.closest('.NB-feed-story').data('story_id');
|
||||
if ($item.hasClass('story')) inverse = true;
|
||||
|
@ -3795,7 +3802,7 @@
|
|||
$('.NB-task-manage').tipsy('hide');
|
||||
$('.NB-task-manage').tipsy('disable');
|
||||
}
|
||||
var toplevel = $item.hasClass("NB-toplevel") ||
|
||||
var toplevel = options.toplevel || $item.hasClass("NB-toplevel") ||
|
||||
$item.children('.folder_title').hasClass("NB-toplevel");
|
||||
var $manage_menu = this.make_manage_menu(type, feed_id, story_id, inverse, $item);
|
||||
$manage_menu_container.empty().append($manage_menu);
|
||||
|
@ -4951,6 +4958,15 @@
|
|||
self.collapse_folder($folder);
|
||||
}
|
||||
});
|
||||
|
||||
// ============
|
||||
// = Feed Bar =
|
||||
// ============
|
||||
|
||||
$.targetIs(e, { tagSelector: '.NB-feedbar .NB-feedlist-manage-icon' }, function($t, $p) {
|
||||
e.preventDefault();
|
||||
self.show_manage_menu('feed', $t.closest('.feed'), {inverse: true, toplevel: true});
|
||||
});
|
||||
$.targetIs(e, { tagSelector: '.NB-feedbar-mark-feed-read' }, function($t, $p){
|
||||
e.preventDefault();
|
||||
var feed_id = parseInt($t.closest('.feed').attr('data-id'), 10);
|
||||
|
@ -5474,8 +5490,8 @@
|
|||
var scroll_y = $('#story_titles').scrollTop();
|
||||
// NEWSBLUR.log(['Story_titles Scroll', full_height, container_offset, visible_height, scroll_y]);
|
||||
|
||||
// Fudge factor is simply because it looks better at 3 pixels off.
|
||||
if ((visible_height + 3) >= full_height) {
|
||||
// Fudge factor is simply because it looks better at 13 pixels off.
|
||||
if ((visible_height + 13) >= full_height) {
|
||||
this.load_page_of_feed_stories();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue