#!/bin/env amp_python.sif

import argparse
from classifier import Classifier as ShotDetection
import traceback
from amp.logging import *
import logging
from amp.file_handler import *
import datetime

setup_logging('shot_detection_evaluation', True)
if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("-g", "--ground-truth-file", type=str, required=True, help="Ground Truth file path.")
    parser.add_argument("-m", "--mgm-output-file", type=str, required=True, help="MGM output file path.")
    parser.add_argument("-t", "--threshold", required=True, type=float, help="Threshold value.")
    parser.add_argument("-o", "--output-file-path", type=str, required=True, help="Test output file path.")

    args = parser.parse_args()
    try:
        current = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
        filename =  get_file_name(args.mgm_output_file) + current + ".json"
        output_path = os.path.join(args.output_file_path, 'shot_detection')
        sd = ShotDetection()
        scores, comparisons = sd.evaluate(args.ground_truth_file, args.mgm_output_file, args.threshold)
        headers = sd.get_headers(comparisons)
        data = {
            "scores": scores,
            "headers": headers,
            "comparison": comparisons
        }
        abs_path = create_json_file(output_path, filename, data)
        print("success:" + abs_path)
    except:
        logging.error(traceback.format_exc())
        print(traceback.format_exc())


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

import argparse
import numpy as np
from scipy.io import FortranFile as fortran_file
from scipy.ndimage import laplace as del2
import matplotlib.pyplot as plt

parser = argparse.ArgumentParser()
parser.add_argument("frame", nargs='?', help="fortran data file")
parser.add_argument('--rc', action='store', help='run control file')
parser.add_argument('--Lx', action='store', default=100.0, type=float, help='span in microns, default 100.0')
parser.add_argument('--Ly', action='store', default=100.0, type=float, help='span in microns, default 100.0')
parser.add_argument('--phi-max', action='store', default=70.0, type=float, help='max expected phi,default 70.0')
parser.add_argument('--zeta', action='store', default=-50.0, type=float, help='zeta potential, default -50.0')
parser.add_argument('--zoom', action='store', default=1.0, type=float, help='zoom factor, default 1.0')
parser.add_argument('--nn', action='store', default=5, type=int, help='spacing for quivers, default 5')
parser.add_argument('--drift', action='store_true', help='plot phoresis drift data')
parser.add_argument('--detail', action='store_true', help='plot conductivity and g fields')
parser.add_argument('--show', action='store_true', help='show the plot')
parser.add_argument('--save', action='store_true', help='save the plot')
args = parser.parse_args()

if not args.rc:
    raise Exception('--rc run control file required')

with open(args.rc) as fp:
    run_name = fp.readline().split()[0]
    ions = fp.readline().split()
    nx, ny, ncmp = [int(v) for v in fp.readline().split()[0:3]]
    bc = [int(v) for v in fp.readline().split()[0:8]]
    z = [int(v) for v in fp.readline().split()[0:ncmp]]
    d = [float(v) for v in fp.readline().split()[0:ncmp]]
    fp.readline() ; fp.readline() ; fp.readline()
    init_file = fp.readline().strip()
    fingerprint = fp.readline().strip()

print('run_control: run_name = ', run_name)
print('run_control: ions = ', ions)
print('run_control: nx, ny, ncmp = ', nx, ny, ncmp)
print('run_control: boundary_conditions = ', bc)
print('run_control: z = ', z)
print('run_control: d = ', d)
print('run_control: init_file = ', init_file)
print('run_control: fingerprint = ', fingerprint)

deltax = args.Lx / (nx - 1)
print('deltax = ', deltax)

data_file = args.frame if args.frame else init_file

print('reading data from', data_file)

with fortran_file(data_file) as f:
    r = f.read_reals()

rr = r.reshape((ncmp+5, nx*ny))

rho = np.zeros((ncmp, nx, ny))

for k in range(ncmp):
    rho[k, :, :] = rr[k, :].reshape((nx, ny)).transpose().copy()

phi = rr[ncmp, :].reshape((nx, ny)).transpose().copy()
fix = rr[ncmp+1, :].reshape((nx, ny)).transpose().copy()
fiy = rr[ncmp+2, :].reshape((nx, ny)).transpose().copy()
div = rr[ncmp+3, :].reshape((nx, ny)).transpose().copy()
curl = rr[ncmp+4, :].reshape((nx, ny)).transpose().copy()

g = np.zeros((nx, ny))
for k in range(ncmp): g += z[k] * d[k] * rho[k, :, :]

sigma = np.zeros((nx, ny))
for k in range(ncmp): sigma += z[k]**2 * d[k] * rho[k, :, :]

rhotot = np.zeros((nx, ny))
for k in range(ncmp): rhotot += 0.25*rho[k, :, :]

rhox = 0.5*(rho[0, :, :] + rho[1, :, :])
rhoy = 0.5*(rho[2, :, :] + rho[3, :, :])

if fingerprint:
    with open(fingerprint) as fp:
        i0, j0, j1 = [int(v) for v in fp.readline().split()]
    print('fingerprint:', fingerprint)
    print('fingerprint:', i0, j0, j1)
    print('fingerprint: sigma = ', sigma[i0, j0:j1+1])
    print('fingerprint:     g = ', g[i0, j0:j1+1])
    print('fingerprint:   phi = ', phi[i0, j0:j1+1])

gy, gx = np.gradient(g/deltax)
ey, ex = np.gradient(-phi/deltax)

ix, iy = [np.multiply(sigma, e) - gradg for e, gradg in zip([ex, ey], [gx, gy])]
ixy, ixx = np.gradient(ix/deltax)
iyy, iyx = np.gradient(iy/deltax)

lnsigmay, lnsigmax = np.gradient(np.log(sigma)/deltax)
approx_curl = np.multiply(lnsigmax, gy) - np.multiply(lnsigmay, gx)

sumrhoz = 0.0
for k in range(ncmp): sumrhoz += z[k] * np.sum(rho[k, :, :])

print('diagnostic: (fortran)     |I| =', np.sqrt(np.sum(fix**2 + fiy**2))/deltax)
print('diagnostic: (python)      |I| =', np.sqrt(np.sum(ix**2 + iy**2)))
print('diagnostic: (fortran)   |∇·I| =', np.sqrt(np.sum(div**2))/deltax**2)
print('diagnostic: (python)    |∇·I| =', np.sqrt(np.sum((ixx + iyy)**2)))
print('diagnostic: (fortran) |∇ ⨯ I| =', np.sqrt(np.sum(curl**2))/deltax**2)
print('diagnostic: (python)  |∇ ⨯ I| =', np.sqrt(np.sum((iyx - ixy)**2)))
print('diagnostic: (estd)    |∇ ⨯ I| =', np.sqrt(np.sum(approx_curl**2)))
print('diagnostic: (python) Σi zi ρi =', sumrhoz)

Lx, Ly = nx - 1.0, ny - 1.0

x = np.linspace(0.0, Lx, nx)
y = np.linspace(0.0, Ly, ny)

phi -= np.min(phi)

kB, T, e = 1.38e-23, 298.0, 1.602e-19
epsr, eps0, eta = 78.0, 8.854e-12, 0.89e-3
kTbye = kB*T/e
prefac = epsr*eps0/eta * kTbye**2 * 1e9 # in um^2 / ms
ezetabykT = args.zeta*1e-3 / kTbye # recall that zeta in mV

A = 4.0*prefac*np.log(np.cosh(0.25*ezetabykT))
B = prefac*ezetabykT

print('kTbye [mV] = %0.2f' % (kTbye*1e3))
print('prefac [um^2 / ms] = %0.3f' % prefac)
print('drift coefficients A, B [um^2/ms] = ', A, B)

# np.gradient returns a list, which is stacked in reverse order

grad_g = np.stack(np.gradient(g)[::-1])
E = np.stack(np.gradient(-phi)[::-1])
grad_ln_rho = np.stack(np.gradient(np.log(rhotot))[::-1])
double_sigma = np.stack([sigma, sigma]) # double up for vector operations

I = double_sigma * E - grad_g

a = A * grad_ln_rho
b = B * grad_g / double_sigma
c = B * I / double_sigma
u = a + b + c

c_mod = np.sqrt(c[0, :, :]**2 + c[1, :, :]**2)
u_mod = np.sqrt(u[0, :, :]**2 + u[1, :, :]**2)

cbyu = c_mod / u_mod
cbyumin, cbyumax = np.min(cbyu), np.max(cbyu)
print('minmax: |c|/|u| = ', cbyumin, cbyumax)

phi *= kTbye * 1e3 # mV

spc = del2(phi) # space charge (a.u)

phimin, phimax = np.min(phi), np.max(phi)
print('minmax: phi = ', phimin, phimax)
phi_levels = list(np.linspace(0.0, args.phi_max, 10))
print('phi levels', phi_levels)

curl *= 1e3 # rescale

curlmin, curlmax = np.min(curl), np.max(curl)
print('minmax: curl = ', curlmin, curlmax)
curl_levels = list(np.linspace(-5.0, 5.0, 7))

rmin, rmax = np.min(rhotot), np.max(rhotot)
print('minmax: rhotot = ', rmin, rmax)
r_levels = list(np.linspace(0.0, 1.0, 11))

sigmin, sigmax = np.min(sigma), np.max(sigma)
print('minmax: conductivity = ', sigmin, sigmax)
sig_levels = list(np.linspace(0.0, 16.0, 16))
print('sigma levels', sig_levels)

gmin, gmax = np.min(g), np.max(g)
print('minmax: g = ', gmin, gmax)
g_levels = list(np.linspace(-2.0, 0.0, 16))
print('g levels', g_levels)

spcmin, spcmax = np.min(spc), np.max(spc)
print('minmax: space charge = ', spcmin, spcmax)
spclim = max([-spcmin, spcmax])
#sig_levels = list(np.linspace(0.0, 16.0, 16))
#print('sigma levels', sig_levels)

for k in range(ncmp):
    rhomin, rhomax = np.min(rho[k, :, :]), np.max(rho[k, :, :])
    print('minmax: rho', ions[k], '=', rhomin, rhomax)

rho_levels = list(np.linspace(0.0, 1.0, 11))
print('rho levels', rho_levels)

if not args.show and not args.save: exit()

