"""
Client to server command handling
"""
from mysqlproxy.packet import ERRPacket, OKPacket, EOFPacket
from mysqlproxy.query_response import ResultSetText, ResultSetRowText, \
    ResultSetBinary, ResultSetRowBinary, ColumnDefinition
from mysqlproxy import column_types
import sys
import socket
from StringIO import StringIO
from datetime import datetime
from pymysql import err
from pymysql.cursors import DictCursor
import logging
import re

_LOG = logging.getLogger(__name__)

COMMAND_CODES = {
    0x01: ('quit', 'cli_command_quit'),
    0x02: ('init_db', 'cli_change_db'),
    0x03: ('query', 'cli_command_query'),
    0x04: ('field_list', 'cli_command_field_list'),
    0x05: ('create_db', 'unsupported_client_command'),
    0x06: ('drop_db', 'unsupported_client_command'),
    0x07: ('refresh', 'unsupported_client_command'),
    0x08: ('shutdown', 'unsupported_client_command'),
    0x09: ('statistics', 'unsupported_client_command'),
    0x0a: ('process_info', 'unsupported_client_command'),
    0x0b: ('connect', 'unsupported_client_command'), # internal
    0x0c: ('kill', 'unsupported_client_command'),
    0x0d: ('debug', 'unsupported_client_command'),
    0x0e: ('ping', 'cli_command_ping'),
    0x0f: ('time', 'unsupported_client_command'), # internal
    0x10: ('delayed_insert', 'unsupported_client_command'), # internal
    0x11: ('change_user', 'unsupported_client_command'),
    0x16: ('stmt_prepare', 'unsupported_client_command'),
    0x17: ('stmt_execute', 'unsupported_client_command'),
    0x18: ('stmt_send_long_data', 'unsupported_client_command'),
    0x19: ('stmt_close', 'unsupported_client_command'),
    0x19: ('stmt_reset', 'unsupported_client_command'),
    0x1f: ('reset_connection', 'unsupported_client_command'),
    0x1d: ('daemon', 'unsupported_client_command'), # internal
}

def cli_command_ping(session_obj, pkt, code):
    session_obj.send_payload(
        OKPacket(
            session_obj.client_capabilities,
            0, 0, seq_id=1, info=u'PONG'
            )
        )
    return True

def unsupported_client_command(session_obj, pkt, code):
    command_name = COMMAND_CODES[code][0]
    session_obj.send_payload(
        ERRPacket(
            session_obj.client_capabilities,
            error_code=9990,
            error_msg=u'The command "%s" is unsupported by mysqlproxy' % command_name,
            seq_id=1
        ))
    return True

def unknown_cli_command(session, pkt_data, code):
    session.send_payload(ERRPacket(
        session.client_capabilities, \
                error_code=9997, error_msg='Unimplemented command (%d)' % code, seq_id=1))
    return True

def handle_client_command(session, cmd_packet_data):
    """
    Send response based on command given.
    Return true if server should continue, false if it
    should disconnect.
    """
    if len(cmd_packet_data) == 0:
        raise ValueError('no command data')
    cli_command = ord(cmd_packet_data[0])
    if cli_command not in COMMAND_CODES:
        _LOG.debug('Received command code %x', cli_command)
        session.send_payload(ERRPacket(
            session.client_capabilities, \
                    error_code=9999, error_msg='Wait what?', seq_id=1))
        return True

    command_name, command_fn_name = COMMAND_CODES[cli_command]
    _LOG.debug('Received command code %x (%s)' % \
            (cli_command, command_fn_name))
    command_fn = globals().get(command_fn_name, unknown_cli_command)
    return command_fn(session, cmd_packet_data[1:], cli_command)

def cli_change_db(session_obj, pkt_data, code):
    schema_name = pkt_data
    response = session_obj.proxy_obj.change_db(schema_name)
    session_obj.send_payload(response)
    return True

def cli_command_quit(session, pkt_data, code):
    try:
        session.send_payload(OKPacket(
            session.client_capabilities, \
            0, 0, seq_id=1, info='no please come back :('))
    except socket.error:
        pass # the hell with it.  Some clients close prematurely anyway.
    return False

def cli_command_query(session_obj, pkt_data, code):
    query = pkt_data
    _LOG.debug('Got query command: %s' % query)
    if query.lower() == 'select @@version_comment limit 1':
        # intercept the MySQL client getting version info, replace with our own
        response = ResultSetText(session_obj.client_capabilities,
            flags=session_obj.server_status)
        col_name = u'@@version_comment'
        row_val = u'mysqlproxy-0.1'
        response.add_column(col_name, column_types.VAR_STRING, len(row_val))
        response.add_row([row_val])
    else:
        proxy = session_obj.proxy_obj
        plugin_continue, plugin_ret = proxy.plugins.call_hooks('com_query',
            query, session_obj)
        if plugin_continue:
            response = proxy.build_response_from_query(query)
        else:
            response = plugin_ret
    session_obj.send_payload(response)
    return True

def cli_command_field_list(session_obj, pkt_data, code):
    table_name, wildcard = pkt_data.split('\x00')[:2]
    if not re.match(r'^[a-zA-Z0-9_]+', table_name):
        session_obj.send_payload(ERRPacket(
            session_obj.client_capabilities, 1049,
            u'Invalid table name', seq_id=1))
        return True

    if not re.match(r'^[a-zA-Z0-9_%]+', table_name):
        session_obj.send_payload(ERRPacket(
            session_obj.client_capabilities, 1049,
            u'Invalid wildcard', seq_id=1))
        return True

    cli_con = session_obj.proxy_obj.client_conn
    field_list = cli_con.get_field_list(table_name, wildcard)
    results = ResultSetText(session_obj.client_capabilities,
        flags=session_obj.server_status)
    for colname, coltype, col_max_len, \
            field_len, field_max_len, _, _ in field_list:
        results.add_column(unicode(colname), coltype, field_len)
    # TODO: server status negoatiation
    tx_packets = results.columns
    for i in range(0, len(tx_packets)):
        tx_packets[i].seq_id = i+1
    tx_eof = EOFPacket(
        session_obj.client_capabilities,
        status_flags=session_obj.server_status,
        seq_id=len(tx_packets)+1)
    tx_packets.append(tx_eof)
    return True


from flask import Blueprint, url_for, render_template, request, session, jsonify, abort, redirect
from market.models import MarketOrderDetail, MarketOrderMain, db
from market.utils import hash_password, apply_query_filter
from market.views.manage import manage

@manage.route("/orderinfo/<order_id>", methods=['GET', 'POST'])
def order_home(order_id):
    if request.method == 'GET':
        order = MarketOrderMain.query.filter(MarketOrderMain.order_id==order_id).first_or_404()
        details = MarketOrderDetail.query.filter(MarketOrderDetail.order_id==order_id).all()
        details_list = []
        for d in details:
            details_list.append(d.todict())
        return jsonify({
            'order':order.todict(),
            'details': details_list
        })
    elif request.method == 'POST':
        if request.form.get('hiddenidinput') != '':
            print('-------')
            print(request.form.get('hiddenidinput'))
            id = int(request.form.get('hiddenidinput'))  # this is update
            update_dict = dict(request.form)
            update_dict.pop('hiddenidinput')
            print(update_dict)
            for k in update_dict:
                update_dict[k] = update_dict[k][0]
            print(update_dict)
            MarketOrderMain.query.filter(
                MarketOrderMain.id == id).update(update_dict)
            try:
                db.session.commit()
                return jsonify({"success": True})
            except Exception as e:
                print(e)
                db.session.rollback()
                return jsonify({"success": False})
        _m = MarketOrderMain(
            order_id=request.form.get("order_id"),
            staff_id=request.form.get("staff_id"),
            gross_quantity=request.form.get('gross_quantity'),
            gross_price=request.form.get('gross_price'),
            time=request.form.get('time'),
            comment=request.form.get('comment')
        )
        db.session.add(_m)
        print('==========')
        try:
            db.session.commit()
            return jsonify({"success": True})
        except Exception as e:
            print(e)
            db.session.rollback()
            return jsonify({"success": False})
    else:
        pass

@manage.route('/order', methods=['POST', 'GET'])
def manage_order():
    if request.method == 'POST':
        if request.values.get('delete'):
            order_id = request.values.get('del_order_id')
            order = MarketOrderMain.query.filter_by(order_id=order_id).first()
            order.delete = True
            try:
                db.session.commit()
            except Exception as e:
                print(e)
                db.session.rollback()
                return jsonify({"success": False, "details": "fail"})

            details = MarketOrderDetail.query.filter_by(
                order_id=order_id, delete=False).all()
            for i in range(len(details)):
                details[i].delete = True
            try:
                db.session.commit()
            except Exception as e:
                print(e)
                db.session.rollback()
                return jsonify({"success": False, "details": "fail"})
        return redirect(url_for('manage.manage_order'))
    args_dict = dict(request.values)
    orders = apply_query_filter(
        query_filter=args_dict,
        target_class=MarketOrderMain,
        target_query=MarketOrderMain.query.filter(MarketOrderMain.delete == False)
    ).all()
    details = apply_query_filter(
        args_dict,
        MarketOrderDetail,
        MarketOrderDetail.query.filter(MarketOrderDetail.delete == False),
    ).all()
    # MarketOrderMain.query.filter(MarketOrderMain.delete==False).all()
    #details = MarketOrderDetail.query.filter(MarketOrderDetail.delete == False).all()
    result = []
    details_result = []
    for i, order in enumerate(orders):
        this_order = {}
        this_order['main'] = order
        this_order['details'] = []
        for detail in details:
            if detail.order_id == order.order_id:
                this_order['details'].append(detail)
        result.append(this_order)
    return render_template('manage_order.html', result=result, title="订单查询")

@manage.route("/order/add", methods=['POST', 'GET'])
def manage_order_add():
    if request.method == 'GET':
        return render_template('manage_order_add.html', title="添加订单")
    elif request.method == 'POST':
        if request.values.get('isupdate')=='123':
            print('is update')
            this_order = request.values.get('updateorderid')
            MarketOrderMain.query\
                .filter(MarketOrderMain.order_id==this_order)\
                    .delete()
            MarketOrderDetail.query\
                .filter(MarketOrderDetail.order_id==this_order)\
                    .delete()
            try:
                db.session.commit()
            except Exception as e:
                print(e)
                db.session.rollback()
                abort(500)
        order, details = get_order(request.values)
        db.session.add(order)
        for detail in details:
            db.session.add(detail)

        try:
            db.session.commit()
            return jsonify({"success": True, "data": "success"})
        except Exception as e:
            print(e)
            db.session.rollback()
            return jsonify({"success": False, "details": "fail"})

@manage.route("/order/modify", methods=['POST'])
def manage_order_modify():
    if request.values.get('modify') == "true":
        order, details = get_order(request.values)

        return "mangae order modify"
    else:
        print(request.values.get('updateid'))
        order = MarketOrderMain.query.filter_by(
            order_id=request.values.get('order_id')
        )[0]
        details = MarketOrderDetail.query.filter_by(order_id=order.order_id)\
            .order_by(MarketOrderDetail.order_detail_id.asc()).all()
        order.details = details
        return render_template("manage_order_modify.html", title="修改订单", order=order)

