#!/usr/bin/env python
"""
Further ananlysis on simulation data and Code for reproducing fig4.
"""
import h5py
import matplotlib as mpl
mpl.rcParams.update({'pdf.fonttype' : 42,
                     'ps.fonttype' : 42,
                     'legend.frameon' : False,
                     'axes.spines.right' :  False,
                     'axes.spines.top' : False})
import matplotlib.pyplot as plt
import numpy as np
import pyximport
pyximport.install()
import os
import scipy.io
from scipy.stats import wilcoxon, ttest_rel, ttest_ind
import sys
from time import time, sleep
from threading import Thread

try:
    if __IPYTHON__:
        # this is used for debugging purposes only. allows to reload classes
        # when changed
        get_ipython().magic('load_ext autoreload')
        get_ipython().magic('autoreload 2')
except NameError:
    pass
#
from fiola.fiolaparams import fiolaparams
from fiola.fiola import FIOLA
from paper_reproduction.Fig7.Fig7_utilities import barplot_annotate_brackets, barplot_pvalue
from fiola.utilities import normalize, normalize_piecewise, match_spikes_greedy, compute_F1, load, signal_filter, extract_spikes
#sys.path.append('/media/nel/storage/Code/NEL_LAB/fiola/use_cases')
#sys.path.append(os.path.abspath('/Users/agiovann/SOFTWARE/fiola'))
#from use_cases.test_run_fiola import run_fiola # must be in use_cases folder
from paper_reproduction.Fig4_5.test_run_fiola import run_fiola
from paper_reproduction.utilities import multiple_dfs

#%%
mode = ['overlapping', 'non_overlapping', 'positron'][0]
dropbox_folder = '/media/nel/storage/NEL-LAB Dropbox/'
#dropbox_folder = '/Users/agiovann/Dropbox/'

if mode == 'overlapping':
    ROOT_FOLDER = dropbox_folder+'NEL/Papers/VolPy_online/data/voltage_data/simulation/overlapping'
    SAVE_FOLDER = dropbox_folder+'NEL/Papers/VolPy_online/result/test_simulations/overlapping'
    names = [f'viola_sim3_{i}' for i in range(1, 19)]
    #names = [f'viola_sim3_{i}' for i in range(4, 7)]
    #names = [f'viola_sim6_{i}' for i in range(2, 20, 3)]

elif mode == 'non_overlapping':
    ROOT_FOLDER = dropbox_folder+'NEL/Papers/VolPy_online/data/voltage_data/simulation/non_overlapping'
    SAVE_FOLDER = dropbox_folder+'NEL/Papers/VolPy_online/result/test_simulations/non_overlapping'
    #names = [f'viola_sim5_{i}' for i in range(1, 8)]
    names = [f'viola_sim5_{i}' for i in range(2, 8, 2)]
    #names = [f'viola_sim7_{i}' for i in range(2, 9)]

elif mode == 'positron':
    ROOT_FOLDER = dropbox_folder+'NEL/Papers/VolPy_online/data/voltage_data/simulation/test/sim4_positron'
    SAVE_FOLDER = dropbox_folder+'NEL/Papers/VolPy_online/result/test_simulations/test/sim4_positron'
    names = [f'viola_sim4_{i}' for i in range(1, 13)]
#%%
# for num_layers in [1, 3, 5, 10, 30]:
#     for trace_with_neg in [True, False]:
distance = [f'dist_{i}' for i in [1, 3, 5, 7, 10, 15]]
#names = [f'viola_sim3_{i}' for i in range(1, 19)]
#names = [f'viola_sim5_{i}' for i in range(2, 8, 2)]
#names = [f'viola_sim6_{i}' for i in range(2, 20, 3)]
#names = [f'viola_sim7_{i}' for i in range(2, 9)]
test = []
t_range = [10000, 75000]
for idx, dist in enumerate(distance):
    #if idx == 1:
    vi_result_all = []
    time_all = []
    spnr_all = []
    if mode == 'overlapping':
        #select = np.arange(idx * 3, (idx + 1) * 3)
        select = np.array([idx])
    else:
        select = np.array(range(len(names)))
    for name in np.array(names)[select]:
        folder = os.path.join(ROOT_FOLDER, name)
        gt_files = [file for file in os.listdir(folder) if 'SimResults' in file]
        gt_file = gt_files[0]
        gt = scipy.io.loadmat(os.path.join(folder, gt_file))
        gt = gt['simOutput'][0][0]['gt']
        spikes = gt['ST'][0][0][0]

        vi_folder = os.path.join(folder, 'viola')
        vi_files = sorted([file for file in os.listdir(vi_folder) if 'v3.3' in file and 'layers_3_' in file ])
        #vi_files = sorted([file for file in os.listdir(vi_folder) if 'v3.0' in file and 'layers_1' in file])
        #vi_files = sorted([file for file in os.listdir(vi_folder) if 'v3.0' in file and f'layers_{num_layers}_' in file and f'trace_with_neg_{trace_with_neg}' in file])
        if len(vi_files) > 1:
            raise Exception('number of files greater than one')
        vi_file = vi_files[0]
        vi = np.load(os.path.join(vi_folder, vi_file), allow_pickle=True).item()

        time_all.append(np.mean(np.diff(vi.timing_online)))

        #vi_spatial = vi.H.copy()
        vi_temporal = vi.t_s.copy()
        vi_spikes = np.array([np.array(sorted(list(set(sp)-set([0])))) for sp in vi.index])[np.argsort(vi.seq)]

        n_cells = spikes.shape[0]
        vi_result = {'F1':[], 'precision':[], 'recall':[]}
        rr = {'F1':[], 'precision':[], 'recall':[]}
        for idx in range(n_cells):
            s1 = spikes[idx].flatten()
            s1 = s1 - 1     # matlab first element is 1
            s1 = s1[np.logical_and(s1>t_range[0], s1<t_range[1])]
            s2 = vi_spikes[idx]
            s2 = s2[np.logical_and(s2>t_range[0], s2<t_range[1])]
            idx1_greedy, idx2_greedy = match_spikes_greedy(s1, s2, max_dist=4)
            F1, precision, recall = compute_F1(s1, s2, idx1_greedy, idx2_greedy)
            rr['F1'].append(F1)
            rr['precision'].append(precision)
            rr['recall'].append(recall)
        vi_result_all.append(rr)

        spnr = []
        for idx in range(n_cells):
            s1 = spikes[idx].flatten()
            s1 = s1 - 1
            s1 = s1[np.logical_and(s1>t_range[0], s1<t_range[1])]
            s2 = vi_spikes[idx]
            s2 = s2[np.logical_and(s2>t_range[0], s2<t_range[1])]
            t2 = vi_temporal[idx]
            t2 = normalize_piecewise(t2, 5000)
            ss = np.mean(t2[s1])
            spnr.append(ss)
        spnr_all.append(spnr)

    folder_name = vi_file[:-4]
    try:
        os.makedirs(os.path.join(SAVE_FOLDER, folder_name))
        print('make folder')
    except:
        print('already exist')
    #np.save(os.path.join(SAVE_FOLDER, folder_name, f'viola_result_{t_range[0]}_{t_range[1]}'), vi_result_all)
    np.save(os.path.join(SAVE_FOLDER, folder_name, f'viola_result_{t_range[0]}_{t_range[1]}_timing'), time_all)

    # np.save(os.path.join(SAVE_FOLDER, folder_name, f'viola_result_spnr_{t_range[0]}_{t_range[1]}_v3.0'), spnr_all)
    # print(len(vi_result_all))
    #np.save(os.path.join(SAVE_FOLDER, folder_name,  f'viola_result_{t_range[0]}_{t_range[1]}_{dist}'), vi_result_all)
    ##np.save(os.path.join(SAVE_FOLDER, folder_name, f'viola_result_spnr_{t_range[0]}_{t_range[1]}_v2.0_without_shrinking'), spnr_all)
    test.append(np.mean(vi_result_all[0]['F1']))

#%%
#'t_' means tested algorithm
a_idx = 2 # algorithm idx
algo = ['volpy', 'suite2p', 'meanroi', 'meanroi_online'][a_idx]
thresh_list = np.arange(2.0, 4.1, 0.1)
best_thresh = [False, True, True, False][a_idx]

if mode == 'overlapping':
    t_range = [10000, 20000]
    names = [f'viola_sim3_{i}' for i in range(1, 19)]
    distance = [f'dist_{i}' for i in [1, 3, 5, 7, 10, 15]]
elif mode == 'non_overlapping':
    t_range = [10000, 75000]
    names = [f'viola_sim5_{i}' for i in range(1, 8)]
    distance = [0]

save_folder = os.path.join(SAVE_FOLDER, f'{algo}_result_v3.1')
try:
    os.makedirs(save_folder)
    print('make folder')
except:
    print('already exist')

for ii, dist in enumerate(distance):
    t_result_all = []
    spnr_all = []
    best_thresh_all = []

    if mode == 'overlapping':
        select = np.arange(ii * 3, (ii + 1) * 3)
    else:
        select = np.array(range(len(names)))

    for name in np.array(names)[select]:
        print(f'now processing {name}')
        folder = os.path.join(ROOT_FOLDER, name)
        gt_files = [file for file in os.listdir(folder) if 'SimResults' in file]
        gt_file = gt_files[0]
        gt = scipy.io.loadmat(os.path.join(folder, gt_file))
        gt = gt['simOutput'][0][0]['gt']
        spikes = gt['ST'][0][0][0]
        temporal = gt['trace'][0][0][:,:,0]
        path_ROIs = os.path.join(folder, 'viola', 'ROIs_gt.hdf5')
        with h5py.File(path_ROIs,'r') as h5:
            spatial = np.array(h5['mov'])
        plt.imshow(spatial.sum(0))

        #summary_file = os.listdir(os.path.join(folder, 'volpy'))
        #summary_file = [file for file in summary_file if 'summary' in file][0]
        #summary = cm.load(os.path.join(folder, 'volpy', summary_file))

        if algo == 'meanroi' or 'meanroi_online':
            movie_file = [file for file in os.listdir(folder) if 'hdf5' in file and 'flip' not in file][0]
            mov = load(os.path.join(folder, movie_file))
            mov = mov.reshape([mov.shape[0], -1], order='F')
            spatial_F = [np.where(sp.reshape(-1, order='F')>0) for sp in spatial]
            t_temporal = np.array([-mov[:, sp].mean((1,2)) for sp in spatial_F])
            t_spatial = spatial

        elif algo == 'volpy':
            t_folder = os.path.join(folder, 'volpy')
            t_files = sorted([file for file in os.listdir(t_folder) if 'adaptive_threshold' in file])
            t_file = t_files[0]
            t = np.load(os.path.join(t_folder, t_file), allow_pickle=True).item()
            t_spatial = t['weights'].copy()
            t_temporal = t['ts'].copy()
            t_ROIs = t['ROIs'].copy()
            t_ROIs = t_ROIs * 1.0
            t_templates = t['templates'].copy()
            t_spikes = t['spikes'].copy()

        if not best_thresh:
            print('not finding best thresh')
            n_cells = t_spatial.shape[0]
            t_result = {'F1':[], 'precision':[], 'recall':[]}
            rr = {'F1':[], 'precision':[], 'recall':[]}

            if algo == 'meanroi_online':
                from fiola.signal_analysis_online import SignalAnalysisOnlineZ
                saoz = SignalAnalysisOnlineZ(mode='voltage', window=10000, step=5000, detrend=True, flip=False,
                                             do_scale=False, template_window=2, robust_std=False, adaptive_threshold=True, fr=400, freq=15,
                                             minimal_thresh=3.0, online_filter_method = 'median_filter', filt_window = 15, do_plot=False)
                saoz.fit(t_temporal[:, :t_range[0]], num_frames=t_temporal.shape[1])
                for n in range(t_range[0], t_temporal.shape[1]):
                    saoz.fit_next(t_temporal[:, n: n+1], n)
                t_spikes = [np.unique(saoz.index[idxx]) for idxx in range(len(saoz.index))]

            for idx in range(n_cells):
                s1 = spikes[idx].flatten()
                s1 = s1 - 1
                s1 = s1[np.logical_and(s1>t_range[0], s1<t_range[1])]
                s2 = t_spikes[idx]
                s2 = s2[np.logical_and(s2>t_range[0], s2<t_range[1])]
                idx1_greedy, idx2_greedy = match_spikes_greedy(s1, s2, max_dist=4)
                F1, precision, recall= compute_F1(s1, s2, idx1_greedy, idx2_greedy)
                rr['F1'].append(F1)
                rr['precision'].append(precision)
                rr['recall'].append(recall)
            t_result_all.append(rr)
        else:
            print('find best thresh')
            from scipy.signal import medfilt
            n_cells = t_spatial.shape[0]
            t_result = {'F1':[], 'precision':[], 'recall':[]}
            t_result_0 = {'F1':[], 'precision':[], 'recall':[]}
            rr = {'F1':[], 'precision':[], 'recall':[]}
            for thresh in thresh_list:
                print(thresh)
                rr = {'F1':[], 'precision':[], 'recall':[]}
                t_temporal_p = np.array([tt - medfilt(tt, kernel_size=15) for tt in t_temporal])
                t_spikes = extract_spikes(t_temporal_p, threshold=thresh)

                for idx in range(n_cells):
                    s1 = spikes[idx].flatten()
                    s1 = s1 - 1
                    s1 = s1[np.logical_and(s1>t_range[0], s1<t_range[1])]
                    s2 = t_spikes[idx]
                    s2 = s2[np.logical_and(s2>t_range[0], s2<t_range[1])]
                    idx1_greedy, idx2_greedy = match_spikes_greedy(s1, s2, max_dist=4)
                    F1, precision, recall = compute_F1(s1, s2, idx1_greedy, idx2_greedy)
                    rr['F1'].append(F1)
                    rr['precision'].append(precision)
                    rr['recall'].append(recall)
                if not t_result['F1']:
                    t_result = rr
                    best_thresh = thresh
                    new_F1 = np.array(rr['F1']).sum()/n_cells
                    print(f'update: thresh:{thresh}, best_F1:{new_F1}, new_F1:{new_F1}')
                else:
                    best_F1 = np.array(t_result['F1']).sum()/n_cells
                    new_F1 = np.array(rr['F1']).sum()/n_cells
                    #print(new_F1)
                    if new_F1 > best_F1:
                        print(f'update: thresh:{thresh}, best_F1:{best_F1}, new_F1:{new_F1}')
                        t_result = rr
                        best_thresh = thresh

            t_result_all.append(t_result)

        if mode == 'non_overlapping':
            spnr = []
            for idx in range(n_cells):
                s1 = spikes[idx].flatten()
                s1 = s1 - 1
                s1 = s1[np.logical_and(s1>t_range[0], s1<t_range[1])]
                t2 = t_temporal_p[idx]
                t2 = normalize_piecewise(t2, 5000)
                ss = np.mean(t2[s1])
                spnr.append(ss)
            spnr_all.append(spnr)

    # if mode == 'non_overlapping':
    #     np.save(os.path.join(save_folder, f'{algo}_F1_{t_range[0]}_{t_range[1]}_v3.1'), t_result_all)
    #     np.save(os.path.join(save_folder, f'{algo}_spnr_{t_range[0]}_{t_range[1]}_v3.1'), spnr_all)
    # elif mode == 'overlapping':
    #     np.save(os.path.join(save_folder, f'{algo}_F1_{t_range[0]}_{t_range[1]}_{dist}'), t_result_all)

