from base64 import urlsafe_b64encode as base64url
from configparser import ConfigParser, NoOptionError, NoSectionError
from time import sleep
import logging
import sys
from pyrogram import Client, errors
from pyrogram.raw import base, functions, types
from pyrogram.session import Session, Auth
from qrcode import QRCode
import os
from subprocess import call

logging.basicConfig(level=logging.INFO)
cfg = ConfigParser()
cfg.read("config.ini")
qr = QRCode()

try:
    APP_ID = cfg.getint("pyrogram", "api_id")
    APP_HASH = cfg.get("pyrogram", "api_hash")
except (NoOptionError, NoSectionError):
    sys.exit(print('fill in configs before making the session.'))

app = Client(sys.argv[1])
app.connect()
app.initialize()
nearest = app.send(functions.help.GetNearestDc())

ACCEPTED = False

def clear_screen():
    call(['cls' if os.name == 'nt' else 'clear'], shell=True)

@app.on_raw_update()
async def raw_handler(client: Client, update: base.Update,  users: list, chats: list):
    global ACCEPTED
    if isinstance(update, types.auth.LoginToken):
        if nearest.nearest_dc != await client.storage.dc_id():
            await check_session(client, dc_id=nearest.nearest_dc)
    if isinstance(update, types.UpdateLoginToken):
        ACCEPTED = True
        try:
            r = await app.send(
                functions.auth.ExportLoginToken(
                    api_id=APP_ID, api_hash=APP_HASH, except_ids=[]
                )
            )
        except errors.exceptions.unauthorized_401.SessionPasswordNeeded as err:
            print(err)
            await app.check_password(input("2FA Password: "))
            r = await app.send(
                functions.auth.ExportLoginToken(
                    api_id=APP_ID, api_hash=APP_HASH, except_ids=[]
                )
            )
        if isinstance(r, types.auth.LoginTokenSuccess):
            me = (await app.get_me()).username
            sys.exit(print(f"Generated session for {me}\n\ quitting..."))
        elif isinstance(r, types.auth.LoginTokenMigrateTo):
            await check_session(app, dc_id=r.dc_id)
            r = await app.send(
                    functions.auth.ExportLoginToken(
                        api_id=APP_ID, api_hash=APP_HASH, except_ids=[]
                    )
                )
            if isinstance(r, types.auth.LoginToken):
                clear_screen()
                print('Auth DC Mismatched! please delete the last session and try again')
                _gen_qr(r.token)
                sleep(30)

async def check_session(
    client: Client,
    dc_id:int
):
    await client.session.stop()
    await client.storage.dc_id(dc_id)
    await client.storage.auth_key(
        await Auth(
            client, await client.storage.dc_id(),
            await client.storage.test_mode()
        ).create()
    )
    client.session = Session(
        client, await client.storage.dc_id(),
        await client.storage.auth_key(), await client.storage.test_mode()
    )
    return await client.session.start()

def create_qrcodes():
    while True:
        clear_screen()
        print(
            'Scan the QR code below:'
        )
        print(
            'Settings > Privacy and Security > Active Sessions > Scan QR Code'
        )
        if ACCEPTED:
            break
        r = app.send(
            functions.auth.ExportLoginToken(
                api_id=APP_ID, api_hash=APP_HASH, except_ids=[]
            )
        )
        if isinstance(r, types.auth.LoginToken):
            _gen_qr(r.token)
            sleep(30)

def _gen_qr(token:bytes):
    token = base64url(token).decode("utf8")
    login_url = "tg://login?token=" + token
    qr.clear()
    qr.add_data(login_url)
    qr.print_ascii()


def findMIssingPositive(arr):
    size = len(arr)
    for x in arr:
        print(arr)
        if abs(x) - 1 < size and arr[abs(x) - 1] > 0:
            arr[abs(x) - 1] *= -1
    for i in range(size):
        if arr[i] > 0:
            return i + 1
    return size + 1

print(findMIssingPositive([1, 2, 1, 9, 10]))


import sys
import os

parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, parentdir)

import time
from chardev.udpchardev import UdpCharDev
from F4Kernel.f4kerneliapdev import CF4KernelIapDev

try:
    with open('..\\User\\ipconfig.json', 'r') as f:
        data = json.load(f)
        f.close()
    F4K_ip = data['inet addr']

except:
    F4K_ip = '192.168.192.7'
    # F4K_ip = '127.0.0.1'

def read():
    BOOTLOADER_START_ADDR = 0x08000000
    BOOTPARAM_ADDR = 0x0800C000
    IAP_UDP_PORT = 5000
    APP_START_ADDR = 0x08010000

    chardev = UdpCharDev((F4K_ip, 15003), (F4K_ip, IAP_UDP_PORT))
    udpIapDev = CF4KernelIapDev(chardev)
    udpIapDev.settargetboardbootloader()
    FWV = udpIapDev.getbootloaderversion()
    if(FWV == 0x01):
        return 0x01
    udpIapDev.readbin(time.strftime('SRC1100%Y%m%d-%H_%M_%S')+'_readback.sc.bin',APP_START_ADDR)
    udpIapDev.restorebootparam(BOOTPARAM_ADDR)
    udpIapDev.jumpToAddress(APP_START_ADDR)
    udpIapDev.resetforwardmode()
    time.sleep(1)
    sys.exit(0)


import numpy as np
import cv2

'''
@NB
    Thresholding helps us in simplifying our picture, e.g. by applying a threshold to a grayscale picture and thus
    converting every value below 125 to 0 and above to 1 respectively. For colored images the threshold is applied
    to every channel independently

@NB
    Thresholding: https://docs.opencv.org/master/d7/d4d/tutorial_py_thresholding.html

@NB
    Blurs and Filters: https://www.youtube.com/watch?v=C_zFhWdM4ic&list=PLhhhoPkZzWjZlXDz7AeIl4HfyGMPlsWK7&index=11
    ED: https://www.youtube.com/watch?v=uihBwtPIBxM&list=PLhhhoPkZzWjZlXDz7AeIl4HfyGMPlsWK7&index=13 (Sobel)
    Impl: https://pythonprogramming.net/thresholding-image-analysis-python-opencv-tutorial/
'''

