Merge branch 'sictiru' of https://github.com/samuelclay/NewsBlur into sictiru

This commit is contained in:
Andrei 2021-01-01 13:15:19 -08:00
commit fd69353bc8
28 changed files with 247 additions and 182 deletions

View file

@ -29,7 +29,7 @@ def FreshenHomepage():
sub.save()
sub.calculate_feed_scores(silent=True)
@app.task(name='clean_analytics', time_limit=720*10)
@app.task(name='clean-analytics', time_limit=720*10)
def CleanAnalytics():
logging.debug(" ---> Cleaning analytics... %s feed fetches" % (
settings.MONGOANALYTICSDB.nbanalytics.feed_fetches.count(),

View file

@ -1599,6 +1599,14 @@ class MSharedStory(mongo.DynamicDocument):
socialsub.save()
self.delete()
def publish_to_subscribers(self):
try:
r = redis.Redis(connection_pool=settings.REDIS_PUBSUB_POOL)
r.publish("social:%s:story" % (self.user_id), '%s,%s' % (self.story_hash, self.shared_date.strftime('%s')))
logging.debug(" ***> [%-30s] ~BMPublishing to Redis for real-time." % (Feed.get_by_id(self.story_feed_id).title[:30],))
except redis.ConnectionError:
logging.debug(" ***> [%-30s] ~BMRedis is unavailable for real-time." % (Feed.get_by_id(self.story_feed_id).title[:30],))
@classmethod
def feed_quota(cls, user_id, story_hash, feed_id=None, days=1, quota=1):
@ -2763,7 +2771,7 @@ class MSocialServices(mongo.Document):
return
return True
class MInteraction(mongo.Document):
user_id = mongo.IntField()

View file

@ -611,6 +611,7 @@ def mark_story_as_shared(request):
}
try:
shared_story = MSharedStory.objects.create(**story_db)
shared_story.publish_to_subscribers()
except NotUniqueError:
shared_story = MSharedStory.objects.get(story_guid=story_db['story_guid'],
user_id=story_db['user_id'])
@ -667,6 +668,7 @@ def mark_story_as_shared(request):
EmailFirstShare.apply_async(kwargs=dict(user_id=request.user.pk))
if format == 'html':
stories = MSharedStory.attach_users_to_stories(stories, profiles)
return render(request, 'social/social_story.xhtml', {

View file

@ -49,8 +49,8 @@ android {
applicationId "com.newsblur"
minSdkVersion 21
targetSdkVersion 29
versionCode 178
versionName "10.1.3"
versionCode 180
versionName "10.2.1b1"
}
compileOptions.with {
sourceCompatibility = JavaVersion.VERSION_1_8

View file

@ -4995,7 +4995,7 @@
this.socket.on('feed:story:new', _.bind(function(feed_id, message) {
var story_hash = message.split(',')[0];
var timestamp = message.split(',')[1];
// NEWSBLUR.log(['Real-time new story', feed_id, story_hash, timestamp]);
NEWSBLUR.log(['Real-time new story', feed_id, story_hash, timestamp]);
NEWSBLUR.app.dashboard_river.new_story(story_hash, timestamp);
}, this));

View file

@ -248,7 +248,10 @@ NEWSBLUR.log = function(msg) {
}
},
favicon: function(feed, empty_on_missing) {
favicon: function (feed, empty_on_missing) {
var empty_icon = NEWSBLUR.Globals.MEDIA_URL + '/img/icons/circular/world.png';
if (!feed) return empty_icon;
if (_.isNumber(feed)) return NEWSBLUR.URLs.favicon.replace('{id}', feed);
else if (feed.get('favicon') && feed.get('favicon').length && feed.get('favicon').indexOf('data:image/png;base64,') != -1) return feed.get('favicon');
else if (feed.get('favicon') && feed.get('favicon').length) return 'data:image/png;base64,' + feed.get('favicon');
@ -259,7 +262,8 @@ NEWSBLUR.log = function(msg) {
else if (_.isNumber(feed.id)) return NEWSBLUR.URLs.favicon.replace('{id}', feed.id);
else if (feed.get('favicon_url')) return feed.get('favicon_url');
else if (feed.is_starred()) return NEWSBLUR.Globals.MEDIA_URL + '/img/reader/tag.png';
return NEWSBLUR.Globals.MEDIA_URL + '/img/icons/circular/world.png';
return empty_icon;
},
deepCopy: function(obj) {
@ -506,4 +510,4 @@ NEWSBLUR.log = function(msg) {
}));
}
});
})(jQuery);
})(jQuery);

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 2.5.1
(function() {
var DEV, MONGODB_PORT, MONGODB_SERVER, app, log, mongo, server, url;
@ -28,48 +28,44 @@
}
if (DEV) {
url = "mongodb://" + MONGODB_SERVER + ":" + MONGODB_PORT + "/newsblur";
url = `mongodb://${MONGODB_SERVER}:${MONGODB_PORT}/newsblur`;
} else {
url = "mongodb://" + MONGODB_SERVER + ":" + MONGODB_PORT + "/newsblur?replicaSet=nbset&readPreference=secondaryPreferred";
url = `mongodb://${MONGODB_SERVER}:${MONGODB_PORT}/newsblur?replicaSet=nbset&readPreference=secondaryPreferred`;
}
mongo.MongoClient.connect(url, (function(_this) {
return function(err, db) {
log.debug("Connected to " + (db != null ? db.serverConfig.s.host : void 0) + ":" + (db != null ? db.serverConfig.s.port : void 0) + " / " + err);
return _this.collection = db != null ? db.collection("feed_icons") : void 0;
};
})(this));
mongo.MongoClient.connect(url, (err, db) => {
log.debug(`Connected to ${db != null ? db.serverConfig.s.host : void 0}:${db != null ? db.serverConfig.s.port : void 0} / ${err}`);
return this.collection = db != null ? db.collection("feed_icons") : void 0;
});
app.get(/\/rss_feeds\/icon\/(\d+)\/?/, (function(_this) {
return function(req, res) {
var etag, feed_id;
feed_id = parseInt(req.params[0], 10);
etag = req.header('If-None-Match');
log.debug(("Feed: " + feed_id + " ") + (etag ? " / " + etag : ""));
return _this.collection.findOne({
_id: feed_id
}, function(err, docs) {
var body;
if (!err && etag && docs && (docs != null ? docs.color : void 0) === etag) {
log.debug(("Cached: " + feed_id + ", etag: " + etag + "/" + (docs != null ? docs.color : void 0) + " ") + (err ? "(err: " + err + ")" : ""));
return res.sendStatus(304);
} else if (!err && docs && docs.data) {
log.debug(("Req: " + feed_id + ", etag: " + etag + "/" + (docs != null ? docs.color : void 0) + " ") + (err ? "(err: " + err + ")" : ""));
res.header('etag', docs.color);
body = new Buffer(docs.data, 'base64');
res.set("Content-Type", "image/png");
return res.status(200).send(body);
app.get(/\/rss_feeds\/icon\/(\d+)\/?/, (req, res) => {
var etag, feed_id;
feed_id = parseInt(req.params[0], 10);
etag = req.header('If-None-Match');
log.debug(`Feed: ${feed_id} ` + (etag ? ` / ${etag}` : ""));
return this.collection.findOne({
_id: feed_id
}, function(err, docs) {
var body;
if (!err && etag && docs && (docs != null ? docs.color : void 0) === etag) {
log.debug(`Cached: ${feed_id}, etag: ${etag}/${docs != null ? docs.color : void 0} ` + (err ? `(err: ${err})` : ""));
return res.sendStatus(304);
} else if (!err && docs && docs.data) {
log.debug(`Req: ${feed_id}, etag: ${etag}/${docs != null ? docs.color : void 0} ` + (err ? `(err: ${err})` : ""));
res.header('etag', docs.color);
body = new Buffer(docs.data, 'base64');
res.set("Content-Type", "image/png");
return res.status(200).send(body);
} else {
log.debug(`Redirect: ${feed_id}, etag: ${etag}/${docs != null ? docs.color : void 0} ` + (err ? `(err: ${err})` : ""));
if (DEV) {
return res.redirect('/media/img/icons/circular/world.png');
} else {
log.debug(("Redirect: " + feed_id + ", etag: " + etag + "/" + (docs != null ? docs.color : void 0) + " ") + (err ? "(err: " + err + ")" : ""));
if (DEV) {
return res.redirect('/media/img/icons/circular/world.png');
} else {
return res.redirect('https://www.newsblur.com/media/img/icons/circular/world.png');
}
return res.redirect('https://www.newsblur.com/media/img/icons/circular/world.png');
}
});
};
})(this));
}
});
});
app.listen(3030);

View file

@ -1,17 +1,17 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 2.5.1
(function() {
var debug, info;
info = function(username, message) {
var timestamp;
timestamp = new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '');
return console.log("[" + timestamp + "] ---> [" + username + "] " + message);
return console.log(`[${timestamp}] ---> [${username}] ${message}`);
};
debug = function(message) {
var timestamp;
timestamp = new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '');
return console.log("[" + timestamp + "] ---> " + message);
return console.log(`[${timestamp}] ---> ${message}`);
};
exports.info = info;

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 2.5.1
(function() {
var DB_PATH, DEV, app, busboy, fs, mkdirp, path, server, splitFeedId;
@ -22,69 +22,67 @@
app.use(busboy());
app.get(/^\/original_page\/(\d+)\/?/, (function(_this) {
return function(req, res) {
var etag, feedId, feedIdDir, filePath, lastModified;
feedId = parseInt(req.params[0], 10);
etag = req.header('If-None-Match');
lastModified = req.header('If-Modified-Since');
feedIdDir = splitFeedId(feedId);
filePath = "" + DB_PATH + "/" + feedIdDir + ".zhtml";
return fs.exists(filePath, function(exists, err) {
console.log((" ---> Loading: " + feedId + " (" + filePath + "). ") + ("" + (exists ? "" : "NOT FOUND")));
if (!exists) {
return res.send(404);
app.get(/^\/original_page\/(\d+)\/?/, (req, res) => {
var etag, feedId, feedIdDir, filePath, lastModified;
feedId = parseInt(req.params[0], 10);
etag = req.header('If-None-Match');
lastModified = req.header('If-Modified-Since');
feedIdDir = splitFeedId(feedId);
filePath = `${DB_PATH}/${feedIdDir}.zhtml`;
return fs.exists(filePath, function(exists, err) {
console.log(` ---> Loading: ${feedId} (${filePath}). ` + `${exists ? "" : "NOT FOUND"}`);
if (!exists) {
return res.send(404);
}
return fs.stat(filePath, function(err, stats) {
if (!err && etag && stats.mtime === etag) {
return res.send(304);
}
return fs.stat(filePath, function(err, stats) {
if (!err && etag && stats.mtime === etag) {
return res.send(304);
}
if (!err && lastModified && stats.mtime === lastModified) {
return res.send(304);
}
return fs.readFile(filePath, function(err, content) {
res.header('Etag', Date.parse(stats.mtime));
return res.send(content);
});
if (!err && lastModified && stats.mtime === lastModified) {
return res.send(304);
}
return fs.readFile(filePath, function(err, content) {
res.header('Etag', Date.parse(stats.mtime));
return res.send(content);
});
});
};
})(this));
});
});
app.post(/^\/original_page\/(\d+)\/?/, (function(_this) {
return function(req, res) {
var feedId, feedIdDir;
feedId = parseInt(req.params[0], 10);
feedIdDir = splitFeedId(feedId);
req.pipe(req.busboy);
return req.busboy.on('file', function(fieldname, file, filename) {
var filePath, filePathDir;
filePath = "" + DB_PATH + "/" + feedIdDir + ".zhtml";
filePathDir = path.dirname(filePath);
return mkdirp(filePathDir, function(err) {
var fstream;
if (err) {
console.log(err);
}
fstream = fs.createWriteStream(filePath);
file.pipe(fstream);
return fstream.on('close', function() {
return fs.stat(filePath, function(err, stats) {
if (err) {
console.log(err);
}
console.log(" ---> Saving: " + feedId + " (" + filePath + ") " + stats.size + " bytes");
return res.send("OK");
});
app.post(/^\/original_page\/(\d+)\/?/, (req, res) => {
var feedId, feedIdDir;
feedId = parseInt(req.params[0], 10);
feedIdDir = splitFeedId(feedId);
req.pipe(req.busboy);
return req.busboy.on('file', function(fieldname, file, filename) {
var filePath, filePathDir;
// console.log "Uploading #{fieldname} / #{file} / #{filename}"
filePath = `${DB_PATH}/${feedIdDir}.zhtml`;
filePathDir = path.dirname(filePath);
return mkdirp(filePathDir, function(err) {
var fstream;
if (err) {
console.log(err);
}
fstream = fs.createWriteStream(filePath);
file.pipe(fstream);
return fstream.on('close', function() {
return fs.stat(filePath, function(err, stats) {
if (err) {
console.log(err);
}
console.log(` ---> Saving: ${feedId} (${filePath}) ${stats.size} bytes`);
return res.send("OK");
});
});
});
};
})(this));
});
});
splitFeedId = function(feedId) {
var rgx;
feedId += '';
// x2 = if feedId.length > 1 then '.' + feedId[1] else ''
rgx = /(\d+)(\d{3})/;
while (rgx.test(feedId)) {
feedId = feedId.replace(rgx, '$1' + '/' + '$2');
@ -92,6 +90,6 @@
return feedId;
};
console.log(" ---> Starting Original Page server " + (DEV ? "on DEV" : "in production"));
console.log(` ---> Starting Original Page server ${DEV ? "on DEV" : "in production"}`);
}).call(this);

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 2.5.1
(function() {
var DEV, Mercury, app, log, server;
@ -23,33 +23,31 @@
log.debug("Running as production server");
}
app.get(/\/rss_feeds\/original_text_fetcher\/?/, (function(_this) {
return function(req, res) {
var api_key, url;
res.setHeader('Content-Type', 'application/json');
if (req.query.test) {
return res.end("OK");
}
url = req.query.url;
if (!url) {
log.debug("Missing url");
return res.end(JSON.stringify({
error: "Missing `url` query parameter."
}));
}
api_key = req.header('x-api-key') || req.query.apikey;
if (!DEV && (!api_key || api_key.indexOf("djtXZrSIEfDa3Dex9FQ9AR") === -1)) {
log.debug("Mismatched API key: " + url + " / " + api_key);
return res.end(JSON.stringify({
error: "Invalid API key. You need to set up your own Original Text server."
}));
}
return Mercury.parse(url).then(function(result) {
log.debug("Fetched: " + url);
return res.end(JSON.stringify(result));
});
};
})(this));
app.get(/\/rss_feeds\/original_text_fetcher\/?/, (req, res) => {
var api_key, url;
res.setHeader('Content-Type', 'application/json');
if (req.query.test) {
return res.end("OK");
}
url = req.query.url;
if (!url) {
log.debug("Missing url");
return res.end(JSON.stringify({
error: "Missing `url` query parameter."
}));
}
api_key = req.header('x-api-key') || req.query.apikey;
if (!DEV && (!api_key || api_key.indexOf("djtXZrSIEfDa3Dex9FQ9AR") === -1)) {
log.debug(`Mismatched API key: ${url} / ${api_key}`);
return res.end(JSON.stringify({
error: "Invalid API key. You need to set up your own Original Text server."
}));
}
return Mercury.parse(url).then((result) => {
log.debug(`Fetched: ${url}`);
return res.end(JSON.stringify(result));
});
});
app.listen(4040);

View file

@ -53,8 +53,8 @@ else
io.on 'connection', (socket) ->
ip = socket.handshake.headers['X-Forwarded-For'] || socket.handshake.address
socket.on 'subscribe:feeds', (@feeds, @username) ->
log.info @username, "Connecting (#{feeds.length} feeds, #{ip})," +
socket.on 'subscribe:feeds', (@feeds, @username) =>
log.info @username, "Connecting (#{@feeds.length} feeds, #{ip})," +
" (#{io.engine.clientsCount} connected) " +
" #{if SECURE then "(SSL)" else "(non-SSL)"}"
@ -86,7 +86,7 @@ io.on 'connection', (socket) ->
else
socket.emit 'feed:update', channel, message
socket.on 'disconnect', () ->
socket.on 'disconnect', () =>
socket.subscribe?.quit()
log.info @username, "Disconnect (#{@feeds?.length} feeds, #{ip})," +
" there are now #{io.engine.clientsCount} users. " +

View file

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.8.0
// Generated by CoffeeScript 2.5.1
(function() {
var DEV, REDIS_SERVER, SECURE, app, certificate, fs, io, log, options, privateKey, redis;
@ -14,6 +14,12 @@
SECURE = !!process.env.NODE_SSL;
// client = redis.createClient 6379, REDIS_SERVER
// RedisStore = require 'socket.io/lib/stores/redis'
// rpub = redis.createClient 6379, REDIS_SERVER
// rsub = redis.createClient 6379, REDIS_SERVER
// rclient = redis.createClient 6379, REDIS_SERVER
log.debug("Starting NewsBlur unread count server...");
if (!DEV && !process.env.NODE_ENV) {
@ -28,6 +34,7 @@
if (SECURE) {
privateKey = fs.readFileSync('/srv/newsblur/config/certificates/newsblur.com.key').toString();
certificate = fs.readFileSync('/srv/newsblur/config/certificates/newsblur.com.crt').toString();
// ca = fs.readFileSync('./config/certificates/intermediate.crt').toString()
options = {
port: 8889,
key: privateKey,
@ -38,7 +45,7 @@
path: "/v2/socket.io"
});
app.listen(options.port);
log.debug("Listening securely on port " + options.port);
log.debug(`Listening securely on port ${options.port}`);
} else {
options = {
port: 8888
@ -48,70 +55,70 @@
path: "/v2/socket.io"
});
app.listen(options.port);
log.debug("Listening on port " + options.port);
log.debug(`Listening on port ${options.port}`);
}
// io.set('transports', ['websocket'])
// io.set 'store', new RedisStore
// redisPub : rpub
// redisSub : rsub
// redisClient : rclient
io.on('connection', function(socket) {
var ip;
ip = socket.handshake.headers['X-Forwarded-For'] || socket.handshake.address;
socket.on('subscribe:feeds', function(feeds, username) {
var _ref;
socket.on('subscribe:feeds', (feeds, username) => {
var ref;
this.feeds = feeds;
this.username = username;
log.info(this.username, ("Connecting (" + feeds.length + " feeds, " + ip + "),") + (" (" + io.engine.clientsCount + " connected) ") + (" " + (SECURE ? "(SSL)" : "(non-SSL)")));
log.info(this.username, `Connecting (${this.feeds.length} feeds, ${ip}),` + ` (${io.engine.clientsCount} connected) ` + ` ${SECURE ? "(SSL)" : "(non-SSL)"}`);
if (!this.username) {
return;
}
socket.on("error", function(err) {
return log.debug("Error (socket): " + err);
return log.debug(`Error (socket): ${err}`);
});
if ((_ref = socket.subscribe) != null) {
_ref.quit();
if ((ref = socket.subscribe) != null) {
ref.quit();
}
socket.subscribe = redis.createClient(6379, REDIS_SERVER);
socket.subscribe.on("error", (function(_this) {
return function(err) {
var _ref1;
log.info(_this.username, "Error: " + err + " (" + _this.feeds.length + " feeds)");
return (_ref1 = socket.subscribe) != null ? _ref1.quit() : void 0;
};
})(this));
socket.subscribe.on("connect", (function(_this) {
return function() {
var feeds_story;
log.info(_this.username, ("Connected (" + _this.feeds.length + " feeds, " + ip + "),") + (" (" + io.engine.clientsCount + " connected) ") + (" " + (SECURE ? "(SSL)" : "(non-SSL)")));
socket.subscribe.subscribe(_this.feeds);
feeds_story = _this.feeds.map(function(f) {
return "" + f + ":story";
});
socket.subscribe.subscribe(feeds_story);
return socket.subscribe.subscribe(_this.username);
};
})(this));
return socket.subscribe.on('message', (function(_this) {
return function(channel, message) {
log.info(_this.username, "Update on " + channel + ": " + message);
if (channel === _this.username) {
return socket.emit('user:update', channel, message);
} else if (channel.indexOf(':story') >= 0) {
return socket.emit('feed:story:new', channel, message);
} else {
return socket.emit('feed:update', channel, message);
}
};
})(this));
socket.subscribe.on("error", (err) => {
var ref1;
log.info(this.username, `Error: ${err} (${this.feeds.length} feeds)`);
return (ref1 = socket.subscribe) != null ? ref1.quit() : void 0;
});
socket.subscribe.on("connect", () => {
var feeds_story;
log.info(this.username, `Connected (${this.feeds.length} feeds, ${ip}),` + ` (${io.engine.clientsCount} connected) ` + ` ${SECURE ? "(SSL)" : "(non-SSL)"}`);
socket.subscribe.subscribe(this.feeds);
feeds_story = this.feeds.map(function(f) {
return `${f}:story`;
});
socket.subscribe.subscribe(feeds_story);
return socket.subscribe.subscribe(this.username);
});
return socket.subscribe.on('message', (channel, message) => {
log.info(this.username, `Update on ${channel}: ${message}`);
if (channel === this.username) {
return socket.emit('user:update', channel, message);
} else if (channel.indexOf(':story') >= 0) {
return socket.emit('feed:story:new', channel, message);
} else {
return socket.emit('feed:update', channel, message);
}
});
});
return socket.on('disconnect', function() {
var _ref, _ref1;
if ((_ref = socket.subscribe) != null) {
_ref.quit();
return socket.on('disconnect', () => {
var ref, ref1;
if ((ref = socket.subscribe) != null) {
ref.quit();
}
return log.info(this.username, ("Disconnect (" + ((_ref1 = this.feeds) != null ? _ref1.length : void 0) + " feeds, " + ip + "),") + (" there are now " + io.engine.clientsCount + " users. ") + (" " + (SECURE ? "(SSL)" : "(non-SSL)")));
return log.info(this.username, `Disconnect (${(ref1 = this.feeds) != null ? ref1.length : void 0} feeds, ${ip}),` + ` there are now ${io.engine.clientsCount} users. ` + ` ${SECURE ? "(SSL)" : "(non-SSL)"}`);
});
});
io.sockets.on('error', function(err) {
return log.debug("Error (sockets): " + err);
return log.debug(`Error (sockets): ${err}`);
});
}).call(this);

View file

@ -1,6 +1,8 @@
#!/srv/newsblur/venv/newsblur/bin/python
from utils.munin.base import MuninGraph
import datetime
import os
os.environ["DJANGO_SETTINGS_MODULE"] = "newsblur.settings"
from django.conf import settings

View file

@ -27,6 +27,8 @@ class NBMuninGraph(MuninGraph):
@property
def stats(self):
import datetime
import os
os.environ["DJANGO_SETTINGS_MODULE"] = "newsblur.settings"
from django.conf import settings
stats = settings.MONGOANALYTICSDB.nbanalytics.page_loads.aggregate([{

View file

@ -1,6 +1,10 @@
#!/srv/newsblur/venv/newsblur/bin/python
from utils.munin.base import MuninGraph
import os
os.environ["DJANGO_SETTINGS_MODULE"] = "newsblur.settings"
import django
django.setup()
class NBMuninGraph(MuninGraph):

View file

@ -1,5 +1,9 @@
#!/srv/newsblur/venv/newsblur/bin/python
from utils.munin.base import MuninGraph
import os
os.environ["DJANGO_SETTINGS_MODULE"] = "newsblur.settings"
import django
django.setup()
class NBMuninGraph(MuninGraph):

View file

@ -1,6 +1,10 @@
#!/srv/newsblur/venv/newsblur/bin/python
from utils.munin.base import MuninGraph
import os
os.environ["DJANGO_SETTINGS_MODULE"] = "newsblur.settings"
import django
django.setup()
class NBMuninGraph(MuninGraph):

View file

@ -1,6 +1,10 @@
#!/srv/newsblur/venv/newsblur/bin/python
from utils.munin.base import MuninGraph
import redis
import os
os.environ["DJANGO_SETTINGS_MODULE"] = "newsblur.settings"
import django
django.setup()
class NBMuninGraph(MuninGraph):

View file

@ -1,5 +1,9 @@
#!/srv/newsblur/venv/newsblur/bin/python
from utils.munin.base import MuninGraph
import os
os.environ["DJANGO_SETTINGS_MODULE"] = "newsblur.settings"
import django
django.setup()
class NBMuninGraph(MuninGraph):

View file

@ -1,5 +1,9 @@
#!/srv/newsblur/venv/newsblur/bin/python
from utils.munin.base import MuninGraph
import os
os.environ["DJANGO_SETTINGS_MODULE"] = "newsblur.settings"
import django
django.setup()
class NBMuninGraph(MuninGraph):

View file

@ -1,5 +1,9 @@
#!/srv/newsblur/venv/newsblur/bin/python
from utils.munin.base import MuninGraph
import os
os.environ["DJANGO_SETTINGS_MODULE"] = "newsblur.settings"
import django
django.setup()
class NBMuninGraph(MuninGraph):

View file

@ -1,5 +1,7 @@
#!/srv/newsblur/venv/newsblur/bin/python
from utils.munin.base import MuninGraph
import os
os.environ["DJANGO_SETTINGS_MODULE"] = "newsblur.settings"
class NBMuninGraph(MuninGraph):

View file

@ -1,5 +1,9 @@
#!/srv/newsblur/venv/newsblur/bin/python
from utils.munin.base import MuninGraph
import os
os.environ["DJANGO_SETTINGS_MODULE"] = "newsblur.settings"
import django
django.setup()
class NBMuninGraph(MuninGraph):

View file

@ -1,6 +1,8 @@
#!/srv/newsblur/venv/newsblur/bin/python
from utils.munin.base import MuninGraph
import datetime
import os
os.environ["DJANGO_SETTINGS_MODULE"] = "newsblur.settings"
from django.conf import settings

View file

@ -1,5 +1,9 @@
#!/srv/newsblur/venv/newsblur/bin/python
from utils.munin.base import MuninGraph
import os
os.environ["DJANGO_SETTINGS_MODULE"] = "newsblur.settings"
import django
django.setup()
class NBMuninGraph(MuninGraph):

View file

@ -1,6 +1,10 @@
#!/srv/newsblur/venv/newsblur/bin/python
import redis
from utils.munin.base import MuninGraph
import os
os.environ["DJANGO_SETTINGS_MODULE"] = "newsblur.settings"
import django
django.setup()
class NBMuninGraph(MuninGraph):

View file

@ -1,6 +1,9 @@
#!/srv/newsblur/venv/newsblur/bin/python
from utils.munin.base import MuninGraph
import os
os.environ["DJANGO_SETTINGS_MODULE"] = "newsblur.settings"
import django
django.setup()
class NBMuninGraph(MuninGraph):

View file

@ -1,12 +1,13 @@
from django.conf import settings
from django import template
from django.utils.safestring import mark_safe
register = template.Library()
@register.simple_tag
def include_bookmarklet_js():
return settings.JAMMIT.render_code('javascripts', 'bookmarklet')
return mark_safe(settings.JAMMIT.render_code('javascripts', 'bookmarklet'))
@register.simple_tag
def include_bookmarklet_css():
return settings.JAMMIT.render_code('stylesheets', 'bookmarklet')
return mark_safe(settings.JAMMIT.render_code('stylesheets', 'bookmarklet'))