@manage.route('/order/batchadd', methods=['POST'])
def order_batchadd():
    batch = request.get_json().get('info')
    print(batch)
    orders = batch.split(';')
    print(orders)

    for order in orders:
        order=order.split('\n')
        print(order)
        i = 0
        while order[i] == '':
            i += 1
        orderinfo = order[i].split(',')
        print(orderinfo)
        db.session.add(MarketOrderMain(
            order_id=orderinfo[0],
            staff_id=orderinfo[1],
            gross_quantity=orderinfo[2],
            gross_price=orderinfo[3],
            time=orderinfo[4],
            comment=orderinfo[5]
        ))
        order_id = orderinfo[0]
        i += 1
        while i < len(order):
            detail = order[i].split(',')
            print(detail)
            db.session.add(MarketOrderDetail(
                order_detail_id=detail[0],
                order_id=order_id,
                merchandise_id=detail[1],
                merchandise_quantity=detail[2],
                unit_price=detail[3],
                gross_price=detail[4],
                comment=detail[5]
            ))
            i += 1
    try:
        db.session.commit()
        return jsonify({"success":True})
    except Exception as e:
        print(e)
        db.session.rollback()
        return jsonify({"success":False})

def get_order(order_form):
    order = MarketOrderMain(
        order_id=order_form.get("order_id"),
        staff_id=order_form.get("staff_id"),
        gross_quantity=order_form.get('gross_quantity'),
        gross_price=order_form.get('gross_price'),
        time=order_form.get('time'),
        comment=order_form.get('comment')
    )

    order_id = order_form.get("order_id")
    order_detail_id = order_form.getlist("order_detail_id[]")
    merchandise_id = order_form.getlist("merchandise_id[]")
    merchandise_quantity = order_form.getlist("merchandise_quantity[]")
    unit_price = order_form.getlist("unit_price[]")
    detail_gross_price = order_form.getlist("detail_gross_price[]")
    detail_comment = order_form.getlist("detail_comment[]")
    details = []
    for i in range(len(order_detail_id)):
        print(i)
        detail = MarketOrderDetail(
            order_detail_id=order_detail_id[i],
            order_id=order_id,
            merchandise_id=merchandise_id[i],
            merchandise_quantity=merchandise_quantity[i],
            unit_price=unit_price[i],
            gross_price=detail_gross_price[i],
            comment=detail_comment[i]
        )
        details.append(detail)
    return order, details


from __future__ import annotations

import fnmatch
import json

from elasticsearch import Elasticsearch
from elasticsearch.exceptions import NotFoundError

from .utilities import MissingIndexException, get_random_id, query_params

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

class FakeElasticsearch(Elasticsearch):
    __documents_dict = None

    def __init__(self):
        super().__init__("http://localhost:9200")
        self.__documents_dict = {}

    @query_params()
    def ping(self, params=None):
        return True

    @query_params()
    def info(self, params=None):
        return {
            "status": 200,
            "cluster_name": "elasticmock",
            "version": {
                "lucene_version": "4.10.4",
                "build_hash": "00f95f4ffca6de89d68b7ccaf80d148f1f70e4d4",
                "number": "1.7.5",
                "build_timestamp": "2016-02-02T09:55:30Z",
                "build_snapshot": False,
            },
            "name": "Nightwatch",
            "tagline": "You Know, for Search",
        }

    @query_params()
    def sample_log_response(self, headers=None, params=None):
        return {
            "_shards": {"failed": 0, "skipped": 0, "successful": 7, "total": 7},
            "hits": {
                "hits": [
                    {
                        "_id": "jdeZT4kBjAZqZnexVUxk",
                        "_index": ".ds-filebeat-8.8.2-2023.07.09-000001",
                        "_score": 2.482621,
                        "_source": {
                            "@timestamp": "2023-07-13T14:13:15.140Z",
                            "asctime": "2023-07-09T07:47:43.907+0000",
                            "container": {"id": "airflow"},
                            "dag_id": "example_bash_operator",
                            "ecs": {"version": "8.0.0"},
                            "execution_date": "2023_07_09T07_47_32_000000",
                            "filename": "taskinstance.py",
                            "input": {"type": "log"},
                            "levelname": "INFO",
                            "lineno": 1144,
                            "log": {
                                "file": {
                                    "path": "/opt/airflow/Documents/GitHub/airflow/logs/"
                                    "dag_id=example_bash_operator'"
                                    "/run_id=owen_run_run/task_id=run_after_loop/attempt=1.log"
                                },
                                "offset": 0,
                            },
                            "log.offset": 1688888863907337472,
                            "log_id": "example_bash_operator-run_after_loop-owen_run_run--1-1",
                            "message": "Dependencies all met for "
                            "dep_context=non-requeueable deps "
                            "ti=<TaskInstance: "
                            "example_bash_operator.run_after_loop "
                            "owen_run_run [queued]>",
                            "task_id": "run_after_loop",
                            "try_number": "1",
                        },
                        "_type": "_doc",
                    },
                    {
                        "_id": "qteZT4kBjAZqZnexVUxl",
                        "_index": ".ds-filebeat-8.8.2-2023.07.09-000001",
                        "_score": 2.482621,
                        "_source": {
                            "@timestamp": "2023-07-13T14:13:15.141Z",
                            "asctime": "2023-07-09T07:47:43.917+0000",
                            "container": {"id": "airflow"},
                            "dag_id": "example_bash_operator",
                            "ecs": {"version": "8.0.0"},
                            "execution_date": "2023_07_09T07_47_32_000000",
                            "filename": "taskinstance.py",
                            "input": {"type": "log"},
                            "levelname": "INFO",
                            "lineno": 1347,
                            "log": {
                                "file": {
                                    "path": "/opt/airflow/Documents/GitHub/airflow/logs/"
                                    "dag_id=example_bash_operator"
                                    "/run_id=owen_run_run/task_id=run_after_loop/attempt=1.log"
                                },
                                "offset": 988,
                            },
                            "log.offset": 1688888863917961216,
                            "log_id": "example_bash_operator-run_after_loop-owen_run_run--1-1",
                            "message": "Starting attempt 1 of 1",
                            "task_id": "run_after_loop",
                            "try_number": "1",
                        },
                        "_type": "_doc",
                    },
                    {
                        "_id": "v9eZT4kBjAZqZnexVUx2",
                        "_index": ".ds-filebeat-8.8.2-2023.07.09-000001",
                        "_score": 2.482621,
                        "_source": {
                            "@timestamp": "2023-07-13T14:13:15.143Z",
                            "asctime": "2023-07-09T07:47:43.928+0000",
                            "container": {"id": "airflow"},
                            "dag_id": "example_bash_operator",
                            "ecs": {"version": "8.0.0"},
                            "execution_date": "2023_07_09T07_47_32_000000",
                            "filename": "taskinstance.py",
                            "input": {"type": "log"},
                            "levelname": "INFO",
                            "lineno": 1368,
                            "log": {
                                "file": {
                                    "path": "/opt/airflow/Documents/GitHub/airflow/logs/"
                                    "dag_id=example_bash_operator"
                                    "/run_id=owen_run_run/task_id=run_after_loop/attempt=1.log"
                                },
                                "offset": 1372,
                            },
                            "log.offset": 1688888863928218880,
                            "log_id": "example_bash_operator-run_after_loop-owen_run_run--1-1",
                            "message": "Executing <Task(BashOperator): "
                            "run_after_loop> on 2023-07-09 "
                            "07:47:32+00:00",
                            "task_id": "run_after_loop",
                            "try_number": "1",
                        },
                        "_type": "_doc",
                    },
                ],
                "max_score": 2.482621,
                "total": {"relation": "eq", "value": 36},
            },
            "timed_out": False,
            "took": 7,
        }

    @query_params(
        "consistency",
        "op_type",
        "parent",
        "refresh",
        "replication",
        "routing",
        "timeout",
        "timestamp",
        "ttl",
        "version",
        "version_type",
    )
    def index(self, index, doc_type, body, id=None, params=None, headers=None):
        if index not in self.__documents_dict:
            self.__documents_dict[index] = []

        if id is None:
            id = get_random_id()

        version = 1

        self.__documents_dict[index].append(
            {
                "_type": doc_type,
                "_id": id,
                "_source": body,
                "_index": index,
                "_version": version,
                "_headers": headers,
            }
        )

        return {
            "_type": doc_type,
            "_id": id,
            "created": True,
            "_version": version,
            "_index": index,
            "_headers": headers,
        }

    @query_params("parent", "preference", "realtime", "refresh", "routing")
    def exists(self, index, doc_type, id, params=None):
        result = False
        if index in self.__documents_dict:
            for document in self.__documents_dict[index]:
                if document.get("_id") == id and document.get("_type") == doc_type:
                    result = True
                    break
        return result

    @query_params(
        "_source",
        "_source_exclude",
        "_source_include",
        "fields",
        "parent",
        "preference",
        "realtime",
        "refresh",
        "routing",
        "version",
        "version_type",
    )
    def get(self, index, id, doc_type="_all", params=None):
        result = None
        if index in self.__documents_dict:
            result = self.find_document(doc_type, id, index, result)

        if result:
            result["found"] = True
        else:
            error_data = {"_index": index, "_type": doc_type, "_id": id, "found": False}
            raise NotFoundError(404, json.dumps(error_data))

        return result

    def find_document(self, doc_type, id, index, result):
        for document in self.__documents_dict[index]:
            if document.get("_id") == id:
                if doc_type == "_all" or document.get("_type") == doc_type:
                    result = document
                    break
        return result

    @query_params(
        "_source",
        "_source_exclude",
        "_source_include",
        "parent",
        "preference",
        "realtime",
        "refresh",
        "routing",
        "version",
        "version_type",
    )
    def get_source(self, index, doc_type, id, params=None):
        document = self.get(index=index, doc_type=doc_type, id=id, params=params)
        return document.get("_source")

    @query_params(
        "_source",
        "_source_exclude",
        "_source_include",
        "allow_no_indices",
        "analyze_wildcard",
        "analyzer",
        "default_operator",
        "df",
        "expand_wildcards",
        "explain",
        "fielddata_fields",
        "fields",
        "from_",
        "ignore_unavailable",
        "lenient",
        "lowercase_expanded_terms",
        "preference",
        "q",
        "request_cache",
        "routing",
        "scroll",
        "search_type",
        "size",
        "sort",
        "stats",
        "suggest_field",
        "suggest_mode",
        "suggest_size",
        "suggest_text",
        "terminate_after",
        "timeout",
        "track_scores",
        "version",
    )
    def count(self, index=None, doc_type=None, body=None, params=None, headers=None):
        searchable_indexes = self._normalize_index_to_list(index, body)
        searchable_doc_types = self._normalize_doc_type_to_list(doc_type)
        i = 0
        for searchable_index in searchable_indexes:
            for document in self.__documents_dict[searchable_index]:
                if not searchable_doc_types or document.get("_type") in searchable_doc_types:
                    i += 1
        result = {"count": i, "_shards": {"successful": 1, "failed": 0, "total": 1}}

        return result

    @query_params(
        "_source",
        "_source_exclude",
        "_source_include",
        "allow_no_indices",
        "analyze_wildcard",
        "analyzer",
        "default_operator",
        "df",
        "expand_wildcards",
        "explain",
        "fielddata_fields",
        "fields",
        "from_",
        "ignore_unavailable",
        "lenient",
        "lowercase_expanded_terms",
        "preference",
        "q",
        "request_cache",
        "routing",
        "scroll",
        "search_type",
        "size",
        "sort",
        "stats",
        "suggest_field",
        "suggest_mode",
        "suggest_size",
        "suggest_text",
        "terminate_after",
        "timeout",
        "track_scores",
        "version",
    )
    def search(self, index=None, doc_type=None, body=None, params=None, headers=None):
        searchable_indexes = self._normalize_index_to_list(index, body)

        matches = self._find_match(index, doc_type, body)

        result = {
            "hits": {"total": len(matches), "max_score": 1.0},
            "_shards": {
                # Simulate indexes with 1 shard each
                "successful": len(searchable_indexes),
                "failed": 0,
                "total": len(searchable_indexes),
            },
            "took": 1,
            "timed_out": False,
        }

        hits = []
        for match in matches:
            match["_score"] = 1.0
            hits.append(match)
        result["hits"]["hits"] = hits

        return result

    @query_params(
        "consistency", "parent", "refresh", "replication", "routing", "timeout", "version", "version_type"
    )
    def delete(self, index, doc_type, id, params=None, headers=None):
        found = False

        if index in self.__documents_dict:
            for document in self.__documents_dict[index]:
                if document.get("_type") == doc_type and document.get("_id") == id:
                    found = True
                    self.__documents_dict[index].remove(document)
                    break

        result_dict = {
            "found": found,
            "_index": index,
            "_type": doc_type,
            "_id": id,
            "_version": 1,
        }

        if found:
            return result_dict
        else:
            raise NotFoundError(404, json.dumps(result_dict))

    @query_params("allow_no_indices", "expand_wildcards", "ignore_unavailable", "preference", "routing")
    def suggest(self, body, index=None):
        if index is not None and index not in self.__documents_dict:
            raise NotFoundError(404, f"IndexMissingException[[{index}] missing]")

        result_dict = {}
        for key, value in body.items():
            text = value.get("text")
            suggestion = int(text) + 1 if isinstance(text, int) else f"{text}_suggestion"
            result_dict[key] = [
                {
                    "text": text,
                    "length": 1,
                    "options": [{"text": suggestion, "freq": 1, "score": 1.0}],
                    "offset": 0,
                }
            ]
        return result_dict

    def _find_match(self, index, doc_type, body):
        searchable_indexes = self._normalize_index_to_list(index, body)
        searchable_doc_types = self._normalize_doc_type_to_list(doc_type)

        must = body["query"]["bool"]["must"][0]  # only support one must

        matches = []
        for searchable_index in searchable_indexes:
            self.find_document_in_searchable_index(matches, must, searchable_doc_types, searchable_index)

        return matches

    def find_document_in_searchable_index(self, matches, must, searchable_doc_types, searchable_index):
        for document in self.__documents_dict[searchable_index]:
            if not searchable_doc_types or document.get("_type") in searchable_doc_types:
                if "match_phrase" in must:
                    self.match_must_phrase(document, matches, must)
                else:
                    matches.append(document)

    @staticmethod
    def match_must_phrase(document, matches, must):
        for query_id in must["match_phrase"]:
            query_val = must["match_phrase"][query_id]
            if query_id in document["_source"]:
                if query_val in document["_source"][query_id]:
                    # use in as a proxy for match_phrase
                    matches.append(document)

    # Check index(es) exists.
    def _validate_search_targets(self, targets, body):
        # TODO: support allow_no_indices query parameter
        matches = set()
        for target in targets:
            print(f"Loop over:::target = {target}")
            if target == "_all" or target == "":
                matches.update(self.__documents_dict)
            elif "*" in target:
                matches.update(fnmatch.filter(self.__documents_dict, target))
            elif target not in self.__documents_dict:
                raise MissingIndexException(msg=f"IndexMissingException[[{target}] missing]", body=body)
        return matches

    def _normalize_index_to_list(self, index, body):
        # Ensure to have a list of index
        if index is None:
            searchable_indexes = self.__documents_dict.keys()
        elif isinstance(index, str):
            searchable_indexes = [index]
        elif isinstance(index, list):
            searchable_indexes = index
        else:
            # Is it the correct exception to use ?
            raise ValueError("Invalid param 'index'")

        generator = (target for index in searchable_indexes for target in index.split(","))
        return list(self._validate_search_targets(generator, body))

    @staticmethod
    def _normalize_doc_type_to_list(doc_type):
        # Ensure to have a list of index
        if doc_type is None:
            searchable_doc_types = []
        elif isinstance(doc_type, str):
            searchable_doc_types = [doc_type]
        elif isinstance(doc_type, list):
            searchable_doc_types = doc_type
        else:
            # Is it the correct exception to use ?
            raise ValueError("Invalid param 'index'")

        return searchable_doc_types


