python - как сопоставить файлы по чему-то в имени файла - PullRequest
0 голосов
/ 10 июля 2020

Это мой первый вопрос. Я все еще новичок в python, поэтому может быть, я просто не знал, как правильно задать вопрос, и пропустил его в stackoverflow!

Что я хочу: автоматизировать проверку веб-сайта на наличие изменений. Я хочу, чтобы он отправлял мне уведомление каждый раз, когда есть изменение, и сообщал мне, что это за изменение.

Пока у меня есть 2 отдельных фрагмента кода, которые работают:

  • An Вызов API, который возвращает список результатов в формате json. (в списке всегда 30 результатов)
  • Инструмент сравнения, который проверяет, совпадают ли файлы json, и выдает разницу, если они не совпадают.

Если Я запускаю вызов API сам по себе, он прекрасно работает и сохраняет json результатов в файл.

Если я различаю каждый файл по одному, код сравнения сработает и выдаст изменения.

Я хочу, чтобы они работали вместе - в результате я могу настроить задание cron + уведомление и go о своей жизни, сэкономив время на том, чтобы не проверять эти сайты, если я не знаю, что произошло изменение.

Моя идея состоит в том, что я постоянно сверяю последнее вытягивание с последним, поэтому я сохраняю результаты в папке.

Пытаясь заставить разные части работать, я разделил старые результаты из новых результатов в папках, понимая, что я не уверен, как указать коду различать старый и новый.

Я хочу перебрать папки, найти соответствующий старый файл и n ew, сделайте каждый объект json, а затем сравните два.

Части того, что я пробовал, работают, но я застрял в том, как связать старый + новый файл вместе.

вот с чем я работаю:

new_files = []
old_files = []
docs = for_docs[0]

for unid in uid_list:
    with open('%s_my_results' % uid, 'w+') as outfile:
        json.dump(docs, outfile)

        for newFiles in os.walk('FILEPATH/new_files'):
            newfiles.append(newFiles)
       
        unpack_newFiles = sorted(newfiles[2])

os.chdir('FILEPATH/old_files'):

for oldfiles in os.walk('FILEPATH/old_files'):
    old_files.append(oldfiles[2])

for fname in unpack_oldFiles:
    if fname.endswith('.json'):
       with open(fname, mode='rb+') as oldFile:
           try:
               unpack_oldFiles = json.load(oldFile)
           except json.decoder.JSONDecodeError:
                continue 


Это работает, но я думаю, что распакованный json объект по-прежнему представляет собой несортированный список json объектов. Так что я определенно запутался здесь и пытаюсь освободиться от узла.

причина, по которой я использовал сортировку, заключалась в надежде, что я могу просто заставить их соответствовать по порядку, потому что они всегда будут загружаться в одном и том же порядке . Я думаю, что обнаружил, что сортировка - не тот инструмент, но я определенно сбился с пути.

это код, который работает, чтобы различать мои json файлы:

    with open('FILEPATH/old_file.json') as f:
        old_docs = json.load(f)
    
    with open('FILEPATH/new_file.json') as fc:
        new_docs = json.load(fc)
    
    # compare the two objects 
    
    thing = (old_docs==new_docs)
    
    # log time and result 
    
    if thing is not True:
        with open('logfile.txt', 'a+') as sys.stdout:
            print(f'{date} this item was added:  ')
            print((DeepDiff(old_docs,new_docs)))
            sys.stdout.close()
    if thing is True:
        with open('logfile.txt', 'a+') as sys.stdout:
            print(f'{date} No Change') 
            sys.stdout.close()

I знаю, что я хочу, а именно:

#for file in list: 
    # if uid in file name matches:
        # decode each file to json 
        # diff the two files 
        # spit out the result 

С этой целью я начал писать варианты нижеприведенного, и мне определенно что-то не хватает. Я нашел fnmatch, но не знаю, как его использовать.

