import sys
import threading
import logging
import select
import socket
import hmac
import binascii
import os

sys.path.append(os.path.join(os.getcwd(), '..'))

from common.variables import *

from common.metaclass import ServerVerifier
from common.descriptors import CheckPort
from common.utils import send_message, get_message
from common.decorators import login_required, Log

server_log = logging.getLogger('server')

class MessageProcessor(threading.Thread, metaclass=ServerVerifier):
    listen_port = CheckPort()

    """Class to work with clients messages. Client-server interface"""
    def __init__(self, db, address, port):
        self.listen_address = address
        self.listen_port = port

        self.clients_list = []  # Client sockets list
        self.clients_names = dict()  # Client names with sockets {client_name: client_socket}
        self.messages_list = []  # Messages from all clients

        self.listen_sockets = None

        self.db = db

        self.sock = None

        self.running = True

        super().__init__()

    @login_required
    def process_client_message(self, message, client):
        """Client message processor. Try to send message from a sender to receiver user if it's ok.
        Processing service messages: contacts list request, client exit request, adding new contact
        request, deleting contact request, known users request, public key request.
        If it's not - return "Bad request" response dict or close connection with this client
        """

        server_log.debug(f'Client message processing : {message}')

        if ACTION in message and TIME in message and \
                message[ACTION] in \
                [PRESENCE, MESSAGE, EXIT, GET_CONTACTS, ADD_CONTACT, REMOVE_CONTACT, USERS_REQUEST, PUBLIC_KEY_REQUEST]:
            if message[ACTION] in PRESENCE and USER in message and ACCOUNT_NAME in message[USER]:
                # -- If this is a presence message authorize user ---------
                self.authorize_user(message, client)

            elif DESTINATION in message and SENDER in message and MESSAGE_TEXT in message \
                    and self.clients_names[message[SENDER]] == client:
                # -- Try to send message to a destination user ------------
                if message[DESTINATION] in self.clients_names:
                    self.db.process_message(message[SENDER], message[DESTINATION])
                    self.process_message(self, message)
                    try:
                        send_message(client, RESPONSE_200)
                    except OSError:
                        self.remove_client(client)
                else:
                    response = RESPONSE_400
                    response['ERROR'] = 'User not registered!'
                    try:
                        send_message(client, response)
                    except OSError:
                        pass

            elif message[ACTION] in EXIT and ACCOUNT_NAME in message and\
                    self.clients_names[message[ACCOUNT_NAME]] == client:
                # -- Close client socket if client exit the chat ---------
                self.remove_client(client)

            # -- Contacts list request ----------------------------
            elif message[ACTION] == GET_CONTACTS and USER in message and \
                    self.clients_names[message[USER]] == client:
                response = RESPONSE_202
                response[LIST_INFO] = self.db.get_contacts(message[USER])
                try:
                    send_message(client, response)
                except OSError:
                    self.remove_client(client)

            # -- New contact adding ------------------------------
            elif message[ACTION] == ADD_CONTACT and ACCOUNT_NAME in message and USER in message \
                    and self.clients_names[message[USER]] == client:
                self.db.add_contact(message[USER], message[ACCOUNT_NAME])
                try:
                    send_message(client, RESPONSE_200)
                except OSError:
                    self.remove_client(client)

            # -- Deleting contact -------------------------------
            elif message[ACTION] == REMOVE_CONTACT and ACCOUNT_NAME in message and USER in message \
                    and self.clients_names[message[USER]] == client:
                self.db.remove_contact(message[USER], message[ACCOUNT_NAME])
                try:
                    send_message(client, RESPONSE_200)
                except OSError:
                    self.remove_client(client)

            # -- Known users request ---------------------------
            elif message[ACTION] == USERS_REQUEST and ACCOUNT_NAME in message and \
                    self.clients_names[message[ACCOUNT_NAME]] == client:
                response = RESPONSE_202
                response[LIST_INFO] = [user[0] for user in self.db.users_list()]
                try:
                    send_message(client, response)
                except OSError:
                    self.remove_client(client)

            # -- Public key request -----------------------------------------
            elif message[ACTION] == PUBLIC_KEY_REQUEST and ACCOUNT_NAME in message:
                response = RESPONSE_511
                response[DATA] = self.db.get_pubkey(message[ACCOUNT_NAME])

                if response[DATA]:
                    try:
                        send_message(client, response)
                    except OSError:
                        self.remove_client(client)
                else:
                    response = RESPONSE_400
                    response[ERROR] = 'Нет публичного ключа для данного пользователя'
                    try:
                        send_message(client, response)
                    except OSError:
                        self.remove_client(client)

            # -- Else sending Bad request message -----------------------
            else:
                response = RESPONSE_400
                response[ERROR] = 'Bad Request'
                try:
                    send_message(client, response)
                except OSError:
                    self.remove_client(client)

    @Log
    def process_message(self, message):
        """ Function try to send a message by destinations name """
        if message[DESTINATION] in self.clients_names and self.clients_names[message[DESTINATION]] in self.listen_sockets:
            # -- Send message to the client with DESTINATION account name -------------------------------
            try:
                send_message(self.clients_names[message[DESTINATION]], message)
            except OSError:
                self.remove_client(message[DESTINATION])

            server_log.info(f'Message sent to a user "{message[DESTINATION]}" from user "{message[SENDER]}"')
        elif message[DESTINATION] in self.clients_names and \
                self.clients_names[message[DESTINATION]] not in self.listen_sockets:
            # -- There's now socket for DESTINATION account name ----------------------------------------
            server_log.error(
                f'Connection with client "{message[DESTINATION]}" is lost!')
            self.remove_client(self.clients_names[message[DESTINATION]])
        else:
            server_log.error(f'There\'s no user with "{message[DESTINATION]}" account name')

    def authorize_user(self, message, sock):
        """Authorize user method"""

        server_log.debug(f'Start auth process for {message[USER][ACCOUNT_NAME]}')
        if message[USER][ACCOUNT_NAME] in self.clients_names.keys():
            response = RESPONSE_400
            response[ERROR] = 'Имя пользователя уже занято.'
            try:
                server_log.debug(f'Username busy, sending {response}')
                send_message(sock, response)
            except OSError:
                server_log.debug('OS Error')
                pass
            self.clients_list.remove(sock)
            sock.close()

        # -- Check if client already registered at server ---------------
        elif not self.db.check_user(message[USER][ACCOUNT_NAME]):
            response = RESPONSE_400
            response[ERROR] = 'Пользователь не зарегистрирован.'
            try:
                server_log.debug(f'Unknown username, sending {response}')
                send_message(sock, response)
            except OSError:
                pass
            self.clients_list.remove(sock)
            sock.close()
        else:
            server_log.debug('Correct username, starting passwd check.')
            # -- Starting authentication process -------------------------
            message_auth = RESPONSE_511
            random_str = binascii.hexlify(os.urandom(64))
            message_auth[DATA] = random_str.decode('ascii')

            # -- Creating password and random string hash
            # -- Saving public key server version
            new_hash = hmac.new(self.db.get_hash(message[USER][ACCOUNT_NAME]), random_str, 'MD5')
            digest = new_hash.digest()
            server_log.debug(f'Auth message = {message_auth}')
            try:
                # -- Send it to a client ------------------------------
                send_message(sock, message_auth)
                answer = get_message(sock)
            except OSError as err:
                server_log.debug('Error in auth, data:', exc_info=err)
                sock.close()
                return

            client_digest = binascii.a2b_base64(answer[DATA])
            # -- If client answer is correct save it to a users list
            if RESPONSE in answer and answer[RESPONSE] == 511 and \
                    hmac.compare_digest(digest, client_digest):
                self.clients_names[message[USER][ACCOUNT_NAME]] = sock
                client_ip, client_port = sock.getpeername()
                try:
                    send_message(sock, RESPONSE_200)
                except OSError:
                    self.remove_client(message[USER][ACCOUNT_NAME])

                # -- Add a client to an active users list and saving public key if it's new
                self.db.user_login(
                    message[USER][ACCOUNT_NAME],
                    client_ip,
                    client_port,
                    message[USER][PUBLIC_KEY])
            else:
                response = RESPONSE_400
                response[ERROR] = 'Неверный пароль.'
                try:
                    send_message(sock, response)
                except OSError:
                    pass
                self.clients_list.remove(sock)
                sock.close()

    def service_update_lists(self):
        """Sends a message with status code 205 to a clients method"""
        for client in self.clients_names:
            try:
                send_message(self.clients_names[client], RESPONSE_205)
            except OSError:
                self.remove_client(self.clients_names[client])

    def init_socket(self):
        """Init server socket method"""
        server_log.info(f'Server started at {self.listen_address}:{self.listen_port}')

        # -- Prepare socket ----------------------------------------------------
        transport = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        transport.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        transport.bind((self.listen_address, self.listen_port))

        # -- Setting up this option to disable "accept" function locking state
        transport.settimeout(0.5)

        # -- Starting listen to a socket ---------------------------------------
        self.sock = transport
        self.sock.listen(MAX_CONNECTIONS)

    def remove_client(self, client):
        """Remove client from the client list and form db"""
        server_log.info(f'Client "{client.getpeername()}" is disconnected')
        for name in self.clients_names:
            if self.clients_names[name] == client:
                self.db.user_logout(name)
                del self.clients_names[name]
                break
        self.clients_list.remove(client)
        client.close()

    def run(self):
        """Main Thread cycle.
        Overriding default Thread method "run" and starting it automatically
        """
        self.init_socket()

        while self.running:
            server_log.info(f'Waiting for new client ...')
            try:
                client_socket, client_address = self.sock.accept()
            except OSError as err:
                # -- The error number returns None because it's just a timeout
                # print(err.errno)
                pass
            else:
                server_log.info(f'New client connected from \'{client_address}\'')
                self.clients_list.append(client_socket)

            recv_data_lst = []

            # -- Checking for a clients that are waiting --------------------------------
            try:
                if self.clients_list:
                    recv_data_lst, self.listen_sockets, _ = select.select(
                        self.clients_list, self.clients_list, [], 0)
            except OSError:
                pass

            # -- If client sends data, need to process it's messages or delete it from a clients list
            if recv_data_lst:
                for client_with_message in recv_data_lst:
                    try:
                        server_log.info(
                            f'Creating server response message for client {client_with_message.getpeername()}')
                        self.process_client_message(get_message(client_with_message), client_with_message)
                    except ValueError as value_error:
                        server_log.error(f'Client response message error: {value_error}.')
                        self.remove_client(client_with_message)
                    except Exception as error:
                        server_log.error(f'Client response message error: {error}.')
                        self.remove_client(client_with_message)


from django.http import HttpResponseServerError
from rest_framework.viewsets import ViewSet
from rest_framework.response import Response
from rest_framework import serializers, status
from rest_framework.decorators import action
from rentajetapi.models import FlightBooking, Flight, Customer

