import arrow
import defusedxml.lxml
import json
import libvirt
import logging
import lxml.etree
import os
import subprocess
import tarfile
from tqdm import tqdm

import virt_backup
from virt_backup.domains import get_xml_block_of_disk
from virt_backup.tools import (
    copy_file_progress, get_progress_bar_tar
)
from . import _BaseDomBackup
from .snapshot import DomExtSnapshot

logger = logging.getLogger("virt_backup")

def build_dom_backup_from_pending_info(pending_info, backup_dir, conn):
    backup = DomBackup(
        dom=conn.lookupByName(pending_info["domain_name"]),
        target_dir=backup_dir,
        dev_disks=tuple(pending_info.get("disks", {}).keys()),
        compression=pending_info.get("compression", "tar"),
        compression_lvl=pending_info.get("compression_lvl", None)
    )
    backup.pending_info = pending_info

    return backup

class DomBackup(_BaseDomBackup):
    """
    Libvirt domain backup
    """
    def __init__(self, dom, target_dir=None, dev_disks=None, compression="tar",
                 compression_lvl=None, conn=None, timeout=None, _disks=None,
                 _ext_snapshot_helper=None):
        """
        :param dev_disks: list of disks dev names to backup. Disks will be
                          searched in the domain to pull more informations, and
                          an exception will be thrown if one of them is not
                          found
        """
        #: domain to backup. Has to be a libvirt.virDomain object
        self.dom = dom

        #: directory where backups will be saved
        self.target_dir = target_dir

        #: disks to backups. If None, will backup every vm disks
        if dev_disks:
            _disks = self._get_self_domain_disks(*dev_disks)
        self.disks = (self._get_self_domain_disks()
                      if _disks is None else _disks)

        #: string indicating how to compress the backups:
        #    * None: no compression, backups will be only copied
        #    * "tar": backups will not be compressed, but packaged in a tar
        #    * "gz"/"bz2"/"xz": backups will be compressed in a tar +
        #        compression selected. For more informations, read the
        #        documentation about the mode argument of tarfile.open
        self.compression = compression

        #: If compression, indicates the lvl to use
        self.compression_lvl = compression_lvl

        #: libvirt connection to use. If not sent, will use the connection used
        #  for self.domain
        self.conn = self.dom._conn if conn is None else conn

        #: timeout when waiting for the block pivot to end. Infinite wait if
        #  timeout is None
        self.timeout = timeout

        #: droppable helper to take and clean external snapshots. Can be
        #  construct with an ext_snapshot_helper to clean the snapshots of an
        #  aborted backup. Starting a backup will erase this helper.
        self._ext_snapshot_helper = _ext_snapshot_helper

        #: useful info collected during a pending backup, allowing to clean
        #  the backup if anything goes wrong
        self.pending_info = {}

    def add_disks(self, *dev_disks):
        """
        Add disk by dev name

        .. warning::

            Adding a disk during a backup is not recommended, as the current
            disks list could be inaccurate. It will pull the informations
            about the current disks attached to the domain, but the backup
            process creates temporary external snapshots, changing the current
            disks attached. This should not be an issue when the backingStore
            property will be correctly handled, but for now it is.

        :param dev_disk: dev name of the new disk to backup. If not indicated,
                         will add all disks.
        """
        dom_all_disks = self._get_self_domain_disks()
        if not dev_disks:
            self.disks = dom_all_disks
        for dev in dev_disks:
            if dev in self.disks:
                continue
            self.disks[dev] = dom_all_disks[dev]

    def start(self):
        """
        Start the entire backup process for all disks in self.disks
        """
        assert self.dom and self.target_dir

        backup_target = None
        logger.info("Backup started for domain {}".format(self.dom.name()))
        definition = self.get_definition()
        definition["disks"] = {}

        if not os.path.exists(self.target_dir):
            logger.debug("Create dir {}".format(self.target_dir))
            os.mkdir(self.target_dir)
        try:
            self._ext_snapshot_helper = DomExtSnapshot(
                self.dom, self.disks, self.conn, self.timeout
            )

            snapshot_date, definition = (
                self._snapshot_and_save_date(definition)
            )

            backup_target = (
                self.target_dir if self.compression is None
                else self.get_new_tar(self.target_dir, snapshot_date)
            )

            # TODO: handle backingStore cases
            for disk, prop in self.disks.items():
                self._backup_disk(disk, prop, backup_target, definition)
                self._ext_snapshot_helper.clean_for_disk(disk)

            self._dump_json_definition(definition)
            self.post_backup(backup_target)
            self._clean_pending_info()
        except:
            self.clean_aborted()
            raise
        logger.info("Backup finished for domain {}".format(self.dom.name()))

    def _snapshot_and_save_date(self, definition):
        """
        Take a snapshot of all disks to backup and mark date into definition

        All disks are frozen when external snapshots have been taken, so we
        consider this step to be the backup date.

        :return snapshot_date, definition: return snapshot_date as `arrow`
            type, and the updated definition
        """
        snapshot_metadatas = self._ext_snapshot_helper.start()

        # all of our disks are snapshot, so the backup date is right now
        definition["date"] = snapshot_metadatas["date"].timestamp

        self.pending_info = definition.copy()
        self.pending_info["disks"] = {
            disk: {
                "src": prop["src"],
                "snapshot": snapshot_metadatas["disks"][disk]["snapshot"]
            } for disk, prop in self.disks.items()
        }
        self._dump_pending_info()

        return snapshot_metadatas["date"], definition

    def get_definition(self):
        """
        Get a json defining this backup
        """
        return {
            "compression": self.compression,
            "compression_lvl": self.compression_lvl,
            "domain_id": self.dom.ID(), "domain_name": self.dom.name(),
            "domain_xml": self.dom.XMLDesc(), "version": virt_backup.VERSION
        }

    def get_new_tar(self, target, snapshot_date):
        """
        Get a new tar for this backup

        self._main_backup_name_format will be used to generate a new tar name

        :param target: directory path that will contain our tar. If not exists,
                       will be created.
        """
        extra_args = {}
        if self.compression not in (None, "tar"):
            mode = "w:{}".format(self.compression)
            extension = "tar.{}".format(self.compression)
            if self.compression is "xz":
                extra_args["preset"] = self.compression_lvl
            else:
                extra_args["compresslevel"] = self.compression_lvl
        else:
            mode = "w"
            extension = "tar"

        if not os.path.isdir(target):
            os.makedirs(target)

        complete_path = os.path.join(
            target,
            "{}.{}".format(
                self._main_backup_name_format(snapshot_date), extension
            )
        )
        if os.path.exists(complete_path):
            raise FileExistsError()
        return tarfile.open(complete_path, mode, **extra_args)

    def _backup_disk(self, disk, disk_properties, backup_target, definition):
        """
        Backup a disk and complete the definition by adding this disk

        :param disk: diskname to backup
        :param disk_properties: dictionary discribing our disk (typically
                                contained in self.disks[disk])
        :param backup_target: target path of our backup
        :param definition: dictionary representing the domain backup
        """
        snapshot_date = arrow.get(definition["date"]).to("local")
        logger.info(
            "Backup disk {} of domain {}".format(disk, self.dom.name())
        )
        target_img = "{}.{}".format(
            self._disk_backup_name_format(snapshot_date, disk),
            disk_properties["type"]
        )
        self.pending_info["disks"][disk]["target"] = target_img
        self._dump_pending_info()

        if definition.get("disks", None) is None:
            definition["disks"] = {}
        definition["disks"][disk] = target_img

        backup_path = self.backup_img(
            disk_properties["src"], backup_target, target_img
        )
        if self.compression:
            if not definition.get("tar", None):
                # all disks will be compacted in the same tar, so already
                # store it in definition if it was not set before
                definition["tar"] = os.path.basename(backup_path)

    def _disk_backup_name_format(self, snapdate, disk_name, *args, **kwargs):
        """
        Backup name format for each disk when no compression/compacting is set

        :param snapdate: date when external snapshots have been created
        :param disk_name: disk name currently being backup
        """
        return (
            "{}_{}".format(self._main_backup_name_format(snapdate), disk_name)
        )

    def backup_img(self, disk, target, target_filename=None):
        """
        Backup a disk image

        :param disk: path of the image to backup
        :param target: dir or filename to copy into/as. If self.compress,
                       target has to be a tarfile.TarFile
        :param target_filename: destination file will have this name, or keep
                                the original one. target has to be a dir
                                (if not exists, will be created)
        :returns backup_path: complete path of our backup
        """
        if self.compression:
            backup_path = self._add_img_to_tarfile(
                disk, target, target_filename
            )
        else:
            backup_path = self._copy_img_to_file(disk, target, target_filename)

        logger.debug("{} successfully copied".format(disk))
        return os.path.abspath(backup_path)

    def _add_img_to_tarfile(self, img, target, target_filename):
        """
        :param img: source img path
        :param target: tarfile.TarFile where img will be added
        :param target_filename: img name in the tarfile
        """
        total_size = os.path.getsize(img)
        tqdm_kwargs = {
            "total": total_size, "unit": "B", "unit_scale": True,
            "ncols": 0, "mininterval": 0.5
        }
        logger.debug("Copy {}…".format(img))
        if self.compression == "xz":
            backup_path = target.fileobj._fp.name
        else:
            backup_path = target.fileobj.name
        self.pending_info["tar"] = os.path.basename(backup_path)
        self._dump_pending_info()

        with tqdm(**tqdm_kwargs) as pbar:
            target.fileobject = get_progress_bar_tar(pbar)
            target.add(img, arcname=target_filename)

        return backup_path

    def _copy_img_to_file(self, img, target, target_filename=None):
        """
        :param img: source img path
        :param target: target is a directory if target_filename is set, or an
                       existing directory or a destination file
        :param target_filename: name of the img copy
        """
        if target_filename is not None:
            if not os.path.isdir(target):
                os.makedirs(target)
        target = os.path.join(target, target_filename or img)
        logger.debug("Copy {} as {}".format(img, target))
        copy_file_progress(img, target, buffersize=10*1024*1024)

        return target

    def post_backup(self, backup_target):
        """
        Post backup process

        Unregister callback and close backup_target if is tarfile
        """
        if self._ext_snapshot_helper is not None:
            self._ext_snapshot_helper.clean()
            self._ext_snapshot_helper = None
        if isinstance(backup_target, tarfile.TarFile):
            backup_target.close()

    def _parse_dom_xml(self):
        """
        Parse the domain's definition
        """
        return defusedxml.lxml.fromstring(self.dom.XMLDesc())

    def _dump_json_definition(self, definition):
        """
        Dump the backup definition as json

        Definition will describe our backup, with the date, backuped
        disks names and other informations
        """
        backup_date = arrow.get(definition["date"]).to("local")
        definition_path = os.path.join(
            self.target_dir,
            "{}.{}".format(self._main_backup_name_format(backup_date), "json")
        )
        with open(definition_path, "w") as json_definition:
            json.dump(definition, json_definition, indent=4)

    def _dump_pending_info(self):
        """
        Dump the temporary changes done, as json

        Useful
        """
        json_path = self._get_pending_info_json_path()
        with open(json_path, "w") as json_pending_info:
            json.dump(self.pending_info, json_pending_info, indent=4)

    def _clean_pending_info(self):
        os.remove(self._get_pending_info_json_path())
        self.pending_info = {}

    def _get_pending_info_json_path(self):
        backup_date = arrow.get(self.pending_info["date"]).to("local")
        json_path = os.path.join(
            self.target_dir,
            "{}.{}.pending".format(
                self._main_backup_name_format(backup_date), "json"
            )
        )
        return json_path

    def _main_backup_name_format(self, snapdate, *args, **kwargs):
        """
        Main backup name format

        Extracted in its own function so it can be easily override

        :param snapdate: date when external snapshots have been created
        """
        str_snapdate = snapdate.strftime("%Y%m%d-%H%M%S")
        return "{}_{}_{}".format(str_snapdate, self.dom.ID(), self.dom.name())

    def clean_aborted(self):
        is_ext_snap_helper_needed = (
            not self._ext_snapshot_helper and
            self.pending_info.get("disks", None)
        )
        if is_ext_snap_helper_needed:
            self._ext_snapshot_helper = DomExtSnapshot(
                self.dom, self.disks, self.conn, self.timeout
            )
            self._ext_snapshot_helper.metadatas = {
                "disks": {
                    disk: {"src": val["src"], "snapshot": val["snapshot"]}
                    for disk, val in self.pending_info["disks"].items()
                }
            }

        if self._ext_snapshot_helper:
            self._ext_snapshot_helper.clean()

        if self.pending_info.get("tar", None):
            self._clean_aborted_tar()
        else:
            self._clean_aborted_non_tar_img()
        try:
            self._clean_pending_info()
        except KeyError:
            # Pending info had no time to be filled, so had not be dumped
            pass

    def _clean_aborted_tar(self):
        tar_path = self.get_complete_path_of(self.pending_info["tar"])
        if os.path.exists(tar_path):
            self._delete_with_error_printing(tar_path)

    def _clean_aborted_non_tar_img(self):
        for disk in self.pending_info.get("disks", {}).values():
            if not disk.get("target", None):
                continue
            target_path = self.get_complete_path_of(disk["target"])
            if os.path.exists(target_path):
                self._delete_with_error_printing(target_path)

    def compatible_with(self, dombackup):
        """
        Is compatible with dombackup ?

        If the target is the same for both dombackup and self, same thing for
        compression and compression_lvl, self and dombackup are considered
        compatibles.
        """
        def same_dombackup_and_self_attr(attr):
            return getattr(self, attr) == getattr(dombackup, attr)

        attributes_to_compare = (
            "target_dir", "compression", "compression_lvl"
        )
        for a in attributes_to_compare:
            if not same_dombackup_and_self_attr(a):
                return False

        same_domain = dombackup.dom.ID() == self.dom.ID()
        return same_domain

    def merge_with(self, dombackup):
        self.add_disks(*dombackup.disks.keys())
        timeout = self.timeout or dombackup.timeout
        self.timeout = timeout

    def get_complete_path_of(self, filename):
        return os.path.join(self.target_dir, filename)


