def compress(srcPath, tgtPath): # #Note: shutil.make_archive isn't used, due to its forcing of the zip extension and due to the need for maintaing a compression standard. if not exists(srcPath): raise('No such path: %s' % srcPath) ensureParent(tgtPath) from zipfile import ZipFile, ZIP_DEFLATED ZipFileObj = ZipFile(tgtPath, 'w', ZIP_DEFLATED) cwd = os.getcwd() # The CWD circus is to reduce the relpath calls. if isContainer(srcPath): os.chdir(srcPath) for root, dummy1, Files in os.walk('.', followlinks=True): for file in Files: ZipFileObj.write(pathJoin(root, file)) else: dir, name = pathSplit(srcPath) os.chdir(dir) ZipFileObj.write(name) os.chdir(cwd) ZipFileObj.close()
def mkdirs(SFTP, remotePath): currentPath = remotePath Skipped = [] while True: err = forgive(lambda: SFTP.mkdir(currentPath, 511)) # #Note: Existense isn't checked for to reduce the number of remote calls. if err: if err.errno is None: # The dir exists. return elif not isinstance(err, IOError): # #Pending: Check: Permission errors could result in infinite loops. raise err else: # Try to create the parent path. currentPath, skipped = pathSplit(currentPath) Skipped.append(skipped) if not currentPath or currentPath == '/': raise Exception('Failed to create the dir: %s' % remotePath) else: if not Skipped: break else: currentPath += '/%s' % Skipped.pop(0)
def LoadFolder(arg): global fdrOpen, FilesIndex fdrOpen = fd.askdirectory() WindowTitle(pathSplit(fdrOpen)[1]) CategoriesShow() pathLVL1(0) FilesIndex = 0 TextInsertion(pathOrigin, pathLocal, 0) TextInsertion(pathOrigin, pathLocal, 0) FilesShow(pathOrigin)
def LocalStep(localPath, Index, step, next_step_set): try: sortedListdir = sorted(listdir(localPath))[Index] if sortedListdir != 'titles.md': fl = oPen(localPath + sortedListdir, "r", encoding='UTF-8') for line in fl.readlines(): step.wait() step.clear() swFilter = regexSub(regexSwearPattern, SwearFilter, line.rstrip()).split(" ", maxsplit=1) try: if swFilter[1] != ostepSWfilter: # TableLocal = '[code][b] ▫ ' + swFilter[1] + '[/b][/code][/code]\n' # TableLocal = '[code][b] ▫ ' + swFilter[1] + '[/b][/code][/th][/tr][/table]\n' # TableLocal = '[tr][th][b] ▫ ' + swFilter[1] + '[/b][/th][/tr][/table][/code]\n' TableLocal = '[hr][/hr][h3] ▫ [b]' + swFilter[ 1] + '[/b][/h3][/code]' else: # TableLocal = '[/code]\n' # TableLocal = '[/th][/tr][/table]\n' # TableLocal = '[/table][/code]\n' TableLocal = '[/code]' tempf.write(str(TableLocal)) except: tempf.write('\nerror at: ' + localPath + sortedListdir + ' -|- ' + line.rstrip() + '\n') next_step_set.set() fl.close() else: print('BREAK! Found titles file at ' + pathSplit(localPath)[1]) # break except FileNotFoundError: quit(1)
def start(): global inputFile, outputFile, password, ad, kept global working, gMode, headerRsc, draggedFiles global dragFolderPath dummy.focus() reedsolo = False chunkSize = 2**20 # Decide if encrypting or decrypting if ".pcv" not in inputFile: mode = "encrypt" gMode = "encrypt" outputFile = inputFile + ".pcv" reedsolo = rs.get() == 1 else: mode = "decrypt" gMode = "decrypt" # Check if Reed-Solomon was enabled by checking for "+" test = open(inputFile, "rb") decider = test.read(1).decode("utf-8") test.close() if decider == "+": reedsolo = True # Decrypted output is just input file without the extension outputFile = inputFile[:-4] # Check if file already exists (getsize() throws error if file not found) try: getsize(outputFile) force = messagebox.askyesno("Warning", overwriteNotice) dummy.focus() if force != 1: return except: pass # Disable inputs and buttons while encrypting/decrypting disableAllInputs() # Make sure passwords match if passwordInput.get() != cpasswordInput.get() and mode == "encrypt": resetEncryptionUI() statusString.set("Passwords don't match.") return # Set progress bar indeterminate progress.config(mode="indeterminate") progress.start(15) statusString.set(rscNotice) # Create Reed-Solomon object if reedsolo: # 13 bytes per 128 bytes, ~10% larger output file rsc = RSCodec(13) # Compress files together if user dragged multiple files if draggedFiles: statusString.set(compressingNotice) tmp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") if dragFolderPath: zfName = Path(dragFolderPath).parent.absolute() zfName = pathJoin(zfName, tmp + ".zip") else: zfName = Path(draggedFiles[0]).parent.absolute() zfName = pathJoin(zfName, tmp + ".zip") zf = ZipFile(zfName, "w") for i in draggedFiles: if dragFolderPath: nameOffset = len(dragFolderPath) zf.write(i, i[nameOffset:]) else: zf.write(i, pathSplit(i)[1]) zf.close() inputFile = zfName outputFile = zfName + ".pcv" outputPath = dirname(outputFile) # Set and get some variables working = True headerBroken = False reedsoloFixedCount = 0 reedsoloErrorCount = 0 dummy.focus() password = passwordInput.get().encode("utf-8") ad = adArea.get("1.0", tkinter.END).encode("utf-8") wipe = erase.get() == 1 # Open files fin = open(inputFile, "rb") if reedsolo and mode == "decrypt": # Move pointer one forward fin.read(1) fout = open(outputFile, "wb+") if reedsolo and mode == "encrypt": # Signal that Reed-Solomon was enabled with a "+" fout.write(b"+") # Generate values for encryption if encrypting if mode == "encrypt": salt = urandom(16) nonce = urandom(24) # Reed-Solomon-encode metadata ad = bytes(headerRsc.encode(ad)) # Write the metadata to output tmp = str(len(ad)).encode("utf-8") # Right-pad with "+" while len(tmp) != 10: tmp += b"+" tmp = bytes(headerRsc.encode(tmp)) fout.write(tmp) # Length of metadata fout.write(ad) # Metadata (associated data) # Write zeros as placeholders, come back to write over it later. # Note that 128 extra Reed-Solomon bytes are added fout.write(b"0" * 192) # SHA3-512 of encryption key fout.write(b"0" * 192) # CRC of file fout.write(b"0" * 144) # Poly1305 tag # Reed-Solomon-encode salt and nonce fout.write(bytes(headerRsc.encode(salt))) # Argon2 salt fout.write(bytes(headerRsc.encode(nonce))) # ChaCha20 nonce # If decrypting, read values from file else: # Move past metadata into actual data tmp = fin.read(138) if tmp[0] == 43: tmp = tmp[1:] + fin.read(1) tmp = bytes(headerRsc.decode(tmp)[0]) tmp = tmp.replace(b"+", b"") adlen = int(tmp.decode("utf-8")) fin.read(int(adlen)) # Read the salt, nonce, etc. cs = fin.read(192) crccs = fin.read(192) digest = fin.read(144) salt = fin.read(144) nonce = fin.read(152) # Reed-Solomon-decode each value try: cs = bytes(headerRsc.decode(cs)[0]) except: headerBroken = True cs = cs[:64] try: crccs = bytes(headerRsc.decode(crccs)[0]) except: headerBroken = True crccs = crccs[:64] try: digest = bytes(headerRsc.decode(digest)[0]) except: headerBroken = True digest = digest[:16] try: salt = bytes(headerRsc.decode(salt)[0]) except: headerBroken = True salt = salt[:16] try: nonce = bytes(headerRsc.decode(nonce)[0]) except: headerBroken = True nonce = nonce[:24] if headerBroken: if keep.get() != 1: statusString.set(veryCorruptedNotice) fin.close() fout.close() remove(outputFile) # Reset UI resetDecryptionUI() return else: kept = "badlyCorrupted" # Show notice about key derivation statusString.set(derivingNotice) # Derive argon2id key key = hash_secret_raw( password, salt, time_cost=8, # 8 iterations memory_cost=2**20, # 2^20 Kibibytes (1GiB) parallelism=8, # 8 parallel threads hash_len=32, type=Type.ID) # Key deriving done, set progress bar determinate progress.stop() progress.config(mode="determinate") progress["value"] = 0 # Compute hash of derived key check = sha3_512.new() check.update(key) check = check.digest() # If decrypting, check if key is correct if mode == "decrypt": # If key is incorrect... if not compare_digest(check, cs): if not headerBroken: statusString.set(passwordNotice) fin.close() fout.close() remove(outputFile) # Reset UI resetDecryptionUI() return # Create XChaCha20-Poly1305 object cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce) # Cyclic redundancy check for file corruption crc = sha3_512.new() # Amount of data encrypted/decrypted, total file size, starting time done = 0 total = getsize(inputFile) # If secure wipe enabled, create a wiper object # Keep track of time because it flies... startTime = datetime.now() previousTime = datetime.now() # Continously read file in chunks of 1MB while True: if mode == "decrypt" and reedsolo: # Read a chunk plus Reed-Solomon recovery bytes piece = fin.read(1104905) else: piece = fin.read(chunkSize) # If EOF if not piece: if mode == "encrypt": # Get the cipher MAC tag (Poly1305) digest = cipher.digest() fout.flush() fout.close() fout = open(outputFile, "r+b") # Compute the offset and seek to it (unshift "+") rsOffset = 1 if reedsolo else 0 fout.seek(138 + len(ad) + rsOffset) # Write hash of key, CRC, and Poly1305 MAC tag fout.write(bytes(headerRsc.encode(check))) fout.write(bytes(headerRsc.encode(crc.digest()))) fout.write(bytes(headerRsc.encode(digest))) else: # If decrypting, verify CRC crcdg = crc.digest() if not compare_digest(crccs, crcdg): # File is corrupted statusString.set(corruptedNotice) progress["value"] = 100 fin.close() fout.close() # If keep file not checked... if keep.get() != 1: remove(outputFile) # Reset UI resetDecryptionUI() del fin, fout, cipher, key return else: if not kept: kept = "corrupted" # Next, verify MAC tag (Poly1305) try: # Throws ValueError if incorrect Poly1305 cipher.verify(digest) except: if not reedsoloErrorCount and not headerBroken: # File is modified statusString.set(modifiedNotice) progress["value"] = 100 fin.close() fout.close() # If keep file not checked... if keep.get() != 1: remove(outputFile) # Reset UI resetDecryptionUI() del fin, fout, cipher, key return else: if not kept: kept = "modified" break # Encrypt/decrypt chunk and update CRC if mode == "encrypt": # Encrypt piece data = cipher.encrypt(piece) # Update checksum crc.update(data) if reedsolo: # Encode using Reed-Solomon if user chooses data = bytes(rsc.encode(data)) else: # Basically encrypting but in reverse if reedsolo: try: data, _, fixed = rsc.decode(piece) except ReedSolomonError: # File is really corrupted if not reedsoloErrorCount: if keep.get() != 1: statusString.set(veryCorruptedNotice) progress["value"] = 100 # If keep file not checked... if keep.get() != 1: fin.close() fout.close() remove(outputFile) # Reset UI resetDecryptionUI() del fin, fout, cipher, key return else: kept = "badlyCorrupted" # Attempt to recover badly corrupted data data = b"" piece = piece[:-13] counter = 0 while True: # Basically just strip the Reed-Solomon bytes # and return the original non-encoded data if counter < 1104905: data += piece[counter:counter + 242] counter += 255 # 255 bytes, 242 original else: break fixed = bytearray() reedsoloErrorCount += 1 data = bytes(data) reedsoloFixedCount += len(fixed) crc.update(data) data = cipher.decrypt(data) else: crc.update(piece) data = cipher.decrypt(piece) # Calculate speed, ETA, etc. first = False elapsed = (datetime.now() - previousTime).total_seconds() or 0.0001 sinceStart = (datetime.now() - startTime).total_seconds() or 0.0001 previousTime = datetime.now() # Prevent divison by zero if not elapsed: elapsed = 0.1**6 percent = done * 100 / total progress["value"] = percent rPercent = round(percent) speed = (done / sinceStart) / 10**6 # Prevent divison by zero if not speed: first = True speed = 0.1**6 rSpeed = str(round(speed, 2)) # Right-pad with zeros to large prevent layout shifts while len(rSpeed.split(".")[1]) != 2: rSpeed += "0" eta = round((total - done) / (speed * 10**6)) # Seconds to minutes if seconds more than 59 if eta >= 60: eta = f"{eta//60}m {eta%60}" if isinstance(eta, int) or isinstance(eta, float): if eta < 0: eta = 0 # If it's the first round and no data/predictions yet... if first: statusString.set("...% at ... MB/s (ETA: ...s)") else: # Update status info = f"{rPercent}% at {rSpeed} MB/s (ETA: {eta}s)" if reedsolo and mode == "decrypt" and reedsoloFixedCount: eng = "s" if reedsoloFixedCount != 1 else "" info += f", fixed {reedsoloFixedCount} corrupted byte{eng}" if reedsolo and mode == "decrypt" and reedsoloErrorCount: info += f", {reedsoloErrorCount} MB unrecoverable" statusString.set(info) # Increase done and write to output done += 1104905 if (reedsolo and mode == "decrypt") else chunkSize fout.write(data) # Flush outputs, close files if not kept: fout.flush() fsync(fout.fileno()) fout.close() fin.close() # Securely wipe files as necessary if wipe: progress.config(mode="indeterminate") progress.start(15) if draggedFiles: for i in draggedFiles: print("===============" + i) secureWipe(i) secureWipe(inputFile) else: if draggedFiles: remove(inputFile) # Show appropriate notice if file corrupted or modified if not kept: if mode == "encrypt": output = inputFile.split("/")[-1] + ".pcv" else: output = inputFile.split("/")[-1].replace(".pcv", "") statusString.set(f"Completed. (Output: {output})") # Show Reed-Solomon stats if it fixed corrupted bytes if mode == "decrypt" and reedsolo and reedsoloFixedCount: statusString.set( f"Completed with {reedsoloFixedCount} bytes fixed." + f" (Output: {output})") else: if kept == "modified": statusString.set(kModifiedNotice) elif kept == "corrupted": statusString.set(kCorruptedNotice) else: statusString.set(kVeryCorruptedNotice) status.config(cursor="hand2") status.bind("<Button-1>", lambda e: print(outputPath)) # Reset variables and UI states resetUI() inputFile = "" outputFile = "" password = "" ad = "" kept = False working = False draggedFiles = False dragFolderPath = False # Wipe keys for safety del fin, fout, cipher, key
def work(): global inputFile, outputFile, working, mode, rs13, rs128, reedsolo global done, stopUpdating, startTime, previousTime, onlyFiles global onlyFolders, allFiles, reedsoloFixed, reedsoloErrors disableAllInputs() dummy.focus() # Set and get some variables kept = False shouldKeep = keep.get() == 1 shouldErase = erase.get() == 1 reedsolo = rs.get() == 1 working = True stopUpdating = False headerBroken = False reedsoloFixed = 0 reedsoloErrors = 0 password = passwordInput.get().encode("utf-8") metadata = metadataInput.get("1.0", tkinter.END).encode("utf-8") cancelBtn["state"] = "normal" cancelBtn.config(cursor="hand2") # Decide if encrypting or decrypting if mode == "encrypt": outputFile = outputInput.get() + ".pcv" else: outputFile = outputInput.get() # Set progress bar indeterminate progress.config(mode="indeterminate") progress.start(15) # Compress files together if necessary if onlyFiles or allFiles: statusString.set(strings[1]) tmp = outputFile[:-4] if onlyFiles: zfPath = Path(onlyFiles[0]).parent.absolute() else: zfPath = Path(dirname(allFiles[0])).parent.absolute() zfOffset = len(str(zfPath)) zfName = pathJoin(zfPath, tmp) zf = ZipFile(zfName, "w") for i in allFiles: zf.write(i, i[zfOffset:]) for i in onlyFiles: zf.write(i, pathSplit(i)[1]) zf.close() inputFile = zfName outputFile = zfName + ".pcv" outputPath = dirname(outputFile) # Open files try: fin = open(inputFile, "rb") except: setEncryptionUI() statusString.set(strings[16]) return # If encrypting, generate values for encryption if mode == "encrypt": salt = urandom(16) # Argon2 salt nonce = urandom(24) # XChaCha20 nonce fout = open(outputFile, "wb+") # Indicate Reed-Solomon with "+" if reedsolo: fout.write(rs128.encode(b"+")) else: fout.write(rs128.encode(b"-")) # Encode metadata and length of metadata metadata = rs128.encode(metadata) tmp = len(metadata) tmp = f"{tmp:+<10}" tmp = rs128.encode(tmp.encode("utf-8")) # Write to file fout.write(tmp) fout.write(metadata) fout.write(rs128.encode(salt)) # Argon2 salt fout.write(rs128.encode(nonce)) # XChaCha20 nonce fout.write(b"0" * 192) # Hash of key fout.write(b"0" * 144) # Poly1305 MAC fout.write(b"0" * 160) # BLAKE3 CRC # If decrypting, read values from file else: tmp = fin.read(129) try: if bytes(rs128.decode(tmp)[0]) == b"+": reedsolo = True else: reedsolo = False except: setDecryptionUI() statusString.set(strings[21]) return metadataLength = fin.read(138) metadataLength = bytes(rs128.decode(metadataLength)[0]) metadataLength = metadataLength.replace(b"+", b"") fin.read(int(metadataLength.decode("utf-8"))) # Read values salt = fin.read(144) nonce = fin.read(152) keycs = fin.read(192) maccs = fin.read(144) crccs = fin.read(160) # Try to decode each value, increase Reed-Solomon errors fixed if needed try: salt, _, fixed = rs128.decode(salt) salt = bytes(salt) reedsoloFixed += len(fixed) except: headerBroken = True salt = salt[:16] try: nonce, _, fixed = rs128.decode(nonce) nonce = bytes(nonce) reedsoloFixed += len(fixed) except: headerBroken = True nonce = nonce[:24] try: keycs, _, fixed = rs128.decode(keycs) keycs = bytes(keycs) reedsoloFixed += len(fixed) except: headerBroken = True keycs = keycs[:64] try: maccs, _, fixed = rs128.decode(maccs) maccs = bytes(maccs) reedsoloFixed += len(fixed) except: headerBroken = True maccs = maccs[:16] try: crccs, _, fixed = rs128.decode(crccs) crccs = bytes(crccs) reedsoloFixed += len(fixed) except: headerBroken = True crccs = crccs[:32] # If the header is broken... if headerBroken: # Stop if user chose not to keep broken output if not shouldKeep: statusString.set(strings[4]) fin.close() try: remove(outputFile) except: pass setDecryptionUI() return else: kept = "badlyCorrupted" statusString.set(strings[9]) # Generate Argon2d key from master password key = hash_secret_raw(password, salt, time_cost=8, memory_cost=2**20, parallelism=8, hash_len=32, type=argonType.D) # Stop the indeterminate progress bar and set determinate progress.stop() progress.config(mode="determinate") progress["value"] = 0 # Hash of the derived Argon2 key check = SHA3_512.new(data=key).digest() # Check if password is correct if mode == "decrypt": if not compare_digest(check, keycs): # If header isn't broken... if not headerBroken: # Tell user password is incorrect statusString.set(strings[2]) fin.close() setDecryptionUI() return fout = open(outputFile, "wb+") crc = blake3() # Blake3 CRC cipher = ChaCha20_Poly1305.new(key=key, nonce=nonce) # XChaCha20 # Variables for calculating speeds, etc. done = 0 total = getsize(inputFile) startTime = datetime.now() previousTime = datetime.now() # Update progress bar, etc. in another thread Thread(target=updateStats, daemon=True, args=(total, )).start() # Start the encryption/decryption process while True: # Check if cancel button pressed if not working: fin.close() fout.close() remove(outputFile) if mode == "encrypt": setEncryptionUI() else: setDecryptionUI() statusString.set("Operation canceled by user.") dummy.focus() return # Read from file, read extra if Reed-Solomon was enabled if mode == "decrypt" and reedsolo: piece = fin.read(1104905) else: piece = fin.read(2**20) # End of file if not piece: break # Encrypt, etc. if mode == "encrypt": data = cipher.encrypt(piece) crc.update(data) if reedsolo: data = bytes(rs13.encode(data)) # Decrypt, etc. else: if reedsolo: try: data, _, fixed = rs13.decode(piece) except ReedSolomonError: # File is really corrupted if not reedsoloErrors and not shouldKeep: stopUpdating = True statusString.set(strings[4]) fin.close() fout.close() remove(outputFile) setDecryptionUI() return # Attempt to recover badly corrupted data kept = "badlyCorrupted" data = b"" piece = piece[:-13] counter = 0 while True: # Basically just strip off the Reed-Solomon bytes if counter < 1104905: data += piece[counter:counter + 242] counter += 255 # 242 bytes + 13 Reed-Solomon else: break fixed = bytearray() reedsoloErrors += 1 reedsoloFixed += len(fixed) crc.update(data) data = cipher.decrypt(data) else: crc.update(piece) data = cipher.decrypt(piece) # Write the data, increase the amount done fout.write(data) done += 1104905 if (mode == "decrypt" and reedsolo) else 2**20 # Stop UI updater from overwriting potential messages stopUpdating = True # Encryption is done, write appropriate values to file if mode == "encrypt": fout.flush() fout.close() fout = open(outputFile, "r+b") fout.seek(129 + 138 + len(metadata) + 144 + 152) fout.write(rs128.encode(check)) fout.write(rs128.encode(cipher.digest())) fout.write(rs128.encode(crc.digest())) # Decryption is done, check for integrity and authenticity else: # File is corrupted if not compare_digest(crccs, crc.digest()): statusString.set(strings[3]) fin.close() fout.close() if keep.get() != 1: remove(outputFile) setDecryptionUI() return else: if not kept: kept = "corrupted" try: cipher.verify(maccs) except: if not reedsoloErrors and not headerBroken: # File is modified statusString.set(strings[5]) fin.close() fout.close() # If keep file not checked... if keep.get() != 1: remove(outputFile) # Reset UI setDecryptionUI() return else: if not kept: kept = "modified" # Flush outputs, close files if not kept: fout.flush() fsync(fout.fileno()) fout.close() fin.close() # Securely wipe files as necessary if shouldErase: if onlyFolders: for i in onlyFolders: secureWipe(i) if onlyFiles: for i in range(len(onlyFiles)): statusString.set(strings[12] + f" ({i}/{len(onlyFiles)}") progress["value"] = i / len(onlyFiles) secureWipe(onlyFiles[i]) secureWipe(inputFile) # Secure wipe not enabled else: # Remove temporary zip file if created if allFiles or onlyFiles: remove(inputFile) # Show appropriate notice if file corrupted or modified arrow = "" if platform.system() == "Darwin" else "🡪" if not kept: statusString.set(f"Completed. (Click here to show output {arrow})") # Show Reed-Solomon stats if it fixed corrupted bytes if mode == "decrypt" and reedsoloFixed: tmp = "s" if reedsoloFixed != 1 else "" statusString.set(f"Completed with {reedsoloFixed} byte{tmp}" + f" fixed. (Click here to show output {arrow})") else: if kept == "modified": statusString.set(strings[7]) elif kept == "corrupted": statusString.set(strings[6]) else: statusString.set(strings[8]) status.config(cursor="hand2") # A little hack to prevent reference nonsense output = "".join([i for i in outputFile]) # Bind the output file to the status label if platform.system() == "Windows": status.bind("<Button-1>", lambda e: showOutput(output.replace("/", "\\"))) else: status.bind("<Button-1>", lambda e: showOutput(output)) # Reset variables and UI states resetUI() inputFile = "" outputFile = "" allFiles = [] onlyFolders = [] onlyFiles = [] working = False
''' def SwearFilter(Swear): if len(Swear[0]) - 2 <= 2: return '⚹' * (len(Swear[0]) - 2) elif len(Swear[0]) - 2 <= 5: return Swear[0][1:2] + '*' * (len(Swear[0]) - 3) elif len(Swear[0]) - 2 > 5: return Swear[0][1:2] + '*' * (len(Swear[0]) - 4) + Swear[0][-2:-1] srtOpen = fd.askopenfilename(title='Open srt sample') fdrOpen = fd.askdirectory(title='Open folder (According Video and Language)') copyfile(srtOpen, pathSplit(srtOpen)) fileopen = open(pathSplit(srtOpen), 'r', encoding='utf-8') fileread = fileopen.readlines() fileopen.close Counter = 0 for mdfiles in sorted(listdir(fdrOpen)): if mdfiles != 'titles.md': fo = open(fdrOpen + '\\' + mdfiles, "r", encoding='UTF-8') for line in fo.readlines(): swFilter = regexSub(regexSwearPattern, SwearFilter, line.rstrip()).split(" ", maxsplit=1) fileread[(3 * (Counter + 1)) + Counter - 1] = swFilter[1] + '\n' # print(swFilter) Counter += 1
def getParentFolder(file): """ [String] file name with full path => [String] parent folder of the file """ return pathSplit(file)[0]
def getFilenameWithoutPath(file): """ [String] file name (with or without full path) => [String] file name without path """ return pathSplit(file)[1]