class FlightBookingView(ViewSet):
    """Rent a Jet flight bookings typesview"""

    def retrieve(self, request, pk):
        """Gets a flight booking by its pk

        Returns:
            Response --  single JSON serialized flight booking dictionary
        """
        flight_booking = FlightBooking.objects.get(pk=pk)
        serializer = FlightBookingSerializer(flight_booking)
        return Response(serializer.data)

    def list(self, request):
        """Gets all flight bookings

        Returns:
            Response -- JSON serialized list of flight bookings
        """
        flight_bookings = FlightBooking.objects.all()
        """filter by customer id"""
        customer = request.query_params.get('customer_id', None)
        if customer is not None:
                flight_bookings = flight_bookings.filter(customer_id=customer)
        """serialize all list requests"""
        serializer = FlightBookingSerializer(flight_bookings, many=True)
        return Response(serializer.data)

    def create(self, request):
        """Handles POST operations

        Returns:
            Response -- JSON serialized flight booking instance
        """
        flight = Flight.objects.get(pk=request.data["flightId"])
        customer = Customer.objects.get(pk=request.data["customerId"])
        flight_booking = FlightBooking.objects.create(
            flight_id=flight,
            customer_id=customer,
            date=request.data["date"],
            payment_method=request.data["paymentMethod"],
        )
        serializer = FlightBookingSerializer(flight_booking)
        return Response(serializer.data)

    def update(self, request, pk):
        """Handles PUT requests for a flight booking

        Returns:
            Response -- Empty body with 204 status code
        """
        flight_booking = FlightBooking.objects.get(pk=pk)
        customer = Customer.objects.get(pk=request.data["customerId"])
        flight_booking.customer_id=customer
        flight = Flight.objects.get(pk=request.data["flightId"])
        flight_booking.flight_id=flight
        flight_booking.date=request.data["date"]
        flight_booking.payment_method=request.data["paymentMethod"]

        flight_booking.save()

        return Response(None, status=status.HTTP_204_NO_CONTENT)

    def destroy(self, request, pk):
        """Handles DELETE requests for a flight booking

        Returns:
            Response -- Empty body with 204 status code
        """
        flight_booking = FlightBooking.objects.get(pk=pk)
        flight_booking.delete()
        return Response(None, status=status.HTTP_204_NO_CONTENT)

class FlightBookingSerializer(serializers.ModelSerializer):
    class Meta:
        model = FlightBooking
        fields = ('id', 'customer_id', 'flight_id', 'date', 'payment_method')
        depth = 2


#!/usr/bin/env python3

import argparse
import numpy as np
import shlex
import subprocess
import glob
import fileinput
import re

def parse():
    parser = argparse.ArgumentParser(description='Copies objects by changing parameters')
    parser.add_argument('sources', nargs='+', help='specify the name of the source object(s)')
    parser.add_argument('-p', '--prop', help='specify the property', required=True)
    parser.add_argument('-v', '--values', type=float, nargs='+', help='specify the values', required=True)
    return parser.parse_args()

def get_property_from_dir_name(name, prop):
    all_properties = name.split("__")
    for prop_name in all_properties:
        if prop_name.startswith(prop):
            return float(prop_name[len(prop)+1:].replace("o", ".").replace("m", "-"))
    return np.nan

def set_property_from_dir_name(name, prop, value):
    all_properties = name.split("__")
    for i in range(len(all_properties)):
        if all_properties[i].startswith(prop):
            all_properties[i] = prop + "_" + str(value).replace(".", "o").replace("-", "m")
    name = ""
    for prop_name in all_properties:
        name += prop_name + "__"
    return name[:-2]

def file_replace(file_name, text, replacement):
    for line in fileinput.FileInput(file_name, inplace=True):
        print(re.sub(text, replacement, line), end='')

def set_parameter(dest, prop, value):
    if prop == "surftimeconst":
        for file_name in glob.glob(dest + "/**/*surf/_behaviour_time_horizon/const/parameters.h", recursive=True):
            file_replace(file_name, r"value = [^\*]* \*", "value = {value} *".format(value=float(value)))
            print("edited: ", file_name)
    elif prop == "surftimeprefactor":
        for file_name in glob.glob(dest + "/**/*surf/_behaviour_time_horizon/*/parameters.h", recursive=True):
            file_replace(file_name, r"prefactor = [^\*]*;", "prefactor = {value};".format(value=float(value)))
            print("edited: ", file_name)
    elif prop == "vs" or prop == "us":
        for file_name in glob.glob(dest + "/**/*active/**/*swimmer/parameters.h", recursive=True):
            file_replace(file_name, r"velocity = [^\*]* \*", "velocity = {value} *".format(value=float(value)))
            print("edited: ", file_name)
        for file_name in glob.glob(dest + "/**/*passive/kinematic_inertial_point/parameters.h", recursive=True):
            file_replace(file_name, r"velocity = [^\*]* \*", "velocity = {value} *".format(value=float(value)))
            print("edited: ", file_name)
        for file_name in glob.glob(dest + "/**/*passive/kinematic_inertial_point_filtered/parameters.h", recursive=True):
            file_replace(file_name, r"velocity = [^\*]* \*", "velocity = {value} *".format(value=float(value)))
            print("edited: ", file_name)
        file_replace(dest + "/group/homogeneous/parameters.h", r"size = [^\*]* \*", "size = 1/({value}*{value}) *".format(value=float(value)))
        print("edited: ", dest + "/group/homogeneous/parameters.h")
    elif prop == "rtime":
        for file_name in glob.glob(dest + "/**/*active/axis/swim/parameters.h", recursive=True):
            file_replace(file_name, r"time = [^\*]* \*", "time = {value} *".format(value=float(value)))
            print("edited: ", file_name)
    elif prop == "reorientationtime":
        for file_name in glob.glob(dest + "/**/*active/**/local_axis_swimmer/parameters.h", recursive=True):
            file_replace(file_name, r"time = [^\*]* \*", "time = {value} *".format(value=float(value)))
            print("edited: ", file_name)
    elif prop == "proportion":
        for file_name in glob.glob(dest + "/**/*passive/spheroid/parameters.h", recursive=True):
            file_replace(file_name, r"proportion = [^\*]*;", "proportion = {value};".format(value=float(value)))
            print("edited: ", file_name)
    elif prop == "filterlength":
        for file_name in glob.glob(dest + "/**/_sensor/velocity_gradients/filtered/parameters.h", recursive=True):
            file_replace(file_name, r"l = [^\*]* \*", "l = {value} *".format(value=float(value)))
            print("edited: ", file_name)
    elif prop == "swimnoise":
        for file_name in glob.glob(dest + "/**/_behaviour/navigator/swimmer_noisy/parameters.h", recursive=True):
            file_replace(file_name, r"noiseIntensity = [^\*]*;", "noiseIntensity = {value};".format(value=float(value)))
            print("edited: ", file_name)
    elif prop == "dirnoise":
        for file_name in glob.glob(dest + "/**/_sensor/direction/noisy/parameters.h", recursive=True):
            file_replace(file_name, r"noiseIntensity = [^\*]*;", "noiseIntensity = {value};".format(value=float(value)))
            print("edited: ", file_name)
    elif prop == "jnoise":
        for file_name in glob.glob(dest + "/**/_sensor/velocity_gradients/noisy/parameters.h", recursive=True):
            file_replace(file_name, r"noiseIntensity = [^\*]* \*", "noiseIntensity = {value} *".format(value=float(value)))
            print("edited: ", file_name)
    elif prop == "delay":
        for file_name in glob.glob(dest + "/**/*passive/*inertial_point*/parameters.h", recursive=True):
            file_replace(file_name, r"delay = [^\*]* \*", "delay = {value} *".format(value=float(value)))
            print("edited: ", file_name)
    elif prop == "reacttime":
        for file_name in glob.glob(dest + "/**/_behaviour/navigator/rotating_swimmer/parameters.h", recursive=True):
            file_replace(file_name, r"time = [^\*]* \*", "time = {value} *".format(value=float(value)))
            print("edited: ", file_name)
    elif prop == "omegamax":
        for file_name in glob.glob(dest + "/**/_behaviour/navigator/rotating_swimmer/parameters.h", recursive=True):
            file_replace(file_name, r"maxSwimmingAngularVelocity = [^\*/]* /", "maxSwimmingAngularVelocity = {value} /".format(value=float(value)))
            print("edited: ", file_name)

def compute(sources, prop, values):
    for source in sources:
        for value in values:
            dest = set_property_from_dir_name(source, prop, value)
            # execute command
            cmd = "./copy_object {source} {dest}".format(source=source, dest=dest)
            print("INFO: running " + cmd)
            subprocess.call(shlex.split(cmd))
            # set parameter
            set_parameter(dest, prop, value)

def main(source, prop, values):
    compute(source, prop, values)

if __name__ == '__main__':
    # parse arguments
    args = parse()
    # call
    main(args.sources, args.prop, args.values)


import pickle

import tensorflow as tf
from tensorflow import keras

import numpy as np

import matplotlib.pyplot as plt

# reload pickled data
with open('mnist.pickle', 'rb') as fp:
    train_images, train_labels, test_images, test_labels = pickle.load(fp)

class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

# see https://www.tensorflow.org/tutorials/keras/basic_classification
# for notes on what this is actually doing -- focusing my notes on
# slurm modifications
train_images = train_images / 255.0
test_images = test_images / 255.0

model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28)),
    keras.layers.Dense(128, activation=tf.nn.relu),
    keras.layers.Dense(10, activation=tf.nn.softmax)
])

model.compile(optimizer=tf.train.AdamOptimizer(),
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(train_images, train_labels, epochs=10)

test_loss, test_acc = model.evaluate(test_images, test_labels)

# make some predictions and write
predictions = model.predict(test_images)

def plot_image(i, predictions_array, true_label, img):
    predictions_array, true_label, img = predictions_array[i], true_label[i], img[i]
    plt.grid(False)
    plt.xticks([])
    plt.yticks([])

    plt.imshow(img, cmap=plt.cm.binary)

    predicted_label = np.argmax(predictions_array)
    if predicted_label == true_label:
        color = 'blue'
    else:
        color = 'red'

    plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label],
                                100*np.max(predictions_array),
                                class_names[true_label]),
                                color=color)

def plot_value_array(i, predictions_array, true_label):
    predictions_array, true_label = predictions_array[i], true_label[i]
    plt.grid(False)
    plt.xticks([])
    plt.yticks([])
    thisplot = plt.bar(range(10), predictions_array, color="#777777")
    plt.ylim([0, 1])
    predicted_label = np.argmax(predictions_array)

    thisplot[predicted_label].set_color('red')
    thisplot[true_label].set_color('blue')
    fig = plt.savefig('output.png')

# Plot the first X test images, their predicted label, and the true label
# Color correct predictions in blue, incorrect predictions in red
num_rows = 5
num_cols = 3
num_images = num_rows*num_cols
plt.figure(figsize=(2*2*num_cols, 2*num_rows))
for i in range(num_images):
  plt.subplot(num_rows, 2*num_cols, 2*i+1)
  plot_image(i, predictions, test_labels, test_images)
  plt.subplot(num_rows, 2*num_cols, 2*i+2)
  plot_value_array(i, predictions, test_labels)

#@title MIT License
#
# Copyright (c) 2017 François Chollet
# Adaptation for Slurm use (c) 2018 Benjamin Hicks
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.


from django.urls import path, include
from . import views

urlpatterns = [
    path('ngo', views.index, name="ngo"),
    path('edit', views.edit, name="edit"),
    path('ngo-logout', views.logout, name="ngo-logout")
]

# aa


import customtkinter
import requests
from bs4 import BeautifulSoup
import tkinter as tk
from tkinter import filedialog
from tkinter import messagebox
from openpyxl import Workbook
from urllib.parse import urlparse, urljoin

def is_valid_url(url, base_url):
	"""Проверяет, является ли URL действительным и относится ли к базовому URL."""
	parsed = urlparse(url)
	return bool(parsed.netloc) and parsed.netloc == urlparse(base_url).netloc

