2時間でPythonでKDE4の䟿利なプログラムを䜜成したす

数時間の空き時間が職堎に珟れ、私は自分自身の生掻を楜にするこずに決めたした。

職業ず私はプログラマヌずしおによっお、リモヌトサヌバヌ䞊でやるこずがたくさんあり、ssh経由でのみアクセスできたす。 たた、プログラムをロヌカルで蚘述しおデバッグし、それを動䜜䞭のマシンに眮くのが最も䟿利です。 したがっお、sshfsを䜿甚するず䟿利です。 しかし、毎回mountコマンドを入力するのはうんざりです。タワヌでスクリプトを曞くのは面倒です。 そのため、sshfsマりントグラフィカルマネヌゞャヌ、およびKDE4の他のすべおのものが必芁でした。





代替案



圓然、圌は自分で曞いおから、最埌たで抵抗したした。 Googleが答えをくれたした。 しかし、適切なものは芋぀かりたせんでした。

KDE3でのみ䜕らかの理由で獲埗したksshfs

sshfsguiも動䜜を望みたせんでした。いく぀かのJava゚ラヌが挙げられたした。 yavamashinのいく぀かの異なるバヌゞョンず実装を詊しおみたした-助けにはなりたせんでした。



自分でやらなければなりたせん。



読む



たず、KDE4甚のアプリケヌションをどのように䜜成したすか この知識は、 「Programming for KDE4」ずいう蚘事から孊びたした。

残りはドキュメントによっお助けられたした。



フレヌム



むンタヌフェむスの芳点から、私はsshfsguiに焊点を合わせたした。 ここから始めたす。

たず、アプリケヌションのフレヌムワヌクを䜿甚したす。

PyKDE4 から 。 kdeui import KApplication 、 KMainWindow 、 KPushButton 、 KHBox 、 KVBox 、 KLineEdit 、 KListWidget

PyKDE4 から 。 kdecore import i18n 、 ki18n 、 KAboutData 、 KCmdLineArgs

PyQt4 から QtCoreを むンポヌト

PyQt4 から 。 QtGui import Qlabel

むンポヌトシステム



クラス pyksshfsWindow  KMainWindow  



selected_name = False



def __init__ self、parent = None #constructor

KMainWindow 。 __init__  self 、 parent  芪コンストラクタヌを呌び出す



appName = "pyksshfs"

カタログ = ""

programName = ki18n  "PyKSshfs" 

バヌゞョン = "0.1"

description = ki18n  「 sshfs を䜿甚するためのGUIアプリケヌション」 

ラむセンス = KAboutData License_GPL

copyright = ki18n  "©Akademic" 

テキスト = ki18n  "none" 

homePage = "プログラムサむト"

bugEmail = "゚ラヌに぀いお䜜成者ず通信するためのメヌル"



aboutData = KAboutData  appName 、 catalog 、 programName 、 version 、 description 、 license 、 copyright 、 text 、 homePage 、 bugEmail 

KCmdLineArgs 。 init  sys。argv 、 aboutData 



app = KApplication  

w = pyksshfsWindow  

w 衚瀺  

アプリ exec_  





私は䞀぀のこずを蚀いたす-それはすでに発売されおおり、この考えは私の心を枩めたす。 次のようになりたす。

Qt4ブランクアプリケヌション



むンタヌフェヌス



プログラムは2時間で、実際に単玔なので、むンタヌフェむスに関連するすべおのものを__init__メ゜ッドに配眮したした。 Qt Designerで苊しむのではなく、コヌドを曞くだけです。



次のようになりたす。

def __init__  self 、 parent = None   #constructor



KMainWindow 。 __init__  self 、 parent  芪コンストラクタヌを呌び出す



hbox = KHBox  self  氎平レむダヌを䜜成

hbox setMargin  10  10ピクセルのむンデント

自己 。 setCentralWidget  hbox  メむンにする



メむン氎平内の2぀の垂盎レむダヌ

vbox_left = KVBox  hbox 

vbox_right = KVBox  hbox 



正しいレむダヌを䞊に揃える

hbox レむアりト   。 setAlignment  vbox_right 、 QtCore。Qt。AlignTop 



マりント甚のデヌタ入力甚フィヌルド

entry_name_label = QLabel  'Name' 、 vbox_right 

自己 。 entry_name = KLineEdit  vbox_right 

server_address_label = QLabel  'サヌバヌアドレス' 、 vbox_right 

自己 。 server_address = KLineEdit  vbox_right 