cap = cv2.VideoCapture(0)
mode = 0
while(True):
    # Capture frame-by-frame
    ret, frame = cap.read()

    # wait for key and switch to mode
    ch = cv2.waitKey(1) & 0xFF

    if ch == ord('1'):
        mode = 1
        # HSV

    if ch == ord('2'):
        mode = 2
        # LAB

    if ch == ord('3'):
        mode = 3
        # YUV

    if ch == ord('4'):
        mode = 4
        # Canny Edge Detection (the easy way)

    if ch == ord('5'):
        # Thresholding Gaussian
        mode = 5

    if ch == ord('6'):
        # Thresholding Otsu
        mode = 6

    if ch == ord('q'):
        break

    '''
        Modes Implementation
    '''

    if mode == 1:
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

        # look for certain colored objects
        # define lower and upper thresholds for blue colors
        lower_blue = np.array([110, 50, 50])
        upper_blue = np.array([130, 255, 255])

        # inRange checks if elements of the array lie between the elements of our boundaries
        mask = cv2.inRange(frame, lower_blue, upper_blue)
        # use the mask to filter only for blue(ish) objects
        res = cv2.bitwise_and(frame, frame, mask = mask)

    if mode == 2:
        # LAB
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2LAB)

    if mode == 3:
        # YUF
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2YUV)

    if mode == 4:
        # Canny Edge
        frame = cv2.Canny(frame, 100, 200, L2gradient = True)

    if mode == 5:
        # Thresholding Gaussian, 255 max value, either-or threshold, 11 block size
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        frame = cv2.adaptiveThreshold(frame, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 1, 1)

    if mode == 6:
        # Thresholding Otsu, 255 max value, either-or threshold
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        retval, frame = cv2.threshold(frame, 125, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
        #cv2.imshow('threshold', threshold)
    # Display the resulting frame
    cv2.imshow('frame', frame)

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()


'''
Author: Ruizhi Liao

Main script to run evaluation
'''

import os
import argparse
import logging
import json

import torch

from resnet_chestxray.main_utils import ModelManager, build_model

current_dir = os.path.dirname(__file__)

parser = argparse.ArgumentParser()
parser.add_argument('--batch_size', default=64, type=int,
                                        help='Mini-batch size')

parser.add_argument('--label_key', default='delta_bnp', type=str,
                                        help='The label key/classification task')

parser.add_argument('--img_size', default=256, type=int,
                    help='The size of the input image')
parser.add_argument('--output_channels', default=4, type=int,
                    help='The number of ouput channels')
parser.add_argument('--model_architecture', default='resnet256_6_2_1', type=str,
                    help='Neural network architecture to be used')

parser.add_argument('--data_dir', type=str,
                                        default='/data/vision/polina/scratch/ruizhi/chestxray/data/png_16bit_256/',
                                        help='The image data directory')
parser.add_argument('--model_type', type=str,default='delta_change',
                   help='The directory for data. delta_change, percent_change, 2_class, 4_class')

# parser.add_argument('--dataset_metadata', type=str,
#                                         default=os.path.join(current_dir, 'data/test_edema.csv'),
#                                         help='The metadata for the model training ')
parser.add_argument('--save_dir', type=str, default = '/data/vision/polina/projects/chestxray/ading/resnet_chestxray_experiments')
#                                       default='/data/vision/polina/scratch/ruizhi/chestxray/experiments/supervised_image/'\
#                                        'tmp_postmiccai_v2/')
parser.add_argument('--checkpoint_name', type=str,
                                        default='pytorch_model_epoch300.bin')

parser.add_argument('--model_size', type = str, default='large', help='The size of the model')

# parser.add_argument('--train_data', dest = 'train', action='store_true')

# parser.add_argument('--eval_data', dest = 'train', action='store_false')

# parser.set_defaults(train=False)

def eval(all_epochs=-1):
        args = parser.parse_args()

        args.dataset_metadata = os.path.join(current_dir, 'data/48h_window', args.model_type, 'bnp_test.csv')

        args.save_dir = '/data/vision/polina/projects/chestxray/ading/resnet_chestxray_experiments/' + args.model_type + '/48h_window'
#         args.dataset_metadata = os.path.join(current_dir, 'data/48h_window', args.model_type+'_adj', 'bnp_test.csv')

#         args.save_dir = '/data/vision/polina/projects/chestxray/ading/resnet_chestxray_experiments/' + args.model_type + '/48h_window/adj'

        if args.model_size == 'small':
            args.model_architecture = args.model_architecture + "_small"

        if args.model_type == 'delta_change' or args.model_type =='percent_change':
            args.train_type = 'regression'
            args.output_channels = 1
        else:
            args.train_type = 'classification'
            if args.model_type == '2_class':
                args.output_channels = 2
            elif args.model_type=='3_class':
                args.output_channels = 3
            else:
                args.output_channels = 4

        print(args)

        '''
        Check cuda
        '''
        device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
        assert torch.cuda.is_available(), "No GPU/CUDA is detected!"

        '''
        Create a sub-directory under save_dir
        based on the label key
        '''
        args.save_dir = os.path.join(args.save_dir, args.model_architecture+'_'+args.label_key)

        checkpoint_path = os.path.join(args.save_dir, args.checkpoint_name)

        model_manager = ModelManager(model_name=args.model_architecture,
                                     img_size=args.img_size,
                                     save_dir = args.save_dir,
                                     output_channels=args.output_channels)
        inference_results, eval_results= model_manager.eval(device=device,
                                                                                args=args,
                                                                                checkpoint_path=checkpoint_path)

        print(f"{checkpoint_path} evaluation results: {eval_results}")

        '''
        Evaluate on all epochs if all_epochs>0
        '''
        if all_epochs>0:
                aucs_all_epochs = []
                for epoch in range(all_epochs):
                        args.checkpoint_name = f'pytorch_model_epoch{epoch+1}.bin'
                        checkpoint_path = os.path.join(args.save_dir, args.checkpoint_name)
                        model_manager = ModelManager(model_name=args.model_architecture,
                                                                                img_size=args.img_size,
                                                                                output_channels=args.output_channels)
                        inference_results, eval_results= model_manager.eval(device=device,
                                                                                args=args,
                                                                                checkpoint_path=checkpoint_path)
                        if args.label_key == 'edema_severity':
                                aucs_all_epochs.append(eval_results['ordinal_aucs'])
                        else:
                                aucs_all_epochs.append(eval_results['aucs'][0])

                print(f"All epochs AUCs: {aucs_all_epochs}")

                eval_results_all={}
                eval_results_all['ordinal_aucs']=aucs_all_epochs
                results_path = os.path.join(args.save_dir, 'eval_results_all.json')
                with open(results_path, 'w') as fp:
                        json.dump(eval_results_all, fp)

eval(all_epochs=-1)


import requests

class BlinkTradeApi:
    def __init__(self, currency, crypto_currency):
        self.currency = currency
        self.crypto_currency = crypto_currency
        self.api_url = "https://api.blinktrade.com/api/v1/%s/ticker?crypto_currency=%s" % (currency, crypto_currency)
    def get_last_status(self):
        resp = requests.get(self.api_url)
        return resp.json()
    def get_buylow_variance(self):
        result = self.get_last_status()
        high = float(result["high"])
        low = float(result["low"])
        buy = float(result["buy"])

        variance = (buy / low - 1) * 100

        return variance


"""
# Employee info
class Employee:
    def __init__(self, id: int, importance: int, subordinates: List[int]):
        # It's the unique id of each node.
        # unique id of this employee
        self.id = id
        # the importance value of this employee
        self.importance = importance
        # the id of direct subordinates
        self.subordinates = subordinates
"""

class Solution:
    def getImportance(self, employees: List['Employee'], id: int) -> int:
        if not employees:
            return 0

        employee_importance = {}
        employee_subordinates = {}

        # creating a hash-map of the form id: importance and id: [sub...]
        for employee in employees:
            employee_importance[employee.id] = employee.importance
            employee_subordinates[employee.id] = employee.subordinates

        # finding the total importance using bfs
        total = 0
        stack = [id]
        while stack:
            current_vertex = stack.pop()
            total += employee_importance[current_vertex]

            for sub_id in employee_subordinates[current_vertex]:
                stack.append(sub_id)

        return total


#! /usr/bin/python -u

import os
import sys
import time
import click
import urllib
import syslog
import subprocess
from swsssdk import SonicV2Connector

from .bootloader import get_bootloader
from .common import run_command

#
# Helper functions
#

_start_time = None
_last_time = None
def reporthook(count, block_size, total_size):
    global _start_time, _last_time
    cur_time = int(time.time())
    if count == 0:
        _start_time = cur_time
        _last_time = cur_time
        return

    if cur_time == _last_time:
        return

    _last_time = cur_time

    duration = cur_time - _start_time
    progress_size = int(count * block_size)
    speed = int(progress_size / (1024 * duration))
    percent = int(count * block_size * 100 / total_size)
    time_left = (total_size - progress_size) / speed / 1024
    sys.stdout.write("\r...%d%%, %d MB, %d KB/s, %d seconds left...   " %
                                  (percent, progress_size / (1024 * 1024), speed, time_left))
    sys.stdout.flush()

# TODO: Embed tag name info into docker image meta data at build time,
# and extract tag name from docker image file.
def get_docker_tag_name(image):
    # Try to get tag name from label metadata
    cmd = "docker inspect --format '{{.ContainerConfig.Labels.Tag}}' " + image
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
    (out, _) = proc.communicate()
    if proc.returncode != 0:
        return "unknown"
    tag = out.rstrip()
    if tag == "<no value>":
        return "unknown"
    return tag

# Function which validates whether a given URL specifies an existent file
# on a reachable remote machine. Will abort the current operation if not
def validate_url_or_abort(url):
    # Attempt to retrieve HTTP response code
    try:
        urlfile = urllib.urlopen(url)
        response_code = urlfile.getcode()
        urlfile.close()
    except IOError:
        response_code = None

    if not response_code:
        click.echo("Did not receive a response from remote machine. Aborting...")
        raise click.Abort()
    else:
        # Check for a 4xx response code which indicates a nonexistent URL
        if response_code / 100 == 4:
            click.echo("Image file not found on remote machine. Aborting...")
            raise click.Abort()

# Callback for confirmation prompt. Aborts if user enters "n"
def abort_if_false(ctx, param, value):
    if not value:
        ctx.abort()

def get_container_image_name(container_name):
    # example image: docker-lldp-sv2:latest
    cmd = "docker inspect --format '{{.Config.Image}}' " + container_name
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
    (out, _) = proc.communicate()
    if proc.returncode != 0:
        sys.exit(proc.returncode)
    image_latest = out.rstrip()

    # example image_name: docker-lldp-sv2
    cmd = "echo " + image_latest + " | cut -d ':' -f 1"
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
    image_name = proc.stdout.read().rstrip()
    return image_name

def get_container_image_id(image_tag):
    # TODO: extract commond docker info fetching functions
    # this is image_id for image with tag, like 'docker-teamd:latest'
    cmd = "docker images --format '{{.ID}}' " + image_tag
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
    image_id = proc.stdout.read().rstrip()
    return image_id

def get_container_image_id_all(image_name):
    # All images id under the image name like 'docker-teamd'
    cmd = "docker images --format '{{.ID}}' " + image_name
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
    image_id_all = proc.stdout.read()
    image_id_all = image_id_all.splitlines()
    image_id_all = set(image_id_all)
    return image_id_all

def hget_warm_restart_table(db_name, table_name, warm_app_name, key):
    db = SonicV2Connector()
    db.connect(db_name, False)
    _hash = table_name + db.get_db_separator(db_name) + warm_app_name
    client = db.get_redis_client(db_name)
    return client.hget(_hash, key)

def hdel_warm_restart_table(db_name, table_name, warm_app_name, key):
    db = SonicV2Connector()
    db.connect(db_name, False)
    _hash = table_name + db.get_db_separator(db_name) + warm_app_name
    client = db.get_redis_client(db_name)
    return  client.hdel(_hash, key)

# Main entrypoint
@click.group()
def cli():
    """ SONiC image installation manager """
    if os.geteuid() != 0:
        exit("Root privileges required for this operation")

# Install image
@cli.command()
@click.option('-y', '--yes', is_flag=True, callback=abort_if_false,
        expose_value=False, prompt='New image will be installed, continue?')
@click.option('-f', '--force', is_flag=True,
        help="Force installation of an image of a type which differs from that of the current running image")
@click.option('--skip_migration', is_flag=True,
        help="Do not migrate current configuration to the newly installed image")
@click.argument('url')
def install(url, force, skip_migration=False):
    """ Install image from local binary or URL"""
    bootloader = get_bootloader()

    if url.startswith('http://') or url.startswith('https://'):
        click.echo('Downloading image...')
        validate_url_or_abort(url)
        try:
            urllib.urlretrieve(url, bootloader.DEFAULT_IMAGE_PATH, reporthook)
            click.echo('')
        except Exception as e:
            click.echo("Download error", e)
            raise click.Abort()
        image_path = bootloader.DEFAULT_IMAGE_PATH
    else:
        image_path = os.path.join("./", url)

    binary_image_version = bootloader.get_binary_image_version(image_path)
    if not binary_image_version:
        click.echo("Image file does not exist or is not a valid SONiC image file")
        raise click.Abort()

    # Is this version already installed?
    if binary_image_version in bootloader.get_installed_images():
        click.echo("Image {} is already installed. Setting it as default...".format(binary_image_version))
        if not bootloader.set_default_image(binary_image_version):
            click.echo('Error: Failed to set image as default')
            raise click.Abort()
    else:
        # Verify that the binary image is of the same type as the running image
        if not bootloader.verify_binary_image(image_path) and not force:
            click.echo("Image file '{}' is of a different type than running image.\n"
                       "If you are sure you want to install this image, use -f|--force.\n"
                       "Aborting...".format(image_path))
            raise click.Abort()

        click.echo("Installing image {} and setting it as default...".format(binary_image_version))
        bootloader.install_image(image_path)
        # Take a backup of current configuration
        if skip_migration:
            click.echo("Skipping configuration migration as requested in the command option.")
        else:
            run_command('config-setup backup')

    # Finally, sync filesystem
    run_command("sync;sync;sync")
    run_command("sleep 3") # wait 3 seconds after sync
    click.echo('Done')

# List installed images
@cli.command('list')
def list_command():
    """ Print installed images """
    bootloader = get_bootloader()
    images = bootloader.get_installed_images()
    curimage = bootloader.get_current_image()
    nextimage = bootloader.get_next_image()
    click.echo("Current: " + curimage)
    click.echo("Next: " + nextimage)
    click.echo("Available: ")
    for image in images:
        click.echo(image)

# Set default image for boot
@cli.command('set_default')
@click.argument('image')
def set_default(image):
    """ Choose image to boot from by default """
    bootloader = get_bootloader()
    if image not in bootloader.get_installed_images():
        click.echo('Error: Image does not exist')
        raise click.Abort()
    bootloader.set_default_image(image)

# Set image for next boot
@cli.command('set_next_boot')
@click.argument('image')
def set_next_boot(image):
    """ Choose image for next reboot (one time action) """
    bootloader = get_bootloader()
    if image not in bootloader.get_installed_images():
        click.echo('Error: Image does not exist')
        sys.exit(1)
    bootloader.set_next_image(image)

# Uninstall image
@cli.command()
@click.option('-y', '--yes', is_flag=True, callback=abort_if_false,
        expose_value=False, prompt='Image will be removed, continue?')
@click.argument('image')
def remove(image):
    """ Uninstall image """
    bootloader = get_bootloader()
    images = bootloader.get_installed_images()
    current = bootloader.get_current_image()
    if image not in images:
        click.echo('Image does not exist')
        sys.exit(1)
    if image == current:
        click.echo('Cannot remove current image')
        sys.exit(1)
    # TODO: check if image is next boot or default boot and fix these
    bootloader.remove_image(image)

# Retrieve version from binary image file and print to screen
@cli.command('binary_version')
@click.argument('binary_image_path')
def binary_version(binary_image_path):
    """ Get version from local binary image file """
    bootloader = get_bootloader()
    version = bootloader.get_binary_image_version(binary_image_path)
    if not version:
        click.echo("Image file does not exist or is not a valid SONiC image file")
        sys.exit(1)
    else:
        click.echo(version)

# Remove installed images which are not current and next
@cli.command()
@click.option('-y', '--yes', is_flag=True, callback=abort_if_false,
        expose_value=False, prompt='Remove images which are not current and next, continue?')
def cleanup():
    """ Remove installed images which are not current and next """
    bootloader = get_bootloader()
    images = bootloader.get_installed_images()
    curimage = bootloader.get_current_image()
    nextimage = bootloader.get_next_image()
    image_removed = 0
    for image in images:
        if image != curimage and image != nextimage:
            click.echo("Removing image %s" % image)
            bootloader.remove_image(image)
            image_removed += 1

    if image_removed == 0:
        click.echo("No image(s) to remove")

# Upgrade docker image
@cli.command('upgrade_docker')
@click.option('-y', '--yes', is_flag=True, callback=abort_if_false,
        expose_value=False, prompt='New docker image will be installed, continue?')
@click.option('--cleanup_image', is_flag=True, help="Clean up old docker image")
@click.option('--skip_check', is_flag=True, help="Skip task check for docker upgrade")
@click.option('--tag', type=str, help="Tag for the new docker image")
@click.option('--warm', is_flag=True, help="Perform warm upgrade")
@click.argument('container_name', metavar='<container_name>', required=True,
    type=click.Choice(["swss", "snmp", "lldp", "bgp", "pmon", "dhcp_relay", "telemetry", "teamd", "radv", "amon", "sflow"]))
@click.argument('url')
def upgrade_docker(container_name, url, cleanup_image, skip_check, tag, warm):
    """ Upgrade docker image from local binary or URL"""

    image_name = get_container_image_name(container_name)
    image_latest = image_name + ":latest"
    image_id_previous = get_container_image_id(image_latest)

    DEFAULT_IMAGE_PATH = os.path.join("/tmp/", image_name)
    if url.startswith('http://') or url.startswith('https://'):
        click.echo('Downloading image...')
        validate_url_or_abort(url)
        try:
            urllib.urlretrieve(url, DEFAULT_IMAGE_PATH, reporthook)
        except Exception as e:
            click.echo("Download error", e)
            raise click.Abort()
        image_path = DEFAULT_IMAGE_PATH
    else:
        image_path = os.path.join("./", url)

    # Verify that the local file exists and is a regular file
    # TODO: Verify the file is a *proper Docker image file*
    if not os.path.isfile(image_path):
        click.echo("Image file '{}' does not exist or is not a regular file. Aborting...".format(image_path))
        raise click.Abort()

    warm_configured = False
    # warm restart enable/disable config is put in stateDB, not persistent across cold reboot, not saved to config_DB.json file
    state_db = SonicV2Connector(host='127.0.0.1')
    state_db.connect(state_db.STATE_DB, False)
    TABLE_NAME_SEPARATOR = '|'
    prefix = 'WARM_RESTART_ENABLE_TABLE' + TABLE_NAME_SEPARATOR
    _hash = '{}{}'.format(prefix, container_name)
    if state_db.get(state_db.STATE_DB, _hash, "enable") == "true":
        warm_configured = True
    state_db.close(state_db.STATE_DB)

    if container_name == "swss" or container_name == "bgp" or container_name == "teamd":
        if warm_configured == False and warm:
           run_command("config warm_restart enable %s" % container_name)

    # Fetch tag of current running image
    tag_previous = get_docker_tag_name(image_latest)
    # Load the new image beforehand to shorten disruption time
    run_command("docker load < %s" % image_path)
    warm_app_names = []
    # warm restart specific procssing for swss, bgp and teamd dockers.
    if warm_configured == True or warm:
        # make sure orchagent is in clean state if swss is to be upgraded
        if container_name == "swss":
            skipPendingTaskCheck = ""
            if skip_check:
                skipPendingTaskCheck = " -s"

            cmd = "docker exec -i swss orchagent_restart_check -w 2000 -r 5 " + skipPendingTaskCheck

            proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
            (out, err) = proc.communicate()
            if proc.returncode != 0:
                if not skip_check:
                    click.echo("Orchagent is not in clean state, RESTARTCHECK failed")
                    # Restore orignal config before exit
                    if warm_configured == False and warm:
                        run_command("config warm_restart disable %s" % container_name)
                    # Clean the image loaded earlier
                    image_id_latest = get_container_image_id(image_latest)
                    run_command("docker rmi -f %s" % image_id_latest)
                    # Re-point latest tag to previous tag
                    run_command("docker tag %s:%s %s" % (image_name, tag_previous, image_latest))

                    sys.exit(proc.returncode)
                else:
                    click.echo("Orchagent is not in clean state, upgrading it anyway")
            else:
                click.echo("Orchagent is in clean state and frozen for warm upgrade")

            warm_app_names = ["orchagent", "neighsyncd"]

        elif container_name == "bgp":
            # Kill bgpd to restart the bgp graceful restart procedure
            click.echo("Stopping bgp ...")
            run_command("docker exec -i bgp pkill -9 zebra")
            run_command("docker exec -i bgp pkill -9 bgpd")
            warm_app_names = ["bgp"]
            click.echo("Stopped  bgp ...")

        elif container_name == "teamd":
            click.echo("Stopping teamd ...")
            # Send USR1 signal to all teamd instances to stop them
            # It will prepare teamd for warm-reboot
            run_command("docker exec -i teamd pkill -USR1 teamd > /dev/null")
            warm_app_names = ["teamsyncd"]
            click.echo("Stopped  teamd ...")

        # clean app reconcilation state from last warm start if exists
        for warm_app_name in warm_app_names:
            hdel_warm_restart_table("STATE_DB", "WARM_RESTART_TABLE", warm_app_name, "state")

    run_command("docker kill %s > /dev/null" % container_name)
    run_command("docker rm %s " % container_name)
    if tag is None:
        # example image: docker-lldp-sv2:latest
        tag = get_docker_tag_name(image_latest)
    run_command("docker tag %s:latest %s:%s" % (image_name, image_name, tag))
    run_command("systemctl restart %s" % container_name)

    # All images id under the image name
    image_id_all = get_container_image_id_all(image_name)

    # this is image_id for image with "latest" tag
    image_id_latest = get_container_image_id(image_latest)

    for id in image_id_all:
        if id != image_id_latest:
            # Unless requested, the previoud docker image will be preserved
            if not cleanup_image and id == image_id_previous:
                continue
            run_command("docker rmi -f %s" % id)

    exp_state = "reconciled"
    state = ""
    # post warm restart specific procssing for swss, bgp and teamd dockers, wait for reconciliation state.
    if warm_configured == True or warm:
        count = 0
        for warm_app_name in warm_app_names:
            state = ""
            # Wait up to 180 seconds for reconciled state
            while state != exp_state and count < 90:
                sys.stdout.write("\r  {}: ".format(warm_app_name))
                sys.stdout.write("[%-s" % ('='*count))
                sys.stdout.flush()
                count += 1
                time.sleep(2)
                state = hget_warm_restart_table("STATE_DB", "WARM_RESTART_TABLE", warm_app_name, "state")
                syslog.syslog("%s reached %s state"%(warm_app_name, state))
            sys.stdout.write("]\n\r")
            if state != exp_state:
                click.echo("%s failed to reach %s state"%(warm_app_name, exp_state))
                syslog.syslog(syslog.LOG_ERR, "%s failed to reach %s state"%(warm_app_name, exp_state))
    else:
        exp_state = ""  # this is cold upgrade

    # Restore to previous cold restart setting
    if warm_configured == False and warm:
        if container_name == "swss" or container_name == "bgp" or container_name == "teamd":
            run_command("config warm_restart disable %s" % container_name)

    if state == exp_state:
        click.echo('Done')
    else:
        click.echo('Failed')
        sys.exit(1)

# rollback docker image
@cli.command('rollback_docker')
@click.option('-y', '--yes', is_flag=True, callback=abort_if_false,
        expose_value=False, prompt='Docker image will be rolled back, continue?')
@click.argument('container_name', metavar='<container_name>', required=True,
    type=click.Choice(["swss", "snmp", "lldp", "bgp", "pmon", "dhcp_relay", "telemetry", "teamd", "radv", "amon", "sflow"]))
def rollback_docker(container_name):
    """ Rollback docker image to previous version"""
    image_name = get_container_image_name(container_name)
    # All images id under the image name
    image_id_all = get_container_image_id_all(image_name)
    if len(image_id_all) != 2:
        click.echo("Two images required, but there are '{}' images for '{}'. Aborting...".format(len(image_id_all), image_name))
        raise click.Abort()

    image_latest = image_name + ":latest"
    image_id_previous = get_container_image_id(image_latest)

    version_tag = ""
    for id in image_id_all:
        if id != image_id_previous:
            version_tag = get_docker_tag_name(id)

    # make previous image as latest
    run_command("docker tag %s:%s %s:latest" % (image_name, version_tag, image_name))
    if container_name == "swss" or container_name == "bgp" or container_name == "teamd":
        click.echo("Cold reboot is required to restore system state after '{}' rollback !!".format(container_name))
    else:
        run_command("systemctl restart %s" % container_name)

    click.echo('Done')

if __name__ == '__main__':
    cli()


import os
import shutil
import numpy as np
import cv2
import re
import pickle
import random
import time
from tqdm import tqdm
import pandas as pd
from glob import glob
from xml.etree.ElementTree import parse
# from pascal_voc_writer import Writer
import matplotlib.pyplot as plt

'''
    Condition Configuration
'''
# 사용 안할 annotation 목록
rej_table = [
    '삭제', 'pulled pork', 'abnormal', 'dog',
    'ASCUS-RE',
    'ASCUS-Re',
    'ASCUS-SIL',
    'ASCwUS-SIL',
    'ASCUS-H',
    'ASC-H',

    'AGUS',
    'Reactive cell',
    'Reactive change',

    'cavity',
    'ASCUS-koilocyte',
    'Lymphocytes',
    'leukocyte',
    'Lymphocyte',
    'leukocytes',
]

# 기 작성된 annotation에서 학습하고자 하는 단위로 교체
replace_table = {
    'Normal-endocervical cells': 'Normal',
    'Normal-Autolytic parabasal cells': 'Normal',
    'Metaplastic cell-Nomal': 'Normal',
    'Normal-multi-nuclear cell': 'Normal',
    'Normal-metaplastic cell': 'Normal',
    'Normal-parabasal cell': 'Normal',
    'Normal-parabasal cells': 'Normal',
    'Normal-parabasal cells ': 'Normal',
    'Normal-Endocervical cell': 'Normal',
    'Endocervical cell-Normal': 'Normal',
    'Endocervical cell': 'Normal',
    'Endometrial cell': 'Normal',
    'Metaplastic cell': 'Normal',
    'Parabasal cell': 'Normal',
    'No malignant cell': 'Normal',
    'No nalignant cell': 'Normal',
    'No malinant cell': 'Normal',
    'No malignant cell-tissue repair': 'Normal',
    'No malignant cell-endocervical cell': 'Normal',
    'No malinant cell-endocervical cell': 'Normal',
    'No malignant cell-squamous metaplasia': 'Normal',
    'No maligant cell-parabasal cell': 'Normal',
    'No maligant cell-squamous metaplasia cell': 'Normal',
    'No maligant cell-endocervical cell': 'Normal',
    'No malignant cell-Squamous metaplastic cell': 'Normal',
    'No maligant cell-squamous metaplastic cell': 'Normal',
    'No malignant cell-metaplastic cell': 'Normal',

    'No malignant cell-Parabasal cell': 'Normal',
    'No malignant cell-parabasal cell': 'Normal',
    'No malinant cell-parabasal cell': 'Normal',
    'Autolytic parabasal cell': 'Normal',

    'normal': 'Normal',
    'ASCUS-US': 'ASCUS',

    'HSILw': 'HSIL',

    'Adenocarcinoma': 'Carcinoma',
    'Adenocarcinoma-endocervical type': 'Carcinoma',
    'Adenocarcinoma-endometrial type': 'Carcinoma',

    'Squamous metaplastic cell': 'Normal',

    'Squamous cell carcinomaw': 'Carcinoma',
    'Squamous cell carcinoma': 'Carcinoma',
    'Suamous cell carcinoma': 'Carcinoma',
    'Squamous cell carcinama': 'Carcinoma',

    #label to delete
    '삭제': '',
    'pulled pork':'',
    'abnormal':'',
    'dog':'',
    'ASCUS-RE':'',
    'ASCUS-Re':'',
    'ASCUS-SIL':'',
    'ASCwUS-SIL':'',
    'ASCUS-H':'',
    'ASC-H':'',

    'AGUS':'',
    'Reactive cell':'',
    'Reactive change':'',

    'cavity':'',
    'ASCUS-koilocyte':'',
    'Lymphocytes':'',
    'leukocyte':'',
    'Lymphocyte':'',
    'leukocytes':'',

    'Normal' : 'Normal',
    'ASCUS' : 'ASCUS',
    'HSIL' : 'HSIL',
    'Carcinoma' : 'Carcinoma',
    'LSIL' : 'LSIL',
    'Benign' : 'Benign',
}

class XMLParser():
    def __init__(self, file_path):
        self.file_name = ''
        self.width = 0
        self.height = 0
        self.objects = []
#         self.labels = []
        self.rejection_size = [(3024, 4032)]

        tree = parse(file_path)
        root = tree.getroot()

        self.file_name = root.find('filename').text
        self.width = int(root.find('size').find('width').text)
        self.height = int(root.find('size').find('height').text)

        objs = root.findall('object')
        for obj in objs:
            orgcls = obj.find('name').text
            cls = replace_table[orgcls]
            xmin = int(obj.find('bndbox').find('xmin').text)
            ymin = int(obj.find('bndbox').find('ymin').text)
            xmax = int(obj.find('bndbox').find('xmax').text)
            ymax = int(obj.find('bndbox').find('ymax').text)
            bbox = [xmin, ymin, xmax, ymax]

            self.objects.append([cls,orgcls, bbox, xmin, ymin, xmax, ymax])
#             self.objectsName.append([self.file_name, cls, bbox, xmin, ymin, xmax, ymax])
#             if cls not in self.labels :
#                 self.labels.append(cls)

def make_3class_label(text) :
    if text == 'Normal' or text == 'Benign' :
        return 'Negative'
    elif text =='ASCUS' :
        return 'Low-Risk'
    else :
        return 'High-Risk'


import numpy as np
import jieba

#读取停用词
def stopwordslist(filepath):
    stopwords = [line.strip() for line in open(filepath, 'r', encoding='utf-8').readlines()]
    return stopwords

# 加载停用词
stopwords = stopwordslist("停用词.txt")

def cosine_similarity(sentence1: str, sentence2: str) -> float:
    """
    :param sentence1:
    :param sentence2:
    :return: 两句文本的相识度
    """
    seg1 = [word for word in jieba.cut(sentence1) if word not in stopwords]
    seg2 = [word for word in jieba.cut(sentence2) if word not in stopwords]
    word_list = list(set([word for word in seg1 + seg2]))#建立词库
    word_count_vec_1 = []
    word_count_vec_2 = []
    for word in word_list:
        word_count_vec_1.append(seg1.count(word))#文本1统计在词典里出现词的次数
        word_count_vec_2.append(seg2.count(word))#文本2统计在词典里出现词的次数

    vec_1 = np.array(word_count_vec_1)
    vec_2 = np.array(word_count_vec_2)
    #余弦公式

    num = vec_1.dot(vec_2.T)
    denom = np.linalg.norm(vec_1) * np.linalg.norm(vec_2)
    cos = num / denom
    sim = 0.5 + 0.5 * cos

    return sim

str1="约翰偷了一辆自行车给玛丽"
str2="玛丽给约翰偷了自行车"
str3= "玛丽有一辆约翰给她偷的自行车"
sim1=cosine_similarity(str1,str2)
sim2=cosine_similarity(str1,str3)
print("sim1 ：",sim1)
print("sim2:",sim2)


# -*- encoding: utf-8 -*-
from __future__ import unicode_literals

from django.shortcuts import render, get_object_or_404
from django.template import RequestContext, loader
from django.utils import timezone
from django.core.exceptions import ObjectDoesNotExist

from oaipmh.datestamp import tolerant_datestamp_to_datetime
from oaipmh.error import DatestampError

from datetime import datetime

from oai.tasks import *
from oai.models import *
from oai.utils import to_kv_pairs, OaiRequestError
from oai.settings import *

def handleListQuery(request, context, queryType, parameters, offset=0):
    if queryType == 'ListRecords' or queryType == 'ListIdentifiers':
        matches = OaiRecord.objects.filter(**parameters)
    elif queryType == 'ListSets':
        matches = OaiSet.objects.all()
    else:
        raise OaiRequestError('badArgument', 'Illegal verb.')
    matches = list(matches[offset:(offset+RESULTS_LIMIT+1)])
    count = len(matches)
    # Should we create a resumption token?
    if count > RESULTS_LIMIT:
        token = createResumptionToken(queryType, parameters, offset+RESULTS_LIMIT, count)
        context['token'] = token
    context['matches'] = matches
    return render(request, 'oai/'+queryType+'.xml', context, content_type='text/xml')

def createResumptionToken(queryType, queryParameters, offset, totalCount):
    token = ResumptionToken(queryType=queryType, offset=offset,
            cursor=offset-RESULTS_LIMIT, total_count=totalCount)
    if 'format' in queryParameters:
        token.metadataPrefix = queryParameters['format']
    if 'timestamp__gte' in queryParameters:
        token.fro = queryParameters['timestamp__gte']
    if 'timestamp__lte' in queryParameters:
        token.until = queryParameters['timestamp__lte']
    if 'sets' in queryParameters:
        token.set = queryParameters['sets']
    token.save()
    token.genkey()
    return token

def resumeRequest(context, request, queryType, key):
    try:
        token = ResumptionToken.objects.get(queryType=queryType, key=key)
    except ObjectDoesNotExist:
        raise OaiRequestError('badResumptionToken', 'This resumption token is invalid: "'+key+'", "'+queryType+'"', context, request)
    parameters = dict()
    parameters['format'] = token.metadataPrefix
    if token.set:
        parameters['sets'] = token.set
    if token.fro:
        parameters['timestamp__gte'] = token.fro
    if token.until:
        parameters['timestamp__lte'] = token.until
    return handleListQuery(request, context, queryType, parameters, token.offset)


import numpy as np
import scipy.optimize
from scipy.optimize import curve_fit
import matplotlib.pyplot as plot
import uncertainties as unc
import uncertainties.unumpy as unp
from uncertainties import correlated_values, correlation_matrix
from uncertainties import ufloat
f, uc , a = np.genfromtxt('lin_resonanzkurve.txt', unpack=True)

#L(10.11e-3,0.03e-3)
#C(2.098e-9,0.006e-9)
#R1(48.1,0.1)
#R2(509.5,0.5)
#Rap(3.3e3)

#plt.plot(f, uc , 'b.', label="Kondensatorspannung")
#
#plt.xlabel(r'$Frequenz / Hz$')
#plt.ylabel(r'$Spannung / V$')
#
#errX=0.1
#errY=0.001
#plt.errorbar(f,uc,xerr=errX, yerr=errY,fmt='none')
#plt.tight_layout()
#plt.legend(loc='best')
#plt.savefig('Resonanzkurve.pdf')

def f(nu,  a_0, a_1,a_2):
    return (a_2 / np.sqrt((1 - a_0 * (nu/1000) ** 2) ** 2 + ((nu/1000) ** 2) * a_1))

x, z, a = np.genfromtxt('messwerte_phasenverschiebung.txt', unpack=True)
x=x*2*np.pi
L=10.11e-3
#,0.03e-3)
C=2.098e-9
#,0.006e-9)
R1=48.1
#,0.1)
R2=509.5
#,0.5)
R2e=R2*1.5
Rap=3.3e3
print(x)
#print(y)
print(z)
#print(a)

params, covar = curve_fit(f,x,z,p0=[L*C,R2**2*C**2,0.75])

print(params)
x_plot = np.linspace(0, 60)
x_plot1 = np.linspace(300, 1000000, 10000)
plot.errorbar(x/1000, z + (a / 10), xerr=None, yerr=(a / 10), fmt='rx', label="Kondensatorspannung")

#plot.xscale('log')
plot.xlabel(' $\omega \;in\; \mathrm{ kHz }$')
plot.ylabel('$U_c/U_0$')
plot.xlim(1.6e2, 2.5e2)

#plot.grid()
#plot.legend(loc='best')
plot.tight_layout(pad=0, h_pad=1.08, w_pad=1.08)
#plot.plot(x_plot, f(x_plot, *params), 'b-', linewidth=1)
plot.plot(x_plot1/1000, f(x_plot1, *params), 'b-', label="Fit")
plot.legend(loc='best')
params1=(L*C,R2**2*C**2)
#plot.plot(x_plot1, f(x_plot1, *params1), 'b-', linewidth=1)
plot.savefig('Resonanzkurve.pdf')
plot.show()


import json
import re
import time

from bs4 import BeautifulSoup

from app.config.setting import DEFAULT_PROBLEM_RATING
from app.libs.helper import str_to_datetime, timestamp_to_str
from app.libs.spider_http import SpiderHttp
from app.models.codeforces_rounds import CodeforcesRounds
from app.models.mapping import Mapping
from app.models.user import User
from app.spiders.base_spider import BaseSpider

class CodeforcesHttp(SpiderHttp):
    @staticmethod
    def _end_request(res, encoding: str):
        time.sleep(0.5)
        return res

class CodeforcesSpider(BaseSpider):
    codeforces_http = CodeforcesHttp()

    def get_user_info(self, oj_username, accept_problems):
        self.crawl_user_rounds_info(oj_username)
        username = oj_username.oj_username
        accept_problem_list = []
        url = 'http://codeforces.com/api/user.status?handle={}'.format(username)
        res = self.codeforces_http.get(url=url)
        res = json.loads(res.text)
        if res['status'] != 'OK':
            return {'success': False, 'data': []}
        res = res['result']
        success = False
        for rec in res:
            success = True
            if rec['testset'] == 'PRETESTS':
                continue
            if rec.get('verdict') == 'OK':
                if rec['problem'].get('problemsetName'):
                    problem_pid = rec['problem']['index']
                else:
                    problem_pid = '{}{}'.format(rec['problem']['contestId'], rec['problem']['index'])
                accept_time = timestamp_to_str(rec['creationTimeSeconds'])
                if accept_problems.get("codeforces-{}".format(problem_pid)) == accept_time:
                    continue
                accept_problem_list.append({
                    'oj': 'codeforces',
                    'problem_pid': problem_pid,
                    'accept_time': accept_time
                })
        return {'success': success, 'data': accept_problem_list}

    def get_problem_info(self, problem_id):
        p = re.match('^([0-9]+)([a-zA-Z]+[0-9]*)$', problem_id)
        problem_id_1 = p.group(1)
        problem_id_2 = p.group(2)
        if int(problem_id_1) < 100000:  # 题目
            url = 'https://codeforces.com/problemset/problem/{}/{}'.format(problem_id_1, problem_id_2)
            res = self.codeforces_http.get(url=url)
            try:
                rating = int(re.search(r'title="Difficulty">\s*\*(\d+)\s*</span>', res.text).group(1))
            except:
                rating = DEFAULT_PROBLEM_RATING
        else:  # gym
            try:
                rating = self._get_gym_contest_rating(problem_id_1)
            except:
                rating = DEFAULT_PROBLEM_RATING
        return {'rating': rating}

    @staticmethod
    def _get_gym_contest_rating(contest_id):
        star_rating = [DEFAULT_PROBLEM_RATING, 1200, 1600, 2000, 2400, 2800]
        mapping = Mapping.get_by_id('gym-{}'.format(contest_id))
        stars = mapping.value
        if stars:
            return star_rating[int(stars)]
        url = 'https://codeforces.com/gyms'
        req = SpiderHttp()
        res = req.get(url=url)
        soup = BeautifulSoup(res.text, 'lxml')
        token = soup.find('input', {'name': 'csrf_token'})['value']
        res = req.post(url=url, data={
            'csrf_token': token,
            'searchByNameOrIdQuery': contest_id,
            'searchByProblem': False,
        })
        soup = BeautifulSoup(res.text, 'lxml')
        stars = len(soup.find('tr', {'data-contestid': contest_id}).findAll('img'))
        mapping.modify(value=str(stars))
        return star_rating[stars]

    def crawl_user_rounds_info(self, oj_username):
        url = 'http://codeforces.com/api/user.info?handles={}'.format(oj_username.oj_username)
        rating = self.codeforces_http.get(url=url).json()['result'][0]['rating']
        url = 'http://codeforces.com/api/user.rating?handle={}'.format(oj_username.oj_username)
        res = self.codeforces_http.get(url=url).json()['result']
        contest_num = len(res)
        user = User.get_by_id(oj_username.username)
        t = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(res[-1]['ratingUpdateTimeSeconds']))
        user.modify(codeforces_rating=rating, contest_num=contest_num, last_cf_date=str_to_datetime(t).date())
        for round in res:
            t = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(round['ratingUpdateTimeSeconds']))
            cf_round = CodeforcesRounds.get_by_username_and_round_name(oj_username.username, round['contestName'])
            cf_round.modify(rank=round['rank'],
                            rating_change=round['newRating'] - round['oldRating'],
                            create_time=str_to_datetime(t))


