# Standard Library
import random
import re
import traceback
from json import loads

# 3rd Party
import docker
import pybreaker
import requests
from dateutil.parser import parse
from flask import Blueprint, current_app, g, make_response, request

# Fastlane
from fastlane.worker import ExecutionResult
from fastlane.worker.errors import HostUnavailableError

# http://docs.docker.com/engine/reference/commandline/ps/#examples
# One of created, restarting, running, removing, paused, exited, or dead
STATUS = {
    "created": ExecutionResult.Status.created,
    "exited": ExecutionResult.Status.done,
    "dead": ExecutionResult.Status.failed,
    "running": ExecutionResult.Status.running,
}

bp = Blueprint("docker", __name__, url_prefix="/docker-executor")
blacklist_key = "docker-executor::blacklisted-hosts"
job_prefix = "fastlane-job"

def get_details():
    details = request.get_json()

    if details is None and request.get_data():
        details = loads(request.get_data())

    return details

@bp.route("/blacklist", methods=["POST", "PUT"])
def add_to_blacklist():
    redis = current_app.redis

    data = get_details()

    if data is None or data == "":
        msg = "Failed to add host to blacklist because JSON body could not be parsed."
        g.logger.warn(msg)

        return make_response(msg, 400)

    if "host" not in data:
        msg = "Failed to add host to blacklist because 'host' attribute was not found in JSON body."
        g.logger.warn(msg)

        return make_response(msg, 400)

    host = data["host"]

    redis.sadd(blacklist_key, host)

    return ""

@bp.route("/blacklist", methods=["DEL", "DELETE"])
def remove_from_blacklist():
    redis = current_app.redis

    data = get_details()

    if data is None or data == "":
        msg = "Failed to remove host from blacklist because JSON body could not be parsed."
        g.logger.warn(msg)

        return make_response(msg, 400)

    if "host" not in data:
        msg = "Failed to remove host from blacklist because 'host' attribute was not found in JSON body."
        g.logger.warn(msg)

        return make_response(msg, 400)

    host = data["host"]

    redis.srem(blacklist_key, host)

    return ""

class DockerPool:
    def __init__(self, docker_hosts):
        self.docker_hosts = docker_hosts

        self.max_running = {}
        self.clients_per_regex = []
        self.clients = {}
        self.__init_clients()

    def __init_clients(self):
        for regex, docker_hosts, max_running in self.docker_hosts:
            client_list = []
            clients = (regex, client_list)
            self.clients_per_regex.append(clients)
            self.max_running[regex] = max_running

            for address in docker_hosts:
                host, port = address.split(":")
                cl = docker.DockerClient(base_url=address)
                self.clients[address] = (host, int(port), cl)
                client_list.append((host, int(port), cl))

    def refresh_circuits(self, executor, clients, blacklisted_hosts, logger):
        def ps(client):
            client.containers.list(sparse=False)

        for host, port, client in clients:
            if f"{host}:{port}" in blacklisted_hosts:
                continue

            try:
                logger.debug("Refreshing host...", host=host, port=port)
                circuit = executor.get_circuit(f"{host}:{port}")
                circuit.call(ps, client)
            except pybreaker.CircuitBreakerError:
                error = traceback.format_exc()
                logger.error("Failed to refresh host.", error=error)

    def get_client(self, executor, task_id, host=None, port=None, blacklist=None):
        logger = current_app.logger.bind(
            task_id=task_id, host=host, port=port, blacklist=blacklist
        )

        if host is not None and port is not None:
            logger.debug("Custom host returned.")

            return self.clients.get(f"{host}:{port}")

        if blacklist is None:
            blacklist = set()

        for regex, clients in self.clients_per_regex:
            logger.debug("Trying to retrieve docker client...", regex=regex)

            if regex is not None and not regex.match(task_id):
                logger.debug("Task ID does not match regex.", regex=regex)

                continue

            self.refresh_circuits(executor, clients, blacklist, logger)
            filtered = [
                (host, port, client)

                for (host, port, client) in clients

                if f"{host}:{port}" not in blacklist
                and executor.get_circuit(f"{host}:{port}").current_state == "closed"
            ]

            if not filtered:
                logger.debug(
                    "No non-blacklisted and closed circuit clients found for farm.",
                    regex=regex,
                )

                continue

            logger.info(
                "Returning random choice out of the remaining clients.",
                clients=[f"{host}:{port}" for (host, port, client) in filtered],
            )

            host, port, client = random.choice(filtered)

            return host, int(port), client

        msg = f"Failed to find a docker host for task id {task_id}."
        logger.error(msg)
        raise RuntimeError(msg)