for fname in folder 1, folder2:
   if UID-in-filename matches: # I do not know how to set this up
       thing = (oldfile == newfile)
       if thing is not True:
       with open('logfile.txt', 'a+') as sys.stdout:
          print(f'{date} {UID} this item was added:')
          print((DeepDiff(oldfile, newfile)
          print(no change)
        if thing is True:
       with open('logfile.txt', 'a+') as sys.stdout:
          print(f'{date} {UID} no change')
          sys.stdout.close()

Надеюсь, я выполнил свой первый запрос. Всем спасибо!

1 Ответ

0 голосов
/ 10 июля 2020

Итак, если я вас правильно понимаю, у вас есть что-то со структурой каталогов примерно так:

data_files/
├── new_data
│   ├── data_file_1970_01_01_e24520c7-94ef-41c6-94b3-a16049b0d882.json
│   ├── data_file_1970_01_03_827a591b-8d10-4f8e-b55d-5a36bdaa96d7.json
│   └── data_file_1971_01_02_18bfab97-aeb9-476e-9332-94f4bb30157b.json
└── old_data
    ├── old_name_1970_01_01_e24520c7-94ef-41c6-94b3-a16049b0d882.json
    ├── old_name_1970_01_03_827a591b-8d10-4f8e-b55d-5a36bdaa96d7.json
    └── old_name_1971_01_02_18bfab97-aeb9-476e-9332-94f4bb30157b.json

где у вас есть папки, заполненные различными json файлами, которые не имеют точного имени, но если где-то в имени используется общий идентификатор uuid, вам нужно прочитать оба файла с одинаковым идентификатором uuid, а затем запустить на них свою программу сравнения. Я бы сделал это примерно так:

import json
import os
import re

from pprint import pprint


uuid_regex = re.compile(r'[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}')


def parse_directory(uuid_dict, filelist, key):
    for file in filelist:

        uuid_matcher = uuid_regex.findall(file)

        # check that a uuid was found in the input filename
        if (uuid_matcher):

            uuid = uuid_matcher[0]

            # dict.get returns existing sub dictionary if found, or defaults to a new dictionary
            per_uuid_subdict = uuid_dict.get(uuid, dict())
            per_uuid_subdict[key] = file

            uuid_dict[uuid] = per_uuid_subdict


old_files = [os.path.abspath(os.path.join('data_files/old_data', i)) for i in os.listdir('data_files/old_data') if i.endswith('.json')]
new_files = [os.path.abspath(os.path.join('data_files/new_data', i)) for i in os.listdir('data_files/new_data') if i.endswith('.json')]

uuid_dict = dict()
parse_directory(uuid_dict, new_files, 'new')
parse_directory(uuid_dict, old_files, 'old')

Здесь используется регулярное выражение для добавления uuid в словарь, чтобы создать сопоставление uuid с файлами, в которых есть этот uuid. Пример того, как это выглядит ...

pprint(uuid_dict)
# prints:
# {'18bfab97-aeb9-476e-9332-94f4bb30157b': {'new': '/path/to/file/data_files/new_data/data_file_1971_01_02_18bfab97-aeb9-476e-9332-94f4bb30157b.json',
#                                           'old': '/path/to/file/data_files/old_data/old_name_1971_01_02_18bfab97-aeb9-476e-9332-94f4bb30157b.json'},
#  '827a591b-8d10-4f8e-b55d-5a36bdaa96d7': {'new': '/path/to/file/data_files/new_data/data_file_1970_01_03_827a591b-8d10-4f8e-b55d-5a36bdaa96d7.json',
#                                           'old': '/path/to/file/data_files/old_data/old_name_1970_01_03_827a591b-8d10-4f8e-b55d-5a36bdaa96d7.json'},
#  'e24520c7-94ef-41c6-94b3-a16049b0d882': {'new': '/path/to/file/data_files/new_data/data_file_1970_01_01_e24520c7-94ef-41c6-94b3-a16049b0d882.json',
#                                           'old': '/path/to/file/data_files/old_data/old_name_1970_01_01_e24520c7-94ef-41c6-94b3-a16049b0d882.json'}}

А дальше просто вопрос перебора результатов.

for uuid, filelist in uuid_dict.items():

    if len(filelist) != 2:

        print('Too many files to diff for uuid: {}'.format(uuid))
        continue

    try:
        with open(filelist['new'], 'r') as file_handler:
            new_file = json.load(file_handler)
    except json.decoder.JSONDecodeError:
        continue

    try:
        with open(filelist['old'], 'r') as file_handler:
            old_file = json.load(file_handler)
    except json.decoder.JSONDecodeError:
        continue

    # DeepDiff handling logic around hereish
    DeepDiff(old_file, new_file)
...