import sys
import collections

finput = sys.stdin.readline

dq = collections.deque()
dq.append((0, 0))

N = int(finput())
K = int(finput())

board = [[0]*N for _ in range(N)]
board[0][0] = 1

for i in range(K):
    y, x = map(int, finput().split())
    board[y-1][x-1] = 2

L = int(finput())
info = [finput().split() for _ in range(L)]

dy, dx = (-1,0,1,0), (0,1,0,-1)

board[0][0] = 1

def move(cy,cx, d):
    global board

    ny, nx = cy + dy[d], cx + dx[d]

    if ny >= N or nx >= N or nx < 0 or ny < 0 or board[ny][nx] == 1:
        return True
    elif board[ny][nx] == 0:
        dq.append((ny,nx))
        board[ny][nx] = 1
        py, px = dq.popleft()
        board[py][px] = 0
    else:
        dq.append((ny, nx))
        board[ny][nx] = 1

    return False

def solve():
    result = 0
    curD = 1

    for i in info:
        sec = int(i[0])

        for _ in range(result, sec, 1):
            result += 1
            cy, cx = dq[len(dq)-1]

            if move(cy, cx, curD):
                return result
        if i[1] == 'D':
            curD = (curD + 1) % 4
        else:
            curD = (curD + 3) % 4

    cy, cx = dq[len(dq) - 1]
    result += 1
    while not move(cy,cx,curD):
        result += 1
        cy, cx = dq[len(dq) - 1]

    return result

print(solve())


import lcm
import matplotlib.pyplot as plt
import numpy as np
import csv

from graph_data import vertex_data
from graph_data import map_data
from graph_data import sensors_data

# This file is used to visualize the gaussian process occupancy grid map (Work with test_gpc_sensor.cpp)
fontsize_dis = 8

num_row = 30
num_col = 30

class Vertex(object):
    def __init__(self, index, pos_x, pos_y, p, ig, occu):
        self.idx_ = index
        self.pos_ = [pos_x, pos_y]
        self.p_ = p
        self.ig_ = ig
        self.occupancy_ = occu