class Executor:
    def __init__(self, app, pool=None):
        self.app = app
        self.logger = app.logger
        self.pool = pool
        self.circuits = {}

        if pool is None:
            docker_hosts = []
            clusters = loads(self.app.config["DOCKER_HOSTS"])

            self.logger.debug("Initializing docker pool...", clusters=clusters)

            for i, cluster in enumerate(clusters):
                regex = cluster["match"]

                if not regex:
                    regex = None

                    if i != len(clusters):
                        self.logger.warn(
                            "Farm with no regex found before the end of the DOCKER_HOSTS "
                            "definition. This means all the subsequent farms will never be"
                            " used as this one will always match anything that reaches it. "
                            "Please ensure that the farm with no regex match is the last one."
                        )
                else:
                    regex = re.compile(regex)

                hosts = cluster["hosts"]
                max_running = cluster.get("maxRunning", 10)
                self.logger.info(
                    "Found farm definition.",
                    regex=cluster["match"],
                    hosts=hosts,
                    max_running=max_running,
                )
                docker_hosts.append((regex, hosts, max_running))

            self.pool = DockerPool(docker_hosts)

    def validate_max_running_executions(self, task_id):
        total_running = 0
        max_running = 0
        logger = self.logger.bind(
            task_id=task_id, operation="docker_host.validate_max_running_executions"
        )

        for regex, _ in self.pool.clients_per_regex:
            if regex is not None and not regex.match(task_id):
                logger.debug("Farm does not match task_id.", regex=regex)

                continue

            running = self.get_running_containers(regex)
            total_running = len(running["running"])
            max_running = self.pool.max_running[regex]
            logger.debug(
                "Found number of running containers.",
                total_running=total_running,
                max_running=max_running,
            )

            break

        return total_running == 0 or total_running <= max_running

    def get_circuit(self, key):
        max_fails = int(current_app.config["DOCKER_CIRCUIT_BREAKER_MAX_FAILS"])
        reset_timeout = int(
            current_app.config["DOCKER_CIRCUIT_BREAKER_RESET_TIMEOUT_SECONDS"]
        )

        return self.circuits.setdefault(
            key,
            pybreaker.CircuitBreaker(
                fail_max=max_fails,
                reset_timeout=reset_timeout,
                state_storage=pybreaker.CircuitRedisStorage(
                    pybreaker.STATE_CLOSED, current_app.redis, namespace=key
                ),
            ),
        )

    def update_image(self, task, job, execution, image, tag, blacklisted_hosts=None):
        if blacklisted_hosts is None:
            blacklisted_hosts = self.get_blacklisted_hosts()

        logger = self.logger.bind(
            task_id=task.task_id,
            job_id=str(job.job_id),
            execution_id=str(execution.execution_id),
            image=image,
            tag=tag,
            blacklisted_hosts=blacklisted_hosts,
            operation="docker_executor.update_image",
        )

        host, port, cl = self.pool.get_client(
            self, task.task_id, blacklist=blacklisted_hosts
        )
        circuit = self.get_circuit(f"{host}:{port}")

        logger = logger.bind(host=host, port=port)

        @circuit
        def run(logger):
            try:
                logger.debug("Updating image in docker host...")
                cl.images.pull(image, tag=tag)
                execution.metadata["docker_host"] = host
                execution.metadata["docker_port"] = port
                logger.info(
                    "Image updated successfully. Docker host and port stored in Job Execution for future reference."
                )
            except requests.exceptions.ConnectionError as err:
                error = traceback.format_exc()
                logger.error(
                    "Failed to connect to Docker Host. Will retry job later with a new host.",
                    error=error,
                )

                if "docker_host" in execution.metadata:
                    del execution.metadata["docker_host"]

                if "docker_port" in execution.metadata:
                    del execution.metadata["docker_port"]

                raise HostUnavailableError(host, port, err)

        run(logger)

    def run(self, task, job, execution, image, tag, command, blacklisted_hosts=None):
        host, port, cl = None, None, None

        logger = self.logger.bind(
            task_id=task.task_id,
            job_id=str(job.job_id),
            execution_id=str(execution.execution_id),
            image=image,
            tag=tag,
            command=command,
            blacklisted_hosts=blacklisted_hosts,
            operation="docker_executor.run",
        )

        if "docker_host" in execution.metadata:
            h = execution.metadata["docker_host"]
            p = execution.metadata["docker_port"]
            host, port, cl = self.pool.get_client(self, task.task_id, h, p)
        else:
            if blacklisted_hosts is None:
                blacklisted_hosts = self.get_blacklisted_hosts()
            host, port, cl = self.pool.get_client(
                self, task.task_id, blacklist=blacklisted_hosts
            )
            execution.metadata["docker_host"] = host
            execution.metadata["docker_port"] = port
            logger.warn(
                "Docker Host and Port were not found in the execution metadata. "
                "This is weird, since the update image part of running a job "
                "should have selected a docker host.",
                new_host=host,
                new_port=port,
            )

        logger = logger.bind(host=host, port=port)

        circuit = self.get_circuit(f"{host}:{port}")

        @circuit
        def run(logger):
            try:
                container_name = f"{job_prefix}-{execution.execution_id}"
                envs = job.metadata.get("envs", {})
                logger = logger.bind(container_name=container_name, envs=envs)
                logger.debug("Running the Job in Docker Host...")
                container = cl.containers.run(
                    image=f"{image}:{tag}",
                    name=container_name,
                    command=command,
                    detach=True,
                    environment=envs,
                )
                execution.metadata["container_id"] = container.id
                logger.info(
                    "Container started successfully. Container ID stored as Job Execution metadata.",
                    container_id=container.id,
                )
            except requests.exceptions.ConnectionError as err:
                error = traceback.format_exc()
                logger.error(
                    "Failed to connect to Docker Host. Will retry job later with a new host.",
                    error=error,
                )

                if "docker_host" in execution.metadata:
                    del execution.metadata["docker_host"]

                if "docker_port" in execution.metadata:
                    del execution.metadata["docker_port"]

                raise HostUnavailableError(host, port, err)

        run(logger)

        return True

    def stop_job(self, task, job, execution):
        logger = self.logger.bind(
            task_id=task.task_id,
            job_id=str(job.job_id),
            execution_id=str(execution.execution_id),
            operation="docker_executor.stop_job",
        )

        if "container_id" not in execution.metadata:
            logger.warn(
                "Can't stop Job Execution, since it has not been started. Aborting..."
            )

            return

        h = execution.metadata["docker_host"]
        p = execution.metadata["docker_port"]
        host, port, cl = self.pool.get_client(self, task.task_id, h, p)

        logger = logger.bind(host=host, port=port)

        circuit = self.get_circuit(f"{host}:{port}")

        @circuit
        def run(logger):
            try:
                container_id = execution.metadata["container_id"]
                logger = logger.bind(container_id=container_id)
                logger.debug("Finding container...")
                container = cl.containers.get(container_id)
                logger.info("Container found.")
                logger.debug("Stopping container...")
                container.stop()
                logger.info("Container stopped.")
            except requests.exceptions.ConnectionError as err:
                error = traceback.format_exc()
                logger.error("Failed to connect to Docker Host.", error=error)

                raise HostUnavailableError(host, port, err)

        run(logger)

    def convert_date(self, dt):
        return parse(dt)

    def get_result(self, task, job, execution):
        h = execution.metadata["docker_host"]
        p = execution.metadata["docker_port"]
        host, port, cl = self.pool.get_client(self, task.task_id, h, p)

        logger = self.logger.bind(
            task_id=task.task_id,
            job_id=str(job.job_id),
            execution_id=str(execution.execution_id),
            operation="docker_executor.get_result",
        )

        circuit = self.get_circuit(f"{host}:{port}")

        @circuit
        def run(logger):
            try:
                container_id = execution.metadata["container_id"]
                logger = logger.bind(container_id=container_id)
                logger.debug("Finding container...")
                container = cl.containers.get(container_id)
                logger.info("Container found.")

                return container

            except requests.exceptions.ConnectionError as err:
                raise HostUnavailableError(host, port, err)

        container = run(logger)

        # container.attrs['State']
        # {'Status': 'exited', 'Running': False, 'Paused': False, 'Restarting': False,
        # 'OOMKilled': False, 'Dead': False, 'Pid': 0, 'ExitCode': 0, 'Error': '',
        # 'StartedAt': '2018-08-27T17:14:14.1951232Z', 'FinishedAt': '2018-08-27T17:14:14.2707026Z'}

        container_id = execution.metadata["container_id"]
        logger = logger.bind(container_id=container_id)

        result = ExecutionResult(
            STATUS.get(container.status, ExecutionResult.Status.done)
        )

        state = container.attrs["State"]
        result.exit_code = state["ExitCode"]
        result.error = state["Error"]
        result.started_at = self.convert_date(state["StartedAt"])

        logger = logger.bind(
            status=container.status,
            state=state,
            exit_code=result.exit_code,
            error=result.error,
        )

        logger.debug("Container result found.")

        if (
            result.status == ExecutionResult.Status.done
            or result.status == ExecutionResult.Status.failed
        ):
            result.finished_at = self.convert_date(state["FinishedAt"])
            result.log = container.logs(stdout=True, stderr=False)

            if result.error != "":
                result.error += (
                    f"\n\nstderr:\n{container.logs(stdout=False, stderr=True)}"
                )
            else:
                result.error = container.logs(stdout=False, stderr=True)

            logger.info("Container finished executing.", finished_at=result.finished_at)

        return result

    def _get_all_clients(self, regex):
        clients = self.pool.clients.values()

        if regex is not None:
            for r, cl in self.pool.clients_per_regex:
                if r is not None and r != regex:
                    continue

                clients = cl

                break

        return [
            (host, port, client, self.get_circuit(f"{host}:{port}"))

            for host, port, client in clients
        ]

    def _list_containers(self, host, port, client, circuit):
        @circuit
        def run():
            running = []
            containers = client.containers.list(
                sparse=False, filters={"status": "running"}
            )

            for container in containers:
                if not container.name.startswith(job_prefix):
                    continue
                running.append((host, port, container.id))

            return running

        return run()

    def get_running_containers(self, regex=None, blacklisted_hosts=None):
        if blacklisted_hosts is None:
            blacklisted_hosts = self.get_blacklisted_hosts()

        running = []

        unavailable_clients = []
        unavailable_clients_set = set()
        clients = self._get_all_clients(regex)

        for (host, port, client, circuit) in clients:
            if f"{host}:{port}" in blacklisted_hosts:
                unavailable_clients_set.add(f"{host}:{port}")
                unavailable_clients.append(
                    (host, port, RuntimeError("server is blacklisted"))
                )

                continue

            try:
                running += self._list_containers(host, port, client, circuit)
            except Exception as err:
                unavailable_clients_set.add(f"{host}:{port}")
                unavailable_clients.append((host, port, err))

        return {
            "available": [
                {
                    "host": host,
                    "port": port,
                    "available": True,
                    "blacklisted": f"{host}:{port}" in blacklisted_hosts,
                    "circuit": circuit.current_state,
                    "error": None,
                }

                for (host, port, client, circuit) in clients

                if f"{host}:{port}" not in unavailable_clients_set
            ],
            "unavailable": [
                {
                    "host": host,
                    "port": port,
                    "available": False,
                    "blacklisted": f"{host}:{port}" in blacklisted_hosts,
                    "circuit": self.get_circuit(f"{host}:{port}").current_state,
                    "error": str(err),
                }

                for (host, port, err) in unavailable_clients
            ],
            "running": running,
        }

    def get_current_logs(self, task_id, job, execution):
        h = execution.metadata["docker_host"]
        p = execution.metadata["docker_port"]
        host, port, cl = self.pool.get_client(self, task_id, h, p)

        container_id = execution.metadata["container_id"]
        container = cl.containers.get(container_id)

        log = container.logs(stdout=True, stderr=True).decode("utf-8")

        return log

    def get_streaming_logs(self, task_id, job, execution):
        h = execution.metadata["docker_host"]
        p = execution.metadata["docker_port"]
        host, port, cl = self.pool.get_client(self, task_id, h, p)

        container_id = execution.metadata["container_id"]

        logger = self.logger.bind(
            task_id=task_id,
            job=str(job.job_id),
            execution_id=str(execution.execution_id),
            operation="docker_host.get_streaming_logs",
            host=host,
            port=port,
            container_id=container_id,
        )

        try:
            container = cl.containers.get(container_id)

            for log in container.logs(stdout=True, stderr=True, stream=True):
                yield log.decode("utf-8")
        except requests.exceptions.ConnectionError as err:
            error = traceback.format_exc()
            logger.error("Failed to connect to Docker Host.", error=error)

            raise HostUnavailableError(host, port, err)

    def get_blacklisted_hosts(self):
        redis = current_app.redis
        hosts = redis.smembers(blacklist_key)

        return set([host.decode("utf-8") for host in hosts])

    def mark_as_done(self, task, job, execution):
        h = execution.metadata["docker_host"]
        p = execution.metadata["docker_port"]
        host, port, cl = self.pool.get_client(self, task.task_id, h, p)

        container_id = execution.metadata["container_id"]

        logger = self.logger.bind(
            task_id=task.task_id,
            job=str(job.job_id),
            execution_id=str(execution.execution_id),
            operation="docker_host.mark_as_done",
            host=host,
            port=port,
            container_id=container_id,
        )

        try:
            logger.debug("Finding container...")
            container = cl.containers.get(container_id)
            logger.info("Container found.")

            new_name = f"defunct-{container.name}"
            logger.debug("Renaming container...", new_name=new_name)
            container.rename(new_name)
            logger.debug("Container renamed.", new_name=new_name)
        except requests.exceptions.ConnectionError as err:
            error = traceback.format_exc()
            logger.error("Failed to connect to Docker Host.", error=error)

            raise HostUnavailableError(host, port, err)

    def remove_done(self):
        removed_containers = []
        clients = self.pool.clients.values()

        for (host, port, client) in clients:
            containers = client.containers.list(
                sparse=False, all=True, filters={"name": f"defunct-{job_prefix}"}
            )

            for container in containers:
                removed_containers.append(
                    {
                        "host": f"{host}:{port}",
                        "name": container.name,
                        "id": container.id,
                        "image": container.image.attrs["RepoTags"][0],
                    }
                )
                container.remove()

        self.logger.info(
            "Removed all defunct containers.", removed_containers=removed_containers
        )

        return removed_containers


