====== Some Alternative ideas ====== Using the built in Linux services and slapping some CNet like UI on them. SQLite DB setup to play with: PRAGMA foreign_keys = ON; -- ========================= -- ACCESS GROUPS -- ========================= CREATE TABLE access_groups ( id INTEGER PRIMARY KEY CHECK(id BETWEEN 0 AND 31), name TEXT NOT NULL, permissions_mask INTEGER NOT NULL DEFAULT 0, daily_time_limit INTEGER DEFAULT 60, -- minutes download_limit INTEGER DEFAULT 100, -- files per day upload_credit_ratio REAL DEFAULT 1.0, is_sysop INTEGER DEFAULT 0 ); -- ========================= -- USERS -- ========================= CREATE TABLE users ( id INTEGER PRIMARY KEY AUTOINCREMENT, handle TEXT UNIQUE NOT NULL, real_name TEXT, password_hash TEXT NOT NULL, access_group_id INTEGER NOT NULL DEFAULT 0, override_grant_mask INTEGER DEFAULT 0, override_deny_mask INTEGER DEFAULT 0, time_limit_override INTEGER, download_limit_override INTEGER, ratio_override REAL, credit_balance INTEGER DEFAULT 0, total_calls INTEGER DEFAULT 0, total_uploads INTEGER DEFAULT 0, total_downloads INTEGER DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, last_login DATETIME, FOREIGN KEY(access_group_id) REFERENCES access_groups(id) ); -- ========================= -- MESSAGE AREAS -- ========================= CREATE TABLE message_areas ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, description TEXT, read_perm_mask INTEGER DEFAULT 0, post_perm_mask INTEGER DEFAULT 0, is_ftn INTEGER DEFAULT 0, ftn_area_tag TEXT ); -- ========================= -- MESSAGES -- ========================= CREATE TABLE messages ( id INTEGER PRIMARY KEY AUTOINCREMENT, area_id INTEGER NOT NULL, from_user_id INTEGER, to_user TEXT, subject TEXT, body TEXT NOT NULL, posted_at DATETIME DEFAULT CURRENT_TIMESTAMP, ftn_msgid TEXT, ftn_reply TEXT, FOREIGN KEY(area_id) REFERENCES message_areas(id), FOREIGN KEY(from_user_id) REFERENCES users(id) ); -- ========================= -- FILE AREAS -- ========================= CREATE TABLE file_areas ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, description TEXT, path TEXT NOT NULL, download_perm_mask INTEGER DEFAULT 0, upload_perm_mask INTEGER DEFAULT 0 ); -- ========================= -- FILE ENTRIES -- ========================= CREATE TABLE files ( id INTEGER PRIMARY KEY AUTOINCREMENT, area_id INTEGER NOT NULL, filename TEXT NOT NULL, description TEXT, uploader_id INTEGER, size INTEGER, upload_date DATETIME DEFAULT CURRENT_TIMESTAMP, download_count INTEGER DEFAULT 0, FOREIGN KEY(area_id) REFERENCES file_areas(id), FOREIGN KEY(uploader_id) REFERENCES users(id) ); -- ========================= -- DOORS -- ========================= CREATE TABLE doors ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, command TEXT NOT NULL, min_access_group INTEGER DEFAULT 0 ); -- ========================= -- NODES (Multi-node tracking) -- ========================= CREATE TABLE nodes ( id INTEGER PRIMARY KEY, user_id INTEGER, login_time DATETIME, status TEXT, FOREIGN KEY(user_id) REFERENCES users(id) ); -- ========================= -- SYSTEM CONFIG -- ========================= CREATE TABLE system_config ( key TEXT PRIMARY KEY, value TEXT ); Not sure? INSERT INTO access_groups (id, name, permissions_mask, is_sysop) VALUES (0, 'New User', 0, 0), (1, 'Regular User', 15, 0), (5, 'Power User', 255, 0), (31, 'SysOp', 4294967295, 1); VDE (Python) Field( label="Handle", db_column="handle", type="text", max_length=30 ) Field( label="Access Group", db_column="access_group_id", type="int", min=0, max=31 ) Field( label="Post Messages", type="tristate_permission", perm_bit=1 )