class map_vis(object):
    def __init__(self):
        self.num_row_ = num_row
        self.num_col_ = num_row
        self.num_fig = 0
        self.training_data_ = []

        self.graph_init()

    def graph_reset(self):
        self.vertex_ = {}

    def graph_init(self):
        self.graph_reset()

        for idx in range(self.num_col_ * self.num_row_):
            row = self.num_row_ - idx/ self.num_row_ - 1
            col = idx % self.num_col_
            p = 0.5
            ig = 0
            occupancy = "UNKNOWN"
            new_vertex = Vertex(idx, row, col, p, ig, occupancy)
            self.vertex_[idx] = new_vertex

    def map_data_handler(self, channel, data):
        self.graph_init()
        msg = map_data.decode(data)
        for cell in msg.vertex_:
            idx = cell.idx_
            self.vertex_[idx].ig_ = cell.ig_
            self.vertex_[idx].p_ = cell.p_
            if self.vertex_[idx].p_ == 0.0:
                self.vertex_[idx].occupancy_ = "FREE"
            elif self.vertex_[idx].p_ == 1.0:
                self.vertex_[idx].occupancy_ = "OCCUPIED"

    def training_data_handler(self,channel,data):
        msg = sensors_data.decode(data)
        for pos in msg.sensor_pos_:
            self.training_data_.append(pos)

        self.GP_map_vis()

    def vis(self):
        # Draw grid map
        x_min = 0
        x_max = self.num_col_
        y_min = 0
        y_max = self.num_row_
        plt.grid(color='black', linestyle='-', linewidth=1)
        plt.xlim(x_min,x_max)
        plt.ylim(y_min,y_max)
        plt.xticks(np.arange(x_min, x_max+1, 1))
        plt.yticks(np.arange(y_min, y_max+1, 1))

        # Draw each cell
        for cell in self.vertex_.values():
            plt.text(cell.pos_[1] + 0.25, cell.pos_[0] + 0.25,"{}".format(round(cell.p_,3)), color='black', fontsize=20)

        ZZ = np.empty([self.num_col_, self.num_row_])
        for cell in self.vertex_.values():
            ZZ[cell.pos_[1],cell.pos_[0]] = cell.p_

        # The number here is the num of col and row + 1
        XX, YY = np.mgrid[0:self.num_col_:11j, 0:self.num_row_:11j]

        CMAP = plt.get_cmap('jet')
        plt.pcolormesh(XX,YY,ZZ,cmap=CMAP)
        cb = plt.colorbar(shrink = 1.0)
        cb.ax.set_yticklabels(cb.ax.get_yticklabels(), fontsize=30)

    def GP_map_vis(self):
        x_min = 0
        x_max = self.num_col_
        y_min = 0
        y_max = self.num_row_
        plt.grid(color='black', linestyle='-', linewidth=1.5)
        plt.xlim(x_min,x_max)
        plt.ylim(y_min,y_max)
        plt.xticks(np.arange(x_min, x_max+1, 10))
        plt.yticks(np.arange(y_min, y_max+1, 10))

         # Draw each cell
        for cell in self.vertex_.values():
            plt.text(cell.pos_[1] + 0.25, cell.pos_[0] + 0.25,"{}".format(round(cell.p_,2)), color='black', fontsize=fontsize_dis)
            if (cell.p_ >= 0.45 and cell.p_ <= 0.55):
                x_region = np.arange(cell.pos_[1], cell.pos_[1] + 2, 1)
                y_region = cell.pos_[0]
                plt.fill_between(x_region, y_region, y_region +1, facecolor='gray', interpolate=True)

            if (cell.p_ > 0.55):
                x_region = np.arange(cell.pos_[1], cell.pos_[1] + 2, 1)
                y_region = cell.pos_[0]
                plt.fill_between(x_region, y_region, y_region +1, facecolor='black', interpolate=True)

        for dt in self.training_data_:
            cv = self.vertex_[dt]
            row = cv.pos_[1] + 0.5
            col = cv.pos_[0] + 0.5
            plt.plot(row,col,"*r",markersize=20)

        plt.show()

def main():
    lc = lcm.LCM()
    map = map_vis()

    for i in range(100000):
        Graph_data = str(i) + "GraphDataGP"
        Training_data = str(i) + "TrainingData"
        subscription = lc.subscribe(Graph_data, map.map_data_handler)
        subscription = lc.subscribe(Training_data, map.training_data_handler)

    try:
        while True:
            lc.handle()
    except KeyboardInterrupt:
        pass

    lc.unsubscribe(subscription)

if __name__ == '__main__':
    main()


import osqp
import numpy as np
import scipy
from scipy import sparse

# NOTE: this code does not work due to improper modeling of torques in contact with the robot arm

# To get this code working without contact torques, we need to extend the CBF formalism to accomodate
# systems where the control input is two derivatives away from the state variable. We use
# exponential barrier functions from this CBF review paper: https://arxiv.org/abs/1903.11199

# This code uses OSQP to solve a quadratic program to compute the safe torque and was based off
# of an example script in the docs: https://osqp.org/docs/examples/least-squares.html
# For ease of debugging, I converted all the sparse linear algebra operations into normal explicit
# numpy operations. We are solving a problem of dimensionality-14, which, for these solvers, is pretty
# small, but in case you need a speed up, you can use the original script as a guide of where
# to re-substitute the scipy.linalg.sparse operations.

# Generate problem data
# sp.random.seed(1)
# m = 30
# n = 20
# Ad = sparse.random(m, n, density=0.7, format='csc')
# b = np.random.randn(m)

# problem setup
# OSQP data

class JointLimitCBFSolver():

    def __init__(self, lower_limits, upper_limits, gamma=1.0):
        self.ll = lower_limits
        self.ul = upper_limits # (both of shape (7,)
        self.gamma = gamma  # for proportional class K function (see Ames above)
        self.prob = osqp.OSQP()
        self.init_problem = False

    def compute_safe_osc_output(self, q, qd, qdd, g, u_pi):
        f = np.concatenate([qd, qdd])

        # this is a slight variant, since joint space are 'generalized' coordinates for the system
        #
        g = np.vstack([np.zeros((7, 6)), g])

        # compute CBF h(x) and \partial h / \partial x
        h = -(q - self.ll) * (q - self.ul)
        dh_dx = np.diag(-(2 * q - (self.ul + self.ll)))
        # compute lie derivatives (but since this is R^n, they are directional derivs)
        Lf_h = np.dot(dh_dx, f)  # since the velocity of the system is f (dynamics)
        Lg_h = np.dot(dh_dx, g)  # affine control transformation

        # in addition to these, we need to compute the following terms
        # Lf^2_h (lie derivative of h twice in the direction of f)
        # LgLf (lie derivative of h first in direction of f then in direction of g)
        # Here are the expressions written out in basic calculus:

        # Lf^2_h
        # \sum_j f_j (\sum_i \frac{del f_i}{del x_j} x \frac{del h}{\del x_i} + f_i \frac{del h}{x_j x_i}
        # we have {del h}{del x_i} in dh_dx. we need{del f_i}{del x_j} (derivative of ith coord of f with respect to joint variable j}{
        # LgLf_h
        # \sum_j g_j (same summation mess indexed by i for Lf^2_h)

        P = scipy.linalg.block_diag(np.zeros((6, 6)), np.eye(6))
        c = np.zeros(6 + 6)
        A = np.vstack([
            np.hstack([np.eye(6), -np.eye(6)]),
            np.hstack([Lg_h, np.zeros((14, 6))])])
        l = np.hstack([u_pi, -self.gamma * h - Lf_h])
        u = np.hstack([u_pi, np.inf * np.ones(7)])
        # then, modify this constraint here to respect the exponential ZBF:
        # currently, we respect the constraint Lf_h + Lg_h u + \gamma h(x) \geq 0
        # now we need to replace that with Lf^2_h + LfLg_h u + (gamma, gamma) \dot (h(x), Lfh) \geq 0.

        # Create an OSQP object
        prob = osqp.OSQP()

        # Setup workspace
        prob.setup(P, c, A, l, u)

        # Solve problem
        return prob.solve()


