|
| 1 | +import wx |
| 2 | +from ftplib import FTP |
| 3 | +import ftplib |
| 4 | +import os |
| 5 | + |
| 6 | +if "2.8" in wx.version(): |
| 7 | + import wx.lib.pubsub.setupkwargs |
| 8 | + from wx.lib.pubsub import pub |
| 9 | +else: |
| 10 | + from wx.lib.pubsub import pub |
| 11 | + |
| 12 | +#host = '127.0.0.1' |
| 13 | +port = 1026 |
| 14 | +ftp = FTP('') |
| 15 | +ID_NEW = 1 |
| 16 | +ID_RENAME = 2 |
| 17 | +ID_REMOVEFILE = 3 |
| 18 | +ID_DOWNLOAD = 4 |
| 19 | +ID_REMOVEDIR = 5 |
| 20 | +ID_BACK = 6 |
| 21 | +ID_FORWARD = 7 |
| 22 | +ID_ONETRANSFER = 8 |
| 23 | +ID_MULTITRANSFER = 9 |
| 24 | + |
| 25 | +class LoginDialog(wx.Dialog): |
| 26 | + """Constructor""" |
| 27 | + def __init__(self): |
| 28 | + wx.Dialog.__init__(self, None, title="Login Dialog", size=(400, 160)) |
| 29 | + #creating login gui |
| 30 | + serverip_sizer = wx.BoxSizer(wx.HORIZONTAL) |
| 31 | + serverip_lbl = wx.StaticText(self, label="Server ip:") |
| 32 | + serverip_sizer.Add(serverip_lbl, 0, wx.ALL | wx.CENTER, 5) |
| 33 | + self.serverip = wx.TextCtrl(self, size=(150, 30)) #creating input box |
| 34 | + serverip_sizer.Add(self.serverip, 0, wx.LEFT | wx.RIGHT, 35) |
| 35 | + |
| 36 | + username_sizer = wx.BoxSizer(wx.HORIZONTAL) |
| 37 | + username_lbl = wx.StaticText(self, label="Username:") |
| 38 | + username_sizer.Add(username_lbl, 0, wx.ALL | wx.CENTER, 5) |
| 39 | + self.username = wx.TextCtrl(self, size=(150, 30)) # creating input box |
| 40 | + username_sizer.Add(self.username, 0, wx.LEFT | wx.RIGHT, 25) |
| 41 | + |
| 42 | + password_sizer = wx.BoxSizer(wx.HORIZONTAL) |
| 43 | + password_lbl = wx.StaticText(self, label="Password:") |
| 44 | + password_sizer.Add(password_lbl, 0, wx.ALL | wx.CENTER, 5) # align center |
| 45 | + self.password = wx.TextCtrl(self, style=wx.TE_PASSWORD | wx.TE_PROCESS_ENTER,size=(150, 30)) # creating input box |
| 46 | + password_sizer.Add(self.password, 0, wx.LEFT | wx.RIGHT, 30) |
| 47 | + |
| 48 | + main_sizer = wx.BoxSizer(wx.VERTICAL) |
| 49 | + main_sizer.Add(serverip_sizer, 0, wx.ALL, 5) |
| 50 | + main_sizer.Add(username_sizer, 0, wx.ALL, 5) |
| 51 | + main_sizer.Add(password_sizer, 0, wx.ALL, 5) |
| 52 | + |
| 53 | + btn = wx.Button(self, label="login", size=(300, 30)) |
| 54 | + btn.Bind(wx.EVT_BUTTON, self.login) # when is pressed the button call the Login function |
| 55 | + main_sizer.Add(btn, 0, wx.ALL | wx.CENTER, 5) |
| 56 | + |
| 57 | + self.SetSizer(main_sizer) |
| 58 | + |
| 59 | + def login(self, event): |
| 60 | + serverip = self.serverip.GetValue() |
| 61 | + username = self.username.GetValue() |
| 62 | + password = self.password.GetValue() |
| 63 | + print(username) |
| 64 | + print(password) |
| 65 | + print(serverip) |
| 66 | + try: |
| 67 | + ftp.connect(serverip, port) |
| 68 | + res = ftp.login(username, password) |
| 69 | + if (res.lower().startswith('230 login successful')): |
| 70 | + global isConnect |
| 71 | + isConnect = True |
| 72 | + self.Destroy() |
| 73 | + main = Main() |
| 74 | + #main.show() |
| 75 | + #pub.sendMessage("frameListener", message="show") |
| 76 | + #self.Destroy() |
| 77 | + except ftplib.all_errors as e: |
| 78 | + print(e) |
| 79 | + |
| 80 | +class ContentMain(wx.Panel): |
| 81 | + previousPath ="" #class variable |
| 82 | + def __init__(self, parent): |
| 83 | + wx.Panel.__init__(self, parent) |
| 84 | + hbox = wx.BoxSizer(wx.HORIZONTAL) |
| 85 | + |
| 86 | + clientDirectoryTree_sizer = wx.BoxSizer(wx.VERTICAL) |
| 87 | + self.clientTree_lbl = wx.StaticText(self,-1,style = wx.ALIGN_CENTER,label="My Local Directory Tree") |
| 88 | + self.dirClient = wx.GenericDirCtrl(self, -1, |
| 89 | + dir=os.path.expanduser('~'), # os.path.expanduser('~') == /home/burakisik |
| 90 | + style= |
| 91 | + wx.DIRCTRL_3D_INTERNAL | |
| 92 | + wx.DIRCTRL_MULTIPLE, |
| 93 | + filter="*",size = (250,400)) |
| 94 | + clientDirectoryTree_sizer.Add(self.clientTree_lbl, 0, wx.ALL | wx.CENTER, 5) |
| 95 | + clientDirectoryTree_sizer.Add(self.dirClient, 0, wx.ALL | wx.CENTER, 5) |
| 96 | + |
| 97 | + #creating transfer buttons |
| 98 | + transfer_sizer = wx.BoxSizer(wx.VERTICAL) |
| 99 | + self.oneTransfer = wx.Button(self, ID_ONETRANSFER, '>') |
| 100 | + self.multiTransfer = wx.Button(self, ID_MULTITRANSFER, '>>') |
| 101 | + self.Bind(wx.EVT_BUTTON, self.uploadSingleFile, id=ID_ONETRANSFER) |
| 102 | + self.Bind(wx.EVT_BUTTON, self.uploadMultiFile, id=ID_MULTITRANSFER) |
| 103 | + transfer_sizer.Add(self.oneTransfer, 1,wx.CENTER, 5) |
| 104 | + transfer_sizer.Add(self.multiTransfer, 1,wx.CENTER, 5) |
| 105 | + |
| 106 | + remoteDirectoryList_sizer = wx.BoxSizer(wx.VERTICAL) |
| 107 | + self.remoteFiles_lbl = wx.StaticText(self,-1,style = wx.ALIGN_CENTER,label="Remote Directories and Files List") |
| 108 | + self.dirRemote = wx.ListBox(self, -1,size = (250,400)) |
| 109 | + remoteDirectoryList_sizer.Add(self.remoteFiles_lbl, 0, wx.ALL | wx.CENTER, 5) |
| 110 | + remoteDirectoryList_sizer.Add(self.dirRemote,0, wx.ALL | wx.CENTER, 5) |
| 111 | + |
| 112 | + #creating back and forward button |
| 113 | + navigation_sizer = wx.BoxSizer(wx.HORIZONTAL) |
| 114 | + self.back = wx.Button(self, ID_BACK, 'BACK') |
| 115 | + self.forward = wx.Button(self, ID_FORWARD, 'FORWARD') |
| 116 | + self.Bind(wx.EVT_BUTTON, self.goBack, id=ID_BACK) |
| 117 | + self.Bind(wx.EVT_BUTTON, self.goForward, id=ID_FORWARD) |
| 118 | + navigation_sizer.Add(self.back,0,wx.LEFT | wx.RIGHT, 5) |
| 119 | + navigation_sizer.Add(self.forward,0, wx.LEFT | wx.RIGHT, 5) |
| 120 | + |
| 121 | + remoteDirectoryList_sizer.Add(navigation_sizer,0, wx.ALL | wx.CENTER, 5) |
| 122 | + self.fillRemoteList(self) |
| 123 | + |
| 124 | + #creating items gui |
| 125 | + btnPanel = wx.Panel(self, -1) |
| 126 | + vbox = wx.BoxSizer(wx.VERTICAL) |
| 127 | + self.itemstag_lbl = wx.StaticText(btnPanel,-1,style = wx.ALIGN_CENTER,label="Items") |
| 128 | + new = wx.Button(btnPanel, ID_NEW, 'mkDir', size=(110, 30)) |
| 129 | + rename = wx.Button(btnPanel, ID_RENAME, 'Rename', size=(110, 30)) |
| 130 | + removeFile = wx.Button(btnPanel, ID_REMOVEFILE, 'Remove File', size=(110, 30)) |
| 131 | + download = wx.Button(btnPanel, ID_DOWNLOAD, 'Download', size=(110, 30)) |
| 132 | + removeDir = wx.Button(btnPanel, ID_REMOVEDIR, 'Remove Dir', size=(110, 30)) |
| 133 | + |
| 134 | + self.Bind(wx.EVT_BUTTON, self.NewItem, id=ID_NEW) |
| 135 | + self.Bind(wx.EVT_BUTTON, self.OnRename, id=ID_RENAME) |
| 136 | + self.Bind(wx.EVT_BUTTON, self.OnRemoveFile, id=ID_REMOVEFILE) |
| 137 | + self.Bind(wx.EVT_BUTTON, self.OnDownload, id=ID_DOWNLOAD) |
| 138 | + self.Bind(wx.EVT_BUTTON, self.OnRemoveDir, id=ID_REMOVEDIR) |
| 139 | + self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnRename) # Call the onRename function when list item is clicked |
| 140 | + |
| 141 | + #vbox.Add((-1, 20)) |
| 142 | + vbox.Add(self.itemstag_lbl ,0, wx.ALL | wx.CENTER, 5) |
| 143 | + vbox.Add(new) |
| 144 | + vbox.Add(rename, 0, wx.TOP, 5) |
| 145 | + vbox.Add(removeFile, 0, wx.TOP, 5) |
| 146 | + vbox.Add(removeDir, 0, wx.TOP, 5) |
| 147 | + vbox.Add(download, 0, wx.TOP, 5) |
| 148 | + |
| 149 | + btnPanel.SetSizer(vbox) |
| 150 | + hbox.Add(clientDirectoryTree_sizer,0.6,wx.EXPAND | wx.RIGHT, 20) |
| 151 | + hbox.Add(transfer_sizer,0.6,wx.CENTER, 20) |
| 152 | + hbox.Add(remoteDirectoryList_sizer,0.6,wx.EXPAND | wx.RIGHT, 20) |
| 153 | + hbox.Add(btnPanel, 0.6, wx.EXPAND | wx.RIGHT, 20) |
| 154 | + |
| 155 | + self.SetSizer(hbox) |
| 156 | + #self.Fit() |
| 157 | + self.Centre() |
| 158 | + self.Show(True) |
| 159 | + |
| 160 | + def NewItem(self, event): |
| 161 | + try: |
| 162 | + text = wx.GetTextFromUser('Enter Directory Name', 'Create New Directory') |
| 163 | + if text != '': |
| 164 | + ftp.mkd(text) |
| 165 | + self.dirRemote.Append(text) |
| 166 | + self.fillRemoteList(self) |
| 167 | + except: |
| 168 | + dial = wx.MessageDialog(None, 'Unvalid Name', 'Error',wx.OK | wx.ICON_ERROR) |
| 169 | + dial.ShowModal() |
| 170 | + |
| 171 | + def OnRename(self, event): |
| 172 | + try: |
| 173 | + sel = self.dirRemote.GetSelection() |
| 174 | + text = self.dirRemote.GetString(sel) |
| 175 | + renamed = wx.GetTextFromUser('Enter New Name', 'Rename File or Directory Name', text) |
| 176 | + if renamed != '': |
| 177 | + ftp.rename(text, renamed) |
| 178 | + self.dirRemote.Delete(sel) |
| 179 | + self.dirRemote.Insert(renamed, sel) |
| 180 | + self.fillRemoteList(self) |
| 181 | + except: |
| 182 | + dial = wx.MessageDialog(None, 'Please Choose File in Remote File List', 'Error',wx.OK | wx.ICON_ERROR) |
| 183 | + dial.ShowModal() |
| 184 | + |
| 185 | + def OnRemoveFile(self, event): |
| 186 | + try: |
| 187 | + sel = self.dirRemote.GetSelection() |
| 188 | + text = self.dirRemote.GetString(sel) |
| 189 | + if sel != -1: |
| 190 | + ftp.delete(text) |
| 191 | + self.dirRemote.Delete(sel) |
| 192 | + self.fillRemoteList(self) #reflesh remote list |
| 193 | + except: |
| 194 | + dial = wx.MessageDialog(None, 'Please Choose Just a File in Remote List','Error',wx.OK | wx.ICON_ERROR) |
| 195 | + dial.ShowModal() |
| 196 | + |
| 197 | + def OnRemoveDir(self, event): |
| 198 | + try: |
| 199 | + sel = self.dirRemote.GetSelection() |
| 200 | + text = self.dirRemote.GetString(sel) |
| 201 | + if sel != -1: |
| 202 | + ftp.rmd(text) |
| 203 | + self.dirRemote.Delete(sel) |
| 204 | + self.fillRemoteList(self) #reflesh remote list |
| 205 | + except: |
| 206 | + dial = wx.MessageDialog(None, 'Please Choose Just a Directory in Remote List','Error',wx.OK | wx.ICON_ERROR) |
| 207 | + dial.ShowModal() |
| 208 | + |
| 209 | + def OnDownload(self, event): |
| 210 | + try: |
| 211 | + sel = self.dirRemote.GetSelection() |
| 212 | + filename = self.dirRemote.GetString(sel) |
| 213 | + if sel != -1: |
| 214 | + localfile = open(filename, 'wb') |
| 215 | + ftp.retrbinary('RETR ' + filename, localfile.write, 1024) |
| 216 | + except: |
| 217 | + dial = wx.MessageDialog(None, 'Please Choose Just a File in Remote Directory Tree','Error',wx.OK | wx.ICON_ERROR) |
| 218 | + dial.ShowModal() |
| 219 | + |
| 220 | + def uploadSingleFile(self, event): |
| 221 | + try: |
| 222 | + path = self.dirClient.GetPath() #GetFilePath() #GetDefaultPath() #GetSelections() #GetFilePath() |
| 223 | + #print self.dirClient.GetPath() |
| 224 | + if os.path.isfile(path): |
| 225 | + fileName = os.path.basename(path) |
| 226 | + print fileName |
| 227 | + ftp.storbinary('STOR ' + fileName, open(path,'rb')) |
| 228 | + self.fillRemoteList(self) #reflesh dirremote list |
| 229 | + else: |
| 230 | + dial = wx.MessageDialog(None, 'Please Choose just One File not Directory in Client Directory Tree', 'Error',wx.OK | wx.ICON_ERROR) |
| 231 | + dial.ShowModal() |
| 232 | + except: |
| 233 | + dial = wx.MessageDialog(None, 'Please Choose just One File not Directory in Client Directory Tree', 'Error',wx.OK | wx.ICON_ERROR) |
| 234 | + dial.ShowModal() |
| 235 | + |
| 236 | + def uploadMultiFile(self,event): |
| 237 | + try: |
| 238 | + paths = self.dirClient.GetFilePaths() |
| 239 | + if paths: #list paths if not empty |
| 240 | + for path in paths: |
| 241 | + if os.path.isfile(path): |
| 242 | + fileName = os.path.basename(path) |
| 243 | + ftp.storbinary('STOR ' + fileName, open(path,'rb')) |
| 244 | + self.fillRemoteList(self) #reflesh dirremote list |
| 245 | + |
| 246 | + else: |
| 247 | + dial = wx.MessageDialog(None, 'Please Choose one File or lots of File not Directories in Client Directory Tree', 'Error',wx.OK | wx.ICON_ERROR) |
| 248 | + dial.ShowModal() |
| 249 | + |
| 250 | + except: |
| 251 | + dial = wx.MessageDialog(None, 'Please Choose Files not Directories in Client Directory Tree', 'Error',wx.OK | wx.ICON_ERROR) |
| 252 | + dial.ShowModal() |
| 253 | + |
| 254 | + def goBack(self, event): |
| 255 | + try: |
| 256 | + print self.previousPath |
| 257 | + if self.previousPath != '': |
| 258 | + ftp.cwd(self.previousPath) |
| 259 | + self.fillRemoteList(self) |
| 260 | + except ftplib.all_errors as er: |
| 261 | + print (er) |
| 262 | + |
| 263 | + def goForward(self, event): |
| 264 | + try: |
| 265 | + sel = self.dirRemote.GetSelection() |
| 266 | + dirname = self.dirRemote.GetString(sel) |
| 267 | + if dirname != '': |
| 268 | + self.previousPath = ftp.pwd() #register the previous path |
| 269 | + ftp.cwd(dirname) |
| 270 | + #print ftp.pwd() |
| 271 | + self.fillRemoteList(self) |
| 272 | + except ftplib.all_errors as er: |
| 273 | + print (er) |
| 274 | + @staticmethod |
| 275 | + def fillRemoteList(self): |
| 276 | + self.dirRemote.Clear() #clear remote files and directories's list |
| 277 | + try: |
| 278 | + files = [] |
| 279 | + ftp.retrlines('LIST',lambda line: files.append(line.split()[-1])) #thanks to split function return only file or dir "name" instead of size, type, modified date etc. #ftp.retrlines('LIST',files.append) |
| 280 | + for file in files: |
| 281 | + self.dirRemote.Append(file) |
| 282 | + except ftplib.all_errors as er: |
| 283 | + print (er) |
| 284 | + """if str(er) == "550 No files found": |
| 285 | + print "No files in this directory" |
| 286 | + else: |
| 287 | + raise""" |
| 288 | + |
| 289 | +class Main(wx.Frame): |
| 290 | + def __init__(self): |
| 291 | + """Constructor""" |
| 292 | + wx.Frame.__init__(self, None, title="Main Page", size=(785,500),style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER) |
| 293 | + panel = ContentMain(self) |
| 294 | + pub.subscribe(self.myListener, "frameListener") |
| 295 | + #Ask user to login |
| 296 | + #dlg = LoginDialog() |
| 297 | + #dlg.ShowModal() |
| 298 | + self.Show() |
| 299 | + |
| 300 | + def myListener(self, message, arg2=None): |
| 301 | + self.Show() |
| 302 | + |
| 303 | +if __name__ == "__main__": |
| 304 | + app = wx.App(False) |
| 305 | + login= LoginDialog() |
| 306 | + login.ShowModal() |
| 307 | + app.MainLoop() |
| 308 | + |
0 commit comments