##################################################################################################################
##################################################################################################################


from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from rest_framework.response import Response
from rest_framework.exceptions import ValidationError, NotFound, PermissionDenied
from rest_framework.decorators import action

from shared.constants.transactions import PLAN_TYPE_PM_FREE
from shared.error_responses.error import gen_error
from shared.permissions.locker_permissions.family_pwd_permission import FamilyPwdPermission
from v1_0.family.serializers import UserPlanFamilySerializer, CreateUserPlanFamilySeriaizer
from v1_0.general_view import PasswordManagerViewSet

class FamilyPwdViewSet(PasswordManagerViewSet):
    permission_classes = (FamilyPwdPermission, )
    http_method_names = ["head", "options", "get", "post", "delete"]

    def get_serializer_class(self):
        if self.action == "member_list":
            self.serializer_class = UserPlanFamilySerializer
        elif self.action == "member_create":
            self.serializer_class = CreateUserPlanFamilySeriaizer
        return super(FamilyPwdViewSet, self).get_serializer_class()

    def get_object(self):
        user = self.request.user
        pm_current_plan = self.user_repository.get_current_plan(user=user)
        # Check permission here
        if self.action == "member_list":
            if not pm_current_plan.pm_plan.is_family_plan and user.pm_plan_family.exists() is False:
                raise PermissionDenied
        else:
            if not pm_current_plan.pm_plan.is_family_plan:
                raise PermissionDenied
        return pm_current_plan

    @action(methods=["get"], detail=False)
    def member_list(self, request, *args, **kwargs):
        pm_current_plan = self.get_object()
        # The retrieving user is owner of the family plan
        if pm_current_plan.pm_plan.is_family_plan:
            owner = request.user
            family_members = pm_current_plan.pm_plan_family.all().order_by('-user_id', '-created_time')
        # Else, user is a member
        else:
            user = request.user
            family_user_plan = user.pm_plan_family.first()
            owner = family_user_plan.root_user_plan.user
            if family_user_plan:
                family_members = family_user_plan.root_user_plan.pm_plan_family.all().order_by(
                    '-user_id', '-created_time'
                )
            else:
                family_members = []
        serializer = self.get_serializer(family_members, many=True)
        owner = [{"id": None, "user_id": owner.user_id, "created_time": owner.creation_date}]
        results = owner + serializer.data
        return Response(status=200, data=results)

    @action(methods=["post"], detail=False)
    def member_create(self, request, *args, **kwargs):
        pm_current_plan = self.get_object()

        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        validated_data = serializer.validated_data
        family_members = validated_data.get("family_members")

        existed_family_members = pm_current_plan.pm_plan_family.all()
        pm_plan = pm_current_plan.get_plan_obj()

        if len(family_members) > pm_plan.get_max_number_members() - existed_family_members.count() - 1:
            raise ValidationError(detail={"non_field_errors": [gen_error("7012")]})

        for family_member in family_members:
            email = family_member.get("email")
            user_id = family_member.get("user_id")
            self.user_repository.add_to_family_sharing(
                family_user_plan=pm_current_plan, user_id=user_id, email=email
            )

        return Response(status=200, data={"success": True})

    @action(methods=["delete"], detail=False)
    def member_destroy(self, request, *args, **kwargs):
        user = self.request.user
        member_id = kwargs.get("member_id")
        pm_current_plan = self.get_object()
        try:
            family_member = pm_current_plan.pm_plan_family.get(id=member_id)
        except ObjectDoesNotExist:
            raise NotFound
        if family_member.user == user:
            raise PermissionDenied
        # Downgrade the plan of the member user
        if family_member.user:
            self.user_repository.update_plan(
                user=family_member.user, plan_type_alias=PLAN_TYPE_PM_FREE, scope=settings.SCOPE_PWD_MANAGER
            )
        family_user_id = family_member.user_id
        family_email = family_member.email
        family_member.delete()
        return Response(status=200, data={"user_id": family_user_id, "email": family_email})


# coding: utf-8

"""
    MongoDB Atlas Administration API

    The MongoDB Atlas Administration API allows developers to manage all components in MongoDB Atlas. To learn more, review the [Administration API overview](https://www.mongodb.com/docs/atlas/api/atlas-admin-api/). This OpenAPI specification covers all of the collections with the exception of Alerts, Alert Configurations, and Events. Refer to the [legacy documentation](https://www.mongodb.com/docs/atlas/reference/api-resources/) for the specifications of these resources.  # noqa: E501

    The version of the OpenAPI document: 2.0
    Generated by: https://openapi-generator.tech
"""

from __future__ import annotations
from inspect import getfullargspec
import pprint
import re  # noqa: F401
import json

from datetime import datetime
from typing import Optional
from pydantic import BaseModel, Field, StrictStr, conlist, constr, validator
from atlas.models.cluster_outage_simulation_outage_filter import ClusterOutageSimulationOutageFilter

