def addObserverForTopics(self, anObserver, aTopics, ownsWeak): if not anObserver: raise ServerException(nsError.NS_ERROR_FAILURE, "Invalid Observer") self.cv.acquire() try: for aTopic in aTopics: self._addObserver(anObserver, aTopic, ownsWeak) finally: self.cv.release()
def evalPythonMacro(part, domdocument, window, scimoz, document, view, code, subject=None, topic="", data=""): lastErrorSvc = components.classes["@activestate.com/koLastErrorService;1"]\ .getService(components.interfaces.koILastErrorService) lastErrorSvc.setLastError(0, '') import komodo komodo.domdocument = domdocument # `.document` is DEPRECATED in Komodo 6.0.0b1, use `.koDoc`. komodo.koDoc = komodo.document = document komodo.editor = scimoz komodo.view = view komodo.window = window komodo.components = components komodo.macro = part komodo.openURI = macro_openURI macroGlobals = {} macroGlobals['komodo'] = komodo macroGlobals['window'] = window if topic: macroGlobals['subject'] = subject macroGlobals['topic'] = topic macroGlobals['data'] = data _partSvc = components.classes["@activestate.com/koToolbox2Service;1"]\ .getService(components.interfaces.koIToolbox2Service) _partSvc.runningMacro = part # Put the Python macro code in a "_code()" function and eval it. # # Note: This has the potential to be problematic if the Python # macro uses a syntax at the top-level that isn't allowed inside # a Python function. For example, "from foo import *" in a function # with Python 2.5 generates: # bar.py:2: SyntaxWarning: import * only allowed at module level # def _code(): # Not sure if that will be made an *error* in future Python versions. code = wrapPythonMacro(code) try: exec code in macroGlobals, macroGlobals retval = eval('_code()', macroGlobals, macroGlobals) _partSvc.runningMacro = None return retval except Exception, e: log.exception("Failed to exec the macro %s", part.name) _partSvc.runningMacro = None err = ''.join(traceback.format_exception(*sys.exc_info())) lastErrorSvc.setLastError(1, err) raise ServerException(nsError.NS_ERROR_ILLEGAL_VALUE, err)
def wait(self, timeout=None): try: retval = self._process.wait(timeout) if self.__communicating_event: # communicate() was called, need to wait until the # communicate call is finished before returning to ensure # the stdout, stderr data is ready for use. self.__communicating_event.wait() return retval except process.ProcessError, ex: raise ServerException(nsError.NS_ERROR_FAILURE, str(ex))
def get_buildNumber(self): argv = [self.get_executablePath(), "-v"] p = process.ProcessOpen(argv, stdin=None) versionDump, stderr = p.communicate() pattern = re.compile("Binary build (\d+(\.\d+)?)( \[\d+\])? provided by ActiveState") match = pattern.search(versionDump) if match: return int(match.group(1)) else: # This is likely not an ActivePerl installation. raise ServerException(nsError.NS_ERROR_UNEXPECTED)
def diff_files(self, fname1, fname2): # XXX upgrade to deal with remote files someday? import difflib try: lines1 = open(fname1, 'rb').readlines() lines2 = open(fname2, 'rb').readlines() except IOError, ex: lastErrorSvc = components.classes["@activestate.com/koLastErrorService;1"]\ .getService(components.interfaces.koILastErrorService) lastErrorSvc.setLastError(0, str(ex)) raise ServerException(nsError.NS_ERROR_UNEXPECTED, str(ex))
def close(self): if not self._file: raise URILibError("file not opened: '%s'" % self._path) try: try: self._file.close() except EnvironmentError, ex: self.lastErrorSvc.setLastError(ex.errno, ex.strerror) raise ServerException(nsError.NS_ERROR_FAILURE, ex.strerror) return 0 finally: self._file = None
def packageProject(self, packagePath, project, overwrite): try: if project.isDirty: err = 'Save project before packaging' self.lastErrorSvc.setLastError(1, err) raise ServerException(nsError.NS_ERROR_ILLEGAL_VALUE, err) project = UnwrapObject(project) self._packageParts(packagePath, orig_project=project, live=project.live, extradir=0, overwrite=overwrite) except Exception, e: log.exception(e)
def addObserver(self, observer, path, watch_type, flags): if not self.__enabled: return # Parse the path into a file object and validate the parameters. uri, nsIFile = self._getUriAndNSIFileForPath(path) if not nsIFile.exists(): raise ServerException(nsError.NS_ERROR_FAILURE, "Invalid path, was unable to locate.") if watch_type == components.interfaces.koIFileNotificationService.WATCH_FILE: if not nsIFile.isFile(): raise ServerException( nsError.NS_ERROR_FAILURE, "The path for a WATCH_FILE type, must be a file.") if not flags & self.available_file_flags: raise ServerException( nsError.NS_ERROR_FAILURE, "A WATCH_FILE type must specify flags as a combination of FS_FILE_CREATED, FS_FILE_DELETED, FS_FILE_MODIFIED." ) else: # WATCH_DIR or WATCH_DIR_RECURSIVE if not nsIFile.isDirectory(): raise ServerException( nsError.NS_ERROR_FAILURE, "The path for a WATCH_DIR type, must be a directory.") # Try using os file notifications, if that fails, then use polling try: if not self.os_notifications_available or \ not self.__os_file_service.addObserver(observer, nsIFile.path, watch_type, flags): if self.__polling_service: self.__polling_service.addObserver(observer, nsIFile.path, watch_type, flags) except OSError as message: if ("%s" % message) == "Too many open files": log.debug(message) else: raise OSError(message)
class _CommonPerlLinter(object): def __init__(self): self.sysUtils = components.classes["@activestate.com/koSysUtils;1"].\ getService(components.interfaces.koISysUtils) self._koVer = components.classes["@activestate.com/koInfoService;1"].\ getService().version supportDir = components.classes["@activestate.com/koDirs;1"].\ getService(components.interfaces.koIDirs).supportDir self._perlTrayDir = os.path.join(supportDir, "perl", "perltray").replace('\\', '/') # appInfoEx has to be created on the main thread, linters run on background threads. def isPerlCriticInstalled(self, forceCheck): appInfoEx = components.classes["@activestate.com/koAppInfoEx?app=Perl;1"].\ getService(components.interfaces.koIPerlInfoEx) return appInfoEx.isPerlCriticInstalled(False) def getPerlCriticVersion(self): appInfoEx = components.classes["@activestate.com/koAppInfoEx?app=Perl;1"].\ getService(components.interfaces.koIPerlInfoEx) return appInfoEx.getPerlCriticVersion() def _writeTempFile(self, cwd, text): tmpFileName = None if cwd: # Try to create the tempfile in the same directory as the perl # file so that @INC additions using FindBin::$Bin work as # expected. # XXX Would really prefer to build tmpFileName from the name of # the file being linted but the Linting system does not # pass the file name through. tmpFileName = os.path.join(cwd, ".~ko-%s-perllint~" % self._koVer) try: fout = open(tmpFileName, 'wb') fout.write(text) fout.close() except (OSError, IOError), ex: tmpFileName = None if not tmpFileName: # Fallback to using a tmp dir if cannot write in cwd. try: tmpFileName = tempfile.mktemp() except OSError, ex: # Sometimes get this error but don't know why: # OSError: [Errno 13] Permission denied: 'C:\\DOCUME~1\\trentm\\LOCALS~1\\Temp\\~1324-test' errmsg = "error determining temporary filename for "\ "Perl content: %s" % ex raise ServerException(nsError.NS_ERROR_UNEXPECTED, errmsg) fout = open(tmpFileName, 'wb') fout.write(text) fout.close()
def parseLine(self, line): """Parse the given line with the current regex and return: (file, line, column) Raise an exception and set an error on the last error service if there is no current regex or the line does not match. (This is used to handle double-clicks in the command output window's scintilla.) """ if not self._parseRegex: errmsg = "There was no parse regex specified for this command." self._lastErrorSvc.setLastError(0, errmsg) raise ServerException(nsError.NS_ERROR_NOT_AVAILABLE, errmsg) match = self._parseRegex.search(line) if not match: errmsg = "This line does not match the current pattern: '%s'"\ % self._parseRegex.pattern self._lastErrorSvc.setLastError(0, errmsg) raise ServerException(nsError.NS_ERROR_NOT_AVAILABLE, errmsg) datum = match.groupdict("") if "file" not in datum: if self._currentFile: datum["file"] = self._currentFile else: datum["file"] = "" elif not _isurl(datum["file"]) \ and not os.path.isabs(datum["file"]) \ and self._cwd: # If this is a relative path name then prepend the cwd. datum["file"] = os.path.join(self._cwd, datum["file"]) if "line" not in datum: datum["line"] = "" if "column" not in datum: datum["column"] = "" return datum["file"], datum["line"], datum["column"]
def read(self, nBytes): try: if nBytes >= 0xFFFFFFFF: # XXX - Hack around the fact that the read nBytes is # marked as an unsigned int in the IDL, but some # parts of the code use read(-1), which makes a # really large unsigned int, causing exceptions! # http://bugs.activestate.com/show_bug.cgi?id=72912 return self._file.read(-1) else: return self._file.read(nBytes) except EnvironmentError, ex: self.lastErrorSvc.setLastError(ex.errno, ex.strerror) raise ServerException(nsError.NS_ERROR_FAILURE, ex.strerror)
def close(self): if not self._file: raise URILibError("file not opened: '%s'" % self._path) try: try: self._file.close() except EnvironmentError, ex: lastErrorSvc = components.classes["@activestate.com/koLastErrorService;1"]\ .getService(components.interfaces.koILastErrorService) lastErrorSvc.setLastError(ex.errno, ex.strerror) raise ServerException(nsError.NS_ERROR_FAILURE, ex.strerror) return 0 finally: self._file = None
def Add(self, ext): if ext[0] != '.': raise ServerException( nsError.NS_ERROR_INVALID_ARG, "Extension must start with a dot: '%s'" % ext) if sys.platform.startswith("win"): ext = ext.lower() if ext not in self._exts: self._exts.append(ext) self._sortedBy = None self._tree.beginUpdateBatch() self._tree.rowCountChanged(len(self._exts) - 2, 1) self._tree.invalidate() self._tree.endUpdateBatch()
def _renameObject(self, id, newName, isContainer): tool = self.getToolById(id) parentTool = tool.get_parent() if parentTool is None: raise ServerException(nsError.NS_ERROR_ILLEGAL_VALUE, "Can't rename a top-level folder") oldPath = tool.path if isContainer: newPathOnDisk = self._prepareUniqueFileSystemName(tool, parentTool.path, newName, ext="") else: newPathOnDisk = self._prepareUniqueFileSystemName( tool, parentTool.path, newName) os.rename(oldPath, newPathOnDisk) # Update the name field in the json tool try: fp = open(newPathOnDisk, 'r') data = koToolbox2.DataParser.readData(fp) fp.close() if data['name'] != newName: # If these are the same, we're doing a null rename, but # treat that as an anomaly. pass data['name'] = newName fp = open(newPathOnDisk, 'r+') koToolbox2.DataParser.writeData(fp, data) fp.close() except: log.exception("Failed to update json on old path:%s, newName:%s", newPathOnDisk, newName) # There shouldn't be an exception in the database. self.toolbox_db.renameTool(id, newName, newPathOnDisk) try: # Remove this item from the cache, since its name changed. del self._tools[id] except KeyError: pass if isContainer: # Update the paths of all child nodes. ids = self.toolbox_db.updateChildPaths(id, oldPath, newPathOnDisk) for id in ids: try: # Remove this item from the cache, since its name changed. del self._tools[id] except KeyError: pass return newPathOnDisk
def initByDiffingDocuments(self, doc1, doc2): """Get a unified diff of the given koIDocument's.""" self._reset() self.doc1 = doc1 self.doc2 = doc2 native_eol = eollib.eol2eolStr[eollib.EOL_PLATFORM] try: # difflib takes forever to work if newlines do not match content1_eol_clean = re.sub("\r\n|\r|\n", native_eol, doc1.buffer) content2_eol_clean = re.sub("\r\n|\r|\n", native_eol, doc2.buffer) except IOError, ex: self.lastErrorSvc.setLastError(0, str(ex)) raise ServerException(nsError.NS_ERROR_UNEXPECTED, str(ex))
def getVersionForBinary(self, phpExe): if not os.path.exists(phpExe): raise ServerException(nsError.NS_ERROR_FILE_NOT_FOUND) out, err = self._GetPHPOutputAndError( "<?php echo(phpversion().\"\\n\"); ?>", php=phpExe) if not out: # (Bug 73485) With some esp. borked PHP setups, even # getting the version dies. Logging this case is the least # we can do. A better (but more onerous to verify as being # safe) change would be to pass up the error and show it # in the using UI (e.g. the PHP prefs panel). log.error("could not determine PHP version number for " "'%s':\n----\n%s\n----", self.get_executablePath(), err) return self._parsedOutput(out)
def _checkFileAssociation(self, ext, action): """Check that the given file association matches that in the system. Returns None if so, a text error message otherwise. """ import wininteg try: result = wininteg.checkFileAssociation(ext, action, self._komodo) if result is not None and action.endswith(self._appName): untypedAction = action[:-len(self._appName)] + "Komodo" return wininteg.checkFileAssociation(ext, untypedAction, self._komodo) return result except WindowsError, ex: self.lastErrorSvc.setLastError(ex.errno, ex.strerror) raise ServerException(nsError.NS_ERROR_UNEXPECTED, ex.strerror)
def getFile(self, prop): path = None persistent = True raise ServerException(nsError.NS_ERROR_FAILURE) # http://plow.activestate.com/source/xref/mozilla/1.8/xpcom/io/nsIDirectoryService.idl # API is: # int8 getFile(in string prop, # out boolean persistent, # out retval nsISomething file) # This translates (I believe, via experimentation) to: # (<file>, <persistent>) nsifile = components.classes["@mozilla.org/file/local;1"] \ .createInstance(components.interfaces.nsILocalFile) nsifile.initWithPath(path) return nsifile, persistent
def _getLinterByCID(self, linterCID): if linterCID not in self._linterCache: try: if linterCID.startswith(self.GENERIC_LINTER_AGGREGATOR_CID): languageName = linterCID[len(self.GENERIC_LINTER_AGGREGATOR_CID) + 1:] linter = components.classes[self.GENERIC_LINTER_AGGREGATOR_CID].createInstance(components.interfaces.koILinter) UnwrapObject(linter).initialize(languageName, self) elif linterCID not in components.classes.keys(): linter = None else: linter = components.classes[linterCID].createInstance(components.interfaces.koILinter) except COMException, ex: errmsg = "Internal Error creating a linter with CID '%s': %s"\ % (linterCID, ex) raise ServerException(nsError.NS_ERROR_UNEXPECTED, errmsg) self._linterCache[linterCID] = linter
def setWriteability(self, path, writeable): if not os.path.exists(path): lastErrorSvc.setLastError(0, "File does not exist") raise ServerException(nsError.NS_ERROR_INVALID_ARG, "File does not exist") try: mode = self.getmod(path) if writeable: desired_mode = mode | stat.S_IWUSR else: desired_mode = mode & ~stat.S_IWUSR os.chmod(path, desired_mode) obtained_mode = self.getmod(path) except EnvironmentError, ex: lastErrorSvc.setLastError(ex.errno, ex.strerror) raise
def _getJSON(cmd, args=None): argv = [stackatoPath, cmd] if args: argv += args argv.append("--json") p = process.ProcessOpen(argv, cwd=None, env=None, stdin=None) stdout, stderr = p.communicate() if stderr: if not stdout: if "Login Required" in stderr and "Please use 'stackato login'" in stderr: log.error(stderr) return None raise ServerException(nsError.NS_ERROR_FAILURE, "stackato %s failed: %s" % (cmd, stderr)) else: log.error("stackato %s error message: %s" % (cmd, stderr)) return json.loads(stdout)
def _getFileFromURI(self, uri, doNotification=True): # first cleanup the uri by passing it through the parser try: self._uriParser.URI = uri uri = self._uriParser.URI kofile = self.findFileByURI(uri) if kofile: return kofile kofile = \ components.classes["@activestate.com/koFileEx;1"] \ .createInstance(components.interfaces.koIFileEx) kofile.URI = uri except Exception, e: log.error("Invalid URL parsed: %r", uri) raise ServerException(nsError.NS_ERROR_FAILURE, str(e))
def changeDir(self, newDir): log.debug("KoFindAvailableDirsView.changeDir(newDir=%r)", newDir) if os.path.isabs(newDir): self.currentDir = newDir elif self.currentDir is None: log.error("Cannot change to a relative dir before the " "current dir has been set.") raise ServerException(nsError.NS_ERROR_NOT_INITIALIZED) else: self.currentDir = os.path.join(self.currentDir, newDir) self.currentDir = os.path.normpath(self.currentDir) preLength = len(self._dirs) try: basenames = os.listdir(self.currentDir) except EnvironmentError, ex: log.debug("'%s' does not exist, emptying available dirs view") self._dirs = []
def getConnectionUsingServerAlias(self, server_alias): server_prefs = self._getServerPrefSettings(server_alias) if server_prefs: protocol = server_prefs[0] #aliasname = server_prefs[1] hostname = server_prefs[2] port = server_prefs[3] username = server_prefs[4] password = server_prefs[5] path = server_prefs[6] passive = server_prefs[7] connection = self._getConnection(protocol, hostname, port, username, password, path, passive) if connection: # Remember the alias used to get the connection. connection.alias = server_alias return connection raise ServerException(nsError.NS_ERROR_FAILURE, "No server found for alias: %r" % (server_alias))
def _getUriAndNSIFileForPath(self, path): try: log.debug("addObserver: path: %s", path) nsIFile = components.classes["@mozilla.org/file/local;1"].\ createInstance(components.interfaces.nsILocalFile); nsIFile.initWithPath(path) # Convert the local path to a uri uri = self.__io_service.getURLSpecFromFile(nsIFile) except COMException, e: # Try uri then log.debug("Could not initialise file with path, trying as URI") try: uri = path nsIFile = self.__io_service.getFileFromURLSpec(uri) log.debug("URI initialised okay.") except COMException, e: log.debug("Could not initialise file with URI") raise ServerException(nsError.NS_ERROR_FAILURE, "Invalid path format")
def getConnection(self, protocol, server, port, username, password, path, passive=True): # XXX - Requires ActivePython to support ssl # http://bugs.activestate.com/show_bug.cgi?id=50207 if protocol == "ftps" and not hasattr(socket, 'ssl'): self._lasterror = "SSL is not supported in Komodo's internal python" lastErrorSvc = components.classes["@activestate.com/koLastErrorService;1"]\ .getService(components.interfaces.koILastErrorService) lastErrorSvc.setLastError(0, self._lasterror) raise ServerException(nsError.NS_ERROR_FAILURE, self._lasterror) return self._getConnection(protocol, server, port, username, password, path, passive)
class KoWindowsIntegrationService: _com_interfaces_ = [components.interfaces.koIWindowsIntegrationService] _reg_clsid_ = "{61DD412D-719B-4240-9362-07C2F5C2D68C}" _reg_contractid_ = "@activestate.com/koWindowsIntegrationService;1" _reg_desc_ = "Service for integrating Komodo into the Windows OS" def __init__(self): self.lastErrorSvc = components.classes["@activestate.com/koLastErrorService;1"]\ .getService(components.interfaces.koILastErrorService) koDirs = components.classes["@activestate.com/koDirs;1"]\ .getService(components.interfaces.koIDirs) self._komodo = os.path.join(koDirs.binDir, "komodo.exe") appinfo = components.classes["@mozilla.org/xre/app-info;1"]\ .getService(components.interfaces.nsIXULAppInfo) self._appName = appinfo.name self._appKeyPath = r"Software\%s\%s" % (appinfo.vendor, appinfo.name) def _addFileAssociation(self, ext, action): import wininteg try: if action.endswith(self._appName): untypedAction = action[:-len(self._appName)] + "Komodo" try: if wininteg.removeFileAssociation(ext, untypedAction, self._komodo, fromHKLM=True): log.info("Removed untyped action %r", untypedAction) except WindowsError, ex: if ex.winerror != 5: # ERROR_ACCESS_DENIED raise # can't remove the untyped action, don't add # the new one either (to prevent duplicates) log.info( "Failed to remove untyped action %r, not adding typed action %r", untypedAction, action) return wininteg.addFileAssociation(ext, action, self._komodo) except WindowsError, ex: self.lastErrorSvc.setLastError(ex.errno, ex.strerror) raise ServerException(nsError.NS_ERROR_UNEXPECTED, ex.strerror)
def __init__(self, instance, iid): self._obj_ = instance self._nominated_interfaces_ = ni = _GetNominatedInterfaces(instance) self._iid_ = iid if ni is None: raise ValueError, "The object '%r' can not be used as a COM object" % ( instance, ) # This is really only a check for the user if __debug__: if iid != IID_nsISupports and iid not in ni: # The object may delegate QI. delegate_qi = getattr(instance, "_query_interface_", None) # Perform the actual QI and throw away the result - the _real_ # QI performed by the framework will set things right! if delegate_qi is None or not delegate_qi(iid): raise ServerException(nsError.NS_ERROR_NO_INTERFACE) # Stuff for the magic interface conversion. self._interface_info_ = None self._interface_iid_map_ = { } # Cache - Indexed by (method_index, param_index)
def _isValidExecutable(self, exe): """Return if the supplied exe is valid for Komodo usage.""" # Class may optionally set a minVersionSupported and maxVersionTuple that # will be used to perform this check. if not hasattr(self, "minVersionSupported"): raise ServerException(nsError.NS_ERROR_NOT_IMPLEMENTED) if not exe: return False #print ' exe: %r' % (exe, ) isvalid = self._executable_is_valid_cache.get(exe) if isvalid is None: try: isvalid = self._isValidExecutableVersion(exe) except Exception as ex: # Something went wrong; report that the executable is unusable log.exception("Failed to check version of executable %s" % (exe,)) isvalid = False self._executable_is_valid_cache[exe] = isvalid #print ' isvalid: %r' % (isvalid, ) return isvalid
def getFiles(self, prop): paths = [] if prop == "PyxpcomExtDirList": # Pyxpcom standalone extension dirs paths = self.__getExtensionDirs() elif prop == "ComsDL": # extension/component dirs list extension_paths = self.__getExtensionDirs() for ext_dir in extension_paths: p = join(ext_dir, "components") if isdir(p): paths.append(p) else: raise ServerException(nsError.NS_ERROR_FAILURE) nsifiles = [] for path in paths: nsifile = components.classes["@mozilla.org/file/local;1"] \ .createInstance(components.interfaces.nsILocalFile) nsifile.initWithPath(path) nsifiles.append(nsifile) return SimpleEnumerator(nsifiles)