#!/usr/bin/env python2.7
#coding=utf-8

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import time
import tables as tb
import tensorflow as tf
import numpy as np
from utils.data_tool import *
from utils.dvector_tool import *
from utils.dvector_io import *
from model.model import *
from utils.tools import *
import os
import utils.dvector_io as dvector_io
import sys
from datetime import datetime
import time

np.set_printoptions(threshold='nan')
from utils.config import *
init_config("config/my.conf")

if not set_section("produce"):
    print("can't find produce configuration section")
    exit(1)
tf.app.flags.DEFINE_string('train_dir', str(get("train_dir")), 'train model store path')
tf.app.flags.DEFINE_string('check_point', str(get("check_point")), 'train model store step')
tf.app.flags.DEFINE_string('num_speakers', str(get("num_speakers")), 'equal to number of speaker in train dataset, which is used to restore model')

tf.app.flags.DEFINE_string('test_file', str(get("test_file")), 'produce dvector data set file path')
tf.app.flags.DEFINE_bool('kaldi_prepare_symbol', bool(get("kaldi_prepare_symbol")), "generate trials file")
tf.app.flags.DEFINE_string('kaldi_prepare_path', str(get("kaldi_prepare_path")), 'kaldi data prepare directory path')
tf.app.flags.DEFINE_string('utt2spk_suffix', str(get("utt2spk_suffix")), 'store dvector file path with kaldi_prepare_path')
tf.app.flags.DEFINE_string('target_file', str(get("target_file")), 'store dvector file path with kaldi_prepare_path')