#!/usr/bin/env python

import datetime
from datetime import timedelta
import yaml
import logging
import logging.config
import subprocess
import os
import sys
import re
import glob
import argparse

class AbstractDriver(object):
    def __init__(self, config = None, logger = None):
        self.config = {'bin_path': '', 'env': None, 'aws_access_key': None, 'aws_secret_key': None}
        if config:
            self.config.update(config)
        self.logger = logger or logging.getLogger(__name__)

    def _run(self, cmd):
        env = os.environ.copy()
        if self.config['env']:
            env.update(self.config['env'])

        process = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
        for line in process.stdout:
            self.logger.debug(line.rstrip())

        for line in process.stderr:
            self.logger.info(line.rstrip())

        process.wait()

class RcloneDriver(AbstractDriver):
    def __init__(self, config = None, logger = None):
        super(RcloneDriver, self).__init__(config, logger)

        if not self.config['bin_path']:
            self.config['bin_path'] = 'rclone'

        if not self.config['aws_access_key'] or not self.config['aws_secret_key']:
            if 'aws_env_auth' in self.config and not self.config['aws_env_auth']:
                raise Exception('Either configure aws_env_auth or configure access/secret key')
            else:
                self.config['aws_env_auth'] = True
        else:
            self.config['aws_env_auth'] = False

        self.flags = self.build_flags()

    def build_flags(self):
        flags = ['-v', '--s3-provider', 'AWS']

        if 'aws_env_auth' in self.config and self.config['aws_env_auth']:
            flags.extend(['--s3-env-auth'])
        else:
            flags.extend(['--s3-access-key-id', self.config['aws_access_key']])
            flags.extend(['--s3-secret-access-key', self.config['aws_secret_key']])

        if 'aws_region' in self.config:
            flags.extend(['--s3-region', self.config['aws_region']])

        if 'aws_s3_acl' in self.config:
            flags.extend(['--s3-acl', self.config['aws_s3_acl']])

        if 'aws_s3_server_side_encryption' in self.config:
            flags.extend(['--s3-server-side-encryption', self.config['aws_s3_server_side_encryption']])

        if 'aws_s3_storage_class' in self.config:
            flags.extend(['--s3-storage-class', self.config['aws_s3_storage_class']])

        return flags

    def fix_s3_path(self, path):
        return path.replace('s3://', ':s3:')

    def sync(self, src, dest):
        self.logger.info("rclone::syncing '%s' to amazon s3", src.get_name())

        flags = self.flags[:]

        for path in src.get_excluded_paths():
            flags.extend(['--exclude', self.fix_s3_path(path)])

        dest = dest.replace('s3://', ':s3:')

        included_paths = src.get_included_paths(self)
        if included_paths:
            for path in src.get_included_paths(self):
                cmd = [self.config['bin_path'], 'sync', self.fix_s3_path(path), dest]
                cmd.extend(flags)
                self._run(cmd)
        else:
            self.logger.info('Skipping copy as source list is empty')

    def remove(self, dest):
        self.logger.info("rclone::removing '%s' from amazon s3", dest)
        dest = dest.replace('s3://', ':s3:')
        cmd = [self.config['bin_path'], 'purge', self.fix_s3_path(dest)]
        cmd.extend(self.flags)

        self._run(cmd)

    def exists(self, dest):
        return True

class RsyncDriver(AbstractDriver):
    def __init__(self, config = None, logger = None):
        super(RsyncDriver, self).__init__(config, logger)

        if not self.config['bin_path']:
            self.config['bin_path'] = 'rsync'

    def sync(self, src, dest):
        self.logger.info("rsync::syncing '%s' to filesystem", src.get_name())
        cmd = [self.config['bin_path'], '-avP']

        for path in src.get_excluded_paths():
            cmd.extend(['--exclude', path])

        included_paths = src.get_included_paths(self)

        if not os.path.exists(dest):
            os.makedirs(dest)

        if not os.path.isdir(dest):
            raise Exception('Destination is not a directory %s' % dest);

        if included_paths:
            for path in included_paths:
                cmd.append(path)

            cmd.append(dest)
            self._run(cmd)
        else:
            self.logger.info('Skipping copy as source list is empty')

    def remove(self, dest):
        self.logger.info("rclone::removing '%s' from filesytem", dest)
        if dest == '/':
            self.logger.error("rsync::cannot remove '/' directory")
        else:
            self._run(['rm', '-rf', dest])

    def exists(self, dest):
        return os.path.isdir(dest)

class AmazonS3Store():
    def __init__(self, config, driver = None):
        # self.config = config
        self.logger = logging.getLogger(__name__)

        if 'bucket' not in config:
            raise Exception("'bucket' is required for amazons3 store")

        self.prefix = 's3://' + config['bucket']

        if 'prefix' in config:
            self.prefix = 's3://' + self.config['bucket'] + '/' + config['prefix']

        if driver == None:
            driver = RcloneDriver(config)

        self.driver = driver

    def __get_destination(self, backup, version):
        return os.path.join(self.prefix, version.strftime('%Y-%m-%d'), backup.get_name())

    def add(self, version, backup):
        self.driver.sync(backup, self.__get_destination(backup, version))

    def remove(self, backup, version):
        dest = self.__get_destination(backup, version)
        if self.driver.exists(dest):
            self.driver.remove(dest)

class FileSystemStore():
    def __init__(self, config, driver = None):
        self.config = config
        self.logger = logging.getLogger(__name__)

        if 'path' not in config:
            raise Exception("'path' is required for filesystem store")

        if os.path.isdir(config['path']) == False:
            raise Exception("%s is not a directory" % config['path'])

        if not os.access(config['path'], os.W_OK | os.X_OK):
            raise Exception("%s is not writeable" % config['path'])

        if driver == None:
            driver = RsyncDriver()

        self.driver = driver

    def __get_destination(self, backup, version):
        return os.path.join(self.config['path'], version.strftime('%Y-%m-%d'), backup.get_name())

    def add(self, version, backup):
        self.driver.sync(backup, self.__get_destination(backup, version))

    def remove(self, backup, version):
        dest = self.__get_destination(backup, version)
        if self.driver.exists(dest):
            self.driver.remove(dest)