def get_page_data(url):
	"""Получает данные о заголовке, описании и тегах h1-h6 страницы."""
	response = requests.get(url)
	response.raise_for_status()
	soup = BeautifulSoup(response.text, 'html.parser')

	title = soup.title.string if soup.title else ''
	description = soup.find('meta', attrs={'name': 'description'})[
		'content'] if soup.find('meta', attrs={'name': 'description'}) else ''
	h1 = soup.find('h1').text if soup.find('h1') else ''
	h2 = soup.find('h2').text if soup.find('h2') else ''
	h3 = soup.find('h3').text if soup.find('h3') else ''
	h4 = soup.find('h4').text if soup.find('h4') else ''
	h5 = soup.find('h5').text if soup.find('h5') else ''
	h6 = soup.find('h6').text if soup.find('h6') else ''

	return title, description, h1, h2, h3, h4, h5, h6

def crawl_website():
	url = entry.get()

	try:
		response = requests.get(url)
		response.raise_for_status()
		soup = BeautifulSoup(response.text, 'html.parser')
		base_url = urlparse(url).scheme + "://" + urlparse(url).netloc

		links = [urljoin(base_url, link.get('href')) for link in
		         soup.find_all('a')]
		pages = list(filter(lambda link: is_valid_url(link, base_url), links))

		total_pages = len(pages)

		if total_pages == 0:
			messagebox.showinfo("Информация",
			                    "На веб-сайте не найдено страниц.")
			return

		save_path = filedialog.asksaveasfilename(defaultextension=".xlsx")
		if save_path:
			workbook = Workbook()
			sheet = workbook.active

			# Заголовки столбцов
			sheet['A1'] = 'URL'
			sheet['B1'] = 'Title'
			sheet['C1'] = 'Description'
			sheet['D1'] = 'H1'
			sheet['E1'] = 'H2'
			sheet['F1'] = 'H3'
			sheet['G1'] = 'H4'
			sheet['H1'] = 'H5'
			sheet['I1'] = 'H6'

			for index, page in enumerate(pages, start=2):
				title, description, h1, h2, h3, h4, h5, h6 = get_page_data(
					page)

				sheet.cell(row=index, column=1).value = page
				sheet.cell(row=index, column=2).value = title
				sheet.cell(row=index, column=3).value = description
				sheet.cell(row=index, column=4).value = h1
				sheet.cell(row=index, column=5).value = h2
				sheet.cell(row=index, column=6).value = h3
				sheet.cell(row=index, column=7).value = h4
				sheet.cell(row=index, column=8).value = h5
				sheet.cell(row=index, column=9).value = h6

				# Обновление счетчика прогресса
				progress_label.configure(
					text=f"Просканировано {index - 1} из {total_pages}")
				root.update()

			workbook.save(save_path)

			messagebox.showinfo("Готово!",
			                    f"Страницы успешно сохранены! Сохранено: {total_pages}")

			# Отображение кнопки "Open File" для открытия сохраненного файла
			def open_file():
				import os
				os.startfile(save_path)

			button_open = tk.Button(root, text="Open File", command=open_file)
			button_open.pack(pady=10)
		else:
			messagebox.showinfo("Информация", "Сохранение файла отменено.")

		# Очистка метки и поля ввода
		entry.delete(0, tk.END)
		progress_label.config(text="")

	except requests.exceptions.RequestException as e:
		messagebox.showerror("Ошибка", f"Произошла ошибка: {e}")

# Создание главного окна
root = customtkinter.CTk()
root.title("OneScanner")
customtkinter.set_default_color_theme("green")
customtkinter.set_appearance_mode("dark")
# Размер окна
window_width = 330
window_height = 180

# Определение положения окна на экране
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
x = int((screen_width / 2) - (window_width / 2))
y = int((screen_height / 2) - (window_height / 2))
root.geometry(f"{window_width}x{window_height}+{x}+{y}")

# Создание метки и поля ввода для URL веб-сайта
# label = tk.Label(root, text="Введите URL веб-сайта:")
# label.pack()
entry = customtkinter.CTkEntry(root, placeholder_text="Введите URL веб-сайта:", width=250)
entry.pack(pady=20)

# Создание кнопки для запуска процесса сканирования
button = customtkinter.CTkButton(root, text="Сканировать", command=crawl_website)
button.pack(pady=10)

# Метка для отображения прогресса
progress_label = customtkinter.CTkLabel(root, text="")
progress_label.pack(pady=10)

# Запуск цикла обработки событий Tkinter
root.mainloop()


import scrapy
from ..items import PlaystoreDatasetItem
main_list=[]
class DatasetSpider(scrapy.Spider):
    name = 'dataset'
    allowed_domains=["play.google.com"]
    start_urls = [
        'https://play.google.com/store/apps/collection/cluster?clp=0g4lCiMKHXRvcHNlbGxpbmdfZnJlZV9DT01NVU5JQ0FUSU9OEAcYAw%3D%3D:S:ANO1ljJhLKU&gsr=CijSDiUKIwoddG9wc2VsbGluZ19mcmVlX0NPTU1VTklDQVRJT04QBxgD:S:ANO1ljIDVBk'
        ]

    def parse(self, response):
        apps=PlaystoreDatasetItem()
        dev_link=[]
        app_name=response.css('.WsMG1c.nnK0zc::text').extract()
        app_developer=response.css('.KoLSrc::text').extract()
        app_link=response.css('.b8cIId.ReQCgd.Q9MA7b a::attr(href)').extract()
        app_developer_link=response.css('.b8cIId.ReQCgd.KoLSrc a.mnKHRc::attr(href)').extract()
        #apps['app_name']=app_name
        # apps['app_developer']=app_developer
        # apps['app_link']=app_link
        #apps['app_developer_link']=app_developer_link
        for link in app_link:
            dev_link.append(link.split('=')[-1])
        #print(dev_link)
        for x in dev_link:
            main_list.append(x)
        temp_list = []
        for i in main_list:
            if i not in temp_list:
                temp_list.append(i)
        mylist = temp_list
        #print(temp_list)
        print("List After removing duplicates ", len(mylist))

        print(mylist)


from __future__ import absolute_import

import datetime

import anyconfig.backend.toml as TT
import anyconfig.backend.tests.ini

from anyconfig.compat import OrderedDict as ODict

# Taken from https://github.com/toml-lang/toml:
CNF_S = """title = "TOML Example"

[owner]
name = "Tom Preston-Werner"
dob = 1979-05-27T07:32:00-08:00 # First class dates

[database]
server = "192.168.1.1"
ports = [ 8001, 8001, 8002 ]
connection_max = 5000
enabled = true

[servers]

  [servers.alpha]
  ip = "10.0.0.1"
  dc = "eqdc10"

  [servers.beta]
  ip = "10.0.0.2"
  dc = "eqdc10"

  [clients]
  data = [ ["gamma", "delta"], [1, 2] ]

hosts = [
  "alpha",
  "omega"
]
"""

CNF = ODict((('clients',
              ODict((('data', [['gamma', 'delta'], [1, 2]]),
                     ('hosts', ['alpha', 'omega'])))),
             ('database',
              ODict((('connection_max', 5000),
                     ('enabled', True),
                     ('ports', [8001, 8001, 8002]),
                     ('server', '192.168.1.1')))),
             ('owner',
              ODict((('dob', datetime.datetime(1979, 5, 27, 7, 32)),
                     ('name', 'Tom Preston-Werner')))),
             ('servers',
              ODict((('alpha',
                      ODict((('dc', 'eqdc10'), ('ip', '10.0.0.1')))),
                     ('beta',
                      ODict((('dc', 'eqdc10'), ('ip', '10.0.0.2'))))))),
             ('title', 'TOML Example')))

class Test10(anyconfig.backend.tests.ini.Test10):

    cnf = CNF
    cnf_s = CNF_S
    load_options = dump_options = dict(dummy="this_will_be_ignored")
    is_order_kept = False  # ..note:: toml backend cannot do this yet.

    def setUp(self):
        self.psr = TT.Parser()

class Test20(anyconfig.backend.tests.ini.Test20):

    psr_cls = TT.Parser
    cnf = CNF
    cnf_s = CNF_S
    cnf_fn = "cnf.toml"

# vim:sw=4:ts=4:et:


#!/usr/bin/env python3

import os
from time import sleep
import math

import RPi.GPIO as gpio
gpio.setwarnings(False)

from lib.shifter import Shifter
from lib.mcp3008 import MCP3008
from lib.hpdl1414 import hpdl_blank, \
    hpdl_write_word, multi_hpdl_write_word, \
    hpdl_loop_words, multi_hpdl_loop_words

## ------------------------------------------------------------------------
# RASPI GPIO - CONF

# 14 - DS / SER    - serial data input          -  data pin
SHIFTER_DATA = 11
# 11 - SH_CP / SCK - shift register clock pin   -  clock pin
SHIFTER_CLK = 12
# 12 - ST_CP / RCK - storage register clock pin -  latch pin
SHIFTER_LATCH = 13

# HPDL-1414 WRT pins
WRT1414_1 = 15
WRT1414_2 = 16

kbd_swtch = 10

# MCP3008 (ADC) pins, using HW SPI0
MCP3008_SPI_BUS   = 0
MCP3008_SPI_DEVICE = 0
# raspi 19 (MOSI) -> DIN
# raspi 21 (MISO) -> DOUT
# raspi 21 (SCLK) -> CLK
# raspi 21 (CE0)  -> CS/SHDN

## ------------------------------------------------------------------------
# RASPI GPIO - SETUP

gpio.setmode(gpio.BOARD)

shifter = Shifter(data=SHIFTER_DATA, clock=SHIFTER_CLK, latch=SHIFTER_LATCH)

gpio.setup(WRT1414_1, gpio.OUT)
gpio.setup(WRT1414_2, gpio.OUT)
# disable write
gpio.output(WRT1414_1, gpio.HIGH)
gpio.output(WRT1414_2, gpio.HIGH)

gpio.setup(kbd_swtch, gpio.IN, pull_up_down=gpio.PUD_DOWN)

adc = MCP3008(bus=MCP3008_SPI_BUS, device=MCP3008_SPI_DEVICE)

## ------------------------------------------------------------------------
## MAIN

def main():
    pause = 0.2
    running = True

    char_row_index = 0
    digit_index = 0

    words = []
    with open(os.path.abspath(os.path.dirname(__file__)) + '/rsc/words.txt') as f:
        for w in f:
            words.append(w.strip().lower())

    def kbd_swtch_pressed():
        return gpio.input(kbd_swtch) == gpio.HIGH
    try:
        # reset shifter data
        shifter.clear()

        # blank displays
        hpdl_blank(WRT1414_1, shifter)
        hpdl_blank(WRT1414_2, shifter)

        # words = ["", "ceci", "est", "un", "test"]
        # hpdl_loop_words(WRT1414_1, shifter, words, infinite=True)

        # words = ["tulipe", "patate", "canard", "tomate"]
        # multi_hpdl_loop_words([WRT1414_1, WRT1414_2], shifter, words, infinite=False, align='center')

        # words = ["tulipe", "patate", "canard", "tomate", "limace", "violon", "carotte", "lasagne", "salade"]
        # multi_hpdl_loop_words([WRT1414_1, WRT1414_2], shifter, words, infinite=True, align='center',
        #                       predicate=kbd_swtch_pressed)

        # hpdl_loop_charset(WRT1414_1, shifter, 0, infinite=False)

        # multi_hpdl_write_word([WRT1414_1, WRT1414_2], shifter, "eignbahn")
        # multi_hpdl_write_word([WRT1414_1, WRT1414_2], shifter, "nornzine")

        while True:
            # v = math.log(adc.read(0) + 0.01)
            v1 = adc.read(0)
            if v1 >= 1000:
                v1 = 999
            multi_hpdl_write_word([WRT1414_1, WRT1414_2], shifter, words[v1])
            sleep(0.1)

    except KeyboardInterrupt:
        print("Bye")
        running = False