import glob
from shutil import copyfile
from tqdm import tqdm

img_path = "/dataset.local/all/hangd/src_code_3/Pytorch-UNet/dataset/imgs/*"
dest_img_path = "/dataset.local/all/hangd/dynamic_data/one32rd/imgs"
dest_mask_path = "/dataset.local/all/hangd/dynamic_data/one32rd/masks"

count = 0
num_first_trial_files = len(glob.glob(img_path))//32

for img in tqdm(glob.glob(img_path)):
    # print(img)
    count += 1
    copyfile(img, dest_img_path+img[img.rfind("/"):])
    mask_path = img.replace("/imgs/", "/masks/")
    copyfile(mask_path, dest_mask_path+mask_path[mask_path.rfind("/"):])
    if count == num_first_trial_files:
        break


'''
resize 256*256

'''
import cv2
import os

train_path = './data'

list1=[]
for file in os.listdir(train_path):
    class_image_path = os.listdir(train_path + "/" + file)
    # print(file)
    image_out_path = train_path + '/' + file
    for files in class_image_path:
        # print(image_input_dir + '/' + file + '/' + files)
        image_path = train_path + '/' + file + '/' + files
        img = cv2.imread(image_path)
        dst_size = (256, 256)
        img_resize = cv2.resize(img, dst_size, interpolation = cv2.INTER_AREA)
        cv2.imwrite(image_path, img_resize)
        print(img_resize.shape)

# for files in os.listdir(train_path):
#     train_path2 = os.listdir(train_path + "/" + files)
#     for file in train_path2:
#         train_path = train_path + '/' + file + '/' + files
#         print(train_path+ '/n')
#         img = cv2.imread(train_path)
#         dst_size = (256, 256)
#         img_resize = cv2.resize(img, dst_size, interpolation = cv2.INTER_AREA)
#         cv2.imwrite(train_path, img_resize)
#         print(img_resize.shape)


"""Add challenge resource

Revision ID: 5c1825290fc4
Revises: c63d06374f79
Create Date: 2020-12-15 17:31:28.562671

"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision = '5c1825290fc4'
down_revision = 'c63d06374f79'
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('challenge',
    sa.Column('id', postgresql.UUID(as_uuid=True), nullable=False),
    sa.Column('title', sa.String(length=255), nullable=False),
    sa.Column('description', sa.String(), nullable=True),
    sa.Column('end_date', sa.DateTime(), nullable=False),
    sa.Column('active', sa.Boolean(), nullable=False),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('title')
    )
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_table('challenge')
    # ### end Alembic commands ###


from __future__ import print_function
import os
import argparse
import torch
import numpy as np
import cv2
import time
from torchvision import transforms as T
from PIL import Image
import math
from tqdm import tqdm
import glob

LABEL = "/mnt/sdb1/data/widerface/train/label.txt"
NEW_LABEL = "/mnt/sdb1/data/widerface/train/new_label.txt"
COVERED_LABEL = "/mnt/sdb1/data/widerface/train/covered_label.txt"
PRETRAIN = "/mnt/sdb3/Git_clone/Face-Detector-1MB-with-landmark/data/SeeTheFullFace/checkpoints/maskMobileULite.pth"
AREA = 2500

parser = argparse.ArgumentParser(description='Retinaface')
parser.add_argument('-m', '--trained_model', default='checkpoints/mobilenet0.25_Final.pth',
                    type=str, help='Trained state_dict file path to open')
parser.add_argument('--network', default='mobile0.25', help='Backbone network mobile0.25 or resnet50')
parser.add_argument('--cpu', action="store_true", default=True, help='Use cpu inference')
parser.add_argument('--confidence_threshold', default=0.02, type=float, help='confidence_threshold')
parser.add_argument('--top_k', default=5000, type=int, help='top_k')
parser.add_argument('--nms_threshold', default=0.4, type=float, help='nms_threshold')
parser.add_argument('--keep_top_k', default=750, type=int, help='keep_top_k')
parser.add_argument('-s', '--save_image', action="store_true", default=True, help='show detection results')
parser.add_argument('--vis_thres', default=0.6, type=float, help='visualization_threshold')
args = parser.parse_args()

TARGET_BRIGHTNESS = 0.43
TARGET_CONSTRAST = 0.43

def check_mask(model, transform, img):
    if img.shape[0]*img.shape[1] >0 :
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        img = Image.fromarray(img).convert('RGB')
        img = transform(img)
        img = img.unsqueeze(0)
        res = model(img)
        r = np.argmax(res.detach().cpu())

        if r:
            return False, math.exp(res[0][r])/(math.exp(res[0][0])+math.exp(res[0][1]))
        else:
            return True, math.exp(res[0][r])/(math.exp(res[0][0])+math.exp(res[0][1]))

    else:
        return False, -1

class FPS_counter():
    def __init__(self):
        self.start = time.time()
        self.count = 0

    def step(self):
        self.now = time.time()
        self.count += 1
        fps = self.estimate()
        return fps

    def estimate(self):
        if self.count >=50 :
            self.count = 0
            self.start = time.time()
        fps = self.count/(self.now-self.start)
        self.count += 1
        return fps

if __name__ == '__main__':
    torch.set_grad_enabled(False)

    # net and model
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    maskNet = torch.load(PRETRAIN, map_location=device)
    maskNet.eval()

    mean = [0.485, 0.456, 0.406]
    std = [0.229, 0.224, 0.225]
    transform = T.Compose([
                            T.Resize((112,112)),
                            T.ToTensor(),
                            T.Normalize(mean, std)])

    print('Finished loading model!')
    # Load labels
    f = open(LABEL,'r')
    # n_f = open(NEW_LABEL, "a")
    lines = f.readlines()
    isFirst = True
    labels = []
    words = []
    imgs_path = []
    imgs_covered_path = []
    imgs_save_path = []
    links = []
    for line in lines:
        line = line.rstrip()
        if line.startswith('#'):
            links.append(line)
            if isFirst is True:
                isFirst = False
            else:
                labels_copy = labels.copy()
                words.append(labels_copy)
                labels.clear()
            path = line[2:]
            path = LABEL.replace('label.txt','images/') + path
            imgs_path.append(path)
            imgs_save_path.append(path.replace("images/", "unmask/"))
            imgs_covered_path.append(path.replace("images/", "covered/"))
        else:
            line = line.split(' ')
            label = [float(x) for x in line]
            labels.append(label)
    words.append(labels)
    skip_count = 0
    save_count = 0
    for index in tqdm(range(len(imgs_path))):
        save = True
        img = cv2.imread(imgs_path[index])
        folder = ""
        path_split = imgs_save_path[index].split("/")[:-1]
        for p in path_split:
            folder += p + "/" if p != path_split[-1] else p
        os.makedirs(folder, exist_ok=True)
        os.makedirs(folder.replace("unmask", "covered"), exist_ok=True)
        height, width, _ = img.shape

        annotations = np.zeros((0, 15))
        labels = words[index]
        dets = []
        if len(labels) == 0:
            continue
        for idx, label in enumerate(labels):
            annotation = np.zeros((15)).astype(np.int32)
            # bbox
            annotation[0] = int(label[0])  # x1
            annotation[1] = int(label[1]) # y1
            annotation[2] = int(label[2])  # w
            annotation[3] = int(label[3])  # h
            # landmarks()
            annotation[4] = int(label[4])    # l0_x
            annotation[5] = int(label[5])    # l0_y
            annotation[6] = int(label[7])    # l1_x
            annotation[7] = int(label[8])    # l1_y
            annotation[8] = int(label[10])   # l2_x
            annotation[9] = int(label[11])   # l2_y
            annotation[10] = int(label[13])  # l3_x
            annotation[11] = int(label[14])  # l3_y
            annotation[12] = int(label[16])  # l4_x
            annotation[13] = int(label[17])  # l4_y

            this_det = []
            for i in annotation:
                this_det.append(i)
            dets.append(this_det)

        for det in dets:
            if det[3]*det[2] < AREA:
                continue
            else:
                face_in_frame = img[det[1]:det[1]+det[3], det[0]:det[0] + det[2]]
                res, prob = check_mask(maskNet, transform, face_in_frame)
                # 1 = no mask
                if res:
                    cv2.imshow("test", face_in_frame)
                    cv2.waitKey(10)
                    save = False
                    print(f"skiped {skip_count}/{index} frames")
        if save:
            n_f = n_f = open(NEW_LABEL, "a")
            n_f.write(links[index] + "\n")
            cv2.imwrite(imgs_save_path[index], img)
            for det in dets:
                new_anno = ""
                for a in det:
                    new_anno += str(a) + " " if a != det[-1] else str(a)
                n_f.write(new_anno + " 1.0 " + "\n")
            n_f.close()
            save_count+=1
        else:
            n_f = n_f = open(COVERED_LABEL, "a")
            n_f.write(links[index] + "\n")
            cv2.imwrite(imgs_covered_path[index], img)
            for det in dets:
                new_anno = ""
                for a in det:
                    new_anno += str(a) + " " if a != det[-1] else str(a)
                n_f.write(new_anno + " 1.0 " + "\n")
            n_f.close()
            skip_count += 1

    print(f"Saved {save_count} frames, skiped {skip_count} frames from {len(imgs_path)} frames")


import pygame
from pygame.sprite import Sprite

class Bullet(Sprite):
    """A class to manage all the bullets fired fromthe ship."""

    def __init__(self, ai_settings, screen, ship):
        """Create a bullet object at the current ship's position."""
        super(Bullet, self).__init__()
        self.screen = screen

        # Let's crete a bullet at top left corner initially since we dont have a image ref.
        # i.e., (0, 0) and then set it to the correct position.
        self.rect = pygame.Rect(0, 0, ai_settings.bullet_width, ai_settings.bullet_height)
        self.rect.centerx = ship.rect.centerx
        self.rect.top = ship.rect.top

        # Now let's store the bullet's y-co-ordinate as a decimal value
        self.y = float(self.rect.y)

        self.color = ai_settings.bullet_color
        self.speed_factor = ai_settings.bullet_speed_factor

    def update(self):
        """Move the bullet up the screen."""
        # Update the decimal position of the bullet on the screen.
        self.y -= self.speed_factor
        # Now we must also update the rectangle position on the screen.
        self.rect.y = self.y

    def draw_bullets(self):
        """Draw the bullets on the screen."""
        pygame.draw.rect(self.screen, self.color, self.rect)