tf.app.flags.DEFINE_integer('batch_size', 1,
                            'The number of samples in each batch. To simulate shuffling input data ')

if not set_section("train"):
    print("can't find train configuration section")
    exit(1)
tf.app.flags.DEFINE_integer('lstm_hidden_units', int(get("lstm_hidden_units")), 'number of lstm cell hidden untis')
tf.app.flags.DEFINE_integer('lstm_num_layers', int(get("lstm_num_layers")), 'number of lstm layers')
tf.app.flags.DEFINE_integer('feature_dim', int(get("feature_dim")), 'dim of feature')
tf.app.flags.DEFINE_integer('left_context', int(get("left_context")), 'number of left context')
tf.app.flags.DEFINE_integer('right_context', int(get("right_context")), 'number of right context')
tf.app.flags.DEFINE_integer('cnn_num_filter', int(get("cnn_num_filter")), 'define number of cnn filter, lstm_time must be divided exactly of this number, using in conv2d')
tf.app.flags.DEFINE_integer('cnn_shift_time', int(get("cnn_shift_time")), 'cnn depth stride time, using in conv3d')
tf.app.flags.DEFINE_integer('affine_feature_dim', int(get("affine_feature_dim")), 'residual feature dim')
tf.app.flags.DEFINE_integer('dvector_dim', int(get("dvector_dim")), 'dvector dim')
tf.app.flags.DEFINE_bool('dropout_symbol', bool(get("dropout_symbol")), 'whether applying dropout layer')
tf.app.flags.DEFINE_float('dropout', float(get("dropout_rate")), 'probability to keep units in cnn')
tf.app.flags.DEFINE_bool('training', False, 'model state')
tf.app.flags.DEFINE_bool('batch_norm', bool(get("batch_norm")), 'doing batch normalization')