if __name__=="__main__":
    main()


from pyzbar.pyzbar import decode
from PIL import Image

def decode_qr():
    img = Image.open(str(input('Enter the QR code pathway: '))) # see tutorial in encoding_qr.py if you don't know how to get it :)
    data = decode(img)
    print(data)

print(decode_qr())


# Importing libraries
import os
from flask import Flask, render_template, request, redirect, flash
from flask_sqlalchemy import SQLAlchemy
from wtforms import StringField, validators, SubmitField, ValidationError
from flask_wtf import FlaskForm
from forms import Add, Delete

# declaring database location
project_dir = os.path.dirname(os.path.abspath(__file__))
database_file = "sqlite:///{}".format(os.path.join(project_dir, "backpack_database.db"))

# Declaring app, database file, and secret key
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = database_file
app.config['SECRET_KEY'] = os.urandom(20)

db = SQLAlchemy(app)

# Defining database model
class Backpack(db.Model):
    id = db.Column(db.Integer, unique=True, nullable=False, primary_key=True)
    amount = db.Column(db.Integer, nullable=False)
    item = db.Column(db.String(80), unique=True, nullable=False)

db.create_all()

# Home page route
@app.route("/", methods=["GET", "POST"])
def home():
    form_add = Add() # Defining forms
    form_delete = Delete()
    if request.method == 'POST' and form_add.validate_on_submit(): # Adding item into database,
        item_name = " ".join(form_add.item.data.lower().split()) # Gets rid of extra spaces before, inbetween, and after text
        item = Backpack(item=item_name, amount=1)
        database_item = Backpack.query.filter_by(item=item_name).first()
        if database_item == None: # checking if item is in database
            db.session.add(item)
            db.session.commit()
            return redirect('/')
        else:
            database_item.amount = database_item.amount + 1 # Incrementing item amount if item is in database
            db.session.commit()
            return redirect('/')
    backpack_items = Backpack.query.all()
    return render_template("home.html", backpack_items=backpack_items, form_add=form_add, form_delete=form_delete)

# Route for delete function
@app.route('/delete', methods=["POST", "GET"])
def delete():
    form = Delete() # Defining delete form
    if request.method == 'POST' and form.validate():
        item_name = " ".join(form.item.data.lower().split()) # Gets rid of extra spaces before, inbetween, and after text
        backpack_item = Backpack.query.filter_by(item=item_name).first()
        if backpack_item == None: # Checks if the item is in the database
            print("no such item in db")
        else:
            db.session.delete(backpack_item)
            flash("Successfully Deleted {}".format(backpack_item.item))
            db.session.commit()
    return redirect('/')

# Route for incrementing amounts of an item in the backpack
@app.route('/increase', methods=["POST", "GET"])
def increase():
    if request.method == 'POST':
        item = request.form.get("item_name")
        if item != None:
            item = item.strip().lower()
            database_item = Backpack.query.filter_by(item=item).first() # Searches database for item and increments it
            database_item.amount = database_item.amount + 1
            db.session.commit()
        else:
            flash("Item was not in database")
    return redirect('/')

# Route for decreasing the amount of an item in the backpack
@app.route('/decrease', methods=["POST", "GET"])
def decrease():
    if request.method == 'POST':
        item = request.form.get("item_name")
        if item != None:
            item = item.strip().lower()
            database_item = Backpack.query.filter_by(item=item).first() # Searches database for item and increments it
            if database_item.amount > 1:
                database_item.amount = database_item.amount - 1
                db.session.commit()
            else:
                db.session.delete(database_item)
                db.session.commit()
        else:
            flash("Item was not in database")
    return redirect('/')

@app.errorhandler(404)
def error404(e):
    return render_template("error404.html")

if __name__ == "__main__":
    app.run(debug=True)


from master.factory import dart_commands
from master.factory import gclient_factory

import config

class DartFactory(gclient_factory.GClientFactory):
  """Encapsulates data and methods common to the dart master.cfg files."""

  DEFAULT_TARGET_PLATFORM = config.Master.default_platform

  # A map used to skip dependencies when a test is not run.
  # The map key is the test name. The map value is an array containing the
  # dependencies that are not needed when this test is not run.
  NEEDED_COMPONENTS = {
  }

  NEEDED_COMPONENTS_INTERNAL = {
  }

  if config.Master.trunk_internal_url:
    CUSTOM_DEPS_JAVA = ('dart/third_party/java',
                        config.Master.trunk_internal_url +
                        '/third_party/openjdk')

  def __init__(self, build_dir, target_platform=None, trunk=False):
    solutions = []
    self.target_platform = target_platform
    deps_file = '/deps/all.deps'
    dart_url = config.Master.dart_bleeding + deps_file
    # If this is trunk use the deps file from there instead.
    if trunk:
      dart_url = config.Master.dart_trunk + deps_file
    custom_deps_list = []

    if config.Master.trunk_internal_url:
      custom_deps_list.append(self.CUSTOM_DEPS_JAVA)

    main = gclient_factory.GClientSolution(
        dart_url,
        needed_components=self.NEEDED_COMPONENTS,
        custom_deps_list = custom_deps_list)
    solutions.append(main)

    gclient_factory.GClientFactory.__init__(self, build_dir, solutions,
                                            target_platform=target_platform)

  def DartFactory(self, target='Release', clobber=False, tests=None,
                  slave_type='BuilderTester', options=None,
                  compile_timeout=1200, build_url=None,
                  factory_properties=None, env=None):
    factory_properties = factory_properties or {}
    tests = tests or []
    # Create the spec for the solutions
    factory_properties['gclient_transitive'] = True
    gclient_spec = self.BuildGClientSpec(tests)
    # Initialize the factory with the basic steps.
    factory = self.BaseFactory(gclient_spec,
                               factory_properties=factory_properties)
    # Get the factory command object to create new steps to the factory.
    dart_cmd_obj = dart_commands.DartCommands(factory,
                                              target,
                                              self._build_dir,
                                              self._target_platform,
                                              env=env)

    # We must always add the MaybeClobberStep, since this factory is
    # created at master start, but the choice of clobber or not may be
    # chosen at runtime (e.g. check the 'clobber' box).
    dart_cmd_obj.AddMaybeClobberStep(clobber, options=options)

    # Add the compile step if needed.
    if slave_type in ['BuilderTester', 'Builder', 'Trybot']:
      dart_cmd_obj.AddCompileStep(options=options,
                                  timeout=compile_timeout)

    # Add all the tests.
    if slave_type in ['BuilderTester', 'Trybot', 'Tester']:
      dart_cmd_obj.AddTests(options=options)

    return factory

  def DartAnnotatedFactory(self, python_script,
                           target='Release', tests=None,
                           timeout=1200, factory_properties=None,
                           env=None):
    factory_properties = factory_properties or {}
    tests = tests or []
    # Create the spec for the solutions
    gclient_spec = self.BuildGClientSpec(tests)
    # Initialize the factory with the basic steps.
    factory = self.BaseFactory(gclient_spec,
                               factory_properties=factory_properties)
    # Get the factory command object to create new steps to the factory.
    dart_cmd_obj = dart_commands.DartCommands(factory,
                                              target,
                                              self._build_dir,
                                              self._target_platform,
                                              env=env)
    dart_cmd_obj.AddAnnotatedSteps(python_script, timeout=timeout)
    return factory


import os
import numpy as np
import torch
import data_egom
import glob
import matplotlib.pyplot as plt
import open3d as o3d
import pickle
import cv2
import time