from django.urls import path, include
from rest_framework.routers import DefaultRouter
from . import views

# Create a router and register our viewsets with it.
router = DefaultRouter()
# router.register(r'snippets', views.SnippetViewSet,basename="snippet")
# router.register(r'users', views.UserViewSet,basename="user")
router.register('movies',views.MovieViewSet,basename="movies")
router.register("tvshows",views.TVShowsViewSet,basename="tvshows")
router.register("episode-list",views.EpisodesViewSet,basename="episode")

# router.register(r'documents',views.ProfileDocumentViewset,basename='profileDocuments')
# The API URLs are now determined automatically by the router.
urlpatterns = [
    path("user",views.UserDashboard.as_view(),),
    path('streaming', include(router.urls)),
     path('',include('userr.urls')),
    path('',include("subscription.urls")),
        path('homeapi', views.HomeAPI.as_view(), name='home-api'),
        path('watchMovie/<str:id>',views.WatchMovieAPI.as_view()),
         path('stream/<int:file_id>/', views.stream_file, name='stream_file'),
]


"""
Main integrations test
"""
import asyncio
import json

import pytest
from selenium.webdriver.common.keys import Keys

@pytest.mark.async_test
async def test_click_output(start_page, browser):
    from tests.apps.pages.click_output import page

    await start_page(page)

    clicker = await browser.wait_for_element_by_id('clicker')

    for i in range(1, 25):
        clicker.click()

        await browser.wait_for_text_to_equal('#output', f'Clicked {i}')
        await browser.wait_for_style_to_equal(
            '#output', 'background-color',
            'rgba(255, 0, 0, 1)' if i % 2 == 1 else 'rgba(0, 0, 255, 1)'
        )

@pytest.mark.async_test
async def test_multi_page(start_visit, browser):
    from tests.apps.multi_page import app

    await start_visit(app)

    for num in ('one', 'two', 'three', 'four'):
        await browser.get(f'http://localhost:8150/{num}')
        await browser.wait_for_text_to_equal('#content', f'Page {num}')

@pytest.mark.async_test
async def test_binding_return_component(start_visit, browser):
    # Bindings can return components successfully.
    from tests.apps.binding_return_component import app

    await start_visit(app)

    await browser.get('http://localhost:8150/')

    await browser.click('#clicker')
    await browser.wait_for_text_to_equal('#from-binding', 'from binding')

@pytest.mark.async_test
async def test_layout_as_function(start_visit, browser):
    # Functions can be used as layout to be evaluated on page request.
    from tests.apps.layout_as_function import app

    await start_visit(app)

    await browser.get('http://localhost:8150')
    await browser.wait_for_text_to_equal('#layout', 'Layout as function')

@pytest.mark.async_test
async def test_generated_component_trigger_binding(start_visit, browser):
    # A component not in the initial layout can trigger other binding.
    from tests.apps.generated_component_trigger_binding import app

    await start_visit(app)

    await browser.click('#click')
    await browser.click('#generated')

    await browser.wait_for_text_to_equal('#output2', 'Generated')

@pytest.mark.async_test
async def test_click_with_state(start_page, browser):
    from tests.apps.pages.click_output import page

    await start_page(page)

    dropdown = await browser.wait_for_element_by_css_selector(
        '#dropdown input'
    )

    dropdown.send_keys('Foo')
    await browser.click('#clicker')

    await browser.wait_for_text_to_equal('#datalist-output', 'Data foo')

@pytest.mark.async_test
async def test_bindings_continue_after_error(start_visit, browser):
    from tests.apps.bindings_continue_after_error import app
    await start_visit(app)

    clicker = await browser.wait_for_element_by_id('click')
    clicker_err = await browser.wait_for_element_by_id('click-error')

    clicker.click()

    await browser.wait_for_text_to_equal('#output', 'Clicked 1')

    clicker_err.click()
    clicker.click()

    await browser.wait_for_text_to_equal('#output', 'Clicked 2')

    # FIXME Bug with caplog and the logger not working.
    # _, err = capsys.readouterr()
    # BUG with something. err is '' yet it is printed.
    # assert 'Clicked error' in err

@pytest.mark.async_test
async def test_aspect_rendering(start_visit, browser):
    from tests.apps import aspect_rendering

    app = aspect_rendering.app
    types = aspect_rendering.aspect_types

    await start_visit(app)

    for name, aspect in types.items():
        await browser.click(f'#set-{name}')
        expected = aspect['value']
        if aspect.get('json'):
            expected = json.dumps(expected, separators=(',', ':'))
        else:
            expected = str(expected)

        await browser.wait_for_text_to_equal(f'#spec-output .{name}', expected)

@pytest.mark.async_test
async def test_binding_set_aspect_trigger_error(start_page, browser):
    # Setting the aspect that triggered should raise an error
    from tests.apps.pages.binding_set_aspect_trigger_error import page

    await start_page(page)

    await browser.click('#click-error')

    # Use a output container to assert the error was raised instead.
    expected = 'Setting the same aspect that triggered: click-error.clicks'
    await browser.wait_for_text_to_equal('#error-output', expected)

@pytest.mark.async_test
async def test_trigger_on_removed_component(start_page, browser):
    from tests.apps.pages.trigger_on_removed_component import page

    await start_page(page)

    setter = await browser.wait_for_element_by_id('setter')
    remover = await browser.wait_for_element_by_id('remover')

    setter.click()

    await browser.wait_for_text_to_equal('#set-me', 'set')
    remover.click()
    await browser.wait_for_text_to_equal('#remove-inner', 'removed 1')
    setter.click()
    await browser.wait_for_text_to_equal('#done', 'done 2')

    # Can continue after error. Maybe add a specific error later.
    remover.click()
    await browser.wait_for_text_to_equal('#remove-inner', 'removed 2')

@pytest.mark.async_test
async def test_binding_chain(start_page, browser):
    # Updating an aspect from the backend should trigger
    # other connected bindings. (trigger-1 -> n bindings -> output)
    from tests.apps.pages.binding_chain import page
    await start_page(page)

    await browser.click('#trigger-1')

    await browser.wait_for_text_to_equal('#output', 'output generated')

@pytest.mark.async_test
async def test_binding_tree(start_page, browser):
    # This ensure that updates are not handled synchronously
    # in the order they come in and waited until the first one completes.
    from tests.apps.pages.binding_tree import page
    await start_page(page)

    await browser.click('#trigger')

    await browser.wait_for_text_to_equal('#done', 'done')
    output = json.loads((await browser.wait_for_element_by_id('output')).text)
    assert sum(output) == sum(range(1, 11))

@pytest.mark.async_test
async def test_dev_requirements(start_page, browser):
    # Make sure the dev requirements are served on page load when debug.
    from tests.apps.pages.click_output import page

    await start_page(page, debug=True)

    await browser.wait_for_element_by_xpath(
        '//script[@src="/dazzler/requirements/'
        'static/dev/react-17-0-2.development.js"]'
    )
    await browser.wait_for_element_by_xpath(
        '//script[contains(@src, '
        '"/dazzler/requirements/static/dazzler_core/dev/dazzler_core")]'
    )

@pytest.mark.async_test
async def test_initial_trigger(start_page, browser):
    from tests.apps.pages.initial_trigger import page

    await start_page(page)

    await browser.wait_for_text_to_equal(
        '#output', 'Input 10'
    )
    await browser.wait_for_text_to_equal(
        '#state-output', 'State 88'
    )

@pytest.mark.async_test
async def test_get_aspect(start_page, browser):
    from tests.apps.pages.get_aspect import page

    await start_page(page)

    await browser.click('#starter')
    await browser.click('#updater')

    await browser.wait_for_text_to_equal(
        '#done', 'done', timeout=30
    )

    result = json.loads(
        (await browser.wait_for_element_by_id('done-output')).text
    )

    assert sum(result) == sum(range(101))

@pytest.mark.async_test
async def test_get_aspect_error(start_page, browser):
    from tests.apps.pages.get_aspect_error import page

    await start_page(page)

    await browser.click('#click-error')

    await browser.wait_for_text_to_equal(
        '#error-output', 'Aspect not found invalid.error'
    )

@pytest.mark.async_test
async def test_component_as_trigger(start_page, browser):
    from tests.apps.pages.component_as_trigger import page

    await start_page(page)

    await browser.wait_for_text_to_equal(
        '#output', 'From component: from children'
    )

    await browser.wait_for_text_to_equal('#array-output', 'Sum: 45')

    nested = json.loads(
        (await browser.wait_for_element_by_id('nested-output')).text
    )

    assert nested['len'] == 2
    assert nested['insider'] == 'inside html div'
    assert nested['as_prop'] == 'attribute'

    (await browser.wait_for_element_by_id('get-aspect-trigger')).click()

    await asyncio.sleep(0.1)
    output = json.loads(
        (await browser.wait_for_element_by_id('get-aspect-output')).text
    )

    assert output['get-aspect'] == 'input-value'
    assert output['state'] == 4747