if args.drift or args.detail:

    plt.subplot(2, 3, 1)
    plt.contour(x, y, phi, phi_levels, colors='black')
    plt.imshow(spc, extent=[0.0, Lx, 0.0, Ly], origin='lower', cmap='RdBu',
               vmin=-spclim, vmax=spclim, alpha=0.5)
    if args.zoom > 1.0:
        zf = 1.0 / args.zoom
        plt.axis([0.5*(1-zf)*Lx, 0.5*(1+zf)*Lx, 0.5*(1-zf)*Lx, 0.5*(1+zf)*Lx])
    plt.title('φ and ∇²φ')

    plt.subplot(2, 3, 2)
    streamlines = plt.streamplot(x, y, ix, iy, color='black')
    plt.imshow(curl, extent=[0.0, Lx, 0.0, Ly], origin='lower', cmap='cool',
               vmin=curl_levels[0], vmax=curl_levels[-1], alpha=0.5)
    # plt.colorbar()
    if args.zoom > 1.0:
        zf = 1.0 / args.zoom
        plt.axis([0.5*(1-zf)*Lx, 0.5*(1+zf)*Lx, 0.5*(1-zf)*Lx, 0.5*(1+zf)*Lx])
    plt.title('I and ∇×I')

    if args.detail:
        plt.subplot(2, 3, 3)
        # plt.contour(x, y, rhox, r_levels, colors='black')
        print('r_levels =', r_levels)
        plt.imshow(rhox, extent=[0.0, Lx, 0.0, Ly], origin='lower', cmap='viridis',
                   vmin=r_levels[0], vmax=r_levels[-1], alpha=0.5)
        if args.zoom > 1.0:
            zf = 1.0 / args.zoom
            plt.axis([0.5*(1-zf)*Lx, 0.5*(1+zf)*Lx, 0.5*(1-zf)*Lx, 0.5*(1+zf)*Lx])
        plt.plot(x, 20+20*rhox[100, :], 'k')
        plt.title(' : '.join(ions[0:2]))
    else:
        plt.subplot(2, 3, 3)
        #plt.contour(x, y, rhotot, r_levels, colors='black')
        plt.imshow(rhotot, extent=[0.0, Lx, 0.0, Ly], origin='lower', cmap='viridis',
                   vmin=r_levels[0], vmax=r_levels[-1], alpha=0.5)
        plt.title('ρ_tot')

    plt.subplot(2, 3, 4)
    plt.contour(x, y, sigma, sig_levels, colors='black')
    plt.imshow(sigma, extent=[0.0, Lx, 0.0, Ly], origin='lower', cmap='viridis',
               vmin=sig_levels[0], vmax=sig_levels[-1], alpha=0.5)
    if args.zoom > 1.0:
        zf = 1.0 / args.zoom
        plt.axis([0.5*(1-zf)*Lx, 0.5*(1+zf)*Lx, 0.5*(1-zf)*Lx, 0.5*(1+zf)*Lx])
    plt.title('σ (conductivity)')

    if args.detail:
        plt.subplot(2, 3, 5)
        plt.contour(x, y, g, g_levels, colors='black')
        plt.imshow(g, extent=[0.0, Lx, 0.0, Ly], origin='lower', cmap='viridis',
                   vmin=g_levels[0], vmax=g_levels[-1], alpha=0.5)
        if args.zoom > 1.0:
            zf = 1.0 / args.zoom
            plt.axis([0.5*(1-zf)*Lx, 0.5*(1+zf)*Lx, 0.5*(1-zf)*Lx, 0.5*(1+zf)*Lx])
        plt.title('g field')
    else:
        plt.subplot(2, 3, 5)
        quivers1 = plt.quiver(x[::4], y[::4], a[0, ::4, ::4], a[1, ::4, ::4], angles='xy', scale_units='xy', scale=0.001, color='red')
        quivers2 = plt.quiver(x[::4], y[::4], b[0, ::4, ::4], b[1, ::4, ::4], angles='xy', scale_units='xy', scale=0.001, color='blue')
        quivers3 = plt.quiver(x[::4], y[::4], c[0, ::4, ::4], c[1, ::4, ::4], angles='xy', scale_units='xy', scale=0.001, color='yellow')
        quivers4 = plt.quiver(x[::4], y[::4], u[0, ::4, ::4], u[1, ::4, ::4], angles='xy', scale_units='xy', scale=0.001, color='black')
        plt.imshow(100*c_mod/u_mod, extent=[0.0, Lx, 0.0, Ly], origin='lower', cmap='cool',
                   vmin=0.0, vmax=30.0, alpha=0.5)
        plt.title('non local fraction')

    if args.detail:
        plt.subplot(2, 3, 6)
        #plt.contour(x, y, rhoy, r_levels, colors='black')
        plt.imshow(rhoy, extent=[0.0, Lx, 0.0, Ly], origin='lower', cmap='viridis',
                   vmin=r_levels[0], vmax=r_levels[-1], alpha=0.5)
        if args.zoom > 1.0:
            zf = 1.0 / args.zoom
            plt.axis([0.5*(1-zf)*Lx, 0.5*(1+zf)*Lx, 0.5*(1-zf)*Lx, 0.5*(1+zf)*Lx])
        plt.plot(x, 20+20*rhoy[100, :], 'k')
        plt.title(' : '.join(ions[2:4]))
    else:
        plt.subplot(2, 3, 6)
        quivers = plt.quiver(x[::2], y[::2], ex[::2, ::2], ey[::2, ::2])
        plt.contour(x, y, phi, phi_levels, colors='black')
        plt.imshow(phi, extent=[0.0, Lx, 0.0, Ly], origin='lower', cmap='plasma',
                   vmin=phi_levels[0], vmax=phi_levels[-1], alpha=0.5)
        plt.title('φ and −∇φ')

else: # not args.drift or args.detail

    plt.subplot(2, 3, 1)
    quivers = plt.quiver(x[::2], y[::2], ex[::2, ::2], ey[::2, ::2])
    plt.contour(x, y, phi, phi_levels, colors='black')
    plt.imshow(phi, extent=[0.0, Lx, 0.0, Ly], origin='lower', cmap='plasma',
               vmin=phi_levels[0], vmax=phi_levels[-1], alpha=0.5)
    # plt.colorbar()
    plt.title('phi and E')

    plt.subplot(2, 3, 4)
    streamlines = plt.streamplot(x, y, ix, iy, color='black')
    plt.imshow(curl, extent=[0.0, Lx, 0.0, Ly], origin='lower', cmap='cool',
               vmin=curl_levels[0], vmax=curl_levels[-1], alpha=0.5)
    # plt.colorbar()
    plt.title('I and curl I')

    for k in range(ncmp):
        trho = rho[k, :, :].copy()
        plt.subplot(2, 3, 2+k if k < 2 else 3+k)
        plt.contour(x, y, trho, rho_levels, colors='black')
        plt.imshow(trho, extent=[0.0, Lx, 0.0, Ly], origin='lower',
                   cmap='Blues', vmin=rho_levels[0], vmax=rho_levels[-1], alpha=0.5)
        plt.title(ions[k])

    if ncmp == 2:

        beta = np.sum(d*np.sign(z)) / np.sum(d*np.abs(z))
        print('binary: beta = %0.3f' % beta)

        rhos = - rho[0, :, :] / z[1]
        phiplus = phi + beta * np.log(rhos) * kTbye * 1e3 # mV

        plt.subplot(2, 3, 5)
        plt.contour(x, y, rhos, rho_levels, colors='black')
        plt.imshow(rhos, extent=[0.0, Lx, 0.0, Ly], origin='lower', cmap='Blues',
                   vmin=rho_levels[0], vmax=rho_levels[-1], alpha=0.5)
        plt.title('rho_s')

        plt.subplot(2, 3, 6)
        plt.contour(x, y, phiplus, phi_levels, colors='black')
        plt.imshow(phiplus, extent=[0.0, Lx, 0.0, Ly], origin='lower', cmap='plasma',
                   vmin=phi_levels[0], vmax=phi_levels[-1], alpha=0.5)
        plt.title('phi + beta ln rho_s')

if args.show:
    plt.show()

if args.save:
    png_file = data_file + '.png'
    plt.savefig(png_file)
    print('written', png_file)


from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from ..models import Movie, Director
from ..serializers import MovieSerializer

@api_view(['GET'])
def get_all(request):
    if request.method == 'GET':
        movies = Movie.objects.all()
        serializer = MovieSerializer(movies, many=True)

        return Response(serializer.data)

@api_view(['GET'])
def get(request, **kwargs):
    if request.method == 'GET':
        try:
            movie = Movie.objects.get(id=kwargs['id'])
            serializer = MovieSerializer(movie)

            return Response(serializer.data)
        except:
            data = {
                'status': 'error',
                'message': 'Movie doesn\'t exist...'
            }

            return Response(data, status=status.HTTP_404_NOT_FOUND)

@api_view(['POST'])
def create(request):
    if request.method == 'POST':
        movie = request.data
        try:
            checkMovie = Movie.objects.filter(title=movie['title']).exists()

            if not checkMovie:
                getDirector = Director.objects.get(id=movie['director'])

                newMovie = Movie.objects.create(
                    title=movie['title'],
                    director=getDirector,
                    release_date=movie['release_date']
                )

                # Add genre/s to newly created movie
                for genre in movie['genre']:
                    newMovie.genre.add(genre)

                movieSerialize = MovieSerializer(newMovie)
                data = {
                    'status': 'success',
                    'message': 'New movie added!',
                    'movie': movieSerialize.data
                }

                return Response(data)
            else:
                data = {
                    'status': 'error',
                    'message': 'Movie already in the database.'
                }

                return Response(data, status=status.HTTP_409_CONFLICT)

        except:
            data = {
                'status': 'error',
                'message': 'Movie not created.'
            }

            return Response(data, status=status.HTTP_400_BAD_REQUEST)

@api_view(['DELETE'])
def delete(request, **kwargs):
    if request.method == 'DELETE':
        try:
            Movie.objects.get(id=kwargs['id']).delete()

            data = {
                'status': 'success',
                'message': 'Movie successfully deleted!'
            }

            return Response(data)
        except:
            data = {
                'status': 'error',
                'message': 'Failed to delete movie.'
            }

            return Response(data, status=status.HTTP_400_BAD_REQUEST)

@api_view(['PUT'])
def update(request, **kwargs):
    if request.method == 'PUT':
        try:
            updateData = request.data
            movie = Movie.objects.get(id=kwargs['id'])
            for key, value in updateData.items():
                # For foreign keys(director & genre) I could create a different function.
                if key == 'director':
                    getDirector = Director.objects.get(id=value)
                    movie.director = getDirector
                elif key == 'genre':
                    movie.genre.set(value)
                elif value:
                    setattr(movie, key, value)
                else:
                    raise

            movie.save()
            serializeMovie = MovieSerializer(movie)
            data = {
                'status': 'success',
                'message': 'Movie successfully updated',
                'movie': serializeMovie.data
            }

            return Response(data)
        except:
            data = {
                'status': 'error',
                'message': 'Movie update failed'
            }

        return Response(data, status=status.HTTP_400_BAD_REQUEST)


import importlib
import inspect
import logging
import os

import pippy
import torch
import torch.distributed.rpc as rpc

pippy_installed = importlib.util.find_spec("pippy") is not None

if pippy_installed:
    from pippy import split_into_equal_size
    from pippy.hf import PiPPyHFTracer, inject_pipeline_forward

logger = logging.getLogger(__name__)

def initialize_rpc_workers(local_rank, world_size, ctx):
    # Get RPC configuration options from model YAML config
    rpc_timeout = ctx.model_yaml_config["pippy"]["rpc_timeout"]
    num_worker_threads = ctx.model_yaml_config["pippy"]["num_worker_threads"]
    options = rpc.TensorPipeRpcBackendOptions(
        num_worker_threads=num_worker_threads, rpc_timeout=rpc_timeout
    )

    # Set up device mapping for RPC workers
    n_devs = torch.cuda.device_count()
    dev_id = local_rank % n_devs
    for i in range(world_size):
        options.set_device_map(f"worker{i}", {dev_id: i % n_devs})

    # Initialize RPC worker
    logger.info(f"rank = {local_rank} pid/device = " f"{os.getpid()}/{dev_id}")
    rpc.init_rpc(
        f"worker{local_rank}",
        rank=local_rank,
        world_size=world_size,
        rpc_backend_options=options,
    )