class Inference:
    def __init__(self):
        self.height = 480
        self.width = 854
        self.frame_idxs = [0]
        self.data_path = '...'
        self.kitchen = 'P03_EPIC_100'

        self.device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
        self.dataset = data_egom.VideoSequentialDataset(self.data_path, self.kitchen, self.height, self.width, self.frame_idxs)
        self.palette = self.dataset.colors
        self.output_dir = os.path.join(self.data_path, self.kitchen, '3D_output')
        if not os.path.exists(self.output_dir):
            os.mkdir(self.output_dir)
        self.output_dir_2d = os.path.join(self.data_path, self.kitchen, 'aff_on_2d')
        if not os.path.exists(self.output_dir_2d):
            os.mkdir(self.output_dir_2d)

        self.alpha = 0.6
        self.depth_model_type = "DPT_Hybrid" #"DPT_Large"
        self.depth_model = torch.hub.load("intel-isl/MiDaS", self.depth_model_type)
        self.depth_model.to(self.device)
        self.depth_model.eval()
        self.depth_transforms = torch.hub.load("intel-isl/MiDaS", "transforms").dpt_transform

    def depth_extractor(self, img, filename):
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        input_batch = self.depth_transforms(img).to(self.device)
        with torch.no_grad():
            prediction = self.depth_model(input_batch)
            prediction = torch.nn.functional.interpolate(
                prediction.unsqueeze(1),
                size=img.shape[:2],
                mode="bicubic",
                align_corners=False,).squeeze()
            disparity = prediction.cpu().numpy()
            depth = 1 / disparity
        return depth

    def paint_affordance_hotpots(self, points, label): #SIMPLIFY THIS FUNCTION
        mask = np.zeros((self.height, self.width))
        aff = label
        aff_center = np.array(aff['affordance_center'])
        cv2.circle(mask, (int(aff_center[0]), int(aff_center[1])), 0, 1, -1)
        mask = mask.astype(bool)
        points = points[mask]

        painting_color = np.array(self.palette[label['verb_id']])
        img = (np.ones((self.height, self.width, 3)) * painting_color)[mask]
        return points, img

    def obtain_rgbd(self, depth, scale):
        z = depth * scale
        x = (np.tile(np.arange(self.width), (self.height, 1)) - self.dataset.cx) * z / self.dataset.fx
        y = (np.tile(np.arange(self.height), (self.width, 1)).T - self.dataset.cy) * z / self.dataset.fy
        points = np.stack([x, y, z], axis=2) #h, w, 3
        return points

    def new_scale_SfM_depth(self, depth, colmap_depths, colmap_coords):
        SfM_depth, NN_depth = [], []
        for kypt in range(len(colmap_coords)):
            SfM_depth.append(colmap_depths[kypt]) #Interpretation 1 of the depth: La distancia entre el plano de la camara y el plano paralelo que corta el punto en 3D
            # Change order in coords, from XY to YX!!!
            u_interp = colmap_coords[kypt, 1] % 1
            v_interp = colmap_coords[kypt, 0] % 1
            u = int(colmap_coords[kypt, 1])
            v = int(colmap_coords[kypt, 0])
            if u < self.width - 1 and v < self.height - 1:
                interpolated_NN_depth = (1 - u_interp) * (1 - v_interp) * depth[v, u] + u_interp * (1 - v_interp) * depth[v, u + 1] + (1 - u_interp) * v_interp * depth[v + 1, u] + u_interp * v_interp * depth[v + 1, u + 1]
                NN_depth.append(interpolated_NN_depth)
            if u > self.width:
                print('alerta 1 !!!', u)
            if v > self.height:
                print('alerta  2 !!!', v)
        local_scale = np.median(np.array(SfM_depth)) / np.median(np.array(NN_depth))
        return local_scale

    def image_to_extrinsics(self, img):
        Rc, tc = img.qvec2rotmat(), img.tvec
        t = -Rc.T @ tc
        R = Rc.T
        return R, t

    def paint_aff_on_2D(self, img, frame_dict, keypoints):
        label = frame_dict["aff_annotation"]
        img_name = frame_dict['filename']
        ep100_label = frame_dict['EP100_annotation']
        visors_objects = frame_dict['VISOR_annotation']
        font = cv2.FONT_HERSHEY_PLAIN
        c = 0
        if label is not None:
            for h in range(len(label['hands'])):
                hand_bbox = label['hands'][h]['hand_bbox']
                cv2.rectangle(img, (hand_bbox[0], hand_bbox[1]), (hand_bbox[2], hand_bbox[3]), color=(0, 255, 0), thickness=2)
            for o in range(len(label['neutral_objects'])):
                obj_bbox = label['neutral_objects'][o]['noun_bbox']
                cv2.rectangle(img, (obj_bbox[0], obj_bbox[1]), (obj_bbox[2], obj_bbox[3]), color=(0, 255, 255), thickness=2)
            for aff_o in range(len(label['interacting_objects'])):
                obj_bbox = label['interacting_objects'][aff_o]['noun_bbox']
                cv2.rectangle(img, (obj_bbox[0], obj_bbox[1]), (obj_bbox[2], obj_bbox[3]), color=(255, 0, 0), thickness=5)
                x_center, y_center = label['interacting_objects'][aff_o]['affordance_center']
                cv2.circle(img, (int(x_center), int(y_center)), radius=10, color=(255, 0, 0), thickness=15)
                text = 'The ' + label['interacting_objects'][aff_o]['hand'] + ' is ' + label['interacting_objects'][aff_o]['verb'] + ' the ' + label['interacting_objects'][aff_o]['noun']
                cv2.putText(img, text, (10, 30 * (c + 1)), font, 1.5, (0, 255, 0), 2, cv2.LINE_AA)
                c += 1
        if keypoints is not None:
            for kp in range(len(keypoints)):
                cv2.circle(img, (int(keypoints[kp, 1]), int(keypoints[kp, 0])), radius=1, color=(255, 255, 255), thickness=1)
        if ep100_label is not None:
            for i in range(len(ep100_label)):
                text = 'EP100 origi is: ' + ep100_label[i]['non_remapped_noun'] + ' remapped: ' + ep100_label[i]['noun'] + ' The verb ' + ep100_label[i]['verb']
                cv2.putText(img, text, (10, 100 + i*20), font, 1.5, (255,0,0), 2, cv2.LINE_AA)
        for i in range(len(visors_objects)):
            cv2.putText(img, 'Object given by VISOR ' + visors_objects[i], (10, 110 + 30 * (i + 1)), font, 1.5, (0,0,255), 2, cv2.LINE_AA)
        cv2.imwrite(os.path.join(self.output_dir_2d, img_name), img)

    def run(self):
        all_abs_depth, all_abs_colors, cameras, all_keypoints, all_rgb_keypoints = [], [], [], [], []
        global_counter = 0
        for i in range(len(self.dataset)):
            output_all = {}
            frame_dict = self.dataset[i]

            print('---------We are analying the frame', i, '--------- corresponding to the image', frame_dict['filename'], '---------')
            try:
                v = next(v for v in self.dataset.imgs_Colmap.values() if v.name == frame_dict['filename'])
            except:
                if frame_dict['exists_affordance']:
                    global_counter += 1
                print('We lost the camera pose for this image')
                continue

            R, t = self.image_to_extrinsics(v) #Location of camera with respect to the world
            cameras.append(t)
            label_t = frame_dict["aff_annotation"]
            colmap_coords = None
            output_all['EGOMETRIC_label'] = {'affordance_labels': []}
            if frame_dict['exists_affordance']:
                colmap_depths = np.array([(v.qvec2rotmat() @ self.dataset.pts_Colmap[p3d].xyz + v.tvec)[2] for p3d in v.point3D_ids[v.point3D_ids > -1]]) #WE PASS TO CAMERA COORDINATES
                colmap_coords = np.array([v.xys[np.where(v.point3D_ids == p3d)][0, ::-1] for p3d in v.point3D_ids[v.point3D_ids > -1]]) #Depth of the keypoints in the camera coordinates
                colmap_keypoints = np.array([self.dataset.pts_Colmap[p3d].xyz for p3d in v.point3D_ids[v.point3D_ids > -1]]) #Absolute coordinates
                colmap_rgb = np.array([self.dataset.pts_Colmap[p3d].rgb for p3d in v.point3D_ids[v.point3D_ids > -1]]) #Absolute coordinates
                colmap_rgb = self.alpha * colmap_rgb + (1 - self.alpha) * 255
                all_keypoints.append(colmap_keypoints)
                all_rgb_keypoints.append(colmap_rgb)
                depth = self.depth_extractor(frame_dict[('color', 0)], frame_dict['filename']) #Depth map in image coordinates (Relative!!)
                local_scale = self.new_scale_SfM_depth(depth, colmap_depths, colmap_coords)
                rescaled_rgbd = self.obtain_rgbd(depth, local_scale)

                for aff in range(len(label_t['interacting_objects'])):
                    rel_points, rel_colors = self.paint_affordance_hotpots(rescaled_rgbd, label_t['interacting_objects'][aff])
                    abs_points = np.dot(R, rel_points.reshape(-1, 3).T).T + t
                    abs_colors = np.reshape(rel_colors, (-1, 3))
                    #abs_points = np.concatenate((abs_points, abs_points + np.random.randn(20, 3) * 0.1), axis=0)
                    #abs_colors = np.concatenate((abs_colors, abs_colors + np.random.randn(20, 3) * 0), axis=0)
                    all_abs_depth.append(abs_points)
                    all_abs_colors.append(abs_colors)
                    dict_aff = {'3D_aff_points': abs_points,
                                '3D_aff_colors': abs_colors,
                                'aff_noun': label_t['interacting_objects'][aff]['noun'],
                                'aff_noun_id': label_t['interacting_objects'][aff]['noun_id'],
                                'aff_verb': label_t['interacting_objects'][aff]['verb'],
                                'aff_verb_id': label_t['interacting_objects'][aff]['verb_id']}
                    output_all['EGOMETRIC_label']['affordance_labels'].append(dict_aff)
                    #output_all['EGOMETRIC_label'][aff]['aff_' + str(aff)] = abs_points
                    #output_all['EGOMETRIC_label'][aff]['aff_rgb_' + str(aff)] = abs_colors
                    #output_all['EGOMETRIC_label'][aff]['aff_noun_' + str(aff)] = label_t['interacting_objects'][aff]['noun']
                    #output_all['EGOMETRIC_label'][aff]['aff_noun_id_' + str(aff)] = label_t['interacting_objects'][aff]['noun_id']
                    #output_all['EGOMETRIC_label'][aff]['aff_verb_' + str(aff)] = label_t['interacting_objects'][aff]['verb']
                    #output_all['EGOMETRIC_label'][aff]['aff_verb_id_' + str(aff)] = label_t['interacting_objects'][aff]['verb_id']
            #self.paint_aff_on_2D(frame_dict[('color', 0)], frame_dict, colmap_coords)
            output_all['colmap'] = {}
            output_all['colmap']['keypoints_3D'] = colmap_keypoints
            output_all['colmap']['keypoints_rgb'] = colmap_rgb
            output_all['colmap']['keypoints_2D'] = colmap_coords
            output_all['colmap']['R_pos'] = R #Rotation matrix of the camera
            output_all['colmap']['t_pos'] = t #Translation vector of the camera
            output_all['VISOR'] = {}
            if label_t is not None:
                output_all['VISOR']['neutral_objects'] = label_t['neutral_objects']
                output_all['VISOR']['hands'] = label_t['hands']
                output_all['VISOR']['interacting_objects'] = label_t['interacting_objects']
                output_all['EPIC_100'] = frame_dict['EP100_annotation']
            output_all['filename'] = frame_dict['filename'] #Name of the image
            output_all['sequence'] = frame_dict['sequence'] #Name of the sequence

            #Save the output_all in a json file
            output_filename = os.path.join(self.output_dir, 'affordances_' + output_all['filename'].split('.')[0] +'.pkl')
            #With pickle
            with open(output_filename, 'wb') as f:
                pickle.dump(output_all, f)

        #Plot the camera pose and the sparse point cloud with Matplotlib
        cameras = np.array(cameras)
        keypoints = np.concatenate(all_keypoints, axis=0)
        abs_depth = np.concatenate(all_abs_depth, axis=0)
        abs_colors = np.concatenate(all_abs_colors, axis=0)
        rgb_keypoints = np.concatenate(all_rgb_keypoints, axis=0)
        print(keypoints.shape, abs_depth.shape, abs_colors.shape, rgb_keypoints.shape)

        #fig = plt.figure()
        #ax = fig.add_subplot(projection='3d')
        #ax.scatter(keypoints[:, 0], keypoints[:, 1], keypoints[:, 2], c='r')
        #ax.scatter(cameras[:, 0], cameras[:, 1], cameras[:, 2], c='b')
        #ax.scatter(origin[0], origin[1], origin[2], c='k')
        #plt.show()

        #Plot the camera pose and the sparse point cloud with Open3D
        pcd_plot = o3d.geometry.PointCloud()
        #Draw these points bigger
        pcd_plot.points = o3d.utility.Vector3dVector(abs_depth)
        pcd_plot.colors = o3d.utility.Vector3dVector(abs_colors / 255.0)
        cameras_plot = o3d.geometry.PointCloud()
        cameras_plot.points = o3d.utility.Vector3dVector(cameras)
        cameras_plot.colors = o3d.utility.Vector3dVector(np.array([[0, 0, 1] for i in range(cameras.shape[0])]))
        keypoints_plot = o3d.geometry.PointCloud()
        keypoints_plot.points = o3d.utility.Vector3dVector(keypoints)
        keypoints_plot.colors = o3d.utility.Vector3dVector(rgb_keypoints / 255.0)
        o3d.visualization.draw_geometries([cameras_plot, pcd_plot, keypoints_plot], height = 800, width = 1200)

inf = Inference()
data = inf.run()


# -*- coding: utf-8 -*-
"""
Created on Fri Mar 16 13:38:53 2018

@author: mrade_000
"""

from imblearn.over_sampling import SMOTE
import pandas as pd
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import numpy as np
from sklearn.cluster import AffinityPropagation, Birch, KMeans, DBSCAN
import matplotlib.pyplot as plt
from sklearn import metrics

def scale_array(A):
    A -= np.amin(A)
    A /= np.amax(A)
    A *= 100
    return A

X_n = np.genfromtxt('data/TSNE_Embedding.txt', delimiter=',')
#af = Birch(threshold=2, branching_factor=110, n_clusters=None)
af = AffinityPropagation()
af.fit(X_n)
cluster_centers = af.cluster_centers_
labels = af.labels_

# np.savetxt('Post_cluster_labels.txt', np.array(labels))

n_clusters_ = len(cluster_centers)

print('Estimated number of clusters: %d' % n_clusters_)
print("Silhouette Coefficient: %0.3f"
      % metrics.silhouette_score(X_n, labels, metric='sqeuclidean'))

# #############################################################################
# Plot result
import matplotlib.pyplot as plt
from itertools import cycle

fig = plt.figure()

colors = cycle(['#e6194b', '#3cb44b', '#ffe119', '#0082c8', '#f58231', '#911eb4', '#46f0f0', '#f032e6', '#d2f53c',
                '#fabebe', '#008080', '#e6beff', '#aa6e28', '#fffac8', '#800000', '#aaffc3', '#808000', '#ffd8b1',
                '#000080', '#808080', '#000000'])

