updated gui and enforcement
This commit is contained in:
+44
-126
@@ -1,33 +1,34 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import threading
|
||||
import time
|
||||
from datetime import datetime
|
||||
import traceback
|
||||
|
||||
from .enforcement import (
|
||||
enforce_all_users,
|
||||
record_usage,
|
||||
get_user_policy,
|
||||
consume_grant_seconds,
|
||||
)
|
||||
|
||||
|
||||
CHECK_INTERVAL = 5
|
||||
|
||||
|
||||
class Scheduler:
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
interval: int = CHECK_INTERVAL,
|
||||
interval_seconds: float = 1.0,
|
||||
):
|
||||
self.interval = interval
|
||||
self.interval_seconds = max(
|
||||
0.1,
|
||||
float(
|
||||
interval_seconds
|
||||
),
|
||||
)
|
||||
|
||||
self._stop_event = (
|
||||
threading.Event()
|
||||
)
|
||||
|
||||
self._thread = None
|
||||
self._stop_event = threading.Event()
|
||||
|
||||
self._last_usage_update = {}
|
||||
|
||||
def start(self):
|
||||
|
||||
if (
|
||||
self._thread is not None
|
||||
and self._thread.is_alive()
|
||||
@@ -45,139 +46,56 @@ class Scheduler:
|
||||
self._thread.start()
|
||||
|
||||
def stop(self):
|
||||
|
||||
self._stop_event.set()
|
||||
|
||||
if self._thread is not None:
|
||||
self._thread.join(
|
||||
timeout=self.interval + 2
|
||||
timeout=3
|
||||
)
|
||||
|
||||
self._thread = None
|
||||
|
||||
def run_once(self):
|
||||
return enforce_all_users()
|
||||
|
||||
def _run(self):
|
||||
while not self._stop_event.is_set():
|
||||
started = time.monotonic()
|
||||
|
||||
# Evaluate immediately when the
|
||||
# application starts.
|
||||
self._tick()
|
||||
try:
|
||||
self.run_once()
|
||||
|
||||
while not self._stop_event.wait(
|
||||
self.interval
|
||||
):
|
||||
self._tick()
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
|
||||
def _tick(self):
|
||||
|
||||
now = time.monotonic()
|
||||
|
||||
results = enforce_all_users()
|
||||
|
||||
for result in results:
|
||||
|
||||
user_id = result["user_id"]
|
||||
|
||||
if not result["logged_in"]:
|
||||
self._last_usage_update.pop(
|
||||
user_id,
|
||||
None,
|
||||
)
|
||||
continue
|
||||
|
||||
if not result["allowed"]:
|
||||
self._last_usage_update.pop(
|
||||
user_id,
|
||||
None,
|
||||
)
|
||||
continue
|
||||
|
||||
previous = (
|
||||
self._last_usage_update.get(
|
||||
user_id
|
||||
)
|
||||
elapsed = (
|
||||
time.monotonic()
|
||||
- started
|
||||
)
|
||||
|
||||
self._last_usage_update[user_id] = now
|
||||
|
||||
if previous is None:
|
||||
continue
|
||||
|
||||
elapsed = int(
|
||||
now - previous
|
||||
remaining = max(
|
||||
0.0,
|
||||
self.interval_seconds
|
||||
- elapsed,
|
||||
)
|
||||
|
||||
if elapsed <= 0:
|
||||
continue
|
||||
|
||||
self._record_allowed_usage(
|
||||
user_id,
|
||||
elapsed,
|
||||
)
|
||||
|
||||
def _record_allowed_usage(
|
||||
self,
|
||||
user_id: int,
|
||||
seconds: int,
|
||||
):
|
||||
|
||||
if seconds <= 0:
|
||||
return
|
||||
|
||||
weekday = datetime.now().weekday()
|
||||
|
||||
(
|
||||
allowance_seconds,
|
||||
usage_seconds,
|
||||
windows,
|
||||
grant_seconds,
|
||||
) = get_user_policy(
|
||||
user_id,
|
||||
weekday,
|
||||
)
|
||||
|
||||
allowance_remaining = max(
|
||||
0,
|
||||
allowance_seconds
|
||||
- usage_seconds,
|
||||
)
|
||||
|
||||
normal_usage = min(
|
||||
seconds,
|
||||
allowance_remaining,
|
||||
)
|
||||
|
||||
grant_usage = (
|
||||
seconds
|
||||
- normal_usage
|
||||
)
|
||||
|
||||
if grant_usage > grant_seconds:
|
||||
grant_usage = grant_seconds
|
||||
|
||||
total_usage = (
|
||||
normal_usage
|
||||
+ grant_usage
|
||||
)
|
||||
|
||||
if total_usage <= 0:
|
||||
return
|
||||
|
||||
record_usage(
|
||||
user_id,
|
||||
total_usage,
|
||||
)
|
||||
|
||||
if grant_usage > 0:
|
||||
|
||||
consume_grant_seconds(
|
||||
user_id,
|
||||
grant_usage,
|
||||
self._stop_event.wait(
|
||||
remaining
|
||||
)
|
||||
|
||||
|
||||
scheduler = Scheduler()
|
||||
_scheduler = Scheduler(
|
||||
interval_seconds=1.0
|
||||
)
|
||||
|
||||
|
||||
def start_scheduler():
|
||||
scheduler.start()
|
||||
_scheduler.start()
|
||||
|
||||
|
||||
def stop_scheduler():
|
||||
scheduler.stop()
|
||||
_scheduler.stop()
|
||||
|
||||
|
||||
def run_scheduler_once():
|
||||
return _scheduler.run_once()
|
||||
|
||||
Reference in New Issue
Block a user