@pytest.mark.async_test
async def test_binding_return_trigger(start_page, browser):
    # This test that returned components can trigger bindings.
    from tests.apps.pages.binding_return_trigger import page

    await start_page(page)

    for i in range(1, 25):
        await browser.click('#click')
        await browser.wait_for_text_to_equal(
            '#trigger-output', f'from click {i}'
        )

@pytest.mark.skip(
    'FIXME Same identity bug #53'
)
@pytest.mark.async_test
async def test_same_identity(start_page, browser):
    # There is bug which you cannot set component with same identity as root.
    # but contained children works as per test_binding_return_trigger.
    # So setting the children aspect with the same component but updated values
    # doesn't work.
    from tests.apps.pages.same_identity import page

    await start_page(page)

    for _ in range(1, 25):
        clicker = await browser.wait_for_element_by_id('click')
        clicker.click()

        await browser.wait_for_property_to_equal('#same', 'value', 1)

@pytest.mark.async_test
async def test_component_as_aspect(start_page, browser):
    from tests.apps.pages.component_as_aspect import page

    await start_page(page)

    (await browser.wait_for_element_by_id('click-sum')).click()
    await browser.wait_for_text_to_equal('#sum-output', 'Sum 45')

    for i in range(1, 12):
        component = await browser.wait_for_element_by_id(f'array-{i}')
        for j in range(25):
            await browser.wait_for_text_to_equal(
                f'#output-array-{i}', f'array-{i} value: {i+j}'
            )
            component.send_keys(Keys.ARROW_UP)

        await browser.wait_for_element_by_id(f'label-{i}')

    for identity in ('single', 'shaped'):
        for i in range(1, 25):
            await browser.click(f'#{identity}')
            await browser.wait_for_text_to_equal(
                f'#{identity}-output', f'Click {identity}: {i}'
            )

@pytest.mark.async_test
async def test_storage(start_page, browser):
    from tests.apps.pages.storage import page

    await start_page(page)

    getter = 'return JSON.parse(window.{}.getItem("data"));'
    local_getter = getter.format('localStorage')
    session_getter = getter.format('sessionStorage')

    for store, getter in zip(
            ['local', 'session'], [local_getter, session_getter]
    ):
        for i in range(1, 25):
            await browser.click(f'#{store}-btn')
            await browser.wait_for_text_to_equal(
                f'#{store}-output', json.dumps({'clicks': i})
            )
            stored = browser.driver.execute_script(getter)

            assert stored['clicks'] == i

    await browser.executor.execute(browser.driver.refresh)
    await asyncio.sleep(1)
    stored = browser.driver.execute_script(local_getter)
    assert stored['clicks'] == 24

@pytest.mark.async_test
async def test_prefer_external(start_visit, browser):
    from tests.apps.prefer_external import app

    await start_visit(app)

    scripts = await browser.wait_for_elements_by_xpath(
        '//script[contains(@src, '
        '"https://unpkg.com/react@17.0.2/umd/react.production.min.js")]'
    )
    assert len(scripts) == 1

@pytest.mark.async_test
async def test_global_requirements(start_visit, browser):
    from tests.apps.app_requirements import app

    await start_visit(app)
    await browser.get('http://localhost:8150/')

    scripts = await browser.wait_for_elements_by_xpath(
        '//script[contains(@src, "withRequirements.js")]'
    )
    assert len(scripts) == 1

@pytest.mark.async_test
async def test_regex_bindings(start_page, browser):
    from tests.apps.pages.regex_bindings import page

    await start_page(page)
    state_input = await browser.wait_for_element_by_id('state1')

    for j in range(1, 3):

        identity = f'btn{j}'
        state_input.send_keys(Keys.BACKSPACE * 4)
        state_input.send_keys(identity)
        await asyncio.sleep(0.1)
        await browser.click(f'#{identity}')

        for i in range(1, 3):
            await browser.wait_for_text_to_equal(
                f'#output{i}', f'clicked from button {identity}'
            )

        await browser.wait_for_text_to_equal(
            '#data-state2-output', 'data@state2: store'
        )

        await browser.wait_for_text_to_equal(
            '#value-state1-output', f'value@state1: {identity}'
        )

@pytest.mark.async_test
async def test_str_trigger(start_page, browser):
    from tests.apps.pages.str_trigger import page

    await start_page(page)

    state = await browser.wait_for_element_by_id('input')

    for i in range(1, 3):
        state.send_keys(Keys.BACKSPACE)
        state.send_keys(str(i))
        await browser.click(f'#btn{i}')
        await browser.wait_for_text_to_equal(
            '#output-trigger', f'btn{i}'
        )

        await browser.wait_for_text_to_equal(
            '#output-state', str(i)
        )

@pytest.mark.async_test
async def test_pages_dir(start_visit, browser):
    from tests.apps.pages_directory import app

    await start_visit(
        app,
        url='http://localhost:8150/page1',
        pages_directory='tests/apps/page_dir'
    )

    await browser.wait_for_text_to_equal('#page_id', 'Page 1')

    await browser.get('http://localhost:8150/page2')
    await browser.wait_for_text_to_equal('#page_id', 'Page 2')

@pytest.mark.async_test
async def test_ties(start_page, browser):
    from tests.apps.pages.ties import page

    await start_page(page)
    text = 'Hello Ties'

    element = await browser.wait_for_element_by_id('input')
    element.send_keys(text)

    await browser.wait_for_text_to_equal('#output', text)
    await browser.wait_for_text_to_equal('#chain', text)
    await browser.wait_for_text_to_equal('#binding-output', text)
    await browser.wait_for_text_to_equal('#regex-output', text)
    await browser.wait_for_text_to_equal('#regex-target-1', text)
    await browser.wait_for_text_to_equal('#regex-target-2', text)

    text = 'foo bar'

    element = await browser.wait_for_element_by_id('multi')
    element.send_keys(text)

    await browser.wait_for_text_to_equal('#output-1', text)
    await browser.wait_for_text_to_equal('#output-2', text)
    await browser.wait_for_text_to_equal('#regex-output', text)
    await browser.wait_for_text_to_equal('#regex-target-1', text)
    await browser.wait_for_text_to_equal('#regex-target-2', text)

@pytest.mark.async_test
async def test_once_triggers(browser, start_page):
    from tests.apps.pages.once import page

    await start_page(page)

    for bind_type in ('binding', 'tie'):
        initial = f'initial-{bind_type}'
        changed = f'change-{bind_type}'
        await browser.wait_for_text_to_equal(
            f'#{bind_type}-output', initial)

        element = await browser.wait_for_element_by_id(f'{bind_type}-input')
        element.send_keys(Keys.BACKSPACE * len(initial))
        element.send_keys(changed)

        # Bindings are 1 to many, ties many to many
        # Assert that removing once doesn't remove the other tie with
        # same trigger.
        await browser.wait_for_text_to_equal(
            f'#always-{bind_type}', changed
        )
        await browser.wait_for_text_to_equal(
            f'#{bind_type}-output', initial
        )

@pytest.mark.async_test
async def test_calls(browser, start_page):
    from tests.apps.pages.calls import page

    await start_page(page)
    text = 'foo bar'

    simple = await browser.wait_for_element_by_id('simple-input')
    simple.send_keys(text)

    await browser.wait_for_text_to_equal('#simple-output', text)

    circular = await browser.wait_for_element_by_id('circular-input')
    circular.send_keys('k')

    await browser.wait_for_text_to_equal('#circular-output', 'circular output')

    # Asserts states & components can be set
    firstname = await browser.wait_for_element_by_id('firstname')
    firstname.send_keys('foo')
    lastname = await browser.wait_for_element_by_id('lastname')
    lastname.send_keys('bar')

    await browser.click('#submit')
    await browser.wait_for_text_to_equal(
        '#output', 'Hello foo bar'
    )

@pytest.mark.async_test
async def test_skip_initial_binding(browser, start_page):
    from tests.apps.pages.skip_initial import page

    await start_page(page)

    await browser.wait_for_text_to_equal('#click-output', 'clicks')
    await browser.click('#clicker')
    await browser.wait_for_text_to_equal('#click-output', '1')
    await browser.wait_for_text_to_equal('#output', 'output')

    inp = await browser.wait_for_element_by_id('input')
    inp.send_keys(' ok')

    await browser.wait_for_text_to_equal('#output', 'initial ok')


from time import sleep
from bs4 import BeautifulSoup
import requests
import pandas as pd
from pprint import pprint

# url = 'https://www.python.org/'
# url = 'https://tech-diary.net/python-scraping-books/'
url = 'https://suumo.jp/chintai/tokyo/sc_shinjuku/?page={}'
d_list = []

for i in range(1, 3):
    print('d_listの大きさ：', len(d_list))
    target_url = url.format(i)

# target_url = url.format(1)
# r = requests.get(url)
    r = requests.get(target_url)
    soup = BeautifulSoup(r.text)

    sleep(1)
    contents = soup.find_all('div', class_='cassetteitem')
    # print(len(contents))
    # content = contents[0]
    # print(content)
    for content in contents:
        detail = content.find('div', class_='cassetteitem-detail')
        table = content.find('table', class_='cassetteitem_other')
        title = detail.find('div', class_='cassetteitem_content-title').text
        address = detail.find('li', class_='cassetteitem_detail-col1').text
        access = detail.find('li', class_='cassetteitem_detail-col2').text
        age = detail.find('li', class_='cassetteitem_detail-col3').text

        # print(title, address, access, age)

        tr_tags = table.find_all('tr', class_='js-cassette_link')
        for tr_tag in tr_tags:
            floor, price, first_fee, capacity = tr_tag.find_all('td')[2:6]
            fee, management_fee = price.find_all('li')
            deposite, gratuity = first_fee.find_all('li')
            madori, menseki = capacity.find_all('li')
            # print(td_tag)
            d = {
                'title': title,
                'address': address,
                'access': access,
                'age': age,
                'floor': floor.text,
                'fee': fee.text,
                'management_fee': management_fee.text,
                'deposite': deposite.text,
                'gratuity': gratuity.text,
                'madori': madori.text,
                'menseki': menseki.text
            }
            d_list.append(d)

    # pprint(d_list[1])
