2023-03-16 04:19:03 +00:00
|
|
|
import queue
|
2023-01-12 01:04:47 +00:00
|
|
|
import threading
|
|
|
|
|
|
|
|
|
2024-06-28 01:57:31 +00:00
|
|
|
class SetQueue(queue.Queue):
|
|
|
|
def _init(self, maxsize):
|
|
|
|
self.queue = set()
|
|
|
|
|
|
|
|
def _put(self, item):
|
|
|
|
self.queue.add(item)
|
|
|
|
|
|
|
|
def _get(self):
|
|
|
|
return self.queue.pop()
|
|
|
|
|
|
|
|
|
|
|
|
class ConfigEvents(threading.Thread):
|
|
|
|
def __init__(self, callback):
|
|
|
|
super(ConfigEvents, self).__init__()
|
|
|
|
self.queue = SetQueue()
|
|
|
|
self.callback = callback
|
|
|
|
self.name = 'CONFIG-EVENTS'
|
|
|
|
self._stopper = threading.Event()
|
|
|
|
|
|
|
|
def put(self, etype):
|
|
|
|
# type: (bool) -> None
|
|
|
|
"""
|
|
|
|
put config save event into queue
|
|
|
|
|
|
|
|
:param etype: force save config.ini if unchanged
|
|
|
|
"""
|
|
|
|
self.queue.put(etype)
|
|
|
|
|
|
|
|
def stopit(self):
|
|
|
|
self._stopper.set()
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
while not self._stopper.is_set():
|
|
|
|
try:
|
|
|
|
# get event type
|
|
|
|
ev_type = self.queue.get(True, 5)
|
|
|
|
except queue.Empty:
|
|
|
|
continue
|
|
|
|
except(BaseException, Exception):
|
|
|
|
continue
|
|
|
|
if ev_type in (True, False, None):
|
|
|
|
if ev_type is None:
|
|
|
|
continue
|
|
|
|
from sickgear import logger
|
|
|
|
logger.debug(f'Callback {self.callback.__name__}(event type:{ev_type})')
|
|
|
|
|
|
|
|
try:
|
|
|
|
# perform callback if we got an event type
|
|
|
|
self.callback(ev_type)
|
|
|
|
|
|
|
|
# event completed
|
|
|
|
self.queue.task_done()
|
|
|
|
except queue.Empty:
|
|
|
|
pass
|
|
|
|
except (BaseException, Exception):
|
|
|
|
pass
|
|
|
|
|
|
|
|
# exiting thread
|
|
|
|
self._stopper.clear()
|
|
|
|
|
|
|
|
|
2023-01-12 01:04:47 +00:00
|
|
|
class Event(object):
|
|
|
|
def __init__(self, etype):
|
|
|
|
self._type = etype
|
|
|
|
|
|
|
|
@property
|
|
|
|
def type(self):
|
|
|
|
return self._type
|
|
|
|
|
|
|
|
|
|
|
|
class Events(threading.Thread):
|
|
|
|
def __init__(self, callback):
|
|
|
|
super(Events, self).__init__()
|
2023-03-16 04:19:03 +00:00
|
|
|
self.queue = queue.Queue()
|
2023-01-12 01:04:47 +00:00
|
|
|
self.daemon = True
|
|
|
|
self.callback = callback
|
|
|
|
self.name = 'EVENT-QUEUE'
|
|
|
|
self._stopper = threading.Event()
|
|
|
|
|
|
|
|
def put(self, etype):
|
|
|
|
self.queue.put(etype)
|
|
|
|
|
|
|
|
def stopit(self):
|
|
|
|
self._stopper.set()
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
while not self._stopper.is_set():
|
|
|
|
try:
|
|
|
|
# get event type
|
2023-03-16 04:19:03 +00:00
|
|
|
ev_type = self.queue.get(True, 1)
|
|
|
|
except queue.Empty:
|
|
|
|
ev_type = 'Empty'
|
2023-03-05 22:52:09 +00:00
|
|
|
except(BaseException, Exception):
|
2023-03-16 04:19:03 +00:00
|
|
|
ev_type = None
|
|
|
|
if ev_type in (self.SystemEvent.RESTART, self.SystemEvent.SHUTDOWN, None, 'Empty'):
|
|
|
|
if ev_type in ('Empty',):
|
2023-03-05 22:52:09 +00:00
|
|
|
continue
|
|
|
|
from sickgear import logger
|
2023-03-16 04:19:03 +00:00
|
|
|
logger.debug(f'Callback {self.callback.__name__}(event type:{ev_type})')
|
2023-01-12 01:04:47 +00:00
|
|
|
|
2023-03-05 22:52:09 +00:00
|
|
|
try:
|
2023-02-13 21:00:11 +00:00
|
|
|
# perform callback if we got an event type
|
2023-03-16 04:19:03 +00:00
|
|
|
self.callback(ev_type)
|
2023-01-12 01:04:47 +00:00
|
|
|
|
|
|
|
# event completed
|
|
|
|
self.queue.task_done()
|
2023-03-16 04:19:03 +00:00
|
|
|
except queue.Empty:
|
2023-01-12 01:04:47 +00:00
|
|
|
pass
|
|
|
|
|
|
|
|
# exiting thread
|
|
|
|
self._stopper.clear()
|
|
|
|
|
|
|
|
# System Events
|
|
|
|
class SystemEvent(Event):
|
|
|
|
RESTART = 'RESTART'
|
|
|
|
SHUTDOWN = 'SHUTDOWN'
|