# uncompyle6 version 3.7.4
# Python bytecode 3.7 (3394)
# Decompiled from: Python 3.6.9 (default, Apr 18 2020, 01:56:04)
# [GCC 8.4.0]
# Embedded file name: /home/runner/work/PyTplot/PyTplot/pytplot/QtPlotter/TVarFigureSpec.py
# Compiled at: 2020-04-24 11:05:41
# Size of source mod 2**32: 17428 bytes
import pyqtgraph as pg, numpy as np
from .. import tplot_utilities
from pyqtgraph.Qt import QtCore
import pytplot
import CustomAxis.DateAxis as DateAxis
import CustomImage.UpdatingImage as UpdatingImage
import CustomImage.ColorbarImage as ColorbarImage
import CustomAxis.BlankAxis as BlankAxis
from CustomLegend.CustomLegend import CustomLegendItem
import CustomAxis.AxisItem as AxisItem
import CustomViewBox.NoPaddingPlot as NoPaddingPlot
import CustomLinearRegionItem.CustomLinearRegionItem as CustomLinearRegionItem

class TVarFigureSpec(pg.GraphicsLayout):

    def __init__(self, tvar_name, show_xaxis=False):
        self.tvar_name = tvar_name
        self.show_xaxis = show_xaxis
        self.crosshair = pytplot.tplot_opt_glob['crosshair']
        pg.GraphicsLayout.__init__(self)
        self.layout.setHorizontalSpacing(10)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.show_xaxis = show_xaxis
        if 'show_all_axes' in pytplot.tplot_opt_glob:
            if pytplot.tplot_opt_glob['show_all_axes']:
                self.show_xaxis = True
        else:
            if self.show_xaxis:
                self.xaxis = DateAxis(orientation='bottom')
                self.xaxis.setHeight(35)
                self.xaxis.enableAutoSIPrefix(enable=False)
            else:
                self.xaxis = DateAxis(orientation='bottom', showValues=False)
                self.xaxis.setHeight(0)
                self.xaxis.enableAutoSIPrefix(enable=False)
            self.yaxis = AxisItem('left')
            self.yaxis.setWidth(100)
            vb = NoPaddingPlot()
            self.plotwindow = self.addPlot(row=0, col=0, axisItems={'bottom':self.xaxis,  'left':self.yaxis}, viewBox=vb)
            self.legendvb = pg.ViewBox(enableMouse=False)
            self.legendvb.setMaximumWidth(100)
            self.legendvb.setXRange(0, 1, padding=0)
            self.legendvb.setYRange(0, 1, padding=0)
            self.addItem(self.legendvb, 0, 1)
            self.curves = []
            self.colors = self._setcolors()
            self.colormap = self._setcolormap()
            if pytplot.tplot_opt_glob['black_background']:
                self.labelStyle = {'font-size':str(pytplot.data_quants[self.tvar_name].attrs['plot_options']['extras']['char_size']) + 'pt',
                 'color':'#FFF'}
            else:
                self.labelStyle = {'font-size':str(pytplot.data_quants[self.tvar_name].attrs['plot_options']['extras']['char_size']) + 'pt',  'color':'#000'}
        self.hoverlegend = CustomLegendItem(offset=(0, 0))
        self.hoverlegend.setItem('Date:', '0')
        self.hoverlegend.setItem(pytplot.data_quants[self.tvar_name].attrs['plot_options']['xaxis_opt']['crosshair'] + ':', '0')
        self.hoverlegend.setItem(pytplot.data_quants[self.tvar_name].attrs['plot_options']['yaxis_opt']['crosshair'] + ':', '0')
        self.hoverlegend.setItem(pytplot.data_quants[self.tvar_name].attrs['plot_options']['zaxis_opt']['crosshair'] + ':', '0')
        self.hoverlegend.setVisible(False)
        self.hoverlegend.setParentItem(self.plotwindow.vb)

    @staticmethod
    def getaxistype():
        axis_type = 'time'
        link_y_axis = False
        return (axis_type, link_y_axis)

    def _set_crosshairs(self):
        self.vLine = pg.InfiniteLine(angle=90, movable=False, pen=(pg.mkPen('k')))
        self.hLine = pg.InfiniteLine(angle=0, movable=False, pen=(pg.mkPen('k')))
        self.plotwindow.addItem((self.vLine), ignoreBounds=True)
        self.plotwindow.addItem((self.hLine), ignoreBounds=True)

    def _set_roi_lines(self):
        if 'roi_lines' in pytplot.tplot_opt_glob.keys():
            roi_1 = pytplot.tplot_utilities.str_to_int(pytplot.tplot_opt_glob['roi_lines'][0])
            roi_2 = pytplot.tplot_utilities.str_to_int(pytplot.tplot_opt_glob['roi_lines'][1])
            x = pytplot.data_quants[self.tvar_name].coords['time']
            x_sub_1 = abs(x - roi_1 * np.ones(len(x)))
            x_sub_2 = abs(x - roi_2 * np.ones(len(x)))
            x_argmin_1 = np.nanargmin(x_sub_1)
            x_argmin_2 = np.nanargmin(x_sub_2)
            x_closest_1 = x[x_argmin_1]
            x_closest_2 = x[x_argmin_2]
            roi = CustomLinearRegionItem(orientation=(pg.LinearRegionItem.Vertical), values=[x_closest_1, x_closest_2])
            roi.setBrush([211, 211, 211, 130])
            roi.lines[0].setPen('r', width=2.5)
            roi.lines[1].setPen('r', width=2.5)
            self.plotwindow.addItem(roi)

    def buildfigure(self):
        self._setxrange()
        self._setyrange()
        self._setyaxistype()
        self._setzaxistype()
        self._setzrange()
        self._visdata()
        self._setxaxislabel()
        self._setyaxislabel()
        self._addlegend()
        self._addtimebars()
        self._addmouseevents()
        self._set_crosshairs()
        self._set_roi_lines()

    def _setyaxislabel(self):
        if 'axis_subtitle' in pytplot.data_quants[self.tvar_name].attrs['plot_options']['yaxis_opt']:
            label = pytplot.data_quants[self.tvar_name].attrs['plot_options']['yaxis_opt']['axis_label']
            sublabel = pytplot.data_quants[self.tvar_name].attrs['plot_options']['yaxis_opt']['axis_subtitle']
            (self.yaxis.setLabel)(f"{label}
 {sublabel} <\\center>", **self.labelStyle)
        else:
            (self.yaxis.setLabel)((pytplot.data_quants[self.tvar_name].attrs['plot_options']['yaxis_opt']['axis_label']), **self.labelStyle)

    def _setxaxislabel(self):
        if self.show_xaxis:
            (self.xaxis.setLabel)((pytplot.data_quants[self.tvar_name].attrs['plot_options']['xaxis_opt']['axis_label']), **self.labelStyle)

    def getfig(self):
        return self

    def _visdata(self):
        dataset, spec_bins = pytplot.tplot_utilities.convert_tplotxarray_to_pandas_dataframe(self.tvar_name)
        specplot = UpdatingImage(dataset, spec_bins, pytplot.data_quants[self.tvar_name].attrs['plot_options']['spec_bins_ascending'], self._getyaxistype(), self._getzaxistype(), self.colormap, self.ymin, self.ymax, self.zmin, self.zmax)
        self.plotwindow.addItem(specplot)

    def _setyaxistype(self):
        if self._getyaxistype() == 'log':
            self.plotwindow.setLogMode(y=True)
        else:
            self.plotwindow.setLogMode(y=False)

    def _addlegend(self):
        zaxis = AxisItem('right')
        if 'axis_subtitle' in pytplot.data_quants[self.tvar_name].attrs['plot_options']['zaxis_opt']:
            label = pytplot.data_quants[self.tvar_name].attrs['plot_options']['zaxis_opt']['axis_label']
            sublabel = pytplot.data_quants[self.tvar_name].attrs['plot_options']['zaxis_opt']['axis_subtitle']
            (zaxis.setLabel)(f"{label}
 {sublabel} <\\center>", **self.labelStyle)
        else:
            (zaxis.setLabel)((pytplot.data_quants[self.tvar_name].attrs['plot_options']['zaxis_opt']['axis_label']), **self.labelStyle)
        if self.show_xaxis:
            emptyAxis = BlankAxis('bottom')
            emptyAxis.setHeight(35)
            p2 = self.addPlot(row=0, col=1, axisItems={'right':zaxis,  'bottom':emptyAxis}, enableMenu=False, viewBox=(self.legendvb))
        else:
            p2 = self.addPlot(row=0, col=1, axisItems={'right': zaxis}, enableMenu=False, viewBox=(self.legendvb))
            p2.hideAxis('bottom')
        p2.buttonsHidden = True
        p2.setMaximumWidth(100)
        p2.showAxis('right')
        p2.hideAxis('left')
        colorbar = ColorbarImage()
        colorbar.setImage(np.array([np.linspace(1, 2, 200)]).T)
        p2.addItem(colorbar)
        p2.setLogMode(y=(self.zscale == 'log'))
        p2.setXRange(0, 1, padding=0)
        colorbar.setLookupTable(self.colormap)
        if self.zscale == 'log':
            colorbar.setRect(QtCore.QRectF(0, np.log10(self.zmin), 1, np.log10(self.zmax) - np.log10(self.zmin)))
            p2.setYRange((np.log10(self.zmin)), (np.log10(self.zmax)), padding=0)
            p2.setYRange((np.log10(self.zmin)), (np.log10(self.zmax)), padding=0)
        else:
            colorbar.setRect(QtCore.QRectF(0, self.zmin, 1, self.zmax - self.zmin))
            p2.setYRange((self.zmin), (self.zmax), padding=0)
        colorbar.setLookupTable(self.colormap)

    def _addmouseevents(self):
        if self.plotwindow.scene() is not None:
            self.plotwindow.scene().sigMouseMoved.connect(self._mousemoved)

    def _mousemoved(self, evt):
        pos = evt
        flag = 0
        if self.plotwindow.sceneBoundingRect().contains(pos):
            mousePoint = self.plotwindow.vb.mapSceneToView(pos)
            index_x = int(mousePoint.x())
            if self._getyaxistype() == 'log':
                index_y = 10 ** round(float(mousePoint.y()), 4)
            else:
                index_y = round(float(mousePoint.y()), 4)
            dataframe, specframe = pytplot.tplot_utilities.convert_tplotxarray_to_pandas_dataframe(self.tvar_name)
            x = np.asarray(dataframe.index.tolist())
            x_sub = abs(x - index_x * np.ones(len(x)))
            x_argmin = np.nanargmin(x_sub)
            x_closest = x[x_argmin]
            if len(specframe) > 1:
                try:
                    speclength = len(specframe.iloc[x_argmin])
                    y = np.asarray(specframe.iloc[x_argmin, 0:speclength - 1])
                except:
                    speclength = len(specframe.iloc[0])
                    y = np.asarray(specframe.iloc[0, 0:speclength - 1])

            else:
                speclength = len(specframe.iloc[0])
                y = np.asarray(specframe.iloc[0, 0:speclength - 1])
            y_sub = abs(y - index_y * np.ones(y.size))
            y_argmin = np.nanargmin(y_sub)
            y_closest = y[y_argmin]
            data_point = dataframe[y_argmin][x_closest]
            pytplot.hover_time.change_hover_time((int(mousePoint.x())), name=(self.tvar_name))
            if self.crosshair:
                self.vLine.setPos(mousePoint.x())
                self.hLine.setPos(mousePoint.y())
                self.vLine.setVisible(True)
                self.hLine.setVisible(True)
            date = pytplot.tplot_utilities.int_to_str(x_closest)[0:10]
            time = pytplot.tplot_utilities.int_to_str(x_closest)[11:19]
            if self.crosshair:
                self.hoverlegend.setVisible(True)
                self.hoverlegend.setItem('Date:', date)
                self.hoverlegend.setItem(pytplot.data_quants[self.tvar_name].attrs['plot_options']['xaxis_opt']['crosshair'] + ':', time)
                self.hoverlegend.setItem(pytplot.data_quants[self.tvar_name].attrs['plot_options']['yaxis_opt']['crosshair'] + ':', str(y_closest))
                self.hoverlegend.setItem(pytplot.data_quants[self.tvar_name].attrs['plot_options']['zaxis_opt']['crosshair'] + ':', str(data_point))
        else:
            self.hoverlegend.setVisible(False)
            self.vLine.setVisible(False)
            self.hLine.setVisible(False)

    def _getyaxistype(self):
        if 'y_axis_type' in pytplot.data_quants[self.tvar_name].attrs['plot_options']['yaxis_opt']:
            return pytplot.data_quants[self.tvar_name].attrs['plot_options']['yaxis_opt']['y_axis_type']
        return 'linear'

    def _setzaxistype(self):
        if self._getzaxistype() == 'log':
            self.zscale = 'log'
        else:
            self.zscale = 'linear'

    def _getzaxistype(self):
        if 'z_axis_type' in pytplot.data_quants[self.tvar_name].attrs['plot_options']['zaxis_opt']:
            return pytplot.data_quants[self.tvar_name].attrs['plot_options']['zaxis_opt']['z_axis_type']
        return 'log'

    def _setcolors(self):
        if 'line_color' in pytplot.data_quants[self.tvar_name].attrs['plot_options']['extras']:
            return pytplot.data_quants[self.tvar_name].attrs['plot_options']['extras']['line_color']
        return pytplot.tplot_utilities.rgb_color(['k', 'r', 'seagreen', 'b', 'darkturquoise', 'm', 'goldenrod'])

    def _setcolormap(self):
        if 'colormap' in pytplot.data_quants[self.tvar_name].attrs['plot_options']['extras']:
            for cm in pytplot.data_quants[self.tvar_name].attrs['plot_options']['extras']['colormap']:
                return tplot_utilities.return_lut(cm)

        else:
            return tplot_utilities.return_lut('inferno')

    def _setxrange(self):
        if 'x_range' in pytplot.tplot_opt_glob:
            self.plotwindow.setXRange(pytplot.tplot_opt_glob['x_range'][0], pytplot.tplot_opt_glob['x_range'][1])

    def _setyrange(self):
        self.ymin = pytplot.data_quants[self.tvar_name].attrs['plot_options']['yaxis_opt']['y_range'][0]
        self.ymax = pytplot.data_quants[self.tvar_name].attrs['plot_options']['yaxis_opt']['y_range'][1]
        if self._getyaxistype() == 'log' and not pytplot.data_quants[self.tvar_name].attrs['plot_options']['yaxis_opt']['y_range'][0] <= 0:
            if pytplot.data_quants[self.tvar_name].attrs['plot_options']['yaxis_opt']['y_range'][1] <= 0:
                self.ymin = np.nanmin(pytplot.data_quants[self.tvar_name].coords['spec_bins'].values)
                self.ymax = np.nanmax(pytplot.data_quants[self.tvar_name].coords['spec_bins'].values)
            self.plotwindow.vb.setYRange((np.log10(self.ymin)), (np.log10(self.ymax)),
              padding=0)
        else:
            self.plotwindow.vb.setYRange((self.ymin), (self.ymax),
              padding=0)

    def _setzrange(self):
        if 'z_range' in pytplot.data_quants[self.tvar_name].attrs['plot_options']['zaxis_opt']:
            self.zmin = pytplot.data_quants[self.tvar_name].attrs['plot_options']['zaxis_opt']['z_range'][0]
            self.zmax = pytplot.data_quants[self.tvar_name].attrs['plot_options']['zaxis_opt']['z_range'][1]
        else:
            dataset_temp = pytplot.data_quants[self.tvar_name].where(pytplot.data_quants[self.tvar_name] != np.inf)
            dataset_temp = dataset_temp.where(dataset_temp != -np.inf)
            if self.zscale == 'log':
                dataset_temp = dataset_temp.where(dataset_temp > 0)
            self.zmax = dataset_temp.max().max().values
            self.zmin = dataset_temp.min().min().values

    def _addtimebars(self):
        dict_length = len(pytplot.data_quants[self.tvar_name].attrs['plot_options']['time_bar'])
        for i in range(dict_length):
            date_to_highlight = pytplot.data_quants[self.tvar_name].attrs['plot_options']['time_bar'][i]['location']
            color = pytplot.data_quants[self.tvar_name].attrs['plot_options']['time_bar'][i]['line_color']
            thick = pytplot.data_quants[self.tvar_name].attrs['plot_options']['time_bar'][i]['line_width']
            infline = pg.InfiniteLine(pos=date_to_highlight, pen=pg.mkPen(color, width=thick))
            self.plotwindow.addItem(infline)


from gevent import monkey
monkey.patch_all()
import gevent
from time import time
from elasticsearch import Elasticsearch
from elasticsearch.client.ingest import IngestClient
import utils
from control import logger, decfun

@decfun
class ES():

    def __init__(self, host='127.0.0.1', port=9200):

        self.es = None
        self.host = host
        self.port = port

    def is_connected(self):
        return True if self.es and self.es.ping() else False

    def connect(self):
        self.es = Elasticsearch([{'host': self.host, 'port': self.port}])
        if self.is_connected():
            msg = 'Connected to ElasticSearch on'
            logger.info('{msg} {host}:{port}'.format(msg=msg, host=self.host,
                                                      port=self.port))
        else:
            msg = 'Error. Failed to connect to Elasticsearch on'
            logger.error('{msg} {host}:{port}'.format(msg=msg, host=self.host,
                                                       port=self.port))

    def secure_delete_index(self, index_name):

        if not self.is_connected():
            logger.error('Error. Not connected to Elasticsearch')
            return

        if type(index_name) is not str:
            logger.error('Error. Index name must be a str')
            return

        msg = "Do you want to delete the index '{}'?".format(index_name)
        if self.es.indices.exists(index_name):
            if utils.query_yes_no(msg, False):
                res = self.es.indices.delete(index=index_name)
                logger.info("The index {} was deleted successfully".
                             format(index_name))
        return True

    def create_index(self, index_name, mapping=None):

        if not self.is_connected():
            logger.error('Error. Not connected to Elasticsearch')
            return

        if type(index_name) is not str:
            logger.error('Error. Index name must be a str')
            return

        if mapping and not isinstance(mapping, dict):
            logger.error('Error. Mapping must be a dictionary')
            return

        try:
            if not self.es.indices.exists(index_name):
                # Ignore 400 means to ignore "Index Already Exist" error.
                res = self.es.indices.create(index=index_name,
                                             body=mapping,
                                             ignore=[400, 404])
        except Exception as ex:
            logger.error("Error creating the index '{}'.Error: {}".
                         format(index_name, str(ex)))
            return
        else:
            logger.info(("Index '{}' was created successfully").
                            format(index_name))
            return True

    def store_record(self, index_name, doc_name, content):

        if not self.is_connected():
            logger.error('Error. Not connected to Elasticsearch')
            return

        if type(index_name) is not str:
            logger.error('Error. Index name must be a str')
            return

        if type(doc_name) is not str:
            logger.error('Error. Missing document name to store in Elasticsearch')
            return

        if not isinstance(content, dict):
            logger.error('Error. Missing content to store in Elasticsearch')
            return

        t1 = time()
        logger.debug("Gevent (before es_obj.index): '{}'".format(gevent.getcurrent().name))

        try:
            res = self.es.index(index=index_name, doc_type=doc_name, body=content)
        except Exception as ex:
            logger.error('Error. Something went wrong storing the data')
            return
        else:
            logger.debug("Gevent (after es_obj.index: '{}' - {}".
                format(gevent.getcurrent().name, time() - t1))
            return res

    def search(self, index_name, content):

        if not self.is_connected():
            logger.error('Error. Not connected to Elasticsearch')
            return

        if type(index_name) is not str:
            logger.error('Error. Index name must be a str')
            return

        if type(content) is not str:
            loggin.error('Error. Content must be a dictionary')
            return

        return self.es.search(index=index_name, body=content)


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

# Created with YooLiang Technology (侑良科技).
# Author: Qi-Liang Wen (温啓良）
# Web: http://www.yooliang.com/
# Date: 2015/7/12.

from google.appengine.ext import webapp
from google.appengine.ext.webapp import blobstore_handlers
from google.appengine.ext import blobstore
import urllib

plugins_helper = {
    'title': u'使用者檔案管理',
    'desc': u'提供網站使用者進行檔案上傳',
    'controllers': {
        'user_file': {
            'group': u'檔案管理',
            'actions': [
                {'action': 'list', 'name': u'檔案管理'},
                {'action': 'images_list', 'name': u'圖片列表'},
                {'action': 'add', 'name': u'新增檔案管理'},
                {'action': 'edit', 'name': u'編輯檔案管理'},
                {'action': 'view', 'name': u'檢視檔案管理'},
                {'action': 'delete', 'name': u'刪除檔案管理'},
                {'action': 'plugins_check', 'name': u'啟用停用模組'},
            ]
        }
    }
}

class GetFileHandler(blobstore_handlers.BlobstoreDownloadHandler):
    def get(self, source_blob_key):
        if self.request.headers.get('If-None-Match'):
                return self.error(304)

        blob_key = source_blob_key.split('.')[0]
        ext = source_blob_key.split('.')[1]
        if ext in ['jpg', 'jpeg', 'png', 'gif']:
            self.response.headers['Content-Transfer-Encoding'] = 'base64'

        self.response.headers['Cache-Control'] = 'public, max-age=604800'
        self.response.headers['ETag'] = source_blob_key

        #blob_key = str(urllib.unquote(source_blob_key))
        blob = blobstore.get(blob_key)
        if blob:
            self.response.headers['Content-Type'] = blob.content_type
            self.send_blob(blob, save_as=False)
        else:
            return self.error(404)

getfile_app = webapp.WSGIApplication([('/userfile/(.+)+', GetFileHandler)],debug=False)

class DownloadFileHandler(blobstore_handlers.BlobstoreDownloadHandler):
    def get(self, source_blob_key):
        if self.request.headers.get('If-Modified-Since'):
            return self.error(304)

        if source_blob_key.find('.jpg'):
            self.response.headers['Content-Type'] = 'image/jpg'
            self.response.headers['Content-Transfer-Encoding'] = 'base64'
            source_blob_key = source_blob_key.replace('.jpg', '')

        blob_key = str(urllib.unquote(source_blob_key))
        self.response.headers['Cache-Control'] = 'public, max-age=604800'
        if not blobstore.get(blob_key):
            self.redirect("/not_found?path=/download/" + source_blob_key)
        else:
            self.send_blob(blobstore.BlobInfo.get(blob_key), save_as=True)

download_app = webapp.WSGIApplication([('/download/(.+)+', DownloadFileHandler)],debug=False)


import csv
import cv2
import numpy as np

from keras.models import Sequential
from keras.layers import Flatten, Dense, Lambda, Cropping2D
from keras.layers.convolutional import Convolution2D
from keras.layers.pooling import MaxPooling2D

lines = []
with open('./data/driving_log.csv') as csv_file:
    csv_reader = csv.reader(csv_file)
    next(csv_reader) # to skip header row in original data csv
    for line in csv_reader:
        lines.append(line)

correction      = 0.2 # this is a parameter to tune
top_crop        = 70
bot_crop        = 25
img_path        = './data/IMG/'
images          = []
measurements    = []
for line in lines:
    file_name = line[0].split('/')[-1] # centre img
    images.append(cv2.imread(img_path + file_name))
    file_name = line[1].split('/')[-1] # left img
    images.append(cv2.imread(img_path + file_name))
    file_name = line[2].split('/')[-1] # right img
    images.append(cv2.imread(img_path + file_name))

    steering_center = float(line[3])
    # create adjusted steering measurements for the side camera images
    steering_left = steering_center + correction
    steering_right = steering_center - correction

    measurements.extend([steering_center, steering_left, steering_right])

augmented_images, augmented_measurements = [], []
for image, measurement in zip(images, measurements):
    augmented_images.append(image)
    augmented_measurements.append(measurement)
    augmented_images.append(cv2.flip(image, 1))
    augmented_measurements.append(measurement*-1.0)

X_train = np.array(augmented_images)
y_train = np.array(augmented_measurements)

row, col, ch = 160, 320, 3  # Raw image format
# row, col, ch = 160 - top_crop - bot_crop, 320, 3  # Trimmed image format

model = Sequential()
# model.add(Lambda(lambda x: (x/255.0) - 0.5, input_shape=(row,col,ch)))
# model.add(Cropping2D(cropping=((top_crop,bot_crop),(0,0)), input_shape=(row,col,ch)))
model.add(Lambda(lambda x: (x/127.5) - 1., input_shape=(row,col,ch), output_shape=(row,col,ch)))
model.add(Cropping2D(cropping=((top_crop,bot_crop),(0,0)), input_shape=(row,col,ch)))
model.add(Convolution2D(24,5,5, subsample=(2,2), activation="relu"))
model.add(Convolution2D(36,5,5, subsample=(2,2), activation="relu"))
model.add(Convolution2D(48,5,5, subsample=(2,2), activation="relu"))
model.add(Convolution2D(64,3,3, activation="relu"))
model.add(Convolution2D(64,3,3, activation="relu"))
model.add(Flatten())
model.add(Dense(100))
model.add(Dense(50))
model.add(Dense(10))
model.add(Dense(1))

model.compile(loss='mse', optimizer='adam')
model.fit(X_train, y_train, validation_split=0.2, shuffle=True, nb_epoch=3)

model.save('model_nv.h5')


#!/usr/bin/env python3
"""CS 424 Program 1

@author Jacob Rigby
@date 6 July 2017

The dice game Beetle, developed using Python 3.6.1, using a Tk GUI"""

#    Copyright 2017 Jacob Rigby
#
#    Licensed under the Apache License, Version 2.0 (the "License");
#    you may not use this file except in compliance with the License.
#    You may obtain a copy of the License at
#
#        http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS,
#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#    See the License for the specific language governing permissions and
#    limitations under the License.

from random import randint
import signal
import sys  # For capturing Ctrl+C
from tkinter import *       # Tkinter GUI components
from tkinter.ttk import *   # Modern Tkinter ToolKit components

class Die:
    """Die that can roll between 1 and given number. Default of 6 sides"""

    def __init__(self, num_sides=6):
        """Default number of sides is 6"""
        self.__num_sides = num_sides

    def roll(self) -> int:
        """Generates a random number"""
        return randint(1, self.__num_sides)

class Beetle:
    """The core class of this program.

    Holds data related to game state for a single player."""

    def __init__(self, name=None):
        """Creates a new gameboard for a player"""
        self.name = name
        self._body = False
        self._head = False
        self._left_legs = False
        self._right_legs = False
        self._left_antenna = False
        self._right_antenna = False
        self._left_eye = False
        self._right_eye = False

    def turn(self, roll) -> bool:
        """Represents the act of taking a turn in the game.

        Moves forward a step in the state machine"""

        # Create the body if 1 is rolled
        if not self._body and roll == 1:
            print(self.name, "rolled a 1, built body")
            self._body = True
            return True

        # Create the head if 2 is rolled once 1 has already been rolled
        if self._body and not self._head and roll == 2:
            print(self.name, "rolled a 2, built head")
            self._head = True
            return True

        # Create the left legs if 3 is rolled
        if self._head and not self._left_legs and roll == 3:
            print(self.name, "rolled a 3, built left legs")
            self._left_legs = True
            return True

        # Create the right legs if 3 is rolled
        if self._left_legs and not self._right_legs and roll == 3:
            print(self.name, "rolled a 3, built right legs")
            self._right_legs = True
            return True

        # Create the left antenna if 4 is rolled
        if self._right_legs and not self._left_antenna and roll == 4:
            print(self.name, "rolled a 4, built left antenna")
            self._left_antenna = True
            return True

        # Create the right antenna if 4 is rolled
        if self._left_antenna and not self._right_antenna and roll == 4:
            print(self.name, "rolled a 4, built right antenna")
            self._right_antenna = True
            return True

        # Create the left eye if 5 is rolled
        if self._right_antenna and not self._left_eye and roll == 5:
            print(self.name, "rolled a 5, built left eye")
            self._left_eye = True
            return True

        # Create the right eye if 5 is rolled
        if self._left_eye and not self._right_eye and roll == 5:
            print(self.name, "rolled a 5, built right eye")
            self._right_eye = True
            return True

        return False  # we didn't move forward in the state machine

    def __str__(self) -> str:
        """Pretty string representation of the beetle"""
        # There are 8 parts, and 100 percent
        percent_complete = sum([self._body, self._head,
                                self._left_legs, self._right_legs,
                                self._left_antenna, self._right_antenna,
                                self._left_eye, self._right_eye]) * 100 / 8
        return '{} is {}% complete'.format(self.name, percent_complete)

    def print(self):
        """Prints string representation directly to console"""
        print(self)

    def complete(self) -> bool:
        """Returns true if beetle is complete and the game has been won

        All parts must exist."""
        return self._body and self._head and \
               self._left_legs and self._right_legs and \
               self._left_antenna and self._right_antenna and \
               self._left_eye and self._right_eye

class TkBeetle(Beetle):
    """A Beetle that can also draw itself to a Tk label"""
    def __init__(self, name=None, imageLabel=None, app=None):
        Beetle.__init__(self, name=name)
        self._image_label = imageLabel
        self._app = app

    def draw(self):
        """Draws the beetle to image_label using included gif images"""
        image = self._app.none_image
        if self._body:
            image = self._app.body_image
        if self._head:
            image = self._app.head_image
        if self._left_legs:
            image = self._app.left_legs_image
        if self._right_legs:
            image = self._app.right_legs_image
        if self._left_antenna:
            image = self._app.left_antenna_image
        if self._right_antenna:
            image = self._app.right_antenna_image
        if self._left_eye:
            image = self._app.left_eye_image
        if self._right_eye:
            image = self._app.right_eye_image
        self._image_label['image'] = image

    def turn(self, roll):
        """Represents the act of taking a turn in the game.

        Moves forward a step in the state machine,
        then draws itself to the screen"""
        # take a normal turn and store the result to return later
        # before drawing to the screen
        out = Beetle.turn(self, roll)
        self.draw()
        return out

class Game:
    """Class representing a single game.

    One instance will be created for each new game."""
    def __init__(self, app=None):
        """Sets up a new game"""
        self.__players = []
        self._app = app
        self.__players.append(TkBeetle("Player 1", imageLabel=app.beetle_1, app=app))
        self.__players.append(TkBeetle("Player 2", imageLabel=app.beetle_2, app=app))
        self.__die = Die()
        self.complete = False

    def turn(self):
        """Takes a turn for the current player."""
        round_info = ""
        for player in self.__players:
            roll = self.__die.roll()
            player.turn(roll)
            round_info += '{} rolled a {}\n'.format(player.name, roll)
            print(round_info)
            self._app.infotext['text'] = round_info
            if player.complete():
                if player.name is not None or player.name is not "":
                    print(player.name, "wins!")
                print("GAME OVER")
                self.complete = True
                yield True # yield returns a generator object that keeps track of its internal state
            yield False    # so we can call turn multiple times per round, once for each player

    def round(self):
        """Takes a turn for all players"""
        for turn in self.turn():
            if turn:
                return True
        return False

class Application(Frame):
    """Application class wrapping the main GUI frame"""
    def __init__(self, parent):
        Frame.__init__(self, parent, padding="3 3 12 12")
        self._parent = parent
        self.setup()
        self.reset()

    def setup(self):
        """Initialize the window and create some constants"""
        # We need to keep a reference to each of the images to keep them from
        # being garbage collected.
        # Also, they should be "public" so that the beetles can get to them
        self.none_image = PhotoImage(file='none.gif')
        self.body_image = PhotoImage(file='body.gif')
        self.head_image = PhotoImage(file='head.gif')
        self.left_legs_image = PhotoImage(file='left_legs.gif')
        self.right_legs_image = PhotoImage(file='right_legs.gif')
        self.left_antenna_image = PhotoImage(file='left_antenna.gif')
        self.right_antenna_image = PhotoImage(file='right_antenna.gif')
        self.left_eye_image = PhotoImage(file='left_eye.gif')
        self.right_eye_image = PhotoImage(file='right_eye.gif')

        self.grid(column=0, row=0, sticky=(N, W, E, S))
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        # beetle_1 and beetle_2 need to be "public" for the same reason as the images
        self.beetle_1 = Label(self)
        self.beetle_1['image'] = self.none_image
        self.beetle_1.grid(column=0, row=0, sticky=(N, W))

        self.beetle_2 = Label(self)
        self.beetle_2['image'] = self.none_image
        self.beetle_2.grid(column=2, row=0, sticky=(N, E))

        self.infotext = Label(self, text="Testing")
        self.infotext.grid(column=1, row=1, sticky=(W, S, E))

        self._turn_button = Button(self, text="Roll", command=self.turn)
        self._turn_button.grid(column=0, row=1, sticky=(W, S))

        self._reset_button = Button(self, text="Reset", command=self.reset)
        self._reset_button.grid(column=2, row=1, sticky=(E, S))

        for child in self.winfo_children():
            # go through every child and set some params
            child.grid_configure(padx=5, pady=5)

        self._turn_button.focus()

    def turn(self):
        """Takes a turn in the game"""
        self._game.round()
        if self._game.complete:
            self.game_over()

    def game_over(self):
        """Caled when a player wins the game"""
        # The game is over! Disable rolling more turns.
        self._turn_button.state(['disabled'])
        self._reset_button.focus()
        self.infotext['text'] += "Game Over!"

    def reset(self):
        """Resets the game state"""
        self._game = Game(app=self)
        self.beetle_1['image'] = self.none_image
        self.beetle_2['image'] = self.none_image
        self._turn_button.state(['!disabled'])
        self._turn_button.focus()

def cli_main():
    """Main loop of program in basic CLI mode.

    Runs the game until exit requested."""
    # Ensure KeyboardInterrupt is fired on SIGINT
    signal.signal(signal.SIGINT, signal.default_int_handler)

    while True:
        try:
            game = Game()

            while not game.round():
                pass

            key = input("Press Enter to play again or q to exit. ")
            if key == 'q' or key == 'Q':
                exit_game()
            # os.system('cls' if os.name == 'nt' else 'clear')

        except KeyboardInterrupt:
            print()  # we need the extra newline
            exit_game()

def exit_game():
    """Prints goodbye and quits the program"""
    print("Goodbye.")
    sys.exit(0)

def main():
    """Sets up and runs the Tk GUI"""
    root = Tk()
    root.title("Beetle by Jacob Rigby")

    app = Application(parent=root)

    app.mainloop()

if __name__ == '__main__':
    main()


#!/usr/bin/env python
#-*- coding:utf-8 -*-
from koutu_lib import *
AHK_FILE="%s%skoutu-ahk.ahk" % (PATH_NAME,OS_SEP)
'''
s = "123123STRINGabcabc"
print find_between( s, "123", "abc" )
print find_between_r( s, "123", "abc" )
gives:

123STRING
STRINGabc
'''
def substringBetween( s, first, last ):
	try:
		start = s.index( first ) + len( first )
		end = s.index( last, start )
		return s[start:end]
	except ValueError:
		return ""

def substringBetween_r( s, first, last ):
	try:
		start = s.rindex( first ) + len( first )
		end = s.rindex( last, start )
		return s[start:end]
	except ValueError:
		return ""
###tom added on Aug 20, 2015
#flag=12 read descrition from ps for pack users,only 4 numbers
class Photoshop(object):
	def __init__(self, args=None):
		self.initialPs()
		if args==None or len(args)<1:
			return
		#flag=int(args[0])
		#print(flag)
		#if flag==3:
		#	self.readKeywords(args[1])
		#if flag==12:
		#	self.readDescInPS(args[1])
		#	return
		#if flag==4:

	def initialPs(self):
		self.launchAHK()
		#WMI = win32com.client.GetObject("winmgmts:")
		#p_java = WMI.ExecQuery('select * from Win32_Process where Name="AutoHotkey.exe"')
		#print ("test",len(p_java))
		#print ("trying to launch ahk1")
		#initial()
		#print ("Photoshop.Application1")
		psApp = win32com.client.Dispatch("Photoshop.Application")
		try:
			#psApp.BringToFront()
			psApp.Preferences.RulerUnits = 1               # 'for PsUnits --> 1 (psPixels)
			psApp.Preferences.TypeUnits = 1                # 'for PsTypeUnits --> 1 (psPixels)
			psApp.DisplayDialogs = 3
			psApp.Visible = True
			#psApp=appRef
			#print ("Photoshop.Application2")
			# set photoshop to use pixels as dimensions
		except:
			pass
		if psApp == None:
			sys.exit(1)
		self.psApp=psApp
	def launchAHK(self):
		process_name = "AutoHotkey.exe"
		WMI = win32com.client.GetObject('winmgmts:')
		processCodeCov = WMI.ExecQuery('select * from Win32_Process where Name="%s"' % (process_name) )
		if not len(processCodeCov) > 0:
			subprocess.Popen("autohotkey.exe %s" %(AHK_FILE), shell=True) #will return quickly
	def openDOC(self,path):
		psApp=self.psApp
		#psApp = win32com.client.Dispatch("Photoshop.Application")
		try:
			id1 = psApp.CharIDToTypeID( "Opn " )
			desc1 = win32com.client.Dispatch('Photoshop.ActionDescriptor')
			id2 = psApp.CharIDToTypeID( "null" )
			desc1.PutPath( id2, path )
			psApp.ExecuteAction( id1, desc1, 2 )
			print ("open file [%s] in photoshop success" % (path) )
		except:
			print ("open file [%s] in photoshop failed" % (path) )
			pass
		#numDocs = psApp.Documents.count
		#print (numDocs)
		if psApp.Documents.count > 0 :
			return psApp.activeDocument
		return None
	def openPDF(self,path):
		psApp=self.psApp
		doc=None
		try:
			id1 =  psApp.CharIDToTypeID( "Opn " )
			desc1 = win32com.client.Dispatch('Photoshop.ActionDescriptor')
			id2 = psApp.CharIDToTypeID( "As  " )
			desc2 = win32com.client.Dispatch('Photoshop.ActionDescriptor')
			#id3 = psApp.CharIDToTypeID( "Nm  " )
			#name = os.path.basename(path)
			#print(name)
			#desc2.PutString( id3, name )
			id4 = psApp.CharIDToTypeID( "Crop" )
			id5 = psApp.StringIDToTypeID( "cropTo" )
			id6 = psApp.StringIDToTypeID( "boundingBox" )
			desc2.PutEnumerated( id4, id5, id6 )
			id7 = psApp.CharIDToTypeID( "Rslt" )
			id8 = psApp.CharIDToTypeID( "#Rsl" )
			desc2.PutUnitDouble( id7, id8, 72 ) #转化为72像素
			id9 = psApp.CharIDToTypeID( "Md  " )
			id10 = psApp.CharIDToTypeID( "ClrS" )
			id11 = psApp.CharIDToTypeID( "RGBC" )
			desc2.PutEnumerated( id9, id10, id11 )
			#id12 = psApp.CharIDToTypeID( "Dpth" )
			#desc2.PutInteger( id12, 8 )
			id13 = psApp.CharIDToTypeID( "AntA" )
			desc2.PutBoolean( id13, False )
			#id14 = psApp.CharIDToTypeID( "Wdth" )
			#id15 = psApp.CharIDToTypeID( "#Pxl" )
			#desc2.PutUnitDouble( id14, id15, 10509.000000 )
			#id16 = psApp.CharIDToTypeID( "Hght" )
			#id17 = psApp.CharIDToTypeID( "#Pxl" )
			#desc2.PutUnitDouble( id16, id17, 10935.000000 )
			id18 = psApp.CharIDToTypeID( "CnsP" )
			desc2.PutBoolean( id18, False )
			id19 = psApp.StringIDToTypeID( "suppressWarnings" )
			desc2.PutBoolean( id19, True ) #理解为不弹出警告
			id20 = psApp.CharIDToTypeID( "fsel" )
			id21 = psApp.StringIDToTypeID( "pdfSelection" )
			id22 = psApp.StringIDToTypeID( "page" )
			desc2.PutEnumerated( id20, id21, id22 )
			id23 = psApp.CharIDToTypeID( "PgNm" )
			desc2.PutInteger( id23, 1 )
			id24 = psApp.CharIDToTypeID( "PDFG" )
			desc1.PutObject( id2, id24, desc2 )
			id25 = psApp.CharIDToTypeID( "null" )
			desc1.PutPath( id25,  path )
			psApp.ExecuteAction( id1, desc1, 2 )
			print ("open pdf [%s] in photoshop success" % (path) )
		except:
			print ("open pdf [%s] in photoshop failed" % (path) )
			pass
		#numDocs = psApp.Documents.count #当前Photoshop中打开的图片的数量
		#print (numDocs)
		if psApp.Documents.count > 0 :
			return psApp.activeDocument
		return None
	def openInPS(self,path):
		doc=None
		if not os.path.exists(path):
			return doc
		ext = getExtensionName(path).lower()
		if ext=="pdf":
			doc= self.openPDF(path) #pdf特殊的打开方式　tom added on November 17, 2015
		else:
			doc= self.openDOC(path)
			#try:
			#	psApp=self.psApp
			#	doc = psApp.Open(path)
			#	print ("open file [%s] in photoshop success" % (path) )
			#except:
			#	print ("open file [%s] in photoshop failed" % (path) )
			#	pass
		return doc

	def close(self):
		"Close Photoshop"
		try:
			self.psApp.ActiveDocument.Close(2)
		except:
			pass#print("can not open doc in ps")
	def defaultJPEGOptions(self,quality=None,formatOptions=None):
		opts = win32com.client.Dispatch("Photoshop.JPEGSaveOptions")
		opts.EmbedColorProfile = False
		#OPTIMIZEDBASELINE PROGRESSIVE STANDARDBASELINE
		if formatOptions==None:
			formatOptions = 1
		opts.FormatOptions = formatOptions
		if quality==None:
			quality = 8
		opts.Quality = quality
		if(formatOptions==2):
			opts.Scans=3
		return opts
	def saveBigJPEG(self,path,quality=None):
		if quality==None:
			quality=6
		opts=self.defaultJPEGOptions(quality,2)
		self.save(path,opts)
	def save(self,target, opts=None):
		deleteFile(target)
		makeDir(os.path.dirname(target)) #create dir, create parent dir if not exist
		if opts==None:
			opts=self.defaultJPEGOptions()
		try:
			doc = self.psApp.activeDocument
			doc.ChangeMode(2)
			doc.BitsPerChannel=8
			doc.SaveAs(target,opts,True, 2)
			print ("save file [%s] in photoshop" % (target) )
		except:
			pass #print ("cannot save file [%s] in photoshop" % (target) )
	'''def saveJpg(self,path,quality=6):
		makeDir(os.path.dirname(path))
		doc = self.psApp.activeDocument
		opt = self.defaultJPEGOptions(6,2)
		#opt.EmbedColorProfile = True
		#opt.FormatOptions = 1
		#opt.Matte = 1
		#opt.Quality = quality
		#doc.SaveAs(path, opt, True, 2)
		doc.ChangeMode(2)  #ChangeMode.RGB
		#print(doc.Mode)
		doc.BitsPerChannel=8
		doc.SaveAs(path,opt)'''
	def resize(self,maxWidth,maxHeight,addCanvas=False):
		psApp=self.psApp
		try:
			id58 = psApp.CharIDToTypeID("ImgS")
			desc12 = win32com.client.Dispatch('Photoshop.ActionDescriptor')#new ActionDescriptor();
			doc = psApp.activeDocument
			width   = doc.Width
			height  = doc.Height
			print("%sx%s"% (width,height))
			if((width/maxWidth) > (height/maxHeight)):
				id59 = psApp.CharIDToTypeID( "Wdth" )
				id60 = psApp.CharIDToTypeID( "#Pxl" )
				desc12.PutUnitDouble( id59, id60, maxWidth )
			else:
				id59 = psApp.CharIDToTypeID( "Hght" )
				id60 = psApp.CharIDToTypeID( "#Pxl" )
				desc12.PutUnitDouble( id59, id60, maxHeight )
			id61 = psApp.StringIDToTypeID( "scaleStyles" )
			desc12.PutBoolean( id61, True )
			id62 = psApp.CharIDToTypeID( "CnsP" )
			desc12.PutBoolean( id62, True )
			id63 = psApp.CharIDToTypeID( "Intr" )
			id64 = psApp.CharIDToTypeID( "Intp" )
			id65 = psApp.StringIDToTypeID( "bicubicSharper" )
			desc12.PutEnumerated( id63, id64, id65 )
			psApp.ExecuteAction( id58, desc12, 2 )
			print(addCanvas)
			if(addCanvas):
				self.resizeAddCanvas(maxWidth,maxHeight)
		except:
			pass
	def resizeAddCanvas(self,maxWidth,maxHeight):
		psApp=self.psApp
		try:
			id11 = psApp.CharIDToTypeID( "CnvS" )
			desc3 = win32com.client.Dispatch('Photoshop.ActionDescriptor')#new ActionDescriptor();
			doc = psApp.activeDocument
			width   = doc.Width
			height  = doc.Height
			if((width/maxWidth) > (height/maxHeight)):
				id12 = psApp.CharIDToTypeID( "Hght" )
				id13 = psApp.CharIDToTypeID( "#Pxl" )
				desc3.PutUnitDouble( id12, id13, maxWidth )
				id14 = psApp.CharIDToTypeID( "Vrtc" )
				id15 = psApp.CharIDToTypeID( "VrtL" )
			else:
				id12 = psApp.CharIDToTypeID( "Wdth" )
				id13 = psApp.CharIDToTypeID( "#Pxl" )
				desc3.PutUnitDouble( id12, id13, maxHeight )
				id14 = psApp.CharIDToTypeID( "Hrzn" )
				id15 = psApp.CharIDToTypeID( "HrzL" )
			id16 = psApp.CharIDToTypeID( "Cntr" )
			desc3.PutEnumerated( id14, id15, id16 )
			id17 = psApp.StringIDToTypeID( "canvasExtensionColorType" )
			id18 = psApp.StringIDToTypeID( "canvasExtensionColorType" )
			id19 = psApp.CharIDToTypeID( "BckC" )
			desc3.PutEnumerated( id17, id18, id19 )
			psApp.ExecuteAction( id11, desc3, 3 )
		except:
			pass
	def addWaterMark(self,waterMark):
		psApp=self.psApp
		#doc = psApp.Open(waterMark)
		doc= self.openDOC(waterMark)
		if doc==None:
			print("open waterMark failed")
			return
		psApp.ActiveDocument = doc
		try:
			id367 = psApp.CharIDToTypeID( "setd" )
			desc80 = win32com.client.Dispatch('Photoshop.ActionDescriptor')#new ActionDescriptor();
			id368 = psApp.CharIDToTypeID( "null" )
			ref33 = win32com.client.Dispatch('Photoshop.ActionReference')#new ActionReference()
			id369 = psApp.CharIDToTypeID( "Chnl" )
			id370 = psApp.CharIDToTypeID( "fsel" )
			ref33.PutProperty( id369, id370 )
			desc80.PutReference( id368, ref33 )
			id371 = psApp.CharIDToTypeID( "T   " )
			id372 = psApp.CharIDToTypeID( "Ordn" )
			id373 = psApp.CharIDToTypeID( "Al  " )
			desc80.PutEnumerated( id371, id372, id373 )
			psApp.ExecuteAction( id367, desc80, 2 )
			id374 = psApp.CharIDToTypeID( "copy" )
			psApp.ExecuteAction( id374, None, 2 )
			id375 = psApp.CharIDToTypeID( "Cls " )
			psApp.ExecuteAction( id375, None, 2 )
			id376 = psApp.CharIDToTypeID( "past" )
			desc81 = win32com.client.Dispatch('Photoshop.ActionDescriptor')#new ActionDescriptor();
			id377 = psApp.CharIDToTypeID( "AntA" )
			id378 = psApp.CharIDToTypeID( "Annt" )
			id379 = psApp.CharIDToTypeID( "Anno" )
			desc81.PutEnumerated( id377, id378, id379 )
			psApp.ExecuteAction( id376, desc81, 2 )
			id380 = psApp.CharIDToTypeID( "Mrg2" )
			desc82 = win32com.client.Dispatch('Photoshop.ActionDescriptor')#new ActionDescriptor();
			psApp.ExecuteAction( id380, desc82, 2 )
		except:
			pass
#flag==4  customer uploads images to TODO dir
#F:\data\wwwroot\databao\ps-script\BO_Photoshop.py 4 "F:\home\LocalUser\testdoc\A FAIRE\logo bbb 400x400.ai" "2015-05-21"
#flag==3  read keywords in Done dir
#F:\data\wwwroot\databao\ps-script\BO_Photoshop.py 3 "F:\home\LocalUser\testdoc\FAIT\logo bbb 400x400.ai"
'''
def main():
	# open photoshop
	#ps = Photoshop(r'F:\home\LocalUser\bddh\A FAIRE\o.bytes.jpg')
	#ps = Photoshop(r'F:\home\LocalUser\bddh\A FAIRE\BMS-174')
	if len(sys.argv)<2:
		return
	print (len(sys.argv))
	flag=int(sys.argv[1])
	if flag==3 and len(sys.argv)==3:
		Photoshop([flag,sys.argv[2]])
		return
	if flag==4 and (len(sys.argv)==4 or len(sys.argv)==5):
		path =  sys.argv[2] #get first arg
		_date =  sys.argv[3]
		processId=None
		if len(sys.argv)==5:
			processId =  int(sys.argv[4]) #get first arg
			#ps = Photoshop(r'F:\home\LocalUser\bddh\A FAIRE\_JML4068.tif',"2015-08-19",123)
		Photoshop([flag,path,_date,processId])
		return
	pythonLog("run photoshop over",len(sys.argv))
	print ("execute cmd over")
	#os._exit()
	print ("execute cmd over2")
	#sys.exit(1)
	sys.exit(0)

	print ("execute cmd over3")

if __name__ == "__main__":
	main()
'''


"""
This spider is a JobtoolsAU spider created on top of the ATSSpider
scrapy crawl jobtools_au -a mining_job_id=9999 -a iteration=1 -a extract=1 -a url="https://smartjobs.qld.gov.au/jobtools/jncustomsearch.searchResults?in_organid=14904"

sample url:
https://smartjobs.qld.gov.au/jobtools/jncustomsearch.searchResults?in_organid=14904
"""

from re import compile
from scrapy.http import Request, FormRequest
from scrapy.selector import Selector
from urlparse import urljoin, urlparse

from brightcorp.base.atsspiders import ATSSpider
from brightcorp.items import BrightcorpItemLoader
from brightcorp.processors import Prefix, ConvertDateString, Replace

class JobtoolsAU(ATSSpider):

    name = "jobtools_au"
    ref_re = compile(r"in_jnCounter=(\d+)")
    comp_re = compile(r"\('(.*)'\)")
    next_url_anchor = 'jncustomsearch.searchAction'
    hidden_name = 'in_storeNextBut'
    hidden_value = 'Next'
    logo_url = ''
    jobtype_xpath = None
    exp_date_format = None
    post_date_format = '%d-%m-%Y'
    headers = {}
    desc_xpath = [
        '//div[@id="overview"]',
        '//div[@id="further-information"]',
    ]
    alt_desc_xpaths = []

    def parse(self, response):
        sel = Selector(response)
        if not self.expected_job_count_set:
            job_count = sel.xpath(
                '//h2[@class="resultset-title"]/strong[2]/text()').extract()
            if job_count:
                self.expected_job_count = job_count

        jobs = sel.xpath('//ol[@class="search-results jobs"]/li')
        for job in jobs:
            job_url = job.xpath('./h3/a/@href').extract()
            if job_url:
                job_url = urljoin(response.url, job_url[0])
                meta = {
                    'title': job.xpath(
                        './/span[@class="result-title"]/strong/text()'
                        ).extract(),
                    'jobtype': job.xpath(
                        './/span[@class="type"]/text()'
                        ).extract(),
                    'loc': job.xpath(
                        './/strong[@class="locality"]/text()'
                        ).extract(),
                    'sal': job.xpath(
                        './/span[@class="salary"]/text()'
                        ).extract(),
                }
                yield Request(
                    job_url, callback=self.parse_job_callback(), meta=meta
                )

        if jobs:
            for i in self.parse_next_page(response):
                yield i

    def parse_job(self, response):
        loader = BrightcorpItemLoader(response=response)

        loader.add_value('url', response.url)
        loader.add_value('logo_url', self.logo_url)
        loader.add_value('title', response.meta.get('title'))
        loader.add_value('baseSalary', response.meta.get('sal'))
        loader.add_value(
            'location', response.meta.get('loc'), Replace('Location -')
            )
        loader.add_value(
            'jobcategory', response.meta.get('cat'), Replace('Category -')
            )
        loader.add_value(
            'referencenumber', response.url,
            Prefix('%s-' % self.name), re=self.ref_re
            )
        loader.add_value(
            'date', response.meta.get('date'),
            ConvertDateString(self.post_date_format)
            )

        if self.exp_date_format:
            loader.add_value(
                'expiration_date', response.meta.get('exp_date'),
                ConvertDateString(self.exp_date_format)
            )
        else:
            loader.add_xpath(
                'expiration_date',
                '//th[text()="Closing date"]/following-sibling::td/text()',
                ConvertDateString('%d-%b-%Y')
            )

        loader.add_value('jobtype', response.meta.get('jobtype'))
        if not loader.get_output_value('jobtype'):
            loader.add_xpath('jobtype', self.jobtype_xpath)

        loader.add_xpath(
            'company',
            '//script[contains(text(), "writeAgency(")]/text()',
            re=self.comp_re
        )
        loader.add_xpath(
            'jobcategory',
            '//th[text()="Occupational group"]/following-sibling::td/text()'
        )
        loader.add_xpath(
            'duration',
            '//th[text()="Job duration"]/following-sibling::td/text()'
        )
        loader.add_xpath('description', self.desc_xpath)
        if not loader.get_output_value('description'):
            loader.add_xpath('description', self.alt_desc_xpaths)

        yield loader.load_item()

    def get_form_hidden_inputs(self, sel):
        formdata = {}
        inputs = sel.xpath('//form[@name="resultsform"]/input')
        for _input in inputs:
            formdata[''.join(_input.xpath('./@name').extract())] = ''.join(_input.xpath('./@value').extract())

        return formdata

    def parse_next_page(self, response):
        sel = Selector(response)
        form_data = self.get_form_hidden_inputs(sel)
        form_data[self.hidden_name] = self.hidden_value
        yield FormRequest(
            urljoin(response.url, self.next_url_anchor),
            formdata=form_data, callback=self.parse, headers=self.headers
        )


#!/usr/bin/python -d
# -*- coding:utf-8 -*-

import httplib
import logging

BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)

#The background is set with 40 plus the number of the color, and the foreground with 30

#These are the sequences need to get colored ouput
RESET_SEQ = "\033[0m"
COLOR_SEQ = "\033[1;%dm"
BOLD_SEQ = "\033[1m"

def formatter_message(message, use_color = True):
    if use_color:
        message = message.replace("$RESET", RESET_SEQ).replace("$BOLD", BOLD_SEQ)
    else:
        message = message.replace("$RESET", "").replace("$BOLD", "")
    return message

# Custom logger class with multiple destinations
class ColoredLogger(logging.Logger):
	FORMAT = "[$BOLD%(name)-20s$RESET][%(levelname)-18s]  %(message)s ($BOLD%(filename)s$RESET:%(lineno)d)"
	COLOR_FORMAT = formatter_message(FORMAT, True)
	def __init__(self, name):
		logging.Logger.__init__(self, name, logging.DEBUG)

		color_formatter = ColoredFormatter(self.COLOR_FORMAT)

		console = logging.StreamHandler()
		console.setFormatter(color_formatter)

		self.addHandler(console)
		return

def send_req ( server, req):

   conn = httplib.HTTPConnection(server)
   try:
      # descargamos el archivo de configuración XML
      conn.request( "GET", req )
      r = conn.getresponse()
   except Exception as e:
      logging.error("Error realizando la petición %s%s\nMotivo: %s"
                     %(server, req, repr(e)))
      return (3, "Error enviado petición al servidor: %s" %repr(e))
   if r.status != 200:
      aux_string = "Error downloading configuration: %s %s"
      logging.error( aux_string % ( r.status, r.reason ) )
      # devolvemos 1 y la info del error
      return( 1, aux_string % ( r.status, r.reason ) )
   else:
      string_returned= r.read()
      return (0, string_returned)

def process_string( string):
   info_list = string.split(";")
   logging.debug("Cadena stripada y splitada:  %s" %info_list)
   info_dict = {}
   for element in info_list:
      key, value = element.split("=")
      info_dict[key]=value
      logging.debug("Añadiendo al diccionario: [%s=>%s]" %(key, value))
   return info_dict

if __name__ == "__main__":
   logging.basicConfig(level=logging.DEBUG)
   logging.setLoggerClass(ColoredLogger)
   (result, result_str) = send_req("c0s", "/cga-inventory/get_expediente.php?mac=00:22:64:b4:59:71")
   if(int(result)>0):
      logging.error("Error en la petición: %s" %(result_str))
   else:
      logging.info("%s" %result_str)
      process_string(result_str)


# -*- coding: utf8 -*-
# Copyright (c) 2017-2018 THL A29 Limited, a Tencent company. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from tencentcloud.common.abstract_model import AbstractModel

class Age(AbstractModel):
    """人体年龄信息。
    AttributesType 不含 Age 或检测超过 5 个人体时，此参数仍返回，但不具备参考意义。

    """

    def __init__(self):
        """
        :param Type: 人体年龄信息，返回值为以下集合中的一个{小孩,青年,中年,老年}。
        :type Type: str
        :param Probability: Type识别概率值，[0.0,1.0],代表判断正确的概率。如0.8则代表有Type值有80%概率正确。
        :type Probability: float
        """
        self.Type = None
        self.Probability = None

    def _deserialize(self, params):
        self.Type = params.get("Type")
        self.Probability = params.get("Probability")

class AttributesOptions(AbstractModel):
    """返回人体属性选项，此值不填则为不需要返回，可以选择的值为以下六个。
    Age、Bag、Gender、Orientation、UpperBodyCloth、LowerBodyCloth，详细的解释请看对象描述
    需注意本接口最多返回面积最大的 5 个人体属性信息，超过 5 个人体（第 6 个及以后的人体）的人体属性不具备参考意义。

    """

    def __init__(self):
        """
        :param Age: 返回年龄信息
        :type Age: bool
        :param Bag: 返回随身挎包信息
        :type Bag: bool
        :param Gender: 返回性别信息
        :type Gender: bool
        :param Orientation: 返回朝向信息
        :type Orientation: bool
        :param UpperBodyCloth: 返回上装信息
        :type UpperBodyCloth: bool
        :param LowerBodyCloth: 返回下装信息
        :type LowerBodyCloth: bool
        """
        self.Age = None
        self.Bag = None
        self.Gender = None
        self.Orientation = None
        self.UpperBodyCloth = None
        self.LowerBodyCloth = None

    def _deserialize(self, params):
        self.Age = params.get("Age")
        self.Bag = params.get("Bag")
        self.Gender = params.get("Gender")
        self.Orientation = params.get("Orientation")
        self.UpperBodyCloth = params.get("UpperBodyCloth")
        self.LowerBodyCloth = params.get("LowerBodyCloth")

class Bag(AbstractModel):
    """人体是否挎包。
    AttributesType 不含 Bag 或检测超过 5 个人体时，此参数仍返回，但不具备参考意义。

    """

    def __init__(self):
        """
        :param Type: 挎包信息，返回值为以下集合中的一个{双肩包, 斜挎包, 手拎包, 无包}。
        :type Type: str
        :param Probability: Type识别概率值，[0.0,1.0],代表判断正确的概率。如0.8则代表有Type值有80%概率正确。
        :type Probability: float
        """
        self.Type = None
        self.Probability = None

    def _deserialize(self, params):
        self.Type = params.get("Type")
        self.Probability = params.get("Probability")

class BodyAttributeInfo(AbstractModel):
    """图中检测出的人体属性信息。

    """

    def __init__(self):
        """
        :param Age: 人体年龄信息。
AttributesType 不含 Age 或检测超过 5 个人体时，此参数仍返回，但不具备参考意义。
注意：此字段可能返回 null，表示取不到有效值。
        :type Age: :class:`tencentcloud.bda.v20200324.models.Age`
        :param Bag: 人体是否挎包。
AttributesType 不含 Bag 或检测超过 5 个人体时，此参数仍返回，但不具备参考意义。
注意：此字段可能返回 null，表示取不到有效值。
        :type Bag: :class:`tencentcloud.bda.v20200324.models.Bag`
        :param Gender: 人体性别信息。
AttributesType 不含 Gender 或检测超过 5 个人体时，此参数仍返回，但不具备参考意义。
注意：此字段可能返回 null，表示取不到有效值。
        :type Gender: :class:`tencentcloud.bda.v20200324.models.Gender`
        :param Orientation: 人体朝向信息。
AttributesType 不含 UpperBodyCloth 或检测超过 5 个人体时，此参数仍返回，但不具备参考意义。
注意：此字段可能返回 null，表示取不到有效值。
        :type Orientation: :class:`tencentcloud.bda.v20200324.models.Orientation`
        :param UpperBodyCloth: 人体上衣属性信息。
AttributesType 不含 Orientation 或检测超过 5 个人体时，此参数仍返回，但不具备参考意义。
注意：此字段可能返回 null，表示取不到有效值。
        :type UpperBodyCloth: :class:`tencentcloud.bda.v20200324.models.UpperBodyCloth`
        :param LowerBodyCloth: 人体下衣属性信息。
AttributesType 不含 LowerBodyCloth 或检测超过 5 个人体时，此参数仍返回，但不具备参考意义。
注意：此字段可能返回 null，表示取不到有效值。
        :type LowerBodyCloth: :class:`tencentcloud.bda.v20200324.models.LowerBodyCloth`
        """
        self.Age = None
        self.Bag = None
        self.Gender = None
        self.Orientation = None
        self.UpperBodyCloth = None
        self.LowerBodyCloth = None

    def _deserialize(self, params):
        if params.get("Age") is not None:
            self.Age = Age()
            self.Age._deserialize(params.get("Age"))
        if params.get("Bag") is not None:
            self.Bag = Bag()
            self.Bag._deserialize(params.get("Bag"))
        if params.get("Gender") is not None:
            self.Gender = Gender()
            self.Gender._deserialize(params.get("Gender"))
        if params.get("Orientation") is not None:
            self.Orientation = Orientation()
            self.Orientation._deserialize(params.get("Orientation"))
        if params.get("UpperBodyCloth") is not None:
            self.UpperBodyCloth = UpperBodyCloth()
            self.UpperBodyCloth._deserialize(params.get("UpperBodyCloth"))
        if params.get("LowerBodyCloth") is not None:
            self.LowerBodyCloth = LowerBodyCloth()
            self.LowerBodyCloth._deserialize(params.get("LowerBodyCloth"))

class BodyDetectResult(AbstractModel):
    """图中检测出来的人体框。

    """

    def __init__(self):
        """
        :param Confidence: 检测出的人体置信度。
误识率百分之十对应的阈值是0.14；误识率百分之五对应的阈值是0.32；误识率百分之二对应的阈值是0.62；误识率百分之一对应的阈值是0.81。
通常情况建议使用阈值0.32，可适用大多数情况。
        :type Confidence: float
        :param BodyRect: 图中检测出来的人体框
        :type BodyRect: :class:`tencentcloud.bda.v20200324.models.BodyRect`
        :param BodyAttributeInfo: 图中检测出的人体属性信息。
        :type BodyAttributeInfo: :class:`tencentcloud.bda.v20200324.models.BodyAttributeInfo`
        """
        self.Confidence = None
        self.BodyRect = None
        self.BodyAttributeInfo = None

    def _deserialize(self, params):
        self.Confidence = params.get("Confidence")
        if params.get("BodyRect") is not None:
            self.BodyRect = BodyRect()
            self.BodyRect._deserialize(params.get("BodyRect"))
        if params.get("BodyAttributeInfo") is not None:
            self.BodyAttributeInfo = BodyAttributeInfo()
            self.BodyAttributeInfo._deserialize(params.get("BodyAttributeInfo"))

class BodyJointsResult(AbstractModel):
    """人体框和人体关键点信息。

    """

    def __init__(self):
        """
        :param BoundBox: 图中检测出来的人体框。
        :type BoundBox: :class:`tencentcloud.bda.v20200324.models.BoundRect`
        :param BodyJoints: 14个人体关键点的坐标，人体关键点详见KeyPointInfo。
        :type BodyJoints: list of KeyPointInfo
        :param Confidence: 检测出的人体置信度，0-1之间，数值越高越准确。
        :type Confidence: float
        """
        self.BoundBox = None
        self.BodyJoints = None
        self.Confidence = None

    def _deserialize(self, params):
        if params.get("BoundBox") is not None:
            self.BoundBox = BoundRect()
            self.BoundBox._deserialize(params.get("BoundBox"))
        if params.get("BodyJoints") is not None:
            self.BodyJoints = []
            for item in params.get("BodyJoints"):
                obj = KeyPointInfo()
                obj._deserialize(item)
                self.BodyJoints.append(obj)
        self.Confidence = params.get("Confidence")

class BodyRect(AbstractModel):
    """人体框

    """

    def __init__(self):
        """
        :param X: 人体框左上角横坐标。
        :type X: int
        :param Y: 人体框左上角纵坐标。
        :type Y: int
        :param Width: 人体宽度。
        :type Width: int
        :param Height: 人体高度。
        :type Height: int
        """
        self.X = None
        self.Y = None
        self.Width = None
        self.Height = None

    def _deserialize(self, params):
        self.X = params.get("X")
        self.Y = params.get("Y")
        self.Width = params.get("Width")
        self.Height = params.get("Height")

class BoundRect(AbstractModel):
    """人体框

    """

    def __init__(self):
        """
        :param X: 人体框左上角横坐标。
        :type X: int
        :param Y: 人体框左上角纵坐标。
        :type Y: int
        :param Width: 人体宽度。
        :type Width: int
        :param Height: 人体高度。
        :type Height: int
        """
        self.X = None
        self.Y = None
        self.Width = None
        self.Height = None

    def _deserialize(self, params):
        self.X = params.get("X")
        self.Y = params.get("Y")
        self.Width = params.get("Width")
        self.Height = params.get("Height")

class Candidate(AbstractModel):
    """识别出的最相似候选人。

    """

    def __init__(self):
        """
        :param PersonId: 人员ID。
        :type PersonId: str
        :param TraceId: 人体轨迹ID。
        :type TraceId: str
        :param Score: 候选者的匹配得分。
十万人体库下，误识率百分之五对应的分数为70分；误识率百分之二对应的分数为80分；误识率百分之一对应的分数为90分。

二十万人体库下，误识率百分之五对应的分数为80分；误识率百分之二对应的分数为90分；误识率百分之一对应的分数为95分。

通常情况建议使用分数80分（保召回）。若希望获得较高精度，建议使用分数90分（保准确）。
        :type Score: float
        """
        self.PersonId = None
        self.TraceId = None
        self.Score = None

    def _deserialize(self, params):
        self.PersonId = params.get("PersonId")
        self.TraceId = params.get("TraceId")
        self.Score = params.get("Score")

class CreateGroupRequest(AbstractModel):
    """CreateGroup请求参数结构体

    """

    def __init__(self):
        """
        :param GroupName: 人体库名称，[1,60]个字符，可修改，不可重复。
        :type GroupName: str
        :param GroupId: 人体库 ID，不可修改，不可重复。支持英文、数字、-%@#&_，长度限制64B。
        :type GroupId: str
        :param Tag: 人体库信息备注，[0，40]个字符。
        :type Tag: str
        :param BodyModelVersion: 人体识别所用的算法模型版本。
目前入参仅支持 “1.0”1个输入。 默认为"1.0"。
不同算法模型版本对应的人体识别算法不同，新版本的整体效果会优于旧版本，后续我们将推出更新版本。
        :type BodyModelVersion: str
        """
        self.GroupName = None
        self.GroupId = None
        self.Tag = None
        self.BodyModelVersion = None

    def _deserialize(self, params):
        self.GroupName = params.get("GroupName")
        self.GroupId = params.get("GroupId")
        self.Tag = params.get("Tag")
        self.BodyModelVersion = params.get("BodyModelVersion")

class CreateGroupResponse(AbstractModel):
    """CreateGroup返回参数结构体

    """

    def __init__(self):
        """
        :param RequestId: 唯一请求 ID，每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
        :type RequestId: str
        """
        self.RequestId = None

    def _deserialize(self, params):
        self.RequestId = params.get("RequestId")

class CreatePersonRequest(AbstractModel):
    """CreatePerson请求参数结构体

    """

    def __init__(self):
        """
        :param GroupId: 待加入的人员库ID。
        :type GroupId: str
        :param PersonName: 人员名称。[1，60]个字符，可修改，可重复。
        :type PersonName: str
        :param PersonId: 人员ID，单个腾讯云账号下不可修改，不可重复。
支持英文、数字、-%@#&_，，长度限制64B。
        :type PersonId: str
        :param Trace: 人体轨迹信息。
        :type Trace: :class:`tencentcloud.bda.v20200324.models.Trace`
        """
        self.GroupId = None
        self.PersonName = None
        self.PersonId = None
        self.Trace = None

    def _deserialize(self, params):
        self.GroupId = params.get("GroupId")
        self.PersonName = params.get("PersonName")
        self.PersonId = params.get("PersonId")
        if params.get("Trace") is not None:
            self.Trace = Trace()
            self.Trace._deserialize(params.get("Trace"))

class CreatePersonResponse(AbstractModel):
    """CreatePerson返回参数结构体

    """

    def __init__(self):
        """
        :param TraceId: 人员轨迹唯一标识。
        :type TraceId: str
        :param BodyModelVersion: 人体识别所用的算法模型版本。
        :type BodyModelVersion: str
        :param InputRetCode: 输入的人体轨迹图片中的合法性校验结果。
只有为0时结果才有意义。
-1001: 输入图片不合法。-1002: 输入图片不能构成轨迹。
        :type InputRetCode: int
        :param InputRetCodeDetails: 输入的人体轨迹图片中的合法性校验结果详情。
-1101:图片无效，-1102:url不合法。-1103:图片过大。-1104:图片下载失败。-1105:图片解码失败。-1109:图片分辨率过高。-2023:轨迹中有非同人图片。-2024: 轨迹提取失败。-2025: 人体检测失败。
RetCode 的顺序和入参中Images 或 Urls 的顺序一致。
        :type InputRetCodeDetails: list of int
        :param RequestId: 唯一请求 ID，每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
        :type RequestId: str
        """
        self.TraceId = None
        self.BodyModelVersion = None
        self.InputRetCode = None
        self.InputRetCodeDetails = None
        self.RequestId = None

    def _deserialize(self, params):
        self.TraceId = params.get("TraceId")
        self.BodyModelVersion = params.get("BodyModelVersion")
        self.InputRetCode = params.get("InputRetCode")
        self.InputRetCodeDetails = params.get("InputRetCodeDetails")
        self.RequestId = params.get("RequestId")

class CreateTraceRequest(AbstractModel):
    """CreateTrace请求参数结构体

    """

    def __init__(self):
        """
        :param PersonId: 人员ID。
        :type PersonId: str
        :param Trace: 人体轨迹信息。
        :type Trace: :class:`tencentcloud.bda.v20200324.models.Trace`
        """
        self.PersonId = None
        self.Trace = None

    def _deserialize(self, params):
        self.PersonId = params.get("PersonId")
        if params.get("Trace") is not None:
            self.Trace = Trace()
            self.Trace._deserialize(params.get("Trace"))

class CreateTraceResponse(AbstractModel):
    """CreateTrace返回参数结构体

    """

    def __init__(self):
        """
        :param TraceId: 人员轨迹唯一标识。
        :type TraceId: str
        :param BodyModelVersion: 人体识别所用的算法模型版本。
        :type BodyModelVersion: str
        :param InputRetCode: 输入的人体轨迹图片中的合法性校验结果。
只有为0时结果才有意义。
-1001: 输入图片不合法。-1002: 输入图片不能构成轨迹。
        :type InputRetCode: int
        :param InputRetCodeDetails: 输入的人体轨迹图片中的合法性校验结果详情。
-1101:图片无效，-1102:url不合法。-1103:图片过大。-1104:图片下载失败。-1105:图片解码失败。-1109:图片分辨率过高。-2023:轨迹中有非同人图片。-2024: 轨迹提取失败。-2025: 人体检测失败。
        :type InputRetCodeDetails: list of int
        :param RequestId: 唯一请求 ID，每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
        :type RequestId: str
        """
        self.TraceId = None
        self.BodyModelVersion = None
        self.InputRetCode = None
        self.InputRetCodeDetails = None
        self.RequestId = None

    def _deserialize(self, params):
        self.TraceId = params.get("TraceId")
        self.BodyModelVersion = params.get("BodyModelVersion")
        self.InputRetCode = params.get("InputRetCode")
        self.InputRetCodeDetails = params.get("InputRetCodeDetails")
        self.RequestId = params.get("RequestId")

class DeleteGroupRequest(AbstractModel):
    """DeleteGroup请求参数结构体

    """

    def __init__(self):
        """
        :param GroupId: 人体库ID。
        :type GroupId: str
        """
        self.GroupId = None

    def _deserialize(self, params):
        self.GroupId = params.get("GroupId")

class DeleteGroupResponse(AbstractModel):
    """DeleteGroup返回参数结构体

    """

    def __init__(self):
        """
        :param RequestId: 唯一请求 ID，每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
        :type RequestId: str
        """
        self.RequestId = None

    def _deserialize(self, params):
        self.RequestId = params.get("RequestId")

class DeletePersonRequest(AbstractModel):
    """DeletePerson请求参数结构体

    """

    def __init__(self):
        """
        :param PersonId: 人员ID。
        :type PersonId: str
        """
        self.PersonId = None

    def _deserialize(self, params):
        self.PersonId = params.get("PersonId")

class DeletePersonResponse(AbstractModel):
    """DeletePerson返回参数结构体

    """

    def __init__(self):
        """
        :param RequestId: 唯一请求 ID，每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
        :type RequestId: str
        """
        self.RequestId = None

    def _deserialize(self, params):
        self.RequestId = params.get("RequestId")

class DetectBodyJointsRequest(AbstractModel):
    """DetectBodyJoints请求参数结构体

    """

    def __init__(self):
        """
        :param Image: 图片 base64 数据，base64 编码后大小不可超过5M。
支持PNG、JPG、JPEG、BMP，不支持 GIF 图片。
        :type Image: str
        :param Url: 图片的 Url 。对应图片 base64 编码后大小不可超过5M。
Url、Image必须提供一个，如果都提供，只使用 Url。
图片存储于腾讯云的Url可保障更高下载速度和稳定性，建议图片存储于腾讯云。
非腾讯云存储的Url速度和稳定性可能受一定影响。
支持PNG、JPG、JPEG、BMP，不支持 GIF 图片。
        :type Url: str
        """
        self.Image = None
        self.Url = None

    def _deserialize(self, params):
        self.Image = params.get("Image")
        self.Url = params.get("Url")

class DetectBodyJointsResponse(AbstractModel):
    """DetectBodyJoints返回参数结构体

    """

    def __init__(self):
        """
        :param BodyJointsResults: 图中检测出的人体框和人体关键点， 包含14个人体关键点的坐标，建议根据人体框置信度筛选出合格的人体；
        :type BodyJointsResults: list of BodyJointsResult
        :param RequestId: 唯一请求 ID，每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
        :type RequestId: str
        """
        self.BodyJointsResults = None
        self.RequestId = None

    def _deserialize(self, params):
        if params.get("BodyJointsResults") is not None:
            self.BodyJointsResults = []
            for item in params.get("BodyJointsResults"):
                obj = BodyJointsResult()
                obj._deserialize(item)
                self.BodyJointsResults.append(obj)
        self.RequestId = params.get("RequestId")

class DetectBodyRequest(AbstractModel):
    """DetectBody请求参数结构体

    """

    def __init__(self):
        """
        :param Image: 人体图片 Base64 数据。
图片 base64 编码后大小不可超过5M。
图片分辨率不得超过 2048*2048。
支持PNG、JPG、JPEG、BMP，不支持 GIF 图片。
        :type Image: str
        :param Url: 人体图片 Url 。
Url、Image必须提供一个，如果都提供，只使用 Url。
图片 base64 编码后大小不可超过5M。
图片分辨率不得超过 2048*2048。
图片存储于腾讯云的Url可保障更高下载速度和稳定性，建议图片存储于腾讯云。
非腾讯云存储的Url速度和稳定性可能受一定影响。
支持PNG、JPG、JPEG、BMP，不支持 GIF 图片。
        :type Url: str
        :param MaxBodyNum: 最多检测的人体数目，默认值为1（仅检测图片中面积最大的那个人体）； 最大值10 ，检测图片中面积最大的10个人体。
        :type MaxBodyNum: int
        :param AttributesOptions: 是否返回年龄、性别、朝向等属性。
可选项有 Age、Bag、Gender、UpperBodyCloth、LowerBodyCloth、Orientation。
如果此参数为空则为不需要返回。
需要将属性组成一个用逗号分隔的字符串，属性之间的顺序没有要求。
关于各属性的详细描述，参见下文出参。
最多返回面积最大的 5 个人体属性信息，超过 5 个人体（第 6 个及以后的人体）的 BodyAttributesInfo 不具备参考意义。
        :type AttributesOptions: :class:`tencentcloud.bda.v20200324.models.AttributesOptions`
        """
        self.Image = None
        self.Url = None
        self.MaxBodyNum = None
        self.AttributesOptions = None

    def _deserialize(self, params):
        self.Image = params.get("Image")
        self.Url = params.get("Url")
        self.MaxBodyNum = params.get("MaxBodyNum")
        if params.get("AttributesOptions") is not None:
            self.AttributesOptions = AttributesOptions()
            self.AttributesOptions._deserialize(params.get("AttributesOptions"))

class DetectBodyResponse(AbstractModel):
    """DetectBody返回参数结构体

    """

    def __init__(self):
        """
        :param BodyDetectResults: 图中检测出来的人体框。
        :type BodyDetectResults: list of BodyDetectResult
        :param BodyModelVersion: 人体识别所用的算法模型版本。
        :type BodyModelVersion: str
        :param RequestId: 唯一请求 ID，每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
        :type RequestId: str
        """
        self.BodyDetectResults = None
        self.BodyModelVersion = None
        self.RequestId = None

    def _deserialize(self, params):
        if params.get("BodyDetectResults") is not None:
            self.BodyDetectResults = []
            for item in params.get("BodyDetectResults"):
                obj = BodyDetectResult()
                obj._deserialize(item)
                self.BodyDetectResults.append(obj)
        self.BodyModelVersion = params.get("BodyModelVersion")
        self.RequestId = params.get("RequestId")

class Gender(AbstractModel):
    """人体性别信息。
    AttributesType 不含 Gender 或检测超过 5 个人体时，此参数仍返回，但不具备参考意义。

    """

    def __init__(self):
        """
        :param Type: 性别信息，返回值为以下集合中的一个 {男性, 女性}
        :type Type: str
        :param Probability: Type识别概率值，[0.0,1.0],代表判断正确的概率。如0.8则代表有Type值有80%概率正确。
        :type Probability: float
        """
        self.Type = None
        self.Probability = None

    def _deserialize(self, params):
        self.Type = params.get("Type")
        self.Probability = params.get("Probability")

class GetGroupListRequest(AbstractModel):
    """GetGroupList请求参数结构体

    """

    def __init__(self):
        """
        :param Offset: 起始序号，默认值为0。
        :type Offset: int
        :param Limit: 返回数量，默认值为10，最大值为1000。
        :type Limit: int
        """
        self.Offset = None
        self.Limit = None

    def _deserialize(self, params):
        self.Offset = params.get("Offset")
        self.Limit = params.get("Limit")

class GetGroupListResponse(AbstractModel):
    """GetGroupList返回参数结构体

    """

    def __init__(self):
        """
        :param GroupInfos: 返回的人体库信息。
        :type GroupInfos: list of GroupInfo
        :param GroupNum: 人体库总数量。
        :type GroupNum: int
        :param RequestId: 唯一请求 ID，每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
        :type RequestId: str
        """
        self.GroupInfos = None
        self.GroupNum = None
        self.RequestId = None

    def _deserialize(self, params):
        if params.get("GroupInfos") is not None:
            self.GroupInfos = []
            for item in params.get("GroupInfos"):
                obj = GroupInfo()
                obj._deserialize(item)
                self.GroupInfos.append(obj)
        self.GroupNum = params.get("GroupNum")
        self.RequestId = params.get("RequestId")

class GetPersonListRequest(AbstractModel):
    """GetPersonList请求参数结构体

    """

    def __init__(self):
        """
        :param GroupId: 人体库ID。
        :type GroupId: str
        :param Offset: 起始序号，默认值为0。
        :type Offset: int
        :param Limit: 返回数量，默认值为10，最大值为1000。
        :type Limit: int
        """
        self.GroupId = None
        self.Offset = None
        self.Limit = None

    def _deserialize(self, params):
        self.GroupId = params.get("GroupId")
        self.Offset = params.get("Offset")
        self.Limit = params.get("Limit")

class GetPersonListResponse(AbstractModel):
    """GetPersonList返回参数结构体

    """

    def __init__(self):
        """
        :param PersonInfos: 返回的人员信息。
        :type PersonInfos: list of PersonInfo
        :param PersonNum: 该人体库的人员数量。
        :type PersonNum: int
        :param BodyModelVersion: 人体识别所用的算法模型版本。
        :type BodyModelVersion: str
        :param RequestId: 唯一请求 ID，每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
        :type RequestId: str
        """
        self.PersonInfos = None
        self.PersonNum = None
        self.BodyModelVersion = None
        self.RequestId = None

    def _deserialize(self, params):
        if params.get("PersonInfos") is not None:
            self.PersonInfos = []
            for item in params.get("PersonInfos"):
                obj = PersonInfo()
                obj._deserialize(item)
                self.PersonInfos.append(obj)
        self.PersonNum = params.get("PersonNum")
        self.BodyModelVersion = params.get("BodyModelVersion")
        self.RequestId = params.get("RequestId")

class GroupInfo(AbstractModel):
    """返回的人员库信息。

    """

    def __init__(self):
        """
        :param GroupName: 人体库名称。
        :type GroupName: str
        :param GroupId: 人体库ID。
        :type GroupId: str
        :param Tag: 人体库信息备注。
        :type Tag: str
        :param BodyModelVersion: 人体识别所用的算法模型版本。
        :type BodyModelVersion: str
        :param CreationTimestamp: Group的创建时间和日期 CreationTimestamp。CreationTimestamp 的值是自 Unix 纪元时间到Group创建时间的毫秒数。
Unix 纪元时间是 1970 年 1 月 1 日星期四，协调世界时 (UTC) 。
        :type CreationTimestamp: int
        """
        self.GroupName = None
        self.GroupId = None
        self.Tag = None
        self.BodyModelVersion = None
        self.CreationTimestamp = None

    def _deserialize(self, params):
        self.GroupName = params.get("GroupName")
        self.GroupId = params.get("GroupId")
        self.Tag = params.get("Tag")
        self.BodyModelVersion = params.get("BodyModelVersion")
        self.CreationTimestamp = params.get("CreationTimestamp")

class KeyPointInfo(AbstractModel):
    """人体关键点信息

    """

    def __init__(self):
        """
        :param KeyPointType: 代表不同位置的人体关键点信息，返回值为以下集合中的一个 [头部,颈部,右肩,右肘,右腕,左肩,左肘,左腕,右髋,右膝,右踝,左髋,左膝,左踝]
        :type KeyPointType: str
        :param X: 人体关键点横坐标
        :type X: float
        :param Y: 人体关键点纵坐标
        :type Y: float
        """
        self.KeyPointType = None
        self.X = None
        self.Y = None

    def _deserialize(self, params):
        self.KeyPointType = params.get("KeyPointType")
        self.X = params.get("X")
        self.Y = params.get("Y")

class LowerBodyCloth(AbstractModel):
    """下衣属性信息

    """

    def __init__(self):
        """
        :param Color: 下衣颜色信息。
        :type Color: :class:`tencentcloud.bda.v20200324.models.LowerBodyClothColor`
        :param Length: 下衣长度信息 。
        :type Length: :class:`tencentcloud.bda.v20200324.models.LowerBodyClothLength`
        :param Type: 下衣类型信息。
        :type Type: :class:`tencentcloud.bda.v20200324.models.LowerBodyClothType`
        """
        self.Color = None
        self.Length = None
        self.Type = None

    def _deserialize(self, params):
        if params.get("Color") is not None:
            self.Color = LowerBodyClothColor()
            self.Color._deserialize(params.get("Color"))
        if params.get("Length") is not None:
            self.Length = LowerBodyClothLength()
            self.Length._deserialize(params.get("Length"))
        if params.get("Type") is not None:
            self.Type = LowerBodyClothType()
            self.Type._deserialize(params.get("Type"))

class LowerBodyClothColor(AbstractModel):
    """下衣颜色信息

    """

    def __init__(self):
        """
        :param Type: 下衣颜色信息，返回值为以下集合中的一个{ 黑色系, 灰白色系, 彩色} 。
        :type Type: str
        :param Probability: Type识别概率值，[0.0,1.0],代表判断正确的概率。如0.8则代表有Type值有80%概率正确。
        :type Probability: float
        """
        self.Type = None
        self.Probability = None

    def _deserialize(self, params):
        self.Type = params.get("Type")
        self.Probability = params.get("Probability")

class LowerBodyClothLength(AbstractModel):
    """下衣长度信息

    """

    def __init__(self):
        """
        :param Type: 下衣长度信息，返回值为以下集合中的一个，{长, 短} 。
        :type Type: str
        :param Probability: Type识别概率值，[0.0,1.0],代表判断正确的概率。如0.8则代表有Type值有80%概率正确。
        :type Probability: float
        """
        self.Type = None
        self.Probability = None

    def _deserialize(self, params):
        self.Type = params.get("Type")
        self.Probability = params.get("Probability")

class LowerBodyClothType(AbstractModel):
    """下衣类型信息

    """

    def __init__(self):
        """
        :param Type: 下衣类型，返回值为以下集合中的一个 {裤子,裙子} 。
        :type Type: str
        :param Probability: Type识别概率值，[0.0,1.0],代表判断正确的概率。如0.8则代表有Type值有80%概率正确。
        :type Probability: float
        """
        self.Type = None
        self.Probability = None

    def _deserialize(self, params):
        self.Type = params.get("Type")
        self.Probability = params.get("Probability")

class ModifyGroupRequest(AbstractModel):
    """ModifyGroup请求参数结构体

    """

    def __init__(self):
        """
        :param GroupId: 人体库ID。
        :type GroupId: str
        :param GroupName: 人体库名称。
        :type GroupName: str
        :param Tag: 人体库信息备注。
        :type Tag: str
        """
        self.GroupId = None
        self.GroupName = None
        self.Tag = None

    def _deserialize(self, params):
        self.GroupId = params.get("GroupId")
        self.GroupName = params.get("GroupName")
        self.Tag = params.get("Tag")

class ModifyGroupResponse(AbstractModel):
    """ModifyGroup返回参数结构体

    """

    def __init__(self):
        """
        :param RequestId: 唯一请求 ID，每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
        :type RequestId: str
        """
        self.RequestId = None

    def _deserialize(self, params):
        self.RequestId = params.get("RequestId")

class ModifyPersonInfoRequest(AbstractModel):
    """ModifyPersonInfo请求参数结构体

    """

    def __init__(self):
        """
        :param PersonId: 人员ID。
        :type PersonId: str
        :param PersonName: 人员名称。
        :type PersonName: str
        """
        self.PersonId = None
        self.PersonName = None

    def _deserialize(self, params):
        self.PersonId = params.get("PersonId")
        self.PersonName = params.get("PersonName")

class ModifyPersonInfoResponse(AbstractModel):
    """ModifyPersonInfo返回参数结构体

    """

    def __init__(self):
        """
        :param RequestId: 唯一请求 ID，每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
        :type RequestId: str
        """
        self.RequestId = None

    def _deserialize(self, params):
        self.RequestId = params.get("RequestId")

class Orientation(AbstractModel):
    """人体朝向信息。
    AttributesType 不含 Orientation 或检测超过 5 个人体时，此参数仍返回，但不具备参考意义。

    """

    def __init__(self):
        """
        :param Type: 人体朝向信息，返回值为以下集合中的一个 {正向, 背向, 左, 右}。
        :type Type: str
        :param Probability: Type识别概率值，[0.0,1.0],代表判断正确的概率。如0.8则代表有Type值有80%概率正确。
        :type Probability: float
        """
        self.Type = None
        self.Probability = None

    def _deserialize(self, params):
        self.Type = params.get("Type")
        self.Probability = params.get("Probability")

class PersonInfo(AbstractModel):
    """人员信息。

    """

    def __init__(self):
        """
        :param PersonName: 人员名称。
        :type PersonName: str
        :param PersonId: 人员ID。
        :type PersonId: str
        :param TraceInfos: 包含的人体轨迹图片信息列表。
        :type TraceInfos: list of TraceInfo
        """
        self.PersonName = None
        self.PersonId = None
        self.TraceInfos = None

    def _deserialize(self, params):
        self.PersonName = params.get("PersonName")
        self.PersonId = params.get("PersonId")
        if params.get("TraceInfos") is not None:
            self.TraceInfos = []
            for item in params.get("TraceInfos"):
                obj = TraceInfo()
                obj._deserialize(item)
                self.TraceInfos.append(obj)

class SearchTraceRequest(AbstractModel):
    """SearchTrace请求参数结构体

    """

    def __init__(self):
        """
        :param GroupId: 希望搜索的人体库ID。
        :type GroupId: str
        :param Trace: 人体轨迹信息。
        :type Trace: :class:`tencentcloud.bda.v20200324.models.Trace`
        :param MaxPersonNum: 单张被识别的人体轨迹返回的最相似人员数量。
默认值为5，最大值为100。
 例，设MaxPersonNum为8，则返回Top8相似的人员信息。 值越大，需要处理的时间越长。建议不要超过10。
        :type MaxPersonNum: int
        :param TraceMatchThreshold: 出参Score中，只有超过TraceMatchThreshold值的结果才会返回。
默认为0。范围[0, 100.0]。
        :type TraceMatchThreshold: float
        """
        self.GroupId = None
        self.Trace = None
        self.MaxPersonNum = None
        self.TraceMatchThreshold = None

    def _deserialize(self, params):
        self.GroupId = params.get("GroupId")
        if params.get("Trace") is not None:
            self.Trace = Trace()
            self.Trace._deserialize(params.get("Trace"))
        self.MaxPersonNum = params.get("MaxPersonNum")
        self.TraceMatchThreshold = params.get("TraceMatchThreshold")

class SearchTraceResponse(AbstractModel):
    """SearchTrace返回参数结构体

    """

    def __init__(self):
        """
        :param Candidates: 识别出的最相似候选人。
        :type Candidates: list of Candidate
        :param InputRetCode: 输入的人体轨迹图片中的合法性校验结果。
只有为0时结果才有意义。
-1001: 输入图片不合法。-1002: 输入图片不能构成轨迹。
        :type InputRetCode: int
        :param InputRetCodeDetails: 输入的人体轨迹图片中的合法性校验结果详情。
-1101:图片无效，-1102:url不合法。-1103:图片过大。-1104:图片下载失败。-1105:图片解码失败。-1109:图片分辨率过高。-2023:轨迹中有非同人图片。-2024: 轨迹提取失败。-2025: 人体检测失败。
        :type InputRetCodeDetails: list of int
        :param BodyModelVersion: 人体识别所用的算法模型版本。
        :type BodyModelVersion: str
        :param RequestId: 唯一请求 ID，每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
        :type RequestId: str
        """
        self.Candidates = None
        self.InputRetCode = None
        self.InputRetCodeDetails = None
        self.BodyModelVersion = None
        self.RequestId = None

    def _deserialize(self, params):
        if params.get("Candidates") is not None:
            self.Candidates = []
            for item in params.get("Candidates"):
                obj = Candidate()
                obj._deserialize(item)
                self.Candidates.append(obj)
        self.InputRetCode = params.get("InputRetCode")
        self.InputRetCodeDetails = params.get("InputRetCodeDetails")
        self.BodyModelVersion = params.get("BodyModelVersion")
        self.RequestId = params.get("RequestId")

class SegmentPortraitPicRequest(AbstractModel):
    """SegmentPortraitPic请求参数结构体

    """

    def __init__(self):
        """
        :param Image: 图片 base64 数据，base64 编码后大小不可超过5M。
图片分辨率须小于2000*2000。
支持PNG、JPG、JPEG、BMP，不支持 GIF 图片。
        :type Image: str
        :param Url: 图片的 Url 。
Url、Image必须提供一个，如果都提供，只使用 Url。
图片分辨率须小于2000*2000 ，图片 base64 编码后大小不可超过5M。
图片存储于腾讯云的Url可保障更高下载速度和稳定性，建议图片存储于腾讯云。
非腾讯云存储的Url速度和稳定性可能受一定影响。
支持PNG、JPG、JPEG、BMP，不支持 GIF 图片。
        :type Url: str
        """
        self.Image = None
        self.Url = None

    def _deserialize(self, params):
        self.Image = params.get("Image")
        self.Url = params.get("Url")

class SegmentPortraitPicResponse(AbstractModel):
    """SegmentPortraitPic返回参数结构体

    """

    def __init__(self):
        """
        :param ResultImage: 处理后的图片 base64 数据，透明背景图
        :type ResultImage: str
        :param ResultMask: 一个通过 Base64 编码的文件，解码后文件由 Float 型浮点数组成。这些浮点数代表原图从左上角开始的每一行的每一个像素点，每一个浮点数的值是原图相应像素点位于人体轮廓内的置信度（0-1）转化的灰度值（0-255）
        :type ResultMask: str
        :param RequestId: 唯一请求 ID，每次请求都会返回。定位问题时需要提供该次请求的 RequestId。
        :type RequestId: str
        """
        self.ResultImage = None
        self.ResultMask = None
        self.RequestId = None

    def _deserialize(self, params):
        self.ResultImage = params.get("ResultImage")
        self.ResultMask = params.get("ResultMask")
        self.RequestId = params.get("RequestId")

class Trace(AbstractModel):
    """人体轨迹信息

    """

    def __init__(self):
        """
        :param Images: 人体轨迹图片 Base64 数组。
数组长度最小为1最大为5。
单个图片 base64 编码后大小不可超过2M。
支持PNG、JPG、JPEG、BMP，不支持 GIF 图片。
        :type Images: list of str
        :param Urls: 人体轨迹图片 Url 数组。
数组长度最小为1最大为5。
单个图片 base64 编码后大小不可超过2M。
Urls、Images必须提供一个，如果都提供，只使用 Urls。
图片存储于腾讯云的Url可保障更高下载速度和稳定性，建议图片存储于腾讯云。
非腾讯云存储的Url速度和稳定性可能受一定影响。
支持PNG、JPG、JPEG、BMP，不支持 GIF 图片。
        :type Urls: list of str
        :param BodyRects: 若输入的Images 和 Urls 是已经裁剪后的人体小图，则可以忽略本参数。
若否，或图片中包含多个人体，则需要通过本参数来指定图片中的人体框。
顺序对应 Images 或 Urls 中的顺序。
当不输入本参数时，我们将认为输入图片已是经过裁剪后的人体小图，不会进行人体检测而直接进行特征提取处理。
        :type BodyRects: list of BodyRect
        """
        self.Images = None
        self.Urls = None
        self.BodyRects = None

    def _deserialize(self, params):
        self.Images = params.get("Images")
        self.Urls = params.get("Urls")
        if params.get("BodyRects") is not None:
            self.BodyRects = []
            for item in params.get("BodyRects"):
                obj = BodyRect()
                obj._deserialize(item)
                self.BodyRects.append(obj)

class TraceInfo(AbstractModel):
    """人体轨迹信息。

    """

    def __init__(self):
        """
        :param TraceId: 人体轨迹ID。
        :type TraceId: str
        :param BodyIds: 包含的人体轨迹图片Id列表。
        :type BodyIds: list of str
        """
        self.TraceId = None
        self.BodyIds = None

    def _deserialize(self, params):
        self.TraceId = params.get("TraceId")
        self.BodyIds = params.get("BodyIds")

class UpperBodyCloth(AbstractModel):
    """上衣属性信息

    """

    def __init__(self):
        """
        :param Texture: 上衣纹理信息。
        :type Texture: :class:`tencentcloud.bda.v20200324.models.UpperBodyClothTexture`
        :param Color: 上衣颜色信息。
        :type Color: :class:`tencentcloud.bda.v20200324.models.UpperBodyClothColor`
        :param Sleeve: 上衣衣袖信息。
        :type Sleeve: :class:`tencentcloud.bda.v20200324.models.UpperBodyClothSleeve`
        """
        self.Texture = None
        self.Color = None
        self.Sleeve = None

    def _deserialize(self, params):
        if params.get("Texture") is not None:
            self.Texture = UpperBodyClothTexture()
            self.Texture._deserialize(params.get("Texture"))
        if params.get("Color") is not None:
            self.Color = UpperBodyClothColor()
            self.Color._deserialize(params.get("Color"))
        if params.get("Sleeve") is not None:
            self.Sleeve = UpperBodyClothSleeve()
            self.Sleeve._deserialize(params.get("Sleeve"))

class UpperBodyClothColor(AbstractModel):
    """上衣颜色信息。

    """

    def __init__(self):
        """
        :param Type: 上衣颜色信息，返回值为以下集合中的一个 {红色系, 黄色系, 绿色系, 蓝色系, 黑色系, 灰白色系。
        :type Type: str
        :param Probability: Type识别概率值，[0.0,1.0],代表判断正确的概率。如0.8则代表有Type值有80%概率正确。
        :type Probability: float
        """
        self.Type = None
        self.Probability = None

    def _deserialize(self, params):
        self.Type = params.get("Type")
        self.Probability = params.get("Probability")

class UpperBodyClothSleeve(AbstractModel):
    """上衣衣袖信息。

    """

    def __init__(self):
        """
        :param Type: 上衣衣袖信息, 返回值为以下集合中的一个 {长袖, 短袖}。
        :type Type: str
        :param Probability: Type识别概率值，[0.0,1.0],代表判断正确的概率。如0.8则代表有Type值有80%概率正确。
        :type Probability: float
        """
        self.Type = None
        self.Probability = None

    def _deserialize(self, params):
        self.Type = params.get("Type")
        self.Probability = params.get("Probability")

class UpperBodyClothTexture(AbstractModel):
    """上衣纹理信息。

    """

    def __init__(self):
        """
        :param Type: 上衣纹理信息，返回值为以下集合中的一个, {纯色, 格子, 大色块}。
        :type Type: str
        :param Probability: Type识别概率值，[0.0,1.0], 代表判断正确的概率。如0.8则代表有Type值有80%概率正确。
        :type Probability: float
        """
        self.Type = None
        self.Probability = None

    def _deserialize(self, params):
        self.Type = params.get("Type")
        self.Probability = params.get("Probability")


"""
Trying to apply twice haar detection to a plate to narrow down the character region only
DID NOT SUCCEED
"""
import sys

from rekkariDetectionSave import DetectPlate
from filterImage import FilterImage
from filterCharacterRegions import FilterCharacterRegions
from initialCharacterRegions import InitialCharacterRegions
from myTesseract import MyTesseract
import glob

# image to plate(s)
files=glob.glob(sys.argv[1])
print(files)
if len(files)==0:
    raise FileNotFoundError('no files with search term: '+sys.argv[1])

for file in files:
    # 1 image to possible plates
    app1 = DetectPlate(imageFileName=file)
    plates = app1.getNpPlates()
    app1.showPlates()
    print(file+' number of plates found '+ str(len(plates)))

    for plate in plates:
        # from a plate image to list of six-rectangles
        #app2 = FilterImage(npImage=plate)
        #plate = app2.filterOtsu()
        app3 = FilterCharacterRegions(npImage=plate)
        platesWithCharacterRegions = app3.imageToPlatesWithCharacterRegions()

        app5 = MyTesseract()
        app5.setImage(plate)
        #app3.showImage()
        app5.defineSixPlateCharacters(platesWithCharacterRegions,lang='eng')
        print("PLATE, confidence, char conf:", \
              app5.getFinalString(), \
              app5.getFinalPlateConfidence(), \
              app5.getFinalCharacterConfidences() )


from django.apps import apps as global_apps
from django.db import migrations
from django.db.utils import OperationalError

from django.db.backends.postgresql.schema import DatabaseSchemaEditor as PgSE

sql = '''

'''

reverse_sql = '''

'''

def forwards(app, schema_editor):
    models = app.all_models['api']
    if not isinstance(schema_editor, PgSE):
        print('this migration is only guaranteed to work with Postgres!')
        return
    try:
        schema_editor.execute('alter table south_migrationhistory rename to legacy_south_migrationhistory;')
        print('Found legacy application')
        for model in models:
            schema_editor.execute('drop table api_{0} cascade;'.format(model))
            schema_editor.execute('alter table portal_{0} rename to api_{0};'.format(model))
            schema_editor.execute('alter sequence portal_{0}_id_seq rename to api_{0}_id_seq;'.format(model))

    except Exception as e:
        pass

def backwards(app, schema_editor):
    models = app.all_models['api']
    if not isinstance(schema_editor, PgSE):
        print('this migration is only guaranteed to work with Postgres!')
        return
    try:
        schema_editor.execute('alter table legacy_south_migrationhistory rename to south_migrationhistory;')
        print('Found migrated application')
        for model in models:
            schema_editor.execute('alter table api_{0} rename to portal_{0};'.format(model))
            schema_editor.execute('alter sequence api_{0}_id_seq rename to portal_{0}_id_seq;'.format(model))
    except Exception as e:
        pass

class Migration(migrations.Migration):
    operations = [
        migrations.RunPython(forwards, backwards),
    ]
    dependencies = [
        ('api', '0001_initial'),
    ]