for k, col in zip(range(n_clusters_), colors):
    my_members = labels == k
    cluster_center = cluster_centers[k]
    for x in X_n[my_members]:
        plt.plot([cluster_center[0], x[0]], [cluster_center[1], x[1]], c=col)

    plt.scatter(cluster_center[0], cluster_center[1],c=col, edgecolor='k', s=100)

#    for x in X_n[my_members]:
#       plt.plot([cluster_center[0], x[0]], [cluster_center[1], x[1]], c=col)

#plt.xlabel('HW')
#plt.ylabel('AS')
plt.dist = 12

plt.show()


import cv2
import sys, datetime
import glob
import dlib
import math
import os
from time import sleep
from shapely.geometry import Polygon

import numpy as np

# Kinect Azure intrinsics
FX = -622.359
CX = 641.666
FY = -620.594
CY = 352.072

FRAME_W, FRAME_H = 1280, 720

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

tracked_face_color = BLUE
new_face_color = RED
tracked_landmarks_color = BLUE
new_landmarks_color = RED

DEBUG = True
STATE_NO_FACE = 0
STATE_INIT = 1
STATE_TRACKED = 2
STATE_LOSE_TRACK_MIN = 3
STATE_LOSE_TRACK_MAX = 5
MIN_FACE_AREA=500
TRACK_BOX_WIDTH = 11

LANDMARK_OPENCV=0
LANDMARK_DLIB = 1
LANDMARK_DETECTOR=LANDMARK_DLIB

#  DATASET_PATH = '/mnt_d/Programming/0VR/OpenARK/data/avatar-dataset/car_exr/mount-tripod-loop'
DATASET_PATH = '/mnt_d/Programming/0VR/OpenARK/data/avatar-dataset/car_exr/mount-tripod-eye-open-close'
#  DATASET_PATH = '/mnt_d/Programming/0VR/OpenARK/data/avatar-dataset/car_exr/mount-tripod-real-road'

# Approximated face points. This can be replaced by real-world 3D face points
# This is using orthographic projection approximation in image coordinates
model_3D_points = np.array([
                            (0.0, 0.0, 0.0),             # Nose tip
                            (0.0, -40.0, -30.0),        # Mouth center
                            (-35, 55, -40.0),     # Left eye center
                            (35, 55, -40.0),      # Right eye center
                            (-25, -35, -60.0),    # Left Mouth corner
                            (25, -35, -60.0)      # Right mouth corner
                        ])

# Set fixed image resize resolution in opencv convension
#  resize_size = (640, 360)
resize_size = (960, 480)

FX_SHR = FX * (resize_size[0] / FRAME_W)
CX_SHR = CX * (resize_size[0] / FRAME_W)
FY_SHR = FY * (resize_size[1] / FRAME_H)
CY_SHR = CY * (resize_size[1] / FRAME_H)

# Approximated camera intrinsic parameters
focal_length = resize_size[0]
center = (resize_size[0]/2, resize_size[1]/2)
camera_matrix = np.array(
                         [[focal_length, 0, center[0]],
                         [0, focal_length, center[1]],
                         [0, 0, 1]], dtype = "double"
                         )
camera_dist_coeffs = np.zeros((4,1)) # Assuming no lens distortion

#https://github.com/twairball/face_tracking/blob/master/face_tracking.py

# OpenCV Face Landmark Indexes:
# 30: nose tip; 31: right nose corner; 33: middle between nose corners; 35: left nose corner
# 36: right eye outside corner; 39: right eye inside corner; 42: left eye inside corner: 45: left eye outside corner
# 48: right mouth corner; 54: left mouth corner

def bbox_to_point(bbox):
    (bX, bY, bW, bH) = bbox
    bX, bY, bW, bH = int(bX), int(bY), int(bW), int(bH)
    return bX + (bW / 2), bY + (bH / 2), 5, 5

def dlib_full_obj_to_np(obj_detection):
    return [(p.x, p.y) for p in obj_detection.parts()]

def draw_boxes(frame, boxes, color=(0,255,0)):
    for i in range(len(boxes)):
        # Prevent empty list units
        if boxes[i]:
            (bX, bY, bW, bH) = boxes[i]
            bX, bY, bW, bH = int(bX), int(bY), int(bW), int(bH)
            cv2.rectangle(frame, (bX, bY), (bX + bW, bY + bH), color, 1)

def draw_points(frame, points,color=(0,0,255)):
    # for set_of_landmarks in points:
    for (x, y) in points:
        cv2.circle(frame, (int(x), int(y)), 2, color, -1)

def resize_image(image, size_limit=500.0):
    max_size = max(image.shape[0], image.shape[1])
    if max_size > size_limit:
        scale = size_limit / max_size
        _img = cv2.resize(image, None, fx=scale, fy=scale)
        return _img
    return image

#a landmark at coordinate (x, y) should have a bounding box of (x - half_width, y - half_width, half_width * 2, half_width * 2)
def make_bbox_for_landmark(landmark, half_width):
    bbox_x = int(landmark[0] - half_width)
    bbox_y = int(landmark[1] - half_width)
    return (bbox_x, bbox_y, half_width * 2 + 1, half_width * 2 + 1)

def make_bbox_from_point_list(point_list):
    # test the validity of the update
    box_min_x = math.inf
    box_min_y = math.inf
    box_max_x = 0
    box_max_y = 0
    for index in range(len(point_list)):
        # calculate its area
        if point_list[index][0]<box_min_x:
            box_min_x=point_list[index][0]
        if point_list[index][0]>box_max_x:
            box_max_x=point_list[index][0]
        if point_list[index][1]<box_min_y:
            box_min_y=point_list[index][1]
        if point_list[index][1]>box_max_y:
            box_max_y=point_list[index][1]

    bbox = (int(box_min_x)-5, int(box_min_y)-5, int(box_max_x-box_min_x)+10, int(box_max_y-box_min_y)+10)
    return bbox

def make_feature_bbox_from_landmarks(landmarks, feature_index=0):

    bboxes=[]
    # Define nose box
    if feature_index==0 or feature_index==1:
        point_list = landmarks[0:4]
        bbox= make_bbox_from_point_list(point_list)
        bboxes.append(bbox)

    # Define right eye box
    if feature_index==0 or feature_index==2:
        point_list = landmarks[4:10]
        bbox= make_bbox_from_point_list(point_list)
        bboxes.append(bbox)

    # Define right eye box
    if feature_index==0 or feature_index==3:
        point_list = landmarks[10:16]
        bbox= make_bbox_from_point_list(point_list)
        bboxes.append(bbox)

    # Define right eye box
    if feature_index==0 or feature_index==4:
        point_list = landmarks[16:20]
        bbox= make_bbox_from_point_list(point_list)
        bboxes.append(bbox)

    return bboxes

def avg_dist_between_points(tracked_points, detected_points):
    if len(tracked_points) != len(detected_points):
        raise Exception
    num_points = len(tracked_points)
    total = sum([calc_distance(tracked_points[i], detected_points[i]) for i in range(len(tracked_points))])
    return total / num_points

def calc_distance(point_1, point_2):
    x1, y1 = point_1 #comes from tracker, so is x, y
    x2, y2 = point_2 #comes from detection, so is x, y
    return math.sqrt((x2 - x1)**2 + (y2 - y1)**2)

#return the percentage overlap between 2 face detection bounding boxes, tracked and newly detected
def overlapping_percentage(bbox_a, bbox_b):
    a_x, a_y, a_w, a_h = bbox_a #x, y is upper left corner
    b_x, b_y, b_w, b_h = bbox_b
    polygon_a = Polygon([(a_x, a_y + a_h), (a_x + a_w, a_y + a_h), (a_x + a_w, a_y), (a_x, a_y)]) #lower left, lower right, upper right, upper left
    polygon_b = Polygon([(b_x, b_y + b_h), (b_x + b_w, b_y + b_h), (b_x + b_w, b_y), (b_x, b_y)]) #lower left, lower right, upper right, upper left
    intersection = polygon_a.intersection(polygon_b)
    min_area = min(polygon_a.area, polygon_b.area)
    return float(intersection.area) / min_area

# take a bounding predicted by opencv and convert it
# to the dlib (top, right, bottom, left)
def bb_to_rect(bb):
    top=bb[1]
    left=bb[0]
    right=bb[0]+bb[2]
    bottom=bb[1]+bb[3]
    return dlib.rectangle(left, top, right, bottom)

# take a bounding predicted by dlib and convert it
# to the format (x, y, w, h) as we would normally do
# with OpenCV
def rect_to_bb(rect):

    x = rect.left()
    y = rect.top()
    w = rect.right() - x
    h = rect.bottom() - y

    # return a tuple of (x, y, w, h)
    return (x, y, w, h)

class FaceDetectorDNN():

    def __init__(self, modelFile="res10_300x300_ssd_iter_140000_fp16.caffemodel", configFile="deploy.prototxt"):
        self.net = cv2.dnn.readNetFromCaffe(configFile, modelFile)
        self.conf_threshold = .8

    def detect(self, frame):
        frameWidth = frame.shape[1]
        frameHeight = frame.shape[0]
        blob = cv2.dnn.blobFromImage(frame, 1.0, (300, 300), [104, 117, 123])
        self.net.setInput(blob)
        detections = self.net.forward()
        faces = []
        for i in range(detections.shape[2]):
            confidence = detections[0, 0, i, 2]
            if confidence > self.conf_threshold:
                x1 = int(detections[0, 0, i, 3] * frameWidth)
                y1 = int(detections[0, 0, i, 4] * frameHeight)
                x2 = int(detections[0, 0, i, 5] * frameWidth)
                y2 = int(detections[0, 0, i, 6] * frameHeight)
                face = (x1, y1, x2 - x1, y2 - y1)
                faces.append(face)
        return faces

class FacemarkDetectorOpenCV():

    def __init__(self):
        self.facemark = cv2.face.createFacemarkLBF()
        self.facemark.loadModel("lbfmodel.yaml")

    #faces should be an np.array of face, where face is (x, y, w, h)
    def detect(self, frame, facebox):
        #fitted[0] is a boolean representing if landmarks were found or not
        #fitted[1] is an array whose first element is a 3D np.array of points
        if len(facebox) > 0:
            faces = np.asarray([facebox])
            fitted = self.facemark.fit(frame, faces)
            success = fitted[0]
            if success:
                # landmarks annotate four track-able areas: nose(4), right eye(6), left eye(6), mouth (4)
                keep = [30, 31, 33, 35, 36, 37,38, 39, 40,41, 42, 43, 44, 45,46, 47, 48, 51, 54, 57] #indices of landmarks to keep
                self.landmarks = [fitted[1][0][0][i] for i in keep]
                return self.landmarks
            else:
                print("No success detecting")
                return []
        else:
            print("No faces passed into landmark detector")
            return []

class FacemarkDetectorDlib():

    def __init__(self):
        self.predictor = dlib.shape_predictor("./shape_predictor_68_face_landmarks.dat")

    def detect(self, frame, bbox):
        if bbox:
            # reduce bbox high due to dlib training on square face boxes
            delta = bbox[3] - bbox[2]
            #  if delta>0:
            #      bbox = (bbox[0], bbox[1] + delta//2, bbox[2], bbox[3]-delta//2)
            rect = bb_to_rect(bbox)
            shape = self.predictor(frame, rect)
            points = dlib_full_obj_to_np(shape)
            # landmarks annotate four track-able areas: nose(4), right eye(6), left eye(6), mouth (4)
            keep = [30, 31, 33, 35, 36, 37, 38,39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 51, 54, 57]
            # keep = [54]
            filtered_points = [points[i] for i in keep]
            return filtered_points
        else:
            return []

