Описание скрипта parser.py
В данном документе будет описан принцип работы данного скрипта.
Для его работы необходимо ввести путь к папке pages
.
Пример:
C:******\Монитор_продаж\pages
Или для монитора продаж, распакованного на диске D :
Скрипт считывает любой путь, независимо от системы, которой пользуется пользователь (Windows, Linux, MacOS).
Для его работы необходим установленный python и pandas.
Первое что делает скрипт, это парсит app.json - составляет нужный пандас датафрейм с необходимыми полями (dataProviders, page_url, page_name)
Далее пробегает по каждому файлу в папке pages,вызывая рекурсивную функцию parse_children.
В данных по ключу children могут быть расположены данные с таким же ключом. Функция parse_children принимает как аргумент целый файл (или фрагмент) и полный путь файла.
Первым делом проверяет наличие таких ключей как ‘children’ и ‘props’.
Затем проверяется ряд условий, необходимые поля добавляются в список строк, затем функция вызывает сама себя передавая в себя объект child.
Таким образом, функция в каждом файле доходит до максимального уровня глубины, пока есть ключи children’, ‘props’, затем переходит к следующему уровню вложенности, а потом и к следующему файлу.
После того, как цикл пройдется по всем файлам и вызовет данную функцию, из строк будет составлен датафрейм, к нему будет будет выполнен джойн ранее созданного датасета.
Сохранение последнего датафрейма будет произведено в ту же папку, где находится исполняемый скрипт.
Сам скрипт можно скопировать тут:
import os
import json
from pprint import pprint
import pandas as pd
from pathlib import Path
path = input('Ввести путь до папки pages: ')
### Пример C:\****\****\****\Монитор_продаж\pages
app_path = Path(path.replace('pages', 'app.json').strip())
path = Path(path.strip())
filenames = os.listdir(path)
rows = []
dataproviders = []
with open(app_path, encoding='utf-8') as ap:
app_data = json.load(ap)
if 'dataProviders' in app_data:
for dp in app_data['dataProviders']:
id = dp['connection']['code']
dataproviders.append(id)
else: dataproviders.append('none')
def parse_children(data, localfilename):
if {'children', 'props'} <= set(data):
for child in data['children']:
if 'dremioAddons' in child['props']:
for addon in child['props']['dremioAddons']:
addons = []
for source in addon['query']['$from']:
addons.append(source)
rows.append([localfilename, child['type'], '.'.join(addons)])
if 'dremio' in child['props']:
addons = []
sources = child['props']['dremio']
if type(sources) == list:
for query in sources:
for addon in query['query']['$from']:
addons.append(addon)
if type(sources) == dict:
for addon in sources['query']['$from']:
addons.append(addon)
rows.append([localfilename, child['type'], '.'.join(addons)])
if 'datasets' in child['props']:
for dataset in child['props']['datasets']:
rows.append([localfilename, child['type'], f'{dataset["query"]["$from"]}.{dataset["name"]}'])
parse_children(child, localfilename)
for name in filenames:
row = []
fullname = path.joinpath(name)
# fullname = rf'{path}\{name}'
with open(fullname, encoding='utf-8') as f:
data = json.load(f)
## Обычно в data 1 элемент, но на всякий случай обрабатывается циклом
for i in data:
parse_children(i, name)
df = pd.DataFrame(rows, columns=['filename', 'type', 'path'])
df['dataproviders'] = ','.join(dataproviders)
df.to_csv('result.csv', index=False)