No edit summary
No edit summary
 
Line 4: Line 4:
Pertama lakukan instalasi pip/dependensi untuk menjalankan script python, berikut adalah scriptnya<syntaxhighlight lang="python">
Pertama lakukan instalasi pip/dependensi untuk menjalankan script python, berikut adalah scriptnya<syntaxhighlight lang="python">
pip install paramiko scp
pip install paramiko scp
</syntaxhighlight>
</syntaxhighlight>Setelah menjalankan perintah di atas, berikut adalah script pythinnya.<syntaxhighlight lang="python" line="1">
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import paramiko
from scp import SCPClient
import os
import threading
import sys
 
class SCPTransferApp:
    def __init__(self, root):
        self.root = root
        self.root.title("SCP Transfer - Windows to Linux")
        self.root.geometry("700x600")
       
        self.setup_ui()
       
    def setup_ui(self):
        # Main frame
        main_frame = ttk.Frame(self.root, padding="10")
        main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
       
        # Server Configuration
        server_frame = ttk.LabelFrame(main_frame, text="Server Configuration", padding="10")
        server_frame.grid(row=0, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=5)
       
        ttk.Label(server_frame, text="Host:").grid(row=0, column=0, sticky=tk.W, pady=5)
        self.host_entry = ttk.Entry(server_frame, width=30)
        self.host_entry.grid(row=0, column=1, pady=5, padx=5)
        self.host_entry.insert(0, "192.168.1.100")
       
        ttk.Label(server_frame, text="Port:").grid(row=0, column=2, sticky=tk.W, pady=5, padx=(20,0))
        self.port_entry = ttk.Entry(server_frame, width=10)
        self.port_entry.insert(0, "22")
        self.port_entry.grid(row=0, column=3, pady=5, padx=5)
       
        ttk.Label(server_frame, text="Username:").grid(row=1, column=0, sticky=tk.W, pady=5)
        self.username_entry = ttk.Entry(server_frame, width=30)
        self.username_entry.grid(row=1, column=1, pady=5, padx=5)
        self.username_entry.insert(0, "username")
       
        ttk.Label(server_frame, text="Password:").grid(row=1, column=2, sticky=tk.W, pady=5, padx=(20,0))
        self.password_entry = ttk.Entry(server_frame, width=15, show="*")
        self.password_entry.grid(row=1, column=3, pady=5, padx=5)
       
        # File Selection
        file_frame = ttk.LabelFrame(main_frame, text="File Transfer", padding="10")
        file_frame.grid(row=1, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=5)
       
        ttk.Label(file_frame, text="Local File:").grid(row=0, column=0, sticky=tk.W, pady=5)
        self.local_file_entry = ttk.Entry(file_frame, width=50)
        self.local_file_entry.grid(row=0, column=1, pady=5, padx=5)
       
        ttk.Button(file_frame, text="Browse", command=self.browse_file).grid(row=0, column=2, pady=5, padx=5)
       
        ttk.Label(file_frame, text="Remote Path:").grid(row=1, column=0, sticky=tk.W, pady=5)
        self.remote_path_entry = ttk.Entry(file_frame, width=50)
        self.remote_path_entry.insert(0, "/home/username/")
        self.remote_path_entry.grid(row=1, column=1, pady=5, padx=5)
       
        # Progress and Log
        progress_frame = ttk.LabelFrame(main_frame, text="Progress & Log", padding="10")
        progress_frame.grid(row=2, column=0, columnspan=2, sticky=(tk.W, tk.E, tk.N, tk.S), pady=5)
       
        self.progress = ttk.Progressbar(progress_frame, mode='indeterminate')
        self.progress.grid(row=0, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=5)
       
        self.log_text = tk.Text(progress_frame, height=12, width=80)
        self.log_text.grid(row=1, column=0, columnspan=2, pady=5)
       
        scrollbar = ttk.Scrollbar(progress_frame, orient="vertical", command=self.log_text.yview)
        scrollbar.grid(row=1, column=2, sticky=(tk.N, tk.S))
        self.log_text.configure(yscrollcommand=scrollbar.set)
       
        # Buttons
        button_frame = ttk.Frame(main_frame)
        button_frame.grid(row=3, column=0, columnspan=2, pady=10)
       
        self.transfer_btn = ttk.Button(button_frame, text="Transfer File", command=self.start_transfer)
        self.transfer_btn.grid(row=0, column=0, padx=5)
       
        ttk.Button(button_frame, text="Test Connection", command=self.test_connection).grid(row=0, column=1, padx=5)
        ttk.Button(button_frame, text="Clear Log", command=self.clear_log).grid(row=0, column=2, padx=5)
        ttk.Button(button_frame, text="Exit", command=self.root.quit).grid(row=0, column=3, padx=5)
       
    def browse_file(self):
        filename = filedialog.askopenfilename(
            title="Select file to transfer",
            filetypes=[("All files", "*.*")]
        )
        if filename:
            self.local_file_entry.delete(0, tk.END)
            self.local_file_entry.insert(0, filename)
   
    def log_message(self, message):
        self.log_text.insert(tk.END, f"{message}\n")
        self.log_text.see(tk.END)
        self.root.update_idletasks()
   
    def clear_log(self):
        self.log_text.delete(1.0, tk.END)
   
    def test_connection(self):
        """Test SSH connection without file transfer"""
        if not self.validate_basic_inputs():
            return
       
        thread = threading.Thread(target=self._test_connection)
        thread.daemon = True
        thread.start()
   
    def _test_connection(self):
        try:
            host = self.host_entry.get()
            port = int(self.port_entry.get())
            username = self.username_entry.get()
            password = self.password_entry.get()
           
            self.log_message(f"Testing connection to {host}:{port}...")
           
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ssh.connect(host, port=port, username=username, password=password, timeout=10)
           
            self.log_message("✓ Connection successful!")
            ssh.close()
           
        except Exception as e:
            self.log_message(f"✗ Connection failed: {str(e)}")
   
    def start_transfer(self):
        if not self.validate_inputs():
            return
       
        self.transfer_btn.config(state='disabled')
        self.progress.start()
       
        # Run transfer in separate thread
        thread = threading.Thread(target=self.transfer_file)
        thread.daemon = True
        thread.start()
   
    def validate_basic_inputs(self):
        if not self.host_entry.get():
            messagebox.showerror("Error", "Please enter host address")
            return False
        if not self.username_entry.get():
            messagebox.showerror("Error", "Please enter username")
            return False
        if not self.password_entry.get():
            messagebox.showerror("Error", "Please enter password")
            return False
        return True
   
    def validate_inputs(self):
        if not self.validate_basic_inputs():
            return False
        if not self.local_file_entry.get():
            messagebox.showerror("Error", "Please select local file")
            return False
        if not os.path.exists(self.local_file_entry.get()):
            messagebox.showerror("Error", "Local file does not exist")
            return False
        return True
   
    def transfer_file(self):
        try:
            host = self.host_entry.get()
            port = int(self.port_entry.get())
            username = self.username_entry.get()
            password = self.password_entry.get()
            local_file = self.local_file_entry.get()
            remote_path = self.remote_path_entry.get()
           
            self.log_message(f"Connecting to {host}:{port}...")
           
            # Create SSH client
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
           
            # Connect to server
            ssh.connect(host, port=port, username=username, password=password)
            self.log_message("✓ Connected successfully!")
           
            # Get file info
            file_size = os.path.getsize(local_file)
            file_name = os.path.basename(local_file)
            remote_file = os.path.join(remote_path, file_name).replace('\\', '/')
           
            self.log_message(f"Transferring: {file_name}")
            self.log_message(f"File size: {file_size} bytes")
            self.log_message(f"Remote path: {remote_file}")
           
            # Create SCP client and transfer file
            with SCPClient(ssh.get_transport()) as scp:
                scp.put(local_file, remote_file)
           
            self.log_message("✓ File transferred successfully!")
           
            # Verify file transfer
            stdin, stdout, stderr = ssh.exec_command(f'ls -la "{remote_file}"')
            result = stdout.read().decode()
            if file_name in result:
                self.log_message("✓ File verification: SUCCESS")
               
                # Get file size on remote
                stdin, stdout, stderr = ssh.exec_command(f'stat -c%s "{remote_file}"')
                remote_size = stdout.read().decode().strip()
                self.log_message(f"Remote file size: {remote_size} bytes")
               
            else:
                self.log_message("⚠ File verification: WARNING")
           
            ssh.close()
            self.log_message("Connection closed")
           
        except paramiko.AuthenticationException:
            self.log_message("✗ Authentication failed. Please check username/password.")
        except paramiko.SSHException as e:
            self.log_message(f"✗ SSH error: {str(e)}")
        except Exception as e:
            self.log_message(f"✗ ERROR: {str(e)}")
        finally:
            self.root.after(0, self.transfer_complete)
   
    def transfer_complete(self):
        self.progress.stop()
        self.transfer_btn.config(state='normal')
 