# pprint(d_list[:2])

df = pd.DataFrame(d_list)
print(df.head())
print(df.shape)

print(len(df.title.unique()))

df.to_csv('test.csv', index=None, encoding='utf-8-sig')

# print(d)

# print(r.url)
# print(r.text)

# soup = BeautifulSoup(r.text)
# print(soup.find('h1').text)
# print(soup.find_all('h2')[0].text)

# h2_tag_list = []
# for i, h2_tag in enumerate(soup.find_all("h2")):
    # h2_tag_list.append(h2_tag.text)

# print(h2_tag_list)

# h2_tag_list2= [i.text for i in soup.find_all("h2")]
# print(h2_tag_list2)

# print(len(soup.find_all('span')))
# print(soup.find_all('span', class_=['say-no-more', 'message']))

# tag_list = [i.text for i in soup.find('article').find_all(['h2', 'h3'])]
# for i in tag_list:
    # print(i)


from flask import url_for
from pyquery import PyQuery

from mrt.forms.meetings import add_custom_fields_for_meeting
from mrt.models import Meeting, CustomField, CategoryDefault, Phrase

from .factories import MeetingFactory, MeetingTypeFactory, normalize_data
from .factories import MeetingCategoryFactory, ParticipantFactory
from .factories import CustomFieldFactory, CategoryDefaultFactory
from .factories import PhraseDefaultFactory

from testsuite.utils import populate_participant_form, add_new_meeting

def test_meeting_add_with_no_spanish(app, user):
    data = normalize_data(MeetingFactory.attributes())
    meeting_type = MeetingTypeFactory()
    data['title-english'] = data.pop('title')
    data['title-spanish'] = 'Spanish title'
    data['venue_city-english'] = data.pop('venue_city')
    data['badge_header-english'] = data.pop('badge_header')
    data['badge_header-header'] = 'Spanish header'
    data['photo_field_id'] = data['media_photo_field_id'] = '0'
    data['address_field_id'] = data['telephone_field_id'] = '0'
    data['meeting_type_slug'] = meeting_type.slug

    client = app.test_client()
    with app.test_request_context():
        with client.session_transaction() as sess:
            sess['user_id'] = user.id
        url = url_for('meetings.add')
        resp = client.get(url)

        form = PyQuery(resp.data)('form.form-horizontal')
        assert len(form('input#title-english')) == 1
        assert len(form('input#title-french')) == 1
        assert len(form('input#title-spanish')) == 0

        assert len(form('input#badge_header-english')) == 1
        assert len(form('input#badge_header-french')) == 1
        assert len(form('input#badge_header-spanish')) == 0

        resp = client.post(url, data=data)

    assert resp.status_code == 302
    assert Meeting.query.count() == 1

def test_participant_add_working_language(app, user):
    category = MeetingCategoryFactory(meeting__owner=user.staff)
    meeting = category.meeting
    data = ParticipantFactory.attributes()
    data['category_id'] = category.id
    data['language'] = 'Spanish'

    client = app.test_client()
    with app.test_request_context():
        add_custom_fields_for_meeting(meeting)
        populate_participant_form(meeting, data)
        with client.session_transaction() as sess:
            sess['user_id'] = user.id
        url = url_for('meetings.participant_edit', meeting_id=meeting.id)

        resp = client.get(url)
        options = PyQuery(resp.data)('select#language option')
        assert len(options) == 3

        resp = client.post(url, data=data)
        assert resp.status_code == 200

def test_custom_field_add_label_language(app, user):
    meeting = MeetingFactory()
    data = CustomFieldFactory.attributes()
    data['label-english'] = data['label'].english
    client = app.test_client()
    with app.test_request_context():
        with client.session_transaction() as sess:
            sess['user_id'] = user.id
        resp = client.get(url_for('meetings.custom_field_edit',
                                  meeting_id=meeting.id,
                                  custom_field_type=CustomField.PARTICIPANT))

        form = PyQuery(resp.data)
        assert len(form('input#label-english')) == 1
        assert len(form('input#label-french')) == 1
        assert len(form('input#label-spanish')) == 0

def test_add_default_category_title_language(app, user):
    data = CategoryDefaultFactory.attributes()
    data = normalize_data(data)
    data['title-english'] = data.pop('title')
    data['title-spanish'] = 'Spanish title'

    client = app.test_client()
    with app.test_request_context():
        with client.session_transaction() as sess:
            sess['user_id'] = user.id
        url = url_for('admin.category_edit')
        resp = client.get(url)
        assert resp.status_code == 200

        form = PyQuery(resp.data)
        assert len(form('input#title-english')) == 1
        assert len(form('input#title-french')) == 1
        assert len(form('input#title-spanish')) == 0

        resp = client.post(url, data=data)
        assert resp.status_code == 302
        assert CategoryDefault.query.count() == 1

def test_add_default_phrase_description_language(app, user):
    phrase = PhraseDefaultFactory()

    client = app.test_client()
    with app.test_request_context():
        with client.session_transaction() as sess:
            sess['user_id'] = user.id
        url = url_for('admin.phrase_edit', meeting_type=phrase.meeting_type,
                      phrase_id=phrase.id)
        resp = client.get(url)

        description = PyQuery(resp.data)('.panel-body')

        assert len(description('#description-english')) == 1
        assert len(description('#description-spanish')) == 0

def test_meeting_registration_success_phrases(app, user, default_meeting):
    meeting = add_new_meeting(app, user)
    category = MeetingCategoryFactory(meeting=meeting)
    online_phrase = meeting.phrases.filter_by(
        group=Phrase.ONLINE_REGISTRATION,
        name=Phrase.PARTICIPANT).scalar()
    online_phrase.description.english = 'Online success message'
    online_phrase.description.french = 'Bonjour monsiuer online'
    email_phrase = meeting.phrases.filter_by(
        group=Phrase.EMAIL_CONFIRMATION,
        name=Phrase.FOR_PARTICIPANTS).scalar()
    email_phrase.description.english = 'Email success message'
    email_phrase.description.french = 'Bonjour monsiuer email'

    data = ParticipantFactory.attributes()
    data['category_id'] = category.id
    data['language'] = 'French'

    client = app.test_client()
    with app.test_request_context():
        add_custom_fields_for_meeting(meeting)
        populate_participant_form(meeting, data)
        resp = client.post(url_for('meetings.registration',
                                   meeting_acronym=meeting.acronym,
                                   lang='fr'),
                           data=data)
        assert resp.status_code == 200
        success_message = PyQuery(resp.data)('.text-center h4')
        assert success_message.text() == online_phrase.description.french

        data['language'] = 'English'
        resp = client.post(url_for('meetings.registration',
                                   meeting_acronym=meeting.acronym,
                                   lang='en'),
                           data=data)
        assert resp.status_code == 200
        success_message = PyQuery(resp.data)('.text-center h4')
        assert success_message.text() == online_phrase.description.english


import torch
from cross_attn.main import MultiModalCrossAttention

# Test the MultiModalCrossAttention module
dim = 512  # For example
num_heads = 8

cross_attn = MultiModalCrossAttention(dim, num_heads)

Hllm_sample = torch.randn(32, dim, dim)  # Batch size = 32, Sequence length = 10
Himg_sample = torch.randn(32, dim, dim)

output = cross_attn(Hllm_sample, Himg_sample)
print(output)

print(output.shape)  # Expected: [32, 10, 512]


import copy
from typing import List

class Solution:

    def rec(self, index:int, tempList:List[int], nums:List[int], output:List[List[int]]):
        prev = -100

        for i in range(index, len(nums)) :
            if prev == nums[i] :
                continue
            prev = nums[i]

            midList = copy.deepcopy(tempList)
            midList.append(nums[i])
            output.append(midList)
            self.rec(i+1, midList, nums, output)
    def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
        output = [[]]
        nums.sort()

        self.rec(0,[], nums, output)
        return output


### Importar Librerias
from binance import Client
from binance.exceptions import BinanceAPIException
import time
import SL_auto as sl