def get_pipeline_driver(model, world_size, ctx):
    """Returns a pipeline driver for the given model.
    Args:
        model (torch.nn.Module): The model to pipeline.
        world_size (int): The number of pipeline stages.
        ctx (Context): The context containing configuration information.
    Returns:
        torch.nn.Sequential: The pipeline driver for the model.
    """
    # Extract configuration parameters from the context

    # Check that the "pippy" and "handler" keys are present in the YAML config
    assert "pippy" in ctx.model_yaml_config, "Missing 'pippy' key in YAML config"
    assert "handler" in ctx.model_yaml_config, "Missing 'handler' key in YAML config"

    # Check that the required keys are present in the "pippy" section

    assert (
        "input_names" in ctx.model_yaml_config["pippy"]
    ), "Missing 'input_names' key in YAML config"
    assert (
        "model_type" in ctx.model_yaml_config["pippy"]
    ), "Missing 'model_type' key in YAML config"

    # Check that the required keys are present in the "handler" section
    assert (
        "model_path" in ctx.model_yaml_config["handler"]
    ), "Missing 'model_path' key in YAML config"

    # Set variables from the config

    input_names = ctx.model_yaml_config["pippy"]["input_names"]
    model_type = ctx.model_yaml_config["pippy"]["model_type"]
    model_path = ctx.model_yaml_config["handler"]["model_path"]
    try:
        chunks = ctx.model_yaml_config["pippy"]["chunks"]
    except KeyError:
        chunks = 1
    try:
        index_filename = ctx.model_yaml_config["handler"]["index_filename"]
    except KeyError:
        index_filename = None

    # Check that the index file exists
    if index_filename is not None:
        index_file_path = os.path.join(model_path, index_filename)
        assert os.path.exists(
            index_file_path
        ), f"Index file '{index_file_path}' not found"
    else:
        index_file_path = None

    checkpoint_prefix = None
    # Set the model to evaluation mode
    model.eval()

    # Extract the concrete arguments for the model's forward method
    sig = inspect.signature(model.forward)
    concrete_args = {
        p.name: p.default for p in sig.parameters.values() if p.name not in input_names
    }

    logger.info("Initializing the model pipeline")

    # Create a tracer if necessary
    tracer = PiPPyHFTracer() if model_type == "HF" else None

    # Add deprecated_arguments to concrete_args if necessary
    if model_type == "HF" and "bloom" in str(model.__class__):
        concrete_args.setdefault("deprecated_arguments", {})

    # Compile the pipeline using PiPPy
    split_policy = split_into_equal_size(world_size)
    pipe_driver, stage_mode = pippy.all_compile(
        model,
        num_ranks=world_size,
        num_chunks=chunks,
        schedule="FillDrain",
        split_policy=split_policy,
        tracer=tracer,
        concrete_args=concrete_args,
        index_filename=index_file_path,
        checkpoint_prefix=checkpoint_prefix,
    )

    # Inject the pipeline forward method if necessary
    if model_type == "HF":
        inject_pipeline_forward(model, pipe_driver)
        return model
    else:
        return pipe_driver


from sys import argv

try:

    entrada = open(argv[1], "r")

    cadena = argv[2]

    lineas = entrada.readlines()
    palabras = []

    for i in range(len(lineas)):
        palabras.append([])

    for i in range(len(lineas)):
        linea = lineas[i].split()
        for j in linea:
            palabras[i].append(j)

    for i in range(len(palabras)):
        for j in palabras[i]:
            if j == cadena:
                print("{}: {}".format(i+1, lineas[i][:-1]))
                break

    entrada.close()
except:
    print("ERROR")


from sys import argv
import argparse
from datetime import datetime
from dep import *
import configparser
from common import *
import traceback
import os

# Go to directory of source

baseCodeDir = sys.argv[0].replace('dep_go.py', '')
if (baseCodeDir != ""): os.chdir(baseCodeDir)

# Define Input parameters

parser = argparse.ArgumentParser(description='DEP input parameters')
parser.add_argument('instr'         , type=str,                             help='Instrument name')
parser.add_argument('utDate'        , type=str, nargs='?', default=None,    help='UTC Date (yyyy-mm-dd) to search for FITS files in prior 24 hours. Default is current date.')
parser.add_argument('tpx'           , type=int, nargs='?', default=0,       help='Update TPX database?  [0, 1].  Default is 0.')
parser.add_argument('procStart'     , type=str, nargs='?', default=None,    help='(OPTIONAL) Name of process to start at. ["obtain", "locate", "add", "dqa", "lev1", "tar", "koaxfr"]. Default is "obtain".')
parser.add_argument('procStop'      , type=str, nargs='?', default=None,    help='(OPTIONAL) Name of process to stop at. ["obtain", "locate", "add", "dqa", "lev1", "tar", "koaxfr"]. Default is "koaxfr".')
parser.add_argument('--searchDir'   , type=str, nargs='?', const=None,      help='(OPTIONAL) Directory to search (recursively) for FITS files.  Default search dirs are defined in instrument class files.')
parser.add_argument('--reprocess'   , type=str, nargs='?', const=None,      help='(OPTIONAL) Set to "1" to indicate reprocessing old data (skips certain locate/search checks)')
parser.add_argument('--modtimeOverride' , type=str, nargs='?', const=None,  help='(OPTIONAL) Set to "1" to ignore modtime on files during FITS locate search.')
parser.add_argument('--metaCompareDir'  , type=str, nargs='?', const=None,  help='(OPTIONAL) Directory to use for special metadata compare report for reprocessing old data.')
parser.add_argument('--useHdrProg'  , type=str, nargs='?', const=None,      help='(OPTIONAL) Set to "force" to force header val if different.  Set to "assist" to use only if indeterminate (useful for processing old data).')
parser.add_argument('--splitTime'   , type=str, nargs='?', const=None,      help='(OPTIONAL) HH:mm of suntimes midpoint for overriding split night timing.')
parser.add_argument('--emailReport' , type=str, nargs='?', default="0",       help='(OPTIONAL) Set to "1" to send email report whether or not it is a full run')
parser.add_argument('--assignProgname' , type=str, nargs='?', default='',    help='(OPTIONAL) Force assign all data to provided progname (ie U190 or 2020A_U190). Can use split time str like "U205,10:21:00,C251"')

# Get input params

args = parser.parse_args()
instr  = args.instr.upper()
utDate = args.utDate
tpx    = args.tpx
pstart = args.procStart
pstop  = args.procStop
emailReport = args.emailReport
assignProgname = args.assignProgname

# Get Config args

configArgs = []
if args.searchDir      : configArgs.append({'section':'LOCATE', 'key':'SEARCH_DIR',         'val': args.searchDir})
if args.modtimeOverride: configArgs.append({'section':'LOCATE', 'key':'MODTIME_OVERRIDE',   'val': args.modtimeOverride})
if args.reprocess      : configArgs.append({'section':'MISC',   'key':'REPROCESS',          'val': args.reprocess})
if args.metaCompareDir : configArgs.append({'section':'MISC',   'key':'META_COMPARE_DIR',   'val': args.metaCompareDir})
if args.useHdrProg     : configArgs.append({'section':'MISC',   'key':'USE_HDR_PROG',       'val': args.useHdrProg})
if args.splitTime      : configArgs.append({'section':'MISC',   'key':'SPLIT_TIME',         'val': args.splitTime})
configArgs.append({'section':'MISC',   'key':'EMAIL_REPORT',       'val': args.emailReport})
configArgs.append({'section':'MISC',   'key':'ASSIGN_PROGNAME',    'val': args.assignProgname})

# Use the current UT date if none provided
if (utDate == None): utDate = datetime.utcnow().strftime('%Y-%m-%d')

# Create and run Dep (wrap in try to catch any runtime errors and email them)

try:
    dep = Dep(instr, utDate, tpx=tpx, configArgs=configArgs)
    dep.go(pstart, pstop)
except Exception as error:
    msg = traceback.format_exc()
    do_fatal_error(msg, instr, utDate, 'dep_go')


import requests
import authenticate

token = authenticate.authenticate(username='Test1')

if token:
    user_id = input('user id: ')
    # Intialize a basic endpoint
    # endpoint = f"http://localhost:8000/api/users/{user_id}/"
    endpoint = f"http://localhost:8000/api/products/{user_id}/"

    response = requests.patch(endpoint, headers={
                'Authorization': f'Bearer {token}'
                },
                data={'name': 'Test product 1 edit 1'})
    # response = requests.put(endpoint, data={...})

    print(response.text)


import torch
import torch.nn as nn
import numpy as np
import config
from torch.autograd import Variable
import torch.nn.functional as F

class Gate_combine_three(nn.Module):
    def __init__(self,hidden,mid,dropout):
        super(Gate_combine_three,self).__init__()
        self.opt=config.parse_opt()
        self.f_proj=nn.Linear(hidden,mid)
        self.a_proj=nn.Linear(hidden,mid)
        self.f_att=nn.Linear(mid,1)
        self.a_att=nn.Linear(mid,1)
        self.sig=nn.Sigmoid()
        self.dropout=nn.Dropout(dropout)

    def forward(self,f,a,q):

        f_proj=self.f_proj(f+q)
        f_proj=self.dropout(f_proj)
        f_g = self.sig(self.f_att(f_proj))

        a_proj=self.a_proj(a+q)
        a_proj=self.dropout(a_proj)
        a_g = self.sig(self.a_att(a_proj))

        fa_comb=f_g*f+a_g*a+q

        return fa_comb

class Full_RNN(nn.Module):
    def __init__(self,in_dim,num_hidden,num_layer,bidirect,dropout,rnn_type='LSTM'):
        super(Full_RNN,self).__init__()
        rnn_cls=nn.LSTM if rnn_type=='LSTM' else nn.GRU
        self.rnn=rnn_cls(in_dim,num_hidden,num_layer,bidirectional=bidirect,dropout=dropout,batch_first=True)
        self.in_dim=in_dim
        self.num_hidden=num_hidden
        self.num_layer=num_layer
        self.rnn_type=rnn_type
        self.num_bidirect=1+int(bidirect)

    def init_hidden(self,batch):
        weight=next(self.parameters()).data
        hid_shape=(self.num_layer * self.num_bidirect,batch,self.num_hidden)
        if self.rnn_type =='LSTM':
            return (Variable(weight.new(*hid_shape).zero_().cuda()),
                    Variable(weight.new(*hid_shape).zero_().cuda()))
        else:
            return Variable(weight.new(*hid_shape).zero_()).cuda()

    def forward(self,x):
        batch=x.size(0)
        hidden=self.init_hidden(batch)
        self.rnn.flatten_parameters()
        output,hidden=self.rnn(x,hidden)
        hidden=hidden[0].squeeze()
        return output,hidden

class CNN_Model(nn.Module):
    def __init__(self,in_dim,num_hidden,opt):
        super(CNN_Model,self).__init__()
        self.in_dim=in_dim
        self.num_hidden=num_hidden
        self.dropout=opt.CNN_DROPOUT
        filter_sizes=[int(fsz) for fsz in opt.FILTER_SIZE.split(',')]
        self.conv=nn.ModuleList([nn.Conv2d(1,opt.NUM_FILTER,(fsz,in_dim)) for fsz in filter_sizes])

    def forward(self,emb):
        emb=emb.unsqueeze(1)
        conv_result=[F.relu(conv(emb)) for conv in self.conv]
        mid=[torch.squeeze(x_i).transpose(1,2).contiguous() for x_i in conv_result]
        return mid


# 绘制横着的条形图
from matplotlib import pyplot as plt
import matplotlib

font = {'family': 'MicroSoft YaHei'}
matplotlib.rc("font", **font)
a = ["战狼2", "速度与激情8", "功夫瑜伽"]
b = [56.01, 26.94, 17.53]

# 设置图形大小
plt.figure(figsize=(12, 8), dpi=80)

plt.barh(range(len(a)), b, height=0.1, color="orange")

plt.yticks(range(len(a)), a)

plt.grid(alpha=0.4)

plt.show()

# =========================================================


#!/usr/bin python3 -tt
# Character_encoding: UTF-8
# -------------------------------------------------------------
# Author: Dalwar Hossain (dalwar014@gmail.com)
# Python Interpreter: >= 3.4
# mySQL Database Version: 5.6.28
# mysql Connector Version: 2.1.5
# -------------------------------------------------------------
# Import Built-in Libraries
import os
import gc
# Import custom library functions
import primaryTableCleaner
import fileOperations
import tableOperations
# Define a function to execute import query
def executeImportQuery(connection,inputDirectory,inputFile):
	# Prepare a cursor object using cursor() method
	cursor = connection.cursor()
	# Create MYSQL database query string according to file name
	dbQuery = createImportQuery(inputDirectory,inputFile)
	# Execute SQL query using execute() method
	try:
		cursor.execute(dbQuery)
		print("[ {} ] file imported successfully".format(inputFile), end='\n')
	except ValueError as e:
		print("Import Error! [ {} ] - [{}]".format(inputFile, e), end='\n')
	# Commit data to DATABASE
	connection.commit()
	# Close Cursor
	cursor.close();