#!/usr/bin/env python3

"""
This script contains a proof-of-concept of how streams (and their consumers) could be added and removed dynamically.
It has three main components:

- The code outside of the classes represents the tool, like the :mod:`tools.consume` tool.
  It has two purposes: it instantiates everything, and it assigns tasks to the :class:`TaskManager`.
  In reality, the code will be slightly more complex since, like the :mod:`tools.consume` tool, the outer code will be split into two processes: `stream_process` and a `consume_process`.

- The :class:`TaskManager` represents a `SplitConsumer`.
  While running, it continuously monitors its assigned tasks.
  If it has a task it has not seen before, it sets it running.
  If any ongoing task is no longer assigned to it, the class instructs the task to stop and stores its output.
  Once it has no more tasks to perform, the :class:`TaskManager` returns each task's output.

- The :class:`Task` represents a `Consumer`.
  The :class:`Task` performs its job until the :class:`TaskManager` instructs it to stop, at which point it returns an output.

The following communication takes place:

- Between the outer code and the :class:`TaskManager`.
  The two share a list of tasks for the input (from the outer code to the :class:`TaskManager`) and a dictionary for the input (from the :class:`TaskManager` to the outer code).
  The latter already exists in the :mod:`consume` tool, while the former would have to be added separately.
  The final version would also have to add a queue of tweets to the communication.
- Between the :class:`TaskManager` and the :class:`Task`.
  The :class:`TaskManager` instructs the :class:`Task` to stop, and when it does, the :class:`TaskManager` gathers its output.

Of course, the outer code does not have to assign the tasks to the :class:`TaskManager`.
The :class:`TaskManager` could load them itself (such as by loading the streams from a database).
The outer code assigns the tasks only to be more interactive.

The main difference, then, lies in the :class:`TaskManager`'s :func:`TaskManager.run_tasks` function.
Instead of running (using `asyncio.gather`) all tasks at once, it sets them running using `asyncio.ensure_future` and 'tracks' them (in the `ongoing` variable).
The :class:`TaskManager` only gathers the tasks' outputs (using `asyncio.gather`) when it stops them.
Here too, the logic to stop tasks can be different; the :class:`TaskManager` could check with the database whether they are still relevant and stop them otherwise.
"""

import asyncio
from multiprocessing import Process, Manager
from multiprocessing.managers import BaseManager
import signal
import time

loop = asyncio.get_event_loop()

class TaskManager():

    def __init__(self):
        """
        Initialize the tasks application.
        """

        self.running = False

    def run(self, tasks, outputs):
        """
        Run the tasks from the given shared list.

        :param tasks: A list of tasks shared by all processes.
        :type tasks: :class:`multiprocessing.managers.ListProxy`
        :param outputs: A list of outputs shared by all processes.
        :type outputs: :class:`multiprocessing.managers.DictProxy`
        """

        async def run_tasks():
            ongoing = { } # the ongoing tasks, storing the tuples of the asyncio tasks and the :class:`Task` class.
            while tasks:
                # start the new tasks
                for task in tasks:
                    if task.ID not in ongoing and task.ID not in outputs:
                        _task = asyncio.ensure_future(task.run())
                        ongoing[task.ID] = (_task, task)

                # gather the results from the stopped tasks
                for task_id, (asyncio_task, task) in ongoing.items():
                    if task_id not in outputs and not any( task_id == _task.ID for _task in tasks ):
                        task.stop()
                        outputs[task_id] = (await asyncio.gather(asyncio_task))[0]
                        print(f"Task { task_id } has stopped with counter { outputs[task_id] }")

                await asyncio.sleep(0.1)

            # gather the results from any remaining tasks
            for task_id, (asyncio_task, task) in ongoing.items():
                if task_id not in outputs and not any( task_id == _task.ID for _task in tasks ):
                    task.stop()
                    outputs[task_id] = (await asyncio.gather(asyncio_task))[0]
                    print(f"Task { task_id } has stopped with counter { outputs[task_id] }")

        def sigint_handler(signal, frame):
            """
            Stop all remaining tasks when the user presses CTRL+C.
            Clearing the remaining tasks also means that the `run_tasks` function will stop processing any tasks.
            For a demo, try pressing CTRL+C before the third task starts.
            """
            while len(tasks):
                tasks.pop()

        signal.signal(signal.SIGINT, sigint_handler)

        self.running = True
        loop.run_until_complete(run_tasks())

    def stop(self):
        """
        Instruct the task manager to stop running.
        """

        self.running = False

class Task():

    def __init__(self, ID):
        """
        Create a task.

        :param ID: The task ID.
                   Tasks need a unique ID because when they are loaded from the shared list into memory, their ID changes.
        :type ID: int
        """

        self.ID = ID
        self.running = False

    async def run(self):
        """
        Set the task running.

        :return: The ID of times the function printed something.
        :rtype: int
        """

        print(f"Task { self.ID } starting")
        self.running = True
        counter = 0 # how many full seconds have elapsed
        progress = 0 # how long the task has run for (seconds)

        while self.running:
            progress += 0.1
            if int(round(progress, 2)) > counter:
                print(f"Task { self.ID } running", flush=True)
                counter = int(round(progress, 2))
            await asyncio.sleep(0.1)

        print(f"Task { self.ID } stopping after { round(progress, 2) }s")
        return counter

    def stop(self):
        """
        Instruct the task to stop running.
        """

        self.running = False

# do nothing (here) when the user presses CTRL+C as the task manager will stop on its own
def sigint_handler(signal, frame):
    return
signal.signal(signal.SIGINT, sigint_handler)

# set up the shared inputs and outputs
resource_manager = Manager()
tasks, outputs = resource_manager.list(), resource_manager.dict()

# start the task manager
manager = TaskManager()
task_manager = Process(target=manager.run, args=(tasks, outputs))
task_manager.start()

# start the first task
tasks.append(Task(1))