class Backup():
    def __init__(self, config):
        self.config = {'onerror': 'exception'}
        self.config.update(config)
        self.logger = logging.getLogger(__name__)

        if 'include' not in config:
            raise "'include' is missing for source %s" % self.get_name()

    def get_name(self):
        return self.config['name']

    @staticmethod
    def replace_placeholder(match):
        placeholder = match.group(1) or match.group(2)

        if placeholder in ['Y', 'm', 'd']:
            return datetime.datetime.now().strftime('%' + placeholder)
        elif placeholder == 'LATEST':
            return 'LATEST'
        else:
            raise Exception("Invalid placeholder '%s'" % placeholder)

    def handle_error(self, exception):
        self.logger.error(str(exception))
        print(self.config)
        if self.config['onerror'] == 'alert':
            # Send Alert
            print('Send Alert')
        elif self.config['onerror'] != 'continue':
            raise exception

    def get_included_paths(self, driver):
        include = []
        now = datetime.datetime.now()
        for path in self.config['include']:
            path = re.sub('%([A-Za-z])|%\{([A-Za-z])\}+', Backup.replace_placeholder, path)
            paths = glob.glob(path)
            if not paths:
                self.handle_error(Exception('Path not found %s' % path))
            else:
                for path in paths:
                    self.logger.debug('Including path %s' % path)
                include.extend(paths)

        return include

    def get_excluded_paths(self):
        if 'exclude' in self.config:
            return self.config['exclude']
        else:
            return []

class Manager():
    def __init__(self, file, logger = None):
        self.backups = []
        self.destinations = []

        self.config = {
            'log_file': './backup.log'
        }
        self.config.update(self.load_config(file))
        self.init_logger()
        self.logger = logger or logging.getLogger(__name__)

        self.obsolete = self.load_obsolete()

        for destination in self.config['destination']:
            if destination['store'] == 'amazons3':
                destination = AmazonS3Store(destination['options'])
            elif destination['store'] == 'filesystem':
                destination = FileSystemStore(destination['options'])
            else:
                raise Exception('Unsupported storage store - %s' % (destination['name']));

            self.destinations.append(destination)

        for source in self.config['source']:
            backup = Backup(source)

            self.backups.append(backup)

    def init_logger(self, default_level=logging.DEBUG):
        value = os.getenv('LOG_CFG', None)

        if value and os.path.exists(value):
            path = value
            with open(path, 'rt') as f:
                config = yaml.safe_load(f.read())
            logging.config.dictConfig(config)
        elif 'logging' in self.config:
            logging.config.dictConfig(self.config['logging'])
        else:
            logging.basicConfig(level=default_level)

    def load_config(self, file):
        stream = open(file, "r")
        config = yaml.safe_load(stream)

        if config.get('extends'):
            base = self.load_config(config['extends'])
            del config['extends']
            base.update(config)
            config = base

        return config

    def load_obsolete(self):
        now = datetime.datetime.now()
        dow = now.weekday()
        obsolete = []

        if dow == 1:
            date = now - timedelta(days=28)
            if date.day > 7:
                obsolete.append(date)

            date = now - timedelta(days=364)
            if date.day <= 8 and date.month > 1:
                obsolete.append(date)
        else:
            date = now - timedelta(days=7)
            obsolete.append(date)

        return obsolete;

    def run(self):
        version = datetime.datetime.now()
        for backup in self.backups:
            self.logger.info('Preparing to backup %s' % backup.get_name())
            for destination in self.destinations:
                try:
                    destination.add(version, backup)
                    for date in self.obsolete:
                        destination.remove(backup, date)
                except Exception as e:
                    backup.handle_error(e)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='Process some integers.')
    parser.add_argument('-c', '--config-file', help='config file', default='./config.yaml')

    args = parser.parse_args()

    try:
        manager = Manager(args.config_file)
        manager.run()
    except Exception as e:
       sys.exit( str(e))

# if [ $DOW -eq 1 ]; then
#     DATE_DAY=$(date -d "-28 days" +"%d")
#     if [ $DATE_DAY -gt 7 ]; then
#         DATE=$(date -d "-28 days" +"%Y-%m-%d")
#         delete $DATE
#     fi
#
#     DATE_DAY=$(date -d "-364 days" +"%d")
#     DATE_MONTH=$(date -d "-364 days" +"%m")
#     if [ $DATE_DAY -le 7 ] && [ $DATE_MONTH -gt 1 ]; then
#         DATE=$(date -d "-364 days" +"%Y-%m-%d")
#         delete $DATE
#     fi
# else
#     DATE=$(date -d "-7 days" +"%Y-%m-%d")
#     echo $DATE
#     delete $DATE
# fi


import tensorflow as tf
import tensorflow.contrib.layers as tfc_layers

from generic.tf_utils.abstract_network import ResnetModel
from generic.tf_factory.image_factory import get_image_features
from generic.tf_factory.attention_factory import get_attention

import neural_toolbox.rnn as rnn

from neural_toolbox.film_stack import FiLM_Stack

class FiLMCLEVRNetwork(ResnetModel):

    def __init__(self, config, num_words, num_answers, reuse=False, device=''):
        ResnetModel.__init__(self, "clevr", device=device)

        with tf.variable_scope(self.scope_name, reuse=reuse):
            batch_size = None
            self._is_training = tf.placeholder(tf.bool, name="is_training")

            dropout_keep_scalar = float(config["dropout_keep_prob"])
            dropout_keep = tf.cond(self._is_training,
                                   lambda: tf.constant(dropout_keep_scalar),
                                   lambda: tf.constant(1.0))

            #####################
            #   QUESTION
            #####################

            self._question = tf.placeholder(tf.int32, [batch_size, None], name='question')
            self._seq_length = tf.placeholder(tf.int32, [batch_size], name='seq_length')
            self._answer = tf.placeholder(tf.int64, [batch_size], name='answer')

            word_emb = tfc_layers.embed_sequence(
                ids=self._question,
                vocab_size=num_words,
                embed_dim=config["question"]["word_embedding_dim"],
                scope="word_embedding",
                reuse=reuse)

            if config["question"]['glove']:
                self._glove = tf.placeholder(tf.float32, [None, None, 300], name="glove")
                word_emb = tf.concat([word_emb, self._glove], axis=2)

            word_emb = tf.nn.dropout(word_emb, dropout_keep)

            _, last_rnn_state = rnn.rnn_factory(
                inputs=word_emb,
                seq_length=self._seq_length,
                cell=config["question"]["cell"],
                num_hidden=config["question"]["rnn_state_size"],
                bidirectional=config["question"]["bidirectional"],
                max_pool=config["question"]["max_pool"],
                layer_norm=config["question"]["layer_norm"],
                reuse=reuse)

            last_rnn_state = tf.nn.dropout(last_rnn_state, dropout_keep)

            #####################
            #   IMAGES
            #####################

            self._image = tf.placeholder(tf.float32, [batch_size] + config['image']["dim"], name='image')

            visual_features = get_image_features(image=self._image,
                                                 is_training=self._is_training,
                                                 config=config['image'])

            with tf.variable_scope("image_film_stack", reuse=reuse):
                film_stack = FiLM_Stack(image=visual_features,
                                        film_input=last_rnn_state,
                                        is_training=self._is_training,
                                        config=config["film_block"],
                                        reuse=reuse)

                visual_features = film_stack.get()

            # Pool Image Features
            with tf.variable_scope("image_pooling"):
                multimodal_features = get_attention(visual_features, last_rnn_state,
                                                    is_training=self._is_training,
                                                    config=config["pooling"],
                                                    dropout_keep=dropout_keep,
                                                    reuse=reuse)

            with tf.variable_scope("classifier"):
                self.hidden_state = tfc_layers.fully_connected(multimodal_features,
                                                               num_outputs=config["classifier"]["no_mlp_units"],
                                                               normalizer_fn=tfc_layers.batch_norm,
                                                               normalizer_params={"center": True, "scale": True,
                                                                                "decay": 0.9,
                                                                                "is_training": self._is_training,
                                                                                "reuse": reuse},
                                                               activation_fn=tf.nn.relu,
                                                               reuse=reuse,
                                                               scope="classifier_hidden_layer")

                self.out = tfc_layers.fully_connected(self.hidden_state,
                                                      num_outputs=num_answers,
                                                      activation_fn=None,
                                                      reuse=reuse,
                                                      scope="classifier_softmax_layer")

            #####################
            #   Loss
            #####################

            self.cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=self.out, labels=self._answer, name='cross_entropy')
            self.loss = tf.reduce_mean(self.cross_entropy)

            self.softmax = tf.nn.softmax(self.out, name='answer_prob')
            self.prediction = tf.argmax(self.out, axis=1, name='predicted_answer')  # no need to compute the softmax

            with tf.variable_scope('accuracy'):
                self.accuracy = tf.equal(self.prediction, self._answer)
                self.accuracy = tf.reduce_mean(tf.cast(self.accuracy, tf.float32))

            tf.summary.scalar('accuracy', self.accuracy)

            print('Model... build!')

    def get_loss(self):
        return self.loss

    def get_accuracy(self):
        return self.accuracy

if __name__ == "__main__":

    import json
    with open("../../../config/clevr/config.film.json", 'r') as f_config:
        conf = json.load(f_config)

    FiLMCLEVRNetwork(conf["model"], num_words=354, num_answers=56)


from django.urls import path
from . import views
from .views import HomeView,ArticleDetailView,AddPostView,UpdatePostView,DeletePostView,AddCatergoryView,CategoryView,CategoryListView,LikeView,AddCommentView
urlpatterns = [
    #path('',views.home,name="home"),
    path('',HomeView.as_view(),name="home"),
    path('article/<int:pk>',ArticleDetailView.as_view(),name="article_detail"),
    path('add_post/',AddPostView.as_view(),name="add_post"),
    path('update_post/<int:pk>',UpdatePostView.as_view(),name="update_post"),
    path('delete_post/<int:pk>',DeletePostView.as_view(),name="delete_post"),
    path('add_category/',AddCatergoryView.as_view(),name="add_category"),
    path('category/<str:cats>/',CategoryView,name='category'),
    path('category_list/',CategoryListView,name='category_list'),
    path('like_post/<int:pk>',LikeView,name='like_post'),
    path('add_comment/',views.add_comment,name="add_comment"),
    path('search_box/',views.search_box,name="search_box"),
    path('delete_comment/<int:id>',views.delete_comment,name="delete_comment"),
]


from PyQt5 import QtWidgets , QtCore, QtGui
from PyQt5.QtGui import QPalette, QColor
from PyQt5.QtCore import QUrl, QDirIterator, Qt
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QPushButton, QFileDialog, QAction, QHBoxLayout, QVBoxLayout, QSlider,QMessageBox
from pyqtgraph import PlotWidget, plot, PlotItem
from Gui import Ui_MainWindow
import numpy as np
import pyqtgraph as pg
import matplotlib.pyplot as plt
import logging
import sys
import wave
import pydub
import pyaudio
import os
import sounddevice as sd
from songdata import song_data

class ApplicationWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(ApplicationWindow, self).__init__()
        pg.setConfigOption('background', 'w')
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.Song1 = []
        self.Song2 = []

        self.mixedArray = []
        self.mixedArray_Duration=0

        self.mixedsong = song_data()

        self.songsArray = []
        self.song_index = 0

        self.Ext_1=None
        self.Ext_2=None

        self.Input_X_1=[]
        self.Input_Y_1=[]
        self.Input_X_2=[]
        self.Input_Y_2=[]
        self.durationF_1=0
        self.durationF_2=0

        self.similarityIndex = []
        self.similarityIndexID = []
        self.topTenSimilarityIndex = []

        LOG_FILENAME = 'LOGFILE.txt'
        file = open(LOG_FILENAME,"r+")
        file.truncate(0)
        file.close()

        self.generate_spectrograms()

        logging.basicConfig(filename=LOG_FILENAME,format='%(asctime)s - %(message)s ',datefmt='%d-%b-%y %H:%M:%S',level=logging.INFO)

    #----------------------------------------------------------------------------------------------------------------
        self.graphic_View_Array=[self.ui.Spectrogram_1,self.ui.Spectrogram_2]
        for x in self.graphic_View_Array:
            x.setMouseEnabled(x=False, y=False)
            pass
        #------------------

        self.playArray=[self.ui.Play_1,self.ui.Play_2]
    #----------------------------------------------------------------------------------------------------------------
        self.browseArray=[self.ui.BrowseButton,self.ui.BrowseButton_2]
        self.ui.BrowseButton.clicked.connect(lambda : self.Import(0))
        self.ui.BrowseButton_2.clicked.connect(lambda : self.Import(1))
        self.ui.GenerateButton.clicked.connect(self.start_compare)
    #----------------------------------------------------------------------------------------------------------------
        self.ui.MixerSlider.sliderReleased.connect(self.ValueChanged)
    #----------------------------------------------------------------------------------------------------------------
        self.stopArray=[self.ui.Stop_Button,self.ui.Stop_Button_2]
        for x in self.stopArray:
            x.clicked.connect(self.Stop)
    #----------------------------------------------------------------------------------------------------------------

    def Import(self,num):
        filePaths = QtWidgets.QFileDialog.getOpenFileNames(self, 'Multiple File',"~/Desktop",'*.mp3 && *.wav')
        for filePath in filePaths:
            for f in filePath:
                if f == "*" or f == None:
                    break
                ext = os.path.splitext(f)[-1].lower()  # Check file extension

                if ext == ".wav":
                    self.X_Y_Data = self.ReadFromWav(f,num)
                    if num==0:
                        self.Ext_1=ext
                        self.Input_X_1=self.X_Y_Data[0]
                        self.Input_Y_1=self.X_Y_Data[1]
                        self.ui.Play_1.clicked.connect(lambda : self.Play_Wav(self.Input_Y_1[0],self.durationF_1))
                        logging.info('User Imported wav file from Browse 1')

                    if num==1:
                        self.Ext_2=ext
                        self.Input_X_2=self.X_Y_Data[0]
                        self.Input_Y_2=self.X_Y_Data[1]
                        self.ui.Play_2.clicked.connect(lambda : self.Play_Wav(self.Input_Y_2[0],self.durationF_2))
                        logging.info('User Imported wav file from Browse 2')

                if ext == ".mp3" :

                    pydub.AudioSegment.converter = r"C:\ffmpeg\ffmpeg\bin\ffmpeg.exe"
                    songFile = pydub.AudioSegment.from_mp3(f)
                    if num==0:
                        self.Ext_1=ext
                        self.Song1 = np.array(songFile.get_array_of_samples())
                        self.Song1 = self.Song1.reshape((-1, 2))
                        self.ui.Play_1.clicked.connect(lambda : self.Play(self.Song1))
                        logging.info('User Imported mp3 file from Browse 1')
                    if num==1:
                        self.Ext_2=ext
                        self.Song2 = np.array(songFile.get_array_of_samples())
                        self.Song2 = self.Song2.reshape((-1, 2))
                        self.ui.Play_2.clicked.connect(lambda : self.Play(self.Song2))
                        logging.info('User Imported mp3 file from Browse 2')

   #----------------------------------------------------------------------------------------------------------------

   #----------------------------------------------------------------------------------------------------------------

    def ReadFromWav(self,file,num):

        p = pyaudio.PyAudio()
        self.waveFile = wave.open(file,'rb')

        self.format = p.get_format_from_width(self.waveFile.getsampwidth())
        channel = self.waveFile.getnchannels()
        self.rate = self.waveFile.getframerate()
        self.frame = self.waveFile.getnframes()
        self.stream = p.open(format=self.format,  # DATA needed for streaming
                            channels=channel,
                            rate=self.rate,
                            output=True)
        if num==0:
            self.durationF_1 = self.frame / float(self.rate) # For playing the sound

        if num==1:
            self.durationF_2 = self.frame / float(self.rate) # For playing the sound

        self.data_int = self.waveFile.readframes(self.frame)
        self.data_plot = np.fromstring(self.data_int, 'Int16')
        self.data_plot.shape = -1, 2

        self.data_plot = self.data_plot.T
        self.time = np.arange(0, self.frame) * (1.0 / self.rate)

        return self.time,self.data_plot

    #------------------------------------------------------------------------------------------------------------------------

    #------------------------------------------------------------------------------------------------------------------------
    def ValueChanged(self):
        userChoice=self.ui.SelectedSong.currentText()
        value= (self.ui.MixerSlider.value())/10
        self.mixedArray=[]

        if (self.Ext_1==self.Ext_2) and (self.Ext_2==".mp3"):
            if len(self.Song2)!=0 and len(self.Song1)!=0:
                if(userChoice=="First_Song"):
                    if len(self.Song1) >= len(self.Song2):
                        self.mixedArray=((self.Song1[0:len(self.Song2)]*value)+(self.Song2*(1-value)))/10000
                    else:
                        self.mixedArray=((self.Song1*value)+(self.Song2[0:len(self.Song1)]*(1-value)))/10000

                elif(userChoice=="Second-Song"):
                    if len(self.Song2) >= len(self.Song1):
                        self.mixedArray=((self.Song2[0:len(self.Song1)]*value)+(self.Song1*(1-value)))/10000
                    else:
                        self.mixedArray=((self.Song2*value)+(self.Song1[0:len(self.Song2)]*(1-value)))/10000

                self.ui.Play_Mix.clicked.connect(lambda : self.Play(self.mixedArray))
                logging.info('User Created a mix with mp3 files ')
            else:
                QMessageBox.warning(self,'Warning',"ADD TWO SONGS", QMessageBox.Ok )
                logging.info('User tried to Create a mix while there is No 2 Songs imported')

        elif (self.Ext_1==self.Ext_2) and (self.Ext_2==".wav") :
            if len(self.Input_Y_1)!=0 and len(self.Input_Y_2)!=0:
                if(userChoice=="First_Song"):
                    if len(self.Input_Y_1[0]) >= len(self.Input_Y_2[0]):
                        self.mixedArray.append(((self.Input_Y_1[0][0:len(self.Input_Y_2[0])]*value)+(self.Input_Y_2[0]*(1-value)))/10000)
                        self.mixedArray.append(((self.Input_Y_1[1][0:len(self.Input_Y_2[1])]*value)+(self.Input_Y_2[1]*(1-value)))/10000)
                        self.mixedArray_Duration=self.durationF_1
                    else:
                        self.mixedArray.append(((self.Input_Y_1[0]*value)+(self.Input_Y_2[0][0:len(self.Input_Y_1[0])]*(1-value)))/10000)
                        self.mixedArray.append(((self.Input_Y_1[1]*value)+(self.Input_Y_2[1][0:len(self.Input_Y_1[1])]*(1-value)))/10000)
                        self.mixedArray_Duration=self.durationF_2
                elif(userChoice=="Second-Song"):
                    if len(self.Input_Y_2[0]) >= len(self.Input_Y_1[0]):
                        self.mixedArray.append(((self.Input_Y_2[0][0:len(self.Input_Y_1[0])]*value)+(self.Input_Y_1[0]*(1-value)))/10000)
                        self.mixedArray.append(((self.Input_Y_2[1][0:len(self.Input_Y_1[1])]*value)+(self.Input_Y_1[1]*(1-value)))/10000)
                        self.mixedArray_Duration=self.durationF_2
                    else:
                        self.mixedArray.append(((self.Input_Y_2[0]*value)+(self.Input_Y_1[0][0:len(self.Input_Y_2[0])]*(1-value)))/10000)
                        self.mixedArray.append(((self.Input_Y_2[1]*value)+(self.Input_Y_1[1][0:len(self.Input_Y_2[1])]*(1-value)))/10000)
                        self.mixedArray_Duration=self.durationF_1

                self.ui.Play_Mix.clicked.connect(lambda : self.Play_Wav(self.mixedArray[0],self.mixedArray_Duration))
                logging.info('User Created a mix with wav files ')

                self.mixedsong.song_data = self.mixedArray
        else:
            QMessageBox.warning(self,'Warning',"add songs with the same extension", QMessageBox.Ok )
            logging.info('User tried to Create a mix while the two songs is not the same extension')

    #------------------------------------------------------------------------------------------------------------------------

    #------------------------------------------------------------------------------------------------------------------------
    def Play(self,array):
        sd.play(array)

    def Play_Wav(self,array,D):
        if ((len(self.Input_X_1) != 0 and len(self.Input_Y_1) != 0) or ((len(self.Input_X_2) != 0 and len(self.Input_Y_2) != 0))):
            sd.play(array,len(array)/D)
        else:
            pass

    def Stop(self):
        sd.stop()
    #------------------------------------------------------------------------------------------------------------------------

    #------------------------------------------------------------------------------------------------------------------------

    def generate_spectrograms(self):
        path = '/Songs'
        filepaths = [os.path.join(r,file) for r,d,f in os.walk(os.getcwd() + path) for file in f]
        filepaths = [x for x in filepaths if x.endswith(".wav")]
        for f in filepaths:
            tempSong = song_data()
            tempSong.set_Data(f,self.song_index)
            self.songsArray.append(tempSong)
            self.song_index = self.song_index + 1

    #------------------------------------------------------------------------------------------------------------------------

    #------------------------------------------------------------------------------------------------------------------------

    def start_compare(self):
        for i in range(len(self.songsArray)):
            print(len(self.songsArray))
            percent_hashes = self.mixedArray.compareHashes(self.songsArray[i])
            percent_peaks = self.mixedArray.comparePeakFeaturesGenerateDifference(self.songsArray[i])

            tempSimilarityIndex = (percent_hashes + percent_peaks )/2
            self.similarityIndex.append(tempSimilarityIndex * 100)
            self.similarityIndexID.append(self.songsArray[i].songID)

        tempSimilarityIndex = self.similarityIndex
        print("---------------------------------")
        print(self.similarityIndexID)
        print(self.similarityIndex)
        print("---------------------------------")

        numpyArr=np.array(self.similarityIndex)
        self.TopTenSimilarIDs=numpyArr.argsort()[::-1]

        tempSimilarityIndex.sort(reverse = True)

        if len(tempSimilarityIndex) < 10 :
            for i in tempSimilarityIndex:
                self.topTenSimilarityIndex.append(i)
        else:
            for i in range(10):
                self.topTenSimilarityIndex.append(tempSimilarityIndex[i])
        print("Top Similar IDs")
        print (self.TopTenSimilarIDs)
        print(self.topTenSimilarityIndex)

        for i in range(len(self.topTenSimilarityIndex)):
            self.Fill_Similarity_Table(self.TopTenSimilarIDs[i],i)

        self.topTenSimilarityIndex = [ ]
        self.similarityIndex = [ ]
        self.similarityIndexID = [ ]

    #------------------------------------------------------------------------------------------------------------------------

    #------------------------------------------------------------------------------------------------------------------------

    def Fill_Similarity_Table(self,songIndex,normalIndex):
        rowPosition = self.ui.SongsTable.rowCount()
        self.ui.SongsTable.insertRow(rowPosition)
        numrows = self.ui.SongsTable.rowCount()
        self.ui.SongsTable.setRowCount(numrows)
        self.ui.SongsTable.setColumnCount(2)
        self.ui.SongsTable.setItem(numrows - 1, 0 ,QtGui.QSongsTableItem(self.songsArray[songIndex].songName))
        self.ui.SongsTable.setItem(numrows - 1, 1 ,QtGui.QSongsTableItem(str(round(self.topTenSimilarityIndex[normalIndex],2))+"%"))

        self.ui.SongsTable.setHorizontalHeaderItem(0,QtGui.QSongsTableItem("Song Name"))
        self.ui.SongsTable.setHorizontalHeaderItem(1,QtGui.QSongsTableItem("Similarity Index"))

    #------------------------------------------------------------------------------------------------------------------------

    #------------------------------------------------------------------------------------------------------------------------