class Tracker():

    def __init__(self, frame, bbox):
        # Arbitrarily picked KCF tracking
        self.tracker = cv2.TrackerKCF_create() # Boosting
        self.tracker.init(frame, bbox)

    def update(self, frame):
        ok, bbox = self.tracker.update(frame)
        return ok, bbox

class Pipeline():

    def __init__(self):
        self.face_detector = FaceDetectorDNN()
        if LANDMARK_DETECTOR==LANDMARK_OPENCV:
            self.facemark_detector = FacemarkDetectorOpenCV()
        else:
            self.facemark_detector = FacemarkDetectorDlib()
        self.landmark_trackers = []

    #return faces and True/False if faces detected
    def detect_faces(self, frame):
        faces = self.face_detector.detect(frame)
        return faces

    def detect_landmarks(self, frame, facebox):
        if len(facebox)!=4:
            #if no faces are found, return
            return [], False
        landmarks = self.facemark_detector.detect(frame, facebox)
        return landmarks

def facial_orientation(bboxes, landmarks, xyz):
    image_points = np.array([
        (0, 0),     # Nose tip
        (0, 0),     # Mouth center
        (0, 0),     # Left eye center
        (0, 0),     # Right eye center
        (0, 0),     # Left Mouth corner
        (0, 0)      # Right mouth corner
    ], dtype="double")

    image_points[0] = [bboxes[0][0]+bboxes[0][2]/2, bboxes[0][1]+bboxes[0][3]/2]
    image_points[1] = [bboxes[3][0]+bboxes[3][2]/2, bboxes[3][1]+bboxes[3][3]/2]
    image_points[2] = [bboxes[1][0]+bboxes[1][2]/2, bboxes[1][1]+bboxes[1][3]/2]
    image_points[3] = [bboxes[2][0]+bboxes[2][2]/2, bboxes[2][1]+bboxes[2][3]/2]
    image_points[4] = landmarks[16]
    image_points[5] = landmarks[18]
    #  points_3d = np.zeros((6, 3));
    #  for i in range(points_3d.shape[0]):
    #      py = min(int(image_points[i,1]), xyz.shape[0]-1)
    #      px = min(int(image_points[i,0]), xyz.shape[1]-1)
    #      points_3d[i, :] = xyz[py, px]
    (success, rotation_vector, translation_vector) = cv2.solvePnP(model_3D_points, image_points, camera_matrix, camera_dist_coeffs, flags=cv2.SOLVEPNP_ITERATIVE)
    #  (success, rotation_vector, translation_vector) = cv2.solvePnP(points_3d, image_points, camera_matrix, camera_dist_coeffs, flags=cv2.SOLVEPNP_ITERATIVE)
    camera_para = (rotation_vector, translation_vector)

    # The following are for debugging purposes of drawing orientation
    #  (nose_end_point2D, jacobian) = cv2.projectPoints(np.array([(0.0, 0.0, 200.0)]), rotation_vector, translation_vector, camera_matrix, camera_dist_coeffs)
    #  p1 = ( int(image_points[0][0]), int(image_points[0][1]))
    # 0 nose
    # 4 R eye
    p1 = ( int(landmarks[0][0]), int(landmarks[0][1]))

    p1_3d = xyz[min(int(landmarks[0][1]), xyz.shape[0]-1),
                min(int(landmarks[0][0]), xyz.shape[1]-1)]
    mouth_3d = xyz[min(int(landmarks[17][1]), xyz.shape[0]-1),
                min(int(landmarks[17][0]), xyz.shape[1]-1)]
    leye_3d = xyz[min(int(landmarks[4][1]), xyz.shape[0]-1),
               min(int(landmarks[4][0]), xyz.shape[1]-1)]
    meye_3d = xyz[min(int((landmarks[4][1] + landmarks[13][1]) /2), xyz.shape[0]-1),
               min(int((landmarks[4][0] + landmarks[13][0]) /2), xyz.shape[1]-1)]
    #  meye_3d = (leye_3d + reye_3d) / 2
    v_up =  meye_3d - mouth_3d
    v_right = meye_3d - leye_3d

    v_fwd = np.cross(v_up, v_right)
    norm = np.linalg.norm(v_fwd)
    if norm == 0.0:
        # Vector is zero
        p2 = p1
    else:
        v_fwd /= norm
        p2_3d = p1_3d - v_fwd * 0.15
        if p2_3d[2] == 0:
            # Invalid point
            p2 = p1
        else:
            p2 = ( int(p2_3d[0] * FX_SHR / p2_3d[2] + CX_SHR),
                   int(p2_3d[1] * FY_SHR / p2_3d[2] + CY_SHR))
    return camera_para, p1, p2

def boxes_overlap(box1, box2):
    # If two boxes overlap in image, return the smaller box that should be removed
    # otherwise, return 0
    (f1X, f1Y,f1W, f1H) = box1
    f1X_center = f1X + f1W/2.0
    f1Y_center = f1Y + f1H/2.0
    (f2X, f2Y,f2W, f2H) = box2
    f2X_center = f2X + f2W/2.0
    f2Y_center = f2Y + f2H/2.0

    is_overlap = False
    if f1X_center>=f2X and f1X_center<=f2X + f2W and f1Y_center>=f2Y and f1Y_center<=f2Y + f2H:
        # box1 center is within box2
        is_overlap = True

    if f2X_center>=f1X and f2X_center<=f1X + f1W and f2Y_center>=f1Y and f2Y_center<=f1Y + f1H:
        # box1 center is within box2
        is_overlap = True

    if is_overlap:
        if f1W*f1H > f2W*f2H:
            return 2
        else:
            return 1
    else:
        return 0

def run():
    # init video stream
    #  video_capture = cv2.VideoCapture(0)

    # init detection pipeline
    pipeline = Pipeline()

    # init state variables
    landmarks = []
    tracked_faces = []
    tracked_faces_status = [] # this list register status of individual faces
    tracked_faces_orientation = []
    tracker_list=[]
    default_stop = False

    class mock_video_capture:
        def __init__(self, path):
            self.rgb_frames = sorted(glob.glob(os.path.join(path, 'rgb/*.jpg')))
            self.depth_frames = sorted(glob.glob(os.path.join(path, 'depth_exr/*.exr')))
            self.cols = None
            self.idx = 0
        def read(self):
            if self.idx >= len(self.rgb_frames):
                return False, None
            frame = cv2.imread(self.rgb_frames[self.idx])
            self.idx += 1
            return True, frame
        def read_depth(self):
            frame = cv2.imread(self.depth_frames[self.idx], cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH)
            return frame
        def read_xyz(self):
            depth = cv2.imread(self.depth_frames[self.idx-1], cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH)

            if self.cols is None:
                self.cols = np.zeros(depth.shape, dtype=np.float32)
                self.rows = np.zeros(depth.shape, dtype=np.float32)
                for i in range(depth.shape[1]):
                    self.cols[:, i] = i - CX
                for i in range(depth.shape[0]):
                    self.rows[i, :] = i - CY
                self.cols /= FX
                self.rows /= FY

            xyz_map = np.zeros((*depth.shape, 3), dtype=np.float32)
            xyz_map[:,:,0] = self.cols * depth
            xyz_map[:,:,1] = self.rows * depth
            xyz_map[:,:,2] = depth
            return xyz_map

    video_capture = mock_video_capture(DATASET_PATH)

    output_video = cv2.VideoWriter('out.mp4', 0x21, 15, resize_size, True)
    while not default_stop:
        return_value, frame = video_capture.read()
        if return_value==False:
            break
        frame_xyz = video_capture.read_xyz()
        frame = cv2.resize(frame, resize_size, interpolation = cv2.INTER_AREA)
        frame_xyz = cv2.resize(frame_xyz, resize_size, interpolation = cv2.INTER_NEAREST)

        if DEBUG:
            # if debugging, copy the current frame for augmenting visual results
            display_frame = frame

        # STAGE 1: Detection
        # On new frame, try to detect faces
        faces = pipeline.detect_faces(frame)

        if len(faces) > 0:

            # Remove impossible faces inside faces
            for face_index in range(len(faces)):
                (fX, fY, fW, fH) = faces[face_index]
                if fW*fH<MIN_FACE_AREA:
                    faces[face_index][2]=0
                    faces[face_index][3]=0
                    continue

                for overlap_face_index in range(face_index):
                    # check if face_index and overlap_face_index overlap
                    if faces[overlap_face_index][3]==0:
                        continue

                    which_overlap = boxes_overlap(faces[face_index], faces[overlap_face_index])

                    if which_overlap==1:
                        faces[face_index]=[]
                        break
                    elif which_overlap==2:
                        faces[overlap_face_index]=[]

            for face_index in range(len(faces)):
                if faces[face_index]:
                    # Exist non-empty face region, marge tracked faces and possible new faces
                    for tracked_face_index in range(len(tracked_faces)):
                        which_overlap = boxes_overlap(faces[face_index], tracked_faces[tracked_face_index])
                        if which_overlap!=0:
                            # It overlaps, use new face region to replace the old one
                            tracked_faces[tracked_face_index] = faces[face_index]
                            # Then remove faces entry from initialization
                            faces[face_index]=[]
                            break

            #  if DEBUG:
                # augment detected faces in the frame
                #  draw_boxes(display_frame, faces, new_face_color)
                #  draw_boxes(display_frame, tracked_faces, tracked_face_color)

        # Stage 2: Initialize New Trackers. When new face detected, initiate tracker(s)
        for face_index in range(len(faces)):

            # First ignore empty face regions
            if not faces[face_index]:
                continue

            # Second, detect new facial landmarks
            landmarks= pipeline.detect_landmarks(frame, faces[face_index])
            if len(landmarks)>0:
                # valid landmarks detected, this is a face region that can be tracked
                # Initiate trackers
                # bboxes = [make_bbox_for_landmark(landmark, TRACK_BOX_WIDTH) for landmark in landmarks]
                bboxes = make_feature_bbox_from_landmarks(landmarks)
                feature_trackers = [Tracker(frame, bbox) for bbox in bboxes]

                tracker_list.append(feature_trackers)
                tracked_faces.append(faces[face_index])
                tracked_faces_status.append(STATE_INIT)

                # Calculate face orientation
                camera_para, p1, p2 = facial_orientation(bboxes, landmarks, frame_xyz)
                tracked_faces_orientation.append(camera_para)

                if DEBUG:
                    # draw detected landmarks
                    #  draw_boxes(display_frame, bboxes, new_landmarks_color)
                    draw_points(display_frame, landmarks, RED)
                    cv2.line(display_frame, p1, p2, (255,0,0), 2)

        # Stage 3: update old tracker parameters
        if  tracked_faces:
            for face_index in range(len(tracked_faces)):
                if tracked_faces_status[face_index] == STATE_INIT:
                    # This is a new face just added above, start tracking next frame
                    tracked_faces_status[face_index] = STATE_TRACKED
                else:
                    # There are old tracked face regions, update them
                    current_track_state = tracked_faces_status[face_index]

                    feature_updates = [t.update(frame) for t in tracker_list[face_index]]
                    new_landmarks= pipeline.detect_landmarks(frame, tracked_faces[face_index])

                    if DEBUG:
                        draw_points(display_frame, new_landmarks, RED)

                    total_feature_area = 0
                    bboxes = []
                    for update_index in range(len(feature_updates)):
                        if feature_updates[update_index][0] == False:
                            # Use the new landmark to replace a failed tracked landmark
                            # tracked_landmark_list[face_index][update_index] = new_landmarks[update_index]

                            # add one penalty for mis-tracked state
                            tracked_faces_status[face_index] = current_track_state + 1

                            # update the tracker
                            bbox = make_feature_bbox_from_landmarks(landmarks, update_index+1)
                            bbox = bbox[0]
                            # bbox = make_bbox_for_landmark(new_landmarks[update_index], TRACK_BOX_WIDTH)
                            tracker_list[face_index][update_index]= Tracker(frame, bbox)

                        # else:
                        #     tracked_landmark_list[face_index][update_index] = landmark_updates[update_index][1]
                        else:
                            bbox = feature_updates[update_index][1]

                        # Check if bbox is outside the face
                            if overlapping_percentage(bbox, tracked_faces[face_index])<0.99:
                                # bbox is outside the face region, add one penalty for mis-tracked state
                                tracked_faces_status[face_index] = current_track_state + 1

                        total_feature_area = total_feature_area + bbox[2]*bbox[3]
                        bboxes.append(bbox)

                    camera_para, p1, p2 = facial_orientation(bboxes, new_landmarks, frame_xyz)
                    tracked_faces_orientation[face_index] = camera_para

                    if DEBUG:
                        #  draw_boxes(display_frame, bboxes, tracked_landmarks_color)
                        cv2.line(display_frame, p1, p2, (255,0,0), 2)

                    if tracked_faces_status[face_index] == STATE_TRACKED:
                        # Test yet another lost track condition:
                        # If tracked region varies away from detected face region, it lost track
                        face_area = tracked_faces[face_index][2]* tracked_faces[face_index][3]
                        if total_feature_area/face_area>0.2 or total_feature_area/face_area<0.01:
                            # Deem lost track
                            tracked_faces_status[face_index] = tracked_faces_status[face_index] + 1

            # Finally, we need to remove those regions that lost track for too many frames
            face_index = 0
            while face_index<len(tracked_faces):
                if tracked_faces_status[face_index] > STATE_LOSE_TRACK_MAX:
                    tracked_faces_status.pop(face_index)
                    tracked_faces.pop(face_index)
                    tracker_list.pop(face_index)
                    tracked_faces_orientation.pop(face_index)
                else:
                    face_index = face_index + 1

        if DEBUG:
            # if debugging, display display_frame
            cv2.imshow('Video', display_frame)
            output_video.write(display_frame)
            pressed_key=cv2.waitKey(10) & 0xFF
            if pressed_key==27 or pressed_key==ord('q'):
                default_stop = True
    output_video.release()

