#!/usr/bin/env python3 """Import applications data from original ShopDB MySQL database.""" import os import sys import pymysql from dotenv import load_dotenv # Add project to path sys.path.insert(0, '/home/camp/projects/shopdb-flask') # Load environment variables load_dotenv('/home/camp/projects/shopdb-flask/.env') # Source MySQL connection (original shopdb) MYSQL_CONFIG = { 'host': '127.0.0.1', 'port': 3306, 'user': 'root', 'password': 'rootpassword', 'database': 'shopdb', 'charset': 'utf8mb4', 'cursorclass': pymysql.cursors.DictCursor } def get_mysql_connection(): """Get MySQL connection to source database.""" return pymysql.connect(**MYSQL_CONFIG) def to_bool(val): """Convert MySQL bit field to Python bool.""" if val is None: return False if isinstance(val, bytes): return val != b'\x00' return bool(val) def import_appowners(mysql_conn, db, AppOwner): """Import app owners from MySQL.""" print("Importing app owners...") cursor = mysql_conn.cursor() cursor.execute("SELECT * FROM appowners WHERE isactive = 1") owners = cursor.fetchall() count = 0 for o in owners: existing = AppOwner.query.filter_by(appownerid=o['appownerid']).first() if not existing: owner = AppOwner( appownerid=o['appownerid'], appowner=o['appowner'], sso=o.get('sso'), isactive=True ) db.session.add(owner) count += 1 db.session.commit() print(f" Imported {count} app owners") return count def import_supportteams(mysql_conn, db, SupportTeam): """Import support teams from MySQL.""" print("Importing support teams...") cursor = mysql_conn.cursor() # Note: source table has typo 'supporteamid' instead of 'supportteamid' cursor.execute("SELECT supporteamid as supportteamid, teamname, teamurl, appownerid, isactive FROM supportteams WHERE isactive = 1") teams = cursor.fetchall() count = 0 for t in teams: existing = SupportTeam.query.filter_by(supportteamid=t['supportteamid']).first() if not existing: team = SupportTeam( supportteamid=t['supportteamid'], teamname=t['teamname'], teamurl=t.get('teamurl'), appownerid=t.get('appownerid'), isactive=True ) db.session.add(team) count += 1 db.session.commit() print(f" Imported {count} support teams") return count def import_applications(mysql_conn, db, Application): """Import applications from MySQL.""" print("Importing applications...") cursor = mysql_conn.cursor() cursor.execute(""" SELECT a.*, st.supporteamid as supportteamid FROM applications a LEFT JOIN supportteams st ON a.supportteamid = st.supporteamid WHERE a.isactive = 1 """) apps = cursor.fetchall() count = 0 skipped_dupes = 0 seen_names = set() for a in apps: # Skip duplicate appnames (source has some) if a['appname'] in seen_names: skipped_dupes += 1 continue seen_names.add(a['appname']) existing = Application.query.filter_by(appname=a['appname']).first() if not existing: app = Application( appid=a['appid'], appname=a['appname'], appdescription=a.get('appdescription'), supportteamid=a.get('supportteamid'), isinstallable=to_bool(a.get('isinstallable')), applicationnotes=a.get('applicationnotes'), installpath=a.get('installpath'), applicationlink=a.get('applicationlink'), documentationpath=a.get('documentationpath'), ishidden=to_bool(a.get('ishidden')), isprinter=to_bool(a.get('isprinter')), islicenced=to_bool(a.get('islicenced')), image=a.get('image'), isactive=True ) db.session.add(app) count += 1 db.session.commit() print(f" Imported {count} applications (skipped {skipped_dupes} duplicates)") return count def import_appversions(mysql_conn, db, AppVersion, Application): """Import application versions from MySQL.""" print("Importing app versions...") cursor = mysql_conn.cursor() cursor.execute(""" SELECT av.*, a.appname FROM appversions av JOIN applications a ON av.appid = a.appid WHERE av.isactive = 1 """) versions = cursor.fetchall() # Build app lookup by name (since we may have different IDs) app_map = {a.appname: a.appid for a in Application.query.all()} count = 0 skipped = 0 for v in versions: # Look up app by name new_appid = app_map.get(v['appname']) if not new_appid: skipped += 1 continue existing = AppVersion.query.filter_by( appid=new_appid, version=v['version'] ).first() if not existing: version = AppVersion( appversionid=v['appversionid'], appid=new_appid, version=v['version'], releasedate=v.get('releasedate'), notes=v.get('notes'), isactive=True ) db.session.add(version) count += 1 db.session.commit() print(f" Imported {count} app versions (skipped {skipped})") return count def import_installedapps(mysql_conn, db, InstalledApp, Machine, Application, AppVersion): """Import installed apps (PC-application relationships) from MySQL.""" print("Importing installed apps...") cursor = mysql_conn.cursor() cursor.execute(""" SELECT ia.*, m.machinenumber, a.appname, av.version as version_str FROM installedapps ia JOIN machines m ON ia.machineid = m.machineid JOIN applications a ON ia.appid = a.appid LEFT JOIN appversions av ON ia.appversionid = av.appversionid WHERE ia.isactive = 1 """) installed = cursor.fetchall() # Build lookup for machines by machinenumber (since IDs may differ) machine_map = {m.machinenumber: m.machineid for m in Machine.query.all()} # Build app lookup by name app_map = {a.appname: a.appid for a in Application.query.all()} # Build version lookup by (appid, version) version_map = {(v.appid, v.version): v.appversionid for v in AppVersion.query.all()} count = 0 skipped = 0 for i in installed: # Look up machine by machinenumber new_machineid = machine_map.get(i['machinenumber']) if not new_machineid: skipped += 1 continue # Look up app by name new_appid = app_map.get(i['appname']) if not new_appid: skipped += 1 continue # Look up version if exists new_versionid = None if i.get('version_str'): new_versionid = version_map.get((new_appid, i['version_str'])) # Check if already exists existing = InstalledApp.query.filter_by( machineid=new_machineid, appid=new_appid ).first() if not existing: installed_app = InstalledApp( machineid=new_machineid, appid=new_appid, appversionid=new_versionid, isactive=True ) db.session.add(installed_app) count += 1 elif new_versionid and not existing.appversionid: # Update existing with version if we now have it existing.appversionid = new_versionid count += 1 db.session.commit() print(f" Imported {count} installed apps (skipped {skipped})") return count def import_knowledgebase(mysql_conn, db, KnowledgeBase, Application): """Import knowledge base articles from MySQL.""" print("Importing knowledge base articles...") cursor = mysql_conn.cursor() cursor.execute(""" SELECT kb.*, a.appname FROM knowledgebase kb LEFT JOIN applications a ON kb.appid = a.appid WHERE kb.isactive = 1 """) articles = cursor.fetchall() # Build app lookup by name app_map = {a.appname: a.appid for a in Application.query.all()} count = 0 skipped = 0 for article in articles: existing = KnowledgeBase.query.filter_by(linkid=article['linkid']).first() if not existing: # Look up app by name if exists new_appid = None if article.get('appname'): new_appid = app_map.get(article['appname']) kb = KnowledgeBase( linkid=article['linkid'], appid=new_appid, shortdescription=article.get('shortdescription'), linkurl=article.get('linkurl'), keywords=article.get('keywords'), clicks=article.get('clicks') or 0, isactive=True ) db.session.add(kb) count += 1 else: skipped += 1 db.session.commit() print(f" Imported {count} knowledge base articles (skipped {skipped} existing)") return count def main(): """Main import function.""" print("=" * 60) print("ShopDB Applications Import") print("=" * 60) from shopdb import create_app from shopdb.extensions import db from shopdb.core.models import Application, AppOwner, SupportTeam, AppVersion, InstalledApp, Machine, KnowledgeBase app = create_app() with app.app_context(): # Create any missing tables print("\nCreating tables if needed...") db.create_all() print("\nConnecting to MySQL...") mysql_conn = get_mysql_connection() print(" Connected!") try: print("\n--- Application Data ---") import_appowners(mysql_conn, db, AppOwner) import_supportteams(mysql_conn, db, SupportTeam) import_applications(mysql_conn, db, Application) import_appversions(mysql_conn, db, AppVersion, Application) print("\n--- PC-Application Relationships ---") import_installedapps(mysql_conn, db, InstalledApp, Machine, Application, AppVersion) print("\n--- Knowledge Base ---") import_knowledgebase(mysql_conn, db, KnowledgeBase, Application) print("\n" + "=" * 60) print("Import complete!") print("=" * 60) finally: mysql_conn.close() if __name__ == '__main__': main()