added a ssh frontend called best ssh python or
bsshpy for short. Changes to be committed: new file: bsshpy.py ssh frontend modified: readme.txt updated some needs more
This commit is contained in:
parent
18ca545440
commit
de0082611a
1
Fbroswer
Submodule
1
Fbroswer
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 1ee9caf82243dd45a72a97bf6c5de681139670e2
|
||||
171
bsshpy.py
Normal file
171
bsshpy.py
Normal file
@ -0,0 +1,171 @@
|
||||
import sys
|
||||
import os
|
||||
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
|
||||
QLineEdit, QPushButton, QTextEdit, QFileDialog, QLabel)
|
||||
from PyQt6.QtCore import QThread, pyqtSignal
|
||||
import paramiko
|
||||
|
||||
class SSHThread(QThread):
|
||||
output_received = pyqtSignal(str)
|
||||
|
||||
def __init__(self, client, command):
|
||||
super().__init__()
|
||||
self.client = client
|
||||
self.command = command
|
||||
|
||||
def run(self):
|
||||
stdin, stdout, stderr = self.client.exec_command(self.command)
|
||||
for line in stdout:
|
||||
self.output_received.emit(line.strip())
|
||||
for line in stderr:
|
||||
self.output_received.emit(line.strip())
|
||||
|
||||
class SSHWindow(QMainWindow):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.setWindowTitle("Enhanced SSH Frontend")
|
||||
self.setGeometry(100, 100, 800, 600)
|
||||
|
||||
self.client = None
|
||||
|
||||
central_widget = QWidget()
|
||||
layout = QVBoxLayout()
|
||||
|
||||
connection_layout = QHBoxLayout()
|
||||
self.host_input = QLineEdit()
|
||||
self.host_input.setPlaceholderText("Host")
|
||||
connection_layout.addWidget(self.host_input)
|
||||
|
||||
self.user_input = QLineEdit()
|
||||
self.user_input.setPlaceholderText("Username")
|
||||
connection_layout.addWidget(self.user_input)
|
||||
|
||||
self.password_input = QLineEdit()
|
||||
self.password_input.setPlaceholderText("Password")
|
||||
self.password_input.setEchoMode(QLineEdit.EchoMode.Password)
|
||||
connection_layout.addWidget(self.password_input)
|
||||
|
||||
self.connect_button = QPushButton("Connect")
|
||||
self.connect_button.clicked.connect(self.connect_ssh)
|
||||
connection_layout.addWidget(self.connect_button)
|
||||
|
||||
self.disconnect_button = QPushButton("Disconnect")
|
||||
self.disconnect_button.clicked.connect(self.disconnect_ssh)
|
||||
self.disconnect_button.setEnabled(False)
|
||||
connection_layout.addWidget(self.disconnect_button)
|
||||
|
||||
layout.addLayout(connection_layout)
|
||||
|
||||
self.output_area = QTextEdit()
|
||||
self.output_area.setReadOnly(True)
|
||||
layout.addWidget(self.output_area)
|
||||
|
||||
command_layout = QHBoxLayout()
|
||||
self.command_input = QLineEdit()
|
||||
self.command_input.setPlaceholderText("Enter command")
|
||||
command_layout.addWidget(self.command_input)
|
||||
|
||||
self.execute_button = QPushButton("Execute")
|
||||
self.execute_button.clicked.connect(self.execute_command)
|
||||
command_layout.addWidget(self.execute_button)
|
||||
|
||||
layout.addLayout(command_layout)
|
||||
|
||||
file_transfer_layout = QHBoxLayout()
|
||||
self.upload_button = QPushButton("Upload File")
|
||||
self.upload_button.clicked.connect(self.upload_file)
|
||||
file_transfer_layout.addWidget(self.upload_button)
|
||||
|
||||
self.download_button = QPushButton("Download File")
|
||||
self.download_button.clicked.connect(self.download_file)
|
||||
file_transfer_layout.addWidget(self.download_button)
|
||||
|
||||
layout.addLayout(file_transfer_layout)
|
||||
|
||||
self.status_label = QLabel("Not connected")
|
||||
layout.addWidget(self.status_label)
|
||||
|
||||
central_widget.setLayout(layout)
|
||||
self.setCentralWidget(central_widget)
|
||||
|
||||
def connect_ssh(self):
|
||||
host = self.host_input.text()
|
||||
username = self.user_input.text()
|
||||
password = self.password_input.text()
|
||||
|
||||
try:
|
||||
self.client = paramiko.SSHClient()
|
||||
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
self.client.connect(hostname=host, username=username, password=password)
|
||||
self.status_label.setText(f"Connected to {host}")
|
||||
self.connect_button.setEnabled(False)
|
||||
self.disconnect_button.setEnabled(True)
|
||||
self.output_area.append(f"Connected to {host}\n")
|
||||
except paramiko.AuthenticationException:
|
||||
self.output_area.append("Authentication failed.\n")
|
||||
except Exception as e:
|
||||
self.output_area.append(f"Error: {str(e)}\n")
|
||||
|
||||
def disconnect_ssh(self):
|
||||
if self.client:
|
||||
self.client.close()
|
||||
self.client = None
|
||||
self.status_label.setText("Not connected")
|
||||
self.connect_button.setEnabled(True)
|
||||
self.disconnect_button.setEnabled(False)
|
||||
self.output_area.append("Disconnected\n")
|
||||
|
||||
def execute_command(self):
|
||||
if not self.client:
|
||||
self.output_area.append("Not connected. Please connect first.\n")
|
||||
return
|
||||
|
||||
command = self.command_input.text()
|
||||
self.output_area.append(f"$ {command}\n")
|
||||
self.command_input.clear()
|
||||
|
||||
self.ssh_thread = SSHThread(self.client, command)
|
||||
self.ssh_thread.output_received.connect(self.update_output)
|
||||
self.ssh_thread.start()
|
||||
|
||||
def update_output(self, output):
|
||||
self.output_area.append(output + "\n")
|
||||
|
||||
def upload_file(self):
|
||||
if not self.client:
|
||||
self.output_area.append("Not connected. Please connect first.\n")
|
||||
return
|
||||
|
||||
file_path, _ = QFileDialog.getOpenFileName(self, "Select File to Upload")
|
||||
if file_path:
|
||||
try:
|
||||
sftp = self.client.open_sftp()
|
||||
remote_path = f"/home/{self.user_input.text()}/{os.path.basename(file_path)}"
|
||||
sftp.put(file_path, remote_path)
|
||||
sftp.close()
|
||||
self.output_area.append(f"Uploaded {file_path} to {remote_path}\n")
|
||||
except Exception as e:
|
||||
self.output_area.append(f"Upload failed: {str(e)}\n")
|
||||
|
||||
def download_file(self):
|
||||
if not self.client:
|
||||
self.output_area.append("Not connected. Please connect first.\n")
|
||||
return
|
||||
|
||||
remote_path, ok = QFileDialog.getText(self, "Download File", "Enter remote file path:")
|
||||
if ok and remote_path:
|
||||
try:
|
||||
sftp = self.client.open_sftp()
|
||||
local_path, _ = QFileDialog.getSaveFileName(self, "Save File As")
|
||||
if local_path:
|
||||
sftp.get(remote_path, local_path)
|
||||
sftp.close()
|
||||
self.output_area.append(f"Downloaded {remote_path} to {local_path}\n")
|
||||
except Exception as e:
|
||||
self.output_area.append(f"Download failed: {str(e)}\n")
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = QApplication(sys.argv)
|
||||
window = SSHWindow()
|
||||
window.show()
|
||||
sys.exit(app.exec())
|
||||
48
readme.txt
48
readme.txt
@ -1,43 +1,5 @@
|
||||
paq8l is an open source (GPL) file compressor and archiver.
|
||||
Last update Mar. 18, 2007 by Matt Mahoney.
|
||||
|
||||
Contents of paq8l.zip:
|
||||
|
||||
readme.txt - this file
|
||||
paq8l.exe - Win32 (MinGW g++) executable for Pentium MMX and higher
|
||||
paq-8l_intel.exe - Faster Win32 executable (compiled by Johan de Bock with Intel C++ from http://uclc.info )
|
||||
paq8l - Linux executable (by Giorgio Tani, Mar. 18, 2007)
|
||||
|
||||
paq8l.cpp - C++ source code for all versions (Mar. 8, 2007)
|
||||
paq7asm.asm - NASM/YASM assembler code for Pentium MMX or higher
|
||||
paq7asmsse.asm - NASM/YASM for Pentium 4 (SSE2) or higher in 32 bit mode
|
||||
paq7asm-x86_64.asm - YASM for x86-64 bit processors (tested in 64 bit Linux)
|
||||
|
||||
paq8l can be compiled for other processors without the assembler
|
||||
code using the -DNOASM option (but it will run slower).
|
||||
The assembler code is the same for all paq7/8 versions.
|
||||
|
||||
paq8l was written by Matt Mahoney (as paq8f) with improvements by
|
||||
Bill Pettis (based on improvements by Alexander Ratushnyak and
|
||||
Przemyslaw Skibinski in the paq8hp* series) and Serge Osnach (additional
|
||||
models), and Andrew Paterson (Borland port). The assembler code was ported
|
||||
to 64 bit by Matthew Fite and 32 bit SSE2 by wowtiger.
|
||||
|
||||
Other contributors to the PAQ project: Berto Destasio (tuning earlier
|
||||
models for better compression), Johan de Bock (benchmarking, compiling
|
||||
fast exectuables), David A. Scott (arithmetic coder improvements),
|
||||
Fabio Buffoni (speed optimizations), Jason Schmidt (compression
|
||||
improvements), Rudi Cilibrasi (text modeling), and Pavel L. Holoborodko
|
||||
(PGM image modeling), and Jari Aalto (licensing/distribution).
|
||||
|
||||
This work would not be possible without the benchmarking efforts of
|
||||
Marcus Hutter (Hutter prize), Werner Bergmans (maximumcompression.com)
|
||||
Johan de Bock (UCLC), Berto Destasio (Emilcont benchmark), Stephan Busch
|
||||
(Squeeze Chart), Leonid A. Broukhis (Calgary Corpus Challenge),
|
||||
and Black Fox.
|
||||
|
||||
A similar (but rewritten) context mixing algorithm is used in
|
||||
WinRK 3.0.3 (pwcm mode) by Malcolm Taylor. Modified versions of
|
||||
PAQ (faster but less compression) are used in UDA and WinUDA by dwing,
|
||||
and in xml-wrt by Przemyslaw Skibinski.
|
||||
|
||||
FBroswer is a sample and loop organizer and browser with extra features
|
||||
such as the ability to sample that audio you're checking out
|
||||
full midi play back support with soundfont controls
|
||||
a timer to help balance work life and personal life
|
||||
a way to keep track of what you're listening to
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user