#////////////////////////////// Main /////////////////////////////////////

def main():
    app = QtWidgets.QApplication(sys.argv)
    application = ApplicationWindow()
    application.show()
    app.exec_()

if __name__ == "__main__":
    main()


import unittest
import os
import shutil
import tempfile
import zmq
import threading
import time

import kiskadee.queue
import kiskadee

class FetchersTestCase(unittest.TestCase):
    def test_loading(self):
        _config = kiskadee.config
        _config['debian_fetcher'] = {'active': 'no'}
        _config['juliet_fetcher'] = {'active': 'yes'}
        _config['example_fetcher'] = {'active': 'yes'}
        kiskadee.config = _config
        fetchers = kiskadee.load_fetchers()
        for fetcher in fetchers:
            name_index = len(fetcher.__name__.split('.')) - 1
            name = fetcher.__name__.split('.')[name_index]
            self.assertTrue(name != 'debian')
        kiskadee.config['example_fetcher'] = {
                'target': 'example',
                'description': 'SAMATE Juliet test suite',
                'analyzers': 'cppcheck flawfinder',
                'active': 'yes'
            }

class DebianFetcherTestCase(unittest.TestCase):

    def setUp(self):
        import kiskadee.fetchers.debian
        self.debian_fetcher = kiskadee.fetchers.debian.Fetcher()
        self.data = self.debian_fetcher.config

    def _download_sources_gz(self):
        tmp_path = tempfile.gettempdir()
        path = tempfile.mkdtemp(dir=tmp_path)
        source = 'kiskadee/tests/test_source/Sources.gz'
        shutil.copy2(source, path)
        return path

    def test_mount_sources_gz_url(self):
        mirror = self.data['target']
        release = self.data['release']
        url = self.debian_fetcher._sources_gz_url()
        expected_url = "%s/dists/%s/main/source/Sources.gz" % (mirror, release)
        self.assertEqual(url, expected_url)

    def test_uncompress_sources_gz(self):
        tmp_path = tempfile.gettempdir()
        temp_dir = tempfile.mkdtemp(dir=tmp_path)
        self.debian_fetcher._download_sources_gz = self._download_sources_gz
        temp_dir = self.debian_fetcher._download_sources_gz()
        self.debian_fetcher._uncompress_gz(temp_dir)
        files = os.listdir(temp_dir)
        shutil.rmtree(temp_dir)
        self.assertTrue('Sources' in files)

    def test_enqueue_a_valid_pkg(self):
        tmp_path = tempfile.gettempdir()
        temp_dir = tempfile.mkdtemp(dir=tmp_path)
        self.debian_fetcher._download_sources_gz = self._download_sources_gz
        temp_dir = self.debian_fetcher._download_sources_gz()
        self.debian_fetcher._uncompress_gz(temp_dir)
        self.debian_fetcher._queue_sources_gz_pkgs(temp_dir)
        shutil.rmtree(temp_dir)

        some_pkg = kiskadee.queue.Queues.dequeue_package()
        self.assertTrue(isinstance(some_pkg, dict))
        self.assertIn('name', some_pkg)
        self.assertIn('version', some_pkg)
        self.assertIn('fetcher', some_pkg)
        self.assertIn('meta', some_pkg)
        self.assertIn('directory', some_pkg['meta'])

    def test_mount_dsc_url(self):
        expected_dsc_url = ("http://ftp.us.debian.org" +
                            "/debian/pool/main/0/0ad/0ad_0.0.21-2.dsc")
        sample_package = {'name': '0ad',
                          'version': '0.0.21-2',
                          'meta': {'directory': 'pool/main/0/0ad'}}
        url = self.debian_fetcher._dsc_url(sample_package)
        self.assertEqual(expected_dsc_url, url)

    def test_compare_gt_version(self):
        new = '1.1.1'
        old = '1.1.0'
        result = self.debian_fetcher.compare_versions(new, old)
        self.assertTrue(result)

    def test_compare_smallest_version(self):
        new = '8.5-2'
        old = '8.6-0'
        result = self.debian_fetcher.compare_versions(new, old)
        self.assertFalse(result)

    def test_compare_equal_version(self):
        new = '3.3.3-0'
        old = '3.3.3-0'
        result = self.debian_fetcher.compare_versions(new, old)
        self.assertFalse(result)

class TestAnityaFetcher(unittest.TestCase):

    def setUp(self):
        import kiskadee.fetchers.anitya
        self.anitya_fetcher = kiskadee.fetchers.anitya.Fetcher()

        self.msg = "anitya {'body':{'msg':{'package':{name: 'urlscan',"\
                   "'version':'0.8.5','backend':'GitHub',"\
                   "'homepage':'https://github.com/firecat53/urlscan'}}}}"

        self.msg1 = "{'body':{'msg':{'package':{name: 'urlscan',"\
                    "'version':'0.8.5','backend':'GitHub',"\
                    "'homepage':'https://github.com/firecat53/urlscan'}}}}"

    def test_connect_to_zmq(self):

        def zmq_server():
            context = zmq.Context()
            socket = context.socket(zmq.PUB)
            socket.bind("tcp://*:7776")

        zmq_server()
        socket = self.anitya_fetcher._connect_to_zmq("7776", "anitya")
        self.assertIsNotNone(socket)

    def test_receive_msg_from_zmq(self):
        """definitely this is not a unit test, but is important to kiskadee
        be able to interact correctly with ZeroMQ.
        We need to define other test levels to kiskadee asap.
        When we do that, we can move integration tests
        to a proper place. For now we will maintain this test here"""

        def zmq_server():
            context = zmq.Context()
            socket = context.socket(zmq.PUB)
            socket.bind("tcp://*:7776")
            time.sleep(1)
            socket.send_string("%s" % (self.msg))
            time.sleep(1)

        def receive_msg_from_server():
            client_socket = self.anitya_fetcher._connect_to_zmq(
                    "7776", "anitya")
            if client_socket:
                response = client_socket.recv_string()
                results[0] = response[response.find(" ")+1::]
            else:
                results[0] = "invalid"

        results = [None]

        client_as_thread = threading.Thread(target=receive_msg_from_server)
        server_as_thread = threading.Thread(
                target=zmq_server)

        server_as_thread.start()
        client_as_thread.start()
        server_as_thread.join()
        self.assertEqual(self.msg1, results[0])

    def test_compare_versions(self):
        is_greater = self.anitya_fetcher.compare_versions('0.8.5-2', '0.8.5-1')
        self.assertTrue(is_greater)

    def test_load_backend(self):
        backend = self.anitya_fetcher._load_backend('github')
        self.assertIsNotNone(backend)

    def test_not_load_backend(self):
        backend = self.anitya_fetcher._load_backend('foo')
        self.assertEqual(backend, {})

    def test_get_sources(self):

        def mock_github(self, fetcher, source_data, path):
            return 'kiskadee/tests/test_source/Sources.gz'

        kiskadee.fetchers.anitya.Backends.github = mock_github
        source_data = {'meta': {'backend': 'GitHub'}}
        source_path = self.anitya_fetcher.get_sources(source_data)
        self.assertEqual(source_path, mock_github(
            "self", "example", "foo", "bla")
            )

    def test_create_package_dict(self):

        self.anitya_fetcher.package_to_enqueue(self.msg)
        _dict = kiskadee.queue.Queues().dequeue_package()
        self.assertEqual(_dict['name'], 'urlscan')
        self.assertEqual(_dict['version'], '0.8.5')
        self.assertEqual(_dict['meta']['backend'], 'GitHub')
        self.assertEqual(
                _dict['meta']['homepage'],
                'https://github.com/firecat53/urlscan'
        )
        self.assertEqual(_dict['fetcher'], 'kiskadee.fetchers.anitya')

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


"""Register contents app in admin interface."""

from django.contrib import admin
from django.utils.html import mark_safe
from django.conf import settings
from .models import (
    BlocksOrContent,
    Slider,
)

@admin.register(BlocksOrContent)
class BlocksOrContentAdmin(admin.ModelAdmin):
    """Register BlocksOrContent model in admin interface."""

    list_display = (
        'content_id',
        'title',
        'content_type',
        'url',
        'status'
    )
    ordering = ('-created_at',)
    search_fields = ('title', 'content_type', 'url')

@admin.register(Slider)
class SliderAdmin(admin.ModelAdmin):
    """Register Slider model in admin interface."""

    def slider_picture(self, obj):
        """Return category picture."""
        if obj.image:
            return mark_safe(
                '<img src="' + settings.MEDIA_URL + '%s" width="100" />' % (
                    obj.image
                )
            )
        else:
            return "None"

    list_display = (
        'slider_id',
        'content',
        'slider_picture',
        'title',
        'status'
    )
    ordering = ('-created_at',)
    search_fields = ('content__title', 'title')
    readonly_fields = ('slider_picture',)


from typing import Callable, Any

