def getDrives(self): if isWindowsOS(): import win32api drives = win32api.GetLogicalDriveStrings() drives = drives.split('\x00') drives = [normalisePath(drive) for drive in drives if drive] drives.sort() else: drives = [] return drives
def testWriteAccess(self): try: fileName = joinPath(self.installRoot, '__write_test__') file = open(fileName, 'w') file.close() os.remove(fileName) except: if not isWindowsOS(): message = 'File updates not possible: You do not have write access to %s%s' % ( self.installRoot, os.sep) else: message = 'File updates not possible: You do not have write access to %s%s' % (self.installRoot,os.sep) \ + '\n\nTry running Analysis as administrator by right clicking on the Analysis ' \ + 'shortcut on the desktop and selecting "Run as administrator", and then apply any updates.' self.warningMessage('Failure', message) return False return True
def installUpdates(self): if self.isGraphical and not showOkCancel( 'Confirmation', 'Continue with file upgrade?'): return if not self.server: self.warningMessage('Warning', 'No accessible server') return if not self.installRoot: self.warningMessage('Warning', 'No installation path') return updates = self.server.getSelectedUpdates() if not updates: self.warningMessage('Warning', 'No selected updates to install') return needMake = False needMakeClean = False needMakeLinks = False for update in updates: update.setInstallFromCache() if update.fileName.endswith('.c'): needMake = True elif update.fileName.endswith('.h'): needMake = needMakeClean = True elif update.fileName == 'Makefile': needMake = needMakeClean = needMakeLinks = True if not isWindowsOS(): self.compileCode(needMakeClean=needMakeClean, needMake=needMake, needMakeLinks=needMakeLinks) if self.isGraphical and not self.isStandAlone: self.warningMessage( 'Notice', 'All updates complete. You must restart for changes to take effect.' )
def getDrives(self): if isWindowsOS(): #import win32api #drives = win32api.GetLogicalDriveStrings() #drives = drives.split('\x00') #drives = [normalisePath(drive) for drive in drives if drive] #drives.sort() # 19 Mar 2012: do not use win32api because not standard from ctypes import windll import string drives = [] bitmask = windll.kernel32.GetLogicalDrives() for letter in string.ascii_uppercase: if bitmask & 1: drives.append(letter) bitmask >>= 1 drives = [drive + ':\\' for drive in drives] drives = [normalisePath(drive) for drive in drives] else: drives = [] return drives
def isGeneralDataWriteable(generalDataRepository): oldPath = generalDataRepository.url.path return (isWindowsOS() or os.access(oldPath, os.W_OK | os.X_OK))
def saveProject(project, newPath=None, newProjectName=None, changeBackup=True, createFallback=False, removeExisting=False, showYesNo=None, checkValid=False, changeDataLocations=False, showWarning=None, revertToOriginal=False): """ Save the userData for a project to a location given by newPath (the url.path of the userData repository) if set, or the existing location if not. If userData does not exist then throws IOError. If newPath is not specified then it is set to oldPath. If newProjectName is not specified then it is set to oldProjectName if newPath==oldPath, otherwise it is set to basename(newPath). If changeBackup, then also changes backup URL path for project. If createFallback, then makes copy of existing modified topObjects files (in newPath, not oldPath) before doing save. If newPath != oldPath and newPath exists (either as file or as directory): If removeExisting: Delete the newPath. Else if showYesNo: Ask the user if it is ok to delete the newPath If yes, delete. If no, return without saving. Else: Raise an IOError Elif newProjectName != oldProjectName and there exists corresponding path (file/directory): If removeExisting: Delete the path. Else if showYesNo: Ask the user if it is ok to delete the path. If yes, delete. If no, return without saving. Else: Raise an IOError If checkValid then does checkAllValid on project If changeDataLocations then copy to project directory If revertToOriginal then after the save changes paths back to as they were originally If there is no exception or early return then at end userData is pointing to newPath. Return True if save done, False if not (unless there is an exception) """ # check project valid (so don't save an obviously invalid project) if checkValid: project.checkAllValid() # only want to change path for userData userData = project.findFirstRepository(name='userData') if not userData: raise IOError('Problem: userData not found') oldPath = userData.url.path oldProjectName = project.name if newPath: # normalise newPath newPath = normalisePath(newPath, makeAbsolute=True) else: newPath = oldPath # if newProjectName isn't specified then use default if not newProjectName: if newPath == oldPath: newProjectName = oldProjectName else: newProjectName = os.path.basename(newPath) # below is because of data model limit newProjectName = newProjectName[:32] renameProject(project, newProjectName) # if newPath same as oldPath, check if newProjectName already exists if it's not same as oldProjectName if newPath == oldPath: if newProjectName != oldProjectName: location = xmlUtil.getTopObjectPath(project) if os.path.exists(location): answer = checkRemoveIfExists(location, removeExisting, showYesNo) if answer is None: project.__dict__[ 'name'] = oldProjectName # TBD: for now name is frozen so change this way return False else: # check instead if newPath already exists if os.path.exists(newPath): answer = checkRemoveIfExists(newPath, removeExisting, showYesNo) if answer is None: if newProjectName != oldProjectName: project.__dict__[ 'name'] = oldProjectName # TBD: for now name is frozen so change this way return False # TBD: should we be removing it? removePath(newPath) else: # NBNB 2008/04/03 Rasmus Fogh. Added because it otherwise fell over when # target path did not exist upDir = os.path.dirname(newPath) if not os.path.exists(upDir): os.makedirs(upDir) # check if any topObject activeRepository is not either of above refData = project.findFirstRepository(name='refData') genData = project.findFirstRepository(name='generalData') topObjects = [] repositories = set() for topObject in project.topObjects: repository = topObject.findFirstActiveRepository() if repository and repository not in (userData, refData, genData): topObjects.append(topObject) repositories.add(repository) if topObjects: print( 'Warning, topObjects %s, in repositories %s, being left in original locations' % (topObjects, repositories)) try: oldUrl = userData.url if changeBackup: # change project backup url to point to new path backupRepository = project.findFirstRepository(name="backup") if backupRepository: oldBackupUrl = backupRepository.url else: changeBackup = False # copy userData files over if newPath != oldPath: # if os.path.exists(oldPath): # only copy if this is a directory if os.path.isdir(oldPath): # just copy everything from oldPath to newPath print( 'Copying directory %s to %s (this might take some time if there are big files)' % (oldPath, newPath)) shutil.copytree(oldPath, newPath) # but need toz remove all implementation files implPath = joinPath(newPath, ImpConstants.modellingPackageName, ImpConstants.implementationPackageName) #implPath = pathImplDirectory(newPath) removePath(implPath) # and need to repoint dataUrl's that were copied over oldPathP = oldPath + '/' for dataLocationStore in project.dataLocationStores: for dataStore in dataLocationStore.dataStores: oldDataPath = dataStore.fullPath if oldDataPath.startswith(oldPathP): dataUrl = dataStore.dataUrl oldDataUrlPath = dataUrl.url.dataLocation if oldDataUrlPath.startswith( oldPathP): # normally true newDataUrlPath = newPath + oldDataUrlPath[ len(oldPath):] dataUrl.url = Implementation.Url( path=newDataUrlPath) else: # path split awkwardly between absolute and relative newDataUrlPath = newPath dataUrl.url = Implementation.Url( path=newDataUrlPath) dataStore.path = oldDataPath[len(oldPath):] # change userData url to point to new path userData.url = Implementation.Url(path=newPath) # above will set project.isModified = True if changeBackup: # change project backup repository url to point to new path backupRepository.url = Implementation.Url(path=newPath + '_backup') # change project name if newProjectName != oldProjectName: if not project.isModified: # if it isModified it will be saved below if createFallback: createTopObjectFallback(project) project.save() # create fallbacks and keep track of modified topObjects modifiedTopObjects = [] if createFallback: for topObject in (project, ) + tuple(project.topObjects): if not topObject.isDeleted and topObject.isModified: createTopObjectFallback(topObject) modifiedTopObjects.append(topObject) if changeDataLocations: dataLocationStores = project.sortedDataLocationStores() userRepository = project.findFirstRepository(name='userData') userPath = userRepository.url.dataLocation # 2010 Aug 11: remove data directory from path #dataPath = joinPath(userPath, 'data') dataPath = userPath # 2010 Aug 11: change name #dataStorePrefix = 'dataStore' dataStorePrefix = 'spectra' if os.path.exists(dataPath): files = [ xx for xx in os.listdir(dataPath) if xx.startswith(dataStorePrefix) ] offset = len(files) else: offset = 0 copyingList = [] dataUrlDict = {} for dataLocationStore in dataLocationStores: for dataStore in dataLocationStore.sortedDataStores(): # wb104: 24 Mar 2010: below check is a complete kludge # we should check whether dataStore is instance of # NumericMatrix, etc., but those are in ccp so should # not be imported here # in any case, there is no proper way to find out if # a dataStore is used without explicit knowledge of class knt = 0 # hicard = 1 for attr in ('nmrDataSourceImage', ): if hasattr(dataStore, attr): if getattr(dataStore, attr): knt += 1 # hicard > 1 for attr in ('externalDatas', 'nmrDataSources'): if hasattr(dataStore, attr): knt += len(getattr(dataStore, attr)) if knt == 0: continue oldFullPath = dataStore.fullPath if not oldFullPath.startswith(userPath + '/'): # first figure out new dataUrl path dataUrl = dataStore.dataUrl oldPath = dataUrl.url.dataLocation if dataUrl in dataUrlDict: newUrl = dataUrlDict[dataUrl] else: offset += 1 newUrlPath = '%s%d' % (dataStorePrefix, offset) newUrlPath = joinPath(dataPath, newUrlPath) newUrl = dataUrlDict[dataUrl] = Implementation.Url( path=newUrlPath) # then add to list to copy over if original data exists if os.path.exists(oldFullPath): newFullPath = joinPath(newUrl.dataLocation, dataStore.path) copyingList.append((oldFullPath, newFullPath)) # now copy data files over nfilesToCopy = len(copyingList) for n, (oldFullPath, newFullPath) in enumerate(copyingList): dirName = os.path.dirname(newFullPath) if not os.path.exists(dirName): os.makedirs(dirName) print('Copying file %s to %s (%d of %d)' % (oldFullPath, newFullPath, n + 1, nfilesToCopy)) shutil.copy(oldFullPath, newFullPath) # finally change dataUrl paths for dataUrl in dataUrlDict: dataUrl.url = dataUrlDict[dataUrl] # save modifications # change way doing save in case exception is thrown if createFallback: for topObject in modifiedTopObjects: try: topObject.save() except: location = xmlUtil.getTopObjectPath(topObject) print('Exception working on topObject %s, file %s' % (topObject, location)) raise # be safe and do below in case new modifications after # modifiedTopObjects has been created project.saveModified() else: project.saveModified() if not isWindowsOS(): os.system('touch "%s"' % newPath) # so that user can see which are most recent badTopObjects = [] for topObject in modifiedTopObjects: if not checkFileIntegrity(topObject): badTopObjects.append(topObject) if badTopObjects: if showWarning: showWarning( 'Incomplete save', 'It looks like one or more files did not save completely, see console for list' ) print( 'It looks like one or more files did not save completely, you should check them:' ) for topObject in badTopObjects: print print('%s, path:' % topObject) print(xmlUtil.getTopObjectPath(topObject)) return False if revertToOriginal: # TBD: the below does not change back dataUrl paths if newProjectName != oldProjectName: project.__dict__[ 'name'] = oldProjectName # TBD: for now name is frozen so change this way if newPath != oldPath: userData.url = oldUrl if changeBackup: backupRepository.url = oldBackupUrl return True except: # saveModified failed so revert to old values if newProjectName != oldProjectName: project.__dict__[ 'name'] = oldProjectName # TBD: for now name is frozen so change this way if newPath != oldPath: userData.url = oldUrl if changeBackup: backupRepository.url = oldBackupUrl try: removePath(newPath) except: pass raise
print 'Error, cannot import core CCPN Python modules:' print 'Maybe your PYTHONPATH environment variable is not set or' print 'does not contain the current CCPN installation directory.' raise from memops.general.Implementation import ApiError from memops.gui.MessageReporter import showError from memops.universal.Util import isWindowsOS from ccp.gui.Io import loadProject from ccpnmr.analysis.AnalysisPopup import AnalysisPopup if isWindowsOS(): # create interactive session when using MS Windows os.environ["PYTHONINSPECT"]="x" top = None def main(projectDir=None, cache_size=64, glDirect=None): global top #print 'cache_size =', cache_size root = Tkinter.Tk() root.withdraw() root.option_add("*Background", "grey90") root.option_add("*Font", "Helvetica -12")
def __init__(self, parent, title='', location='', hide=False, font=None, modal=False, transient=False, quitFunc=None, docKey=None, tipText=None, createToolTip=False, *args, **kw): self.parent = parent self.location = location self.isTransient = transient self.modal = modal if (not kw.has_key('bg') and not kw.has_key('background')): kw['bg'] = 'grey90' Tkinter.Toplevel.__init__(self, parent, *args, **kw) Base.__init__(self, docKey=docKey, tipText=tipText, createToolTip=createToolTip) if modal: self.config(borderwidth=5, bg='red') if (not location): x = parent.winfo_rootx() + 50 y = parent.winfo_rooty() + 50 location = '+%d+%d' % (x, y) if hasattr(parent, 'top'): self.top = parent.top else: self.top = self if (parent and transient): self.transient(parent) self.var = Tkinter.StringVar() self.setTitle(title) #self.root = self._root() self.geometry(location) if hide: self.withdraw() self.protocol('WM_DELETE_WINDOW', self.close) #self.bind('<Escape>', self.close) self.grid_rowconfigure(0, weight=1) self.grid_columnconfigure(0, weight=1) frame = Frame(self) frame.grid(row=0, column=0, sticky=Tkinter.NSEW) if quitFunc: self.protocol('WM_DELETE_WINDOW', quitFunc) self.initial_focus = self.body(frame) if not self.initial_focus: self.initial_focus = self self.initial_focus.focus_set() #base_popups.append(self) self.help_popup = None if not hasattr(self, 'font'): if font is None: if hasattr(parent, 'font'): font = parent.font self.font = font self.setFont() if modal: self.do_grab() self.wait_variable(self.var) if isWindowsOS(): # Fix so that Windows popups aren't empty when opened self.update_idletasks() geometry = self.geometry() size = geometry.split('+')[0] x, y = size.split('x') x = str(int(x) + 1) self.geometry('%sx%s' % (x, y))
def __init__(self, parent, scrollX=True, scrollY=True, *args, **kw): self.parent = parent self.scrollX = scrollX self.scrollY = scrollY self.prototypes = [] self.nodes = [] self.node = None # Selected self.links = [] self.link = None # Selected self.objDict = {} # Map canvas to nodes, links self.cornerDict = {} self.editWidget = None self.mouseOver = None self.inMotion = None self.inMotion2 = None self.inMotion3 = None self.dragRegion = None self._resizeBusy = False self.selectedNodes = [] self.selectedLinks = [] self.highlightNodes = [] self.highlightLinks = [] kw['relief'] = 'flat' kw['borderwidth'] = 0 Frame.__init__(self, parent, *args, **kw) self.canvas = canvas = Canvas(self, relief='flat', borderwidth=0) self.canvas.configure(xscrollincrement=2, yscrollincrement=2, bg=self.cget('bg')) self.canvas.grid(row=0, column=0, sticky='nsew') if scrollX: self.horizScrollbar = Tkinter.Scrollbar(self, bg=self.cget('bg'), command=self.canvas.xview, orient=Tkinter.HORIZONTAL, borderwidth=1) self.canvas.configure(xscrollcommand=self.horizScrollbar.set) if scrollY: self.vertScrollbar = Tkinter.Scrollbar(self, bg=self.cget('bg'), command=self.canvas.yview, orient=Tkinter.VERTICAL, borderwidth=1) self.canvas.configure(yscrollcommand=self.vertScrollbar.set) canvas.bind('<Button-1>', self._mouseSingleClick) if not isWindowsOS(): canvas.bind('<Button-4>', self.scrollUp) canvas.bind('<Button-5>', self.scrollDown) else: canvas.bind('<MouseWheel>', self._windowsOsScroll) canvas.bind('<Double-1>', self._mouseDoubleClick) canvas.bind('<B1-Motion>', self._mouseDrag) canvas.bind('<ButtonRelease-1>', self._mouseRelease) canvas.bind('<Motion>', self._mouseEnter) canvas.bind('<Enter>', self._mouseEnter) canvas.bind('<Leave>', self._mouseLeave) canvas.bind('<KeyPress-Up>', self._moveUp) canvas.bind('<KeyPress-Down>', self._moveDown) canvas.bind('<KeyPress-Right>', self._moveRight) canvas.bind('<KeyPress-Left>', self._moveLeft) canvas.bind('<KeyPress-Delete>', self.deleteSelected) self.bind('<Configure>', self._resizeAfter) self.menu = Menu(self, tearoff=False) alignItems = [{ 'kind': 'command', 'label': 'Y axis', 'command': self._alignHorizontal }, { 'kind': 'command', 'label': 'X axis', 'command': self._alignVertical }] distributeItems = [{ 'kind': 'command', 'label': 'Horizontal', 'command': self._distributeHorizontal }, { 'kind': 'command', 'label': 'Verical', 'command': self._distributeVertical }] menuItems = [ { 'kind': 'cascade', 'label': 'Align', 'submenu': alignItems }, #0 { 'kind': 'cascade', 'label': 'Distribute', 'submenu': distributeItems }, #1 { 'kind': 'command', 'label': 'Link Selected', 'command': self.linkSelected }, #2 { 'kind': 'command', 'label': 'Reset Links', 'command': self._resetLinks }, #3 { 'kind': 'separator' }, { 'kind': 'command', 'label': 'Delete Links', #5 'command': self.deleteLinks }, { 'kind': 'command', 'label': 'Delete Items', #6 'command': self.deleteNodes }, { 'kind': 'separator' }, { 'kind': 'command', 'label': 'Save PostScript File', 'command': self.printCanvas }, ] self.menuItems = menuItems self.menu.setMenuItems(menuItems) canvas.bind('<ButtonPress-3>', self._popupMenu) self._drawAfter()
def saveProject(project, newPath = None, newProjectName = None, changeBackup = True, createFallback = False, removeExisting = False, showYesNo = None, checkValid = False): """ Save the userData for a project to a location given by newPath (the url.path of the userData repository) if set, or the existing location if not. If userData does not exist then throws IOError. If newPath is not specified then it is set to oldPath. If newProjectName is not specified then it is set to oldProjectName if newPath==oldPath, otherwise it is set to basename(newPath). If changeBackup, then also changes backup URL path for project. If createFallback, then makes copy of existing modified topObjects files (in newPath, not oldPath) before doing save. If newPath != oldPath and newPath exists (either as file or as directory): If removeExisting: Delete the newPath. Else if showYesNo: Ask the user if it is ok to delete the newPath If yes, delete. If no, return without saving. Else: Raise an IOError Elif newProjectName != oldProjectName and there exists corresponding path (file/directory): If removeExisting: Delete the path. Else if showYesNo: Ask the user if it is ok to delete the path. If yes, delete. If no, return without saving. Else: Raise an IOError if checkValid then does checkAllValid on project If there is no exception or early return then at end userData is pointing to newPath. Return True if save done, False if not (unless there is an exception) """ # check project valid (so don't save an obviously invalid project) if checkValid: project.checkAllValid() # only want to change path for userData userData = project.findFirstRepository(name='userData') if not userData: raise IOError('Problem: userData not found') oldPath = userData.url.path oldProjectName = project.name if newPath: # normalise newPath newPath = normalisePath(newPath, makeAbsolute=True) else: newPath = oldPath # if newProjectName isn't specified then use default if not newProjectName: if newPath == oldPath: newProjectName = oldProjectName else: newProjectName = os.path.basename(newPath) # change project name if newProjectName != oldProjectName: project.override = True # TBD: for now name is frozen so change this way try: # below constraint is not checked in setName() if override is True so repeat here isValid = newProjectName.isalnum() # superfluous but faster in most cases if not isValid: for cc in newProjectName: if cc != '_' and not cc.isalnum(): isValid = False break else: isValid = True if (not (isValid)): raise ApiError('project name must only have characters that are alphanumeric or underscore') # below checks for length of name as well project.name = newProjectName finally: project.override = False # if newPath same as oldPath, check if newProjectName already exists if it's not same as oldProjectName if newPath == oldPath: if newProjectName != oldProjectName: location = xmlUtil.getTopObjectPath(project) if os.path.exists(location): answer = checkRemoveIfExists(location, removeExisting, showYesNo) if answer is None: project.__dict__['name'] = oldProjectName # TBD: for now name is frozen so change this way return False else: # check instead if newPath already exists if os.path.exists(newPath): answer = checkRemoveIfExists(newPath, removeExisting, showYesNo) if answer is None: if newProjectName != oldProjectName: project.__dict__['name'] = oldProjectName # TBD: for now name is frozen so change this way return False # TBD: should we be removing it? removePath(newPath) else: # NBNB 2008/04/03 Rasmus Fogh. Added because it otherwise fell over when # target path did not exist upDir = os.path.dirname(newPath) if not os.path.exists(upDir): os.makedirs(upDir) # check if any topObject activeRepository is not either of above refData = project.findFirstRepository(name='refData') genData = project.findFirstRepository(name='generalData') topObjects = [] repositories = set() for topObject in project.topObjects: repository = topObject.findFirstActiveRepository() if repository and repository not in (userData, refData, genData): topObjects.append(topObject) repositories.add(repository) if topObjects: print 'Warning, topObjects %s, in repositories %s, being left in original locations' % (topObjects, repositories) try: oldUrl = userData.url if changeBackup: # change project backup url to point to new path backupRepository = project.findFirstRepository(name="backup") if backupRepository: oldBackupUrl = backupRepository.url else: changeBackup = False # copy userData files over if newPath != oldPath: # if os.path.exists(oldPath): # only copy if this is a directory if os.path.isdir(oldPath): # just copy everything from oldPath to newPath shutil.copytree(oldPath, newPath) # but need to remove all implementation files implPath = joinPath(newPath, ImpConstants.modellingPackageName, ImpConstants.implementationPackageName) #implPath = pathImplDirectory(newPath) removePath(implPath) # change userData url to point to new path userData.url = Implementation.Url(path=newPath) # above will set project.isModified = True if changeBackup: # change project backup repository url to point to new path backupRepository.url = Implementation.Url(path=newPath+'_backup') # change project name if newProjectName != oldProjectName: if not project.isModified: # if it isModified it will be saved below if createFallback: createTopObjectFallback(project) project.save() # create fallbacks if createFallback: for topObject in (project,)+tuple(project.topObjects): if not topObject.isDeleted and topObject.isModified: createTopObjectFallback(topObject) # save modifications project.saveModified() if not isWindowsOS(): os.system('touch %s' % newPath) # so that user can see which are most recent return True except: # saveModified failed so revert to old values if newProjectName != oldProjectName: project.__dict__['name'] = oldProjectName # TBD: for now name is frozen so change this way if newPath != oldPath: userData.url = oldUrl if changeBackup: backupRepository.url = oldBackupUrl try: removePath(newPath) except: pass raise