def __init__(self, parent): wx.Dialog.__init__(self, parent) conf = Config() boxSizer = wx.BoxSizer(wx.HORIZONTAL) b = BucketConfigPanel(self, conf.getBuckets().keys(), self.onOkBtn) boxSizer.Add(b, 1, wx.EXPAND) self.Layout() self.Center()
class MainFrame(framework.XFrame): def __init__(self): wx.Frame.__init__(self, None, -1, u'七牛文件管理('+VERSION+')', size=(800, 640)) self.conf = Config() ak, sk = self.conf.getKeys() self.__auth = qiniu.Auth(ak, sk) self.SetIcon(libs.icons.desktop().GetIcon()) #self.SetWindowStyle((self.GetWindowStyle() | wx.STAY_ON_TOP)) self.createSplitter() self.createMenuBar(self.menuData()) self.createToolBar(self.toolbarData()) self.createStatusBar([-1, 100, 140, 70]) self.createTaskBarIcon(self.taskMenuData()) self.Bind(wx.EVT_CLOSE, self.onHideEvent) self.Center() for bucket in self.conf.getBuckets(): self._bucketPanel.setBucketName(bucket) return def bucketMenuData(self): bucketsMenu = [] for bucket in self.conf.getBuckets(): bucketsMenu.append((bucket, bucket, self.onBucketChangedEvent, wx.ITEM_RADIO)) bucketsMenu.append("---") bucketsMenu.append((u"新建空间", u"新建空间",self.onCreateBucketEvent)) return (u"空间", bucketsMenu) def menuData(self): return [ (u"文件", [ (u"上传", u"上传文件到当前空间", self.onUploadFileEvent), "---", (u"最小化", u"最小化到系统托盘", self.onHideEvent), (u"退出", u"退出系统", self.onExitEvent) ]), (u"视图", [ (u"查看方式", [ ([u"详细信息", u"列表", u"大图标", u"小图标"], "", self.onViewChangedEvent, wx.ITEM_RADIO) ]), "---", (u"排序方式", [ ([u"名称",u"大小",u"时间"], "", self.onSortChangedEvent, wx.ITEM_RADIO) ]) ,"---" , (u"系统设置", u"系统运行视图参数设置", self.onConfigEvent) ]), self.bucketMenuData(), (u"关于", [ (u"检查更新", u"连接服务器检测是否更新", self.onUploadEvent), (u"关于软件", u"关于软件简介", self.onAboutSoftEvent), (u"关于作者", u"作者简介", self.onAboutUserEvent) ]) ] def toolbarData(self): return [ (u"上传", u"上传文件到当前空间", "upload.png", self.onUploadFileEvent), ((ID.ID_TOOLBAR_DOWNLOAD, u"下载"), u"下载选中文件", ["download.png","download.dis.png"], self.onDownloadFileEvent, False), "---", ((ID.ID_TOOLBAR_TRASH, u"删除"), u"删除选中文件", ["trash.png","trash.dis.png"], self._bucketPanel.onDeleteEvent, False), "---", ((ID.ID_TOOLBAR_PREV_PAGE, U"上一页"), u"加载上一页文件", ["prev.png", "prev.dis.png"], self._bucketPanel.onPrevPageEvent, False), ((ID.ID_TOOLBAR_NEXT_PAGE, U"下一页"), u"加载下一页文件", ["next.png", "next.dis.png"], self._bucketPanel.onNextPageEvent, False), "---", (u"刷新", u"刷新当前页" , "refresh.png",self._bucketPanel.onRefreshEvent), "---", ((ID.ID_TOOLBAR_LIMIT,u"显示个数:"),["10","20","50","100","200","500"],self._bucketPanel.onPageLimitEvent), "---", ((ID.ID_TOOLBAR_SEARCH_TEXT, u"搜索关键字"), (u"", u"文件前缀"), {wx.EVT_KEY_DOWN:self._bucketPanel.onSearchEvent}), (u"搜索", u"在当前空间搜索", "search.png", self._bucketPanel.onSearchEvent), ] def taskMenuData(self): return [ (u"显示", u"", self.onShowEvent), "-", (u"关于软件", u"关于软件简介", self.onAboutSoftEvent), "-", (u"退出", u"", self.onExitEvent) ] def createSplitter(self): self._splitter = wx.SplitterWindow(self) self._items = self.createBucketsPanel(self._splitter) self._uploadify = wx.Panel(self._splitter, style=wx.BORDER_SIMPLE) self._uploadify.SetSizer(wx.BoxSizer(wx.VERTICAL)) self._splitter.Initialize(self._items) return self._splitter def createBucketsPanel(self, parent): self._bucketPanel = BucketPanel(parent, self.__auth) self.SetDropTarget(FileDropUpLoadTarget(self.uploadFile)) return self._bucketPanel def onScheduleFinally(self, panel=None, status=True): """上传动作结束(正确上传,上传错误,。。。)均会调用""" if status and panel: self._uploadify.GetSizer().Hide(panel) self._uploadify.GetSizer().Remove(panel) self._uploadify.RemoveChild(panel) children = len(self._uploadify.GetChildren()) if children == 0 : self.__switchSplitWindow(False) self._uploadify.Layout() def onUploadFileEvent(self, event): wildcard = u"所有文件 (*.*) | *.*" result = dialogs.fileDialog(parent=self._uploadify, title=u'选择文件', filename='', wildcard=wildcard, style=wx.OPEN) if result.accepted: for file_path in result.paths: if os.path.isdir(file_path) : continue self.uploadFile(file_path) event.Skip() def onDownloadFileEvent(self, event): self.__switchSplitWindow(True) folder = "" results = dialogs.dirDialog(self, u"选择下载位置") if results.accepted: folder = results.path files = self._bucketPanel.getSelectedFiles() for file in files : dnPanel = DownloadPanel(folder, file, self.onScheduleFinally, self._uploadify) boxSizer = self._uploadify.GetSizer() boxSizer.Add(dnPanel, flag=wx.EXPAND) self._uploadify.Layout() event.Skip() else: self.onScheduleFinally(None,False) def uploadFile(self,file_path): self.__switchSplitWindow(True) bucketName = self._bucketPanel.getBucketName() up = UploadifyPanel(self.__auth, bucketName, file_path, self.onScheduleFinally, self._uploadify) boxSizer = self._uploadify.GetSizer() boxSizer.Add(up, flag=wx.EXPAND) #self._uploadify.GetSizer().Fit(self._uploadify) #self._uploadify.GetSizer().SetSizeHints(self._uploadify) self._uploadify.Layout() def __switchSplitWindow(self,open=True): """选择上传下载队列窗口状态""" if open: if not self._splitter.IsSplit() : rect = self.GetScreenRect() self._splitter.SplitVertically(self._items, self._uploadify, rect.width - 370) else: if self._splitter.IsSplit(): self._splitter.Unsplit() #self._bucketPanel.setBucketName(self._bucketPanel.getBucketName()) def onBucketChangedEvent(self, event): item = event.EventObject.FindItemById(event.GetId()) bucketName = item.GetText() self._bucketPanel.setBucketName(bucketName) def onViewChangedEvent(self, event): item = event.EventObject.FindItemById(event.GetId()) text = item.GetText() wx.MessageBox(u"首先感谢您的支持!视图查看功能此版本不包含。该项功能正在加紧开发。",u"抱歉") def onSortChangedEvent(self, event): item = event.EventObject.FindItemById(event.GetId()) text = item.GetText() self._bucketPanel.sortBy(text) def onCreateBucketEvent(self, event): wx.MessageBox(VERSION+u"版暂不支持此功能!",u"抱歉") def onConfigEvent(self, event): from libs.login import BucketConfigPanel class ConfigDialog(wx.Dialog): def __init__(self, parent): wx.Dialog.__init__(self, parent) conf = Config() boxSizer = wx.BoxSizer(wx.HORIZONTAL) b = BucketConfigPanel(self, conf.getBuckets().keys(), self.onOkBtn) boxSizer.Add(b, 1, wx.EXPAND) self.Layout() self.Center() def onOkBtn(self): self.Hide() self.Destroy() ConfigDialog(self).ShowModal() def onUploadEvent(self, event): webbrowser.open_new("http://github.com/ihaiker/QiniuAdminGui") def onAboutUserEvent(self, event): self.onUploadEvent(event) def onAboutSoftEvent(self, event): self.onUploadEvent(event)
class BucketPanel(wx.Panel, wx.lib.mixins.listctrl.ColumnSorterMixin): def __init__(self, parent, auth): wx.Panel.__init__(self, parent) self.__frame = self.GetParent().GetParent() self.__auth = auth self.__bucketManger = qiniu.BucketManager(self.__auth) self.__conf = Config() self.__bucketName = "" self.__download_url = None self.__prefix = "" self.__marker = None self.__limit = LIMIT self.__initImages() self.__boxSizer = wx.BoxSizer() self.__dataList = self.__initList() self.__boxSizer.Add(self.__dataList, 1, wx.EXPAND) self.__initPopMenu() self.SetSizer(self.__boxSizer) # init column sorter wx.lib.mixins.listctrl.ColumnSorterMixin.__init__(self, LIMIT) def GetListCtrl(self): return self.__dataList def GetSortImages(self): return (self.down, self.up) def OnSortOrderChanged(self): self.__downloadButtonAndDeleteButtonStatus() def setBucketName(self, bucketName): ## 之所以放在这是因为,在初始化此面板的时候还未初始化toolbar self.__toolbar = self.__frame._toolbar self.__bucketName = bucketName # 当前空间名称 self.__download_url = self.__conf.getBuckets()[self.__bucketName] self.__resetStartLoad() def setPrefix(self, prefix): self.__prefix = prefix self.__enableToolbar(ID.ID_TOOLBAR_SEARCH_BTN, False) self.__enableToolbar(ID.ID_TOOLBAR_SEARCH_TEXT, False) self.__resetStartLoad() def setLimit(self, limit): self.__limit = limit self.__enableToolbar(ID.ID_TOOLBAR_LIMIT, False) self.__resetStartLoad() def getBucketName(self): return self.__bucketName def __resetStartLoad(self): """从头开始重新加载""" self.__marker = None # 下一页marker,加载下一页的时候需要 self.__store = Store() # 保存数据 self.__dataList.DeleteAllItems() AsynchronousThread(self.__loadData).start() def __initImages(self): # load some images into an image list self.__images_16x = wx.ImageList(16, 16, False) self.__icons = [] for types, image in libs.mimetype.typeImage: self.__images_16x.Add(icons.mimeType('16x', image).GetBitmap()) self.__icons.append(image) self.up = self.__images_16x.AddWithColourMask( icons.get("/sorter/up.png").GetBitmap(), "blue") self.down = self.__images_16x.AddWithColourMask( icons.get("/sorter/down.png").GetBitmap(), "blue") def __initList(self): list = wx.ListCtrl(self, -1, style=wx.LC_REPORT | wx.LC_SORT_ASCENDING | wx.BORDER_SUNKEN) # assign the image list to it list.AssignImageList(self.__images_16x, wx.IMAGE_LIST_SMALL) # Add some columns for col, text in enumerate([u"路径", u"类型", u"大小", u"上传时间"]): list.InsertColumn(col, text, wx.CENTER) # set the width of the columns in various ways list.SetColumnWidth(0, 320) list.SetColumnWidth(1, 120) list.SetColumnWidth(2, 80) list.SetColumnWidth(3, 140) self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.__onTreeSelected, list) self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.__onTreeSelected, list) self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.__onTreeSelected, list) # rename event self.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.__onEditNameStart, list) self.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.__onEditNameEnd, list) # key up event (rename & delete) list.Bind(wx.EVT_KEY_UP, self.__onListKeyUp) #drop to download, bug bug #self.Bind(wx.EVT_LIST_BEGIN_DRAG, self._startDragEvent, list) return list def _startDragEvent(self, e): # create temp folder # folder = libs.config.WORK_PATH + "/temp" # libs.config.mkdirs(folder) text = self.__dataList.GetItem(e.GetIndex()).GetText() text = text if text[0] == "/" else "/" + text # temp_file = os.path.join(folder, os.path.basename(text if text[0] == "/" else "/" + text)) # Create drag data data = wx.FileDataObject() data.AddFile(text) # Create drop source and begin drag-and-drop. dropSource = wx.DropSource(self.__dataList) dropSource.SetData(data) # Get Source res = dropSource.DoDragDrop(flags=wx.Drag_AllowMove) if res == wx.DragMove or res == wx.DragCopy: ## 下载 print("DragMove & DragCopy") return text def __onTreeSelected(self, event): self.__downloadButtonAndDeleteButtonStatus() def __pageButtonStatus(self): self.__enableToolbar(ID.ID_TOOLBAR_SEARCH_BTN, True) self.__enableToolbar(ID.ID_TOOLBAR_SEARCH_TEXT, True) self.__enableToolbar(ID.ID_TOOLBAR_LIMIT, True) self.__enableToolbar(ID.ID_TOOLBAR_NEXT_PAGE, self.__store.hasNext() or self.__marker != None) self.__enableToolbar(ID.ID_TOOLBAR_PREV_PAGE, self.__store.hasPrev()) self.__updateStatus() self.__downloadButtonAndDeleteButtonStatus() def __downloadButtonAndDeleteButtonStatus(self): selected = self.__dataList.GetSelectedItemCount() > 0 self.__enableToolbar( ID.ID_TOOLBAR_DOWNLOAD, selected and self.__download_url != None and self.__download_url != "") self.__enableToolbar(ID.ID_TOOLBAR_TRASH, selected) def __loadNextData(self): if self.__store.hasNext(): self.__showData(self.__store.next()) self.__pageButtonStatus() elif self.__marker != None: AsynchronousThread(self.__loadData).start() def __loadPrevData(self): if self.__store.hasPrev(): self.__showData(self.__store.prev()) self.__pageButtonStatus() def __loadData(self): ret, eof, info = self.__bucketManger.list(bucket=self.__bucketName, marker=self.__marker, limit=self.__limit, prefix=self.__prefix) if info.ok(): items = ret.get("items") self.__store.add(items) wx.CallAfter(self.__showData, items) if not eof: self.__marker = ret.get("marker") else: self.__marker = None else: if self.__marker != None: self.__enableToolbar(ID.ID_TOOLBAR_NEXT_PAGE, True) wx.MessageBox(info.error) self.__pageButtonStatus() def __showData(self, items): self.itemDataMap = {} for row, item in enumerate(items): name = item.get(u"key") fsize = libs.config.fileSizeShow(item.get(u"fsize")) putTime = time.strftime( '%Y-%m-%d %H:%M:%S', time.localtime(round(item.get("putTime") / 10000 / 1000))) mimeType = item.get(u"mimeType") image = libs.mimetype.showType(mimeType, name) index = self.__dataList.InsertStringItem(sys.maxint, name) self.__dataList.SetStringItem(index, 1, mimeType) self.__dataList.SetStringItem(index, 2, fsize) self.__dataList.SetStringItem(index, 3, putTime) self.__dataList.SetItemData(index, row) # sort data self.itemDataMap[index] = (name, mimeType, item.get("fsize"), item.get("putTime")) # 设置图标 self.__dataList.SetItemImage(index, self.__icons.index(image)) def __initPopMenu(self): self.popupMenu = wx.Menu() urlMenu = self.popupMenu.Append(-1, u"复制地址", u"复制地址") self.Bind(wx.EVT_MENU, self.onCopyUrlEvent, urlMenu) self.popupMenu.AppendSeparator() deleteMenu = self.popupMenu.Append(-1, u"删除", u"删除选中文件") self.Bind(wx.EVT_MENU, self.onDeleteEvent, deleteMenu) refreshMenu = self.popupMenu.Append(-1, u"更新", u"强制更新缓存,保证上传的文件可以显示最新") self.Bind(wx.EVT_MENU, self.onRefreshCacheEvent, refreshMenu) renameMenu = self.popupMenu.Append(-1, u"重命名", u"重命名") self.Bind(wx.EVT_MENU, self.onRenameEvent, renameMenu) downloadMenu = self.popupMenu.Append(-1, u"下载", u"下载选中文件") self.Bind(wx.EVT_MENU, self.__frame.onDownloadFileEvent, downloadMenu) self.Bind(wx.EVT_CONTEXT_MENU, self.__onShowPopup) def __onShowPopup(self, event): if len(self.getSelectedFiles()) != 0: pos = event.GetPosition() pos = self.ScreenToClient(pos) self.PopupMenu(self.popupMenu, pos) else: ##没有选中文件,不可操作 pass def __onPopupItemSelected(self, event): item = self.popupMenu.FindItemById(event.GetId()) text = item.GetText() wx.MessageBox("You selected item '%s'" % text) def __onListKeyUp(self, event): keyCode = event.GetKeyCode() if keyCode == wx.WXK_DELETE: self.onDeleteEvent(event) elif keyCode == wx.WXK_F2: if len(self.getSelectedFiles()) == 1: self.onRenameEvent(event) elif event.ControlDown() and keyCode == 67: self.onCopyUrlEvent(event) elif event.ControlDown() and keyCode == 65: for index in range(self.__dataList.GetItemCount()): self.__dataList.Select(index, True) event.Skip() def __onEditNameStart(self, event): print("重命名开始") def __onEditNameEnd(self, event): print("重命名结束") def getSelectedFiles(self): files = [] index = self.__dataList.GetFirstSelected() while index != -1: item = self.__dataList.GetItem(index) key = item.GetText() mimeType = self.itemDataMap[index][1] fileSize = self.itemDataMap[index][2] base_url = 'http://%s/%s' % (self.__download_url, key) private_url = self.__auth.private_download_url(base_url, expires=3600) files.append((private_url, key, mimeType, fileSize)) index = self.__dataList.GetNextSelected(index) return files def onRefreshEvent(self, event): self.__resetStartLoad() def onNextPageEvent(self, event): self.__dataList.DeleteAllItems() self.__enableToolbar(ID.ID_TOOLBAR_NEXT_PAGE) self.__loadNextData() def onPrevPageEvent(self, event): self.__dataList.DeleteAllItems() self.__enableToolbar(ID.ID_TOOLBAR_PREV_PAGE) self.__loadPrevData() def onCopyUrlEvent(self, event): files = self.getSelectedFiles() value = "" for url, key, mimeType, fileSize in files: value += url + "\n" data = wx.TextDataObject() data.SetText(value) if wx.TheClipboard.Open(): wx.TheClipboard.SetData(data) wx.TheClipboard.Close() else: wx.MessageBox(u"不能打开剪切板!", u"复制错误") def onDeleteEvent(self, event): """删除文件""" self.__enableToolbar(ID.ID_TOOLBAR_TRASH, False) message = u"您确定删除以下文件?\n" files = [] index = self.__dataList.GetFirstSelected() while index != -1: item = self.__dataList.GetItem(index) key = item.GetText() message += key + "\n" files.append(key) index = self.__dataList.GetNextSelected(index) results = dialogs.messageDialog(self, message, "Sure?") if results.accepted: AsynchronousThread((self.deleteSelectedFile, files)).start() else: self.__downloadButtonAndDeleteButtonStatus() def deleteSelectedFile(self, files): ops = build_batch_delete(self.__bucketName, files) ret, info = self.__bucketManger.batch(ops) if info.ok(): wx.CallAfter(wx.MessageBox, u"删除成功", u"提示") wx.CallAfter(self.setBucketName, self.__bucketName) else: wx.CallAfter(wx.MessageBox, info.error) def onRefreshCacheEvent(self, event): """刷新缓存""" files = self.getSelectedFiles() for url, key, mimeType, fileSize in files: self.__bucketManger.prefetch(self.__bucketName, key) wx.MessageBox(u"更新成功", u"Note") def onRenameEvent(self, event): """重命名""" selected = len(self.getSelectedFiles()) if selected == 1: # self.__onEditNameStart(event) index = self.__dataList.GetFirstSelected() key = self.itemDataMap[index][0] results = dialogs.textEntryDialog(self, u"请输入修改的名字", u"重命名", key) if results.accepted: newKey = results.text try: ret, info = self.__bucketManger.rename( self.__bucketName, key, newKey) if info.ok(): wx.MessageBox(u"重命名成功!", u"成功") else: wx.MessageBox(info.error, u"错误") except: wx.MessageBox(u"名字错误,查阅七牛文档!", u"错误") else: wx.MessageBox(u"不能同时重命名多个文件!", u"错误") def onSearchEvent(self, event): if isinstance(event, wx.KeyEvent): keycode = event.GetKeyCode() if keycode == wx.WXK_RETURN or keycode == wx.WXK_NUMPAD_ENTER: pass else: event.Skip() return True textCtrl = self.__frame._toolbar.FindById( ID.ID_TOOLBAR_SEARCH_TEXT).GetControl() self.setPrefix(textCtrl.GetValue()) def onPageLimitEvent(self, event): limit = int(event.EventObject.GetStringSelection(), 10) self.setLimit(limit) event.Skip() def sortBy(self, type): dict = {u"名称": 0, u"大小": 2, u"时间": 3} idx = dict[type] def compare_func(row1, row2): val1 = self.itemDataMap[row1][idx] val2 = self.itemDataMap[row2][idx] if val1 < val2: return -1 elif val1 > val2: return 1 else: return 0 self.__dataList.SortItems(compare_func) def __enableToolbar(self, id, enable=False): """禁用或者启用某个菜单""" self.__toolbar.EnableTool(id, enable) def __updateStatus(self): moreMark = "+" if self.__marker == None: moreMark = "" statusText = (u"空间:%s" % (self.__bucketName)) self.__frame.SetStatusText(statusText, 2) statusText = (u"页码:%d/%d%s" % (self.__store.page(), self.__store.length(), moreMark)) self.__frame.SetStatusText(statusText, 3)
class MainFrame(framework.XFrame): def __init__(self): wx.Frame.__init__(self, None, -1, u'七牛文件管理(' + VERSION + ')', size=(800, 640)) self.conf = Config() ak, sk = self.conf.getKeys() self.__auth = qiniu.Auth(ak, sk) self.SetIcon(libs.icons.desktop().GetIcon()) #self.SetWindowStyle((self.GetWindowStyle() | wx.STAY_ON_TOP)) self.createSplitter() self.createMenuBar(self.menuData()) self.createToolBar(self.toolbarData()) self.createStatusBar([-1, 100, 140, 70]) self.createTaskBarIcon(self.taskMenuData()) self.Bind(wx.EVT_CLOSE, self.onHideEvent) self.Center() for bucket in self.conf.getBuckets(): self._bucketPanel.setBucketName(bucket) return def bucketMenuData(self): bucketsMenu = [] for bucket in self.conf.getBuckets(): bucketsMenu.append( (bucket, bucket, self.onBucketChangedEvent, wx.ITEM_RADIO)) bucketsMenu.append("---") bucketsMenu.append((u"新建空间", u"新建空间", self.onCreateBucketEvent)) return (u"空间", bucketsMenu) def menuData(self): return [(u"文件", [(u"上传", u"上传文件到当前空间", self.onUploadFileEvent), "---", (u"最小化", u"最小化到系统托盘", self.onHideEvent), (u"退出", u"退出系统", self.onExitEvent)]), (u"视图", [(u"查看方式", [([u"详细信息", u"列表", u"大图标", u"小图标"], "", self.onViewChangedEvent, wx.ITEM_RADIO)]), "---", (u"排序方式", [([u"名称", u"大小", u"时间"], "", self.onSortChangedEvent, wx.ITEM_RADIO)]), "---", (u"系统设置", u"系统运行视图参数设置", self.onConfigEvent)]), self.bucketMenuData(), (u"关于", [(u"检查更新", u"连接服务器检测是否更新", self.onUploadEvent), (u"关于软件", u"关于软件简介", self.onAboutSoftEvent), (u"关于作者", u"作者简介", self.onAboutUserEvent)])] def toolbarData(self): return [ (u"上传", u"上传文件到当前空间", "upload.png", self.onUploadFileEvent), ((ID.ID_TOOLBAR_DOWNLOAD, u"下载"), u"下载选中文件", ["download.png", "download.dis.png"], self.onDownloadFileEvent, False), "---", ((ID.ID_TOOLBAR_TRASH, u"删除"), u"删除选中文件", ["trash.png", "trash.dis.png"], self._bucketPanel.onDeleteEvent, False), "---", ((ID.ID_TOOLBAR_PREV_PAGE, U"上一页"), u"加载上一页文件", ["prev.png", "prev.dis.png"], self._bucketPanel.onPrevPageEvent, False), ((ID.ID_TOOLBAR_NEXT_PAGE, U"下一页"), u"加载下一页文件", ["next.png", "next.dis.png"], self._bucketPanel.onNextPageEvent, False), "---", (u"刷新", u"刷新当前页", "refresh.png", self._bucketPanel.onRefreshEvent), "---", ((ID.ID_TOOLBAR_LIMIT, u"显示个数:"), ["10", "20", "50", "100", "200", "500"], self._bucketPanel.onPageLimitEvent), "---", ((ID.ID_TOOLBAR_SEARCH_TEXT, u"搜索关键字"), (u"", u"文件前缀"), { wx.EVT_KEY_DOWN: self._bucketPanel.onSearchEvent }), (u"搜索", u"在当前空间搜索", "search.png", self._bucketPanel.onSearchEvent), ] def taskMenuData(self): return [(u"显示", u"", self.onShowEvent), "-", (u"关于软件", u"关于软件简介", self.onAboutSoftEvent), "-", (u"退出", u"", self.onExitEvent)] def createSplitter(self): self._splitter = wx.SplitterWindow(self) self._items = self.createBucketsPanel(self._splitter) self._uploadify = wx.Panel(self._splitter, style=wx.BORDER_SIMPLE) self._uploadify.SetSizer(wx.BoxSizer(wx.VERTICAL)) self._splitter.Initialize(self._items) return self._splitter def createBucketsPanel(self, parent): self._bucketPanel = BucketPanel(parent, self.__auth) self.SetDropTarget(FileDropUpLoadTarget(self.uploadFile)) return self._bucketPanel def onScheduleFinally(self, panel=None, status=True): """上传动作结束(正确上传,上传错误,。。。)均会调用""" if status and panel: self._uploadify.GetSizer().Hide(panel) self._uploadify.GetSizer().Remove(panel) self._uploadify.RemoveChild(panel) children = len(self._uploadify.GetChildren()) if children == 0: self.__switchSplitWindow(False) self._uploadify.Layout() def onUploadFileEvent(self, event): wildcard = u"所有文件 (*.*) | *.*" result = dialogs.fileDialog(parent=self._uploadify, title=u'选择文件', filename='', wildcard=wildcard, style=wx.OPEN) if result.accepted: for file_path in result.paths: if os.path.isdir(file_path): continue self.uploadFile(file_path) event.Skip() def onDownloadFileEvent(self, event): self.__switchSplitWindow(True) folder = "" results = dialogs.dirDialog(self, u"选择下载位置") if results.accepted: folder = results.path files = self._bucketPanel.getSelectedFiles() for file in files: dnPanel = DownloadPanel(folder, file, self.onScheduleFinally, self._uploadify) boxSizer = self._uploadify.GetSizer() boxSizer.Add(dnPanel, flag=wx.EXPAND) self._uploadify.Layout() event.Skip() else: self.onScheduleFinally(None, False) def uploadFile(self, file_path): self.__switchSplitWindow(True) bucketName = self._bucketPanel.getBucketName() up = UploadifyPanel(self.__auth, bucketName, file_path, self.onScheduleFinally, self._uploadify) boxSizer = self._uploadify.GetSizer() boxSizer.Add(up, flag=wx.EXPAND) #self._uploadify.GetSizer().Fit(self._uploadify) #self._uploadify.GetSizer().SetSizeHints(self._uploadify) self._uploadify.Layout() def __switchSplitWindow(self, open=True): """选择上传下载队列窗口状态""" if open: if not self._splitter.IsSplit(): rect = self.GetScreenRect() self._splitter.SplitVertically(self._items, self._uploadify, rect.width - 370) else: if self._splitter.IsSplit(): self._splitter.Unsplit() #self._bucketPanel.setBucketName(self._bucketPanel.getBucketName()) def onBucketChangedEvent(self, event): item = event.EventObject.FindItemById(event.GetId()) bucketName = item.GetText() self._bucketPanel.setBucketName(bucketName) def onViewChangedEvent(self, event): item = event.EventObject.FindItemById(event.GetId()) text = item.GetText() wx.MessageBox(u"首先感谢您的支持!视图查看功能此版本不包含。该项功能正在加紧开发。", u"抱歉") def onSortChangedEvent(self, event): item = event.EventObject.FindItemById(event.GetId()) text = item.GetText() self._bucketPanel.sortBy(text) def onCreateBucketEvent(self, event): wx.MessageBox(VERSION + u"版暂不支持此功能!", u"抱歉") def onConfigEvent(self, event): from libs.login import BucketConfigPanel class ConfigDialog(wx.Dialog): def __init__(self, parent): wx.Dialog.__init__(self, parent) conf = Config() boxSizer = wx.BoxSizer(wx.HORIZONTAL) b = BucketConfigPanel(self, conf.getBuckets().keys(), self.onOkBtn) boxSizer.Add(b, 1, wx.EXPAND) self.Layout() self.Center() def onOkBtn(self): self.Hide() self.Destroy() ConfigDialog(self).ShowModal() def onUploadEvent(self, event): webbrowser.open_new("http://github.com/ihaiker/QiniuAdminGui") def onAboutUserEvent(self, event): self.onUploadEvent(event) def onAboutSoftEvent(self, event): self.onUploadEvent(event)
class BucketPanel(wx.Panel, wx.lib.mixins.listctrl.ColumnSorterMixin): def __init__(self, parent, auth): wx.Panel.__init__(self, parent) self.__frame = self.GetParent().GetParent() self.__auth = auth self.__bucketManger = qiniu.BucketManager(self.__auth) self.__conf = Config() self.__bucketName = "" self.__download_url = None self.__prefix = "" self.__marker = None self.__limit = LIMIT self.__initImages() self.__boxSizer = wx.BoxSizer() self.__dataList = self.__initList() self.__boxSizer.Add(self.__dataList, 1, wx.EXPAND) self.__initPopMenu() self.SetSizer(self.__boxSizer) # init column sorter wx.lib.mixins.listctrl.ColumnSorterMixin.__init__(self, LIMIT) def GetListCtrl(self): return self.__dataList def GetSortImages(self): return (self.down, self.up) def OnSortOrderChanged(self): self.__downloadButtonAndDeleteButtonStatus() def setBucketName(self, bucketName): ## 之所以放在这是因为,在初始化此面板的时候还未初始化toolbar self.__toolbar = self.__frame._toolbar self.__bucketName = bucketName # 当前空间名称 self.__download_url = self.__conf.getBuckets()[self.__bucketName] self.__resetStartLoad() def setPrefix(self, prefix): self.__prefix = prefix self.__enableToolbar(ID.ID_TOOLBAR_SEARCH_BTN,False) self.__enableToolbar(ID.ID_TOOLBAR_SEARCH_TEXT,False) self.__resetStartLoad() def setLimit(self, limit): self.__limit = limit self.__enableToolbar(ID.ID_TOOLBAR_LIMIT,False) self.__resetStartLoad() def getBucketName(self): return self.__bucketName def __resetStartLoad(self): """从头开始重新加载""" self.__marker = None # 下一页marker,加载下一页的时候需要 self.__store = Store() # 保存数据 self.__dataList.DeleteAllItems() AsynchronousThread(self.__loadData).start() def __initImages(self): # load some images into an image list self.__images_16x = wx.ImageList(16, 16, False) self.__icons = [] for types, image in libs.mimetype.typeImage: self.__images_16x.Add(icons.mimeType('16x',image).GetBitmap()) self.__icons.append(image) self.up = self.__images_16x.AddWithColourMask(icons.get("/sorter/up.png").GetBitmap(),"blue") self.down = self.__images_16x.AddWithColourMask(icons.get("/sorter/down.png").GetBitmap(),"blue") def __initList(self): list = wx.ListCtrl(self, -1, style=wx.LC_REPORT | wx.LC_SORT_ASCENDING | wx.BORDER_SUNKEN) # assign the image list to it list.AssignImageList(self.__images_16x, wx.IMAGE_LIST_SMALL) # Add some columns for col, text in enumerate([u"路径", u"类型", u"大小", u"上传时间"]): list.InsertColumn(col, text, wx.CENTER) # set the width of the columns in various ways list.SetColumnWidth(0, 320) list.SetColumnWidth(1, 120) list.SetColumnWidth(2, 80) list.SetColumnWidth(3, 140) self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.__onTreeSelected, list) self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.__onTreeSelected, list) self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.__onTreeSelected, list) # rename event self.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.__onEditNameStart, list) self.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.__onEditNameEnd, list) # key up event (rename & delete) list.Bind(wx.EVT_KEY_UP, self.__onListKeyUp) #drop to download, bug bug #self.Bind(wx.EVT_LIST_BEGIN_DRAG, self._startDragEvent, list) return list def _startDragEvent(self, e): # create temp folder # folder = libs.config.WORK_PATH + "/temp" # libs.config.mkdirs(folder) text = self.__dataList.GetItem(e.GetIndex()).GetText() text = text if text[0] == "/" else "/" + text # temp_file = os.path.join(folder, os.path.basename(text if text[0] == "/" else "/" + text)) # Create drag data data = wx.FileDataObject() data.AddFile(text) # Create drop source and begin drag-and-drop. dropSource = wx.DropSource(self.__dataList) dropSource.SetData(data) # Get Source res = dropSource.DoDragDrop(flags=wx.Drag_AllowMove) if res == wx.DragMove or res == wx.DragCopy: ## 下载 print("DragMove & DragCopy") return text def __onTreeSelected(self, event): self.__downloadButtonAndDeleteButtonStatus() def __pageButtonStatus(self): self.__enableToolbar(ID.ID_TOOLBAR_SEARCH_BTN,True) self.__enableToolbar(ID.ID_TOOLBAR_SEARCH_TEXT,True) self.__enableToolbar(ID.ID_TOOLBAR_LIMIT,True) self.__enableToolbar(ID.ID_TOOLBAR_NEXT_PAGE, self.__store.hasNext() or self.__marker != None) self.__enableToolbar(ID.ID_TOOLBAR_PREV_PAGE, self.__store.hasPrev()) self.__updateStatus() self.__downloadButtonAndDeleteButtonStatus() def __downloadButtonAndDeleteButtonStatus(self): selected = self.__dataList.GetSelectedItemCount() > 0 self.__enableToolbar(ID.ID_TOOLBAR_DOWNLOAD, selected and self.__download_url != None and self.__download_url != "") self.__enableToolbar(ID.ID_TOOLBAR_TRASH, selected) def __loadNextData(self): if self.__store.hasNext(): self.__showData(self.__store.next()) self.__pageButtonStatus() elif self.__marker != None: AsynchronousThread(self.__loadData).start() def __loadPrevData(self): if self.__store.hasPrev(): self.__showData(self.__store.prev()) self.__pageButtonStatus() def __loadData(self): ret, eof, info = self.__bucketManger.list(bucket=self.__bucketName, marker=self.__marker,limit=self.__limit, prefix=self.__prefix) if info.ok(): items = ret.get("items") self.__store.add(items) wx.CallAfter(self.__showData,items) if not eof: self.__marker = ret.get("marker") else: self.__marker = None else: if self.__marker != None: self.__enableToolbar(ID.ID_TOOLBAR_NEXT_PAGE, True) wx.MessageBox(info.error) self.__pageButtonStatus() def __showData(self, items): self.itemDataMap = {} for row, item in enumerate(items): name = item.get(u"key") fsize = libs.config.fileSizeShow(item.get(u"fsize")) putTime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(round(item.get("putTime") / 10000 / 1000))) mimeType = item.get(u"mimeType") image = libs.mimetype.showType(mimeType, name) index = self.__dataList.InsertStringItem(sys.maxint, name) self.__dataList.SetStringItem(index, 1, mimeType) self.__dataList.SetStringItem(index, 2, fsize) self.__dataList.SetStringItem(index, 3, putTime) self.__dataList.SetItemData(index, row) # sort data self.itemDataMap[index] = (name, mimeType, item.get("fsize"), item.get("putTime")) # 设置图标 self.__dataList.SetItemImage(index, self.__icons.index(image)) def __initPopMenu(self): self.popupMenu = wx.Menu() urlMenu = self.popupMenu.Append(-1, u"复制地址", u"复制地址") self.Bind(wx.EVT_MENU, self.onCopyUrlEvent, urlMenu) self.popupMenu.AppendSeparator() deleteMenu = self.popupMenu.Append(-1, u"删除",u"删除选中文件") self.Bind(wx.EVT_MENU, self.onDeleteEvent, deleteMenu) refreshMenu = self.popupMenu.Append(-1, u"更新", u"强制更新缓存,保证上传的文件可以显示最新") self.Bind(wx.EVT_MENU, self.onRefreshCacheEvent, refreshMenu) renameMenu = self.popupMenu.Append(-1, u"重命名", u"重命名") self.Bind(wx.EVT_MENU, self.onRenameEvent, renameMenu) downloadMenu = self.popupMenu.Append(-1, u"下载", u"下载选中文件") self.Bind(wx.EVT_MENU, self.__frame.onDownloadFileEvent, downloadMenu) self.Bind(wx.EVT_CONTEXT_MENU, self.__onShowPopup) def __onShowPopup(self, event): if len(self.getSelectedFiles()) != 0 : pos = event.GetPosition() pos = self.ScreenToClient(pos) self.PopupMenu(self.popupMenu, pos) else: ##没有选中文件,不可操作 pass def __onPopupItemSelected(self, event): item = self.popupMenu.FindItemById(event.GetId()) text = item.GetText() wx.MessageBox("You selected item '%s'" % text) def __onListKeyUp(self, event): keyCode = event.GetKeyCode() if keyCode == wx.WXK_DELETE: self.onDeleteEvent(event) elif keyCode == wx.WXK_F2: if len(self.getSelectedFiles()) == 1: self.onRenameEvent(event) elif event.ControlDown() and keyCode == 67: self.onCopyUrlEvent(event) elif event.ControlDown() and keyCode == 65: for index in range(self.__dataList.GetItemCount()): self.__dataList.Select(index, True) event.Skip() def __onEditNameStart(self, event): print("重命名开始") def __onEditNameEnd(self, event): print("重命名结束") def getSelectedFiles(self): files = [] index = self.__dataList.GetFirstSelected() while index != -1: item = self.__dataList.GetItem(index) key = item.GetText() mimeType = self.itemDataMap[index][1] fileSize = self.itemDataMap[index][2] base_url = 'http://%s/%s' % (self.__download_url, key) private_url = self.__auth.private_download_url(base_url, expires=3600) files.append((private_url,key,mimeType,fileSize)) index = self.__dataList.GetNextSelected(index) return files def onRefreshEvent(self,event): self.__resetStartLoad() def onNextPageEvent(self, event): self.__dataList.DeleteAllItems() self.__enableToolbar(ID.ID_TOOLBAR_NEXT_PAGE) self.__loadNextData() def onPrevPageEvent(self, event): self.__dataList.DeleteAllItems() self.__enableToolbar(ID.ID_TOOLBAR_PREV_PAGE) self.__loadPrevData() def onCopyUrlEvent(self, event): files = self.getSelectedFiles() value = "" for url, key, mimeType, fileSize in files: value += url + "\n" data = wx.TextDataObject() data.SetText(value) if wx.TheClipboard.Open(): wx.TheClipboard.SetData(data) wx.TheClipboard.Close() else: wx.MessageBox(u"不能打开剪切板!", u"复制错误") def onDeleteEvent(self, event): """删除文件""" self.__enableToolbar(ID.ID_TOOLBAR_TRASH,False) message = u"您确定删除以下文件?\n" files = [] index = self.__dataList.GetFirstSelected() while index != -1: item = self.__dataList.GetItem(index) key = item.GetText() message += key + "\n" files.append(key) index = self.__dataList.GetNextSelected(index) results = dialogs.messageDialog(self,message,"Sure?") if results.accepted : AsynchronousThread((self.deleteSelectedFile,files)).start() else: self.__downloadButtonAndDeleteButtonStatus() def deleteSelectedFile(self,files): ops = build_batch_delete(self.__bucketName, files) ret, info = self.__bucketManger.batch(ops) if info.ok() : wx.CallAfter(wx.MessageBox,u"删除成功",u"提示") wx.CallAfter(self.setBucketName, self.__bucketName) else: wx.CallAfter(wx.MessageBox,info.error) def onRefreshCacheEvent(self, event): """刷新缓存""" files = self.getSelectedFiles() for url,key,mimeType,fileSize in files : self.__bucketManger.prefetch(self.__bucketName, key) wx.MessageBox(u"更新成功",u"Note") def onRenameEvent(self, event): """重命名""" selected = len(self.getSelectedFiles()) if selected == 1: # self.__onEditNameStart(event) index = self.__dataList.GetFirstSelected() key = self.itemDataMap[index][0] results = dialogs.textEntryDialog(self, u"请输入修改的名字", u"重命名", key) if results.accepted : newKey = results.text try: ret, info = self.__bucketManger.rename(self.__bucketName, key, newKey) if info.ok(): wx.MessageBox(u"重命名成功!", u"成功") else: wx.MessageBox(info.error, u"错误") except: wx.MessageBox(u"名字错误,查阅七牛文档!", u"错误") else: wx.MessageBox(u"不能同时重命名多个文件!", u"错误") def onSearchEvent(self, event): if isinstance(event,wx.KeyEvent): keycode = event.GetKeyCode() if keycode == wx.WXK_RETURN or keycode == wx.WXK_NUMPAD_ENTER : pass else: event.Skip() return True textCtrl = self.__frame._toolbar.FindById(ID.ID_TOOLBAR_SEARCH_TEXT).GetControl() self.setPrefix(textCtrl.GetValue()) def onPageLimitEvent(self, event): limit = int(event.EventObject.GetStringSelection(), 10) self.setLimit(limit) event.Skip() def sortBy(self, type): dict = {u"名称": 0, u"大小": 2, u"时间": 3} idx = dict[type] def compare_func(row1, row2): val1 = self.itemDataMap[row1][idx] val2 = self.itemDataMap[row2][idx] if val1 < val2: return -1 elif val1 > val2: return 1 else: return 0 self.__dataList.SortItems(compare_func) def __enableToolbar(self, id, enable=False): """禁用或者启用某个菜单""" self.__toolbar.EnableTool(id, enable) def __updateStatus(self): moreMark = "+" if self.__marker == None: moreMark = "" statusText = (u"空间:%s" % (self.__bucketName)) self.__frame.SetStatusText(statusText, 2) statusText = (u"页码:%d/%d%s" % (self.__store.page(), self.__store.length(),moreMark)) self.__frame.SetStatusText(statusText, 3)
class BucketConfigPanel(wx.Panel): def __init__(self, parent, buckets, onConfigSuccess): wx.Panel.__init__(self, parent, style=wx.BORDER_SIMPLE) self.frame = parent self.onConfigSuccess = onConfigSuccess self.buckets = buckets self.conf = Config() self.startConfigBucket() def startConfigBucket(self): mainSizer = wx.BoxSizer(wx.VERTICAL) title = wx.StaticText(self, -1, u"配置空间下载域名") title.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD)) mainSizer.Add((0, 10)) mainSizer.Add(title, 0, wx.CENTER | wx.TOP | wx.BOTTOM, 10) mainSizer.Add((0, 10)) mainSizer.Add(wx.StaticLine(self), 0, wx.EXPAND | wx.TOP | wx.BOTTOM, 5) configBuckets = self.conf.getBuckets() self.bucketsSizer = wx.FlexGridSizer(cols=3, hgap=3, vgap=3) for idx, bucket in enumerate(self.buckets): domain = configBuckets.get(bucket) or "" bucketName = wx.StaticText(self, -1, bucket) self.bucketsSizer.Add(bucketName, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL) bucketDomain = wx.TextCtrl(self, -1, domain, size=(160,25)) bucketDomain.SetHint(u"未配置部分功能不可使用") self.bucketsSizer.Add(bucketDomain, 2, wx.EXPAND) bmp = libs.icons.get("/status/question.png").GetBitmap() button = wx.BitmapButton(self, -1, bmp) self.bucketsSizer.Add(button, 0, wx.EXPAND) self.bucketsSizer.AddGrowableCol(1) mainSizer.Add(self.bucketsSizer, 0, wx.EXPAND | wx.ALL, 5) okBtn = wx.Button(self, -1, u"确定") okBtn.Bind(wx.EVT_BUTTON, self.endConfigBucket) exitBtn = wx.Button(self, -1, u"退出") exitBtn.Bind(wx.EVT_BUTTON, self.OnExit) btnSizer = wx.BoxSizer(wx.HORIZONTAL) btnSizer.Add((50, 20)) btnSizer.Add(okBtn,1) btnSizer.Add((50, 20)) btnSizer.Add(exitBtn,1) btnSizer.Add((50, 20)) mainSizer.Add(btnSizer, 0, wx.EXPAND | wx.ALL, 10) self.SetSizer(mainSizer) def endConfigBucket(self, event): items = self.bucketsSizer.GetChildren() buffers = {} for idx in range(0, len(items) / 3): if idx * 3 + 1 < len(items): input = items[idx * 3 + 1] bucketName = items[idx*3].GetWindow().GetLabelText() oldDomain = input.GetWindow().GetLabelText() domain = input.GetWindow().GetValue() if oldDomain != domain: print(u"检查【%s】下载地址: http://%s"%(bucketName,domain)) buffers[bucketName] = domain self.conf.setBuckets(buffers) self.onConfigSuccess() def OnExit(self, evt): self.frame.Hide() self.frame.Destroy()