if not set_section("sample"):
    print("cant find sample configuration section")
    exit(1)
tf.app.flags.DEFINE_integer('lstm_time', int(get("window_size")), 'lstm max time')
tf.app.flags.DEFINE_integer('window_size', int(get("window_size")), 'the number of frames in one sample')
tf.app.flags.DEFINE_integer('window_shift', int(get("window_shift")), 'the number of frames in utt frames shift')

FLAGS = tf.app.flags.FLAGS

model_path = FLAGS.train_dir

test_feats_file_list = open(FLAGS.test_file, 'r').readlines()

num_speakers = int(FLAGS.num_speakers)

#model file path
check_point_dir = os.path.join(os.path.dirname(os.path.abspath(model_path)), 'train_logs-' + FLAGS.check_point)

def main(_):
    tf.logging.set_verbosity(tf.logging.INFO)

    graph = tf.Graph()
    with graph.as_default(), tf.device('/gpu:0'):
        global_step = tf.Variable(0, name='global_step', trainable=False)
        neighbor_dim = FLAGS.left_context + FLAGS.right_context + 1
        lstm_time = FLAGS.lstm_time
        with tf.variable_scope(tf.get_variable_scope()):
            with tf.device('/gpu:0'):
                inputs = tf.placeholder(tf.float32, [FLAGS.batch_size, lstm_time, neighbor_dim, FLAGS.feature_dim])
                labels = tf.placeholder(tf.int32, [FLAGS.batch_size])
                #  _, embeddings1, embeddings2 = prepare_model_BiGRU(inputs, num_speakers, FLAGS)
                _, embeddings1, embeddings2 = prepare_model_res_GRU(inputs, num_speakers, FLAGS)

    config = tf.ConfigProto(allow_soft_placement=True)
    config.gpu_options.allow_growth = True
    with tf.Session(graph=graph, config=config) as sess:
        saver = tf.train.Saver()
        sess.run(tf.global_variables_initializer())
#        sess.run(tf.local_variables_initializer())
        saver.restore(sess, check_point_dir)
        step = 0

        test_dvectors = {}
        num_test_utt = 0
        for test_feats_ark in test_feats_file_list:
            ark_path = test_feats_ark.strip()
            test_feats_dicts = read_mat(ark_path)
            for k,v in test_feats_dicts.iteritems():
                start_time = time.time()
                samples = produce_utt_samples(v, FLAGS.window_size, FLAGS.window_shift, FLAGS.left_context, FLAGS.right_context)
                spk_dvectors = []
                for sample in samples:
                    em1, em2 = sess.run([embeddings1, embeddings2], feed_dict={inputs:[sample], labels:[1]})
                    em1 = dvector_normalize_length(np.reshape(em1, [FLAGS.dvector_dim]))
                    em2 = dvector_normalize_length(np.reshape(em2, [FLAGS.dvector_dim]))
                    spk_dvector = np.divide(np.add(em1, em2), 2.0)
                    spk_dvector = dvector_normalize_length(spk_dvector)
                    spk_dvector = dvector_normalize_length(np.reshape(em1, [FLAGS.dvector_dim]))
                    if spk_dvector.shape[0] != FLAGS.dvector_dim:
                        continue
                    spk_dvectors.append(spk_dvector)
                if len(spk_dvectors) == 0:
                    print("error dvector extract for utt:" + k)
                    continue
                dvector = np.mean(spk_dvectors, axis=0)
                if dvector.shape[0] != FLAGS.dvector_dim:
                    print("error dvector extract for utt:" + k)
                    continue
                test_dvectors[k] = dvector
                print("finish speaker [%s] utt dvector" % (k))
                end_time = time.time()
                print("used time: " + str((end_time - start_time)) + "s")
                num_test_utt += 1

        print("finish extract %d utt dvectors" % (num_test_utt))
        if not os.path.exists(FLAGS.kaldi_prepare_path):
            os.makedirs(FLAGS.kaldi_prepare_path)
        dvector_file = FLAGS.kaldi_prepare_path.rstrip('/') + '/' + FLAGS.target_file
        if not dvector_io.write_vec(dvector_file, test_dvectors):
            exit(1)
        print("finish write vec to " + FLAGS.target_file)
        if FLAGS.kaldi_prepare_symbol:
            if not dvector_io.write_to_kaldi_prepare(FLAGS.kaldi_prepare_path, test_dvectors, FLAGS.utt2spk_suffix):
                exit(1)
            print("finish write utt2spk to " + FLAGS.kaldi_prepare_path)
        #  eer, eer_th = compute_eer(test_dvectors, test_dvectors)
        #  print("eer: %.4f, threshold: %.4f" % (eer, eer_th))

if __name__ == "__main__":
    tf.app.run()


#!/usr/bin/python3
#
# Apache 2.0 license

import argparse
import bugzilla
from croniter import croniter
from dotted_dict import DottedDict
from functools import reduce, wraps
from heapq import heappop, heappush
from itertools import count
import os
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
from slack_sdk.socket_mode import SocketModeClient
from slack_sdk.socket_mode.response import SocketModeResponse
import sqlite3
import time
import traceback
import yaml

ISSUE_LINK = 'https://github.com/coreos/triagebot/issues'
HELP = f'''
I understand these commands:
`unresolve` (in BZ thread) - unresolve the BZ
`refresh` (in BZ thread) - refresh the BZ description
`track {{BZ-URL|BZ-number}}` - start tracking the specified BZ
`report` - summarize unresolved bugs to the channel
`ping` - check whether the bot is running properly
`help` - print this message
Report problems <{ISSUE_LINK}|here>.
'''

def escape(message):
    '''Escape a string for inclusion in a Slack message.'''
    # https://api.slack.com/reference/surfaces/formatting#escaping
    map = {
        '&': '&',
        '<': '<',
        '>': '>',
    }
    return reduce(lambda s, p: s.replace(p[0], p[1]), map.items(), message)

