From 8a26285c885733c58f9e56a3c2b4825c91068f7b Mon Sep 17 00:00:00 2001 From: j Date: Wed, 2 Dec 2015 22:05:23 +0100 Subject: [PATCH] better online/offline status handling --- oml/downloads.py | 12 ++++++------ oml/item/models.py | 5 ++++- oml/localnodes.py | 1 + oml/nodes.py | 40 ++++++++++++++++++++++++++++++---------- oml/server.py | 17 ++++------------- oml/tor.py | 5 +++-- oml/utils.py | 13 +++++++++++++ oml/websocket.py | 8 ++++++++ static/js/folders.js | 7 ++++++- static/js/statusIcon.js | 12 ++++++++---- static/js/utils.js | 12 +++++++++--- 11 files changed, 92 insertions(+), 40 deletions(-) diff --git a/oml/downloads.py b/oml/downloads.py index 5414a45..5169985 100644 --- a/oml/downloads.py +++ b/oml/downloads.py @@ -74,12 +74,12 @@ class ScrapeThread(Thread): return True logger.debug('scrape %s', s.item) try: - s.item.scrape() - for f in s.item.files: - f.move() - s.item.update_icons() - s.remove() - trigger_event('change', {}) + if s.item.scrape(): + for f in s.item.files: + f.move() + s.item.update_icons() + s.remove() + trigger_event('change', {}) scraped = True except: logger.debug('scrape failed %s', s.item, exc_info=1) diff --git a/oml/item/models.py b/oml/item/models.py index 7383cbf..9270a5f 100644 --- a/oml/item/models.py +++ b/oml/item/models.py @@ -353,7 +353,10 @@ class Item(db.Model): m['primaryid'] = primaryid self.meta = m self.modified = datetime.utcnow() - self.update() + self.update() + return True + return False + return True def queue_download(self): u = state.user() diff --git a/oml/localnodes.py b/oml/localnodes.py index 31aecd6..0ec1213 100644 --- a/oml/localnodes.py +++ b/oml/localnodes.py @@ -148,6 +148,7 @@ class LocalNodesBase(Thread): state.nodes.queue('add', u.id) self.send() + def get_ip(self): pass diff --git a/oml/nodes.py b/oml/nodes.py index fdaa8d8..3f21c6f 100644 --- a/oml/nodes.py +++ b/oml/nodes.py @@ -38,7 +38,7 @@ class Node(Thread): _pulling = False host = None local = None - online = False + _online = None download_speed = 0 TIMEOUT = 5 @@ -78,11 +78,12 @@ class Node(Thread): #return Thread.join(self) def pull(self): - if not self._pulling: + if state.online and not self._pulling: self._q.put('pull') def ping(self): - self._q.put('ping') + if state.online: + self._q.put('ping') def go_online(self): self._q.put('go_online') @@ -99,6 +100,18 @@ class Node(Thread): url = 'https://%s.onion:9851' % self.user_id return url + @property + def online(self): + return self._online + + @online.setter + def online(self, online): + if self._online != online: + self._online = online + self.trigger_status() + else: + self._online = online + def resolve(self): #logger.debug('resolve node %s', self.user_id) r = self.get_local() @@ -263,13 +276,13 @@ class Node(Thread): self.online = False else: self.online = False - self.trigger_status() def trigger_status(self): - trigger_event('status', { - 'id': self.user_id, - 'online': self.online - }) + if self.online is not None: + trigger_event('status', { + 'id': self.user_id, + 'online': self.online + }) def pullChanges(self): if not self.online or not self.user.peered: @@ -280,7 +293,6 @@ class Node(Thread): changes = self.request('pullChanges', from_revision) except: self.online = False - self.trigger_status() logger.debug('%s went offline', self.user.name) return False if not changes: @@ -296,7 +308,6 @@ class Node(Thread): r = self.request('pushChanges', changes) except: self.online = False - self.trigger_status() r = False logger.debug('pushedChanges %s %s', r, self.user_id) @@ -407,6 +418,15 @@ class Nodes(Thread): def __init__(self): self._q = Queue() self._running = True + with db.session(): + for u in user.models.User.query.filter_by(peered=True): + if 'local' in u.info: + del u.info['local'] + u.save() + self.queue('add', u.id) + for u in user.models.User.query.filter_by(queued=True): + logger.debug('adding queued node... %s', u.id) + self.queue('add', u.id) self._local = LocalNodes() self._cleanup = PeriodicCallback(lambda: self.queue('cleanup'), 120000) self._cleanup.start() diff --git a/oml/server.py b/oml/server.py index 8526cb3..d2ad381 100644 --- a/oml/server.py +++ b/oml/server.py @@ -53,6 +53,7 @@ def log_request(handler): request_time = 1000.0 * handler.request.request_time() log_method("%d %s %.2fms", handler.get_status(), handler._request_summary(), request_time) + def run(): setup.create_db() PID = sys.argv[2] if len(sys.argv) > 2 else None @@ -106,7 +107,6 @@ def run(): state.tasks = tasks.Tasks() def start_node(): - import user import downloads import nodes import tor @@ -117,21 +117,12 @@ def run(): state.downloads = downloads.Downloads() state.scraping = downloads.ScrapeThread() state.nodes = nodes.Nodes() - def add_users(): + def publish(): if not state.tor.is_online(): - state.main.add_callback(add_users) + state.main.call_later(1, publish) else: - with db.session(): - for u in user.models.User.query.filter_by(peered=True): - if 'local' in u.info: - del u.info['local'] - u.save() - state.nodes.queue('add', u.id) - for u in user.models.User.query.filter_by(queued=True): - logger.debug('adding queued node... %s', u.id) - state.nodes.queue('add', u.id) nodes.publish_node() - state.main.add_callback(add_users) + state.main.add_callback(publish) state.main.add_callback(start_node) if ':' in settings.server['address']: host = '[%s]' % settings.server['address'] diff --git a/oml/tor.py b/oml/tor.py index d98c2fc..dfa5823 100644 --- a/oml/tor.py +++ b/oml/tor.py @@ -8,6 +8,7 @@ from stem.control import Controller import settings import state +import utils import logging logger = logging.getLogger(__name__) @@ -127,7 +128,7 @@ class Tor(object): self.connected = True self.socks_port = int(self.controller.get_conf('SocksPort').split(' ')[0]) self.publish() - state.online = True + state.online = self.is_online() return True def reconnect(self): @@ -193,4 +194,4 @@ class Tor(object): state.online = False def is_online(self): - return self.connected and self.controller.is_alive() + return self.connected and self.controller.is_alive() and utils.can_connect_dns() diff --git a/oml/utils.py b/oml/utils.py index 7dce1ff..9b99a7b 100644 --- a/oml/utils.py +++ b/oml/utils.py @@ -346,3 +346,16 @@ def open_folder(folder=None, path=None): else: logger.debug('unsupported platform %s', sys.platform) subprocess.Popen(cmd, close_fds=True) + +def can_connect_dns(host="8.8.8.8", port=53): + """ + host: 8.8.8.8 (google-public-dns-a.google.com) + port: 53/tcp + """ + try: + socket.setdefaulttimeout(1) + socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port)) + return True + except: + pass + return False diff --git a/oml/websocket.py b/oml/websocket.py index 3c8825f..6c6457f 100644 --- a/oml/websocket.py +++ b/oml/websocket.py @@ -9,6 +9,7 @@ import json from oxtornado import json_dumps import state +import settings import logging logger = logging.getLogger(__name__) @@ -33,6 +34,13 @@ class Handler(WebSocketHandler): self.close() if self not in state.websockets: state.websockets.append(self) + trigger_event('status', { + 'id': settings.USER_ID, + 'online': state.online + }) + if state.nodes: + for node in state.nodes._nodes.values(): + node.trigger_status() #websocket calls diff --git a/static/js/folders.js b/static/js/folders.js index c5a4b6d..cd5b47f 100644 --- a/static/js/folders.js +++ b/static/js/folders.js @@ -344,7 +344,12 @@ oml.ui.folders = function() { Ox.print('peering.remove reload list') Ox.Request.clearCache('getUsers'); that.updateElement(); - } + }, + status: function(data) { + if (data.id == oml.user.id) { + oml.user.online = data.online; + } + }, }); return that.updateElement(); diff --git a/static/js/statusIcon.js b/static/js/statusIcon.js index fa8c3b8..621fbc4 100644 --- a/static/js/statusIcon.js +++ b/static/js/statusIcon.js @@ -42,9 +42,13 @@ oml.ui.statusIcon = function(user, index) { } function getStatus(data) { - return !oml.user.online ? 'unknown' - : data.online ? 'connected' - : 'disconnected'; + if (!oml.user.online) { + return 'unknown'; + } + if (user.id == data.id) { + return data.online ? 'connected' : 'disconnected'; + } + return status || 'unknown'; } function render() { @@ -75,7 +79,7 @@ oml.ui.statusIcon = function(user, index) { } function update(data) { - if (data.id == user.id) { + if (data.id == user.id || data.id == oml.user.id) { var newStatus = getStatus(data); if (status != newStatus) { status = newStatus; diff --git a/static/js/utils.js b/static/js/utils.js index 40cf851..9ffaae6 100644 --- a/static/js/utils.js +++ b/static/js/utils.js @@ -890,11 +890,17 @@ oml.renameUser = function(data) { var ui = oml.user.ui, index = Ox.getIndexById(ui._users, data.id), - name = ui._users[index].name, + name, set = {}, - oldFind = Ox.clone(ui.find, true), - newFind = Ox.clone(ui.find, true); + oldFind, + newFind; + if (index == -1) { + return; + } + name = ui._users[index].name; + oldFind = Ox.clone(ui.find, true); + newFind = Ox.clone(ui.find, true); ui._users[index].name = data.name; ui._users[index].nickname = data.nickname; set['showFolder.' + name] = null;