# start a second task
time.sleep(2)
tasks.append(Task(2))

# stop the first task and start a third
time.sleep(3)
if len(tasks):
    tasks.pop(0)
tasks.append(Task(3))

task_manager.join()
print(outputs)


from urllib.request import urlopen
from bs4 import BeautifulSoup
import re
import sql

pages=set()

def getlink(newpage, recursionLevel):
    global pages
    if recursionLevel > 4:
        return;
    frompage_id = sql.insertPageIfNotExists(newpage)
    url = urlopen("https://en.wikipedia.org"+newpage)
    html = BeautifulSoup(url,"lxml")
    print(html.title.get_text())
    links = html.findAll("a",href=re.compile("^/wiki/((?!:).)*$"))
    for link in links:
        href = link.attrs['href']
        if href not in pages:
            topage_id=sql.insertPageIfNotExists(href)
            sql.insertLink(frompage_id, topage_id)
            pages.add(href)
            print(href)
            getlink(href,recursionLevel+1)

getlink("/wiki/Main_Page",0)


import typing

from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from aiogram.utils.callback_data import CallbackData

ikb_booking_callback = CallbackData("booking", "id")

def cancel_booking_btn(
        booking: dict
):
    markup = InlineKeyboardMarkup(1)
    btns = [
        InlineKeyboardButton(
            text=f"Отменить: {booking.get('width').strftime('%Y-%m-%d %H:%M')} ({booking.get('master_name')})",
            callback_data=ikb_booking_callback.new(id=booking.get("id"))
        )
    ]
    markup.add(*btns)

    return markup


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

import sys
import argparse
from collections import Counter
import json
from progressbar import Bar
from vkgroups import VkUser

def write_json_file(uid: "int user id",
                    groups: "list of dict with groups info"):
    filename = "{}_groups.json".format(uid)
    with open(filename, 'w', encoding="utf8") as jf:
        jf.write(json.dumps(groups, ensure_ascii=False, indent=3))
    print("group analysis results has been stored in {}".format(filename))

def main(vk: "VkUser object provides access to VK API",
         limit: "int number friends per group"):
    user_friends = vk.get_friends_list()
    user_groups = vk.get_groups_list(vk.get_user_id())
    friends_number = len(user_friends)
    print("{}({}) has {} friends and participate in {} groups\n".format(vk.get_user_name(), vk.get_user_id(),
                                                                        friends_number, len(user_groups)))
    friends_groups = list()
    bar = Bar(friends_number, 'loading friends groups')
    for i, friend in enumerate(user_friends):
        groups = vk.get_groups_list(friend)
        if groups:
            friends_groups.extend(groups)
        bar.show_progress(i)
    else:
        bar.show_progress_100("loaded groups data for {} friends".format(friends_number))
    group_counts = Counter(friends_groups)  # count number of friends using each group, place results in the dict
    result = list(set(user_groups) - set(group_counts.keys()))  # unique user groups
    if limit > 0:  # add groups where friends participate
        for group, count in group_counts.items():
            if group in user_groups and count <= limit:
                result.append(group)
    write_json_file(vk.get_user_id(), [vk.get_group_info(group) for group in result])

def check_limit(value: "int") -> int:
    ival = int(value)
    if ival < 0 or ival > 99:
        raise argparse.ArgumentTypeError("{} is an invalid limit value".format(value))
    return ival

if __name__ == '__main__':
    ap = argparse.ArgumentParser(description='This program looks for secret groups of the VK user')
    ap.add_argument("uid", help="  user id or short 'screen name'")
    ap.add_argument("--token", dest="token", action="store", help="  VK API access token")
    ap.add_argument("--limit", dest="limit", action="store", type=check_limit, default=0,
                    help="  max number of friends in one group (0 <= limit <= 99, default=0)")
    args = ap.parse_args(sys.argv[1:])
    if args.token:
        vkapi = VkUser(userid=args.uid, token=args.token)
    else:
        vkapi = VkUser(userid=args.uid)
    main(vkapi, args.limit)


from functools import reduce
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt

# noinspection PyTypeChecker
def k_means(data, kernel, step=0):
    """
    :param data: samples
    :param kernel: numeric or list
    :param step: int
    """
    # c: set groups, u: kernel vector
    if isinstance(kernel, list):
        c = [[sample] for sample in kernel]
        u = [data[sample] for sample in kernel]
    else:
        index = np.arange(len(data))
        np.random.shuffle(index)
        index = index[:kernel]
        c = [[sample] for sample in index]
        u = [data[sample] for sample in index]

    for i in range(step):
        # append all the vectors into different set groups.
        for sample_index in range(len(data)):
            dist_list = [np.linalg.norm(data[sample_index] - u[set_index]) for set_index in range(len(u))]
            set_index = np.argmin(np.array(dist_list))
            if sample_index not in c[set_index]:
                c[set_index].append(sample_index)

        # reset the kernel vector.
        for set_index in range(len(u)):
            sum_vector = reduce(lambda x, y: x + y, [data[sample_index] for sample_index in c[set_index]])
            u[set_index] = sum_vector / len(c[set_index])

    # matrix of samples after k-means.
    v = []
    for set_index in range(len(u)):
        v.append(data[c[set_index]])
    return c, u, v

# noinspection PyTypeChecker
def k_means_graph(data, kernel, step=0):
    fig = plt.figure()
    ax = fig.add_subplot(111)
    c, u, v = k_means(data=data, kernel=kernel, step=step)
    for index in range(len(c)):
        point, = ax.plot(v[index][:, 0], v[index][:, 1], 'o', markersize=10)
        ax.plot(u[index][0], u[index][1], '+', c=point.get_color(), markersize=10)

if __name__ == '__main__':
    watermelon = pd.read_csv('./watermelon.csv', sep='\t', header=0)

    k_means_graph(data=watermelon.values, kernel=3, step=5)

    pd.scatter_matrix(watermelon, diagonal='kde', alpha=.8, marker='o')
    plt.show()


#!/usr/bin/env python3
import json
import base64
from emzmachine import run_program

WELCOME_MESSAGE = """EmzMachine 8000
---------------

Input EmzMachine 8000 OpCodes (as hex string):
"""

if __name__ == "__main__":
    try:
        USER_PROGRAM = bytearray.fromhex(input(WELCOME_MESSAGE))
    except:
        print("Error occured in reading program.\nPlease input program as hexadecimal string.")
        exit(1)

    print('Program:', bytes(USER_PROGRAM))

    hyp = run_program(USER_PROGRAM)

    for vm in hyp.vms:
        if vm[0] == 'USER':
            print("result:")
            for item in vm[3].stdout:
                print(item)

            print("machine state")
            machine_state = vm[3].machine_state
            machine_state['FB'] = base64.b64encode(machine_state['FB']).decode()
            machine_state['TEXT'] = machine_state['TEXT'].decode()
            print(json.dumps(machine_state))
    exit(0)


from datetime import datetime, timedelta
import multiprocessing
import faster_whisper

STYLES = {
    # Great format to run with screenshots
    1: [
        "Fontsize={font_size},",
        "PrimaryColour={primary_color},",
        "OutlineColour=&H40000000,",
        "Bold={bold},",
        "Alignment=6,",
        "MarginL=0,",
        "MarginR=0,",
        "MarginV=200",
    ],
    # Centerd Bold Text
    2: [
        "Fontsize={font_size},",
        "PrimaryColour=&HFFFFFF&,",
        "OutlineColour=&H40000000,",
        "Bold={bold},",
        "Alignment=10,",
        "MarginL=0,",
        "MarginR=0,",
        "MarginV=0",
    ],
}

def get_subtitles_style(
    primary_color: str = "&HFFFFFF&",
    font_size: float = 18,
    bold: bool = True,
    desired_style: int = 1,
):
    """
    Get subtitles style.
    :param primary_color: Primary color.
    :param font_size: Font size.
    :param bold: Bold text.
    :param desired_style: Desired style.
    :return: Subtitles style.
    """
    return "".join(STYLES[desired_style]).format(
        primary_color=primary_color, font_size=font_size, bold=bold
    )