class Database:
    def __init__(self, config):
        # Use DB locking to protect against races between the Bugzilla
        # polling thread and the track command, and to avoid SQLITE_BUSY on
        # lock upgrade.  We're not performance-critical.
        self._db = sqlite3.connect(config.database, isolation_level='immediate',
                timeout=60)
        with self:
            ver = self._db.execute('pragma user_version').fetchone()[0]
            if ver < 1:
                self._db.execute('create table bugs '
                        '(bz integer unique not null, '
                        'channel text not null, '
                        'timestamp text not null, '
                        'resolved integer not null default 0)')
                self._db.execute('create unique index bugs_messages on bugs '
                        '(channel, timestamp)')
            if ver < 2:
                self._db.execute('create table specials '
                        '(name text unique not null, '
                        'channel text not null, '
                        'id text not null)')
                self._db.execute('create unique index specials_messages '
                        'on specials (channel, id)')
            if ver < 3:
                self._db.execute('create table events '
                        '(added integer not null, '
                        'channel text not null, '
                        'timestamp text not null)')
                self._db.execute('create unique index events_unique '
                        'on events (channel, timestamp)')
            if ver < 4:
                self._db.execute('alter table specials add column '
                        'unixtime integer not null default 0')
            if ver < 5:
                self._db.execute('create index bugs_resolved on bugs '
                        '(resolved)')
                self._db.execute('pragma user_version = 5')

    def __enter__(self):
        '''Start a database transaction.'''
        self._db.__enter__()
        return self

    def __exit__(self, exc_type, exc_value, tb):
        '''Commit a database transaction.'''
        if exc_type is HandledError:
            # propagate exception but commit anyway
            self._db.__exit__(None, None, None)
            return False
        return self._db.__exit__(exc_type, exc_value, tb)

    def add_bug(self, bz, channel, ts):
        self._db.execute('insert into bugs (bz, channel, timestamp) '
                'values (?, ?, ?)', (bz, channel, ts))

    def set_resolved(self, bz, resolved=True):
        self._db.execute('update bugs set resolved = ? where bz == ?',
                (int(resolved), bz))

    def list_unresolved(self):
        res = self._db.execute('select bz from bugs where '
                'resolved == 0 order by timestamp').fetchall()
        return [r[0] for r in res]

    def lookup_bz(self, bz):
        res = self._db.execute('select channel, timestamp, resolved '
                'from bugs where bz == ?', (bz,)).fetchone()
        if res is None:
            raise KeyError
        channel, ts, resolved = res
        return channel, ts, bool(resolved)

    def lookup_ts(self, channel, ts):
        res = self._db.execute('select bz, resolved from bugs where '
                'channel == ? and timestamp == ?', (channel, ts)).fetchone()
        if res is None:
            raise KeyError
        bz, resolved = res
        return bz, bool(resolved)

    def set_special(self, name, channel, id):
        self._db.execute('insert or replace into specials '
                '(name, channel, id, unixtime) values (?, ?, ?, ?)',
                (name, channel, id, int(time.time())))

    def lookup_special(self, name):
        res = self._db.execute('select channel, id from specials where '
                'name == ?', (name,)).fetchone()
        if res is None:
            raise KeyError
        return res

    def get_special_unixtime(self, name):
        res = self._db.execute('select unixtime from specials where name == ?',
                (name,)).fetchone()
        if res is None:
            raise KeyError
        return res[0]

    def add_event(self, channel, ts):
        '''Return False if the event is already present.'''
        try:
            self._db.execute('insert into events (added, channel, timestamp) '
                    'values (?, ?, ?)', (int(time.time()), channel, ts))
            return True
        except sqlite3.IntegrityError:
            return False

    def prune_events(self, max_age=3600):
        self._db.execute('delete from events where added < ?',
                (int(time.time() - max_age),))

class Bug:
    # Database transactions must be supplied by the caller.

    def __init__(self, config, client, bzapi, db, bz=None, channel=None,
            ts=None):
        self._config = config
        self._client = client
        self._db = db
        self.bz = bz
        self.channel = channel or config.channel  # default for new bug
        self.ts = ts
        self.resolved = False  # default for new bug
        if bz is not None:
            assert channel is None and ts is None
            try:
                self.channel, self.ts, self.resolved = db.lookup_bz(bz)
            except KeyError:
                # new bug hasn't been added yet
                pass
        else:
            assert channel is not None and ts is not None
            # raises KeyError on unknown timestamp
            self.bz, self.resolved = db.lookup_ts(channel, ts)
        fields = ['summary', 'product', 'component', 'assigned_to', 'status',
                'resolution']
        details = bzapi.getbug(self.bz, include_fields=fields)
        for field in fields:
            setattr(self, field, getattr(details, field))
        self.assigned_to_name = details.assigned_to_detail['real_name']

    def __str__(self):
        return f'[{self.bz}] {self.summary}'

    @staticmethod
    def is_unresolved(db, bz):
        '''Class method returning True if the specified BZ is posted and
        unresolved.  This allows the Bugzilla polling loop to check whether
        to process a BZ without constructing a Bug, since the latter makes
        an additional Bugzilla query.'''
        try:
            _, _, resolved = db.lookup_bz(bz)
            return not resolved
        except KeyError:
            return False

    @classmethod
    def list_unresolved(cls, config, client, bzapi, db):
        for bz in db.list_unresolved():
            yield cls(config, client, bzapi, db, bz=bz)

    @property
    def posted(self):
        '''True if this bug has been posted to Slack.'''
        return self.ts is not None

    def _make_message(self):
        '''Format the Slack message for a bug.'''
        icon = ':white_check_mark:' if self.resolved else ':bugzilla:'
        message = f'{icon} <{self._config.bugzilla_bug_url}{self.bz}|[{self.bz}] {escape(self.summary)}> :thread:'
        blocks = [
            {
                'type': 'section',
                'text': {
                    'type': 'mrkdwn',
                    'text': message,
                }
            }
        ]
        if not self.resolved:
            blocks.append({
                'type': 'actions',
                'elements': [
                    {
                        'type': 'button',
                        'text': {
                            'type': 'plain_text',
                            'text': 'Resolve'
                        },
                        'value': 'resolve',
                    },
                ]
            })
        else:
            if self.product != self._config.bugzilla_product:
                status = f'Moved to *{escape(self.product)}*/*{escape(self.component)}*'
            elif self.component != self._config.bugzilla_component:
                status = f'Moved to *{escape(self.component)}*'
            elif self.status == 'CLOSED':
                status = f'Closed as *{escape(self.resolution)}*'
            else:
                status = f'Assigned to *{escape(self.assigned_to_name)}*'
            blocks.append({
                'type': 'context',
                'elements': [
                    {
                        'type': 'mrkdwn',
                        'text': status,
                    },
                ]
            })
        return message, blocks

    def post(self):
        '''Post this bug to Slack and record in DB.'''
        assert not self.posted
        message, blocks = self._make_message()
        self.ts = self._client.chat_postMessage(channel=self.channel,
                text=message, blocks=blocks, unfurl_links=False,
                unfurl_media=False)['ts']
        self._client.pins_add(channel=self.channel, timestamp=self.ts)
        self._db.add_bug(self.bz, self.channel, self.ts)

    def update_message(self):
        '''Rerender the existing Slack message for this bug.'''
        assert self.posted
        message, blocks = self._make_message()
        self._client.chat_update(channel=self.channel, ts=self.ts,
                text=message, blocks=blocks)

    def resolve(self):
        '''Mark the bug resolved and record in DB.  Safe to call if already
        resolved.'''
        assert self.posted
        self.resolved = True
        self.update_message()
        try:
            self._client.pins_remove(channel=self.channel, timestamp=self.ts)
        except SlackApiError as e:
            if e.response['error'] != 'no_pin':
                raise
        self._db.set_resolved(self.bz)

    def unresolve(self):
        '''Mark the bug unresolved and record in DB.  Safe to call if
        already unresolved.'''
        assert self.posted
        self.resolved = False
        self.update_message()
        try:
            self._client.pins_add(channel=self.channel, timestamp=self.ts)
        except SlackApiError as e:
            if e.response['error'] != 'already_pinned':
                raise
        self._db.set_resolved(self.bz, False)

    def log(self, message):
        '''Post the specified message as a threaded reply to the bug.'''
        assert self.posted
        self._client.chat_postMessage(channel=self.channel, text=message,
                thread_ts=self.ts)

def post_report(config, client, bzapi, db):
    '''Post a summary of unresolved bugs to the channel.  Return the channel
    and timestamp.'''
    parts = []
    for bug in Bug.list_unresolved(config, client, bzapi, db):
        age_days = int((time.time() - float(bug.ts)) / 86400)
        link = client.chat_getPermalink(channel=bug.channel,
                message_ts=bug.ts)["permalink"]
        part = f':bugzilla: <{config.bugzilla_bug_url}{bug.bz}|[{bug.bz}]> <{link}|{escape(bug.summary)}> ({age_days} days)'
        parts.append(part)
    if not parts:
        parts.append('_No bugs!_')
    message = '\n'.join(['*Unresolved bug summary:*'] + parts)
    ts = client.chat_postMessage(channel=config.channel,
            text=message, unfurl_links=False, unfurl_media=False)['ts']
    return config.channel, ts

class HandledError(Exception):
    '''An exception which should just be swallowed.'''
    pass

def report_errors(f):
    '''Decorator that sends exceptions to an administrator via Slack DM
    and then swallows them.  The first argument of the function must be
    the config.'''
    import json, requests, socket, urllib.error
    @wraps(f)
    def wrapper(config, *args, **kwargs):
        try:
            return f(config, *args, **kwargs)
        except HandledError:
            pass
        except (json.JSONDecodeError, requests.ConnectionError, requests.HTTPError, requests.ReadTimeout) as e:
            # Exception type leaked from the bugzilla API.  Assume transient
            # network problem; don't send message.
            print(e)
        except (socket.timeout, urllib.error.URLError) as e:
            # Exception type leaked from the slack_sdk API.  Assume transient
            # network problem; don't send message.
            print(e)
        except Exception:
            try:
                message = f'Caught exception:\n```\n{traceback.format_exc()}```'
                client = WebClient(token=config.slack_token)
                channel = client.conversations_open(users=[config.error_notification])['channel']['id']
                client.chat_postMessage(channel=channel, text=message)
            except Exception:
                traceback.print_exc()
    return wrapper