# Define a function to create SQL query
def createImportQuery(inputDirectory,inputFile):
	tableName = 't_delegation_p1'
	querySegment_1 = "LOAD DATA LOCAL INFILE '"
	querySegment_2 = inputDirectory + inputFile + "'"
	querySegment_3 = " INTO TABLE " + tableName
	querySegment_4 = """ FIELDS TERMINATED BY '|' """ # OPTIONALLY ENCLOSED BY '"' ESCAPED BY '"' LINES TERMINATED BY '\\n' """
	# Now complete query by joining all the segments togather
	completeImportQuery = querySegment_1 + querySegment_2 + querySegment_3 + querySegment_4 #+ querySegment_5 + querySegment_6
	# return complete query
	return completeImportQuery
# Create a function that will insert the data to the database
def csvImport(dbConnection):
	# Create empty list that will store csv file names, and logs
	csvList = []
	csvLog = []
	inputDirectory = fileOperations.csvFileLocation
	for f in os.listdir(inputDirectory):
		if f.endswith('.csv'):
			csvList.append(f)
	# check and match csv files for new files
	inputFileList = fileOperations.csvCheck()
	if inputFileList:
		# Create list of tables for data transfer
		srcNdstList = [['v_historical', 't_historical_s1'],['t_delegation_p2', 't_delegation_s1'],['v_delegation_2', 't_current_delegation_s1']]
		cSrcNdstList = [['v_delegation_2', 't_current_delegation_s1']]
		table2Update = 't_delegation_p2'
		# Create query count
		currentQueryCount = 1
		totalQueryCount = len(inputFileList)
		print("\nImporting CSV files to DB.....\n", end='\n')
		# Call a function that will import CSV to database
		for fileName in inputFileList:
			# Clean the Primary Tables to insert data
			primaryTableCleaner.truncate(dbConnection, flag=1)
			# Print executing query message
			print("\n[ {} of {} ] -> ".format(currentQueryCount,totalQueryCount), end='')
			# Import csv file to primary table
			executeImportQuery(dbConnection, inputDirectory, fileName)
			# Transfer data from view to table
			if(fileName.endswith('01.csv')):
				# Transfer data to a second table and update it
				tableOperations.executeUpdate(table2Update)
				for item in srcNdstList:
					tableOperations.transferData(item)
			else:
				for item in cSrcNdstList:
					tableOperations.transferData(item)
			# Clean the Primary Tables to insert data
			primaryTableCleaner.truncate(dbConnection, flag=0)
			csvLog.append(fileName)
			currentQueryCount += 1
		# write the log file
		print("Writing csv log...", end = '\n')
		fileOperations.csvLogging(csvLog)
		gc.collect()
# -------------------------------------------------------------
# This is a standard boilerplate that calls the main() function
if __name__ == '__main__':
	main()


# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.utils import timezone
from django.db import models

MEASURE_CHOICES = (
    (1, 'ºC'),
    (2, 'ºF'),
    (3, 'K')

)

class AllowedAddress(models.Model):
    ip = models.CharField(
        verbose_name="IP",
        max_length=15,
        unique=True)
    is_active = models.BooleanField(verbose_name='Is active?', default=False)
    measure = models.IntegerField(
        verbose_name="Measure", choices=MEASURE_CHOICES, default=1)
    max_temperature = models.FloatField(
        verbose_name='Maximum temperature allowed', default=20.0)
    min_temperature = models.FloatField(
        verbose_name='Minimum temperature allowed', default=18.0)
    days_to_delete = models.IntegerField(
        verbose_name='Days to delete', default=30)
    local = models.CharField(
        verbose_name="Local", max_length=150, unique=True, default='')
    device_name = models.CharField(
        verbose_name='Device Name', max_length=20, default='')

    class Meta:
        verbose_name = (u'Allowed Address')
        verbose_name_plural = (u"Allowed Addresses")

    def __str__(self):
        string = self._meta.get_field("ip").verbose_name.title() \
            + ":" + self.ip + ", "
        string = string + self._meta.get_field("local").verbose_name.title() \
            + ":" + self.local

        return string

class ThermoInfo(models.Model):
    temperature = models.FloatField(verbose_name="Temperature")
    device_ip = models.ForeignKey(
        AllowedAddress,
        verbose_name=u"Device",
        related_name="thermo_info")
    capture_date = models.DateTimeField(
        verbose_name="Capture Date", default=timezone.now)
    allowed_temp = models.BooleanField(
        verbose_name='Allowed Temperature ?', default=True)

    class Meta:
        verbose_name = (u'Thermo Info')
        verbose_name_plural = (u"Thermo Info's")

    def __str__(self):
        string = self._meta.get_field("capture_date").verbose_name.title()
        string = string + ":" + str(self.capture_date)
        string = string + "," + \
            self._meta.get_field("temperature").verbose_name.title()
        string = string + ":" + str(self.temperature)
        string = string + "," + \
            self._meta.get_field("device_ip").verbose_name.title()
        string = string + ":" + str(self.device_ip)
        return string

class ThermoLog(models.Model):
    request = models.TextField(verbose_name="Request")
    log = models.TextField(verbose_name='LOG')
    device_ip = models.CharField(
        verbose_name="Device IP", max_length=15)
    capture_date = models.DateTimeField(
        verbose_name="Capture Date", default=timezone.now)
    all_worked = models.BooleanField(
        verbose_name='All worked ?', default=False)

    class Meta:
        verbose_name = (u'Thermo Log')
        verbose_name_plural = (u"Thermo Logs")

class DeviceStatus(models.Model):
    check_offline = models.BooleanField(verbose_name="Check Offline", default=False)
    last_connection = models.BooleanField(verbose_name="Last Connection", default=False)
    previous_last_connection = models.BooleanField(verbose_name="Previous Last Connection", default=False)
    check_date = models.DateTimeField(
        verbose_name=u'Check Date', default=timezone.now)
    allowed_address = models.OneToOneField(AllowedAddress, related_name='device_status')

    class Meta:
        verbose_name = (u'Device Status')
        verbose_name_plural = (u"Devices Status")


from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
    QMetaObject, QObject, QPoint, QRect,
    QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
    QFont, QFontDatabase, QGradient, QIcon,
    QImage, QKeySequence, QLinearGradient, QPainter,
    QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QHBoxLayout, QLabel, QSizePolicy,
    QToolButton, QWidget)

from spinetoolbox.widgets.custom_qlineedits import PropertyQLineEdit
from spine_items import resources_icons_rc

class Ui_Form(object):
    def setupUi(self, Form):
        if not Form.objectName():
            Form.setObjectName(u"Form")
        Form.resize(282, 47)
        self.horizontalLayout = QHBoxLayout(Form)
        self.horizontalLayout.setSpacing(4)
        self.horizontalLayout.setObjectName(u"horizontalLayout")
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.label_sysimage = QLabel(Form)
        self.label_sysimage.setObjectName(u"label_sysimage")

        self.horizontalLayout.addWidget(self.label_sysimage)

        self.lineEdit_sysimage = PropertyQLineEdit(Form)
        self.lineEdit_sysimage.setObjectName(u"lineEdit_sysimage")
        self.lineEdit_sysimage.setMaximumSize(QSize(16777215, 24))
        self.lineEdit_sysimage.setReadOnly(False)
        self.lineEdit_sysimage.setClearButtonEnabled(True)

        self.horizontalLayout.addWidget(self.lineEdit_sysimage)

        self.toolButton_abort_sysimage = QToolButton(Form)
        self.toolButton_abort_sysimage.setObjectName(u"toolButton_abort_sysimage")

        self.horizontalLayout.addWidget(self.toolButton_abort_sysimage)

        self.toolButton_new_sysimage = QToolButton(Form)
        self.toolButton_new_sysimage.setObjectName(u"toolButton_new_sysimage")
        icon = QIcon()
        icon.addFile(u":/icons/file.svg", QSize(), QIcon.Normal, QIcon.Off)
        self.toolButton_new_sysimage.setIcon(icon)
        self.toolButton_new_sysimage.setToolButtonStyle(Qt.ToolButtonIconOnly)

        self.horizontalLayout.addWidget(self.toolButton_new_sysimage)

        self.toolButton_open_sysimage = QToolButton(Form)
        self.toolButton_open_sysimage.setObjectName(u"toolButton_open_sysimage")
        icon1 = QIcon()
        icon1.addFile(u":/icons/folder-open-solid.svg", QSize(), QIcon.Normal, QIcon.Off)
        self.toolButton_open_sysimage.setIcon(icon1)

        self.horizontalLayout.addWidget(self.toolButton_open_sysimage)

        self.retranslateUi(Form)

        QMetaObject.connectSlotsByName(Form)
    # setupUi

    def retranslateUi(self, Form):
        Form.setWindowTitle(QCoreApplication.translate("Form", u"Form", None))
        self.label_sysimage.setText(QCoreApplication.translate("Form", u"Sysimage", None))
