def run(cls, target): if not os.path.exists(target): sys.stderr.write("Unable to find file %s" % target) sys.exit(1) dirName, fileName = os.path.split(target) dirName = os.path.abspath(os.path.normpath(dirName)) db = SnowFileDB(dirName) fileInfo = db.getFileInfo(fileName) if not fileInfo: sys.stderr.write("File %s not found in %s" % (target, os.path.join(dirName, Config.getDBFilename()))) sys.exit(1) client = SnowClient(fileInfo.getTableName(), fileInfo.getInstance()) record = client.get(fileInfo.getSysId()) recordName = record.sys_id content = normalizeNewlines(getattr(record, fileInfo.getContentFieldName())) if os.path.isfile(os.path.join(dirName, Config.getLockFilename())): #swatch is watching, we do not want him to re-upload, we write a file for swatch.py to know ignoreWatchFilePath = target + Config.getIgnoreWatchFilenameSuffix() SLogger.debug("Creating file %s to avoid swatch to re-upload" % ignoreWatchFilePath) ignoreWatchFile = open(ignoreWatchFilePath, "w") ignoreWatchFile.close() f = codecs.open(target, "w", "utf-8") f.write(content) db.setUpdatedOn(fileName, record.sys_updated_on) db.commitAndClose() SLogger.debug("Updated record %s to file %s. set updated_on to %s" % (recordName, fileName, record.sys_updated_on))
def directoryShouldBeIgnored(dirPath): dirPath = os.path.normpath(os.path.abspath(dirPath)) if dirPath in Config.getIgnoreDirs(): return True else: for dirName in Config.getIgnoreDirs(): if dirPath.find(dirName) != -1: return True return False
def processFile(self, filePath): ignoreWatchFilePath = filePath + Config.getIgnoreWatchFilenameSuffix() if os.path.isfile(ignoreWatchFilePath): #this file was updated by supdate.py, do not process os.remove(ignoreWatchFilePath) return #Loic Horisberger - 17.10.2014: #This is a fix for MacVIM where current files are swap files. #If the file ends with ".swp", remove the extention to get the #original filename. Remove the "." at the beginning that makes #the file hidden as well. if filePath.endswith(".swp"): filePath = filePath.replace(".swp","") filePath = filePath[::-1].replace("/."[::-1],"/"[::-1],1)[::-1] self.__dbWorker.getFileInfo(self, filePath) fileInfo = self.__inputQueue.get() if fileInfo: SLogger.debug("Local modification detected for: %s" % filePath) client = clientPool.getClient(fileInfo.getTableName(), fileInfo.getInstance()) localUpdateDateString = fileInfo.getUpdatedOn() canUpdate = True if localUpdateDateString: SLogger.debug("Checking remote version...") remoteRecord = client.get(fileInfo.getSysId()) remoteUpdatedOnString = remoteRecord.sys_updated_on canUpdate = checkCanUpdate(localUpdateDateString, remoteUpdatedOnString) if canUpdate: SLogger.debug("Done") else: SLogger.warning("Remote file changed by %s on %s. Previous local version is %s. Cannot update" % (remoteRecord.sys_updated_by, snowServerToLocalDate(remoteUpdatedOnString), localUpdateDateString)) Commands.cannotUpload(remoteRecord.sys_updated_by, remoteUpdatedOnString, localUpdateDateString) if canUpdate: SLogger.debug("Updating in SNOW...") content = codecs.open(filePath, "r", "utf-8").read() success = client.updateContent(fileInfo.getSysId(), fileInfo.getContentFieldName(), content) if success: SLogger.debug("Updating local update date...") newRemoteRecord = client.get(fileInfo.getSysId()) newRemoteUpdatedOnString = newRemoteRecord.sys_updated_on self.__dbWorker.setUpdatedOn(self, filePath, newRemoteUpdatedOnString) confirmation = self.__inputQueue.get() if confirmation: SLogger.debug("Success updating %s" % fileInfo.getFileName()) Commands.success(fileInfo) else: SLogger.warning("Update of local date failed for file %s" % fileInfo) Commands.warning("Upload failed", "Update of local date failed for file %s" % fileInfo) else: SLogger.warning("Update of local date failed for file %s" % fileInfo) Commands.warning("Upload failed", "Update of local date failed for file %s" % fileInfo)
def cannotUpload(cls, updatedBy, remoteUpdatedOnString, localUpdateDateString): cannotUploadCommandTemplate = Config.getCannotUploadCommand() if cannotUploadCommandTemplate: command = cannotUploadCommandTemplate % {"person": updatedBy, "remoteDate" : snowServerToLocalDate(remoteUpdatedOnString), "localDate": localUpdateDateString} subprocess.call(shlex.split(str(command)))
def __setCommandLineOptions(self): commandLineOptions = [ "instance", "username", "password", "nameField", "contentField", "deleteLockFiles", "recursive", ] commandLineOptionValues = {} for commandLineOptionName in commandLineOptions: if hasattr(self.__options, commandLineOptionName): optionValue = getattr(self.__options, commandLineOptionName) if optionValue: commandLineOptionValues[commandLineOptionName] = optionValue Config.setOptions(commandLineOptionValues)
def __setLoggerLevel(self): if self.__options.verbose: SLogger.setLevel(logging.DEBUG) else: level = Config.getLoggerLevel() if level == "warning": SLogger.setLevel(logging.WARNING) elif level == "debug": SLogger.setLevel(logging.DEBUG)
def _getTableInfo(cls, tableName): try: nameField = Config.getNameField() if not nameField: nameField = TableInfo.getNameField(tableName) contentField = Config.getContentField() if not contentField: contentField = TableInfo.getContentField(tableName) except KeyError: sys.stderr.write( "No name_field or content_field parameter and no default information about table %s, aborting\n" % tableName ) sys.exit(1) try: fileExtension = TableInfo.getFileExtension(tableName) except KeyError: fileExtension = ".txt" return (nameField, contentField, fileExtension)
def __scheduleDir(cls, dirPath, rootDirPath): if not directoryShouldBeIgnored(dirPath): SLogger.debug("Watching dir %s" % os.path.abspath(dirPath)) lockFilePath = os.path.abspath(os.path.join(dirPath, Config.getLockFilename())) if os.path.exists(lockFilePath): SLogger.warning("%s already exists. Another swatch might be watching this directory or might not have shut down correctly. Consider using the scleanlockfiles command." % (lockFilePath)) if dirPath == rootDirPath: Commands.warning("Directory already watched", "Another swatch might be watching or might not have shut down correctly.") else: lockFile = open(lockFilePath, "w") lockFile.close() cls.__lockFiles.append(lockFilePath) cls.__observer.schedule(cls.__handler, path=dirPath)
def process(self): self.__options, self.__args = self.parse_args() self.__verifyNArgs() Config.loadOptionsFromFile(self.__options.configFilePath) self.__setCommandLineOptions() Config.setDefaultsIfOptionNotPresent() self.__setLoggerLevel() if Config.getConfigFilePath(): SLogger.debug("Loaded config file from %s" % Config.getConfigFilePath()) self.__launchCommand()
def run(cls, targetDir): cls.__dbWorker = DBWorker() cls.__dbWorker.start() cls.__handler = EventHandler(cls.__dbWorker) cls.__lockFiles = [] cls.__observer = Observer() if Config.isRecursive(): for root, _, _ in os.walk(targetDir): cls.__scheduleDir(root, targetDir) else: cls.__scheduleDir(targetDir, targetDir) cls.__observer.start() try: while True: time.sleep(1) except KeyboardInterrupt: SLogger.debug("Stopping...") finally: cls.__shutdown()
def run(cls, targetDir): if Config.isRecursive(): for root, _, _ in os.walk(targetDir): cls.__cleanDir(root) else: cls.__cleanDir(targetDir)
def __init__(self, path): self.__dbFilePath = os.path.join(path, Config.getDBFilename()) SLogger.debug("Opening DB File: %s" % self.__dbFilePath) self.__conn = sqlite3.connect(self.__dbFilePath) self.__cursor = self.__conn.cursor()
def run(cls, src, dst): src = os.path.abspath(os.path.normpath(src)) dst = os.path.abspath(os.path.normcase(dst)) if src == dst: return if not os.path.exists(src): sys.stderr.write("File %s does not exist\n" % src) sys.exit(1) if os.path.exists(dst): sys.stderr.write("File %s already exists\n" % dst) sys.exit(1) sourceDir, sourceFilename = os.path.split(src) if not SnowFileDB.existsAtDir(sourceDir): sys.stderr.write("DB file not found at %s, aborting\n" % os.path.join(sourceDir, Config.getDBFilename())) sys.exit(1) destDir, destFilename = os.path.split(dst) if sourceDir != destDir: sourceDB = SnowFileDB(sourceDir) destDB = SnowFileDB(destDir) fileInfo = sourceDB.getFileInfo(sourceFilename) if not fileInfo: sys.stderr.write("File %s not present at DB file %s\n" % (sourceFilename, sourceDB.getDBFilePath())) sys.exit(1) sourceDB.deleteFile(sourceFilename) fileInfo.setFileName(destFilename) destDB.addFileInfo(fileInfo) shutil.move(src, dst) sourceDB.commitAndClose() destDB.commitAndClose() else: db = SnowFileDB(sourceDir) sucesss = db.renameFile(sourceFilename, destFilename) if not sucesss: sys.stderr.write("File %s not present at DB file %s\n" % (sourceFilename, db.getDBFilePath())) sys.exit(1) shutil.move(src, dst) db.commitAndClose() SLogger.debug("File successfully moved from %s to %s\n" % (src, dst))
def existsAtDir(cls, path): return os.path.exists(os.path.join(path, Config.getDBFilename()))
def fileShouldBeIgnored(filePath): fileDir, fileName = os.path.split(os.path.normpath(os.path.abspath(filePath))) if fileName in Config.getIgnoreFiles().union(set([Config.getDBFilename(), Config.getLockFilename()])): return True else: return directoryShouldBeIgnored(fileDir)
def snowServerToLocalDate(dateString): if dateString: dt = datetime.datetime.strptime(dateString, Config.getServerDateFormat()) return dt.strftime(Config.getLocalDateFormat()) else: return dateString
def checkCanUpdate(localDateString, remoteDateString): localDate = datetime.datetime.strptime(localDateString, Config.getLocalDateFormat()) remoteDate = datetime.datetime.strptime(remoteDateString, Config.getServerDateFormat()) return remoteDate <= localDate
def __cleanDir(cls, dirPath): lockFilePath = os.path.abspath(os.path.join(dirPath, Config.getLockFilename())) if os.path.exists(lockFilePath): SLogger.debug("Deleting %s" % os.path.abspath(lockFilePath)) os.remove(lockFilePath)
def warning(cls, title, msg): warningCommandTemplate = Config.getWarningCommand() if warningCommandTemplate: command = warningCommandTemplate % {"msg": msg, "title": title} subprocess.call(shlex.split(str(command)))
def success(cls, fileInfo): successCommandTemplate = Config.getSuccessCommand() if successCommandTemplate: command = successCommandTemplate % {"filename": fileInfo.getFileName().replace("[", "\[")} subprocess.call(shlex.split(str(command)))