@report_errors
def process_event(config, socket_client, req):
    '''Handler for a Slack event.'''
    client = socket_client.web_client
    payload = DottedDict(req.payload)
    db = Database(config)
    bzapi = bugzilla.Bugzilla(config.bugzilla, api_key=config.bugzilla_key,
            force_rest=True)

    def make_bug(**kwargs):
        return Bug(config, client, bzapi, db, **kwargs)

    def ack_event():
        '''Acknowledge the event, as required by Slack.'''
        resp = SocketModeResponse(envelope_id=req.envelope_id)
        socket_client.send_socket_mode_response(resp)

    def complete_command():
        '''Add a success emoji to a command mention.'''
        client.reactions_add(channel=payload.event.channel,
                name='ballot_box_with_check', timestamp=payload.event.ts)

    def fail_command(message):
        '''Reply to a command mention with an error.'''
        client.chat_postMessage(channel=payload.event.channel,
                text=f"<@{payload.event.user}> {message}",
                # start a new thread or continue the existing one
                thread_ts=payload.event.get('thread_ts', payload.event.ts))
        raise HandledError()

    with db:
        if req.type == 'events_api' and payload.event.type == 'app_mention':
            if payload.event.channel != config.channel:
                # Don't even acknowledge events outside our channel, to
                # avoid interfering with separate instances in other
                # channels.
                return
            ack_event()
            if not db.add_event(payload.event.channel, payload.event.event_ts):
                # When we ignore some events, Slack can send us duplicate
                # retries.  Detect and ignore those after acknowledging.
                return
            message = payload.event.text.replace(f'<@{config.bot_id}>', '').strip()
            if message == 'unresolve':
                if 'thread_ts' not in payload.event:
                    fail_command('`unresolve` command must be used in a thread.')
                try:
                    bug = make_bug(channel=payload.event.channel,
                            ts=payload.event.thread_ts)
                except KeyError:
                    fail_command("Couldn't find a BZ matching this thread.")
                bug.unresolve()
                complete_command()
            elif message == 'refresh':
                if 'thread_ts' not in payload.event:
                    fail_command('`refresh` command must be used in a thread.')
                try:
                    bug = make_bug(channel=payload.event.channel,
                            ts=payload.event.thread_ts)
                except KeyError:
                    fail_command("Couldn't find a BZ matching this thread.")
                bug.update_message()
                complete_command()
            elif message.startswith('track '):
                try:
                    # Accept a bug number or a BZ URL with optional anchor.
                    # Slack puts URLs inside <>.
                    bz = int(message.replace('track ', '', 1). \
                            replace(config.bugzilla_bug_url, '', 1). \
                            split('#')[0]. \
                            strip(' <>'))
                except ValueError:
                    fail_command("Invalid bug number.")
                bug = make_bug(bz=bz)
                if bug.posted:
                    link = client.chat_getPermalink(channel=bug.channel,
                            message_ts=bug.ts)["permalink"]
                    fail_command(f"Bug {bz} <{link}|already tracked>.")
                bug.post()
                bug.log(f'_Requested by <@{payload.event.user}>._')
                complete_command()
            elif message == 'report':
                # Post unscheduled report to the channel
                # We make a potentially large number of BZ queries; tell
                # the user we're working
                client.reactions_add(channel=payload.event.channel,
                        timestamp=payload.event.ts,
                        name='hourglass_flowing_sand')
                try:
                    post_report(config, client, bzapi, db)
                finally:
                    client.reactions_remove(channel=payload.event.channel,
                            timestamp=payload.event.ts,
                            name='hourglass_flowing_sand')
                complete_command()
            elif message == 'ping':
                # Check Bugzilla connectivity
                try:
                    if not bzapi.logged_in:
                        raise Exception('Not logged in.')
                except Exception:
                    # Swallow exception details and just report the failure
                    fail_command('Cannot contact Bugzilla.')
                # Check time since last successful poll
                try:
                    last_check = db.get_special_unixtime('watchdog')
                except KeyError:
                    fail_command('Have never successfully polled Bugzilla.')
                time_since_check = time.time() - last_check
                if time_since_check > 1.5 * config.bugzilla_poll_interval:
                    fail_command(f'Last successful Bugzilla poll was {int(time_since_check / 60)} minutes ago.')
                complete_command()
            elif message == 'help':
                client.chat_postMessage(channel=payload.event.channel, text=HELP,
                        # start a new thread or continue the existing one
                        thread_ts=payload.event.get('thread_ts', payload.event.ts))
            elif message == 'throw':
                # undocumented
                complete_command()
                raise Exception(f'Throwing exception as requested by <@{payload.event.user}>')
            else:
                fail_command(f"I didn't understand that.  Try `<@{config.bot_id}> help`")
        elif req.type == 'interactive' and payload.type == 'block_actions' and payload.actions[0].value == 'resolve':
            if payload.container.channel_id != config.channel:
                # Don't even acknowledge events outside our channel, to
                # avoid interfering with separate instances in other
                # channels.
                return
            ack_event()
            if not db.add_event(payload.container.channel_id, payload.actions[0].action_ts):
                # In case Slack sends duplicate action notifications, detect
                # and ignore them after acknowledging, since we have the
                # infrastructure anyway.
                return
            try:
                bug = make_bug(channel=payload.container.channel_id,
                        ts=payload.container.message_ts)
            except KeyError:
                client.chat_postMessage(channel=payload.container.channel_id,
                        text=f"<@{payload.user.id}> Couldn't find a record of this bug.",
                        thread_ts=payload.container.message_ts)
                return
            if bug.product != config.bugzilla_product:
                status = f'Bug now in *{escape(bug.product)}*/*{escape(bug.component)}*.'
            elif bug.component != config.bugzilla_component:
                status = f'Bug now in *{escape(bug.component)}*.'
            elif bug.status == 'CLOSED':
                status = f'Bug now *CLOSED/{escape(bug.resolution)}*.'
            elif bug.status == 'NEW':
                client.chat_postMessage(channel=payload.container.channel_id,
                        text=f"<@{payload.user.id}> Bug still in component {escape(config.bugzilla_component)} and status NEW, cannot resolve.",
                        thread_ts=payload.container.message_ts)
                return
            elif bug.assigned_to == config.bugzilla_assignee:
                client.chat_postMessage(channel=payload.container.channel_id,
                        text=f"<@{payload.user.id}> Bug still assigned to {escape(bug.assigned_to_name)}, cannot resolve.",
                        thread_ts=payload.container.message_ts)
                return
            else:
                status = f'Bug now *{escape(bug.status)}*, assigned to *{escape(bug.assigned_to_name)}*.'
            bug.resolve()
            bug.log(f'_Resolved by <@{payload.user.id}>. {status} Unresolve with_ `<@{config.bot_id}> unresolve`')

class Scheduler:
    def __init__(self, config, client, bzapi, db):
        self._config = config
        self._bzapi = bzapi
        self._client = client
        self._db = db
        self._jobs = []
        self._add_timer(self._check_bugzilla, 'bugzilla_poll_interval', 300)
        self._add_cron(self._post_report, 'report_schedule')

    def _add_cron(self, fn, config_key, default=None):
        schedule = self._config.get(config_key, default)
        if schedule is not None:
            it = croniter(schedule)
            # add the list length as a tiebreaker when sorting, so we don't
            # try to compare two fns
            heappush(self._jobs, (next(it), len(self._jobs), fn, it))

    def _add_timer(self, fn, config_key, default=None):
        interval = self._config.get(config_key, default)
        if interval is not None:
            it = count(int(time.time()), interval)
            # add the list length as a tiebreaker when sorting, so we don't
            # try to compare two fns
            heappush(self._jobs, (next(it), len(self._jobs), fn, it))

    def run(self):
        while True:
            # get the next job that's due
            nex, idx, fn, it = heappop(self._jobs)
            # wait for the scheduled time, allowing for spurious wakeups
            while True:
                now = time.time()
                if now >= nex:
                    break
                time.sleep(nex - now)
            # run the job, passing the config to make report_errors() happy
            report_errors(fn)(self._config)
            # schedule the next run, skipping any times that are already
            # in the past
            now = time.time()
            while True:
                nex = next(it)
                if nex > now:
                    break
            heappush(self._jobs, (nex, idx, fn, it))

    def _check_bugzilla(self, _config):
        queries = [
            # NEW bugs
            self._bzapi.build_query(product=self._config.bugzilla_product,
                    component=self._config.bugzilla_component, status='NEW'),
            # Open bugs assigned to default assignee
            self._bzapi.build_query(product=self._config.bugzilla_product,
                    component=self._config.bugzilla_component,
                    status='__open__',
                    assigned_to=self._config.bugzilla_assignee),
        ]
        bzs = set()
        for query in queries:
            query['include_fields'] = ['id']
            bzs.update(bz.id for bz in self._bzapi.query(query))
        # Remove ignored bugs
        bzs.difference_update(self._config.get('bugzilla_ignore_bugs', []))

        for bz in sorted(bzs):
            with self._db:
                if not Bug.is_unresolved(self._db, bz):
                    bug = Bug(self._config, self._client, self._bzapi,
                            self._db, bz=bz)
                    if not bug.posted:
                        # Unknown bug; post it
                        bug.post()
                    else:
                        # Resolved bug; unresolve it
                        assert bug.resolved
                        bug.unresolve()
                        self._client.chat_postMessage(channel=bug.channel,
                                text=f'_Bug now *{escape(bug.status)}* in *{escape(bug.component)}*, assigned to *{escape(bug.assigned_to_name)}*. Unresolving._',
                                thread_ts=bug.ts)
        with self._db:
            self._db.prune_events()
            self._update_watchdog()

    def _update_watchdog(self):
        '''Reschedule the message-in-a-bottle that warns of a bot failure.'''
        # First, add new message
        expiration = int(time.time() + 60 * self._config.watchdog_minutes)
        message = f":robot_face: If you're seeing this, I haven't completed a Bugzilla check in {self._config.watchdog_minutes} minutes.  I may be misconfigured, disconnected, or dead, or Bugzilla may be down."
        new_id = self._client.chat_scheduleMessage(channel=self._config.channel,
                post_at=expiration, text=message)['scheduled_message_id']
        # Then delete the old one
        name = 'watchdog'
        try:
            old_channel, old_id = self._db.lookup_special(name)
        except KeyError:
            # No previous message
            pass
        else:
            try:
                self._client.chat_deleteScheduledMessage(channel=old_channel,
                        scheduled_message_id=old_id)
            except SlackApiError as e:
                if e.response['error'] == 'invalid_scheduled_message_id':
                    # Watchdog timer already fired.  Report that we're back.
                    self._client.chat_postMessage(channel=self._config.channel,
                            text='_is back_')
                else:
                    # Unexpected error.  We already rescheduled the timer, and
                    # it doesn't seem like we should abort the transaction for
                    # this.  Just log it.
                    print(e)
        # Update DB
        self._db.set_special(name, self._config.channel, new_id)

    def _post_report(self, _config):
        with self._db:
            post_report(self._config, self._client, self._bzapi, self._db)

def main():
    parser = argparse.ArgumentParser(
            description='Simple Bugzilla triage helper bot for Slack.')
    parser.add_argument('-c', '--config', metavar='FILE',
            default='~/.triagebot', help='config file')
    parser.add_argument('-d', '--database', metavar='FILE',
            default='~/.triagebot-db', help='database file')
    args = parser.parse_args()

    # Read config
    with open(os.path.expanduser(args.config)) as fh:
        config = DottedDict(yaml.safe_load(fh))
        config.database = os.path.expanduser(args.database)
    env_map = (
        ('TRIAGEBOT_SLACK_APP_TOKEN', 'slack-app-token'),
        ('TRIAGEBOT_SLACK_TOKEN', 'slack-token'),
        ('TRIAGEBOT_BUGZILLA_KEY', 'bugzilla-key')
    )
    for env, config_key in env_map:
        v = os.environ.get(env)
        if v:
            setattr(config, config_key, v)

    # Connect to services
    client = WebClient(token=config.slack_token)
    # store our user ID
    config.bot_id = client.auth_test()['user_id']
    bzapi = bugzilla.Bugzilla(config.bugzilla, api_key=config.bugzilla_key,
            force_rest=True)
    if not bzapi.logged_in:
        raise Exception('Did not authenticate')
    db = Database(config)

    # Start socket-mode listener in the background
    socket_client = SocketModeClient(app_token=config.slack_app_token,
            web_client=WebClient(token=config.slack_token))
    socket_client.socket_mode_request_listeners.append(
            lambda socket_client, req: process_event(config, socket_client, req))
    socket_client.connect()

    # Run scheduler
    Scheduler(config, client, bzapi, db).run()