def main():
    root = tk.Tk()
    app = SCPTransferApp(root)
    root.mainloop()
 
if __name__ == "__main__":
    main()
</syntaxhighlight>Simpan dengan nama <code>aplikasi-scp.py</code>
 
Setelah itu jalankan aplikasinya dengan perintah<syntaxhighlight lang="python">
python aplikasi-scp.py
</syntaxhighlight>jika tidak ada error, maka akan tampil seperti pada gambar berikut ini
 
[[File:Aplikasi-python-scp.jpg]]

Latest revision as of 07:10, 25 October 2025

Aplikasi-python-scp

Ini adalah script python untuk membuat aplikasi SCP di windows, tujuannya adalah untuk mempermudah kita melakukan copy file dari Windows ke Linux.

Pertama lakukan instalasi pip/dependensi untuk menjalankan script python, berikut adalah scriptnya

pip install paramiko scp

Setelah menjalankan perintah di atas, berikut adalah script pythinnya.

import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import paramiko
from scp import SCPClient
import os
import threading
import sys

class SCPTransferApp:
    def __init__(self, root):
        self.root = root
        self.root.title("SCP Transfer - Windows to Linux")
        self.root.geometry("700x600")
        
        self.setup_ui()
        
    def setup_ui(self):
        # Main frame
        main_frame = ttk.Frame(self.root, padding="10")
        main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # Server Configuration
        server_frame = ttk.LabelFrame(main_frame, text="Server Configuration", padding="10")
        server_frame.grid(row=0, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=5)
        
        ttk.Label(server_frame, text="Host:").grid(row=0, column=0, sticky=tk.W, pady=5)
        self.host_entry = ttk.Entry(server_frame, width=30)
        self.host_entry.grid(row=0, column=1, pady=5, padx=5)
        self.host_entry.insert(0, "192.168.1.100")
        
        ttk.Label(server_frame, text="Port:").grid(row=0, column=2, sticky=tk.W, pady=5, padx=(20,0))
        self.port_entry = ttk.Entry(server_frame, width=10)
        self.port_entry.insert(0, "22")
        self.port_entry.grid(row=0, column=3, pady=5, padx=5)
        
        ttk.Label(server_frame, text="Username:").grid(row=1, column=0, sticky=tk.W, pady=5)
        self.username_entry = ttk.Entry(server_frame, width=30)
        self.username_entry.grid(row=1, column=1, pady=5, padx=5)
        self.username_entry.insert(0, "username")
        
        ttk.Label(server_frame, text="Password:").grid(row=1, column=2, sticky=tk.W, pady=5, padx=(20,0))
        self.password_entry = ttk.Entry(server_frame, width=15, show="*")
        self.password_entry.grid(row=1, column=3, pady=5, padx=5)
        
        # File Selection
        file_frame = ttk.LabelFrame(main_frame, text="File Transfer", padding="10")
        file_frame.grid(row=1, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=5)
        
        ttk.Label(file_frame, text="Local File:").grid(row=0, column=0, sticky=tk.W, pady=5)
        self.local_file_entry = ttk.Entry(file_frame, width=50)
        self.local_file_entry.grid(row=0, column=1, pady=5, padx=5)
        
        ttk.Button(file_frame, text="Browse", command=self.browse_file).grid(row=0, column=2, pady=5, padx=5)
        
        ttk.Label(file_frame, text="Remote Path:").grid(row=1, column=0, sticky=tk.W, pady=5)
        self.remote_path_entry = ttk.Entry(file_frame, width=50)
        self.remote_path_entry.insert(0, "/home/username/")
        self.remote_path_entry.grid(row=1, column=1, pady=5, padx=5)
        
        # Progress and Log
        progress_frame = ttk.LabelFrame(main_frame, text="Progress & Log", padding="10")
        progress_frame.grid(row=2, column=0, columnspan=2, sticky=(tk.W, tk.E, tk.N, tk.S), pady=5)
        
        self.progress = ttk.Progressbar(progress_frame, mode='indeterminate')
        self.progress.grid(row=0, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=5)
        
        self.log_text = tk.Text(progress_frame, height=12, width=80)
        self.log_text.grid(row=1, column=0, columnspan=2, pady=5)
        
        scrollbar = ttk.Scrollbar(progress_frame, orient="vertical", command=self.log_text.yview)
        scrollbar.grid(row=1, column=2, sticky=(tk.N, tk.S))
        self.log_text.configure(yscrollcommand=scrollbar.set)
        
        # Buttons
        button_frame = ttk.Frame(main_frame)
        button_frame.grid(row=3, column=0, columnspan=2, pady=10)
        
        self.transfer_btn = ttk.Button(button_frame, text="Transfer File", command=self.start_transfer)
        self.transfer_btn.grid(row=0, column=0, padx=5)
        
        ttk.Button(button_frame, text="Test Connection", command=self.test_connection).grid(row=0, column=1, padx=5)
        ttk.Button(button_frame, text="Clear Log", command=self.clear_log).grid(row=0, column=2, padx=5)
        ttk.Button(button_frame, text="Exit", command=self.root.quit).grid(row=0, column=3, padx=5)
        
    def browse_file(self):
        filename = filedialog.askopenfilename(
            title="Select file to transfer",
            filetypes=[("All files", "*.*")]
        )
        if filename:
            self.local_file_entry.delete(0, tk.END)
            self.local_file_entry.insert(0, filename)
    
    def log_message(self, message):
        self.log_text.insert(tk.END, f"{message}\n")
        self.log_text.see(tk.END)
        self.root.update_idletasks()
    
    def clear_log(self):
        self.log_text.delete(1.0, tk.END)
    
    def test_connection(self):
        """Test SSH connection without file transfer"""
        if not self.validate_basic_inputs():
            return
        
        thread = threading.Thread(target=self._test_connection)
        thread.daemon = True
        thread.start()
    
    def _test_connection(self):
        try:
            host = self.host_entry.get()
            port = int(self.port_entry.get())
            username = self.username_entry.get()
            password = self.password_entry.get()
            
            self.log_message(f"Testing connection to {host}:{port}...")
            
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ssh.connect(host, port=port, username=username, password=password, timeout=10)
            
            self.log_message("✓ Connection successful!")
            ssh.close()
            
        except Exception as e:
            self.log_message(f"✗ Connection failed: {str(e)}")
    
    def start_transfer(self):
        if not self.validate_inputs():
            return
        
        self.transfer_btn.config(state='disabled')
        self.progress.start()
        
        # Run transfer in separate thread
        thread = threading.Thread(target=self.transfer_file)
        thread.daemon = True
        thread.start()
    
    def validate_basic_inputs(self):
        if not self.host_entry.get():
            messagebox.showerror("Error", "Please enter host address")
            return False
        if not self.username_entry.get():
            messagebox.showerror("Error", "Please enter username")
            return False
        if not self.password_entry.get():
            messagebox.showerror("Error", "Please enter password")
            return False
        return True
    
    def validate_inputs(self):
        if not self.validate_basic_inputs():
            return False
        if not self.local_file_entry.get():
            messagebox.showerror("Error", "Please select local file")
            return False
        if not os.path.exists(self.local_file_entry.get()):
            messagebox.showerror("Error", "Local file does not exist")
            return False
        return True
    
    def transfer_file(self):
        try:
            host = self.host_entry.get()
            port = int(self.port_entry.get())
            username = self.username_entry.get()
            password = self.password_entry.get()
            local_file = self.local_file_entry.get()
            remote_path = self.remote_path_entry.get()
            
            self.log_message(f"Connecting to {host}:{port}...")
            
            # Create SSH client
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            
            # Connect to server
            ssh.connect(host, port=port, username=username, password=password)
            self.log_message("✓ Connected successfully!")
            
            # Get file info
            file_size = os.path.getsize(local_file)
            file_name = os.path.basename(local_file)
            remote_file = os.path.join(remote_path, file_name).replace('\\', '/')
            
            self.log_message(f"Transferring: {file_name}")
            self.log_message(f"File size: {file_size} bytes")
            self.log_message(f"Remote path: {remote_file}")
            
            # Create SCP client and transfer file
            with SCPClient(ssh.get_transport()) as scp:
                scp.put(local_file, remote_file)
            
            self.log_message("✓ File transferred successfully!")
            
            # Verify file transfer
            stdin, stdout, stderr = ssh.exec_command(f'ls -la "{remote_file}"')
            result = stdout.read().decode()
            if file_name in result:
                self.log_message("✓ File verification: SUCCESS")
                
                # Get file size on remote
                stdin, stdout, stderr = ssh.exec_command(f'stat -c%s "{remote_file}"')
                remote_size = stdout.read().decode().strip()
                self.log_message(f"Remote file size: {remote_size} bytes")
                
            else:
                self.log_message("⚠ File verification: WARNING")
            
            ssh.close()
            self.log_message("Connection closed")
            
        except paramiko.AuthenticationException:
            self.log_message("✗ Authentication failed. Please check username/password.")
        except paramiko.SSHException as e:
            self.log_message(f"✗ SSH error: {str(e)}")
        except Exception as e:
            self.log_message(f"✗ ERROR: {str(e)}")
        finally:
            self.root.after(0, self.transfer_complete)
    
    def transfer_complete(self):
        self.progress.stop()
        self.transfer_btn.config(state='normal')

def main():
    root = tk.Tk()
    app = SCPTransferApp(root)
    root.mainloop()

if __name__ == "__main__":
    main()

Simpan dengan nama aplikasi-scp.py Setelah itu jalankan aplikasinya dengan perintah

python aplikasi-scp.py

jika tidak ada error, maka akan tampil seperti pada gambar berikut ini