summaryrefslogtreecommitdiffstats
path: root/module/remote/wsbackend/AsyncHandler.py
diff options
context:
space:
mode:
authorGravatar RaNaN <Mast3rRaNaN@hotmail.de> 2013-06-09 18:10:22 +0200
committerGravatar RaNaN <Mast3rRaNaN@hotmail.de> 2013-06-09 18:10:23 +0200
commit16af85004c84d0d6c626b4f8424ce9647669a0c1 (patch)
tree025d479862d376dbc17e934f4ed20031c8cd97d1 /module/remote/wsbackend/AsyncHandler.py
parentadapted to jshint config (diff)
downloadpyload-16af85004c84d0d6c626b4f8424ce9647669a0c1.tar.xz
moved everything from module to pyload
Diffstat (limited to 'module/remote/wsbackend/AsyncHandler.py')
-rw-r--r--module/remote/wsbackend/AsyncHandler.py167
1 files changed, 0 insertions, 167 deletions
diff --git a/module/remote/wsbackend/AsyncHandler.py b/module/remote/wsbackend/AsyncHandler.py
deleted file mode 100644
index 158033ee8..000000000
--- a/module/remote/wsbackend/AsyncHandler.py
+++ /dev/null
@@ -1,167 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-###############################################################################
-# Copyright(c) 2008-2012 pyLoad Team
-# http://www.pyload.org
-#
-# This file is part of pyLoad.
-# pyLoad is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# Subjected to the terms and conditions in LICENSE
-#
-# @author: RaNaN
-###############################################################################
-
-import re
-from Queue import Queue, Empty
-from threading import Lock
-from time import time
-
-from mod_pywebsocket.msgutil import receive_message
-
-from module.Api import EventInfo, Interaction
-from module.utils import lock
-from AbstractHandler import AbstractHandler
-
-class Mode:
- STANDBY = 1
- RUNNING = 2
-
-class AsyncHandler(AbstractHandler):
- """
- Handler that provides asynchronous information about server status, running downloads, occurred events.
-
- Progress information are continuous and will be pushed in a fixed interval when available.
- After connect you have to login and can set the interval by sending the json command ["setInterval", xy].
- To start receiving updates call "start", afterwards no more incoming messages will be accepted!
- """
-
- PATH = "/async"
- COMMAND = "start"
-
- PROGRESS_INTERVAL = 2
- EVENT_PATTERN = re.compile(r"^(package|file|interaction)", re.I)
- INTERACTION = Interaction.All
-
- def __init__(self, api):
- AbstractHandler.__init__(self, api)
- self.clients = []
- self.lock = Lock()
-
- self.core.evm.addEvent("event", self.add_event)
-
- @lock
- def on_open(self, req):
- req.queue = Queue()
- req.interval = self.PROGRESS_INTERVAL
- req.events = self.EVENT_PATTERN
- req.interaction = self.INTERACTION
- req.mode = Mode.STANDBY
- req.t = time() # time when update should be pushed
- self.clients.append(req)
-
- @lock
- def on_close(self, req):
- try:
- del req.queue
- self.clients.remove(req)
- except ValueError: # ignore when not in list
- pass
-
- @lock
- def add_event(self, event, *args):
- # Convert arguments to json suited instance
- event = EventInfo(event, [x.toInfoData() if hasattr(x, 'toInfoData') else x for x in args])
-
- for req in self.clients:
- # Not logged in yet
- if not req.api: continue
-
- # filter events that these user is no owner of
- # TODO: events are security critical, this should be revised later
- # TODO: permissions? interaction etc
- if not req.api.user.isAdmin():
- skip = False
- for arg in args:
- if hasattr(arg, 'owner') and arg.owner != req.api.primaryUID:
- skip = True
- break
-
- # user should not get this event
- if skip: break
-
- if req.events.search(event.eventname):
- self.log.debug("Pushing event %s" % event)
- req.queue.put(event)
-
- def transfer_data(self, req):
- while True:
-
- if req.mode == Mode.STANDBY:
- try:
- line = receive_message(req)
- except TypeError, e: # connection closed
- self.log.debug("WS Error: %s" % e)
- return self.passive_closing_handshake(req)
-
- self.mode_standby(line, req)
- else:
- if self.mode_running(req):
- return self.passive_closing_handshake(req)
-
- def mode_standby(self, msg, req):
- """ accepts calls before pushing updates """
- func, args, kwargs = self.handle_call(msg, req)
- if not func:
- return # Result was already sent
-
- if func == 'login':
- return self.do_login(req, args, kwargs)
-
- elif func == 'logout':
- return self.do_logout(req)
-
- else:
- if not req.api:
- return self.send_result(req, self.FORBIDDEN, "Forbidden")
-
- if func == "setInterval":
- req.interval = args[0]
- elif func == "setEvents":
- req.events = re.compile(args[0], re.I)
- elif func == "setInteraction":
- req.interaction = args[0]
- elif func == self.COMMAND:
- req.mode = Mode.RUNNING
-
-
- def mode_running(self, req):
- """ Listen for events, closes socket when returning True """
- try:
- # block length of update interval if necessary
- ev = req.queue.get(True, req.interval)
- try:
- self.send(req, ev)
- except TypeError:
- self.log.debug("Event %s not converted" % ev)
- ev.event_args = []
- # Resend the event without arguments
- self.send(req, ev)
-
- except Empty:
- pass
-
- if req.t <= time():
- # TODO: server status is not enough
- # modify core api to include progress? think of other needed information to show
- # eta is quite wrong currently
- # notifications
- self.send(req, self.api.getServerStatus())
- self.send(req, self.api.getProgressInfo())
-
- # update time for next update
- req.t = time() + req.interval \ No newline at end of file