if __name__ == '__main__':
    main()


#！／user/bin/env python
#-*- coding:utf-8 -*-
import copy
from matplotlib import pyplot as plt
from matplotlib import animation#绘制动图

training_set=[[[3,3],1],[[4,2],1],[[1,1],-1],[[2,0],-1]]

#初值选择为0
w=[0,0]
b=0
alpha = 1
history=[]
#对应于（3）

def update(item):
   # 更新参数，步长(学习率)为1
   global w,b,history
   w[0]+=alpha*item[1]*item[0][0]
   w[1]+=alpha*item[1]*item[0][1]
   b+=alpha*item[1]
   print(w,b)
   history.append([copy.copy(w),b])

def loss(item):#计算损失函数值y(w*x+b)
    res=0
    for i in range(len(item[0])):
        res+=item[0][i]*w[i]
    res+=b
    res*=item[1]
    # print(res)
    return res

def check():
    #检查是否需要继续更新
    flag=False
    for item in training_set:
        # print(item)
        if loss(item)<=0:
            flag=True
            update(item)
    if not flag:
        print("RESULT:w:"+str(w)+"  b:"+str(b))
    return flag

if __name__=="__main__":
    for i in range(1000):
        if not check():
            break

#下面是绘图
fig=plt.figure()
ax=plt.axes(xlim=(0,2),ylim=(-2,2))
line,=ax.plot([],[],'g',lw=2)
label=ax.text([],[],'')

def init():
    line.set_data([],[])
    x,y,x_,y_,=[],[],[],[]
    for p in training_set:
        if p[1]>0:
            x.append(p[0][0])
            y.append(p[0][1])
        else:
            x_.append(p[0][0])
            y_.append(p[0][1])
    plt.plot(x,y,'bo',x_,y_,'r^')
    plt.axis([-6,6,-6,6])
    plt.grid()
    plt.xlabel('x1')
    plt.ylabel('x2')
    plt.title('Perception')
    return line,label

def animate(i):
    global history,ax,line,label
    w=history[i][0]
    b=history[i][1]
    if w[1]==0:return line,label
    x1 = -7.0
    y1 = -(b + w[0] * x1) / w[1]
    x2 = 7.0
    y2 = -(b + w[0] * x2) / w[1]
    line.set_data([x1, x2], [y1, y2])
    x1 = 0.0
    y1 = -(b + w[0] * x1) / w[1]
    label.set_text(str(history[i][0]) + ' ' + str(b))
    label.set_position([x1, y1])
    return line, label

anim = animation.FuncAnimation(fig, animate, init_func=init, frames=len(history), interval=1000, repeat=True,blit=True)
#保存为动图需要安装imagemagick模块
anim.save('sin_dot.gif', writer='imagemagick', fps=60)
plt.show()

#
# import numpy as np
# import matplotlib.pyplot as plt
#
# p_x = np.array([[3, 3], [4, 3], [1, 1]])
# y = np.array([1, 1, -1])
# plt.figure()
# for i in range(len(p_x)):
#     if y[i] == 1:
#         plt.plot(p_x[i][0], p_x[i][1], 'ro')
#     else:
#         plt.plot(p_x[i][0], p_x[i][1], 'bo')
#
# w = np.array([1, 0])
# b = 0
# delta = 1
#
# for i in range(100):
#     choice = -1
#     for j in range(len(p_x)):
#         if y[j] != np.sign(np.dot(w, p_x[0]) + b):
#             choice = j
#             break
#     if choice == -1:
#         break
#     w = w + delta * y[choice] * p_x[choice]
#     print("weight:",w)
#     b = b + delta * y[choice]
#     print("bias：",b)
#
# line_x = [0, 10]
# line_y = [0, 0]
#
# for i in range(len(line_x)):
#     line_y[i] = (-w[0] * line_x[i] - b) / w[1]
#
# plt.plot(line_x, line_y)
# plt.savefig("picture.png")


#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
clients.py: Clients methods
"""
import gluon.main               # Sets up logging
import logging

from clients import ClientCrud, ClientJqGrid

# E0602: *Undefined variable %r*
# pylint: disable=E0602

PhoneNumber = local_import('phone', app='shared').PhoneNumber
best_guess_code = local_import('addresses', app='shared').best_guess_code
AutoCompleteWidget = local_import('stickon/sqlhtml',
        app='shared').AutoCompleteWidget

from jqgrid import initialize_response_files
initialize_response_files(globals())

LOG = logging.getLogger('app')

@auth.requires_login()
def index():
    """Default view. """

    redirect(URL(r=request, f='edit'))
    return

@auth.requires_login()
def edit():
    """Controller for client edit view. """

    def on_accept(form):
        """Processing if form is accepted"""
        redirect(URL(r=request, f='edit', args=[form.vars.id]))

    client_crud = ClientCrud(db.client, auth)
    form = client_crud.form(crud, client_id=request.args(0),
            onaccept=on_accept)

    return dict(
            form=form,
            expired=client_crud.expired,
            has_clear=client_crud.has_clear,
            has_listing=client_crud.has_listing,
            layout='layout.html',
            listing_url=URL('listing'),
            place_of_birth=client_crud.place_of_birth,
            select_another_url=URL('edit'),
            token=client_crud.token,
            )

@auth.requires_login()
def listing():
    """Controller used to display client listing jqgrid."""
    return ClientJqGrid(globals(), db.client,
            select_callback_url=URL(c='clients', f='edit') + '/{id}')()


import os
import time
import numpy as np
from sklearn.metrics import roc_auc_score
import oneflow as flow

from config import get_args
from dataloader_utils import OFRecordDataLoader
from wide_and_deep_module import WideAndDeep
from util import dump_to_npy, save_param_npy

def prepare_modules(args):
    train_dataloader = OFRecordDataLoader(
        args, data_root=args.data_dir, batch_size=args.batch_size
    )
    val_dataloader = OFRecordDataLoader(args, data_root=args.data_dir, mode="val")
    wdl_module = WideAndDeep(args)
    if args.model_load_dir != "":
        print("load checkpointed model from ", args.model_load_dir)
        wdl_module.load_state_dict(flow.load(args.model_load_dir))

    if args.save_initial_model and args.model_save_dir != "":
        path = os.path.join(args.model_save_dir, "initial_checkpoint")
        if not os.path.isdir(path):
            flow.save(wdl_module.state_dict(), path)

    bce_loss = flow.nn.BCELoss(reduction="mean")

    wdl_module.to("cuda")
    bce_loss.to("cuda")

    opt = flow.optim.SGD(wdl_module.parameters(), lr=args.learning_rate, momentum=0.9)
    return train_dataloader, val_dataloader, wdl_module, bce_loss, opt

def print_eval_metrics(step, loss, lables_list, predicts_list):
    all_labels = np.concatenate(lables_list, axis=0)
    all_predicts = np.concatenate(predicts_list, axis=0)
    auc = (
        "NaN"
        if np.isnan(all_predicts).any()
        else roc_auc_score(all_labels, all_predicts)
    )
    print(f"iter {step} eval_loss {loss} auc {auc}")

if __name__ == "__main__":
    args = get_args()
    train_dataloader, val_dataloader, wdl_module, loss, opt = prepare_modules(args)

    losses = []
    wdl_module.train()
    for i in range(args.max_iter):
        (
            labels,
            dense_fields,
            wide_sparse_fields,
            deep_sparse_fields,
        ) = train_dataloader()
        labels = labels.to("cuda").to(dtype=flow.float32)
        dense_fields = dense_fields.to("cuda")
        wide_sparse_fields = wide_sparse_fields.to("cuda")
        deep_sparse_fields = deep_sparse_fields.to("cuda")
        predicts = wdl_module(dense_fields, wide_sparse_fields, deep_sparse_fields)
        train_loss = loss(predicts, labels)
        losses.append(train_loss.numpy().mean())
        train_loss.backward()
        opt.step()
        opt.zero_grad()
        if (i + 1) % args.print_interval == 0:
            l = sum(losses) / len(losses)
            losses = []
            print(f"iter {i+1} train_loss {l} time {time.time()}")
            if args.eval_batchs <= 0:
                continue

            eval_loss_acc = 0.0
            lables_list = []
            predicts_list = []
            wdl_module.eval()
            for j in range(args.eval_batchs):
                (
                    labels,
                    dense_fields,
                    wide_sparse_fields,
                    deep_sparse_fields,
                ) = val_dataloader()
                labels = labels.to("cuda").to(dtype=flow.float32)
                dense_fields = dense_fields.to("cuda")
                wide_sparse_fields = wide_sparse_fields.to("cuda")
                deep_sparse_fields = deep_sparse_fields.to("cuda")
                predicts = wdl_module(
                    dense_fields, wide_sparse_fields, deep_sparse_fields
                )
                eval_loss = loss(predicts, labels)

                eval_loss_acc += eval_loss.numpy().mean()
                lables_list.append(labels.numpy())
                predicts_list.append(predicts.numpy())

            print_eval_metrics(
                i + 1, eval_loss_acc / args.eval_batchs, lables_list, predicts_list
            )
            wdl_module.train()


class Employee:
    def __init__(self, first, last, pay):
        self.first = first
        self.last = last
        self.pay = pay
        self.email = first + '.' + last + '@company.com'

    def fullname(self):
        return '{} {}'.format(self.first, self.last )

emp_1 = Employee( 'Corey' , 'Schafer' , 50 )
emp_2 = Employee( 'Test' , 'User' , 10 )

name = Employee.fullname(emp_1)
print(name)
print(emp_1.email)
print(emp_2.email)
#print('{} {}'.format(emp_1.first, emp_1.last ) )
name2 = emp_2.fullname()
print(name2)

#print(emp_1)
#print(emp_2)

#emp_1.first = 'Corey'
#emp_1.last = 'Schafer'
#emp_1.email = 'Corey.Schaefer@company.com'
#emp_1.pay = 50

#emp_2.first = 'Test'
#emp_2.last = 'User'
#emp_2.email = 'Test.User@company.com'
#emp_2.pay = 10

#print(emp_1.email)
#print(emp_2.email)


import itertools

import six

class NestableDict(dict):
    """``NestableDict`` extends ``dict`` to support setting a path from
    a sequence of keys.
    """
    def set_path(self, keys, value):
        """Set a path from a sequence of keys.
        """
        if isinstance(keys, six.string_types):
            keys = (keys, )
        d = self
        for key in keys[:-1]:
            d = d.setdefault(key, {})
        d[keys[-1]] = value

def nest(records, accessor, rollup=None):
    """Nest a sequence of records.

    Args:
        records: A sequence of records.
        accessor: A function that returns a key for nesting
            the sequence of records.
        rollup: This function is applied to each sequence of leaf elements.
            The return value of this function will replace each sequence
            of leaf elements in the nested ``dict``.

    Returns:
        A nested ``dict``.
    """
    records = sorted(records, key=accessor)
    rollup = rollup if rollup else lambda x: x
    groups = {k: list(g) for k, g in itertools.groupby(records, accessor)}
    nest = NestableDict()
    for k, g in groups.items():
        nest.set_path(k, rollup(g))
    return nest