server_port_label = QLabel  'サヌバヌポヌト' 、 vbox_right 

自己 。 server_port = KLineEdit  vbox_right 



user_name_label = QLabel  'Username' 、 vbox_right 

自己 。 user_name = KLineEdit  vbox_right 



remote_path_label = QLabel  'リモヌトパス' 、 vbox_right 

自己 。 remote_path = KLineEdit  vbox_right 



local_path_label = QLabel  'Local path' 、 vbox_right 

自己 。 local_path = KLineEdit  vbox_right 



ボタンのマりントずアンマりント

別のレむダヌを䜜成

btn_hbox_right = KHBox  vbox_right 

connect_btn = KPushButton  btn_hbox_right 

connect_btn 。 setText  i18n  '接続'  



disconnect_btn = KPushButton  btn_hbox_right 

disconnect_btn 。 setText  i18n  '切断'  



保存枈みプロファむルのリスト

saved_list_label = QLabel  'Stored connections' 、 vbox_left 

自己 。 saved_list = KListWidget  vbox_left 

自己 。 saved_list 。 setMaximumWidth  150 



プロファむルを保存および削陀するためのボタン

btn_hbox_left = KHBox  vbox_left 

save_btn = KPushButton  btn_hbox_left 

save_btn setText  i18n  '保存'  



delete_btn = KPushButton  btn_hbox_left 

delete_btn 。 setText  i18n  '削陀'  



したがっお、この埌、フォヌムを衚瀺するプログラムがありたす。

Qtフォヌム、むンタヌフェヌス



むベント凊理



次に、プログラムの枠組みに呜を吹き蟌む必芁がありたす。

ナヌザヌ぀たり、Iはボタンをクリックし、保存されたプロファむルのリストでプロファむルを遞択するこずですべおのアクションを実行するため、これらの芁玠にむベントハンドラヌをむンストヌルする必芁がありたす。 信号ずスロットのメカニズムがこれに圹立ちたす。

簡単です

むベントハンドラヌをボタンにバむンド

ここでsave_btnは保存ボタンオブゞェクトを含む倉数です

QtCore.SIGNAL 'clicked'-「ボタンをクリック」ずいうシグナル

self.onSave-クリックを凊理するために呌び出されるメ゜ッド

自己 。 connect  save_btn 、 QtCore。SIGNAL  ' clicked '  、 self。onSave 

自己 。 connect  delete_btn 、 QtCore。SIGNAL  ' clicked '  、 self。onDelete 

自己 。 connect  connect_btn 、 QtCore。SIGNAL  'clicked'  、 self。onConnect 

自己 。 connect  disconnect_btn 、 QtCore。SIGNAL  ' clicked '  、 self。onDisconnect 



最も困難なこずは、「リスト内のアむテムをクリックした」シグナルの名前をドキュメントで芋぀けるこずでした

自己 。 connect  self。saved_list 、 QtCore。SIGNAL  'itemClickedQListWidgetItem *'  、 self。onSelectServer 





プロファむルを保存しおいたす


ハンドラヌ自䜓を䜜成するのはあなた次第です。 順番に始めたしょう。プロファむルを保存し、プロファむルを削陀したす。

プロファむルをナヌザヌのホヌムディレクトリの〜/ .pyksshfs / hosts /に保存したす。

プロファむルごずに1぀のファむルファむル名は、フォヌムで「名前」ず呌ばれるものです。

起動時に、プログラムがそのようなディレクトリがあるかどうかをチェックし、䞍圚の堎合に䜜成する必芁があるのは論理的です。

これを行うには、プログラムの説明の埌に次の掗緎されおいないコヌドを远加したす。

config_path = os 。 getenv  'HOME'  + '/.pyksshfs/hosts'

osで ない 堎合 。 パス isdir  config_path  

os 。 makedirs  config_path 、 0700 





そしお、むンポヌトOSプログラムでファむルの先頭に

フォヌムフィヌルドの倀をファむルに保存する最善の方法を考えお、私はおそらくPythonに蚭定を保存するための既補のモゞュヌルがあるず思いたした。 そしおそれが起こった。

わずかなグヌグルですぐに結果が埗られたしたimport ConfigParser

onSaveメ゜ッド

def onSave  self  

'' '

蚭定を保存する

' ' '

自己の 堎合 。 entry_name 。 text    プロファむル名がある堎合

config = ConfigParser 。 RawConfigParser   構成を䜜成しお入力する

config add_section  '接続' 

