TL; DR - что создает пробел в конце строки, хранящейся в наборе?
Описание проблемы:
Представьте себе, что вы пишете сценарий для обхода каталога и внесения конкретных изменений в каталог, упомянутый в файле фильтра.
Из-за некоторых архитектурных ограничений вы выбираете, чтобы сценарий отображал структуру dir и построчно сохранял ее в текстовом файле. Пример:
./Test
./Test/foo
./Test/foo/bar
Затем, когда вы снова запустите сценарий, он сравнит новый текстовый файл, сгенерированный в прогоне nth , со старым текстовым файлом из прогона n-1 . Если были какие-либо изменения, он будет реагировать на них, сравнивая изменения с текстовым файлом фильтра, в котором хранятся интересующие каталоги.
Однако при запуске сценария происходит сбой. После отладки оказывается, что пробел был добавлен непосредственно перед концом строк, сохраненных в наборе «изменений» следующим образом:
changed_path = {str}'.\\Test\\foo\\bar \n' # Detected Path change
watched_path = {str}'.\\Test\\foo\\bar\n' # Path as detailed in filter file
Есть идеи, что вызвало это?
Кажется, проблема в функции "проверки"
Полный код:
# Script
################
# Relevant Imports
###############
import os
################
# Parameter definitions:
###############
PATH = "." # default is the root folder holding the script
FILTERS = "./Filters/" # Default is a folder named "Filters" in root folder
SUFFIX = ".txt"
DIFF = []
################
# Function definitions
###############
def return_as_list(filter_file):
"""Creates a list of strings out of a text file, line by line"""
with open(FILTERS+filter_file, 'r') as filter:
results = filter.readlines()
return results
def checker(filter_as_list, changes_as_set):
"""Compares the filter list to the changes set, and returns
the difference if there is any"""
#changes_set = set(filter_as_list).intersection(changes_as_set)
changes_list = []
for watched_path in filter_as_list:
for changed_path in changes_as_set:
if watched_path == changed_path:
changes_list.append(watched_path)
if not changes_list: # If the list is empty
print('changes_list is empty!')
pass # Skips loop since there is no match between filter and Changelog
else:
return (changes_list)
###############
# Generate log of changes made to the directory structure:
###############
# Check if log exists, if so designate it as old for comparison later
if os.path.isfile('log_current.txt'):
if not os.path.isfile('log_old.txt'):
os.rename('log_current.txt', 'log_old.txt')
# Fill log_current with current directory structure
for root, dirs, files in os.walk(PATH, topdown=True):
for name in dirs:
os.system('echo ' + os.path.join(root, name) + ' >> log_current.txt')
# If two logs exist, create a log of all differences between the two
if (os.path.isfile('log_current.txt') and os.path.isfile('log_old.txt')):
with open('log_current.txt', 'r') as current:
with open('log_old.txt', 'r') as old:
DIFF = set(current).symmetric_difference(old)
# Create a text file containing all changes
with open('log_changes.txt', 'w+') as changes:
for line in DIFF:
changes.write(line)
###############
# Script start
###############
# Check if the changes set is empty
if not DIFF:
print('Set is empty, no changes')
if os.path.isfile('log_old.txt'):
os.remove('log_old.txt')
if os.path.isfile('log_changes.txt'):
os.remove('log_changes.txt')
else:
# Cycle through the filters and compare them to the changes log
for filename in os.listdir(FILTERS):
if filename.endswith(SUFFIX):
# Retrieve email address and send file to be processed
filter_file_as_list = return_as_list(filename)
email_address = filter_file_as_list.pop(0)
# Get a list of changes that are mentioned in the filter file
list_of_changed_paths = checker(filter_file_as_list, DIFF)
# If there was no match
if not list_of_changed_paths:
pass
else:
paths_for_email = ("\n".join(list_of_changed_paths))
# Create text file for Email script
with open('message.txt', 'w+') as msg:
msg.write("The following paths have changed:\n " + paths_for_email)
print(paths_for_email)
#os.system("./outlook-sendmail.exe " + email_address + ' "Changes" ' + ' "message.txt"')
# Clean up
if os.path.isfile('message.txt'):
os.remove("message.txt")
if os.path.isfile('log_old.txt'):
os.remove('log_old.txt')
if os.path.isfile('log_changes.txt'):
os.remove('log_changes.txt')