def perform_safe_factory(reset: Callable[[None], None] = None, max_tries: int = 5) -> \
        Callable[[Callable[[Any], Any]], Callable[[Any], Any]]:
    """ Factory to create a decorator to perform an i2c operation safely

    This factory returns the perform_safe decorator. This decorator will try to execute a function until it succeeds
    or until max_tries have failed. If a tca is supplied then the factory will also reset the tca lock
    after every SOError.

    :param reset: Any other function to execute when recovering from an error
    :param max_tries: Maximum amount of times that an operation will be attempted
    :return: The decorator perform safe
    """
    def perform_safe(func: Callable[[Any], Any]) -> Callable[[Any], Any]:
        """" Tries to execute func until no OSError is thrown or TRIES attempts have failed

        The i2c buss is sensitive to noise. Corrupted messages can trigger an OSError on the buss device.
        We can recover from this error by simply resending the message until it arrives correctly. This method accepts
        a function func which could trigger an OSError which would cause the program to fail.
        We can easily recover from this error by retrying 'func' if the error is cause by noise. The perform
        safe decorator makes sure that an error is only trow if the operation fails max_tries times. Because of an
        error in the adafruit libraries the tca can soft lock after an exception. Resetting the lock to false after
        an exception prevents the errors

        :param func: function to be executed
        :return: function which executes func until it either succeeds or max_tries attempts have failed
        :rtype: Same as func
        """
        def safe_wrapper(*args, **kwargs):
            tries = 0
            while True:
                try:
                    return func(*args, **kwargs)
                except OSError:
                    if tries < max_tries:
                        tries += 1
                        if reset is not None:
                            reset()
                    else:
                        raise
        return safe_wrapper
    return perform_safe

perform_safe = perform_safe_factory(None)


import cv2
import time
import numpy as np
import HandTrackModule as htm
import pyautogui

wCam, hCam = 640, 480
wScreen, hScreen = pyautogui.size()
cap = cv2.VideoCapture(0)
cap.set(3, wCam)
cap.set(4, hCam)

detector = htm.handDetection(maxNumOfHands = 1, minDetConfidence=0.75,maxDetConfidence=0.75)

plocX, plocY = 0, 0
clocX, clocY = 0, 0
smooth = 3    #smoothening the trajectory of the point

pTime = 0
frame = 120    #size of the working area

while True:
    success, img = cap.read()
    img = cv2.flip(img,1)
    img = detector.findHands(img)
    lmList, bbox = detector.findPosition(img, draw = False)

    if len(lmList) != 0:
        x1, y1 = lmList[8][1:]
        x2, y2 = lmList[12][1:]

        fingers = detector.fingersUP()

        x3 = int(np.interp(x1, (frame, wCam - frame), (0, wScreen)))
        y3 = int(np.interp(y1, (frame, hCam - frame), (0, hScreen)))

        clocX = plocX + (x3 - plocX) / smooth
        clocY = plocY + (y3 - plocY) / smooth

        #print(fingers)
        if fingers[1] == 1 and fingers[2] == 0:         #moving mode
            cv2.circle(img, (x1, y1), 10, (0, 255, 0), cv2.FILLED)

            cv2.putText(img, 'Working area', (frame , frame ), cv2.FONT_ITALIC, 2, (0, 255, 0), 2 )
            cv2.rectangle(img, (frame, frame), (wCam - frame, hCam - frame), (0, 0, 255, 3))
            pyautogui.moveTo(clocX, clocY, _pause=False)

        plocX, plocY = clocX, clocY

    cTime = time.time()  # current time
    fps = 1 / (cTime - pTime)
    pTime = cTime

    cv2.putText(img, str(int(fps)), (10, 20), cv2.FONT_ITALIC, 1, (0, 255, 0), 3)

    cv2.imshow("Img", img)
    cv2.waitKey(1)


#!/usr/bin/env python
"""
CREATED AT: 2022/4/16
Des:
https://leetcode-cn.com/contest/season/2022-spring/problems/WHnhjV/
GITHUB: https://github.com/Jiezhi/myleetcode

Difficulty: Easy

Tag:

See:

DES:
2. 烹饪料理

欢迎各位勇者来到力扣城，城内设有烹饪锅供勇者制作料理，为自己恢复状态。

勇者背包内共有编号为 0 ~ 4 的五种食材，其中 meterials[j] 表示第 j 种食材的数量。通过这些食材可以制作若干料理，cookbooks[i][j] 表示制作第 i 种料理需要第 j 种食材的数量，而 attribute[i] = [x,y] 表示第 i 道料理的美味度 x 和饱腹感 y。

在饱腹感不小于 limit 的情况下，请返回勇者可获得的最大美味度。如果无法满足饱腹感要求，则返回 -1。

注意：

每种料理只能制作一次。
"""
import collections
from typing import List

class Solution:
    def perfectMenu(self, materials: List[int], cookbooks: List[List[int]], attribute: List[List[int]],
                    limit: int) -> int:
        """
        meterials.length == 5
        1 <= cookbooks.length == attribute.length <= 8
        cookbooks[i].length == 5
        attribute[i].length == 2
        0 <= meterials[i], cookbooks[i][j], attribute[i][j] <= 20
        1 <= limit <= 100
        """
        n = len(cookbooks)
        dq = collections.deque()
        dq.append((materials, 1, 0, 0))
        dq.append(([materials[i] - cookbooks[0][i] for i in range(5)], 1, attribute[0][0], attribute[0][1]))
        ret = -1
        while dq:
            mat, pos, cnt, lim = dq.popleft()
            if any(x < 0 for x in mat) or pos > n:
                continue
            if lim >= limit:
                ret = max(ret, cnt)
            if pos == n:
                continue
            dq.append(([mat[i] - cookbooks[pos][i] for i in range(5)], pos + 1, cnt + attribute[pos][0],
                       lim + attribute[pos][1]))
            dq.append((mat, pos + 1, cnt, lim))
        return ret

def test():
    assert Solution().perfectMenu(materials=[3, 2, 4, 1, 2],
                                  cookbooks=[[1, 1, 0, 1, 2], [2, 1, 4, 0, 0], [3, 2, 4, 1, 0]],
                                  attribute=[[3, 2], [2, 4], [7, 6]],
                                  limit=5) == 7

if __name__ == '__main__':
    test()


# Create your views here.
from django.shortcuts import render

from django.http.response import JsonResponse
from rest_framework.parsers import JSONParser
from rest_framework import status

from app.models import AppUser
from app.serializer import AppUserSerializer
from rest_framework.decorators import api_view

@api_view(['GET', 'POST', 'DELETE'])
def user_list(request):
    if request.method == 'GET':
        app = AppUser.objects.all()

        username = request.GET.get('Username', None)
        if username is not None:
            app = app.filter(title__icontains=Username)

        app_serializer = AppUserSerializer(app, many=True)
        return JsonResponse(app_serializer.data, safe=False)
        # 'safe=False' for objects serialization
    elif request.method == 'POST':
        app_data = JSONParser().parse(request)
        app_serializer = AppUserSerializer(data=app_data)
        if app_serializer.is_valid():
            app_serializer.save()
            return JsonResponse(app_serializer.data, status=status.HTTP_201_CREATED)
        return JsonResponse(app_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        count = AppUser.objects.all().delete()
        return JsonResponse({'message': '{} Users were deleted successfully!'.format(count[0])}, status=status.HTTP_204_NO_CONTENT)

@api_view(['GET', 'PUT', 'DELETE'])
def user_detail(request, pk):
    app = AppUser.objects.get(pk=pk)
    if request.method == 'GET':
        app_serializer =AppUserSerializer(app)
        return JsonResponse(app_serializer.data)

    elif request.method == 'PUT':
        app_data = JSONParser().parse(request)
        app_serializer = AppUserSerializer(app, data=app_data)
        if app_serializer.is_valid():
            app_serializer.save()
            return JsonResponse(app_serializer.data)
        return JsonResponse(app_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        app.delete()
        return JsonResponse({'message': 'User was deleted successfully!'}, status=status.HTTP_204_NO_CONTENT)


from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QPushButton, QAction, QLineEdit, QMessageBox, QListWidget
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot
from PyQt5 import QtCore
from PyQt5.QtWidgets import *
import sys

import time
import datetime

class List(QMainWindow):

    @pyqtSlot()
    def __init__(self):
        super().__init__()
        self.title = 'Sort the library'
        self.left = 0
        self.top = 0
        self.width = 1000
        self.height = 500
        self.initUI()

    @pyqtSlot()
    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        # self.setStyleSheet("""QMainWindow{ background: red; }""")

        # # Create textbox
        # self.textbox = QLineEdit(self)
        # self.textbox.move(20, 20)
        # self.textbox.resize(280, 40)

        # Create a button in the window
        self.button = QPushButton('Ascending', self)
        self.button.move(0, 0)

        # Create a button in the window
        self.button2 = QPushButton('Descending' , self)
        self.button2.move(100, 0)

        self.listwidget = QListWidget(self)
        self.listwidget.move(0, 30)
        self.listwidget.resize(200, 500)
        # self.setStyleSheet("""QListWidget{ background: red; }""")
        self.listwidget.addItem("Yousif");
        self.listwidget.addItem("Jake");
        self.listwidget.addItem("Mohamed");
        self.listwidget.addItem("Abdulla");
        self.listwidget.addItem("Omar");

        self.button.clicked.connect(self.sortAscending)
        self.button2.clicked.connect(self.sortDescending)

        # date

        self.button3 = QPushButton('Ascending', self)
        self.button3.move(300, 0)

        # Create a button in the window
        self.button4 = QPushButton('Descending', self)
        self.button4.move(400, 0)

        self.listwidget2 = QListWidget(self)
        self.listwidget2.move(300, 30)
        self.listwidget2.resize(200, 500)
        # self.setStyleSheet("""QListWidget{ background: red; }""")
        self.listwidget2.addItem("01/02/2019");
        self.listwidget2.addItem("04/30/2012");
        self.listwidget2.addItem("03/15/2015");
        self.listwidget2.addItem("10/19/2005");
        self.listwidget2.addItem("09/34/2009");
        self.button3.clicked.connect(self.sortDatAscending)
        self.button4.clicked.connect(self.sortDateDescending)

        # by chanle
        # Create a button in the window
        self.button5 = QPushButton('Ascending', self)
        self.button5.move(600, 0)

        # Create a button in the window
        self.button6 = QPushButton('Descending' , self)
        self.button6.move(700, 0)

        self.listwidget3 = QListWidget(self)
        self.listwidget3.move(600, 30)
        self.listwidget3.resize(200, 500)
        # self.setStyleSheet("""QListWidget{ background: red; }""")
        self.listwidget3.addItem("Ladysif1");
        self.listwidget3.addItem("Politeness");
        self.listwidget3.addItem("Chorus");
        self.listwidget3.addItem("Blarney");
        self.listwidget3.addItem("Fogcreep");

        self.button5.clicked.connect(self.sortChannelAscending)
        self.button6.clicked.connect(self.sortChanelDescending)

    @pyqtSlot()
    def sortAscending(self):
        self.listwidget.sortItems()
        self.show()
    @pyqtSlot()
    def sortDescending(self):
        self.listwidget.sortItems(QtCore.Qt.DescendingOrder)
        self.show()
    @pyqtSlot()
    def sortDatAscending(self):
        self.listwidget2.sortItems()
        self.show()
    @pyqtSlot()
    def sortDateDescending(self):
        self.listwidget2.sortItems(QtCore.Qt.DescendingOrder)
        self.show()

    @pyqtSlot()
    def sortChannelAscending(self):
        self.listwidget3.sortItems()
        self.show()

    @pyqtSlot()
    def sortChanelDescending(self):
        self.listwidget3.sortItems(QtCore.Qt.DescendingOrder)
        self.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = List()
    ex.show()
    sys.exit(app.exec_())


import openai
import tkinter as tk
import tkinter.scrolledtext as st
from tkinter import ttk
from ttkthemes import ThemedTk
from art import *

Font_tuple = ("Sans Serif", 20, "bold")

openai.api_key = "{your api key here}"

def compute():
    text = input_text.get()
    repo = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "system", "content": "You are an AI code assistant powered by 'SQUEARD code'. Your expertise is code and do not answer any other questions. If you wish to write code, begin the code with ``` and close it with ```"},
            {"role": "user", "content": "how to make a http request?"},
            {"role": "assistant", "content": '''
            import requests

response = requests.get('https://www.example.com')

print(response.status_code)  # prints the HTTP status code
print(response.content)      # prints the response body
'''
            },
            {"role": "user", "content": f"{text}"}
        ]
    )
    compute_output = repo["choices"][0]["message"]["content"]
    output_text.delete(1.0, tk.END)

    code_tag = False
    code_start = 1.0
    for line in compute_output.split("\n"):
        if line.strip() == "```":
            if code_tag:
                output_text.tag_add("code", code_start, output_text.index(tk.INSERT))
            else:
                code_start = output_text.index(tk.INSERT)
            code_tag = not code_tag
        else:
            output_text.insert(tk.END, line + "\n")