config 蚭定  「接続」 、 「ホスト」 、 自己 。 サヌバヌアドレス 。 テキスト   

config 蚭定  「接続」 、 「ポヌト」 、 自己 。 サヌバヌ ポヌト 。 テキスト   

config セット  'Connection' 、 'user_name' 、 self。user_name。text   

config set  'Connection' 、 'remote_path' 、 self。remote_path。text   

config set  'Connection' 、 'local_path' 、 self。local_path。text   



自己の 堎合 。 selected_name 

os 。 unlink  self。config_path + '/' + self。selected_name 



path = self config_path + '/' + self entry_name 。 テキスト  

ファむル = オヌプン  パス 、 'w' 

config write  file  蚭定を保存

ファむル 。 閉じる  

自己 。 selected_name = self 。 entry_name 。 テキスト  

自己 。 listServers   プロファむルのリストを曎新





プロフィヌルリスト


メ゜ッドの蚘述の最埌に、新しいプロファむルがすぐにリストに衚瀺されたらいいず思いたす。プログラムを開くず、保存されたプロファむルのリストも衚瀺する必芁がありたす。

そのため、出力を受信しお​​䞀芧衚瀺するメ゜ッドをすぐに蚘述し、__ init__およびonSaveの最埌に呌び出しを挿入したす。

def listServers  self  

自己 。 saved_list 。 クリア  

hosts = os listdir  self。config_path 

自己 。 saved_list 。 insertItems  O 、 hosts  この呌び出しで、ファむルのリストをリストりィゞェットに远加したす

自己の 堎合 。 selected_name  すでにプロファむルを遞択しおいる堎合は、リストで遞択する必芁がありたす

item = self saved_list 。 findItems  self。selected_name 、 QtCore。Qt。MatchExactly 

自己 。 saved_list 。 setItemSelected  item [ O ] 、 True 



䜕らかの理由で、Habrはコヌドに0を衚瀺したくないため、倧文字のOに眮き換えたした。



アンマりント


さらに進みたしょう。 リモヌトディレクトリをアンマりントする方法。 基本的に説明するこずはありたせん。



def onDisconnect  self  

if  self。local_path。text    

os 。 system  'fusermount -u' + str  self。local_path。text    





取り付け


マりントははるかに興味深いです。 私はこの郚分を最も長く苊しめたした。 この方法のせいで、2時間以䞊かかったのは秘密です。 しかし、実際には、問題はそのような性質のものであったため、以前にそれらのこずを知っおいたなら、芋出しに瀺された期限を完党に満たしおいただろう。

問題sshを䜿甚しおディレクトリをマりントするコマンドは察話型であり、ナヌザヌからのパスワヌドが必芁です。 ただし、キヌによる認蚌が行われた堎合は必芁ありたせん。 したがっお、コマンドを䜜成し、実行し、パスワヌドが芁求されおいるかどうかを確認しおから、ナヌザヌに芁求する必芁がありたす。 パスワヌドが䞍芁な堎合は、ナヌザヌに觊れないでください。

sshfsコマンドには、stdinでパスワヌドを枡すこずができるパラメヌタヌがありたす。 ただし、ナヌザヌは、パスワヌドが䞍芁な堎合、あたり良くないものを事前に尋ねる必芁がありたす。

別の埮劙な点がありたす。 sshを介しおサヌバヌにアクセスしたこずがない堎合は、「圌を信頌したすか」ず尋ねられたす。



䞀般に、これらのケヌスを䜕らかの圢で凊理する必芁がありたす。 このような問題を解決するために、pexpectモゞュヌルpexpectのむンポヌトがありたす。 これを䜿甚するず、察話型プログラムtelnet、ftp、sshなどで䜜業できたす。 さお、コヌドを衚瀺する時間です。

def onConnect  self  

コマンド = 'sshfs'

自己の 堎合 。 user_name テキスト   

command + = self user_name テキスト   + '@'

command + = self server_address 。 テキスト  

自己の 堎合 。 remote_path 。 テキスト   

command + = '' + self remote_path 。 テキスト  

その他 

コマンド + = '/'



自己の 堎合 。 server_port 。 テキスト   

command + = '-p' + self 。 server_port 。 テキスト  



command + = '' + self 。 local_path 。 テキスト  



sshfs = pexpect spawn  str  command  、 env = { 'SSH_ASKPASS'  '/ dev / null' } 

ssh_newkey = '接続を続行しおもよろしいですか

i = sshfs expect  [ ssh_newkey 、 'assword' 、 pexpect。EOF 、 pexpect。TIMEOUT ] 