def generate_srt(subtitles: list) -> str:
    """
    Generate an SRT file from a list of timestamps of words
    :param subtitles: Subtitles list.
    :return: .srt file contents
    """
    timestamp_format = datetime.strptime(
        "00:00:00,000", "%H:%M:%S,%f"
    )  # Null element of addition to keep the timestamp format
    srt = []
    for i, subtitle in enumerate(subtitles):
        start_time = (subtitle["start_time"] + timestamp_format).strftime(
            "%H:%M:%S,%f"
        )[:-3]
        end_time = (subtitle["end_time"] + timestamp_format).strftime("%H:%M:%S,%f")[
            :-3
        ]
        words = subtitle["words"]

        srt.append(f"{i+1}")
        srt.append(f"{start_time} --> {end_time}")
        srt.append(" ".join(words) + "\n")

    return "\n".join(srt)

def append_segment_to_subtitles(subtitles: list, segment: tuple) -> list:
    """
    Append segment to subtitles.
    :param subtitles: Subtitles list.
    :param segment: Segment to append.
    :return: Subtitles list.
    """
    # Calculate end_time for each word
    start_time = timedelta(seconds=segment.start)
    end_time = timedelta(seconds=segment.end)
    # Create subtitle for each word
    subtitle = {
        "start_time": start_time,
        "end_time": end_time,
        "words": [segment.word],
    }
    subtitles.append(subtitle)
    return subtitles

def transcribe_audio(audio_path: str, srt_path: str, word_by_word: bool = True) -> None:
    """
    Transcribe audio file to SRT file.
    :param audio_path: Path to the audio file.
    :param srt_path: Path to the SRT file.
    :param word_by_word: If True, the subtitles will be generated by each word.
    """
    model = faster_whisper.WhisperModel(
        "base", cpu_threads=multiprocessing.cpu_count()
    )  # You can choose: [tinu, base, small, medium] to more accurate subtitles
    transcribe = model.transcribe(audio=audio_path, word_timestamps=True)
    segments = transcribe[0]
    subtitles = []
    for segment in segments:
        # Segment Information
        words = segment.words
        if word_by_word:
            for word in words:
                subtitles = append_segment_to_subtitles(subtitles, word)
        else:
            subtitles = append_segment_to_subtitles(subtitles, segment)

    # Gererate the SRT File
    srt_content = generate_srt(subtitles)

    # Write the SRT File
    with open(srt_path, "w", encoding="utf-8") as file:
        file.write(srt_content)


from selenium import webdriver
import time
import unittest

class NewVisitorTest(unittest.TestCase):

    def setUp(self):
        self.browser = webdriver.Firefox()

    def tearDown(self):
        self.browser.quit()

    def test_opens_blog_home_page_and_browses(self):
        #user opens blog home page
        self.opens_blog_page()

        #they expect the correct header and title to be shown
        self.assertIn("Davinder's Blog", self.browser.title)
        header_text = self.browser.find_element_by_tag_name('h1').text
        self.assertIn("Davinder's Blog", header_text)

        time.sleep(1)

        #they then move on to the CV page
        self.opens_CV_page()

        #this also needs the correct header and title
        self.assertIn("Davinder's CV", self.browser.title)
        header_text = self.browser.find_element_by_tag_name('h1').text
        self.assertIn("Davinder's CV", header_text)

        time.sleep(1)

        #they also see an option to return to the Blog site
        header_text = self.browser.find_element_by_tag_name('h3').text
        self.assertIn("Davinder's Blog", header_text)

        #they test this link
        self.opens_blog_page()

        time.sleep(1)

        #they then move back to the CV page
        self.opens_CV_page()

        time.sleep(1)

        #they click on a section of the CV expect to see the details
        self.opens_CV_section_detail(1)

        time.sleep(1)

        #they click edit and expect to see the option to edit the section
        self.opens_CV_section_edit(1)

        time.sleep(1)

        #they then move back to the CV page
        self.opens_CV_page()

        time.sleep(1)

        #they click on another section of the CV expect to see the details
        self.opens_CV_section_detail(2)
        time.sleep(1)

        #they click edit and expect to see the option to edit the section
        self.opens_CV_section_edit(2)

        time.sleep(1)

    def opens_CV_page(self):
        self.browser.get('http://dsb874.pythonanywhere.com/CV')

    def opens_blog_page(self):
        self.browser.get('http://dsb874.pythonanywhere.com/')

    def opens_CV_section_detail(self, pageNum):
        self.browser.get('http://dsb874.pythonanywhere.com/section/'+str(pageNum)+'/')

    def opens_CV_section_edit(self, pageNum):
        self.browser.get('http://dsb874.pythonanywhere.com/section/'+str(pageNum)+'/edit/')

if __name__ == '__main__':
    unittest.main(warnings='ignore')


from selenium import webdriver # https://www.selenium.dev/documentation
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import unittest # https://docs.python.org/3/library/unittest.html

class NavigationExample(unittest.TestCase):

    URL = "https://google.com"

    '''
        Overrides the setUp method provided by unittest.TesCase
    '''
    def setUp(self):
        self.browser = webdriver.Chrome()
        self.browser.set_page_load_timeout(30) # seconds for page to load
        self.browser.implicitly_wait(10) # seconds for elements
        self.browser.get(self.URL)
        self.browser.maximize_window()

    def tearDown(self):
        self.browser.quit()

    def accept_cookies(self):
        accept_cookies_btn = self.browser.find_element(By.XPATH, "//button[div[text()='Accept all']]")
        # Accept cookies
        accept_cookies_btn.click()

    '''
        Uses JavaScript executor for opening a tab (compatible with Selenium < 4)
    '''
    def test_new_tab_example(self):
        wait = WebDriverWait(self.browser, 10)
        self.accept_cookies()

        # get identifier for current tab
        original_tab = self.browser.current_window_handle # unique window handle ID

        # open a new tab by executing JS and wait for it to open
        self.browser.execute_script("window.open('https://bing.com')")
        wait.until(EC.number_of_windows_to_be(2))

        # switch to new tab
        self.browser.switch_to.window(self.browser.window_handles[1])

        # close current tab
        self.browser.close()

        # return to original tab
        self.browser.switch_to.window(original_tab)

        self.assertEqual("Google", self.browser.title)

    '''
        Selenium 4 compatible way of opening a new tab
    '''
    def test_new_tab_example2(self):
        wait = WebDriverWait(self.browser, 10)
        self.accept_cookies()

        # get identifier for current tab
        original_tab = self.browser.current_window_handle # unique window handle ID

        # open a new tab and switch to it
        self.browser.switch_to.new_window("tab")
        wait.until(EC.number_of_windows_to_be(2))

        # close current tab
        self.browser.close()

        # return to original tab
        self.browser.switch_to.window(original_tab)

        self.assertEqual("Google", self.browser.title)

    '''
        Selenium 4 compatible way of opening a new browser window
    '''
    def test_new_window_example(self):
        self.accept_cookies()

        # get identifier for current tab
        original_tab = self.browser.current_window_handle # unique window handle ID

        # open a new window and switch to it
        self.browser.switch_to.new_window("window")

        # close current window
        self.browser.close()

        # return to original window
        self.browser.switch_to.window(original_tab)

        self.assertEqual("Google", self.browser.title)

    def test_resize_window_example(self):
        self.accept_cookies()

        # window sizes
        mobile_window_size = (520, 850)
        tablet_window_size = (780, 1024)
        desktop_window_size = (1024, 720)

        # get original size
        original_window_size = self.browser.get_window_size()
        original_width = original_window_size.get("width")
        original_height = original_window_size.get("height")

        # change to mobile size
        self.browser.set_window_size(mobile_window_size[0], mobile_window_size[1])
        new_size = self.browser.get_window_size()
        self.assertEqual(new_size.get("width"), mobile_window_size[0])
        self.assertEqual(new_size.get("height"), mobile_window_size[1])

        # change to tablet size
        self.browser.set_window_size(tablet_window_size[0], tablet_window_size[1])
        new_size = self.browser.get_window_size()
        self.assertEqual(new_size.get("width"), tablet_window_size[0])
        self.assertEqual(new_size.get("height"), tablet_window_size[1])

        # change to desktop size
        self.browser.set_window_size(desktop_window_size[0], desktop_window_size[1])
        new_size = self.browser.get_window_size()
        self.assertEqual(new_size.get("width"), desktop_window_size[0])
        self.assertEqual(new_size.get("height"), desktop_window_size[1])

    def test_screenshot_example(self):
        self.accept_cookies()
        search_bar = self.browser.find_element(By.NAME, "q")
        search_bar.send_keys("kittens")
        # take a screenshot of the search bar with text in it
        search_bar.screenshot("./search_bar.png")

        # take a screenshot of the page
        search_bar.send_keys(Keys.ENTER)
        self.browser.save_screenshot("./search_result.png")

        self.assertEqual("kittens - Google Search", self.browser.title)

