This commit is contained in:
Dmytro Bogovych 2023-08-20 13:25:32 +03:00
parent 479055ced2
commit 22ec365d73
3 changed files with 139 additions and 132 deletions

View File

@ -1,6 +1,6 @@
#!/usr/bin/python3
from pathlib import Path
from utils_qualtest import Phone, TaskList
from utils_types import Phone, TaskList
import os
import shutil
import json

View File

@ -18,9 +18,7 @@ from socket import timeout
from crontab import CronTab
from pathlib import Path
from utils_cache import InfoCache
start_system_time = time.time()
start_monotonic_time = time.monotonic()
from utils_types import Phone, TaskList
# Error report produced by this function has to be updated with 'task_name' & 'phone_name' keys
def build_error_report(endtime: int, reason: str):
@ -37,94 +35,6 @@ def build_error_report(endtime: int, reason: str):
return r
class TaskList:
tasks: list = []
def __init__(self):
self.tasks = []
# Merges incoming task list to existing one
# It preserves existing schedules
# New items are NOT scheduled automatically
def merge_with(self, tasklist) -> bool:
changed = False
if tasklist.tasks is None:
return True
# Iterate all tasks, see if task with the same name exists already
# Copy all keys, but keep existing ones
for new_task in tasklist.tasks:
# Find if this task exists already
existing_task = self.find_task_by_name(new_task["name"])
# If task is found - copy all items to it.
# It is required as task can hold schedule items already
# Bad idea to copy tasks itself.
if existing_task is not None:
# Check if scheduled time point has to be removed (if cron string changed)
if new_task["schedule"] != existing_task["schedule"] and "scheduled_time" in existing_task:
del existing_task["scheduled_time"]
# Finally copy new values
for key, value in new_task.items():
if existing_task[key] != value:
existing_task[key] = value
changed = True
else:
# Copy new task to list
self.tasks.extend([new_task])
changed = True
# Check if old tasks are here... And delete them
for existing_task in self.tasks:
new_task = self.find_task_by_name(existing_task["name"])
if new_task is None:
self.tasks.remove(existing_task)
changed = True
return changed
def schedule(self):
# Remove items without schedule before
self.tasks = [t for t in self.tasks if len(t['schedule']) > 0]
# https://crontab.guru is good for crontab strings generation
# Use monotonic time source!
current_time = time.monotonic()
for task in self.tasks:
if 'scheduled_time' not in task and 'schedule' in task:
# No schedule flag, so time to schedule
try:
cron_string = task['schedule'].strip()
if cron_string == '* * * * *':
task['scheduled_time'] = time.monotonic() - 0.001 # To ensure further comparison will not be affected by precision errors
else:
cron = CronTab(task['schedule'])
task['scheduled_time'] = current_time + cron.next(default_utc=True)
# Just to help in further log reading & debugging - show the scheduled time in readable form
task['scheduled_time_str'] = time.ctime(task['scheduled_time'] - start_monotonic_time + start_system_time)
except:
utils.log_error("Error", sys.exc_info()[0])
# Remove non scheduled items
self.tasks = [t for t in self.tasks if 'scheduled_time' in t]
# Sort everything
self.tasks = sorted(self.tasks, key=lambda t: t["scheduled_time"])
# Returns None if failed
def find_task_by_name(self, name):
for t in self.tasks:
if t["name"] == name:
return t
return None
def ParseAttributes(t: str) -> dict:
result: dict = dict()
@ -136,46 +46,6 @@ def ParseAttributes(t: str) -> dict:
return result
class Phone:
identifier: int = 0
name: str = ""
role: str = ""
attributes: dict = ""
audio_id: int = 0
def __init__(self):
self.identifier = 0
self.name = ""
self.role = ""
self.attributes = dict()
self.audio_id = 0
def to_dict(self) -> dict:
return {
'id': self.identifier,
'name': self.name,
'role': self.role,
'attr': self.attributes,
'audio_id': self.audio_id
}
def make(d: dict):
r = Phone()
r.identifier = d['id']
r.name = d['name']
r.role = d['role']
if 'attr' in d:
r.attr = d['attr']
else:
r.attr = None
if 'audio_id' in d:
r.audio_id = d['audio_id']
else:
r.audio_id = None
return r
class QualtestBackend:
address: str

137
src/utils_types.py Normal file
View File

@ -0,0 +1,137 @@
#!/usr/bin/python3
import time
start_system_time = time.time()
start_monotonic_time = time.monotonic()
class Phone:
identifier: int = 0
name: str = ""
role: str = ""
attributes: dict = ""
audio_id: int = 0
def __init__(self):
self.identifier = 0
self.name = ""
self.role = ""
self.attributes = dict()
self.audio_id = 0
def to_dict(self) -> dict:
return {
'id': self.identifier,
'name': self.name,
'role': self.role,
'attr': self.attributes,
'audio_id': self.audio_id
}
def make(d: dict):
r = Phone()
r.identifier = d['id']
r.name = d['name']
r.role = d['role']
if 'attr' in d:
r.attr = d['attr']
else:
r.attr = None
if 'audio_id' in d:
r.audio_id = d['audio_id']
else:
r.audio_id = None
return r
class TaskList:
tasks: list = []
def __init__(self):
self.tasks = []
# Merges incoming task list to existing one
# It preserves existing schedules
# New items are NOT scheduled automatically
def merge_with(self, tasklist) -> bool:
changed = False
if tasklist.tasks is None:
return True
# Iterate all tasks, see if task with the same name exists already
# Copy all keys, but keep existing ones
for new_task in tasklist.tasks:
# Find if this task exists already
existing_task = self.find_task_by_name(new_task["name"])
# If task is found - copy all items to it.
# It is required as task can hold schedule items already
# Bad idea to copy tasks itself.
if existing_task is not None:
# Check if scheduled time point has to be removed (if cron string changed)
if new_task["schedule"] != existing_task["schedule"] and "scheduled_time" in existing_task:
del existing_task["scheduled_time"]
# Finally copy new values
for key, value in new_task.items():
if existing_task[key] != value:
existing_task[key] = value
changed = True
else:
# Copy new task to list
self.tasks.extend([new_task])
changed = True
# Check if old tasks are here... And delete them
for existing_task in self.tasks:
new_task = self.find_task_by_name(existing_task["name"])
if new_task is None:
self.tasks.remove(existing_task)
changed = True
return changed
def schedule(self):
# Remove items without schedule before
self.tasks = [t for t in self.tasks if len(t['schedule']) > 0]
# https://crontab.guru is good for crontab strings generation
# Use monotonic time source!
current_time = time.monotonic()
for task in self.tasks:
if 'scheduled_time' not in task and 'schedule' in task:
# No schedule flag, so time to schedule
try:
cron_string = task['schedule'].strip()
if cron_string == '* * * * *':
task['scheduled_time'] = time.monotonic() - 0.001 # To ensure further comparison will not be affected by precision errors
else:
cron = CronTab(task['schedule'])
task['scheduled_time'] = current_time + cron.next(default_utc=True)
# Just to help in further log reading & debugging - show the scheduled time in readable form
task['scheduled_time_str'] = time.ctime(task['scheduled_time'] - start_monotonic_time + start_system_time)
except:
utils.log_error("Error", sys.exc_info()[0])
# Remove non scheduled items
self.tasks = [t for t in self.tasks if 'scheduled_time' in t]
# Sort everything
self.tasks = sorted(self.tasks, key=lambda t: t["scheduled_time"])
# Returns None if failed
def find_task_by_name(self, name):
for t in self.tasks:
if t["name"] == name:
return t
return None