1
0
Fork 0
mirror of https://github.com/dbarzin/pandora-box.git synced 2025-07-19 05:19:40 +02:00
pandora-box/pandora-box.py

638 lines
23 KiB
Python
Raw Normal View History

2022-06-11 18:25:10 +02:00
#!/usr/bin/python3
2023-02-14 20:41:49 +01:00
#
2023-02-12 18:10:04 +01:00
# This file is part of the Pandora-box distribution.
# https://github.com/dbarzin/pandora-box
2022-07-13 15:26:00 +02:00
# Copyright (c) 2022 Didier Barzin.
2023-02-12 18:10:04 +01:00
#
2023-02-14 20:41:49 +01:00
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
2022-07-13 15:26:00 +02:00
# the Free Software Foundation, version 3.
#
2023-02-14 20:41:49 +01:00
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2022-07-13 15:26:00 +02:00
# General Public License for more details.
#
2023-02-14 20:41:49 +01:00
# You should have received a copy of the GNU General Public License
2022-07-13 15:26:00 +02:00
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
2022-06-11 21:50:01 +02:00
2023-02-15 13:22:59 +01:00
"""The Pandora-Box Module."""
2022-06-11 21:06:59 +02:00
import os
2023-02-14 20:57:56 +01:00
import time
2022-06-12 11:14:38 +02:00
import logging
2023-02-14 20:57:56 +01:00
from curses import wrapper
from datetime import datetime
2022-06-16 13:24:36 +02:00
import configparser
2022-06-17 22:09:21 +02:00
import shutil
2023-02-14 20:57:56 +01:00
import curses
import pyudev
import psutil
import pypandora
2022-06-11 20:06:30 +02:00
2023-02-15 13:22:59 +01:00
class PandoraBox:
"""The PandoraBox class"""
# -----------------------------------------------------------
# Config variables
# -----------------------------------------------------------
is_fake_scan = None
has_usb_auto_mount = None
pandora_root_url = None
has_quarantine = None
quarantine_folder = None
has_curses = None
# -----------------------------------------------------------
2022-09-25 10:30:14 +02:00
# Curses
2023-02-15 13:22:59 +01:00
# -----------------------------------------------------------
screen = None
status_win = None
progress_win = None
title_win = None
log_win = None
# Pandora logo
logo = None
# -----------------------------------------------------------
2023-02-19 11:49:44 +00:00
# Interval box variables
2023-02-15 13:22:59 +01:00
# -----------------------------------------------------------
device = None
mount_point = None
infected_files = None
# ----------------------------------------------------------
2023-02-15 18:03:18 +01:00
def _config(self):
2023-02-15 13:22:59 +01:00
""" read configuration file """
# intantiate a ConfirParser
config_parser = configparser.ConfigParser()
# read the config file
config_parser.read('pandora-box.ini')
# set values
self.is_fake_scan=config_parser['DEFAULT']['FAKE_SCAN'].lower()=="true"
self.has_usb_auto_mount=config_parser['DEFAULT']['USB_AUTO_MOUNT'].lower()=="true"
self.pandora_root_url=config_parser['DEFAULT']['PANDORA_ROOT_URL']
# Quarantine
self.has_quarantine = config_parser['DEFAULT']['QUARANTINE'].lower()=="true"
self.quarantine_folder = config_parser['DEFAULT']['QUARANTINE_FOLDER']
# Curses
self.has_curses = config_parser['DEFAULT']['CURSES'].lower()=="true"
# ----------------------------------------------------------
2023-02-15 18:03:18 +01:00
def _human_readable_size(self,size, decimal_places=1):
2023-02-15 13:22:59 +01:00
""" Convert size to human readble string """
for unit in ['B','KB','MB','GB','TB']:
if size < 1024.0:
break
size /= 1024.0
return f"{size:.{decimal_places}f}{unit}"
# -----------------------------------------------------------
# Image Screen
# -----------------------------------------------------------
def display_image(self, status):
""" Display image on screen """
if not self.has_curses:
if status=="WAIT":
image = "images/key*.png"
elif status=="WORK":
image = "images/wait*.png"
elif status=="OK":
image = "images/ok.png"
elif status=="BAD":
image = "images/bad.png"
elif status=="ERROR":
image = "images/error.png"
else:
return
# hide old image
os.system("killall -s 9 fim 2>/dev/null")
# display image
if "*" in image:
# slide show
os.system(f"fim -qa -c 'while(1){{display;sleep 1;next;}}' {image} "\
"</dev/null 2>/dev/null >/dev/null &")
else :
# only one image
2023-02-15 18:03:18 +01:00
os.system(f"fim -qa {image} </dev/null 2>/dev/null >/dev/null &")
2023-02-15 13:22:59 +01:00
# -----------------------------------------------------------
def wait_mouse_click(self):
""" Wait for mouse click event """
with open("/dev/input/mice", "rb" ) as mouse:
down = False
while True:
buf = mouse.read(3)
if (buf[0] & 0x1)==1:
down = True
if ((buf[0] & 0x1)==0) and down:
break
# -----------------------------------------------------------
# has_curses Screen
# -----------------------------------------------------------
2023-02-15 18:03:18 +01:00
def _init_curses(self):
2023-02-15 13:22:59 +01:00
"""Initialise curses"""
if self.has_curses:
self.screen = curses.initscr()
self.screen.keypad(1)
curses.mousemask(curses.ALL_MOUSE_EVENTS | curses.REPORT_MOUSE_POSITION)
curses.flushinp()
curses.noecho()
curses.curs_set(0)
2022-06-28 18:58:29 +02:00
else:
2023-02-15 13:22:59 +01:00
self.display_image("WAIT")
2023-02-15 18:03:18 +01:00
def _print_fslabel(self, label):
2023-02-15 13:22:59 +01:00
"""Print FS Label"""
2023-02-15 18:03:18 +01:00
if label is None:
label = ""
2023-02-15 13:22:59 +01:00
if self.has_curses:
2023-02-15 18:03:18 +01:00
self.status_win.addstr(1, 1, f"Partition : {label:32}", curses.color_pair(2))
2023-02-15 13:22:59 +01:00
self.status_win.refresh()
2023-02-15 18:03:18 +01:00
def _print_size(self, label):
2023-02-15 13:22:59 +01:00
"""Print FS Size"""
if self.has_curses:
2023-02-15 18:03:18 +01:00
self.status_win.addstr(2, 1, f"Size : {label:32} ", curses.color_pair(2))
2023-02-15 13:22:59 +01:00
self.status_win.refresh()
2023-02-15 18:03:18 +01:00
def _print_used(self, label):
2023-02-15 13:22:59 +01:00
"""Print FS Used Size"""
if self.has_curses:
2023-02-15 18:03:18 +01:00
self.status_win.addstr(3, 1, f"Used : {label:32} ",curses.color_pair(2))
2023-02-15 13:22:59 +01:00
self.status_win.refresh()
2023-02-15 18:03:18 +01:00
def _print_fstype(self, label):
2023-02-15 13:22:59 +01:00
"""Print device FS type"""
if self.has_curses:
2023-02-15 18:03:18 +01:00
self.status_win.addstr(1, 50, f"Part / Type : {label:32}", curses.color_pair(2))
2023-02-15 13:22:59 +01:00
self.status_win.refresh()
2023-02-15 18:03:18 +01:00
def _print_model(self, label):
2023-02-15 13:22:59 +01:00
"""Print device model"""
if self.has_curses:
2023-02-15 18:03:18 +01:00
self.status_win.addstr(2, 50, f"Model : {label:32}", curses.color_pair(2))
2023-02-15 13:22:59 +01:00
self.status_win.refresh()
2023-02-15 18:03:18 +01:00
def _print_serial(self, label):
2023-02-15 13:22:59 +01:00
"""Print device serail number"""
if self.has_curses:
2023-02-15 18:03:18 +01:00
self.status_win.addstr(3, 50, f"Serial : {label:32}", curses.color_pair(2))
2023-02-15 13:22:59 +01:00
self.status_win.refresh()
2023-02-15 18:03:18 +01:00
def _init_bar(self):
2023-02-15 13:22:59 +01:00
"""Initialise progress bar"""
if self.has_curses:
self.progress_win = curses.newwin(3, curses.COLS-12, 17, 5)
self.progress_win.border(0)
self.progress_win.refresh()
2023-02-15 18:03:18 +01:00
def _update_bar(self, progress):
2023-02-15 13:22:59 +01:00
"""Update progress bar"""
if self.has_curses:
if progress == 0:
self.progress_win.clear()
self.progress_win.border(0)
time.sleep(0)
self.progress_win.addstr(0, 1, "Progress:")
else:
pos = ((curses.COLS-14) * progress) // 100
self.progress_win.addstr(1, 1, "#"*pos)
2023-02-15 14:51:46 +01:00
self.progress_win.addstr(0, 1, f"Progress: {progress}%")
2023-02-15 13:22:59 +01:00
self.progress_win.refresh()
2023-02-15 18:03:18 +01:00
def _print_screen(self):
2023-02-15 13:22:59 +01:00
"""Print main screen"""
if self.has_curses:
curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK)
curses.init_pair(2, curses.COLOR_BLUE, curses.COLOR_BLACK)
curses.init_pair(3, curses.COLOR_GREEN, curses.COLOR_BLACK)
self.title_win = curses.newwin(12, curses.COLS, 0, 0)
# title_win.border(0)
title_col = (curses.COLS - len(self.logo[0]))//2
self.title_win.addstr(1, title_col, self.logo[0], curses.color_pair(1))
self.title_win.addstr(2, title_col, self.logo[1], curses.color_pair(1))
self.title_win.addstr(3, title_col, self.logo[2], curses.color_pair(1))
self.title_win.addstr(4, title_col, self.logo[3], curses.color_pair(1))
self.title_win.addstr(5, title_col, self.logo[4], curses.color_pair(1))
self.title_win.addstr(6, title_col, self.logo[5], curses.color_pair(1))
self.title_win.addstr(7, title_col, self.logo[6], curses.color_pair(1))
self.title_win.addstr(8, title_col, self.logo[7], curses.color_pair(1))
self.title_win.addstr(9, title_col, self.logo[8], curses.color_pair(1))
self.title_win.addstr(10, title_col, self.logo[9], curses.color_pair(1))
self.title_win.refresh()
self.status_win = curses.newwin(5, curses.COLS, 12, 0)
self.status_win.border(0)
self.status_win.addstr(0, 1, "USB Key Information")
2023-02-15 18:03:18 +01:00
self._print_fslabel("")
self._print_size("")
self._print_used("")
self._print_fstype("")
self._print_model("")
self._print_serial("")
self._init_bar()
self._update_bar(0)
self._log('Ready.')
2023-02-22 21:38:56 +01:00
logging.info("pandora-box-start")
2023-02-15 18:03:18 +01:00
def _end_curses(self):
2023-02-15 13:22:59 +01:00
"""Closes curses"""
if self.has_curses:
curses.endwin()
curses.flushinp()
2022-06-28 18:58:29 +02:00
else:
2023-02-15 13:22:59 +01:00
# hide old image
os.system("killall -s 9 fim 2>/dev/null")
# -----------------------------------------------------------
# Logging windows
# -----------------------------------------------------------
2023-02-15 18:03:18 +01:00
def _init_log(self):
2023-02-15 13:22:59 +01:00
"""Inititalize logging function"""
if self.has_curses:
self.log_win = curses.newwin(curses.LINES-20, curses.COLS, 20, 0)
self.log_win.border(0)
logging.basicConfig(
2023-02-22 21:38:56 +01:00
filename='/var/log/pandora-box.log',
2023-02-15 13:22:59 +01:00
level=logging.INFO,
format='%(asctime)s - %(message)s',
datefmt='%m/%d/%y %H:%M'
)
logs = []
2023-02-15 18:03:18 +01:00
def _log(self, msg):
2023-02-15 13:22:59 +01:00
"""log something"""
if self.has_curses:
# display log on screen
2023-02-15 14:58:55 +01:00
self.logs.append(msg)
2023-02-15 13:22:59 +01:00
if len(self.logs)>(curses.LINES-22):
self.logs.pop(0)
self.log_win.clear()
self.log_win.border(0)
for i in range(min(curses.LINES-22,len(self.logs))):
self.log_win.addstr(i+1,1,self.logs[i][:curses.COLS-2],curses.color_pair(3))
self.log_win.refresh()
# -----------------------------------------------------------
# Device
# -----------------------------------------------------------
def mount_device(self):
"""Mount USB device"""
2023-02-22 21:38:56 +01:00
self._log('Mount device')
2023-02-15 13:22:59 +01:00
if self.has_usb_auto_mount:
2023-02-19 12:34:30 +00:00
self.mount_point = None
2023-02-15 13:22:59 +01:00
loop = 0
2023-02-15 18:03:18 +01:00
while (self.mount_point is None) and (loop < 15):
2023-02-15 13:22:59 +01:00
# need to sleep before devide is mounted
time.sleep(1)
for partition in psutil.disk_partitions():
if partition.device == self.device.device_node:
2023-02-15 18:03:18 +01:00
self.mount_point = partition.mountpoint
2023-02-15 13:22:59 +01:00
loop += 1
2023-02-15 18:03:18 +01:00
if self.mount_device is None:
self._log('No partition mounted')
2022-06-28 18:58:29 +02:00
else:
2023-02-19 12:34:30 +00:00
self.mount_point = "/media/box"
2023-02-15 13:22:59 +01:00
if not os.path.exists("/media/box"):
2023-02-15 18:03:18 +01:00
self._log("folder /media/box does not exists")
2023-02-15 13:22:59 +01:00
return None
os.system(f"pmount {self.device.device_node} /media/box >/dev/null 2>/dev/null")
loop = 0
while loop < 10:
time.sleep(1)
try:
os.statvfs(self.mount_point)
2023-02-15 18:03:18 +01:00
except Exception as ex:
self._log(f"Unexpected error: {ex}")
2023-02-15 13:22:59 +01:00
loop +=1
continue
break
def umount_device(self):
"""Unmount USB device"""
if self.has_usb_auto_mount:
2023-02-15 18:03:18 +01:00
self._log("Sync partitions")
2023-02-15 13:22:59 +01:00
os.system("sync")
2022-06-12 00:26:34 +02:00
else:
2023-02-15 13:22:59 +01:00
os.system("pumount /media/box 2>/dev/null >/dev/null")
2023-02-15 18:03:18 +01:00
def _log_device_info(self, dev):
2023-02-15 13:22:59 +01:00
"""Log device information"""
logging.info(
2023-02-15 18:03:18 +01:00
'device_name="%s", ' \
'path_id="%s", ' \
'bus system="%s", ' \
'USB_driver="%s", ' \
'device_type="%s", ' \
'device_usage="%s", ' \
'partition type="%s", ' \
'fs_type="%s", ' \
'partition_label="%s", ' \
'device_model="%s", ' \
'model_id="%s", ' \
'serial_short="%s", '\
'serial="%s"',
dev.get("DEVNAME"),
dev.get("ID_PATH"),
dev.get("ID_BUS"),
dev.get("ID_USB_DRIVER"),
dev.get("DEVTYPE"),
dev.get("ID_FS_USAGE"),
dev.get("ID_PART_TABLE_TYPE"),
dev.get("ID_FS_TYPE"),
dev.get("ID_FS_LABEL"),
dev.get("ID_MODEL"),
dev.get("ID_MODEL_ID"),
dev.get("ID_SERIAL_SHORT"),
dev.get("ID_SERIAL")
)
2023-02-15 13:22:59 +01:00
# -----------------------------------------------------------
# pandora
# -----------------------------------------------------------
def scan(self, used):
"""Scan a mount point with Pandora"""
self.infected_files = []
scanned = 0
file_count = 0
scan_start_time = time.time()
if self.has_quarantine:
qfolder = os.path.join(self.quarantine_folder,datetime.now().strftime("%y%m%d-%H%M"))
if not self.is_fake_scan:
2023-02-15 14:51:46 +01:00
pandora = pypandora.PyPandora(root_url=self.pandora_root_url)
2023-02-15 13:22:59 +01:00
try:
2023-02-15 14:51:46 +01:00
for root, _, files in os.walk(self.mount_point):
2023-02-15 13:22:59 +01:00
for file in files:
status = None
full_path = os.path.join(root,file)
file_size = os.path.getsize(full_path)
# log("Check %s [%s]" % (file, human_readable_size(file_size)))
file_scan_start_time = time.time()
if self.is_fake_scan :
2022-06-13 20:10:33 +00:00
time.sleep(0.1)
2023-02-15 13:22:59 +01:00
status = "SKIPPED"
2023-02-13 15:45:28 +01:00
else:
2023-02-22 22:31:31 +01:00
# do not scan files bigger than 1G
2023-02-15 13:22:59 +01:00
if file_size > (1024*1024*1024):
status = "TOO BIG"
else:
res = pandora.submit_from_disk(full_path)
time.sleep(0.1)
loop = 0
while loop < 960:
res = pandora.task_status(res["taskId"])
status = res["status"]
if status != "WAITING":
break
time.sleep(0.5)
loop += 1
file_scan_end_time = time.time()
2023-02-22 21:38:56 +01:00
2023-02-15 18:03:18 +01:00
self._log(
2023-02-22 21:38:56 +01:00
f'Scan {file} '\
f'[{self._human_readable_size(file_size)}] '\
'-> '\
f'{status} ({int(file_scan_end_time - file_scan_start_time)}s)')
logging.info(
f'file="{file}", '\
f'size="{file_size}", '\
2023-02-15 13:22:59 +01:00
f'status="{status}"", '\
f'duration="{int(file_scan_end_time - file_scan_start_time)}"')
scanned += os.path.getsize(full_path)
file_count += 1
2023-02-15 18:03:18 +01:00
self._update_bar(scanned * 100 // used)
2023-02-15 13:22:59 +01:00
if status == "ALERT":
self.infected_files.append(full_path)
if self.has_quarantine:
if not os.path.isdir(qfolder) :
os.mkdir(qfolder)
shutil.copyfile(full_path, os.path.join(qfolder,file))
2023-02-15 14:51:46 +01:00
except Exception as ex :
2023-02-19 14:21:54 +00:00
self._log(f"Unexpected error: {str(ex)}")
2023-02-22 21:38:56 +01:00
logging.info(f'error="{str(ex)}"', exc_info=True)
2023-02-15 18:26:50 +01:00
return "ERROR"
2023-02-15 18:03:18 +01:00
self._update_bar(100)
2023-02-22 21:38:56 +01:00
self._log("Scan done in %ds, %d files scanned, %d files infected" %
((time.time() - scan_start_time),file_count,len(self.infected_files)))
logging.info(
2023-02-22 22:01:59 +01:00
f'duration="{int(time.time() - scan_start_time)}", '\
2023-02-15 13:22:59 +01:00
f'files_scanned="{file_count}", '\
f'files_infected="{len(self.infected_files)}"')
2023-02-15 18:26:50 +01:00
return "CLEAN"
2023-02-15 13:22:59 +01:00
# --------------------------------------
def wait_device(self):
"""Wait for insert of remove of USB device"""
# Loop
context = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by("block")
try:
for dev in iter(monitor.poll, None):
if dev.get("ID_FS_USAGE") == "filesystem" and dev.device_node[5:7] == "sd":
if dev.action == "add":
2023-02-15 18:03:18 +01:00
return self._device_inserted(dev)
2023-02-15 13:22:59 +01:00
if dev.action == "remove":
2023-02-15 18:03:18 +01:00
return self._device_removed()
2023-02-15 14:51:46 +01:00
except Exception as ex:
2023-02-15 18:03:18 +01:00
self._log(f"Unexpected error: {str(ex)}")
2023-02-22 21:38:56 +01:00
logging.info(f'error="{str(ex)}"', exc_info=True)
2023-02-15 13:22:59 +01:00
return "STOP"
2023-02-15 18:03:18 +01:00
def _device_inserted(self, dev):
2023-02-22 22:01:59 +01:00
self._log("Device inserted")
logging.info("device-inserted")
2023-02-15 18:03:18 +01:00
self.device = dev
self._log_device_info(self.device)
if not self.has_curses:
self.display_image("WORK")
else:
# display device type
self._print_fslabel(self.device.get("ID_FS_LABEL"))
self._print_fstype(self.device.get("ID_PART_TABLE_TYPE")
+ " " + self.device.get("ID_FS_TYPE"))
self._print_model(self.device.get("ID_MODEL"))
self._print_serial(self.device.get("ID_SERIAL_SHORT"))
return "INSERTED"
def _device_removed(self):
2023-02-22 22:01:59 +01:00
self._log("Device removed")
logging.info("device-removed")
2023-02-15 18:03:18 +01:00
self.device = None
if not self.has_curses:
self.display_image("WAIT")
else:
self._print_fslabel("")
self._print_size("")
self._print_used("")
self._print_fstype("")
self._print_model("")
self._print_serial("")
self._update_bar(0)
return "WAIT"
2023-02-15 13:22:59 +01:00
# --------------------------------------
def mount(self):
2023-02-15 18:03:18 +01:00
""" Mount device """
self.mount_device()
self._log(f'Partition mounted at {self.mount_point}')
2023-02-15 13:22:59 +01:00
if self.mount_point is None:
# no partition
if not self.has_curses:
self.display_image("WAIT")
return "WAIT"
try:
os.statvfs(self.mount_point)
2023-02-15 14:51:46 +01:00
except Exception as ex :
2023-02-22 21:38:56 +01:00
self._log(f"Unexpected error: {str(ex)}")
logging.info(f'error="{str(ex)}"', exc_info=True)
2023-02-15 13:22:59 +01:00
if not self.has_curses:
self.display_image("WAIT")
return "WAIT"
return "SCAN"
# --------------------------------------
def scan_device(self):
"""Scan devce with pypandora"""
try:
statvfs=os.statvfs(self.mount_point)
2023-02-15 14:51:46 +01:00
except Exception as ex :
2023-02-15 18:03:18 +01:00
self._log(f"error={ex}")
2023-02-15 13:22:59 +01:00
logging.info("An exception was thrown!", exc_info=True)
if not self.has_curses:
self.display_image("WAIT")
return "WAIT"
2023-02-15 18:03:18 +01:00
self._print_size(self._human_readable_size(statvfs.f_frsize * statvfs.f_blocks))
self._print_used(
2023-02-15 18:26:50 +01:00
self._human_readable_size(statvfs.f_frsize * (statvfs.f_blocks - statvfs.f_bfree)))
return self.scan(statvfs.f_frsize * (statvfs.f_blocks - statvfs.f_bfree))
# --------------------------------------
def error(self):
""" Display error message """
if not self.has_curses:
self.display_image("ERROR")
return "WAIT"
2023-02-15 13:22:59 +01:00
# --------------------------------------
def clean(self):
"""Remove infected files"""
if len(self.infected_files) > 0:
2023-02-22 21:38:56 +01:00
self._log(f"{len(self.infected_files)} infected_files detecetd !")
logging.info(f"infeted_files={len(self.infected_files)}")
2023-02-15 13:22:59 +01:00
if not self.has_curses:
self.display_image("BAD")
self.wait_mouse_click()
else:
2023-02-15 18:03:18 +01:00
self._log('PRESS KEY TO CLEAN')
2023-02-15 13:22:59 +01:00
self.screen.getch()
# Remove infected files
for file in self.infected_files:
try :
os.remove(file)
2023-02-15 18:03:18 +01:00
self._log(f"{file} removed")
2023-02-22 21:38:56 +01:00
logging.info(f'removed="{file}"')
2023-02-15 14:51:46 +01:00
except Exception as ex :
2023-02-22 21:38:56 +01:00
self._log(f"Unexpected error: {str(ex)}")
logging.info(f'error="{str(ex)}"', exc_info=True)
2023-02-15 13:22:59 +01:00
os.system("sync")
if not self.has_curses:
self.display_image("OK")
else:
if not self.has_curses:
self.display_image("OK")
self.umount_device()
2023-02-13 15:45:28 +01:00
return "WAIT"
2023-02-15 13:22:59 +01:00
# --------------------------------------
2023-02-15 14:51:46 +01:00
def move_to_script_folder(self):
"""Move to pandora-box folder"""
2023-02-15 13:22:59 +01:00
abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
os.chdir(dname)
# --------------------------------------
def startup(self):
"""Start Pandora-box"""
# Move to script folder
2023-02-19 11:49:44 +00:00
self.move_to_script_folder()
2023-02-15 18:03:18 +01:00
# read config
self._config()
# Initialize curesrs
self._init_curses()
# Initilize log
self._init_log()
2023-02-15 13:22:59 +01:00
# Read logo
2023-02-15 18:03:18 +01:00
with open('pandora-box.txt', mode='r', encoding='utf-8') as file1:
2023-02-15 13:22:59 +01:00
self.logo = file1.readlines()
# Print logo screen
2023-02-15 18:03:18 +01:00
self._print_screen()
2023-02-15 13:22:59 +01:00
# First unmount remaining device
self.umount_device()
2023-02-13 15:45:28 +01:00
return "WAIT"
2022-06-11 18:25:10 +02:00
2023-02-15 13:22:59 +01:00
# --------------------------------------
def loop(self, state):
"""Main event loop"""
match state:
case "START":
return self.startup()
case "WAIT":
return self.wait_device()
case "INSERTED":
return self.mount()
case "SCAN":
return self.scan_device()
case "CLEAN":
return self.clean()
2023-02-15 18:26:50 +01:00
case "ERROR":
return self.error()
2023-02-15 13:22:59 +01:00
case _:
return "STOP"
# --------------------------------------
def main(self):
"""Main entry point"""
try :
state="START"
while state!="STOP":
state = self.loop(state)
except Exception as ex :
2023-02-22 21:38:56 +01:00
self._log(f"Unexpected error: {str(ex)}")
logging.info(f'error="{str(ex)}"', exc_info=True)
2023-02-15 13:22:59 +01:00
finally:
2023-02-15 18:03:18 +01:00
self._end_curses()
2023-02-15 13:22:59 +01:00
2023-02-15 14:51:46 +01:00
def main(_):
"""Main entry point"""
2023-02-15 13:22:59 +01:00
pandora_box = PandoraBox()
pandora_box.main()
2023-02-12 18:10:04 +01:00
2022-06-11 21:06:59 +02:00
if __name__ == "__main__":
2022-06-12 00:26:34 +02:00
wrapper(main)