class ClusterOutageSimulation(BaseModel):
    """NOTE: This class is auto generated by OpenAPI Generator.
    Ref: https://openapi-generator.tech

    Do not edit the class manually.
    """
    cluster_name: Optional[constr(strict=True, max_length=64, min_length=1)] = Field(None, alias="clusterName", description="Human-readable label that identifies the cluster that undergoes outage simulation.")
    group_id: Optional[constr(strict=True, max_length=24, min_length=24)] = Field(None, alias="groupId", description="Unique 24-hexadecimal character string that identifies the project that contains the cluster to undergo outage simulation.")
    id: Optional[constr(strict=True, max_length=24, min_length=24)] = Field(None, description="Unique 24-hexadecimal character string that identifies the outage simulation.")
    outage_filters: Optional[conlist(ClusterOutageSimulationOutageFilter, min_items=1)] = Field(None, alias="outageFilters", description="List of settings that specify the type of cluster outage simulation.")
    start_request_date: Optional[datetime] = Field(None, alias="startRequestDate", description="Date and time when MongoDB Cloud started the regional outage simulation.")
    state: Optional[StrictStr] = Field(None, description="Phase of the outage simulation.  | State       | Indication | |-------------|------------| | `START_REQUESTED`    | User has requested cluster outage simulation.| | `STARTING`           | MongoDB Cloud is starting cluster outage simulation.| | `SIMULATING`         | MongoDB Cloud is simulating cluster outage.| | `RECOVERY_REQUESTED` | User has requested recovery from the simulated outage.| | `RECOVERING`         | MongoDB Cloud is recovering the cluster from the simulated outage.| | `COMPLETE`           | MongoDB Cloud has completed the cluster outage simulation.|")
    __properties = ["clusterName", "groupId", "id", "outageFilters", "startRequestDate", "state"]

    @validator('cluster_name')
    def cluster_name_validate_regular_expression(cls, v):
        if not re.match(r"^([a-zA-Z0-9]([a-zA-Z0-9-]){0,21}(?<!-)([\w]{0,42}))$", v):
            raise ValueError(r"must validate the regular expression /^([a-zA-Z0-9]([a-zA-Z0-9-]){0,21}(?<!-)([\w]{0,42}))$/")
        return v

    @validator('group_id')
    def group_id_validate_regular_expression(cls, v):
        if not re.match(r"^([a-f0-9]{24})$", v):
            raise ValueError(r"must validate the regular expression /^([a-f0-9]{24})$/")
        return v

    @validator('id')
    def id_validate_regular_expression(cls, v):
        if not re.match(r"^([a-f0-9]{24})$", v):
            raise ValueError(r"must validate the regular expression /^([a-f0-9]{24})$/")
        return v

    @validator('state')
    def state_validate_enum(cls, v):
        if v is None:
            return v

        if v not in ('START_REQUESTED', 'STARTING', 'SIMULATING', 'RECOVERY_REQUESTED', 'RECOVERING', 'COMPLETE'):
            raise ValueError("must validate the enum values ('START_REQUESTED', 'STARTING', 'SIMULATING', 'RECOVERY_REQUESTED', 'RECOVERING', 'COMPLETE')")
        return v

    class Config:
        allow_population_by_field_name = True
        validate_assignment = True

    def to_str(self) -> str:
        """Returns the string representation of the model using alias"""
        return pprint.pformat(self.dict(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> ClusterOutageSimulation:
        """Create an instance of ClusterOutageSimulation from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self):
        """Returns the dictionary representation of the model using alias"""
        _dict = self.dict(by_alias=True,
                          exclude={
                            "cluster_name",
                            "group_id",
                            "id",
                            "start_request_date",
                            "state",
                          },
                          exclude_none=True)
        # override the default output from pydantic by calling `to_dict()` of each item in outage_filters (list)
        _items = []
        if self.outage_filters:
            for _item in self.outage_filters:
                if _item:
                    _items.append(_item.to_dict())
            _dict['outageFilters'] = _items
        return _dict

    @classmethod
    def from_dict(cls, obj: dict) -> ClusterOutageSimulation:
        """Create an instance of ClusterOutageSimulation from a dict"""
        if obj is None:
            return None

        if type(obj) is not dict:
            return ClusterOutageSimulation.parse_obj(obj)

        _obj = ClusterOutageSimulation.parse_obj({
            "cluster_name": obj.get("clusterName"),
            "group_id": obj.get("groupId"),
            "id": obj.get("id"),
            "outage_filters": [ClusterOutageSimulationOutageFilter.from_dict(_item) for _item in obj.get("outageFilters")] if obj.get("outageFilters") is not None else None,
            "start_request_date": obj.get("startRequestDate"),
            "state": obj.get("state")
        })
        return _obj


import pygame
import os
import random
import neat
import pickle
import pygame_menu

GAME_WIDTH = 1100
GAME_HEIGHT = 700
clock = pygame.time.Clock()
pygame.font.init()
pygame.init()
os.environ['SDL_VIDEO_CENTERED'] = '1'
GAME_WINDOW = pygame.display.set_mode((GAME_WIDTH, GAME_HEIGHT))
pygame.display.set_icon(pygame.image.load("res/icon.png"))
pygame.display.set_caption("AI CAR GAME")
STAT_FONT = pygame.font.SysFont("comicsans", 30)
GEN = 0
MODE = 0

class Background:
    BG_IMG = pygame.image.load('res/bg.png')
    bgImages = [BG_IMG, BG_IMG]

    def __init__(self, y1, x, y2, animationSpeed):
        self.y1 = y1
        self.x = x
        self.y2 = y2
        self.animationSpeed = animationSpeed

    def drawBackground(self, gameWindow):

        self.y1 += self.animationSpeed
        self.y2 += self.animationSpeed

        if self.BG_IMG.get_height() + self.y1 > 2 * GAME_HEIGHT:
            self.y1 = self.y2 - self.BG_IMG.get_height()
        if self.BG_IMG.get_height() + self.y2 > 2 * GAME_HEIGHT:
            self.y2 = self.y1 - self.BG_IMG.get_height()

        gameWindow.blit(self.bgImages[0], (0, self.y1))
        gameWindow.blit(self.bgImages[1], (0, self.y2))

class Wall:
    GAP = 150
    WALL_IMG = pygame.image.load('res/wall.png')

    def __init__(self, y, animationSpeed):
        self.y = y
        self.LEFT_WALL = self.WALL_IMG
        self.RIGHT_WALL = pygame.transform.flip(self.WALL_IMG, True, False)
        self.leftX = 0
        self.rightX = 0
        self.passed = False
        self.width = 0
        self.animationSpeed = animationSpeed
        self.set_width()

    def set_width(self):
        self.width = random.randrange(50, 950)
        self.leftX = self.width - self.WALL_IMG.get_width()
        self.rightX = self.leftX + self.WALL_IMG.get_width() + self.GAP

    def move(self):
        self.y += self.animationSpeed

    def drawWalls(self, gameWindow):
        gameWindow.blit(self.WALL_IMG, (self.leftX, self.y))
        gameWindow.blit(self.WALL_IMG, (self.rightX, self.y))

    def collide(self, playerCar):
        carMask = playerCar.getMask()
        leftWallMask = pygame.mask.from_surface(self.LEFT_WALL)
        rightWallMask = pygame.mask.from_surface(self.RIGHT_WALL)

        leftOffset = (self.leftX - playerCar.x, self.y - playerCar.y)
        rightOffset = (self.rightX - playerCar.x, self.y - playerCar.y)

        leftCollisionPoint = carMask.overlap(leftWallMask, leftOffset)
        rightCollisionPoint = carMask.overlap(rightWallMask, rightOffset)

        if leftCollisionPoint or rightCollisionPoint:
            return True
        else:
            return False

class Player:
    PLAYER_IMG = pygame.image.load('res/car.png')

    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.xVel = 20

    def drawCar(self, gameWindow):
        gameWindow.blit(self.PLAYER_IMG, (self.x, self.y))

    def moveRight(self):
        if self.x + self.PLAYER_IMG.get_width() < GAME_WIDTH:
            self.x += self.xVel

    def moveLeft(self):
        if self.x > 0:
            self.x -= self.xVel

    def getMask(self):
        return pygame.mask.from_surface(self.PLAYER_IMG)

def drawGame(gameWindow, bg, walls, score, cars):
    bg.drawBackground(gameWindow)
    for wall in walls:
        wall.drawWalls(gameWindow)
    for car in cars:
        car.drawCar(gameWindow)
    scoreText = STAT_FONT.render("Score: " + str(score), 1, (255, 255, 0))
    quitText = STAT_FONT.render("ESC to stop", 1, (0, 0, 0))
    gameWindow.blit(scoreText, (GAME_WIDTH - 30 - scoreText.get_width(), 10))
    gameWindow.blit(quitText, (20, 10))
    pygame.display.update()

def drawGameAILearning(gameWindow, bg, cars, walls, score, gen):
    bg.drawBackground(gameWindow)
    for wall in walls:
        wall.drawWalls(gameWindow)
    for car in cars:
        car.drawCar(gameWindow)
        pygame.draw.line(gameWindow, (255, 255, 0), (int(car.x + car.PLAYER_IMG.get_width() // 2), car.y),
                         (walls[0].rightX, walls[0].y), 1)
        pygame.draw.line(gameWindow, (255, 255, 0), (int(car.x + car.PLAYER_IMG.get_width() // 2), car.y),
                         (walls[0].rightX - walls[0].GAP, walls[0].y), 1)
    scoreText = STAT_FONT.render("Score: " + str(score), 1, (0, 0, 0))
    quitText = STAT_FONT.render("ESC to stop", 1, (0, 0, 0))
    generation = STAT_FONT.render("Gen: " + str(gen), 1, (0, 0, 0))
    alive = STAT_FONT.render("Alive: " + str(len(cars)), 1, (0, 0, 0))
    gameWindow.blit(scoreText, (GAME_WIDTH - 30 - scoreText.get_width(), 10))
    gameWindow.blit(generation, (20, 10))
    gameWindow.blit(alive, (20, 35))
    gameWindow.blit(quitText, (20, 60))
    pygame.display.update()

def eval_genomes(genomes, config):
    global GEN
    GEN += 1
    cars = []
    nets = []
    ge = []
    animationSpeed = 10
    bg = Background(0, 0, GAME_HEIGHT, 10)
    walls = [Wall(0, animationSpeed)]
    score = 0

    for genome_id, genome in genomes:
        genome.fitness = 0
        net = neat.nn.FeedForwardNetwork.create(genome, config)
        nets.append(net)
        cars.append(Player(GAME_WIDTH // 2, GAME_HEIGHT - 125))
        ge.append(genome)

    addWall = False
    running = True
    while running:
        clock.tick(30)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
                pygame.quit()
                quit()

        keys = pygame.key.get_pressed()
        if keys[pygame.K_ESCAPE]:
            ge[0].fitness = 2000
            cars.clear()
            GEN = 0

        wallInd = 0
        if len(cars) > 0:
            if len(walls) > 1 and cars[0].y > walls[0].y + walls[0].RIGHT_WALL.get_height():
                wallInd = 1
        else:
            break

        for x, car in enumerate(cars):
            ge[x].fitness += 0.1

            output = nets[x].activate((animationSpeed,
                                       (car.x + car.PLAYER_IMG.get_width() // 2)
                                       - (walls[wallInd].rightX - walls[wallInd].GAP),
                                       walls[wallInd].rightX - (car.x + car.PLAYER_IMG.get_width() // 2)))
            if output[0] > 0.8:
                car.moveRight()
            if output[1] > 0.8:
                car.moveLeft()

        rem = []
        for wall in walls:
            for x, car in enumerate(cars):
                if wall.collide(car):
                    ge[x].fitness -= 1
                    cars.pop(x)
                    nets.pop(x)
                    ge.pop(x)

                if not wall.passed and wall.y > car.y:
                    wall.passed = True
                    addWall = True

            if wall.y + wall.RIGHT_WALL.get_height() > GAME_HEIGHT:
                rem.append(wall)
            wall.move()

        if addWall:
            score += 1
            if animationSpeed < 30:
                if score % 5 == 0:
                    animationSpeed += 1
                    bg.animationSpeed += 1
                    for car in cars:
                        if car.xVel < 50:
                            car.xVel += 2
            for g in ge:
                g.fitness += 5
            walls.append(Wall(0, animationSpeed))
            addWall = False

        for r in rem:
            walls.remove(r)

        if score == 150:
            for car in cars:
                car.xVel = 0
        drawGameAILearning(GAME_WINDOW, bg, cars, walls, score, GEN)

def runAILearning():
    local_dir = os.path.dirname(__file__)
    config_file = os.path.join(local_dir, 'config.txt')
    config = neat.config.Config(neat.DefaultGenome, neat.DefaultReproduction,
                                neat.DefaultSpeciesSet, neat.DefaultStagnation,
                                config_file)

    p = neat.Population(config)
    # p.add_reporter(neat.StdOutReporter(True))
    # stats = neat.StatisticsReporter()
    # p.add_reporter(stats)
    p.run(eval_genomes, 5)

def gameLoop():
    local_dir = os.path.dirname(__file__)
    config_path = os.path.join(local_dir, 'config.txt')
    config = neat.config.Config(neat.DefaultGenome, neat.DefaultReproduction,
                                neat.DefaultSpeciesSet, neat.DefaultStagnation,
                                config_path)
    pickle_in = open("bestCar.pickle", "rb")
    bestCar = pickle.load(pickle_in)
    startGame(bestCar, config)

def startGame(genomes, config):
    cars = []
    animationSpeed = 10
    bg = Background(0, 0, GAME_HEIGHT, 10)
    walls = [Wall(0, animationSpeed)]
    score = 0
    net = neat.nn.FeedForwardNetwork.create(genomes, config)
    cars.append(Player(GAME_WIDTH // 2, GAME_HEIGHT - 125))

    if MODE == 1:
        cars.append(Player(GAME_WIDTH // 2, GAME_HEIGHT - 125))
        cars[1].PLAYER_IMG = pygame.image.load('res/car1.png')

    addWall = False
    running = True
    while running:
        clock.tick(30)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
                pygame.quit()
                quit()

        keys = pygame.key.get_pressed()

        if keys[pygame.K_ESCAPE]:
            break

        if len(cars) >= 2:
            if keys[pygame.K_LEFT]:
                cars[1].moveLeft()

            elif keys[pygame.K_RIGHT]:
                cars[1].moveRight()

        wallInd = 0
        if len(cars) > 0:
            if len(walls) > 1 and cars[0].y > walls[0].y + walls[0].RIGHT_WALL.get_height():
                wallInd = 1
        else:
            break

        output = net.activate((animationSpeed,
                               (cars[0].x + cars[0].PLAYER_IMG.get_width() // 2) - (
                                       walls[wallInd].rightX - walls[wallInd].GAP),
                               walls[wallInd].rightX - (cars[0].x + cars[0].PLAYER_IMG.get_width() // 2)))

        if output[0] > 0.8:
            cars[0].moveRight()
        if output[1] > 0.8:
            cars[0].moveLeft()

        rem = []
        for wall in walls:
            for x, car in enumerate(cars):
                if len(cars) > 2 and wall.collide(cars[1]):
                    running = False
                    break
                elif wall.collide(car):
                    cars.pop(x)

                if not wall.passed and wall.y > car.y:
                    wall.passed = True
                    addWall = True

            if wall.y + wall.RIGHT_WALL.get_height() > GAME_HEIGHT:
                rem.append(wall)
            wall.move()

            if (len(cars) >= 2) and wall.collide(cars[1]):
                cars.remove(cars[1])
                running = False
                break

        if addWall:
            score += 1
            if animationSpeed < 30:
                if score % 5 == 0:
                    animationSpeed += 1
                    bg.animationSpeed += 1
                    for car in cars:
                        if car.xVel < 50:
                            car.xVel += 2
            walls.append(Wall(0, animationSpeed))
            addWall = False

        for r in rem:
            walls.remove(r)

        if score == 500:
            for car in cars:
                car.xVel = 0

        if len(cars) < 2 and MODE == 1:
            break

        drawGame(GAME_WINDOW, bg, walls, score, cars)

def setMode(mode, value):
    global MODE
    MODE = value

def makeMenu(gameWindow, gameWidth, gameHeight):
    font = pygame_menu.font.FONT_NEVIS
    fontSize = 35
    fontColor = (0, 0, 0)
    shadowColor = (255, 255, 0)
    selectionColor = (0, 0, 255)

    menu = pygame_menu.Menu(gameHeight, gameWidth, 'Reinforcement learning Car Game', onclose=pygame_menu.events.EXIT,
                            theme=pygame_menu.themes.THEME_BLUE, mouse_visible=False, mouse_enabled=False)
    menu.add_label("Look how AI learns the game or just try yourself vs bot!", font_color=fontColor,
                   shadow=True, shadow_color=shadowColor, font_name=font,
                   font_size=fontSize)
    menu.add_vertical_margin(100)
    menu.add_selector('Mode: ', [('AI Game', 0), ('Self vs AI', 1)], onchange=setMode,
                      font_name=font, font_size=fontSize,
                      font_color=fontColor, shadow=True, shadow_color=shadowColor, selection_color=selectionColor)
    menu.add_button('Play!', gameLoop, font_name=font, font_size=fontSize,
                    font_color=fontColor, shadow=True, shadow_color=shadowColor, selection_color=selectionColor)
    menu.add_button('Look how AI learns the game!', runAILearning,  font_name=font, font_size=fontSize,
                    font_color=fontColor, shadow=True, shadow_color=shadowColor, selection_color=selectionColor)
    menu.add_button('Quit!', pygame_menu.events.EXIT,  font_name=font, font_size=fontSize,
                    font_color=fontColor, shadow=True, shadow_color=shadowColor, selection_color=selectionColor)
    menu.mainloop(gameWindow)

def main(gameWindow, gameWidth, gameHeight):
    makeMenu(gameWindow, gameWidth, gameHeight)

if __name__ == '__main__':
    main(GAME_WINDOW, GAME_WIDTH, GAME_HEIGHT)


# -*- coding: utf-8 -*-
"""
Created on Tue Nov 29 10:31:08 2016

@author: DAKHMETO
TC 11 syslog parser to investigate 2T Login perfomance problem
"""
import glob
import re
import xlsxwriter
import datetime
from pytz import timezone
import pytz

#RFOLDER_PATH = "c:\\_WORK\\PBI\\July2017\\FNA_2T\\"
#RFOLDER_PATH = "c:\\_WORK\\2018_Metrics\\Houston_We_Have_A_Problem\\2T_Login_FNA_22Dec_Upward_Shift\\Dec_2017\\"
RFOLDER_PATH = "c:\\_WORK\\2018_Metrics\\Houston_We_Have_A_Problem\\2T_Login_FNA_22Dec_Upward_Shift\\Jan_09\\10AM\\temp\\4parser\\"
WFILE_PATH = RFOLDER_PATH

#RFOLDER_PATH = "c:\\_WORK\\PBI\\2T_Login_low_perf\\syslogs\\Login0216\\"
#WFILE_PATH = "c:\\_WORK\\PBI\\2T_Login_low_perf\\syslogs\\Login0216\\"

#RFOLDER_PATH = "c:\\_WORK\\PBI\\2T_Login_low_perf\\FCO\\FCO_Syslogs\\"
#WFILE_PATH = "c:\\_WORK\\PBI\\2T_Login_low_perf\\FCO\\FCO_Syslogs\\"

THRESHOLD_DBCON = datetime.timedelta(seconds=3)
THRESHOLD_SCHLD1 = datetime.timedelta(seconds=3)
THRESHOLD_TRNSV = datetime.timedelta(seconds=5)
THRESHOLD_TCHTH = datetime.timedelta(seconds=7)
THRESHOLD_LIBTCCORE = datetime.timedelta(seconds=10)
THRESHOLD_SCHLD2 = datetime.timedelta(seconds=10)
THRESHOLD_CCAS = datetime.timedelta(seconds=5)
THRESHOLD_CHKLIC = datetime.timedelta(seconds=8)
THRESHOLD_LIBSUB = datetime.timedelta(seconds=10)
THRESHOLD_STRT = datetime.timedelta(seconds=10)
THRESHOLD_IMANV = datetime.timedelta(seconds=10)

def time2ets (UTCeventdatetime):
    UTCeventdatetime=(pytz.utc).localize(UTCeventdatetime)
    print ("  func: in UTC= ",end="")
    print(UTCeventdatetime)
    #FNA US/Eastern
    ETSeventdatetime=UTCeventdatetime.astimezone(timezone('US/Eastern'))
    #FSA America/Bahia
    #ETSeventdatetime=UTCeventdatetime.astimezone(timezone('America/Bahia'))
    #FCO China/Beijing
    #ETSeventdatetime=UTCeventdatetime.astimezone(timezone('Asia/Shanghai'))
    #FOE Europe/Budapest
    #ETSeventdatetime=UTCeventdatetime.astimezone(timezone('Europe/Budapest'))
    #IND Asia/Calcutta
    #ETSeventdatetime=UTCeventdatetime.astimezone(timezone('Asia/Calcutta'))
    print ("  func: in ETS= ",end="")
    print(ETSeventdatetime)
    format="%Y-%m-%d %H:%M:%S"
    #change format after tz conversion
    strETSeventdatetime=ETSeventdatetime.strftime(format)
    #convert again to datetime object
    ETSeventdatetime=datetime.datetime.strptime(strETSeventdatetime, format)
    return ETSeventdatetime

def duration (datetimeafter, datetimebefore):
    datetimeafter=datetimeafter.replace(microsecond=0)
    datetimebefore=datetimebefore.replace(microsecond=0)
    duration = datetimeafter - datetimebefore
    print ("  func: duration= ",end="")
    print(duration)
    #strduration=str(duration)
    return duration

def check_duration(duration, treshhold):
    alarm=False
    if duration > treshhold:
        alarm=True
        print ("Long duration detected!!!")
    return alarm

print("START")
#print (os.listdir(RFOLDER_PATH))
print (RFOLDER_PATH + "*.syslog")
file_list = glob.glob(RFOLDER_PATH + "*.syslog")
file_list.reverse()
print (file_list)

# Create an new Excel file and add a worksheet.
workbook = xlsxwriter.Workbook(WFILE_PATH + datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S").replace(":","_") + '_results.xlsx')
worksheet = workbook.add_worksheet()
# Add a bold format to use to highlight cells.
bold = workbook.add_format({'bold': True, 'bg_color': 'silver'})
red = workbook.add_format({'bold': True, 'font_color': 'red', 'bg_color': 'yellow'})
link_format = workbook.add_format({'color': 'blue', 'underline': 1})

# Widen the column to make the text clearer.
worksheet.set_column('A:A', len('Syslog Creation Date  '))
# Write captions text.
worksheet.write('A1', 'Syslog Creation Date', bold)

# Widen the column to make the text clearer.
worksheet.set_column('B:B', len('Connection to DB   '))
# Write captions text.
worksheet.write('B1', 'Connection to DB', bold)

# Widen the column to make the text clearer.
worksheet.set_column('C:C', len('Con2DBduration '))
# Write captions text.
worksheet.write('C1', 'Con2DBduration', bold)

# Widen the column to make the text clearer.
worksheet.set_column('D:D', len('SchemaLoaded1     '))
# Write captions text.
worksheet.write('D1', 'SchemaLoaded1', bold)

# Widen the column to make the text clearer.
worksheet.set_column('E:E', len('SchLd1duration'))
# Write captions text.
worksheet.write('E1', 'SchLd1duration', bold)

# Widen the column to make the text clearer.
worksheet.set_column('F:F', len('Transient Volume     '))
# Write captions text.
worksheet.write('F1', 'Transient Volume', bold)

# Widen the column to make the text clearer.
worksheet.set_column('G:G', len('TrnsVolduration'))
# Write captions text.
worksheet.write('G1', 'TrnsVolduration', bold)

# Widen the column to make the text clearer.
worksheet.set_column('H:H', len('00001 - Service Request:'))
# Write captions text.
worksheet.write('H1', '00001 - Service Request:', bold)

# Widen the column to make the text clearer.
worksheet.set_column('I:I', len('DurBWNTrnsV&1stRequest'))
# Write captions text.
worksheet.write('I1', 'DurBWNTrnsV&1stRequest', bold)

# Widen the column to make the text clearer.
worksheet.set_column('J:J', len('libtcsoacore.dll     '))
# Write captions text.
worksheet.write('J1', 'libSessionVersion_register_callbacks', bold)

# Widen the column to make the text clearer.
worksheet.set_column('K:K', len('DurBWN1stRequest&libSessionVersion_register_callbacks'))
# Write captions text.
worksheet.write('K1', 'DurBWN1stRequest&libSessionVersion_register_callbacks', bold)

# Widen the column to make the text clearer.
worksheet.set_column('L:L', len('POM_login     '))
# Write captions text.
worksheet.write('L1', 'POM_login', bold)

# Widen the column to make the text clearer.
worksheet.set_column('M:M', len('CCAS=POM_login - libSessionVersion_register_callbacks'))
# Write captions text.
worksheet.write('M1', 'CCAS=POM_login-libSessionVersion_register_callbacks', bold)

# Widen the column to make the text clearer.
worksheet.set_column('N:N', len('check_license    '))
# Write captions text.
worksheet.write('N1', 'check_license', bold)

# Widen the column to make the text clearer.
worksheet.set_column('O:O', len('check_license-POM_login'))
# Write captions text.
worksheet.write('O1', 'check_license-POM_login', bold)

# Widen the column to make the text clearer.
worksheet.set_column('P:P', len('MultiFieldKeyAttrsMap    '))
# Write captions text.
worksheet.write('P1', 'MultiFieldKeyAttrsMap', bold)

# Widen the column to make the text clearer.
worksheet.set_column('Q:Q', len('b/n chklic and MultiFieldKeyAttrsMap'))
# Write captions text.
worksheet.write('Q1', 'b/n chklic and MultiFieldKeyAttrsMap', bold)

# Widen the column to make the text clearer.
worksheet.set_column('R:R', len('LOV-Master     '))
# Write captions text.
worksheet.write('R1', 'LOV-Master', bold)

# Widen the column to make the text clearer.
worksheet.set_column('S:S', len('DurBWNLOV-Master&MFK'))
#Write captions text.
worksheet.write('S1', 'DurBWNLOV-Master&MFK', bold)

# Widen the column to make the text clearer.
worksheet.set_column('T:T', len('Started.    '))
# Write captions text.
worksheet.write('T1', 'Started.', bold)

# Widen the column to make the text clearer.
worksheet.set_column('U:U', len('b/n LOV-Master and Started.'))
# Write captions text.
# Library is delay loaded
worksheet.write('U1', 'b/n LOV-Master andt Started.', bold)

# Widen the column to make the text clearer.
worksheet.set_column('V:V', len('ImanVolumeImpl::    '))
# Write captions text.
worksheet.write('V1', 'ImanVolumeImpl::', bold)

# Widen the column to make the text clearer.
worksheet.set_column('W:W', len('b/n Started. and ImanVolumeImpl'))
# Write captions text.
# Library is delay loaded
worksheet.write('W1', 'b/n Started. and ImanVolumeImpl', bold)

# Widen the column to make the text clearer.
worksheet.set_column('X:X', len('library libeint    '))
# Write captions text.
worksheet.write('X1', 'library libeint', bold)

# Widen the column to make the text clearer.
worksheet.set_column('Y:Y', len('Duration b/n ImanVolumeImpl and library_libeint'))
# Write captions text.
# Library is delay loaded
worksheet.write('Y1', 'Duration b/n ImanVolumeImpl and library_libeint', bold)

# Widen the column to make the text clearer.
worksheet.set_column('Z:Z', len('EndOfSession    '))
# Write captions text.
worksheet.write('Z1', 'EndOfSession', bold)

# Widen the column to make the text clearer.
worksheet.set_column('AA:AA', len('Duration b/n syslogcreation and endofsession'))
# Write captions text.
# Library is delay loaded
worksheet.write('AA1', 'Duration b/n syslogcreation and endofsession', bold)

worksheetnew = workbook.add_worksheet()
# Create a new Chart object.
chart = workbook.add_chart({'type': 'column'})

re1='.*?'	# Non-greedy match on filler
re2='((?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday|Tues|Thur|Thurs|Sun|Mon|Tue|Wed|Thu|Fri|Sat))'	# Day Of Week 1
re3='(\\s+)'	# White Space 1
re4='((?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Sept|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?))'	# Month 1
re5='(\\s+)'	# White Space 2
re6='((?:(?:[0-2]?\\d{1})|(?:[3][01]{1})))(?![\\d])'	# Day 1
re7='(\\s+)'	# White Space 3
re8='((?:(?:[0-1][0-9])|(?:[2][0-3])|(?:[0-9])):(?:[0-5][0-9])(?::[0-5][0-9])?(?:\\s?(?:am|AM|pm|PM))?)'	# HourMinuteSec 1
re9='(\\s+)'	# White Space 4
re10='((?:(?:[1]{1}\\d{1}\\d{1}\\d{1})|(?:[2]{1}\\d{3})))(?![\\d])'	# Year 1
rg0 = re.compile(re1+re2+re3+re4+re5+re6+re7+re8+re9+re10,re.IGNORECASE|re.DOTALL)

rre1='.*?'	# Non-greedy match on filler
rre2='((?:(?:[1]{1}\\d{1}\\d{1}\\d{1})|(?:[2]{1}\\d{3}))[-:\\/.](?:[0]?[1-9]|[1][012])[-:\\/.](?:(?:[0-2]?\\d{1})|(?:[3][01]{1})))(?![\\d])'	# YYYYMMDD 1
rre3='(.)'	# Any Single Character 1
rre4='((?:(?:[0-1][0-9])|(?:[2][0-3])|(?:[0-9])):(?:[0-5][0-9])(?::[0-5][0-9])?(?:\\s?(?:am|AM|pm|PM))?)'	# HourMinuteSec 1
rg = re.compile(rre1+rre2+rre3+rre4,re.IGNORECASE|re.DOTALL)

file_counter = 0

gap = 1
for file in file_list:
    file_counter +=1
    line_counter = 0
    gap +=14
    found_flag = 0
    print (str(file_counter) +" "+ file)
    chartdata = []
    with open (file, "r") as syslog:
        for line in syslog:
            line_counter +=1
            if (re.search('system log created', line)):
               m = rg0.search(line)
               if m:
                    dayofweek1=m.group(1)
                    ws1=m.group(2)
                    month1=m.group(3)
                    ws2=m.group(4)
                    day1=m.group(5)
                    ws3=m.group(6)
                    time1=m.group(7)
                    ws4=m.group(8)
                    year1=m.group(9)
                    content = dayofweek1+ws1+month1+ws2+day1+ws3+time1+ws4+year1
                    print (content)
                    format='%a %b %d %H:%M:%S %Y'
                    syscrdatetime=datetime.datetime.strptime(content, format)
                    print(syscrdatetime)
                    #change dateformat
                    format="%Y-%m-%d %H:%M:%S"
                    #syscrdatetime=syscrdatetime.strftime(format)
                    #syscrdatetime = time.strptime(content, '%a %b %d %H:%M:%S %Y')
                    syscrtime = syscrdatetime.time()
                    print ("ETS syslog creation: ",end="")
                    print(syscrdatetime)
                    #print (syscrtime)
                    # Text with formatting.
                    cell = 'A'+ str(file_counter + 1)
                    #worksheet.write(cell, content+"  "+ file)
                    content = content+"  "+ file
                    worksheet.write_url(cell, file, link_format, content)
                    print(cell + " COMPLETED")
            if (re.search('Database Installation Identifier:', line)):
                m = rg.search(line)
                if m:
                    yyyymmdd1=m.group(1)
                    c1=m.group(2)
                    time1=m.group(3)
                    print(yyyymmdd1)
                    print(yyyymmdd1[0:4])
                    print(yyyymmdd1[5:7])
                    print(yyyymmdd1[8:10])
                    print(time1)
                    #content=yyyymmdd1[5:10]+"/"+yyyymmdd1[0:4]
                    content=yyyymmdd1[0:4]+"-"+yyyymmdd1[5:7]+"-"+yyyymmdd1[8:10]+" "+time1
                    format="%Y-%m-%d %H:%M:%S"
                    content=content.strip()
                    print('-=DEBUG=-')
                    print(content)
                    # UTC time from syslog
                    dbcondatetime=datetime.datetime.strptime(content, format)
                    print ("UTC db connect: ",end="")
                    print(dbcondatetime)
                    # Convert to ETS timezone based on syslog creation
                    dbcondatetime=time2ets(dbcondatetime)
                    print (dbcondatetime)
                    content=dbcondatetime.strftime(format)+"   line#: " + str(line_counter)
                    print(content)
                    # Text with formatting.
                    cell = 'B'+ str(file_counter + 1)
                    worksheet.write(cell, content)
                    content=str(duration(dbcondatetime,syscrdatetime))
                    # Text with formatting.
                    cell = 'C'+ str(file_counter + 1)
                    if check_duration(duration(dbcondatetime,syscrdatetime),THRESHOLD_DBCON):
                        worksheet.write(cell, content, red)
                    else: worksheet.write(cell, content)
                    chartdata.append(content)
                    print(cell + " COMPLETED")
            if (re.search('NoId - Schema Loaded.', line)):
                m = rg.search(line)
                if m:
                    yyyymmdd1=m.group(1)
                    c1=m.group(2)
                    time1=m.group(3)
                    #content=yyyymmdd1[5:10]+"/"+yyyymmdd1[0:4]
                    content=yyyymmdd1[0:4]+"-"+yyyymmdd1[5:7]+"-"+yyyymmdd1[8:10]+" "+time1
                    format="%Y-%m-%d %H:%M:%S"
                    content=content.strip()
                    print(content)
                    # UTC time from syslog
                    schl1datetime=datetime.datetime.strptime(content, format)
                    print ("UTC schema loaded1: ",end="")
                    print(schl1datetime)
                    # Convert to ETS timezone based on syslog creation
                    schl1datetime=time2ets(schl1datetime)
                    print (schl1datetime)
                    content=schl1datetime.strftime(format)+"   line#: " + str(line_counter)
                    print(content)
                    # Text with formatting.
                    cell = 'D'+ str(file_counter + 1)
                    worksheet.write(cell, content)
                    try:
                        content=str(duration(schl1datetime, dbcondatetime))
                        # Text with formatting.
                        cell = 'E'+ str(file_counter + 1)
                        if check_duration(duration(schl1datetime, dbcondatetime),THRESHOLD_SCHLD1):
                            worksheet.write(cell, content, red)
                        else: worksheet.write(cell, content)
                        chartdata.append(content)
                        print(cell + " COMPLETED")
                    except Exception:
                        pass
            if (re.search('The Transient Volume Root Directory at', line)):
                m = rg.search(line)
                if m:
                    yyyymmdd1=m.group(1)
                    c1=m.group(2)
                    time1=m.group(3)
                    #content=yyyymmdd1[5:10]+"/"+yyyymmdd1[0:4]
                    content=yyyymmdd1[0:4]+"-"+yyyymmdd1[5:7]+"-"+yyyymmdd1[8:10]+" "+time1
                    format="%Y-%m-%d %H:%M:%S"
                    content=content.strip()
                    print(content)
                    # UTC time from syslog
                    trnsvoldatetime=datetime.datetime.strptime(content, format)
                    print ("UTC Transient Vol: ",end="")
                    print(trnsvoldatetime)
                    # Convert to ETS timezone based on syslog creation
                    trnsvoldatetime=time2ets(trnsvoldatetime)
                    print (trnsvoldatetime)
                    content=trnsvoldatetime.strftime(format) +"   line#: " + str(line_counter)
                    print(content)
                    # Text with formatting.
                    cell = 'F'+ str(file_counter + 1)
                    worksheet.write(cell, content)
                    content=str(duration(trnsvoldatetime,schl1datetime))
                    # Text with formatting.
                    cell = 'G'+ str(file_counter + 1)
                    if check_duration(duration(trnsvoldatetime,schl1datetime),THRESHOLD_TRNSV):
                        worksheet.write(cell, content, red)
                    else: worksheet.write(cell, content)
                    print(cell + " COMPLETED")
            if (re.search('00001 - Service Request:', line)): # 00001 - Service Request:  Core-2011-06-Session:login
                m = rg.search(line)
                if m:
                    yyyymmdd1=m.group(1)
                    c1=m.group(2)
                    time1=m.group(3)
                    #content=yyyymmdd1[5:10]+"/"+yyyymmdd1[0:4]
                    content=yyyymmdd1[0:4]+"-"+yyyymmdd1[5:7]+"-"+yyyymmdd1[8:10]+" "+time1
                    format="%Y-%m-%d %H:%M:%S"
                    content=content.strip()
                    print(content)
                    # UTC time from syslog
                    hthmondatetime=datetime.datetime.strptime(content, format)
                    print ("UTC 00001 - Service Request: ",end="")
                    print(hthmondatetime)
                    # Convert to ETS timezone based on syslog creation
                    hthmondatetime=time2ets(hthmondatetime)
                    print (hthmondatetime)
                    content=hthmondatetime.strftime(format) +"   line#: " + str(line_counter)
                    print(content)
                    # Text with formatting.
                    cell = 'H'+ str(file_counter + 1)
                    worksheet.write(cell, content)
                    content=str(duration(hthmondatetime,trnsvoldatetime))
                    # Text with formatting.
                    cell = 'I'+ str(file_counter + 1)
                    if check_duration(duration(hthmondatetime,trnsvoldatetime),THRESHOLD_TCHTH):
                        worksheet.write(cell, content, red)
                    else: worksheet.write(cell, content)
                    print(cell + " COMPLETED")
            if (re.search('libSessionVersion_register_callbacks', line)): #to estimate CCAS time
                m = rg.search(line)
                if m:
                    yyyymmdd1=m.group(1)
                    c1=m.group(2)
                    time1=m.group(3)
                    #content=yyyymmdd1[5:10]+"/"+yyyymmdd1[0:4]
                    content=yyyymmdd1[0:4]+"-"+yyyymmdd1[5:7]+"-"+yyyymmdd1[8:10]+" "+time1
                    format="%Y-%m-%d %H:%M:%S"
                    content=content.strip()
                    print(content)
                    # UTC time from syslog
                    libtcsoacoredatetime=datetime.datetime.strptime(content, format)
                    print ("UTC error about libSessionVersion_register_callbacks: ",end="")
                    print(libtcsoacoredatetime)
                    # Convert to ETS timezone based on syslog creation
                    libtcsoacoredatetime=time2ets(libtcsoacoredatetime)
                    print (libtcsoacoredatetime)
                    content=libtcsoacoredatetime.strftime(format) + "   line#: " + str(line_counter)
                    print(content)
                    # Text with formatting.
                    cell = 'J'+ str(file_counter + 1)
                    worksheet.write(cell, content)
                    try:
                        content=str(duration(libtcsoacoredatetime,hthmondatetime))
                        # Text with formatting.
                        cell = 'K'+ str(file_counter + 1)
                        if check_duration(duration(libtcsoacoredatetime,hthmondatetime),THRESHOLD_LIBTCCORE):
                            worksheet.write(cell, content, red)
                        else: worksheet.write(cell, content)
                        print(cell + " COMPLETED")
                    except Exception:
                        pass
            if (re.search('POM_login:', line)):
                m = rg.search(line)
                if m:
                    yyyymmdd1=m.group(1)
                    c1=m.group(2)
                    time1=m.group(3)
                    #content=yyyymmdd1[5:10]+"/"+yyyymmdd1[0:4]
                    content=yyyymmdd1[0:4]+"-"+yyyymmdd1[5:7]+"-"+yyyymmdd1[8:10]+" "+time1
                    format="%Y-%m-%d %H:%M:%S"
                    content=content.strip()
                    print(content)
                    # UTC time from syslog
                    pomlgndatetime=datetime.datetime.strptime(content, format)
                    print ("UTC POM_login: ",end="")
                    print(pomlgndatetime)
                    # Convert to ETS timezone based on syslog creation
                    pomlgndatetime=time2ets(pomlgndatetime)
                    print (pomlgndatetime)
                    content=pomlgndatetime.strftime(format) +"   line#: " + str(line_counter)
                    print(content)
                    # Text with formatting.
                    cell = 'L'+ str(file_counter + 1)
                    worksheet.write(cell, content)
                    try:
                        content=str(duration(pomlgndatetime,libtcsoacoredatetime))
                        # Text with formatting.
                        cell = 'M'+ str(file_counter + 1)
                        if check_duration(duration(pomlgndatetime,libtcsoacoredatetime),THRESHOLD_CCAS):
                            worksheet.write(cell, content, red)
                        else: worksheet.write(cell, content)
                        chartdata.append(content)
                        print(cell + " COMPLETED")
                    except Exception:
                        pass
            if (re.search('library libdocmgt', line)): #to estimate license check
                m = rg.search(line)
                if m:
                    yyyymmdd1=m.group(1)
                    c1=m.group(2)
                    time1=m.group(3)
                    #content=yyyymmdd1[5:10]+"/"+yyyymmdd1[0:4]
                    content=yyyymmdd1[0:4]+"-"+yyyymmdd1[5:7]+"-"+yyyymmdd1[8:10]+" "+time1
                    format="%Y-%m-%d %H:%M:%S"
                    content=content.strip()
                    print(content)
                    # UTC time from syslog
                    chklicdatetime=datetime.datetime.strptime(content, format)
                    print ("UTC check_license, library libdocmgt is first event after lic info: ",end="")
                    print(chklicdatetime)
                    # Convert to ETS timezone based on syslog creation
                    chklicdatetime=time2ets(chklicdatetime)
                    print (chklicdatetime)
                    content=chklicdatetime.strftime(format) +"   line#: " + str(line_counter)
                    print(content)
                    # Text with formatting.
                    cell = 'N'+ str(file_counter + 1)
                    worksheet.write(cell, content)
                    content=str(duration(chklicdatetime,pomlgndatetime))
                    # Text with formatting.
                    cell = 'O'+ str(file_counter + 1)
                    if check_duration(duration(chklicdatetime,pomlgndatetime),THRESHOLD_CHKLIC):
                        worksheet.write(cell, content, red)
                    else: worksheet.write(cell, content)
                    print(cell + " COMPLETED")
            if (re.search('MultiFieldKeyAttrsMap', line)):
                m = rg.search(line)
                if m:
                    yyyymmdd1=m.group(1)
                    c1=m.group(2)
                    time1=m.group(3)
                    #content=yyyymmdd1[5:10]+"/"+yyyymmdd1[0:4]
                    content=yyyymmdd1[0:4]+"-"+yyyymmdd1[5:7]+"-"+yyyymmdd1[8:10]+" "+time1
                    format="%Y-%m-%d %H:%M:%S"
                    content=content.strip()
                    print(content)
                    # UTC time from syslog
                    libsubdatetime=datetime.datetime.strptime(content, format)
                    print ("UTC MultiFieldKeyAttrsMap: ",end="")
                    print(libsubdatetime)
                    # Convert to ETS timezone based on syslog creation
                    libsubdatetime=time2ets(libsubdatetime)
                    print (libsubdatetime)
                    content=libsubdatetime.strftime(format) +"   line#: " + str(line_counter)
                    print(content)
                    # Text with formatting.
                    cell = 'P'+ str(file_counter + 1)
                    worksheet.write(cell, content)
                    try:
                        content=str(duration(libsubdatetime,chklicdatetime))
                        # Text with formatting.
                        cell = 'Q'+ str(file_counter + 1)
                        if check_duration(duration(libsubdatetime,chklicdatetime),THRESHOLD_LIBSUB):
                            worksheet.write(cell, content, red)
                        else: worksheet.write(cell, content)
                        print(cell + " COMPLETED")
                    except Exception:
                        pass
            if (re.search('LOV-Master', line)):
                m = rg.search(line)
                if m:
                    yyyymmdd1=m.group(1)
                    c1=m.group(2)
                    time1=m.group(3)
                    #content=yyyymmdd1[5:10]+"/"+yyyymmdd1[0:4]
                    content=yyyymmdd1[0:4]+"-"+yyyymmdd1[5:7]+"-"+yyyymmdd1[8:10]+" "+time1
                    format="%Y-%m-%d %H:%M:%S"
                    content=content.strip()
                    print(content)
                    # UTC time from syslog
                    schl2datetime=datetime.datetime.strptime(content, format)
                    print ("UTC LOV-Master: ",end="")
                    print(schl2datetime)
                    # Convert to ETS timezone based on syslog creation
                    schl2datetime=time2ets(schl2datetime)
                    print (schl2datetime)
                    content=schl2datetime.strftime(format) +"   line#: " + str(line_counter)
                    print(content)
                    # Text with formatting.
                    cell = 'R'+ str(file_counter + 1)
                    worksheet.write(cell, content)
                    try:
                        content=str(duration(schl2datetime,libsubdatetime))
                        # Text with formatting.
                        cell = 'S'+ str(file_counter + 1)
                        if check_duration(duration(schl2datetime,libsubdatetime),THRESHOLD_SCHLD2):
                            worksheet.write(cell, content, red)
                        else: worksheet.write(cell, content)
                        #chartdata.append(content)
                        print(cell + " COMPLETED")
                    except Exception:
                        pass
            if (re.search('Started. - Teamcenter.CoreModelGeneral', line)):
                m = rg.search(line)
                if m:
                    yyyymmdd1=m.group(1)
                    c1=m.group(2)
                    time1=m.group(3)
                    #content=yyyymmdd1[5:10]+"/"+yyyymmdd1[0:4]
                    content=yyyymmdd1[0:4]+"-"+yyyymmdd1[5:7]+"-"+yyyymmdd1[8:10]+" "+time1
                    format="%Y-%m-%d %H:%M:%S"
                    content=content.strip()
                    print(content)
                    # UTC time from syslog
                    starteddatetime=datetime.datetime.strptime(content, format)
                    print ("UTC Started.: ",end="")
                    print(starteddatetime)
                    # Convert to ETS timezone based on syslog creation
                    starteddatetime=time2ets(starteddatetime)
                    print (starteddatetime)
                    content=starteddatetime.strftime(format) +"   line#: " + str(line_counter)
                    print(content)
                    # Text with formatting.
                    cell = 'T'+ str(file_counter + 1)
                    worksheet.write(cell, content)
                    try:
                        content=str(duration(starteddatetime,schl2datetime))
                        # Text with formatting.
                        cell = 'U'+ str(file_counter + 1)
                        worksheet.write(cell, content)
                        print(cell + " COMPLETED")
                    except Exception:
                        pass
            if (re.search('ImanVolumeImpl::', line)):
                if found_flag==0:
                    m = rg.search(line)
                    if m:
                        #To catch only first occurrence
                        found_flag=1
                        yyyymmdd1=m.group(1)
                        c1=m.group(2)
                        time1=m.group(3)
                        #content=yyyymmdd1[5:10]+"/"+yyyymmdd1[0:4]
                        content=yyyymmdd1[0:4]+"-"+yyyymmdd1[5:7]+"-"+yyyymmdd1[8:10]+" "+time1
                        format="%Y-%m-%d %H:%M:%S"
                        content=content.strip()
                        print(content)
                        # UTC time from syslog
                        imanvoldatetime=datetime.datetime.strptime(content, format)
                        print ("UTC ImanVolumeImpl: ",end="")
                        print(imanvoldatetime)
                        # Convert to ETS timezone based on syslog creation
                        imanvoldatetime=time2ets(imanvoldatetime)
                        print (imanvoldatetime)
                        content=imanvoldatetime.strftime(format) +"   line#: " + str(line_counter)
                        print(content)
                        # Text with formatting.
                        cell = 'V'+ str(file_counter + 1)
                        worksheet.write(cell, content)
                        content=str(duration(imanvoldatetime,starteddatetime))
                        # Text with formatting.
                        cell = 'W'+ str(file_counter + 1)
                        if check_duration(duration(imanvoldatetime,starteddatetime),THRESHOLD_IMANV):
                            worksheet.write(cell, content, red)
                        else: worksheet.write(cell, content)
                        print(cell + " COMPLETED")
            if (re.search('library libeint is delay loaded', line)):
               print(line)
               m = rg.search(line)
               if m:
                    yyyymmdd1=m.group(1)
                    c1=m.group(2)
                    time1=m.group(3)
                    #content=yyyymmdd1[5:10]+"/"+yyyymmdd1[0:4]
                    content=yyyymmdd1[0:4]+"-"+yyyymmdd1[5:7]+"-"+yyyymmdd1[8:10]+" "+time1
                    format="%Y-%m-%d %H:%M:%S"
                    content=content.strip()
                    print(content)
                    # UTC time from syslog
                    libeintdatetime=datetime.datetime.strptime(content, format)
                    print ("UTC Started.: ",end="")
                    print(libeintdatetime)
                    # Convert to ETS timezone based on syslog creation
                    libeintdatetime=time2ets(libeintdatetime)
                    print (libeintdatetime)
                    content=libeintdatetime.strftime(format) +"   line#: " + str(line_counter)
                    print(content)
                    # Text with formatting.
                    cell = 'X'+ str(file_counter + 1)
                    worksheet.write(cell, content)
                    try:
                        content=str(duration(libeintdatetime,imanvoldatetime))
                        # Text with formatting.
                        cell = 'Y'+ str(file_counter + 1)
                        worksheet.write(cell, content)
                        print(cell + " COMPLETED")
                    except Exception:
                        pass
            if (re.search('@@@', line)):#TC End of Session
               print(line)
               m = rg0.search(line)
               if m:
                    dayofweek1=m.group(1)
                    ws1=m.group(2)
                    month1=m.group(3)
                    ws2=m.group(4)
                    day1=m.group(5)
                    ws3=m.group(6)
                    time1=m.group(7)
                    ws4=m.group(8)
                    year1=m.group(9)
                    content = dayofweek1+ws1+month1+ws2+day1+ws3+time1+ws4+year1
                    print (content)
                    format='%a %b %d %H:%M:%S %Y'
                    endofsessiontime=datetime.datetime.strptime(content, format)
                    print(endofsessiontime)
                    #change dateformat
                    format="%Y-%m-%d %H:%M:%S"
                    print ("ETS syslog creation: ",end="")
                    print(endofsessiontime)
                    # Text with formatting.
                    cell = 'Z'+ str(file_counter + 1)
                    worksheet.write(cell, content)
                    content=str(duration(endofsessiontime,syscrdatetime))
                    # Text with formatting.
                    cell = 'AA'+ str(file_counter + 1)
                    worksheet.write(cell, content)
                    print(cell + " COMPLETED")

    #chart.add_series({'values': '=Sheet1!$B$2'})
    # Insert the chart into the worksheet.
    #place = 'A' + str(gap)
    #worksheetnew.insert_chart(place, chart)

workbook.close()
print("THIS IS THE END")

'''def time2ets (syscrdatetime,eventdatetime):
    delta = eventdatetime - syscrdatetime
    datetime.timedelta(0, 8, 562000)
    divmod(delta.days * 86400 + delta.seconds, 60)
    eventdatetime = eventdatetime - delta
    print ("func: UTC-ETS= ",end="")
    print (delta)
    print ("func: in ETS= ",end="")
    print(eventdatetime),
    return eventdatetime'''

# Write some numbers, with row/column notation.
#worksheet.write(2, 0, 123)
#worksheet.write(3, 0, 123.456)
# Insert an image.
#worksheet.insert_image('B5', 'logo.png')


from typing import List
from ninja.router import Router
from ninja import Schema
from comic.models import Comic, MyList
from rest.schemes.comics import MyListSchema

router = Router()

class ComicSlugSchema(Schema):
    class Config:
        title = "Modelo Mangá com o campo slug"
    slug: str = "example: dsadasd"

@router.post("", response=MyListSchema)
def add_comic_the_list(request, payload: ComicSlugSchema):
    comic = Comic.objects.filter(slug=payload.slug).first()

    mylist = MyList.objects.filter(user=request.client).first()

    if mylist:
        if not mylist.comics.contains(comic):
            mylist.comics.add(comic)
    else:
        mylist = MyList()
        mylist.user = request.client
        mylist.save()
        mylist.comics.add(comic)
    mylist.save()
    comics = [{
        "name": comic.name,
        "description": comic.description,
        "type": comic.type,
        "category": comic.category.type,
        "slug": comic.slug,
        "old_min": comic.old_min,
    } for comic in mylist.comics.all()]

    return {
        "id": mylist.id,
        "comics": comics,
        "user": mylist.user.id
    }

@router.get("", response=MyListSchema)
def get_my_list(request):
    mylist = MyList.objects.filter(user=request.client).first()

    if mylist:
        comics = [{
            "name": comic.name,
            "description": comic.description,
            "type": comic.type,
            "slug": comic.slug,
            "image": comic.image_front_book.url,
            "category": comic.category.type,
            "old_min": comic.old_min,
        } for comic in mylist.comics.all()]

        print(comics)
        return {
            "id": mylist.id,
            "comics": comics,
            "user": mylist.user.id
        }
    return None

@router.post("/delete", response=MyListSchema)
def remove_comic_of_the_list(request, payload: ComicSlugSchema):
    comic = Comic.objects.filter(slug=payload.slug).first()

    mylist = MyList.objects.filter(user=request.client).first()

    if mylist.comics.count() == 1:
        mylist.comics.clear()
    else:
        if mylist.comics.contains(comic):
            mylist.comics.remove(comic)

    mylist.save()

    comics = [{
            "name": comic.name,
            "description": comic.description,
            "slug": comic.slug,
            "type": comic.type,
            "image": comic.image_front_book.url,
            "slug": comic.slug,
            "category": comic.category.type,
            "old_min": comic.old_min,
    } for comic in mylist.comics.all()]

    return {
        "id": mylist.id,
        "comics": comics,
        "user": mylist.user.id
    }


import pygame
import sys
import time
import random
from pygame.locals import *

pygame.init()
mainClock = pygame.time.Clock()
all_fonts = pygame.font.get_fonts()
basicFont = pygame.font.SysFont('arial', 20)

W = 550
H = 550

Surface = pygame.display.set_mode((W,H), 0, 32)
pygame.display.set_caption('Template')

BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
RED = (255, 0, 0)
YELLOW = (255, 255, 0)

def text_print(text,color1,color2,left,top,Font=basicFont):
    text = Font.render(text,True,color1,color2)
    text_rect = text.get_rect()
    text_rect.top = top
    text_rect.left = left
    Surface.blit(text, text_rect)

class Tile(object):
    def __init__(self,left,top,column,row,sur=0,width=40,height=40,color=WHITE):
        self.left = left
        self.top = top
        self.width = width
        self.height = height
        self.color = color
        self.rect = pygame.Rect(left,top,width,height)
        self.mine = False
        self.flag = False
        self.click = False
        self.column = column
        self.row = row
        self.sur = sur

def new_mines():
    for item in tile_list:
        item.mine = False
        item.color = WHITE
        item.click = False
        item.flag = False
    for i in range(0,mines):
        add = True
        while (add == True):
            row = random.randint(0,9)
            col = random.randint(1,9)
            num = (row * 10 + col)
            if (tile_list[num].mine == False):
                tile_list[num].mine = True
                #tile_list[num].color=RED
                add = False
    for item in tile_list:
        row = item.row
        col = item.column
        sur = 0
        for tile in tile_list:
            if tile.row <= row + 1 and tile.row >= row - 1:
                if tile.column <= col + 1 and tile.column >= col - 1:
                    if tile.mine == True:
                        sur += 1
        item.sur = sur

game = True
tile_list = []
mines = 15
click = False
button = 99
POS = (0,0)
state = -1

reset = pygame.Rect(W - 100,0,100,50)

for i in range(0,10):
    for j in range(0,10):
        tile_list.append(Tile(65 + i * 42,100 + j * 42,i + 1,j + 1))

new_mines()

while game == True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit(0)
        if event.type == KEYUP:
            if event.key == K_ESCAPE:
                pygame.quit()
                sys.exit(0)
        if event.type == MOUSEBUTTONUP:
            click = True
            button = event.button
            pos = event.pos
        if event.type == MOUSEMOTION:
            POS = event.pos

    if click:
        if reset.collidepoint(pos):
            state = -1
            mines = 15
            new_mines()
        if state == -1:
            for item in tile_list:
                if item.rect.collidepoint(pos):
                    if button == 1:
                        if item.mine == False:
                            item.click = True
                            if item.sur == 0:
                                for var in tile_list:
                                    if var.sur == 0:
                                        var.click = True
                        else:
                            item.color = RED
                            #mines -=1
                            state = 1
                            #game = False
                    if button == 3:
                        if item.flag == False:
                            item.flag = True
                            item.color = GREEN
                            mines -= 1
                        else:
                            if item.flag == True:
                                item.flag = False
                                item.color = WHITE
                                mines += 1
        click = False
        button = 99

    if mines == 0:
        unflagged = 0
        for item in tile_list:
            if item.mine == True and item.flag == False:
                unflagged += 1
        if unflagged == 0:
            state = 0

    Surface.fill(BLACK)

    pygame.draw.rect(Surface, RED, reset)

    for item in tile_list:
        pygame.draw.rect(Surface, item.color, item.rect)
        if item.mine == False and item.click == True:
            if item.sur == 0:
                col1 = BLACK
            if item.sur == 1:
                col1 = BLUE
            if item.sur == 2:
                col1 = GREEN
            if item.sur == 3:
                col1 = RED
            if item.sur == 4:
                col1 = YELLOW
            if item.sur > 4:
                col1 = BLACK
            text_print(str(item.sur),col1,WHITE,item.rect.centerx - 8,item.rect.centery - 10)
            #text_print(str(item.row)+','+str(item.column),BLACK,WHITE,item.rect.left,item.rect.top)

    text_print('Mines:' + str(mines),RED,BLACK,W / 2 - 45,10)
    text_print('RESET',BLACK,RED,reset.left + 17,reset.top + 13)

    if state == 0:
        text_print('YOU WON!',RED,WHITE,W / 2 - 55,50)
    else:
        if state == 1:
            text_print('You Lost... :(',RED,WHITE,W / 2 - 55,50)

    #text_print(str(POS[0])+','+str(POS[1]),RED,BLACK,10,10)

    pygame.display.flip()
    mainClock.tick(100)


import configparser

# Specify the file path
file_path = '../configfiles/machineConfig.ini'

# Read the file content
with open(file_path, 'r') as file:
    file_content = file.read()

# Create a ConfigParser object and read the content
config = configparser.ConfigParser()
config.read_string(file_content)

# Get the values of timezone and UTC
timezone = config.get('timezone', 'timezone')
utc = config.get('timezone', 'UTC')

# Print the values
print('Timezone:', timezone)
print('UTC:', utc)


def text_from_box(boxfile):
    '''Reads Tesseract *.box file and returns its text string'''
    with open(boxfile, encoding='utf-8') as f:
        value = ''.join(l[0] for l in f)
    value = value.replace('\t', '\n').strip()

    return value

if __name__ == '__main__':
    import argparse

    parser = argparse.ArgumentParser(description='Extracts text from tesseract BOX file')
    parser.add_argument('boxfile', nargs='+', help='One or more *.box files')

    args = parser.parse_args()

    for boxfile in args.boxfile:
        print(text_from_box(boxfile))


import cv2
import os

"""
This script downscales all downloaded images to half the width and height.
"""

root_dir = os.getcwd()
downloads_dir = root_dir + '\\standardized'

if not os.path.exists(root_dir + '\\dataset\\original'):
    os.makedirs(root_dir + '\\dataset\\original')
original_dir = root_dir + '\\dataset\\original'

if not os.path.exists(root_dir + '\\dataset\\downscaled'):
    os.makedirs(root_dir + '\\dataset\\downscaled')
downscaled_dir = root_dir + '\\dataset\\downscaled'

count = 1
for subdir, dirs, files in os.walk(downloads_dir):
    for file in files:
        print('Processing', os.path.join(subdir, file))
        try:
            image = cv2.imread(os.path.join(subdir, file))
            width = int(image.shape[1] * 0.5)
            height = int(image.shape[0] * 0.5)
            resized_img = cv2.resize(image, (width, height))
            cv2.imwrite(original_dir + '\\' + str(count) + '.png', image)
            cv2.imwrite(downscaled_dir + '\\' + str(count) + '.png', resized_img)
            count += 1
        except AttributeError:
            pass # if you run into weird Nonetype errors, just ignore them


import numpy as np
import torch
import warnings

import utils

with warnings.catch_warnings():
    warnings.filterwarnings("ignore", category=FutureWarning)
    import tensorflow as tf
    tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)

if __name__ == '__main__':
    args = utils.parse_args()
    experiment_id = utils.get_random_string()
    print(f'Running PPO2 controller for ALRS training...\nArgs:\n{utils.args_to_str(args)}\n')
    print(f'Experiment ID:', experiment_id)

    env = utils.make_alrs_env(args)
    model = utils.make_ppo2_controller(env, args)

    utils.args_to_file(args, experiment_id)
    best_episode_reward = -np.inf
    best_val_loss = np.inf

    def callback(_locals, _globals):
        """
        Callback called every n steps.
        """
        global experiment_id, best_episode_reward, best_val_loss, model, args

        minor_save_interval = 2000  if args.dataset == 'mnist' else 1000
        major_save_interval = 10000 if args.dataset == 'mnist' else 5000

        steps = str(int(model.num_timesteps/1000))+'k'
        val_loss = model.env.venv.envs[0].env.latest_end_val

        def write_value(tag, value):
            summary = tf.Summary(value=[tf.Summary.Value(tag=tag, simple_value=value)])
            _locals['writer'].add_summary(summary, model.num_timesteps)

        if val_loss is not None:

            write_value('val_loss', val_loss)
            write_value('log_val_loss', np.log(val_loss))

            if val_loss < best_val_loss:
                print(f'Achieved new minimum val loss: {val_loss} (previous: {best_val_loss})')
                best_val_loss = val_loss
                model.save(f'data/{experiment_id}_steps={steps}_val={str(np.around(best_val_loss, decimals=4))}.zip')

        if model.num_timesteps % minor_save_interval == 0 and model.num_timesteps > 0:
            model.save(f'data/{experiment_id}_current')

        if model.num_timesteps % major_save_interval == 0 and model.num_timesteps > 0:
            model.save(f'data/{experiment_id}_steps={steps}.zip')

        return True

    tb_log_name = experiment_id
    if args.tb_suffix is not None:
        tb_log_name += '__'+args.tb_suffix

    model.learn(
        total_timesteps=args.ppo2_total_timesteps,
        tb_log_name=tb_log_name,
        reset_num_timesteps=False,
        callback=callback
    )
    print('Training terminated successfully!')


from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import pad
from Cryptodome.Util.Padding import unpad
import base64

BLOCK_SIZE = 32
KEY = b'86bd8a144720b6b0650cbde99a0db485'
VECTOR = b'0000000011111111'

class CryptAes:
    """
    Класс для шифрования сообщений по алгоритму AES.
    """
    def encrypt(self, message):
        message = message.encode()
        raw = pad(message, BLOCK_SIZE)
        cipher = AES.new(KEY, AES.MODE_CBC, VECTOR)
        enc = cipher.encrypt(raw)
        return base64.b64encode(enc).decode('utf-8')

    def decrypt(self, raw_string_crypt):
        raw_string_crypt = base64.b64decode(raw_string_crypt)
        cipher = AES.new(KEY, AES.MODE_CBC, VECTOR)
        dec = cipher.decrypt(raw_string_crypt)
        return unpad(dec, BLOCK_SIZE).decode('utf-8')


#!/usr/bin/env python3

import os
import re
import sys
import copy
import math
import numpy
import string
import random
import crcmod.predefined

debug = False

phenotype_dict = {
	'a': 'amber',
	'b': 'bald',
	'c': 'conehead',
	'd': 'dumpy',
	'e': 'eyeless',
	'f': 'forked',
	'g': 'garnet',
	'h': 'hook',
	'i': 'indy',
	'j': 'jagged',
	'k': 'kidney',
	'l': 'lyra',
	'm': 'marula',
	'n': 'notch',
	'o': 'okra',
	'p': 'prickly',
	'q': 'quick',
	'r': 'rosy',
	's': 'scute',
	't': 'taxi',
	'u': 'upturned',
	'v': 'vestigial',
	'w': 'white',
	'x': 'xray',
	'y': 'yellow',
	'z': 'zipper',
}

def invertType(genotype, basetype):
	newtype = ''
	for i in range(3):
		if genotype[i] == '+':
			newtype += basetype[i]
		else:
			newtype += '+'
	return newtype

def flipGene(genotype, gene, basetype):
	newlist = list(genotype)
	for i in range(3):
		if basetype[i] == gene:
			if genotype[i] == '+':
				newlist[i] = basetype[i]
			else:
				newlist[i] = '+'
	newtype = ""
	for i in newlist:
		newtype += i
	return newtype

def getGeneOrder(basetype):
	basetype2 = basetype[0]+basetype[2]+basetype[1]
	basetype3 = basetype[1]+basetype[0]+basetype[2]

	#gene order
	if debug is True: print("selecting gene order")
	geneorder = random.choice([basetype, basetype2, basetype3])
	if debug is True: print(geneorder)
	return geneorder

def getDistances():
	#integers
	key_maps = {
		35:	[10, 20, 30, 40, ],
		30:	[ 5, 10, 15, 20, 25, 35,],
		25:	[ 2,  4,  6,  8, 12, 14, 16, 18, 22,],
		20:	[ 5, 10, 15, 25, 30, 35,],
		15:	[10, 20, 30, 40, ],
		10:	[ 5, 15, 20, 25, 30, 35,],
		5:	[10, 20, 30, 40, ],
	}
	#a = random.choice(list(key_maps.keys()))
	#b = random.choice(key_maps[a])
	a = random.randint(15,35)
	b = random.randint(2,a-2)
	if a == b:
		print("ERROR")
		sys.exit(1)
	if debug is True: print("determine gene distances")
	distances = [a, b]
	random.shuffle(distances)
	distance3 = int(distances[0] + distances[1] - (distances[0] * distances[1])/50)
	distances.append(distance3)
	if debug is True: print(distances)
	return distances

def getDistancesOriginal():
	if debug is True: print("determine gene distances")
	a = numpy.random.poisson(lam=12, size=7)
	a.sort()
	distances = [a[0], a[-1]]
	random.shuffle(distances)
	distance3 = distances[0] + distances[1] - (distances[0] * distances[1])/50.
	distances.append(distance3)
	if debug is True: print(distances)
	return distances

def getProgenySize(distances):
	if debug is True: print("determine progeny size")
	gcd1 = math.gcd(distances[0], 100)
	gcd2 = math.gcd(distances[1], 100)
	gcdfinal = math.gcd(gcd1, gcd2)
	if debug is True: print("Final GCD", gcdfinal)
	progenybase = 100/gcdfinal
	minprogeny =  900/progenybase
	maxprogeny = 6000/progenybase
	progs = numpy.arange(minprogeny, maxprogeny+1, 1, dtype=numpy.float64)*progenybase
	#print(progs)
	numpy.random.shuffle(progs)
	#print(progs)
	bases = progs * distances[0] * distances[1] / 1e4
	#print(bases)
	devs = (bases - numpy.around(bases, 0))**2
	#print(devs)
	argmin = numpy.argmin(devs)
	progeny_size = int(progs[argmin])
	if debug is True: print(("total progeny: %d\n"%(progeny_size)))
	return progeny_size

def getPhenotype(genotype):
	if genotype == "+++":
		return 'wildtype'
	phenotype_list = []
	for allele in genotype:
		if allele == '+':
			continue
		phenotype = phenotype_dict.get(allele)
		phenotype_list.append(phenotype)
	#print(phenotype_list)
	phenotype_string = ', '.join(phenotype_list)
	return phenotype_string

def makeProgenyHtmlTable(typemap, progeny_size):
	alltypes = list(typemap.keys())
	alltypes.sort()
	td_extra = 'align="center" style="border: 1px solid black;"'
	span = ''
	table = '
'
	table += '
'
	table += '  {1}Phenotype	'.format(td_extra, span)
	table += '  {1}Genotypes	'.format(td_extra, span)
	table += '  {1}Progeny
Count	'.format(td_extra, span)
	table += '
'
	for type in alltypes:
		phenotype_string = getPhenotype(type)
		table += '
'
		table += '  {1}{2}	'.format(td_extra.replace('center', 'left'), span, phenotype_string)
		table += ' {1}{2}	'.format(td_extra, span, type[0])
		table += ' {1}{2}	'.format(td_extra, span, type[1])
		table += ' {1}{2}	'.format(td_extra, span, type[2])
		table += ' {1}{2:d}	'.format(td_extra.replace('center', 'right'), span, typemap[type])
		table += '
'
	table += '
'
	table += '  {1}TOTAL =	'.format(td_extra.replace('center', 'right'), span)
	table += '  {1}{2:d}	'.format(td_extra.replace('center', 'right'), span, progeny_size)
	table += '
'
	table += '
'
	return table

def makeProgenyAsciiTable(typemap, progeny_size):
	alltypes = list(typemap.keys())
	alltypes.sort()
	table = ''
	for type in alltypes:
		phenotype_string = getPhenotype(type)
		table += ("{0}\t".format(type[0]))
		table += ("{0}\t".format(type[1]))
		table += ("{0}\t".format(type[2]))
		table += ("{0:d}\t".format(typemap[type]))
		table += ("{0}\t".format(phenotype_string))
		table += "\n"
	table +=  "\t\t\t-----\n"
	table +=  "\t\tTOTAL\t%d\n\n"%(progeny_size)
	return table

def generateProgenyData(types, type_counts, basetype):
	if debug is True: print("\n\ngenerate progeny data")
	typemap = {}
	for t in types:
		n = invertType(t, basetype)
		#rand = random.gauss(0.5, 0.01)
		try:
			count = type_counts[t]
		except KeyError:
			count = type_counts[n]
		tcount = 0
		ncount = 0
		for i in range(count):
			if random.random() > 0.5:
				tcount += 1
			else:
				ncount += 1
		sys.stderr.write(".")
		#typemap[t] = int(rand * count)
		#typemap[n] = count - typemap[t]
		typemap[t] = tcount
		typemap[n] = ncount
	sys.stderr.write("\n")
	return typemap

def generateTypeCounts(parental, doublecross, basetype):
	type_counts = {}
	if debug is True: print("determine double type")
	doubletype = flipGene(parental, geneorder[1], basetype)
	doublecount = int(round(doublecross*progeny_size/100.))
	if debug is True: print("  ", doubletype, invertType(doubletype, basetype), doublecount)
	type_counts[doubletype] = doublecount

	if debug is True: print("determine first flip")
	firsttype = flipGene(parental, geneorder[0], basetype)
	firstcount = int(round(distances[0]*progeny_size/100.)) - doublecount
	if debug is True: print("  ", firsttype, invertType(firsttype, basetype), firstcount)
	type_counts[firsttype] = firstcount

	if debug is True: print("determine second flip")
	secondtype = flipGene(parental, geneorder[2], basetype)
	secondcount = int(round(distances[1]*progeny_size/100.)) - doublecount
	if debug is True: print("  ", secondtype, invertType(secondtype, basetype), secondcount)
	type_counts[secondtype] = secondcount

	if debug is True: print("determine parental type count")
	parentcount = progeny_size - doublecount - firstcount - secondcount
	if debug is True: print("  ", parental, invertType(parental, basetype), parentcount)
	type_counts[parental] = parentcount

	return type_counts

def makeQuestion(basetype, geneorder, distances, progeny_size):
	if debug is True: print("------------")
	answerString = ("%s - %d - %s - %d - %s"
		%(geneorder[0], distances[0], geneorder[1], distances[1], geneorder[2]))
	print(answerString)
	if debug is True: print("------------")

	if debug is True: print("determine double crossovers")
	doublecross = distances[0]*distances[1]/100.
	if debug is True: print("doublecross", doublecross*10, 'per 1000')

	if debug is True: print("determine parental type")
	types = ['+++', '++'+basetype[2], '+'+basetype[1]+'+', '+'+basetype[1]+basetype[2]]
	parental = random.choice(types)
	if debug is True: print("  ", parental, invertType(parental, basetype))
	type_counts = generateTypeCounts(parental, doublecross, basetype)
	typemap = generateProgenyData(types, type_counts, basetype)
	return typemap

def questionText(basetype):
	question_string = '
Three-Point Test-Cross Gene Mapping
'
	question_string += '
A test-cross with a heterozygote fruit fly for three genes is conducted. '
	question_string += 'The resulting phenotypes are summarized in the table above.
 '
	question_string += '
Using the table above, determine the order of the genes and the distances between them. '
	question_string += 'Once calculated, fill in the following four blanks:

'
	question_string += '
The distance between genes {0} and {1} is [{0}{1}] cM ({0}{1})
'.format(basetype[0].upper(),basetype[1].upper())
	question_string += '
The distance between genes {0} and {1} is [{0}{1}] cM ({0}{1})
'.format(basetype[0].upper(),basetype[2].upper())
	question_string += '
The distance between genes {0} and {1} is [{0}{1}] cM ({0}{1})
'.format(basetype[1].upper(),basetype[2].upper())
	question_string += '
From this the correct order of the genes is [geneorder] (gene order).

'
	question_string += '
Hint 1: ALL gene distances will be whole numbers, '
	question_string += 'do NOT enter a decimal; if you have a decimal your calculations are wrong.
'
	question_string += '
Hint 2: enter your answer in the blank using only letters or numbers '
	question_string += ' with no spaces or commas. Also, do NOT add units, e.g. cM or m.u.
'
	return question_string

def getVariables(basetype):
	variable_list = []
	if basetype[0] < basetype[1]:
		variable = '{0}{1}'.format(basetype[0].upper(),basetype[1].upper())
	else:
		variable = '{0}{1}'.format(basetype[1].upper(),basetype[0].upper())
	variable_list.append(variable)
	if basetype[1] < basetype[2]:
		variable = '{0}{1}'.format(basetype[1].upper(),basetype[2].upper())
	else:
		variable = '{0}{1}'.format(basetype[2].upper(),basetype[1].upper())
	variable_list.append(variable)
	if basetype[0] < basetype[2]:
		variable = '{0}{1}'.format(basetype[0].upper(),basetype[2].upper())
	else:
		variable = '{0}{1}'.format(basetype[2].upper(),basetype[0].upper())
	variable_list.append(variable)
	variable = 'geneorder'
	variable_list.append(variable)
	return variable_list

#=======================
def getCrc16_FromString(mystr):
	crc16 = crcmod.predefined.Crc('xmodem')
	crc16.update(mystr.encode('ascii'))
	return crc16.hexdigest().lower()

#=====================
def makeQuestionPretty(question):
	pretty_question = copy.copy(question)
	#print(len(pretty_question))
	pretty_question = re.sub('\<table.+\<\/table\>', '[]\n', pretty_question)
	#print(len(pretty_question))
	pretty_question = re.sub('\<\/p\>\s*\
', '\n', pretty_question)
	#print(len(pretty_question))
	return pretty_question

#=====================
def formatBB_FIB_PLUS_Question(N, question, variable_list, geneorder, distances):
	number = "{0}. ".format(N)
	crc16 = getCrc16_FromString(question)

	#FIB_PLUS TAB question text TAB variable1 TAB answer1 TAB answer2 TAB TAB variable2 TAB answer3
	bb_question = 'FIB_PLUS\t
{0}. {1}
 {2}'.format(N, crc16, question)
	pretty_question = makeQuestionPretty(question)
	print('{0}. {1} -- {2}'.format(N, crc16, pretty_question))

	variable_to_distance = {}
	for i in range(len(variable_list)-1):
		variable_to_distance[variable_list[i]] = distances[i]
	variable_list.sort()
	for i in range(len(variable_list)-1):
		variable = variable_list[i]
		bb_question += '\t{0}\t{1}\t'.format(variable, variable_to_distance[variable])
	bb_question += '\tgeneorder\t{0}\t{1}'.format(geneorder, geneorder[::-1])
	bb_question += '\n'
	return bb_question

#=====================
#=====================
if __name__ == "__main__":
	lowercase = "abcdefghijklmnpqrsuvwxyz"

	outfile = 'bbq-' + os.path.splitext(os.path.basename(__file__))[0] + '-questions.txt'
	print('writing to file: '+outfile)
	f = open(outfile, 'w')
	duplicates = 1
	j = -1
	N = 0
	for i in range(duplicates):
		N += 1
		j += 1
		if j + 2 == len(lowercase):
			j = 0
		basetype = lowercase[j:j+3]
		geneorder = getGeneOrder(basetype)
		distances = getDistances()
		print(distances)
		progeny_size = getProgenySize(distances)
		typemap = makeQuestion(basetype, geneorder, distances, progeny_size)
		ascii_table = makeProgenyAsciiTable(typemap, progeny_size)
		print(ascii_table)
		html_table = makeProgenyHtmlTable(typemap, progeny_size)
		#print(html_table)
		question_string = questionText(basetype)
		variable_list = getVariables(geneorder)
		complete_question = html_table + question_string
		final_question = formatBB_FIB_PLUS_Question(N, complete_question, variable_list, geneorder, distances)
		#print(final_question)

		f.write(final_question)
	f.close()

#THE END


import json
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By

print('Welcome to kleinanzeigen. We will generate a list of your desired purchase.\nIncluding Price and Title of Product')
plz = input("Enter your zip code please: ")
item = input("Enter name of product you want listings from: ")

chrome_driver_path = "/Users/malik/Library/Mobile Documents/com~apple~CloudDocs/Development/chromedriver"
serv = Service(chrome_driver_path)
driver = webdriver.Chrome(service=serv)

URL = "https://www.ebay-kleinanzeigen.de/"
driver.get(URL)

time.sleep(2)
search = driver.find_element(By.ID, 'site-search-query')
search.send_keys(item)
zip_code = driver.find_element(By.ID, 'site-search-area')
zip_code.send_keys(plz)
time.sleep(1)
cookie_accept = driver.find_element(By.ID, 'gdpr-banner-accept')
cookie_accept.click()
time.sleep(1)
search_button = driver.find_element(By.ID, 'site-search-submit')
search_button.click()
time.sleep(2)

list_dict = {}
listings = driver.find_element(By.ID, 'srchrslt-adtable').find_elements(By.CLASS_NAME, 'lazyload-item')
for li in listings:
    list_dict[li.find_element(By.CLASS_NAME, 'text-module-begin').text] = li.find_element(By.CLASS_NAME, 'aditem-main--middle--price-shipping--price').text.split(' €')[0]

with open('kleinanzeigen-listings.json', 'w') as outfile:
    json.dump(list_dict, outfile)

driver.quit()