#if QT_CONFIG(tooltip)
        self.toolButton_abort_sysimage.setToolTip(QCoreApplication.translate("Form", u"
Abort sysimage creation
", None))
#endif // QT_CONFIG(tooltip)
        self.toolButton_abort_sysimage.setText(QCoreApplication.translate("Form", u"...", None))
#if QT_CONFIG(tooltip)
        self.toolButton_new_sysimage.setToolTip(QCoreApplication.translate("Form", u"
New Julia sysimage
", None))
#endif // QT_CONFIG(tooltip)
        self.toolButton_new_sysimage.setText(QCoreApplication.translate("Form", u"...", None))
#if QT_CONFIG(tooltip)
        self.toolButton_open_sysimage.setToolTip(QCoreApplication.translate("Form", u"
Open Julia sysimage
", None))
#endif // QT_CONFIG(tooltip)
        self.toolButton_open_sysimage.setText(QCoreApplication.translate("Form", u"...", None))
    # retranslateUi


import pytest

from pathlib import Path

from ojd_daps.flows.extract.reed import (
    get_salary_info,
    get_reed_details,
    reed_detail_parser,
    strip_html,
    get_meta,
)

from ojd_daps.flows.extract.reed import BeautifulSoup

PATH = Path(__file__).parent
EXAMPLE_QUERY = PATH / "resources" / "example_reed_ad.html"
EXPECTED_DETAILS = {
    "job_id": "41339969",
    "data_source": "Reed",
    "created": "09/11/2020",
}
TEST_HTML = "jobId: '41339969',\r\n"
TEST_UNSTRIPPED_HTML = 'Unstripped HTML'

@pytest.fixture
def html_and_soup():
    with open(EXAMPLE_QUERY) as f:
        text = f.read()
    soup = BeautifulSoup(text)
    return text, soup

def test_get_meta():
    span = BeautifulSoup(" <meta itemprop='bar' content='baz'>")
    assert get_meta(span, itemprop="bar") == "baz"

def test_get_salary_info(html_and_soup):
    _, soup = html_and_soup
    salary_info = get_salary_info(soup)
    assert salary_info == {
        "raw_salary": "52000.0000",
        "raw_min_salary": "52000.0000",
        "raw_max_salary": "55000.0000",
        "raw_salary_unit": "YEAR",
        "raw_salary_currency": "GBP",
        "salary_competitive": False,
        "salary_negotiable": False,
    }

def test_get_reed_details():
    f = open(EXAMPLE_QUERY, "r")
    content = f.read()
    ad_dict = get_reed_details(content)
    assert ad_dict["id"] == EXPECTED_DETAILS["job_id"]
    assert ad_dict["data_source"] == EXPECTED_DETAILS["data_source"]
    assert ad_dict["created"] == EXPECTED_DETAILS["created"]

def test_reed_detail_parser():
    assert reed_detail_parser("jobId", TEST_HTML) == "41339969"

def test_strip_html():
    assert strip_html(TEST_UNSTRIPPED_HTML) == "Unstripped HTML"


"""medplus URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/3.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from django.conf.urls import url,include

from users import views

urlpatterns = [
    path('admin/', admin.site.urls),
    url(r'^$',views.index, name='index'),
    url(r'^special/', views.special, name='special'),
    url(r'^users/', include('users.urls')),
    url(r'^outpatients/', include('outpatients.urls')),
    url(r'^inventory/', include('inventory.urls')),
    url(r'^pharmacy/', include('pharmacy.urls')),
    url(r'^laboratory/', include('laboratory.urls')),
    url(r'^frontoffice/', include('frontoffice.urls')),
    url(r'^purchase/', include('purchase.urls')),
    url(r'^billing/', include('billing.urls')),
    url(r'^iamadmin/', include('iamadmin.urls')),
    url(r'^finance/', include('finance.urls')),
    #url(r'^rc/', include('rc.urls')),
    #url(r'^inventory/', include('inventory.urls')),
    url(r'^fleet/', include('fleet.urls')),
    #url(r'^pm/', include('pm.urls')),
    #url(r'^sales/', include('sales.urls')),
    url(r'^settings/', include('settings.urls')),
    url(r'^settings/', include('uzer_settings.urls')),
    url(r'^iam/', include('iamadmin.urls')),
    #url(r'^pdf/', include('dopdf.urls')),
    url(r'^signin/$',views.signin, name='signin'),
    url(r'^signout/$', views.signout, name='signout'),
]


"""
file: list_mode_data_decoder_tests.py
brief: Unittests for the list_mode_data_decoder class.
author: S. V. Paulauskas
date: March 5, 2019
"""
from io import BytesIO
import unittest

from dolosse.hardware.xia.pixie16.tests.test_data import Pixie16TestData as td, pack_data

import dolosse.hardware.xia.pixie16.list_mode_data_decoder as decoder
import dolosse.hardware.xia.pixie16.list_mode_data_mask as lmdm

# TODO : We'll need to add tests to cover the major firmware revisions.
class ListModeDataDecoderTestCase(unittest.TestCase):
    """
    Test fixture for the List Mode Data Decoder functions
    """

    def setUp(self):
        """
        Configures the data mask for all the tests to use
        """
        self.frequency = 250
        self.firmware = 30474
        self.mask = lmdm.ListModeDataMask(self.frequency, self.firmware)

    def test_decode_word_zero(self):
        """
        Tests that we can decode the first word of the header properly
        """
        self.assertEqual({
            'channel': 13,
            'slot': 2,
            'crate': 0,
            'header_length': 4,
            'event_length': 4,
            'finish_code': 0
        }, decoder.decode_word_zero(td.header(self.frequency, self.firmware)[0], self.mask))

    def test_decode_word_two(self):
        """
        Checks that we can decode the third word of the header properly
        """
        self.assertEqual({
            'event_time_high': 26001,
            'cfd_fractional_time': 0,
            'cfd_trigger_source_bit': 0,
            'cfd_forced_trigger_bit': 0
        }, decoder.decode_word_two(td.header(self.frequency, self.firmware)[2], self.mask))

    def test_decode_word_three(self):
        """
        Test that we can decode the final word of the header properly
        """
        self.assertEqual({
            'energy': 2345,
            'trace_length': 0,
            'trace_out_of_range': 0
        }, decoder.decode_word_three(td.header(self.frequency, self.firmware)[3], self.mask))

    def test_decode_energy_sums(self):
        """
        Test that we can decode the energy sums. These can be tricky
        b/c the baseline is encoded in IEEE 754 format.
        """
        self.assertEqual(td.esums(decoded=True),
                         decoder.decode_energy_sums(BytesIO(td.esums(True))))

    def test_decode_external_timestamp(self):
        """
        Tests that we can decode external timestamps appropriately.
        """
        self.assertEqual(td.external_timestamp(), decoder.decode_external_timestamp(
            BytesIO(td.external_timestamp(True)), self.mask))

    def test_decode_qdc(self):
        """
        Tests that we can decode the QDC header into an array.
        """
        self.assertEqual(td.qdc(), decoder.decode_qdc(BytesIO(td.qdc(True))))

    def test_decode_trace(self):
        """
        Tests that we can decode a trace from the data stream.
        """
        self.assertEqual(td.trace(), decoder.decode_trace(BytesIO(td.trace(True))))

    def test_process_optional_header_data_bad_header_length(self):
        """Tests that we raise a Value Error when decoding a bad header length."""
        with self.assertRaises(ValueError):
            decoder.process_optional_header_data(BytesIO(td.external_timestamp(True)), 3, self.mask)

    def test_process_optional_header_data(self):
        """ Test that we can process all the various header data correctly. """
        self.assertDictEqual({'external_timestamp': td.external_timestamp()},
                             decoder.process_optional_header_data(
                                 BytesIO(td.external_timestamp(True)),
                                 decoder.HeaderCodes.HEADER_W_ETS, self.mask))
        self.assertDictEqual({'esums': td.esums(False, True)},
                             decoder.process_optional_header_data(BytesIO(td.esums(True)),
                                                                  decoder.HeaderCodes.HEADER_W_ESUM,
                                                                  self.mask))
        self.assertDictEqual(
            {'external_timestamp': td.external_timestamp(), 'esums': td.esums(False, True)},
            decoder.process_optional_header_data(
                BytesIO(td.esums(True) + td.external_timestamp(True)),
                decoder.HeaderCodes.HEADER_W_ESUM_ETS, self.mask))
        self.assertDictEqual({'qdc': td.qdc()},
                             decoder.process_optional_header_data(BytesIO(td.qdc(True)),
                                                                  decoder.HeaderCodes.HEADER_W_QDC,
                                                                  self.mask))
        self.assertDictEqual({'external_timestamp': td.external_timestamp(), 'qdc': td.qdc()},
                             decoder.process_optional_header_data(
                                 BytesIO(td.qdc(True) + td.external_timestamp(True)),
                                 decoder.HeaderCodes.HEADER_W_QDC_ETS, self.mask))
        self.assertDictEqual({'esums': td.esums(False, True), 'qdc': td.qdc()},
                             decoder.process_optional_header_data(
                                 BytesIO(td.esums(True) + td.qdc(True)),
                                 decoder.HeaderCodes.HEADER_W_ESUM_QDC, self.mask))
        self.assertDictEqual({'external_timestamp': td.external_timestamp(), 'qdc': td.qdc(),
                              'esums': td.esums(False, True)}, decoder.process_optional_header_data(
            BytesIO(td.esums(True) + td.qdc(True) + td.external_timestamp(True)),
            decoder.HeaderCodes.HEADER_W_ESUM_QDC_ETS, self.mask))

    def test_decode_listmode_data(self):
        """
        Test that we can decode a full 4 word header properly.
        """
        self.assertEqual([td.header(decoded=True)],
                         decoder.decode_listmode_data(BytesIO(td.header(as_bytes=True)), self.mask))
        self.assertEqual([{**td.header_with_trace(decoded=True), **{'trace': td.trace()}}],
                         decoder.decode_listmode_data(
                             BytesIO(td.header_with_trace(as_bytes=True) + td.trace(True)),
                             self.mask))

    def test_decode_listmode_data_bad_header_length(self):
        header = td.header()
        header[0] = 561197
        with self.assertRaises(BufferError):
            decoder.decode_listmode_data(BytesIO(pack_data(header, "I")), self.mask)

    def test_decode_listmode_data_bad_event_length(self):
        header = td.header()
        header[0] = 671789
        header[3] = 657705
        with self.assertRaises(ValueError):
            decoder.decode_listmode_data(BytesIO(pack_data(header, "I")), self.mask)

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


import discord, json, os, datetime, random, requests, shutil, asyncio

from discord.ext import tasks, commands
from discord.utils import get
from PIL import Image, ImageFont, ImageDraw

file_path = "C:\\Users\\Default\\Documents\\Python\\Scripts\\Vorbis"
#file_path = "A:\\Documents\\Python\\Scripts\\Vorbis"

user_location = file_path+"\\Members"
guild_location = file_path+"\\Guilds"
config_location = file_path+"\\Config"
global_profile = file_path+"\\GlobalProfiles"
metadata_location = file_path+"\\Metadata"
queue_location = file_path+"\\Queue"
asset_location = file_path+"\\Assets"
vorbis_img = "https://cdn.discordapp.com/attachments/800136030228316170/802961405296902154/icon2.jpg"

WHITE = discord.Color.from_rgb(255, 255, 255)
TERQ = discord.Color.from_rgb(49,171,159)
RED = discord.Color.from_rgb(255, 0, 0)
YELLOW = discord.Color.from_rgb(255, 255, 0)
LIGHT_BLUE = discord.Color.from_rgb(155, 155, 255)
GREEN = discord.Color.green()
MAGENTA = discord.Color.magenta()
DARK_RED = discord.Color.dark_red()
DARK_BLUE = discord.Color.dark_blue()
DARK_ORANGE = discord.Color.dark_orange()
ORANGE = discord.Color.orange()
PURPLE = discord.Color.purple()

def filt_str_mod(string : str):

    filtered_1 = ''.join(filter(lambda char: char != '"', string))
    filtered_2 = ''.join(filter(lambda char: char != ':', filtered_1))
    filtered_3 = ''.join(filter(lambda char: char != '|', filtered_2))
    filtered_4 = ''.join(filter(lambda char: char != '.wav', filtered_3))
    filtered_5 = ''.join(filter(lambda char: char != ']', filtered_4))
    filtered_6 = ''.join(filter(lambda char: char != '[', filtered_5))
    filtered_7 = ''.join(filter(lambda char: char != "'", filtered_6))

    return filtered_7

def make_asset(file : os.PathLike, mode : str, data : dict=None, indent : int=4):
    if data is None:
        with open(file, mode) as make_file:
            make_file.close()
    with open(file, mode) as make_json:
        json.dump(obj=data, fp=make_json, indent=indent)
        make_json.close()

def return_data(file : str, tabel : str=None, sub_tabel : str=None):
    try:
        if tabel is None:
            with open(file) as data:

                RwText_Data = data.read()
                RwJSON_Data = json.loads(RwText_Data)

                return RwJSON_Data

        elif tabel is not None and sub_tabel is not None:
            with open(f"{file}") as data:

                RwText_Data = data.read()
                RwJSON_Data = json.loads(RwText_Data)

                return RwJSON_Data[tabel][sub_tabel]

        elif tabel is not None and sub_tabel is None:
            with open(f"{file}") as data:

                RwText_Data = data.read()
                RwJSON_Data = json.loads(RwText_Data)

                return RwJSON_Data[tabel]

    except (FileNotFoundError, OSError, KeyError):
        return None

def check_dirfile(path : os.PathLike, Type : str):

    if Type == "dir":
        if os.path.isdir(path):
            return True
        else:
            return False

    elif Type == "file":
        if os.path.isfile(path):
            return True
        else:
            return False
    else:
        raise TypeError(f"There is no file type with the type: {Type}! (Chose only > dir | file)")

class listeners(commands.Cog):

    def __init__(self, client):
        print("Loaded Listeners")
        self.client = client

    @commands.Cog.listener()
    async def on_message(self, message):

        if message.author.id == 798867893910765579:
            return

        channel = None
        member = message.author

        try:
            if return_data(f"{config_location}\\{message.guild.id}\\config.json", "config", "log_channel") is not None:
                pass
            else:
                channel = self.client.get_channel(message.channel.id)

            try:
                guild = f"\\{message.guild.id}"
                full_user_path = user_location+guild
                channel_path = f"{config_location}\\{message.guild.id}\\config.json"
                main_usr_data = return_data(f"{user_location}\\{message.guild.id}\\{message.author.id}\\{message.author.id}.json")

            except AttributeError:
                pass

            usr_exp = 0
            until_nxt_lvl = None
            usr_lvl = 0

            embed = discord.Embed(color=message.author.colour)
            member_id = message.author.id

            def make_plr():

                name = message.author.name
                avatar = message.author.avatar_url

                with open(f"{full_user_path}\\{member_id}\\{member_id}.json", "w+") as write_member:
                    global_path = global_profile+f"\\{message.author.id}"

                    if check_dirfile(global_path, Type="dir") != True:
                        os.makedirs(global_path)

                        if check_dirfile(global_path+f"\\{message.author.id}.json", "file") != True:

                            global_data = {}
                            global_data["global"] = ({
                                "has-link": False,
                                "link-id": None,
                                "playlist-list": {},
                                "listened-playlist-list": [],
                                "auto-correct": {
                                    "failure": {
                                        "failure-name": None,
                                        "command-completion": False,
                                        "failure-count": 0,
                                        "correct-playlist": None
                                    }
                                },
                                "chatroom": {
                                    "connected-chatroom": None
                                }
                            })
                            make_asset(global_path+f"\\{message.author.id}.json", "w", global_data, indent=4)

                    member_metadata = {}

                    member_metadata[f'{member_id}'] = ({
                        "member-id": str(member_id),
                        "member-name": str(name),
                        "member-avatar": str(avatar),
                        "member-joindate": str(message.author.joined_at)
                    })

                    member_metadata[f'progress-bar'] = ({
                        "progress-bar-count": 0
                    })
                    json.dump(member_metadata, write_member, indent=4)

                    write_member.close()

            try:

                with open(full_user_path+f"\\{member_id}\\{member_id}-exp.json", "r") as read_current_level:

                    text = read_current_level.read()
                    json_readable = json.loads(text)

                    usr_exp = json_readable[f'{member_id}']['member-exp']
                    usr_lvl = json_readable[f'{member_id}']['member-level']
                    until_nxt_lvl = json_readable[f'{member_id}']['member-until-next-lvl']

                    read_current_level.close()

                    with open(full_user_path+f"\\{message.author.id}\\{message.author.id}-exp.json", "w") as write_data:

                        userBankPath = f"{user_location}\\{message.guild.id}\\{member_id}\\{member_id}-bank.json"
                        userBankData = return_data(userBankPath)

                        data = {}
                        numbers = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

                        level_numbers = [50, 60, 70, 80, 90, 100]
                        level_numbers_100 = [100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200]
                        level_numbers_200 = [200, 210, 220, 230, 240, 250, 260, 270, 280, 290, 300]
                        level_numbers_300 = [300, 310, 320, 330, 340, 350, 360, 370, 380, 390, 400]
                        level_numbers_400 = [400, 410, 420, 430, 440, 450, 460, 470, 480, 490, 500]
                        level_numbers_500 = [500, 510, 520, 530, 540, 550, 560, 570, 580, 590, 600, 1000]

                        level_values = None

                        if message.guild.premium_tier == 0:
                            new_exp = usr_exp+1
                            userBankData[f"{member_id}"]["balance"] = userBankData[f"{member_id}"]["balance"]+5
                        elif message.guild.premium_tier == 1:
                            new_exp = usr_exp+2
                            userBankData[f"{member_id}"]["balance"] = userBankData[f"{member_id}"]["balance"]+10
                        elif message.guild.premium_tier == 2:
                            new_exp = usr_exp+3
                            userBankData[f"{member_id}"]["balance"] = userBankData[f"{member_id}"]["balance"]+15

                        make_asset(userBankPath, "w", userBankData, 4)

                        if new_exp >= until_nxt_lvl:

                            until_nxt_lvl = int(random.choice(level_numbers))
                            curnt_time = str(datetime.datetime.now())

                            new_exp = 0
                            usr_lvl = usr_lvl+1
                            role = None
                            next_milestone = None

                            if usr_lvl < 100:
                                level_values = level_numbers
                            elif usr_lvl > 100 and usr_lvl < 200:
                                level_values = level_numbers_100
                            elif usr_lvl > 200 and usr_lvl < 300:
                                level_values = level_numbers_200
                            elif usr_lvl > 300 and usr_lvl < 400:
                                level_values = level_numbers_300
                            elif usr_lvl > 400 and usr_lvl < 500:
                                level_values = level_numbers_400
                            elif usr_lvl > 500:
                                level_values = level_numbers_500

                            until_nxt_lvl = int(random.choice(level_values))

                            if usr_lvl in numbers:
                                role = discord.utils.get(self.client.get_guild(message.guild.id).roles, name=f"Level {usr_lvl}")
                                if usr_lvl == 10:
                                    pass
                                else:
                                    roleToRemove = discord.utils.get(self.client.get_guild(message.guild.id).roles, name=f"Level {usr_lvl-10}")
                            else:
                                for x in range(len(numbers)):
                                    if usr_lvl < numbers[x] and usr_lvl > numbers[x-1]:
                                        next_milestone = numbers[x]

                            if next_milestone is None:
                                next_milestone = usr_lvl+10
                            if usr_lvl >= 100:
                                next_milestone = "No more milestones"

                            main_usr_data["progress-bar"]["progress-bar-count"] = 0

                            embed.set_author(name="Level Up \u200b")
                            embed.set_image(url=message.author.avatar_url)

                            embed.add_field(name=f"Ø   {message.author} levelled up to level {usr_lvl}!", value="\u200b")
                            embed.add_field(name=f"Ø   Next milestone   Ø   {next_milestone}", value="\u200b", inline=False)

                            embed.set_footer(text="Time of Level Up Ø {}  UTC".format(curnt_time.split(".")[0]))

                            if channel is not None:
                                await channel.send(embed=embed)
                            else:
                                await self.client.get_guild(message.guild.id).get_channel(message.channel.id).send(embed=embed)

                            if role is not None:
                                await message.author.add_roles(role)
                                if usr_lvl == 10:
                                    pass
                                else:
                                    await message.author.remove_roles(roleToRemove)
                            else:
                                pass

                        if usr_exp % 2 == 0:
                            pass
                        else:
                            main_usr_data["progress-bar"]["progress-bar-count"] = main_usr_data["progress-bar"]["progress-bar-count"]+1

                        data[member_id] = ({
                            "member-exp": new_exp,
                            "member-level": usr_lvl,
                            "member-until-next-lvl": until_nxt_lvl

                        })

                        userID = str(message.author.id)

                        globalData = return_data(global_profile+f"\\{member_id}\\{member_id}.json")
                        serverLinks = return_data(f"{guild_location}\\{message.guild.id}\\{message.guild.id}-LINKS.json")["guild-links"]
                        userLinks = return_data(f"{full_user_path}\\{userID}\\{userID}-links.json")
                        userMetadata = return_data(metadata_location+f"\\{message.guild.id}\\payload-data.json")
                        userMetadata['data']['message-id'] = message.id

                        if userID in serverLinks:

                            if serverLinks["links-enabled"]:

                                linkedData = f"{serverLinks[userID]}".split("'")
                                userData = f"{user_location}\\{linkedData[3]}\\{linkedData[1]}\\{linkedData[1]}-exp.json"

                                make_asset(userData, "w", data, 4)

                        if userLinks["member-link"]["link-enabled"]:
                            try:
                                link = int(userLinks["member-link"]["links"][0])
                                guildName = self.client.get_guild(link)

                                if guildName is not None:
                                    guildPath = f"{user_location}\\{link}\\{userID}\\{userID}-exp.json"

                                    make_asset(guildPath, "w", data, 4)
                                    make_asset(f"{user_location}\\{message.guild.id}\\{message.author.id}\\{message.author.id}.json", "w", main_usr_data, 4)
                                    make_asset(metadata_location+f"\\{message.guild.id}\\payload-data.json", "w", userMetadata, 4)

                                else:
                                    print(f"{globalData['global']['has-link']} >>>> {self.client.get_guild(globalData['global']['link-id'])}")
                                    if globalData["global"]["has-link"] is True and self.client.get_guild(globalData["global"]["link-id"]) is None:

                                        userLinks["member-link"]["links"].clear()
                                        globalData["global"]["has-link"] = False

                                        linkUser = self.client.get_user(member_id)
                                        await linkUser.send("The server you made a link on has since been deleted or I was kicked, I have severed your link.\nAnd you have kept all Experience data you gathered from both servers, sorry for the inconvinience. (Note: Of course, I can only make a link to a server if I'm in it)")

                                        make_asset(f"{full_user_path}\\{userID}\\{userID}-links.json", "w", userLinks, 4)
                                        make_asset(global_profile+f"\\{member_id}\\{member_id}.json", "w", globalData, 4)

                                    else:
                                        pass

                            except IndexError:
                                pass

                        make_asset(f"{user_location}\\{message.guild.id}\\{message.author.id}\\{message.author.id}.json", "w", main_usr_data, 4)
                        make_asset(metadata_location+f"\\{message.guild.id}\\payload-data.json", "w", userMetadata, 4)
                        json.dump(data, write_data, indent=4)

            except FileNotFoundError:
                if os.path.isdir(f"{user_location}\\{message.guild.id}\\{message.author.id}"):
                    pass
                else:
                    os.mkdir(f"{user_location}\\{message.guild.id}\\{message.author.id}")

                make_plr()

                data = {}
                member_links = {}
                bank = {}

                data[member_id] = ({
                    "member-exp": 0,
                    "member-level": 0,
                    "member-until-next-lvl": 5
                })
                member_links[f"member-link"] = ({
                    "link-enabled": False,
                    "links": []
                })

                bank[f"{member_id}"] = ({
                    "balance": 50,
                    "inventory": {}
                })

                make_asset(file=f"{full_user_path}\\{member_id}\\{member_id}-exp.json", mode="w+", data=data, indent=4)
                make_asset(file=f"{full_user_path}\\{member_id}\\{member_id}-links.json", mode="w+", data=member_links, indent=4)
                make_asset(file=f"{full_user_path}\\{member_id}\\{member_id}-bank.json", mode="w+", data=bank, indent=4)

        except AttributeError:
            pass

    @commands.Cog.listener()
    async def on_member_join(self, member):

        embed = discord.Embed(color=TERQ)
        c_path = f"{config_location}\\{member.guild.id}"
        guild = member.guild.id
        full_user_path = user_location+f"\\{guild}"
        user_path = f"{full_user_path}\\{member.id}"

        g_img = None
        g_txt = None
        g_chl = None

        try:
            if return_data(file=f"{c_path}\\whitelist.json", tabel="setting1", sub_tabel="whitelist") == bool(True):

                embed.set_author(name="Whitelist is enabled on this server, you cannot join.")
                print("Player got kicked becuase of whitelist")

                await member.send(embed=embed)
                return await member.kick(reason="Whitelist is enabled")

        except FileNotFoundError:
            pass

        try:
            os.chdir(full_user_path)
        except FileNotFoundError:
            os.mkdir(full_user_path)

        if os.path.isdir(full_user_path+f"\\{member.id}") != True:
            os.mkdir(f"{member.id}")

        name = member.name
        avatar = member.avatar_url

        data = {}
        member_level = {}
        member_metadata = {}
        member_links = {}
        member_bank = {}

        data['setting1'] = ({
            "warnings": 0
        })

        member_metadata[f'{member.id}'] = ({
            "member-id": str(member.id),
            "member-name": str(name),
            "member-avatar": str(avatar),
            "member-joindate": str(member.joined_at),
            "member-exp": 0,
            "member-link": {
                "link-enabled": False,
                "links": []
            }
        })

        member_metadata['progress-bar'] = ({
            "progress-bar-count": 0
        })
        member_links[f"member-link"] = ({
            "link-enabled": False,
            "links": []
        })

        member_level[member.id] = ({
            "member-exp": 0,
            "member-level": 0,
            "member-until-next-lvl": 50
        })

        member_bank[f"{member.id}"] = ({
            "balance": 50,
            "inventory": {}
        })

        make_asset(file=f"{user_path}\\{member.id}.json", mode="w+", data=member_metadata, indent=4)
        make_asset(file=f"{user_path}\\{member.id}-warnings.json", mode="w+", data=data, indent=4)
        make_asset(file=f"{user_path}\\{member.id}-exp.json", mode="w+", data=member_level, indent=4)
        make_asset(file=f"{user_path}\\{member.id}-links.json", mode="w+", data=member_links, indent=4)
        make_asset(file=f"{user_path}\\{member.id}-bank.json", mode="w+", data=member_bank, indent=4)

        cfg_g = f"{config_location}\\{member.guild.id}"

        if check_dirfile(path=f"{cfg_g}\\join_channel.json", Type="file") and check_dirfile(path=f"{cfg_g}\\join_image.json", Type="file") and check_dirfile(path=f"{cfg_g}\\join_message.json", Type="file"):
            pass
        else:
            return False

        try:
            g_chl = return_data(file=f"{cfg_g}\\config.json", tabel="config", sub_tabel="join_channel")
        except KeyError:
            return
        try:
            g_img = return_data(file=f"{cfg_g}\\config.json", tabel="config", sub_tabel="join_image")

            if g_img is None:
                g_img = vorbis_img
        except KeyError:
            g_img = vorbis_img
        try:
            g_txt = return_data(file=f"{cfg_g}\\config.json", tabel="config", sub_tabel="join_message")

            if g_txt is None:
                g_txt = f"{member} has joined the guild, Please give them a warm welcome."
        except KeyError:
            g_txt = f"{member} has joined the guild, Please give them a warm welcome."

        embed.set_author(name="Notification")
        embed.set_thumbnail(url=member.avatar_url)
        embed.add_field(name=f"{member} has joined {member.guild}", value=g_txt)
        embed.set_image(url=g_img)

        try:
            await self.client.get_channel(int(g_chl)).send(embed=embed)
        except discord.errors.Forbidden:
            pass

        image = str(member.avatar_url)

        if os.path.isfile(f"{c_path}\\join_role.json"):
            try:
                role = return_data(file=f"{c_path}\\join_role.json", tabel="join_role", sub_tabel="role")
                role_to_give = discord.utils.get(self.client.get_guild(member.guild.id).roles, name=role)

                await member.add_roles(role_to_give)
            except AttributeError:
                pass
    @commands.Cog.listener()
    async def on_guild_join(self, guild):

        async def make_role(role_name : str, color):
            await guild.create_role(name=f"{role_name}", colour=color)

        channel = None

        try:
            channel = await self.client.get_channel(guild.system_channel.id).create_invite(reason="For security purposes.")
        except AttributeError:
            pass

        directories = ['Music', 'Queue', 'Temp', 'Members', 'Metadata', 'Resources', 'Config']

        colors = {}

        colors = ({
            "COLOR": {
                "GREEN": {
                    "COLOR": GREEN,
                    "ID": 0
                },
                "LIGHT_BLUE": {
                    "COLOR": LIGHT_BLUE,
                    "ID": 1
                },
                "TERQ": {
                    "COLOR": TERQ,
                    "ID": 2
                },
                "YELLOW": {
                    "COLOR": YELLOW,
                    "ID": 3
                },
                "RED": {
                    "COLOR": RED,
                    "ID": 4
                },
                "DARK_RED": {
                    "COLOR": DARK_RED,
                    "ID": 5
                },
                "DARK_BLUE": {
                    "COLOR": DARK_BLUE,
                    "ID": 6
                },
                "DARK_ORANGE": {
                    "COLOR": DARK_ORANGE,
                    "ID": 7
                },
                "ORANGE": {
                    "COLOR": ORANGE,
                    "ID": 8
                },
                "PURPLE": {
                    "COLOR": PURPLE,
                    "ID": 9
                }
            }
        })

        if str(guild) != "tt":
            try:
                for x in range(len(directories)):
                    if os.path.isdir(f"{file_path}\\{directories[x]}\\{guild.id}") != True:
                        os.mkdir(f"{file_path}\\{directories[x]}\\{guild.id}")

            except FileExistsError:
                pass

        make_roles = True

        num = []
        color = []

        while make_roles is True:

            role_id = None
            role_colour = None
            roles = colors["COLOR"]
            role_l = list(colors["COLOR"])
            role_color = random.choice(role_l)
            role_full = roles[f"{role_color}"]
            role_id = role_full["ID"]
            role_colour = role_full["COLOR"]

            if role_id is not None:

                colors["COLOR"][f"{role_color}"]["ID"] = None

                num.append(".")
                color.append(role_colour)

            else:
                if len(num) > 9:
                    for y in range(0, 10):

                        await make_role(role_name=f"Level {y+1}0", color=color[y])

                    break
                else:
                    pass

        if str(guild) == "tt":
            return False

        config = {}
        links = {}
        bank = {}
        payload = {}
        metadata = {}

        config['config'] = ({
            "vol": 0.3,
            "loop": False
        })

        links["guild-links"] = ({
            "links-enabled": True
        })

        bank[f"{guild.id}"] = ({
            "guild-balance": 0,
            "items": [],
            "guild-items": {}
        })

        metadata['metadata'] = ({
            "name": None,
            "views": None,
            "author": None,
            "queued-playlist": None
        })
        payload["data"] = ({
            "author-id": None,
            "message-id": None,
            "og-message-id": None
        })

        make_asset(file=f"{config_location}\\{guild.id}\\config.json", mode="w+", data=config, indent=4)
        make_asset(file=f"{metadata_location}\\{guild.id}\\metadata.json", mode="w+", data=metadata, indent=4)
        make_asset(file=f"{metadata_location}\\{guild.id}\\payload-data.json", mode="w+", data=payload, indent=4)

        os.chdir(guild_location)

        def mk_metadata():
            if os.path.isdir(guild_location+f"\\{guild.id}") == False:
                os.mkdir(guild_location+f"\\{guild.id}")

            with open(guild_location+f"\\{guild.id}\\{guild.id}.json", "w+") as edit_svr_metadata:

                server_matadata = {}
                server_matadata[guild.id] = ({
                    f"{guild.id}-id": str(guild.id),
                    f"{guild.id}-ico": str(guild.icon),
                    f"{guild.id}-nm": str(guild.name),
                    f"{guild.id}-bnr": str(guild.banner),
                    f"{guild.id}-desc": str(guild.description),
                    f"{guild.id}-cunrt-boosts": str(guild.premium_subscription_count),
                    f"{guild.id}-roles": str(guild.roles),
                    f"{guild.id}-member-count": str(guild.member_count),
                    f"{guild.id}-invite": str(channel)

                })

                json.dump(server_matadata, edit_svr_metadata, indent=4)
                make_asset(file=f"{guild_location}\\{guild.id}\\{guild.id}-LINKS.json", mode="w+", data=links, indent=4)
                make_asset(file=f"{guild_location}\\{guild.id}\\{guild.id}-INVENTORY.json", mode="w+", data=bank, indent=4)

                print("Made Assets")

        embed = discord.Embed(color=self.client.get_user(guild.owner_id).color)
        fabian, austin = self.client.get_user(533285613021954049), self.client.get_user(400089431933059072)

        embed.set_author(name=f"I have joined {guild}!")
        embed.add_field(name="I am Vorbis!", value="I can play songs, make playlists, queue songs, and I have a level system! do /help for help, and /usage for command usage!\n(This is Austin Talking) And here is Vorbis' YouTube Channel, I will upload tutorials on how to operate Vorbis. As I understand it is difficult to use, I apologise.")
        embed.set_footer(text=f"Programmed by {fabian} and {austin} (On discord) 👩💻")
        embed.set_thumbnail(url=vorbis_img)

        mk_metadata()

        try:
            await self.client.get_guild(guild.id).get_channel(guild.system_channel.id).send(embed=embed)
            await self.client.get_user(guild.owner_id).send('Note for Owner / Administrators : Do "/server help" in server\nAnd if/when you want the bot to leave the server\nDo /leave')

        except AttributeError:
            print("Server has no system channel, not sending welcome message..")
            mk_metadata()

    @commands.Cog.listener()
    async def on_guild_update(self, before, after):

        guild = after
        guild_data = {}

        guild_data[guild.id] = ({
                    f"{guild.id}-id": str(guild.id),
                    f"{guild.id}-ico": str(guild.icon),
                    f"{guild.id}-nm": str(guild.name),
                    f"{guild.id}-bnr": str(guild.banner),
                    f"{guild.id}-desc": str(guild.description),
                    f"{guild.id}-cunrt-boosts": str(guild.premium_subscription_count),
                    f"{guild.id}-roles": str(guild.roles)
        })

        make_asset(file=guild_location+f"\\{guild.id}\\{guild.id}.json", mode="w+", data=guild_data, indent=4)

    @commands.Cog.listener()
    async def on_member_remove(self, member):

        embed = discord.Embed(color=DARK_BLUE)
        g_id = member.guild.id

        if member.id == 798867893910765579:
            return

        location_msg = f"{config_location}\\{g_id}\\config.json"
        location_img = f"{config_location}\\{g_id}\\config.json"
        location_chnl = f"{config_location}\\{g_id}\\config.json"

        l_value = None
        l_img = None
        chnl_id = None
        if check_dirfile(path=location_msg, Type="file") and check_dirfile(path=location_img, Type="file") and check_dirfile(path=location_chnl, Type="file"):
            pass
        else:
            return False

        l_name = f"{member} left {member.guild}!"
        try:
            l_value = return_data(file=location_msg, tabel="config", sub_tabel="leave_message")

            if l_value is None:
                l_value = f"{member} has left the guild."

        except KeyError:
            l_value = f"{member} has left the guild."
        try:
            l_img = return_data(file=location_img, tabel="config", sub_tabel="leave_image")

            if l_img is None:
                l_img = vorbis_img
        except KeyError:
            l_img = vorbis_img
        try:
            chnl_id = return_data(file=location_chnl, tabel="config", sub_tabel="leave_channel")
        except KeyError:
            return

        try:
            embed.set_author(name="Notification")
            embed.add_field(name=l_name, value=l_value)
            embed.set_image(url=l_img)

            await self.client.get_guild(g_id).get_channel(chnl_id).send(embed=embed)
        except discord.errors.Forbidden():
            pass

    @commands.Cog.listener()
    async def on_raw_reaction_add(self, payload):
        ctx, member = self.client.get_channel(payload.channel_id), payload.member
        messageChannel = self.client.get_channel(payload.channel_id)
        message = await messageChannel.fetch_message(payload.message_id)
        embed = discord.Embed(color=LIGHT_BLUE)

        try:
            channel, vorbis = member.voice.channel, self.client.get_user(self.client.user.id)
            guild = self.client.get_guild(payload.guild_id)
            voice = get(self.client.voice_clients, guild=guild)

            metadata = return_data(metadata_location+f"\\{payload.guild_id}\\payload-data.json")
            config = return_data(f"{config_location}\\{payload.guild_id}\\config.json")

            if member.id != 798867893910765579:
                if member in channel.members and vorbis in channel.members:
                    if payload.message_id == metadata["data"]["message-id"] or payload.message_id == metadata["data"]["og-message-id"] and member.id == metadata["data"]["author-id"]:

                        if payload.emoji.name == "\U0001f3b5":
                            voice.pause()

                        elif payload.emoji.name == "\U0001f3b6":
                            voice.pause()
                            voice.stop()

                            config["config"]["loop"] = False
                            make_asset(f"{config_location}\\{payload.guild_id}\\config.json", "w", config, 4)

                            await message.remove_reaction("\U0001f3b6", member)
                        elif payload.emoji.name == "\U0001f4fc":
                            song_list = []
                            songsList = os.listdir(queue_location+f"\\{payload.guild_id}")

                            embed.set_author(name="Queued Songs")

                            for x in range(len(songsList)):
                                song = songsList[x].split(".wav")[0]

                                embed.add_field(name=f"Song {x+1}  Ø ", value=song, inline=False)

                            embed.set_footer(text=f"Amount of songs left: {len(songsList)}")
                            await ctx.send(embed=embed, delete_after=10)
                            await message.remove_reaction("\U0001f4fc", member)
                        elif payload.emoji.name == "\U0001f502":
                            config["config"]["loop"] = True
                            make_asset(f"{config_location}\\{payload.guild_id}\\config.json", "w", config, 4)

                    else:
                        return
                else:
                    return
            else:
                return
        except AttributeError:
            return

    @commands.Cog.listener()
    async def on_raw_reaction_remove(self, payload):

        emoji, guildID = payload.emoji.name, payload.guild_id
        metadata = return_data(f"{metadata_location}\\{guildID}\\payload-data.json")
        messageChannel = self.client.get_channel(payload.channel_id)
        message = await messageChannel.fetch_message(payload.message_id)
        config = return_data(f"{config_location}\\{guildID}\\config.json")

        try:
            guild = self.client.get_guild(payload.guild_id)
            voice = get(self.client.voice_clients, guild=guild)

            if message.author.id == metadata["data"]["author-id"] and message.id == metadata["data"]["message-id"] or message.id == metadata["data"]["og-message-id"]:
                if emoji == "\U0001f502":
                    config["config"]["loop"] = False
                    make_asset(f"{config_location}\\{guildID}\\config.json", "w", config, 4)
                elif emoji == "\U0001f3b5":
                    voice.resume()
                else:
                    return
            else:
                return
        except AttributeError:
            pass

def setup(client):
    client.add_cog(listeners(client))


import datetime

from django.test import TestCase
from django.utils import timezone
from django.urls import reverse

from .models import Question
from .helper import language_check

# Create your tests here.

class QuestionModelTests(TestCase):
    def test_was_published_recently_with_future_question(self):
        '''
        was_published_recently() returns False for questions whose pub_date
        is in the future
        '''
        time = timezone.now() + datetime.timedelta(days=30)
        future_question = Question(pub_date=time)
        self.assertIs(future_question.was_published_recently(), False)

    def test_was_published_recently_with_old_question(self):
        '''
        was_published_recently() returns False for questions whose pub_date
        is older than 1 day
        '''
        time = timezone.now() - datetime.timedelta(
            days=1, seconds=1)
        old_question = Question(pub_date=time)
        self.assertIs(old_question.was_published_recently(), False)

    def test_was_published_recently_with_recent_question(self):
        '''
        was_published_recently() returns False for questions whose pub_date
        is within the last day
        '''
        time = timezone.now() - datetime.timedelta(
            hours=23, minutes=59, seconds=59)
        recent_question = Question(pub_date=time)
        self.assertIs(recent_question.was_published_recently(), True)

def create_question(question_text, days, choices=True):
    '''
    Creates a question with given 'question_text' and number
    of days from now. (-) before now, (+) after now. if choices is
    True (default), 1 choice will be created for the question. OTW
    no choices will be created.
    '''
    time = timezone.now() + datetime.timedelta(days=days)
    q = Question.objects.create(question_text=question_text, pub_date=time)
    if choices:
        q.choice_set.create(choice_text='exp choice', votes=0)
    return q

class QuestionIndexViewTests(TestCase):
    def test_no_questions(self):
        '''
        if no questions exist, an appropriate
        message will display
        '''
        response = self.client.get(reverse('polls:index'))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, 'No polls are available.')
        self.assertQuerysetEqual(
            response.context['latest_question_list'], [])

    def test_past_question(self):
        '''
        Questions with pub_date in the past are displayed on index
        '''
        create_question(question_text="past question", days=-30)
        response = self.client.get(reverse('polls:index'))
        self.assertQuerysetEqual(
            response.context['latest_question_list'],
            ['<Question: past question>']
        )

    def test_future_question(self):
        '''
        Questions with pub_date in the future are not displayed on idex
        '''
        create_question(question_text='future question', days=30)
        response = self.client.get(reverse('polls:index'))
        self.assertContains(response, 'No polls are available.')
        self.assertQuerysetEqual(
            response.context['latest_question_list'], [])

    def test_future_and_past_question(self):
        '''
        if both past and future questions exist, only
        past questions are displayed on index
        '''
        create_question(question_text='future q', days=30)
        create_question(question_text='past q', days=-30)
        response = self.client.get(reverse('polls:index'))
        self.assertQuerysetEqual(
            response.context['latest_question_list'],
            ['<Question: past q>']
        )

    def test_two_past_questions(self):
        '''
        question index page may display multiple questions
        '''
        create_question(question_text='past q1', days=-30)
        create_question(question_text='past q2', days=-15)
        response = self.client.get(reverse('polls:index'))
        self.assertQuerysetEqual(
            response.context['latest_question_list'],
            ['<Question: past q2>', '<Question: past q1>']
        )

class QuestionChoicesIndexTest(TestCase):

    def test_no_choices(self):
        '''
        the index should not display questions if
        question has no choices
        '''
        create_question(question_text='no choice', days=-1, choices=False)
        response = self.client.get(reverse('polls:index'))
        self.assertContains(response, 'No polls are available.')
        self.assertQuerysetEqual(response.context['latest_question_list'], [])

    def test_choices(self):
        '''
        test index if displays 2/3 questions, one of which
        has no choices.
        '''
        create_question(question_text='no choice', days=-1, choices=False)
        create_question(question_text='choice1', days=-1)
        create_question(question_text='choice2', days=-1)
        response = self.client.get(reverse('polls:index'))
        self.assertQuerysetEqual(
            response.context['latest_question_list'],
            ["<Question: choice2>", "<Question: choice1>"]
        )

class QuestionDetailViewTests(TestCase):
    def test_future_question(self):
        '''
        the detail view of a question with a pub_date
        in the future returns 404
        '''
        future_q = create_question(question_text='future question', days=5)
        url = reverse('polls:detail', args=(future_q.id,))
        response = self.client.get(url)
        self.assertEqual(response.status_code, 404)

    def test_past_question(self):
        '''
        the detail view of a uestion with pub_date
        in past displays question text
        '''
        past_q = create_question(question_text='past question', days=-3)
        url = reverse('polls:detail', args=(past_q.id,))
        response = self.client.get(url)
        self.assertContains(response, past_q.question_text)

class languageFilterTests(TestCase):
    def test_good_language(self):
        '''
        check if good language. will return tuple of (False, None)
        '''
        test_phrase = "Is this a bad question?"
        resp = language_check(test_phrase)
        self.assertFalse(resp[0])
        self.assertIsNone(resp[1])

    def test_bad_language(self):
        '''
        checks coarse language. Will return tuple (True, coarse_word)
        '''
        test_phrase = "What the heck is this?"
        resp = language_check(test_phrase)
        self.assertTrue(resp[0])
        self.assertEqual(resp[1], 'heck')

    def test_bad_language_mixed_capitalization(self):
        '''
        mixed capitalization on coarse word
        '''
        test_phrase = "Crap I forgot"
        resp = language_check(test_phrase)
        self.assertTrue(resp[0])
        self.assertEqual(resp[1], 'crap')

    def test_bad_language_mixed_punctuation(self):
        '''
        use of punctuation with coarse word
        '''
        test_phrase = 'CrI!Mi..nY??'
        resp = language_check(test_phrase)
        self.assertTrue(resp[0])
        self.assertEqual(resp[1], 'criminy')


import re

def process_bag_rules(rules):

    to_remove = re.compile(r"(bag)(s{0,1})|\.") # removes bag, bags, and '.'

    rule_dict = {}
    for rule in rules:
        stripped_rule = to_remove.sub('', rule)
        outer_bag, inner_bags_string = stripped_rule.split("contain")
        outer_bag = outer_bag.strip()

        inner_bag_list = [inner_bag.strip() for inner_bag in inner_bags_string.split(",")]
        inner_bag_dict = {}
        for inner_bag in inner_bag_list:
            bag_count = inner_bag.split()[0]
            bag_type = inner_bag.split(bag_count)[1].strip()

            if bag_count == "no":
                bag_count = '0'

            inner_bag_dict.update({bag_type: int(bag_count)})

        rule_dict.update({outer_bag: inner_bag_dict})
    return(rule_dict)

def check_inner_bags(rule_dict, outer_bag):
    shiny_gold_bag_count = 0
    for inner_bag in rule_dict[outer_bag].keys():
        if inner_bag == "shiny gold":
            shiny_gold_bag_count += 1
            return(shiny_gold_bag_count)
        elif inner_bag == "other":
            continue
        else:
            shiny_gold_bag_count += check_inner_bags(rule_dict, inner_bag)

    # we only care about whether the outermost bags can EVENTUALLY get a shiny gold, not how many variations of shiny
    # gold there are in total
    if shiny_gold_bag_count > 1:
        shiny_gold_bag_count = 1
    return(shiny_gold_bag_count)

def count_shiny_gold_bag_options(rule_dict):
    shiny_gold_options_count = 0

    for outer_bag in rule_dict.keys():
        shiny_gold_options_count += check_inner_bags(rule_dict, outer_bag)

    print(f'Part 1: {shiny_gold_options_count}')

    return()

def count_inner_bags(rule_dict, outer_bag):
    internal_bag_count = 0

    for inner_bag_type, bag_count in rule_dict[outer_bag].items():
        if inner_bag_type == "other":
            continue
        else:
            # print(f'{inner_bag_type}: {bag_count}')

            # we need to add the bag itself plus all internal bags
            internal_bag_count += bag_count + (bag_count * count_inner_bags(rule_dict, inner_bag_type))
    return(internal_bag_count)

def count_bags_in_shiny_bag(rule_dict):

    internal_bag_count = 0
    if "shiny gold" in rule_dict.keys():
        internal_bag_count = count_inner_bags(rule_dict, "shiny gold")

    print(f'Part 2: {internal_bag_count}')
    return()

def main():

    lines = []
    # with open("./day07/example.txt", 'r') as infile:
    with open("./day07/input.txt", 'r') as infile:
        lines = infile.read().splitlines()

    rule_dict = process_bag_rules(lines)
    count_shiny_gold_bag_options(rule_dict)

    count_bags_in_shiny_bag(rule_dict)

    return()

if __name__ == "__main__":
    main()


# coding: utf-8

'''Converts bookmarklets in src/.

Python >= 3.5 is required.
'''

from pathlib import Path
import subprocess

def main():
    cd = Path('.')
    dir_src = cd / 'src'
    dir_dist = cd / 'dist'

    make_dir_if_not_exists(dir_dist)
    run_conversion(get_conversion_list(dir_src, dir_dist))

def make_dir_if_not_exists(dir: Path):
    if not dir.is_dir():
        dir.mkdir(0o744)

def get_conversion_list(dir_src: Path, dir_dist) -> list:
    pairs = []
    for file in dir_src.iterdir():
        if file.is_file() and file.suffix == '.js':
            file_converted = get_converted_name(file, dir_dist)
            pairs.append((str(file), file_converted))

    return pairs

def run_conversion(conversion_list: list):
    cmd = 'node_modules/.bin/bookmarklet'
    for original, converted in conversion_list:
        subprocess.run([cmd, original, converted])
        print('converted: {} -> {}'.format(original, converted))

def get_converted_name(original: Path, dir_dist: Path) -> str:
    name_dist = original.with_suffix('.txt').name
    return str(dir_dist / name_dist)

if __name__ == '__main__':
    main()


# coding=utf-8
import os
import datetime
import time
from speech.metric.wer import wer as wer_calculation

from speech_pb2 import CLMInputUnit, CLMInput, SpeechInput
from asr_component.speech_service import SpeechService
import sys
from plugins.octbit import octbit_mat_mul

MAX_ERROR_RATE = 10000
VER = sys.version[0]

if __name__ == '__main__':
    import argparse

    from asr_component.service_parser import parser, pinyin_dict
    parser.add_argument("-tc", "--circle_number", default=10, type=int)
    FLAGS = parser.parse_args()
    speech_service = SpeechService()
    speech_service.load_graph(FLAGS.speech_graph_pb_path,
                              py_dict=FLAGS.speech_pinyin_dict)

    id_ = "octbit.wav"
    if VER == '2':
        audio_data = open(id_, 'r').read()
    else:
        audio_data = open(id_, "r", encoding="latin-1").read()
    sinputs = []
    sinputs.append(audio_data)
    start_time = time.time()
    context = ""
    for i in range(FLAGS.circle_number):
        for speech_output in speech_service.SpeechRecognize([
                SpeechInput(sinput=sinputs[0],
                            error_code=-1,
                            contactJson="")],
                context):
            pass
    print(time.time() - start_time)