# Run tests
if __name__ == '__main__':
    unittest.main(verbosity=2)


from PIL import Image
from math import *
from test import get_projected_pics

base_dir = '/Users/dingweiqi/Documents/projected4/'
pics = get_projected_pics(base_dir)
'''
    E +
    W -
    S +
    N -
'''
lat_input = 14
lng_input = 15

for pic in pics:
    '''
        经度小于15度补偿100像素
        经度大于15度补偿-100像素
        经度大于20度补偿-150像素
        经度大于25度补偿-200像素
    '''
    lng = lng_input*2*pi/360
    lat = lat_input*2*pi/360
    x = 2048 * sin(lng)-100
    y = 2048 * sin(lat)
    # print(x)
    # print(y)
    img = Image.open(base_dir + pic)
    # print(img.size)
    line = 2048
    img = img.crop((line+int(x)-400, line-int(y)-400, line+int(x)+400, line-int(y)+400))
    img = img.resize((100, 100))
    img.save('/Users/dingweiqi/Documents/finished5/' + pic)
    lng_input += 0.1


import torch.nn as nn
import copy
import os
import sys
sys.path.append(os.path.dirname(os.path.abspath(os.path.dirname(__file__))))
from subLayer.residualConnectionLayer import ResidualConnectionLayer

class EncoderBlock(nn.Module):
    def __init__(self, self_attention, position_ff, norm, dr_rate = 0):
        super(EncoderBlock, self).__init__()
        self.self_attention = self_attention
        self.residual1 = ResidualConnectionLayer(copy.deepcopy(norm), dr_rate)
        self.residual2 = ResidualConnectionLayer(copy.deepcopy(norm), dr_rate)
        self.position_ff = position_ff

    def forward(self, src, src_mask):
        out = src
        out = self.residual1(out, lambda out: self.self_attention(query=out, key=out, value=out, mask=src_mask))
        out = self.residual2(out, self.position_ff)
        return out


from django.shortcuts import render
from .models import destinasi

#variabel global untuk context
nav = [
            ['/','Home','Kembali ke halaman awal'],
            ['/gallery','360 Gallery','Wisata virtual 360 kebun strawberry Malang Raya'],
            ['/destinations','Destinations','Pilihan destinasi wisata strawberry Malang Raya'],
            ['/edu','Cultivation','Edukasi penanaman strawberry'],
            ['/market','Shop','Jual beli hasil tani dan peralatan'],
            ['/forum','Forum','Forum jual beli'],
        ]

pagename = {
            'web' : 'Strawbeli',
            'page' : 'Destinations',
        }

# Create your views here.

def dest(request):
    tempats = destinasi.objects.all()

    context = {
        'pagename' : pagename,
        'tempats' : tempats,

        'nav' : nav
    }
    return render(request, 'destinations/index.html',context)

def spesifik(request,aidi):
    tempats = destinasi.objects.all()

    context = {
        'pagename' : pagename,
        'tempats' : tempats,
        'nav' : nav,
        'aidi' : aidi,
    }
    return render(request,'destinations/index.html',context)


from Collector import Collector
from Sorter import Sorter
from multiprocessing import Manager
from LogErrors import LogErrors
import traceback
from datetime import datetime

from Storage import Storage

class ProcessRunner:
    def __init__(self, global_storage_namespace: Storage = None):
        self.global_data_storage: Manager = global_storage_namespace
        self.sorter_instance = Sorter()
        self.sorter_instance.assignGlobalStorageNamespace(self.global_data_storage)
        self.collector_instance = Collector(next_process=self.sorter_instance)
        self.collector_instance.assignGlobalStorage(self.global_data_storage)
        self.start_time: str = '13:30'
        self.end_time: str = '15:00'

    def runProcess(self):
        has_run: bool = False
        if self.isTimeCorrect():
            while not has_run:
                self.collector_instance.entireProcess()
                has_run = self.sorter_instance.entireProcess()

    def isTimeCorrect(self):
        is_good_to_go: bool = False
        if self.convertStrTimeToDoubleTime(time=self.timeNowHourMinute()) > 13.5 and\
                self.convertStrTimeToDoubleTime(self.timeNowHourMinute()) < 15.0:
            is_good_to_go = True

        return is_good_to_go

    @staticmethod
    def convertStrTimeToDoubleTime(time: str) -> float:
        try:
            time_slices: list = time.split(sep=':')
            hour: str = time_slices[0]
            minute: str = time_slices[1]
            minute_share: float = int(minute)/60
            return float(hour) + minute_share
        except IndexError:
            error: str = traceback.format_exc()
            LogErrors.logError(error)
        except AttributeError:
            error: str = traceback.format_exc()
            LogErrors.logError(error)
        except ValueError:
            error: str = traceback.format_exc()
            LogErrors.logError(error)

    @staticmethod
    def timeNowHourMinute():
        return datetime.now().strftime("%H:%M")


from django.conf import settings
from django.db import models
from django.utils.translation import gettext_lazy as _
from django_anysign import api as django_anysign

from django_adobesign.client import AdobeSignClient

class SignatureType(django_anysign.SignatureType):

    web_root_url = models.CharField(
        _('AdobeSign web root url (on the shard where your oauth app '
          'is defined)'),
        max_length=255,
        default=settings.ADOBESIGN_WEB_ROOT_URL)

    api_root_url = models.CharField(
        _('AdobeSign region-specific api root url (will be filled from '
          'the API)'),
        max_length=255,
        blank=True)

    application_id = models.CharField(
        _('AdobeSign application id'),
        max_length=100,
        help_text='https://www.adobe.io/apis/documentcloud/sign/docs/overview.'
                  'html',
        default='')

    application_secret = models.CharField(
        _('AdobeSign application secret'),
        max_length=100,
        help_text='https://www.adobe.io/apis/documentcloud/sign/docs/overview.'
                  'html',
        default='')

    access_token = models.CharField(
        _('AdobeSign token'),
        max_length=100,
        help_text='https://www.adobe.io/apis/documentcloud/sign/docs/overview.'
                  'html',
        default='')

    refresh_token = models.CharField(
        _('AdobeSign refresh token'),
        max_length=100,
        help_text='https://www.adobe.io/apis/documentcloud/sign/docs/overview.'
                  'html',
        default='')

    @property
    def signature_backend_options(self):
        return {
            'adobesign_client': AdobeSignClient(self.api_root_url,
                                                self.access_token)
        }

class Signature(django_anysign.SignatureFactory(SignatureType)):
    document = models.FileField(
        _('document'),
        upload_to='signatures',
    )
    document_title = models.CharField(
        _('title'),
        max_length=100,
    )
    state = models.CharField(
        _('AdobeSign state'),
        max_length=100,
        default='DEMO_NOT_YET_SIGN'
    )

    def signature_documents(self):
        """Return list of documents (file wrappers) to sign.

        Part of `django_anysign`'s API implementation.

        """
        # For compliance with other signature backends
        # Will be removed in major version
        self.document.bytes = self.document
        yield self.document

    def __str__(self):
        return self.document_title

class Signer(django_anysign.SignerFactory(Signature)):
    full_name = models.CharField(
        _('full name'),
        max_length=50,
        db_index=True,
    )
    email = models.EmailField(
        _('email'),
        db_index=True,
    )

    current_status = models.CharField(
        _('Internal signer status'),
        max_length=50,
        db_index=True,
        default='NOT_YET_VISIBLE'
    )