i = = 0の 堎合 

sshfs sendline  'yes' 

i = sshfs expect  [ ssh_newkey 、 'assword' 、 pexpect。EOF ] 

i = = 1の 堎合 

パスワヌドが芁求されない堎合

askpasscmd = 'ksshaskpasss'  self entry_name 。 テキスト  

パスワヌド = pexpect 実行  askpasscmd  。 split  '\ n'  [ 1 ]

sshfs sendline  パスワヌド 

j = sshfs expect  [ pexpect。EOF 、 'assword' ] 

j = = 1の 堎合 

パスワヌドが正しくありたせん、匷制的に接続を閉じたす

「パスワヌドが正しくありたせん」を 印刷

sshfs 閉じる  True 

p.terminateTrue

elif i = = 2 

すべおの問題

print "゚ラヌが芋぀かりたしたs"  sshfs 。 前に

elif i = = 3 

タむムアりト

print "Timeouts"  sshfs 。 前に

sshfsを出力したす。 前に



linux-volume-manager-fuse-kde4プロゞェクトからコヌドの䞀郚を取りたした。 最初は私のコヌドは動䜜したくありたせんでしたが、コヌドが動䜜した埌、私はこれをすべお同じたたにするこずにしたした。 より倚くのオプションを凊理したす。

ナヌザヌからパスワヌドを取埗するには、ksshaskpassプログラムを䜿甚したした。 第䞀に、曞かないために、第二に、圌女はkwalletdからパスワヌドを保存/受信する方法を知っおいたす。これは非垞に䟿利です。

オリゞナルのコヌドは、ksshaskpassのドキュメントによるずパスワヌドを返す必芁があるため、たったく機胜したせんでしたが、その代わりに、パスワヌドに加えお、他のデバッグ行を返したす。 圌女はこのように陀倖しなければなりたせんでした

パスワヌド= pexpect.run 'ksshaskpass'.split '\ n'[1]

ずころで、突然デバッグ行が消えるず、プログラムは動䜜を停止したす。



プロフィヌルのアップロヌド


ほずんどすべおの準備が敎いたした。 最埌のアクションは残りたす。ナヌザヌがリストから遞択したずきにプロファむルをロヌドしたす。 すぐにコヌド。

def onSelectServer  self 、 item  

「」 「

seved_listでアむテムが遞択されおいる堎合、ファむルから蚭定を取埗

「 」

name = item テキスト   ファむル名

自己 。 selected_name = name 遞択を芚えおおいおください



config = ConfigParser 。 RawConfigParser  

config readfp  open  self。config_path + '/' + name   蚭定を開きたす



蚭定からフォヌムフィヌルドに入力

自己 。 entry_name 。 setText  name 

自己 。 server_address 。 setText  config。get  'Connection' 、 'host'  

自己 。 server_port 。 setText  config。get  'Connection' 、 'port'  

自己 。 user_name setText  config。get  'Connection' 、 'user_name'  

自己 。 remote_path 。 setText  config。get  'Connection' 、 'remote_path'  

自己 。 local_path 。 setText  config。get  'Connection' 、 'local_path'  





結果



以䞊です。 ほんの2、3時間で、Pythonシンタックス、グヌグル、ブラックベルトのみを䜿甚しお、かなり実甚的なコピヌ/貌り付けプログラムを䜜成したした。

おそらく蚘事では、コヌドの䞀郚を芋逃しおいたした。

ですから、完党に動䜜するpyKSshfsバヌゞョンをダりンロヌドするのが最善です。



最埌にスクリヌンショット

終了したプログラム

蚈画



プログラムの䜜成の途䞭で、プラズマアプレットずしおより䟿利になるず思いたした。 そしお、フラッシュドラむブをマりントするためのアプレットのように芋えるはずです。 しかし、ksshaskpassで忙しかったので、延期するこずにしたした。 たぶんすぐにやろう。 たたは倚分あなたの䞀人が私の先を行くでしょう-私はただうれしいです。



参照資料



  1. pyKSshfsをダりンロヌドしたす 。
  2. 「KDE4のプログラミング」
  3. PyQtドキュメント
  4. Kommanderスクリプトksshfs
  5. sshfsgui javaプログラム
  6. コヌドの䞀郚はここで取埗されたした。




ご枅聎ありがずうございたした



これをすべお読むこずができたすべおの人のおかげで、私はそれが簡単ではなかったこずを知っおいたす。 =

皆さんに幞運を



All Articles