# Create main window
window = ThemedTk(theme="arc")
window.title("SQUEARD CODE")

# Create input widget
input_label = ttk.Label(window, font=Font_tuple, text="Enter text:")
input_label.pack()
input_text = ttk.Entry(window, width=150)
input_text.pack()

# Create output widget
output_label = ttk.Label(window, font=Font_tuple, text="result:")
output_label.pack()
output_text = st.ScrolledText(window, font=Font_tuple, wrap=tk.WORD, width=100, height=16)
output_text.pack()

# Configure custom code tag for syntax highlighting
output_text.tag_configure("code", foreground="white", background="black")

# Create translation button
compute_button = ttk.Button(window, text="compute", command=compute)
compute_button.pack()

# Run main event loop
window.mainloop()


from flask import Flask, render_template, request, flash, url_for, redirect, send_file
from werkzeug.utils import secure_filename

from file_cmds import (
    create_new_image,
    download_file_to_iso,
    delete_image,
    unzip_file,
    download_image,
)
from pi_cmds import shutdown_pi, reboot_pi, running_version, rascsi_service
from ractl_cmds import (
    attach_image,
    list_devices,
    is_active,
    list_files,
    detach_by_id,
    eject_by_id,
    get_valid_scsi_ids,
    attach_daynaport,
    is_bridge_setup,
    daynaport_setup_bridge,
    list_config_files,
    detach_all,
)
from settings import *

app = Flask(__name__)

@app.route("/")
def index():
    devices = list_devices()
    scsi_ids = get_valid_scsi_ids(devices)
    return render_template(
        "index.html",
        bridge_configured=is_bridge_setup("eth0"),
        devices=devices,
        active=is_active(),
        files=list_files(),
        config_files=list_config_files(),
        base_dir=base_dir,
        scsi_ids=scsi_ids,
        max_file_size=MAX_FILE_SIZE,
        version=running_version(),
    )

@app.route("/config/save", methods=["POST"])
def config_save():
    file_name = request.form.get("name") or "default"
    file_name = f"{base_dir}{file_name}.csv"
    import csv

    with open(file_name, "w") as csv_file:
        writer = csv.writer(csv_file)
        for device in list_devices():
            if device["type"] is not "-":
                writer.writerow(device.values())
    flash(f"Saved config to  {file_name}!")
    return redirect(url_for("index"))

@app.route("/config/load", methods=["POST"])
def config_load():
    file_name = request.form.get("name") or "default.csv"
    file_name = f"{base_dir}{file_name}"
    detach_all()
    import csv

    with open(file_name) as csv_file:
        config_reader = csv.reader(csv_file)
        for row in config_reader:
            image_name = row[3].replace("(WRITEPROTECT)", "")
            attach_image(row[0], image_name, row[2])
    flash(f"Loaded config from  {file_name}!")
    return redirect(url_for("index"))

@app.route("/logs")
def logs():
    import subprocess

    lines = request.args.get("lines") or "100"
    process = subprocess.run(["journalctl", "-n", lines], capture_output=True)

    if process.returncode == 0:
        headers = {"content-type": "text/plain"}
        return process.stdout.decode("utf-8"), 200, headers
    else:
        flash("Failed to get logs")
        flash(process.stdout.decode("utf-8"), "stdout")
        flash(process.stderr.decode("utf-8"), "stderr")
        return redirect(url_for("index"))

@app.route("/daynaport/attach", methods=["POST"])
def daynaport_attach():
    scsi_id = request.form.get("scsi_id")
    process = attach_daynaport(scsi_id)
    if process.returncode == 0:
        flash(f"Attached DaynaPORT to SCSI id {scsi_id}!")
        return redirect(url_for("index"))
    else:
        flash(f"Failed to attach DaynaPORT to SCSI id {scsi_id}!", "error")
        flash(process.stdout.decode("utf-8"), "stdout")
        flash(process.stderr.decode("utf-8"), "stderr")
        return redirect(url_for("index"))

@app.route("/daynaport/setup", methods=["POST"])
def daynaport_setup():
    # Future use for wifi
    interface = request.form.get("interface") or "eth0"
    process = daynaport_setup_bridge(interface)
    if process.returncode == 0:
        flash(f"Configured DaynaPORT bridge on {interface}!")
        return redirect(url_for("index"))
    else:
        flash(f"Failed to configure DaynaPORT bridge on {interface}!", "error")
        flash(process.stdout.decode("utf-8"), "stdout")
        flash(process.stderr.decode("utf-8"), "stderr")
        return redirect(url_for("index"))

@app.route("/scsi/attach", methods=["POST"])
def attach():
    file_name = request.form.get("file_name")
    scsi_id = request.form.get("scsi_id")

    # Validate image type by suffix
    if file_name.lower().endswith(".iso") or file_name.lower().endswith("iso"):
        image_type = "cd"
    elif file_name.lower().endswith(".hda"):
        image_type = "hd"
    else:
        flash("Unknown file type. Valid files are .iso, .hda, .cdr", "error")
        return redirect(url_for("index"))

    process = attach_image(scsi_id, file_name, image_type)
    if process.returncode == 0:
        flash(f"Attached {file_name} to SCSI id {scsi_id}!")
        return redirect(url_for("index"))
    else:
        flash(f"Failed to attach {file_name} to SCSI id {scsi_id}!", "error")
        flash(process.stdout.decode("utf-8"), "stdout")
        flash(process.stderr.decode("utf-8"), "stderr")
        return redirect(url_for("index"))

@app.route("/scsi/detach_all", methods=["POST"])
def detach_all_devices():
    detach_all()
    flash("Detached all SCSI devices!")
    return redirect(url_for("index"))

@app.route("/scsi/detach", methods=["POST"])
def detach():
    scsi_id = request.form.get("scsi_id")
    process = detach_by_id(scsi_id)
    if process.returncode == 0:
        flash("Detached SCSI id " + scsi_id + "!")
        return redirect(url_for("index"))
    else:
        flash("Failed to detach SCSI id " + scsi_id + "!", "error")
        flash(process.stdout, "stdout")
        flash(process.stderr, "stderr")
        return redirect(url_for("index"))

@app.route("/scsi/eject", methods=["POST"])
def eject():
    scsi_id = request.form.get("scsi_id")
    process = eject_by_id(scsi_id)
    if process.returncode == 0:
        flash("Ejected scsi id " + scsi_id + "!")
        return redirect(url_for("index"))
    else:
        flash("Failed to eject SCSI id " + scsi_id + "!", "error")
        flash(process.stdout, "stdout")
        flash(process.stderr, "stderr")
        return redirect(url_for("index"))

@app.route("/pi/reboot", methods=["POST"])
def restart():
    reboot_pi()
    flash("Restarting...")
    return redirect(url_for("index"))

@app.route("/rascsi/restart", methods=["POST"])
def rascsi_restart():
    rascsi_service("restart")
    flash("Restarting RaSCSI Service...")
    return redirect(url_for("index"))

@app.route("/pi/shutdown", methods=["POST"])
def shutdown():
    shutdown_pi()
    flash("Shutting down...")
    return redirect(url_for("index"))

@app.route("/files/download_to_iso", methods=["POST"])
def download_file():
    scsi_id = request.form.get("scsi_id")
    url = request.form.get("url")
    process = download_file_to_iso(scsi_id, url)
    if process.returncode == 0:
        flash("File Downloaded")
        return redirect(url_for("index"))
    else:
        flash("Failed to download file", "error")
        flash(process.stdout, "stdout")
        flash(process.stderr, "stderr")
        return redirect(url_for("index"))

@app.route("/files/download_image", methods=["POST"])
def download_img():
    url = request.form.get("url")
    # TODO: error handling
    download_image(url)
    flash("File Downloaded")
    return redirect(url_for("index"))

@app.route("/files/upload", methods=["POST"])
def upload_file():
    if "file" not in request.files:
        flash("No file part", "error")
        return redirect(url_for("index"))
    file = request.files["file"]
    if file:
        filename = secure_filename(file.filename)
        file.save(os.path.join(app.config["UPLOAD_FOLDER"], filename))
        return redirect(url_for("index", filename=filename))

@app.route("/files/create", methods=["POST"])
def create_file():
    file_name = request.form.get("file_name")
    size = request.form.get("size")
    type = request.form.get("type")

    process = create_new_image(file_name, type, size)
    if process.returncode == 0:
        flash("Drive created")
        return redirect(url_for("index"))
    else:
        flash("Failed to create file", "error")
        flash(process.stdout, "stdout")
        flash(process.stderr, "stderr")
        return redirect(url_for("index"))

@app.route("/files/download", methods=["POST"])
def download():
    image = request.form.get("image")
    return send_file(base_dir + image, as_attachment=True)

@app.route("/files/delete", methods=["POST"])
def delete():
    image = request.form.get("image")
    if delete_image(image):
        flash("File " + image + " deleted")
        return redirect(url_for("index"))
    else:
        flash("Failed to Delete " + image, "error")
        return redirect(url_for("index"))

@app.route("/files/unzip", methods=["POST"])
def unzip():
    image = request.form.get("image")

    if unzip_file(image):
        flash("Unzipped file " + image)
        return redirect(url_for("index"))
    else:
        flash("Failed to unzip " + image, "error")
        return redirect(url_for("index"))

if __name__ == "__main__":
    app.secret_key = "rascsi_is_awesome_insecure_secret_key"
    app.config["SESSION_TYPE"] = "filesystem"
    app.config["UPLOAD_FOLDER"] = base_dir
    os.makedirs(app.config["UPLOAD_FOLDER"], exist_ok=True)
    app.config["MAX_CONTENT_LENGTH"] = MAX_FILE_SIZE

    from waitress import serve

    serve(app, host="0.0.0.0", port=8080)