Work on native gui. Display records and add missing tasks and measurements.
This commit is contained in:
+167
-8
@@ -7,23 +7,35 @@ Notebook mit Vessel, User, Lists, Settings
|
||||
"""
|
||||
|
||||
import os
|
||||
import pyudev
|
||||
from gi.repository import GLib, Gtk, Gdk, Rsvg
|
||||
from datetime import datetime
|
||||
import subprocess
|
||||
import locale
|
||||
|
||||
from .view import View
|
||||
from yms import gtkutils, combobox, treeview
|
||||
from yms.lookup import Dropdown
|
||||
from yms.model import user
|
||||
|
||||
class BaseView(View):
|
||||
|
||||
def __init__(self, context):
|
||||
super().__init__(context, _("Base Data"), "base.ui")
|
||||
#self.title = _("Base Data")
|
||||
#builder = Gtk.Builder()
|
||||
#builder.set_translation_domain(context.textdomain)
|
||||
#builder.add_from_file(os.path.join(context.ui_path, "base.ui"))
|
||||
#builder.connect_signals(self)
|
||||
#self.topwidget = builder.get_object("topobject")
|
||||
#gtkutils.init_named_controls(self, builder)
|
||||
self.context = context
|
||||
|
||||
self.user = user.User(context.db) # current user record
|
||||
self.newuser = False
|
||||
|
||||
self.backupdevice = None # USB-Stick detected only on demand
|
||||
|
||||
# Settings
|
||||
self.sys_currency = context.db.load_setting(4)[0] or '€'
|
||||
self.entry['sys_currency'].set_text(self.sys_currency)
|
||||
self.sys_max_width = context.db.load_setting(20)[1] or 1024
|
||||
self.spin['sys_max_width'].set_value(self.sys_max_width)
|
||||
self.sys_max_height = context.db.load_setting(21)[1] or 768
|
||||
self.spin['sys_max_height'].set_value(self.sys_max_height)
|
||||
|
||||
# combos
|
||||
roles = {'captain': 'Captain', 'helmsman': 'Helmsman', 'sailor': 'Sailor'}
|
||||
@@ -31,6 +43,14 @@ class BaseView(View):
|
||||
langs = {'de': 'Deutsch', 'en': 'English'}
|
||||
combobox.load_from_dict(self.combo['user_lang'], langs)
|
||||
|
||||
today = datetime.now()
|
||||
datedict = {
|
||||
key: f"{prefix} - {today.strftime(fmt)}"
|
||||
for key, (fmt, prefix) in context.datefmt_map.items()
|
||||
}
|
||||
self.datefmt = context.db.load_setting(2)[0] or 'Y-m-d'
|
||||
combobox.load_from_dict(self.combo['datefmt'], datedict, self.datefmt)
|
||||
|
||||
# shipyard
|
||||
self.db.cur.execute("SELECT compid, compname FROM company WHERE comptype=3 ORDER BY compname")
|
||||
shipyards = dict(self.db.cur.fetchall())
|
||||
@@ -129,6 +149,132 @@ class BaseView(View):
|
||||
storages = dict(self.db.cur.fetchall())
|
||||
combobox.refresh_dict(self.combo['storage'], {-1: _("─── none ───")} | storages)
|
||||
|
||||
def find_usb_sticks(self):
|
||||
result = []
|
||||
for name in os.listdir("/sys/block"):
|
||||
device = "/sys/block/" + name
|
||||
removable = device + "/removable"
|
||||
if not os.path.exists(removable):
|
||||
continue
|
||||
with open(removable) as f:
|
||||
if f.read().strip() != "1":
|
||||
continue
|
||||
device_path = os.path.realpath(device + "/device")
|
||||
if "/usb" in device_path.lower():
|
||||
result.append(name)
|
||||
return result
|
||||
|
||||
def is_mounted(self, device):
|
||||
with open("/proc/mounts") as f:
|
||||
for line in f:
|
||||
mounted_device = line.split()[0]
|
||||
if mounted_device == device:
|
||||
return True
|
||||
return False
|
||||
|
||||
def on_but_usbdevice_clicked(self, widget):
|
||||
self.backupdevice = None
|
||||
|
||||
devlist = self.find_usb_sticks()
|
||||
if len(devlist) == 0:
|
||||
self.label['usb_device'].set_text('n/a')
|
||||
return
|
||||
if len(devlist) != 1:
|
||||
print(devlist)
|
||||
print("Multiple devices not supported yet")
|
||||
self.label['usb_device'].set_text('multiple')
|
||||
return
|
||||
usbdev = devlist[0]
|
||||
self.label['usb_device'].set_text(f"/dev/{usbdev}")
|
||||
|
||||
"""
|
||||
serial number via python3-pyudev:
|
||||
import pyudev
|
||||
|
||||
Settings
|
||||
7 - usb backup device serial
|
||||
8 - usb backup partition uuid
|
||||
9 - last backup timestamp
|
||||
|
||||
"""
|
||||
# first get stick hardware data
|
||||
udevctx = pyudev.Context()
|
||||
device = pyudev.Devices.from_sys_path(udevctx, os.path.join("/sys/class/block", usbdev))
|
||||
|
||||
serial = device.get("ID_SERIAL_SHORT")
|
||||
vendor = device.get("ID_VENDOR")
|
||||
model = device.get("ID_MODEL")
|
||||
self.label['usb_serial'].set_text(serial or 'n/a')
|
||||
self.label['usb_vendor'].set_text(vendor or 'n/a')
|
||||
self.label['usb_model'].set_text(model or 'n/a')
|
||||
|
||||
# TODO second get partition, filesystem type and label
|
||||
# there must be only one ext4 partition on disk
|
||||
partitions = [
|
||||
child for child in device.children
|
||||
if child.device_type == "partition"
|
||||
]
|
||||
partition = partitions[0]
|
||||
print(f"Partition={partition}")
|
||||
if len(partitions) != 1:
|
||||
print("error: more than one partition!")
|
||||
return
|
||||
|
||||
partuuid = partition.properties.get("ID_PART_ENTRY_UUID")
|
||||
fstype = partition.get("ID_FS_TYPE")
|
||||
plabel = partition.get("ID_FS_LABEL")
|
||||
self.label['usb_partition'].set_text(plabel)
|
||||
self.label['usb_uuid'].set_text(partuuid)
|
||||
self.label['usb_fstype'].set_text(fstype)
|
||||
|
||||
if fstype != "ext4":
|
||||
print(f"error: invalid fileystem type {fstype}, ext4 expected")
|
||||
return
|
||||
|
||||
self.backupdevice = f"/dev/{usbdev}1" # partition!
|
||||
|
||||
# check if device is mounted
|
||||
if not self.is_mounted(self.backupdevice):
|
||||
print("device is not mounted. trying to mount now")
|
||||
pass
|
||||
|
||||
# For backup there must be an directory names ymsbackup which contains
|
||||
# backup description and backup sets
|
||||
# Desription and identification file backup.json?
|
||||
# if plabel != 'BACKUP' or not os.path.isdir('ymsbackup')
|
||||
mountpoint = os.path.join("/media", os.getlogin(), "BACKUP")
|
||||
if not os.path.isdir(mountpoint):
|
||||
print(f"Device is not mounted at {mountpoint}")
|
||||
|
||||
def on_but_usbinit_clicked(self, widget):
|
||||
if self.backupdevice is None:
|
||||
return
|
||||
# UUID of devive -> settings
|
||||
# check if backups already exist
|
||||
answer = gtkutils.questionbox(
|
||||
_("Initialize USB-Stick\n"
|
||||
"All data on that device will be lost!\n"
|
||||
"Are you really sure?"
|
||||
), title="YMS")
|
||||
if answer == False:
|
||||
return
|
||||
if self.label['usb_fstype'].get_text() != 'ext4':
|
||||
print("formatting {self.backupdevice} with ext4")
|
||||
#try:
|
||||
# subprocess.run(["sudo", "mkfs.ext4", "-L", "BACKUP", self.backupdevice], check=True)
|
||||
#except subprocess.CalledProcessError as e:
|
||||
# print("formatting failed: ", e)
|
||||
myself = os.getlogin()
|
||||
mountpoint = os.path.join("/media", myself, "backup")
|
||||
basedir = os.path.join(mountpoint, 'ymsbackup')
|
||||
print(basedir)
|
||||
# mkdir basedir
|
||||
# chown (os.getlogin(), 'yms')
|
||||
# chmod 770
|
||||
else:
|
||||
#
|
||||
pass
|
||||
|
||||
def on_cmb_vessel_changed(self, widget):
|
||||
self.context.vessel.load(combobox.get_list_value(widget))
|
||||
sql = ("UPDATE settings SET valint=%s WHERE userid=0 AND sno=1")
|
||||
@@ -189,7 +335,20 @@ class BaseView(View):
|
||||
def display_vessel(self, vessel):
|
||||
self.label['vesselname'].set_text(vessel.vesselname)
|
||||
self.label['model'].set_text(vessel.model or '')
|
||||
self.label['year_built'].set_text(self.format_int(vessel.year_built, default='n/a'))
|
||||
self.label['shipyard'].set_text(str(vessel.shipyard))
|
||||
self.label['year_built'].set_text(self.format_int(vessel.year_built, False, default='n/a'))
|
||||
self.label['loa'].set_text(self.format_float(vessel.loa, 2, suffix="m"))
|
||||
self.label['lwl'].set_text(self.format_float(vessel.lwl, 2, suffix="m"))
|
||||
self.label['beam'].set_text(self.format_float(vessel.beam, 2, suffix="m"))
|
||||
self.label['draught'].set_text(self.format_float(vessel.draught, 2, suffix="m"))
|
||||
self.label['draught_min'].set_text(self.format_float(vessel.draught_min, 2, suffix="m"))
|
||||
self.label['displacement'].set_text(self.format_int(vessel.displacement, 2, suffix="kg"))
|
||||
self.label['ballast'].set_text(self.format_int(vessel.ballast, 2, suffix="kg"))
|
||||
self.label['belt_bow'].set_text(self.format_float(vessel.beltpos_bow, 2, suffix="m"))
|
||||
self.label['belt_aft'].set_text(self.format_float(vessel.beltpos_aft, 2, suffix="m"))
|
||||
self.label['hull_shape'].set_text(vessel.shapefile or '')
|
||||
self.label['storage_def'].set_text(str(vessel.sid_default))
|
||||
self.label['remarks'].set_text(vessel.remarks or '')
|
||||
|
||||
def edit_vessel(self, vessel):
|
||||
self.entry['vesselname'].set_text(vessel.vesselname)
|
||||
|
||||
Reference in New Issue
Block a user