def tp_auto(client,orden,ganancia,perdida,porcentaje_ts):

    ### id de la orden
    orderid = orden["orderId"]
    simbolo = orden["symbol"]

    ### Traer orden actualizada
    orden_act = client.futures_get_order(symbol = simbolo,
                                   orderId = orderid)

    c = 0
    max_c = 180
    while c <= max_c:
        ### Traer estado Última Orden
        status = orden_act["status"]

        if status == "FILLED":
            client.futures_cancel_all_open_orders(symbol = simbolo)

            ### Posición Actual
            while True:
                try:
                    pos_act = client.futures_position_information(symbol = orden["symbol"])[0]
                    break
                except BinanceAPIException as e:
                    # Espera 0.2 segundos antes de intentar nuevamente
                    print(e)
                    time.sleep(0.2)

            ### TP Limit Según lado
            roe = ganancia

            aux = None
            decimas = len(orden_act["price"].split(".")[1])
            palanca = int(pos_act["leverage"])
            if orden_act["side"] == "SELL":
                aux = "BUY"
                precio_salida = str(round(float(pos_act["entryPrice"])*(1-(roe/(100*palanca))),decimas))
                precio_act_tsl = str(round(float(pos_act["entryPrice"])*(1-(roe*porcentaje_ts/(100*palanca))),decimas))
            else:
                aux = "SELL"
                precio_salida = str(round(float(pos_act["entryPrice"])*(1+(roe/(100*palanca))),decimas))
                precio_act_tsl = str(round(float(pos_act["entryPrice"])*(1+(roe*porcentaje_ts/(100*palanca))),decimas))

            ### Crear Orden TP
            while True:
                try:
                    orden_salida = client.futures_create_order(symbol = orden_act["symbol"],
                                        side = aux,
                                        price = precio_salida,
                                        quantity = abs(int(pos_act["positionAmt"])),
                                        type = 'LIMIT',
                                        timeinforce = 'GTC',
                                        reduceOnly = True)
                    break
                except BinanceAPIException as e:
                    # Espera 0.2 segundos antes de intentar nuevamente
                    print(e)
                    time.sleep(0.2)

            ### Imprimir Ganancia
            total_salida = float(orden_salida["price"])*float(orden_salida["origQty"])
            total_entrada = abs(float(pos_act["entryPrice"])*float(pos_act["positionAmt"]))
            ganancia = total_salida - total_entrada
            comision = total_salida*0.0002 + total_entrada*0.0002
            ganancia_neta = abs(ganancia-comision)
            print("La ganancia es aproximandamente:", round(ganancia_neta,2))
            return(sl.sl_auto(client,orden_act,perdida),precio_act_tsl,aux)

        elif c == max_c:
            print("Se cancela la orden")
            client.futures_cancel_all_open_orders(symbol = orden_act["symbol"])
            break
        else:
            time.sleep(0.5)
            orden_act = client.futures_get_order(symbol = simbolo,
                                                 orderId = orderid)
            c = c+1
            print("Intento",c)


import sys, random
from PySide2.QtWidgets import *
from PySide2.QtGui import *
from PySide2 import QtCore
from random import randint

class MyCanvas(QWidget):
    def __init__(self):
        super().__init__()
        self.resize(500, 500)
        self.count = 0
        self.smile = QImage("smile.png")
        self.font = QFont('Decorative', 36)

        self.timer = QtCore.QTimer()
        #타이머 터지는 주기 설정
        self.timer.setInterval(1000)
        # timeout 시그널 연결
        self.timer.timeout.connect(self.doTimerJob)
        # 타이머 시작
        self.timer.start()

    def doTimerJob(self):
        self.update()

    def keyPressEvent(self, event):
        key = event.key()
        if key == QtCore.Qt.Key_Right : print("RIGHT")
        elif key == QtCore.Qt.Key_Left : print("LEFT")
        elif key == QtCore.Qt.Key_Down : print("DOWN")
        elif key == QtCore.Qt.Key_Up : print("UP")

    def mousePressEvent(self, event):
        pos = event.pos()
        #event.globalPos()를 사용하면 자신의 컴퓨터 크기에 맞는 픽셀이 나옴
        self.x = pos.x()
        self.y = pos.y()
        print(self.x, self.y)

    def paintEvent(self, event):
        qp = QPainter()
        qp.begin(self)

        x = randint(0, 500 - 50)
        y = randint(0, 500 - 50)

        qp.setFont(self.font)
        qp.drawText(QtCore.QRect(0, 0, 500, 500),
                    QtCore.Qt.AlignCenter, f"{self.count}")
        qp.drawImage(QtCore.QRect(x, y, 50, 50), self.smile)
        self.count += 1

        qp.end()

if __name__ == "__main__":
    app = QApplication(sys.argv)

    c = MyCanvas()
    c.show()

    sys.exit(app.exec_())


"""
Used to extract sentiment from headlines
"""

import logging
import nltk.sentiment.vader

MAX_TWEET_LENGTH = 280

def compound_score(text):
    """
    Provides the compound sentiment score of the text provided, using the VADER sentiment
    analyser. Expects text to be less than 280 characters
    :param text: text to be analysed for sentiment
    :return: Compound sentiment score
    """
    # warning, due to vader being trained on short text -- social media posts
    if len(text) > MAX_TWEET_LENGTH:
        logging.warning('Text provided is longer than a standard tweet, VADER is designed to be '
                        'used on short pieces of text')
    vader = nltk.sentiment.vader.SentimentIntensityAnalyzer()
    return vader.polarity_scores(text)['compound']


import threading
import requests
from PyQt6.QtGui import *
from PyQt6.QtCore import *
from PyQt6.QtWidgets import *
from .chatmsg import ChatMessage
from .borderlesswindow import BorderlessWindow

from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from .chatbox import ChatBox
    from ...gpt import RoleGpt