if __name__ == '__main__':
    run()
    #import timeit
    #print(timeit.repeat("run()", setup="from __main__ import run", repeat = 5, number=1))


#################################
# Your name: Vicktoria Kraslavski
#################################

# Please import and use stuff only from the packages numpy, sklearn, matplotlib
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm
from sklearn.datasets import make_blobs

"""
Q4.1 skeleton.

Please use the provided functions signature for the SVM implementation.
Feel free to add functions and other code, and submit this file with the name svm.py
"""

# Generate points in 2D
# Return training_data, training_labels, validation_data, validation_labels
def get_points():
    X, y = make_blobs(n_samples=120, centers=2, random_state=0, cluster_std=0.88)
    return X[:80], y[:80], X[80:], y[80:]

def create_plot(X, y, clf):
    plt.clf()

    # Plot the data points
    plt.scatter(X[:, 0], X[:, 1], c=y, s=30, cmap=plt.cm.PiYG)

    # Plot the decision function
    ax = plt.gca()
    xlim = ax.get_xlim()
    ylim = ax.get_ylim()

    # Create grid to evaluate model
    xx = np.linspace(xlim[0] - 2, xlim[1] + 2, 30)
    yy = np.linspace(ylim[0] - 2, ylim[1] + 2, 30)
    YY, XX = np.meshgrid(yy, xx)
    xy = np.vstack([XX.ravel(), YY.ravel()]).T
    Z = clf.decision_function(xy).reshape(XX.shape)

    # Plot decision boundary and margins
    ax.contour(XX, YY, Z, colors='k', levels=[-1, 0, 1], alpha=0.5,
               linestyles=['--', '-', '--'])

def train_three_kernels(X_train, y_train, X_val, y_val):
    """
    Returns: np.ndarray of shape (3,2) :
                A two dimensional array of size 3 that contains the number of support vectors for each class(2) in the three kernels.
    """
    # Defying all classifiers
    linear_clf = svm.SVC(kernel='linear', C=1000)
    quadratic_clf = svm.SVC(kernel='poly', degree=2, C=1000)
    rbf_clf = svm.SVC(kernel='rbf', C=1000)

    # Training on train data
    linear_clf.fit(X_train, y_train)
    quadratic_clf.fit(X_train, y_train)
    rbf_clf.fit(X_train, y_train)

    # Getting SV
    numof_linear_sv = linear_clf.n_support_[0] + linear_clf.n_support_[1]  # TODO: Check if that is what i need
    numof_quadratic_sv = quadratic_clf.n_support_[0] + quadratic_clf.n_support_[1]
    numof_rbf_sv = rbf_clf.n_support_[0] + rbf_clf.n_support_[1]

    # Plotting classifiers
    create_plot(X_train, y_train, linear_clf)
    plt.title("Linear Kernel, %d support vectors" % numof_linear_sv)
    plt.show()
    create_plot(X_train, y_train, quadratic_clf)
    plt.title("Quadratic Kernel, %d support vectors" % numof_quadratic_sv)
    plt.show()
    create_plot(X_train, y_train, rbf_clf)
    plt.title("RBF Kernel, %d support vectors" % numof_rbf_sv)
    plt.show()

    return np.array([linear_clf.n_support_], [quadratic_clf.n_support_], [rbf_clf.n_support_])

def linear_accuracy_per_C(X_train, y_train, X_val, y_val):
    """
        Returns: np.ndarray of shape (11,) :
                    An array that contains the accuracy of the resulting model on the VALIDATION set.
    """
    c_vector = np.array([10.0**p for p in np.arange(-5, 6)])
    accuracy_vector = []
    c_check_points = np.array([10**-4, 10**-2, 10**2])

    for c in c_vector:
        linear_clf = svm.SVC(kernel='linear', C=c)
        linear_clf.fit(X_train, y_train)
        mean_accuracy = linear_clf.score(X_val, y_val)
        accuracy_vector.append(mean_accuracy)
        if c in c_check_points:
            create_plot(X_val, y_val, linear_clf)
            plt.title("Linear Kernel, C = %f, " % c + "accuracy = %f" % mean_accuracy)
            plt.show()

    best_c = c_vector[np.argmax(accuracy_vector)]
    plt.plot(c_vector, accuracy_vector, label="Average accuracy", marker=".", color="blue")
    plt.xscale("log")
    plt.ylim((-0.1, 1.1))
    plt.xlabel('C')
    plt.axvline(best_c, color='yellow', label="best C: {}".format(best_c))
    plt.ylabel('Average accuracy')
    plt.legend()
    plt.show()

    return accuracy_vector

def rbf_accuracy_per_gamma(X_train, y_train, X_val, y_val):
    """
        Returns: np.ndarray of shape (11,) :
                    An array that contains the accuracy of the resulting model on the VALIDATION set.
    """
    gamma_vector = np.array([10.0**p for p in np.arange(-5, 6)])
    C = 10
    accuracy_vector = []
    gamma_check_points = np.array([10 ** -1, 10 ** 0, 10, 10 ** 2])

    for gamma in gamma_vector:
        rbf_clf = svm.SVC(kernel='rbf', C=C, gamma=gamma)
        rbf_clf.fit(X_train, y_train)
        mean_accuracy = rbf_clf.score(X_val, y_val)
        accuracy_vector.append(mean_accuracy)
        if gamma in gamma_check_points:
            create_plot(X_val, y_val, rbf_clf)
            plt.title("Linear Kernel, gamma = %f, " % gamma + "accuracy = %f" % mean_accuracy)
            plt.show()

    best_gamma = gamma_vector[np.argmax(accuracy_vector)]
    print(accuracy_vector)
    plt.plot(gamma_vector, accuracy_vector, label="Average accuracy", marker=".", color="blue")
    plt.xscale("log")
    plt.ylim((-0.1, 1.1))
    plt.xlabel('gamma')
    plt.axvline(best_gamma, color='yellow', label="best gamma: {}".format(best_gamma))
    plt.ylabel('Average accuracy')
    plt.legend()
    plt.show()

X_train, y_train, X_val, y_val = get_points()
#train_three_kernels(X_train, y_train, X_val, y_val)
#linear_accuracy_per_C(X_train, y_train, X_val, y_val)
rbf_accuracy_per_gamma(X_train, y_train, X_val, y_val)


from datetime import datetime
from uuid import UUID

import pytest

from uptimer.events import Event
from uptimer.events.serializer import dumps, loads

FIXTURE_SERIALIZED = """
{
  "uuid": "0e436b7c-4814-46ec-bcbc-3884060f735b",
  "event_time": "2020-02-21T11:56:52.399558+00:00",
  "schema_title": "DummyEvent",
  "schema_version": "0.1.0",
  "target": "nowhere",
  "reader": "readers.dummies.dummy_events",
  "integer_value": 42,
  "float_value": 13.37
}
"""

FIXTURE_SERIALIZED_INCOMPLETE = """
{
  "target": "nowhere",
  "reader": "readers.dummies.dummy_events",
  "integer_value": 42,
  "float_value": 13.37
}
"""

def test_serializer_loads():

    event = loads(FIXTURE_SERIALIZED)

    assert isinstance(event["event_time"], datetime)
    assert isinstance(event["uuid"], UUID)
    assert isinstance(event["integer_value"], int)
    assert isinstance(event["float_value"], float)

def test_serializer_loads_error():
    with pytest.raises(ValueError):
        loads(FIXTURE_SERIALIZED_INCOMPLETE)

def test_serializer_dumps():
    event = Event()
    dumped_event = dumps(event)
    reloaded_event = loads(dumped_event)

    assert isinstance(dumped_event, bytes)
    assert isinstance(event, Event)
    assert event == reloaded_event


from pyspark.sql import SparkSession
from pyspark.sql.functions import count, countDistinct, approx_count_distinct, first, last, expr, max, col, rank, dense_rank

spark = SparkSession.builder.master('local').appName('aggregationBasic').getOrCreate()

def countTest():
    countDf = spark.read.format('csv').option("header", "true").option("inferSchema", "true").load("../data/flights.csv")
    print( countDf.count() )
    print( countDf.rdd.getNumPartitions() )
    print(countDf.repartition(10).rdd.pipe("wc -l").collect())

countTest()


import pytest

from backend.app import get_app

@pytest.fixture
def app():
    app = get_app()
    return app

def test_hello_flask(client):
    response = client.get("/api/hello")

    assert response.status_code == 200
    assert response.json['info'] == 'Hello flask 2!'

def test_should_return_empty_list_of_items(client, mocker):
    mocker.patch('backend.app.DataSource.find_all', return_value=[])
    response = client.get("/api/docs")

    assert response.status_code == 200
    assert response.json['items'] == []

def test_should_return_list_of_items(client, mocker):
    expected_items = [
        {
            'firstname': 'tony',
            'lastname': 'stark'
        },
        {
            'firstname': 'steve',
            'lastname': 'rogers'
        }
    ]
    # mock DataStore inside the scope of backend.app module
    mocker.patch('backend.app.DataSource.find_all', return_value=expected_items)
    response = client.get("/api/docs")

    assert response.status_code == 200
    assert response.json['items'] == expected_items