diff --git a/INSTALL b/INSTALL index b2eff33..896b72a 100644 --- a/INSTALL +++ b/INSTALL @@ -31,12 +31,12 @@ the privileges for accessing and modifying it. Create database-user for application with minimum necessary rights. - CREATE USER 'ymsgui'@'localhost' IDENTIFIED BY '********'; - GRANT SELECT, INSERT, UPDATE, DELETE ON yms.* TO 'ymsgui'@'localhost'; + CREATE USER 'ymsweb'@'localhost' IDENTIFIED BY '********'; + GRANT SELECT, INSERT, UPDATE, DELETE ON yms.* TO 'ymsweb'@'localhost'; 3. Run database import -Import the mariadb.sql file into your database, which will create the tables +Import the mariadb.sql file into your database, which will create the tables. mariadb yms < mariadb.sql @@ -54,21 +54,23 @@ Optional import some sample data mariadb yms < mariadb_sample.sql 4. Initialize document storage -Customize path and accessrights to your needs - +Customize path and access rights to your needs + mkdir /var/local/yms mkdir /var/local/yms/thumb chown -R www-data /var/local/yms chmod -R 750 /var/local/yms -5. Upload webgui files +5. Install webgui + +5.1 Upload webgui files Upload all files and directories (except the install directory) to your webserver. Disallow access to include files (.inc). There is an example _htaccess file. -6. Create and edit webgui config file +5.2. Create and edit webgui config file Rename sample configfile config.php-sample: @@ -76,24 +78,26 @@ Rename sample configfile config.php-sample: Open config.inc in a text editor and fill in your database details. -7. Check file access rights for security +5.3. Check file access rights for security Configfile should be readable by webserver but not writeable. chmod 640 config.inc chgrp www-data config.inc -8. Setup local GUI +6. Setup local GUI Create a local database user with same name as your computer user and allow database acces with current unix credentials: - mysql> CREATE USER 'ymsgui'@'localhost' IDENTIFIED BY 'geheim'; - mysql> ALTER USER ymsgui@localhost IDENTIFIED VIA unix_socket; + mysql> CREATE USER 'ymsgui'@'localhost' IDENTIFIED VIA unix_socket; -Start ymdgui.py, default configuration file is automatically created +Start ymsgui.py, default configuration file is automatically created -9. Start using YMS +7. Start using YMS +Use webgui: Start your browser and login to YMS with the default username/password: captain/captain +Use local client: +Start ymsgui.py diff --git a/db/mariadb_sample.sql b/db/mariadb_sample.sql new file mode 100644 index 0000000..b571033 --- /dev/null +++ b/db/mariadb_sample.sql @@ -0,0 +1,78 @@ +/* Generic data suitable for all kind of boats + * SPDX-License-Identifier: WTFPL + */ + +INSERT INTO user (userid, login, pass, displayname, role) VALUES +(2, 'helmsman', '$2y$10$4keuVm.WD/JeRmAqp2h4MeSxxKITsKv2q07XZrxPUuT/V80CTPbje', 'Helmsman', 'helmsman'), +(3, 'sailor', '$2y$10$4keuVm.WD/JeRmAqp2h4MeSxxKITsKv2q07XZrxPUuT/V80CTPbje', 'Sailor', 'sailor'); + +INSERT INTO settings (userid, sno, valint) VALUES +(2, 1, 1), -- Vessel 1 for helmsman +(3, 1, 1); -- Vessel 1 for sailor + +INSERT INTO dropdown (ddid, ddval, ddtext) VALUES +(1, 1, 'Einrumpf'), -- Mono +(1, 2, 'Katamaran'), +(1, 3, 'Trimaran'); + +INSERT INTO dropdown (ddid, ddval, ddtext) VALUES +(2, 3, 'Dienstleister'), -- Service +(2, 4, 'Werft'), -- Shipyard +(2, 5, 'Segelmacher'), -- Sailmaker +(2, 6, 'Yachthafen'), -- Marina + +INSERT INTO dropdown (ddid, ddval, ddtext) VALUES +(3, 2, 'Bilge'), +(3, 3, 'Schwalbennest'); + +INSERT INTO dropdown (ddid, ddval, ddtext) VALUES +(4, 1, 'Rumpf'), +(4, 2, 'Decks'), +(4, 3, 'Rigg'), +(4, 4, 'Segel'), +(4, 5, 'Motor'), +(4, 6, 'Elektrik'), +(4, 7, 'Elektronik'), +(4, 8, 'Navigation'), +(4, 9, 'Pantry'); + +INSERT INTO dropdown (ddid, ddval, ddtext) VALUES +(5, 1, 'Allgemein'), +(5, 2, 'Getränke'); + +INSERT INTO dropdown (ddid, ddval, ddtext) VALUES +(6, 1, 'kg'), +(6, 2, 'Liter'), +(6, 3, 'Stück'), +(6, 4, 'Packung'), +(6, 5, 'Dose'), +(6, 6, 'Flasche'); + +INSERT INTO dropdown (ddid, ddval, ddtext) VALUES +(7, 1, 'ATO'), +(7, 2, 'Streifensicherung'), +(7, 3, 'Feinsicherung (GS)'), +(7, 4, 'Torpedosicherung'), +(7, 5, 'T-Sicherung'); + +INSERT INTO dropdown (ddid, ddval, ddtext) VALUES +(8, 1, 'mm'), +(8, 2, 'cm'), +(8, 3, 'g'), +(8, 4, 'kg'); + +INSERT INTO storage (sid, vid, sname, stype, x, y, z, remarks) VALUES +(0, 1, 'An Bord', 0, 0, 0, 0, 'Alles wo der Ort nicht spezifiziert werden kann'); + +/* Eine Liste mit häufig verwendeten Herstellern + comptype=2 +*/ + +INSERT INTO company (comptype, compname) VALUES +(2, 'Garmin'), +(2, 'Watcheye'), +(2, 'Digital Yacht'), +(2, 'B&G'), +(2, 'Raymarine'), +(2, 'Harken'), +(2, 'Selden'); diff --git a/db/minimal.sql b/db/minimal.sql index 922fa14..9d29b7f 100644 --- a/db/minimal.sql +++ b/db/minimal.sql @@ -16,6 +16,32 @@ INSERT INTO settings (userid, sno, valint) VALUES (0, 1, 0), -- Keine Bootszuordnung für SYSTEM (1, 1, 0); -- Keine Bootszuordnung für Benutzer "captain" +/* setting descriptions */ +INSERT INTO settings (userid, sno, valstr) VALUES +(-1, 1, 'vessel id'), +(-1, 100, 'equipment sorting order'), +(-1, 101, 'inventory sorting order'), +(-1, 102, 'provision sorting order'), +(-1, 103, 'storage sorting order'), +(-1, 104, 'maintenance sorting order'), +(-1, 105, 'project sorting order'), +(-1, 106, 'task sorting order'), +(-1, 107, 'measurement sorting order'), +(-1, 108, 'company sorting order'), +(-1, 109, 'document sorting order'), +(-1, 110, 'tag sorting order'), +(-1, 200, 'equipment filter json'), +(-1, 201, 'inventory filter json'), +(-1, 202, 'provision filter json'), +(-1, 203, 'storage filter json'), +(-1, 204, 'maintenance filter json'), +(-1, 205, 'project filter json'), +(-1, 206, 'task filter json'), +(-1, 207, 'measurement filter json'), +(-1, 208, 'company filter json'), +(-1, 209, 'document filter json'), +(-1, 210, 'tag filter json'); + /* Liste der Listen wird immer benötigt */ INSERT INTO dropdown (ddid, ddval, ddtext) VALUES (0, 0, 'Liste der Listen'), diff --git a/db/minimal_en.sql b/db/minimal_en.sql index 6fa427f..cb81fc4 100644 --- a/db/minimal_en.sql +++ b/db/minimal_en.sql @@ -16,6 +16,32 @@ INSERT INTO settings (userid, sno, valint) VALUES (0, 1, 0), -- No vessel for SYSTEM (1, 1, 0); -- No vessel for captain +/* setting descriptions */ +INSERT INTO settings (userid, sno, valstr) VALUES +(-1, 1, 'vessel id'), +(-1, 100, 'equipment sorting order'), +(-1, 101, 'inventory sorting order'), +(-1, 102, 'provision sorting order'), +(-1, 103, 'storage sorting order'), +(-1, 104, 'maintenance sorting order'), +(-1, 105, 'project sorting order'), +(-1, 106, 'task sorting order'), +(-1, 107, 'measurement sorting order'), +(-1, 108, 'company sorting order'), +(-1, 109, 'document sorting order'), +(-1, 110, 'tag sorting order'), +(-1, 200, 'equipment filter json'), +(-1, 201, 'inventory filter json'), +(-1, 202, 'provision filter json'), +(-1, 203, 'storage filter json'), +(-1, 204, 'maintenance filter json'), +(-1, 205, 'project filter json'), +(-1, 206, 'task filter json'), +(-1, 207, 'measurement filter json'), +(-1, 208, 'company filter json'), +(-1, 209, 'document filter json'), +(-1, 210, 'tag filter json'); + /* list of lists needed */ INSERT INTO dropdown (ddid, ddval, ddtext) VALUES (0, 0, 'list of lists'), diff --git a/yms/vessel.py b/yms/vessel.py new file mode 100644 index 0000000..e58c441 --- /dev/null +++ b/yms/vessel.py @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- + +from datetime import datetime +import MySQLdb.cursors + +class Vessel(): + + def __init__(self, dbconn, vessel_id=None): + self.conn = dbconn + self.dcur = dbconn.cursor(MySQLdb.cursors.DictCursor) + self.fields = ('vid', 'vtype', 'vesselname', 'model', 'loa', 'lwl', + 'beam', 'draught', 'draught_min', 'displacement', 'ballast', + 'beltpos_aft', 'beltpos_bow', 'shapefile', 'remarks') + if vessel_id: + self.vid = long(vessel_id) + self.load() + else: + self.vid = None + self.vtype = None + self.model = None + self.loa = None + self.lwl = None + self.beam = None + self.draught = None + self.draught_min = None + self.displacement = None + self.ballast = None + self.beltpos_aft = None + self.beltpos_bow = None + self.shapefile = None + self.remarks = None + self.data = {} # for old/new checks + + def load(self): + sql = ( + "SELECT {}".format(', '.join(self.fields)) + "FROM vessel " + "WHERE vessel_id=%s" + ) + self.dcur.execute(sql, (self.vid,)) + self.data = self.dcur.fetchone() + # TODO + self.parent_id = self.data['parent_id'] + + def save(self): + last_row_id = None + self.last_update = datetime.now() + if self.vid: + # record already available + sqlfield = [] + values = [] + for field in self.fields: + newdata = getattr(self, field) + if self.data[field] != newdata: + sqlfield.append("{}=%s".format(field)) + values.append(newdata) + self.data[field] = newdata + if values: + # only save ich there are changes + sql = ( + "UPDATE vessel SET " + ",".join(sqlfield) + + " WHERE vidid=%s" + ) + values.append(self.vid) + self.dcur.execute(sql, values) + # TODO check sql result + last_row_id = self.vid + else: + # new record + sql = ( + "INSERT INTO risk (" + ",".join(self.fields) + + ") VALUES (" + ",".join(["%s"] * len(self.fields)) + ")" + ) + values = [] + for field in self.fields: + newdata = getattr(self, field) + values.append(newdata) + self.data[field] = newdata + self.dcur.execute(sql, values) + last_row_id = self.dcur.lastrowid + self.vid = last_row_id + + def delete(self, vessel_id): + sql = "DELETE FROM vessel WHERE vid=%s" + self.cur.execute(sql, (self.vid,)) + + def __str__(self): + out = "Vessel({})".format(self.vid) + return out diff --git a/yms48.png b/yms48.png new file mode 100644 index 0000000..7a7f805 Binary files /dev/null and b/yms48.png differ