class CustomListView(QListWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.prompts = []
        self.itemClicked.connect(self.on_item_click)
        self.itemSelectionChanged.connect(self.on_item_select)
        thread = threading.Thread(target=self.fetch_data)
        thread.start()
        # self.fetch_data()

    def on_item_click(self, item: QListWidgetItem):
        print(f"{item.text()} {item.id} clicked")
        prompt = item.toolTip()
        # print("Setting prompt:", prompt)
        chatbox: ChatBox = self.parent().parent()
        rolegpt: RoleGpt = chatbox.rolegpt
        rolegpt.system_role = prompt
        rolegpt.sub_role = ""
        rolegpt.prompt_chain = []
        chat_user, chat_response = rolegpt.confirm_role()
        chatbox.add_message(ChatMessage(chat_user, chat_response))

    def on_item_select(self):
        return
        for item in self.selectedItems():
            print(f"{item.text()} selected")

    def fetch_data(self):
        url = "https://www.jailbreakchat.com/api/getprompts"
        try:
            response = requests.get(url)
            prompts = response.json()
            prompts = sorted(prompts, key=lambda x: x["created_at"])
            self.prompts = prompts
            self.kprompts = {prompt["uuid"]: prompt for prompt in prompts}
            # print(prompts[0])
            for prompt in prompts:
                name = prompt["name"]
                if name:
                    list_item = QListWidgetItem(name)
                    list_item.setToolTip(prompt["text"])
                    list_item.id = prompt["id"]
                    list_item.uuid = prompt["uuid"]
                    self.addItem(list_item)
                    # list_item.clicked.connect(lambda item: print(f"Clicked on item: {item.text()}"))
        except requests.exceptions.RequestException as e:
            print("Error fetching data:", e)

class PromptsWindow(BorderlessWindow):
    def __init__(self, parent=None):
        super().__init__([Qt.WindowType.WindowStaysOnTopHint], parent)
        self.setStyleSheet("""
            QListWidget{
                border: 1px solid #d9d9d9;
                outline: none;
            }
            QListWidget::item{
                padding: 5px;
            }
            QListWidget::item:selected{
                color: black;
                background-color: #f5f5f5;
            }
            QListWidget::item:hover{
                color: black;
                background-color: #efefef;
            }
            """)
        layout = QVBoxLayout(self)
        self.custom_list_view = CustomListView(self)
        layout.addWidget(self.custom_list_view)
        self.resize(350, 500)


#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import logging

from tornado.ioloop import IOLoop
from tornado.options import define, options
from tornado.web import Application, RequestHandler
from tornado.websocket import WebSocketHandler

rel = lambda *x: os.path.abspath(os.path.join(os.path.dirname(__file__), *x))

class MainHandler(RequestHandler):
	def get(self):
		self.render('index.html')

class WebRTCHandler(RequestHandler):
	def get(self):
		self.render('index3.html')

class EchoWebSocket(WebSocketHandler):
	clients = []

	def open(self):
		logging.info('WebSocket opened from %s', self.request.remote_ip)
		EchoWebSocket.clients.append(self)

	def on_message(self, message):
		logging.info('got message from %s: %s', self.request.remote_ip, message)
		for client in EchoWebSocket.clients:
			if client is self:
				continue
			client.write_message(message)

	def on_close(self):
		logging.info('WebSocket closed')
		EchoWebSocket.clients.remove(self)

class SignallingHandler(WebSocketHandler):
	clients = []

	def open(self):
		logging.info('WebSocket opened from %s', self.request.remote_ip)
		SignallingHandler.clients.append(self)

	def on_message(self, message):
		logging.info('got message from %s: %s', self.request.remote_ip, message)
		for client in SignallingHandler.clients:
			if client is not self:
				client.write_message(message)

	def on_close(self):
		logging.info('WebSocket closed')
		SignallingHandler.clients.remove(self)

def main():
	define('listen', metavar='IP', default='127.0.0.1', help='listen on IP address (default 127.0.0.1)')
	define('port', metavar='PORT', default=8888, type=int, help='listen on PORT (default 8888)')
	define('debug', metavar='True|False', default=False, type=bool,
			help='enable Tornado debug mode: templates will not be cached '
			'and the app will watch for changes to its source files '
			'and reload itself when anything changes')

	options.parse_command_line()

	settings = dict(
			template_path=rel('templates'),
			static_path=rel('static'),
			debug=options.debug
			)

	application = Application([
		(r'/', MainHandler),
		(r'/ws', EchoWebSocket),
		(r'/websocket', SignallingHandler),
		(r'/webrtc', WebRTCHandler)
		], **settings)

	#application.listen(address=options.listen, port=options.port)
	application.listen(7080)
	IOLoop.instance().start()

if __name__ == '__main__':
	main()


from datetime import datetime
from decimal import Decimal
from typing import Any, Dict

import pytest
from bson import Decimal128, ObjectId
from pymongo.database import Database

from surebets_finder.bet.domain.entities import Bet
from surebets_finder.bet.domain.errors import BetNotFoundError
from surebets_finder.bet.infrastructure.mongodb_bet_repo import MongoDBBetRepository
from surebets_finder.shared.category import Category
from surebets_finder.shared.provider import Provider

def test_can_create_bet(mongodb: Database) -> None:
    # given
    repo = MongoDBBetRepository()  # type: ignore

    # and
    bet = Bet(
        id=ObjectId(),
        opponent_1="test 1",
        opponent_2="test 2",
        odds_1=Decimal(4.12),
        odds_2=Decimal(3.56),
        category=Category.ESPORT,
        provider=Provider.EFORTUNA,
        date=datetime.utcnow(),
        url="/test/bet/url",
        updated_at=datetime.utcnow(),
    )

    # when
    repo.create(bet)

    # then
    document = mongodb["bet"].find_one({"_id": bet.id})
    assert document["_id"] == bet.id
    assert document["opponent_1"] == bet.opponent_1
    assert document["opponent_2"] == bet.opponent_2

def test_can_get_bet(mongodb: Database) -> None:
    # given
    repo = MongoDBBetRepository()  # type: ignore

    # when
    bet_id = ObjectId()
    mongodb["bet"].insert_one(
        {
            "_id": bet_id,
            "opponent_1": "test 1",
            "opponent_2": "test 2",
            "odds_1": Decimal128("4.12"),
            "odds_2": Decimal128("3.56"),
            "category": Category.ESPORT.value,
            "provider": Provider.EFORTUNA.value,
            "date": datetime.utcnow(),
            "url": "/test/bet/url",
            "updated_at": datetime.utcnow(),
            "created_at": datetime.utcnow(),
        }
    )

    # and
    bet = repo.get(bet_id)

    # then
    assert isinstance(bet, Bet)
    assert bet.id == bet_id
    assert bet.opponent_1 == "test 1"
    assert bet.opponent_2 == "test 2"
    assert bet.odds_1.compare(Decimal(4.12))
    assert bet.odds_2.compare(Decimal(3.56))
    assert bet.url == "/test/bet/url"

def test_get_bet_should_raise_an_exception_when_entity_does_not_exist(mongodb: Database) -> None:
    # given
    repo = MongoDBBetRepository()  # type: ignore

    # then
    with pytest.raises(BetNotFoundError):
        repo.get(ObjectId())

@pytest.mark.usefixtures("fill_in_db_with_bets_which_are_in_future")
def test_get_all_bets_which_are_in_future(mongodb: Database) -> None:
    # given
    repo = MongoDBBetRepository()  # type: ignore

    # when
    in_future = repo.get_all_which_are_in_future()

    # then
    assert len(in_future) == 5

def test_find_one(mongodb: Database, dummy_bet_document: Dict[str, Any]) -> None:
    # given
    repo = MongoDBBetRepository()  # type: ignore

    # when
    bet = repo.find_one(
        {
            "opponent_1": dummy_bet_document["opponent_1"],
            "opponent_2": dummy_bet_document["opponent_2"],
            "date": dummy_bet_document["date"],
        }
    )

    # then
    assert isinstance(bet, Bet)

def test_find_one_should_raise_an_exception_when_there_is_not_such_bet(
    mongodb: Database, dummy_bet_document: Dict[str, Any]
) -> None:
    # given
    repo = MongoDBBetRepository()  # type: ignore

    # then
    with pytest.raises(BetNotFoundError):
        repo.find_one(
            {"opponent_1": "john", "opponent_2": dummy_bet_document["opponent_2"], "date": dummy_bet_document["date"]}
        )

def test_can_save_bet(mongodb: Database, dummy_bet_id: ObjectId) -> None:
    # given
    repo = MongoDBBetRepository()  # type: ignore

    # and
    bet = repo.get(dummy_bet_id)

    # and
    bet.odds_1 = Decimal(6.12)
    bet.url = "another/new/url"

    # when
    repo.save(bet)

    # then
    document = mongodb["bet"].find_one({"_id": bet.id})
    assert str(document["odds_1"]) == str(round(bet.odds_1, 2))
    assert document["url"] == "another/new/url"


from constructs import Construct
from aws_cdk import (
Stack,
Environment,
SecretValue,
pipelines
)

from .webservice_stage import WebServiceStage

APP_ACCOUNT = '782160816199'

class PipelineStack(Stack):
  def __init__(self, scope: Construct, id: str, **kwargs):
    super().__init__(scope, id, **kwargs)

    source = pipelines.CodePipelineSource.git_hub("abhishekbose86/aws-apigw-lambda-eventbridge-kinesis-S3", "main",
        authentication=SecretValue.secrets_manager("github-token"))
    pipeline = pipelines.CodePipeline(self, 'Pipeline',
      pipeline_name='TestPipeline',

      synth=pipelines.ShellStep("Synth",
        input = source,
        commands=[
          'npm install -g aws-cdk && pip install -r requirements.txt',
          'pytest unittests',
          'cdk synth'
        ]
    ))

    pre_prod_app = WebServiceStage ( self, 'Pre-Prod',
     env = Environment (account = APP_ACCOUNT, region = "us-east-2" ))
    pipeline.add_stage(pre_prod_app)


import os,sys
import shutil
import datetime

from liblda import interfaces

from liblda.util import rungen
from liblda.util import newman_topicmodel

import subprocess

from local_settings import PROJECT_PATH, topicmodel_DIR, RUNDIRS_ROOT

import logging
logger = logging.getLogger('NewmanLdaModel')
logger.setLevel(logging.INFO)

# Errors accociated with this
class IncompleteInputError(Exception):
    """
    The user didn't supply a corpus or numT
    """
    def __init__(self, msg):
        self.msg = msg
    def __str__(self):
        return repr(self.msg)

class ScriptError(Exception):
    """
    An error occurred somewhere in train(), i.e creating rundir
    writing input to disk, mv-ing the executable in place in rundir
    or running ./topicmodel
    """
    def __init__(self, msg):
        self.msg = msg
    def __str__(self):
        return repr(self.msg)

class NewmanLdaModel(interfaces.LdaModelABC):
    """
    A class that calls Dave Newman's Gibbs sampler to train the
    model.

    Parameters:
        numT        : number of topics in model
        alpha       : Dirichlet prior on theta (topics in docs)
                      len: numT   or  constant scalar
        beta        : Dirichlet prior on phi (words in topics)

    Input data:
        corpus      : reference to a corpus object (anything that looks like [[ (termid,count) ]]
        numDocs     : len(corpus)

    Optional input:
        vocab       : ref to Vacabulary object  #calV
                      (which can map word id to word string)
        numTerms    : len(vocab) #V

    API:
        corpus=[[(1,1),(2,4)],[(1,1)]]
        lda = NewmanLdaModel( corpus=corpus, numT=17, alpha=50.0/17, beta=0.01 )
        lda.train()

    Then some time goes by...
    and the following things appear.

    Inferred model:
        phi         : topic-word distribution
                      size: numT x numTerms
                      alias: prob_w_given_t
        theta       : document-topic distibution
                      size: numDocs x numT
                      alias: prob_t_given_d
        z           : the topic assignment
                      size: ?

    """

    def __init__(self, numT=None, alpha=None, beta=None, corpus=None,  vocab=None):
        """
        This creates the LDA model.

        Must supply corpus and numT before you can train() it.
        """
        self.numT = numT                    # number of topics
        self.alpha = alpha                  # Dirichlet prior on theta (topics in docs)
        self.beta  = beta                   # Dirichlet prior on phi (words in topics)

        self.corpus= corpus
        #numDocs = len(corpus)      how do i make this lazy?

        self.vocab = vocab

        self.phi = None
        self.theta = None
        self.z = None

    def is_trained(self):
        """
        Tells you whether model has been trained or not.
        """
        raise NotImplementedError('cannot instantiate abstract base class')

    def train(self, rundir=None, rundir_root=None, iter=50,seed=None):
        """
        Runs the Dave Newman's C code:
         1/ setup a rundir, if no rundir, then create one in /tmp
         2/ write the contents of corpus to  rundir/docword.txt
         3/ extract a copy of the executable for that OS
         4/ run topicmodel
                run topic model(T=10 topics, iter=200 iterations),
                ./topicmodel 10 200 777
         5/ read in  Nwt.txt,  Ndt.txt,  z.txt into
                     p(w|t)    p(t|d)    Z_{d_i,w_j}

        """
        if not self.numT:
            raise  IncompleInputError('Must specify number of topics: self.numT')
        if self.corpus ==None:
            raise  IncompleInputError('Must provide a corpus to train on: self.corpus')

        # params
        self.iter = iter    # iter set to 50 by default..

        if not seed:
            seed = 777
        self.seed = seed

        self.mkrundir(rundir)
        self.copy_topicmodel(rundir)
        self.write_corpus_to_docword(rundir)
        self.run(rundir,iter,seed)
        self.load_probs(rundir)

    def mkrundir(self,rundir):
        # sort out the rundir
        if not rundir:
            # ok so we will generate one
            if not rundir_root:
                rundir_root=RUNDIRS_ROOT
            rundir = rungen.mk_next_rundir(rundir_root)

        # ok so we have a rundir now
        assert os.path.exists(rundir), "rundir doesn't exist!"
        self.rundir = rundir    # tag it onto the LdaModel while we are at it

    def copy_topicmodel(self, rundir):
        # move topicmodel binary into place
        binary = os.path.join(topicmodel_DIR,"topicmodel")
        assert os.path.exists(binary), "topicmodel binary doesn't exist."
        shutil.copy(binary,rundir)

    def write_corpus_to_docword(self, rundir):
        # write corpus to docwords...
        dwfile = os.path.join(rundir,"docword.txt")
        newman_topicmodel.NewmanWriter.writeCorpus(dwfile, self.corpus)
        assert os.path.exists(dwfile), "docword.txt doesn't exist."

    def run(self,rundir,iter,seed):
        # cd to rundir
        os.chdir(rundir)

        # get the party started
        logger.info("Starting Newman's Gibbs sampler")
        #logger.info("Starting run in  "+ rundir )

        runcommand = os.path.join(rundir,"topicmodel") +" "+str(self.numT)+" "+str(iter)+" "+str(seed)
        logger.info("run command: "+runcommand )

        ###### CALLING STARTS  #####################################################
        start_time = datetime.datetime.now()
        (out,err)  = subprocess.Popen(runcommand, shell=True, \
                                                   stdout=subprocess.PIPE, \
                                                   stderr=subprocess.PIPE \
                                                   ).communicate()

        end_time = datetime.datetime.now()
        duration = (end_time-start_time).seconds
        logger.info("run duration: "+str(duration)+" seconds")
        ###### CALLING STOPS  ######################################################

    def load_probs(self,rundir):
        # read Nwt.txt
        fname1 = os.path.join(rundir,"Nwt.txt")
        Nwt=newman_topicmodel.loadsparsemat(fname1)   # teruns an array of counts
        self.Nwt = Nwt
        # make into normalized probability distirbution
        self.phi = newman_topicmodel.conv_Nwt_to_phi(Nwt)

        # read Ndt
        fname2 = os.path.join(rundir,"Ndt.txt")
        Ndt=newman_topicmodel.loadsparsemat(fname2)   # teruns an array of counts
        self.Ndt = Ndt
        # make into normalized probability distirbution
        self.theta = newman_topicmodel.conv_Ndt_to_theta(Ndt)

        logger.info("Done loading LDA model (phi,theta) from files" )


import os, sys

from setuptools import setup, find_packages

def read_requirements():
    """Parse requirements from requirements.txt."""

    reqs_path = os.path.join('.', 'requirements.txt')
    with open(reqs_path, 'r') as f:
        requirements = [line.rstrip() for line in f]
    return requirements

setup(
    name='primely_docker_flask',
    version='0.0.1',
    description='Host Primely on Docker',
    long_description='README.md',
    author='Yoshiki Nakagawa',
    author_email='ben.nakagawa01@gmail.com',
    install_requires=read_requirements(),
    url='https://github.com/yoshiki-o0/primely_package',
    lincense='LICENCE',
    # package_dir={'': 'primely'},
    packages=find_packages(),
    # packages=[
    #     'primely.controller',
    #     'primely.models',
    #     'primely.templates',
    #     'primely.views',
    #     'tests',
    # ],
    test_suite='tests'
)


from functools import lru_cache

@lru_cache
def divs(n):
    s = {1, n}
    for d in range(2, int(n**0.5) + 1):
        if n % d == 0:
            s.add(d)
            s.add(n // d)
    return s

# print(divs(100), len(divs(100)))
a = list(map(int, open('17_adv.txt').readlines()))
# print(a)
mx = -10**10
divs_key = None
for el in a:
    if len(divs(el)) > mx:
        mx = len(divs(el))
        divs_key = divs(el)

ans = []
for i in range(1, len(a)):
    p1, p2 = a[i - 1], a[i]
    if len(divs(p1) & divs_key) >= 3 and len(divs(p2) & divs_key) >= 3:
        ans.append(len(divs(p1) & divs(p2)))
print(len(ans), max(ans))


# flake8: noqa
# fmt: off
import json
import uuid
import pytest
import requests.auth
from CEI_TestSetup import *

def test_incident_key_failure():
    """Test to ensure a faulty (Broken Key) call is handled properly
    API must return 400 error or the test fails
    """

    data = open_json_file("KeyErrorTest.json", False)
    data_call = json.dumps(data).replace("RANDOMIZEGUID", str(uuid.uuid4()))
    api_url = get_API_url()
    # Get API Token
    headers["Authorization"] = get_API_token()

    # construct API Call
    incident_url = f"{api_url}/cad/incidents"
    incident_post_results = requests.post(incident_url, data=data_call, headers=headers)
    if "400" not in str(incident_post_results):
        pytest.fail(f"API post has failed - response: {str(incident_post_results)}")

def test_config_msg_bad_format():
    """Test that the configuration call handles msg format failures gracefully
    Fails if the resulting response indicates success
    """
    data = open_json_file("ConfigurationBadFormatCall.json", False)
    data_call = json.dumps(data).replace("'", '"').replace("|||", "'").replace("|", "")
    api_url = get_API_url()
    # construct API Call
    config_url = f"{api_url}/cad/configuration"
    config_post_results = requests.post(config_url, data=data_call, headers=headers)
    if "200" in str(config_post_results):
        pytest.fail(f"API post has failed - response: {str(config_post_results)}")

def test_config_msg_incomplete():
    """Test that the configuration call handles incomplete failures gracefully
    Fails if the resulting response indicates success
    """
    data = open_json_file("ConfigurationIncompleteCall.json", False)
    data_call = json.dumps(data).replace("'", '"').replace("|||", "'").replace("|", "")
    api_url = get_API_url()
    # construct API Call
    config_url = f"{api_url}/cad/configuration"
    config_post_results = requests.post(config_url, data=data_call, headers=headers)
    if "200" in str(config_post_results):
        pytest.fail(f"API post has failed - response: {str(config_post_results)}")

# fmt: on


import socketio
from mode import Service
from mode.threads import ServiceThread

import settings
from app.meth_one.stream import fx_message_stream_topic_eur_usd, FxStreamMessage, fx_message_live_stream_topic, \
    fx_price_prediction_stream, fx_candle_stream, Candle, fx_candle_1min_stream, PricePrediction
from app.meth_one.utils import read_from_ws_history, read_from_ws_live, process_message
from application import stapp
from utils.stream_helper import stream_last_

m_sio = socketio.AsyncRedisManager(settings.SOCKET_IO_MESSAGE_BROKER, write_only=True)

EURUSD = "EURUSD"

class MethodOne(ServiceThread):

    async def on_start(self) -> None:
        print('MethodOne STARTING')

    @Service.task
    async def web_stream_live_data_eur_usd(self):
        async def result_reader(message):
            await fx_message_live_stream_topic.send(value=FxStreamMessage(message=message, type="TICK"))

        await read_from_ws_live(EURUSD, result_reader)

    @Service.task
    async def web_steam_data_eur_usd(self):
        async def result_reader(message):
            await fx_message_stream_topic_eur_usd.send(value=FxStreamMessage(message=message, type="CANDLE"))

        await read_from_ws_history(EURUSD, result_reader, count=120)

    @Service.task
    async def web_steam_data_eur_jpy(self):
        async def result_reader(message):
            await fx_message_stream_topic_eur_usd.send(value=FxStreamMessage(message=message, type="CANDLE"))

        await read_from_ws_history(EURUSD, result_reader)

async def call_after_process_candle_live_feed(candle):
    await fx_candle_stream.send(value=candle)

@stream_last_(fx_candle_stream, stapp)
async def candle_stream_fx(stream):
    await fx_candle_1min_stream.send(value=stream)

@stapp.agent(fx_message_stream_topic_eur_usd)
async def process_bar_data(views):
    async for fx_msg in views:
        await process_message(fx_msg.message, call_back=call_after_process_candle_live_feed)

@stapp.agent(fx_candle_1min_stream)
async def live_stream_candle_fx_data(messages):
    async  for candle in messages:
        candle: Candle = candle
        await m_sio.emit('candle_live_stream_eur_usd',
                         {
                             "open": candle.open,
                             "close": candle.close,
                             "high": candle.high,
                             "low": candle.low,
                             "date": candle.open_time,
                             "close_time": candle.epoch
                         },
                         namespace='/trading'
                         )

@stapp.agent(fx_message_live_stream_topic)
async def live_stream_fx_data(messages):
    async for fx_msg in messages:
        tick = await process_message(fx_msg.message)
        await m_sio.emit('original_data',
                         {'data': [tick['ask'], tick['bid'], tick['quote']], 'time': tick['timestamp']},
                         namespace='/trading'
                         )

@stapp.agent(fx_price_prediction_stream)
async def fx_price_prediction_stream_broad_cast(predictions):
    async for prediction in predictions:
        prediction: PricePrediction = prediction
        await m_sio.emit('price_prediction',
                         {
                             "time": prediction.time,
                             "price": prediction.price,
                             "price_change": prediction.price_change,
                             "origin_time": prediction.origin_time,
                             "originator": prediction.originator,
                         },
                         namespace='/trading'
                         )