import os import sys import pyodbc import csv from configparser import ConfigParser import paramiko import time import re import html # Load configuration from a file (e.g., config.ini) config = ConfigParser() config.read('config.ini') groupingIds = config['Clients']['GroupIDs'].split(',') groupingIds = [int(id) for id in groupingIds] groupingIds_str = ",".join(map(str, groupingIds)) cliCount = 0 server = config['Database']['Server'] database = config['Database']['Database'] username = config['Database']['Username'] password = config['Database']['Password'] output_csv = config['Files']['output'] SFTPAddress = config['SFTP']['address'] SFTPPort = config['SFTP']['port'] SFTPUsername= config['SFTP']['username'] SFTPPassword = config['SFTP']['password'] SFTPDestination = config['SFTP']['destination'] connection_string = ( f"DRIVER={{ODBC Driver 18 for SQL Server}};" f"SERVER={server};" f"DATABASE={database};" f"UID={username};" f"PWD={password};" f"TrustServerCertificate=yes;" ) def sanitize_field(value): if isinstance(value, str): value = html.unescape(value) value = value.replace('\n', ' ').replace('\r', ' ').replace('\t', ' ') value = value.replace(';', ',') value = value.replace('"', '') value = re.sub(r'\s+', ' ', value) value = value.strip() return value return value try: with pyodbc.connect(connection_string) as connection: with connection.cursor() as cursor: clients_query = f""" SELECT DISTINCT m.Client_No, m.ClientID, m.Name, m.Location, m.Loc2, m.OKPassword, pt.Name, ac.ControlName, REPLACE(REPLACE(REPLACE(REPLACE(CAST(m.SpecRequest AS VARCHAR(MAX)), CHAR(13), '
'), CHAR(10), '
'), CHAR(9), '
'), ';', '') AS SpecRequest, REPLACE(REPLACE(REPLACE(REPLACE(CAST(m.SP_Page AS VARCHAR(MAX)), CHAR(13), '
'), CHAR(10), '
'), CHAR(9), '
'), ';', '') AS SP_page, m.DecommissionDate, REPLACE(REPLACE(REPLACE(REPLACE(CAST(m.DecommissionReason AS VARCHAR(MAX)), CHAR(13), '
'), CHAR(10), '
'), CHAR(9), '
'), ';', '') AS DecommissionReason FROM Memalarm m JOIN ClientGroupingAssign cg ON m.Client_No = cg.Client_No LEFT JOIN AccessControlNames ac ON m.Client_No = ac.ClientNo LEFT JOIN PanelTypes pt ON m.PanelTypeId = pt.IDPanelTypes WHERE cg.ClientGroupingID IN ({groupingIds_str}) AND (m.TemplateType = '0' OR m.TemplateType IS NULL) """ # Other queries remain the same users_query = """ SELECT u.UserId, u.User_Name, u.PhoneNo3, u.Email FROM Muser u JOIN UserToClient uc ON u.UserId = uc.UserId WHERE u.Type IN ('U','Z','E') AND uc.ClientNo = ?; """ zones_query = """ SELECT z.Zone_No, z.Zone_area FROM Mzone z WHERE z.Client_No = ?; """ key_query = """ SELECT k.Name ,REPLACE(REPLACE(REPLACE(CAST(k.Description AS VARCHAR(MAX)), CHAR(13), ' '), CHAR(10), ' '), CHAR(9), ' ') AS Description FROM [Patriot].[dbo].[Key] k WHERE k.ClientNo = ?; """ # Execute the clients query cursor.execute(clients_query) clients = cursor.fetchall() with open(output_csv, mode='w', newline='', encoding='latin-1', errors='replace') as csvfile: csv_writer = csv.writer(csvfile, delimiter=';') for client in clients: cliCount += 1 csv_writer.writerow(['Client_No', 'ClientID', 'Name', 'Location', 'Loc2', 'OKPassword', 'PanelType', 'DeviceRef', 'SpecRequest', 'ExtraInfo', 'DecommissionDate', 'DecommissionReason']) csv_writer.writerow([sanitize_field(field) for field in client]) csv_writer.writerow(['UserID', 'User_Name', 'PhoneNo3', 'Email']) cursor.execute(users_query, client.Client_No) users = cursor.fetchall() for user in users: csv_writer.writerow([sanitize_field(field) for field in user]) csv_writer.writerow(['Zone_No', 'Zone_area']) cursor.execute(zones_query, client.Client_No) zones = cursor.fetchall() for zone in zones: csv_writer.writerow([sanitize_field(field) for field in zone]) csv_writer.writerow(['Key_Name', 'Key_Desc']) cursor.execute(key_query, client.Client_No) keys = cursor.fetchall() for key in keys: csv_writer.writerow([sanitize_field(field) for field in key]) print(f"{cliCount} Fetched: {client.Client_No}, {client[2]}") time.sleep(0.1) print(f"{cliCount} clients exported successfully to {output_csv}") output_csv_path = f"{output_csv}" # Path to the CSV file on the Windows server try: # Check if the file exists on the Windows server if not os.path.exists(output_csv_path): raise FileNotFoundError(f"File {output_csv_path} does not exist") # Create an SSH client and set the policy to automatically add host keys ssh_client = paramiko.SSHClient() ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # Connect to the Ubuntu server using SSH with username and password print(f"Connecting to {SFTPAddress}...") ssh_client.connect(SFTPAddress, username=SFTPUsername, password=SFTPPassword) print("Connected successfully.") # Define the remote destination path on the Ubuntu server print(f"Transfering file from {output_csv_path} to {SFTPDestination}{output_csv}...") # Transfer the file from the Windows server to the Ubuntu server sftp = ssh_client.open_sftp() try: sftp.put(output_csv_path, os.path.join(SFTPDestination, output_csv)) print("File transfer completed successfully.") except Exception as e: print(f"Error transferring file: {e}") # Close the SFTP connection and SSH client sftp.close() ssh_client.close() print("Disconnected.") except FileNotFoundError as e: print(e) except Exception as e: print(f"An error occurred: {e}") except pyodbc.Error as e: import sys print(f"An error occurred: {e}", file=sys.stderr)