﻿  #!C:\Python\Python311\python.exe
# -*- coding: utf-8 -*-
# __init__.py
# from datetime import datetime
import datetime
import json
import random
from flask import Flask, jsonify, render_template
from flask import make_response
from flask import request
from flask import abort
from werkzeug.routing import BaseConverter

from .handlers.cl_man_req  import  *
# # from .handlers.cl_man_req  import  cl_man_req
# from handlers import cl_man_req
# import logging
# import sys

app = Flask(__name__)
# print("__init__ sys.path")
# print(sys.path)

from .registration  import  * 
from .device_management   import  * 
# app.debug = True
 
if app.debug is not True: 
    import logging
    if platform.system() == "Windows":
        path_log = 'f:/xampp/htdocs/asia-tires.ruloc/www/telegram_esp32adv/python.log'
    else:
        path_log = '/opt/Telegram_ESP32/site2/telegram_esp32adv/python.log'
    from logging.handlers import RotatingFileHandler
    file_handler = RotatingFileHandler(path_log
                                       , maxBytes=1024 * 1024 * 100,
                                        backupCount=20)
    # file_handler.setLevel(logging.ERROR)
    formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
    file_handler.setFormatter(formatter)
    app.logger.addHandler(file_handler)
 
app.logger.info("__init__ >>> %s", 111)


@app.route('/<string:API_KEY>/email/', methods=['POST'])  # 02-11-202310:00 
def request_email(API_KEY):  # 02-11-202310:00
    print("request_email")
    print(request.method)
    request_data = request.get_json()
    print(request_data)
    ans = cl_man_req.regRequest(request , "", app, API_KEY, True)  # 10-11-202314:01  
    if ans != 0 and ans == 1:
            return json.dumps({'result':clC.resultNotValidData}), clC.resultNotValidData, {'ContentType':'application/json'} 
    
    ans = cl_man_req.request_email(API_KEY, request_data, app)
    # ans = 0  # d++
    if ans == 0:
        # raise InvalidAPIUsage("this mac address is not registered", status_code=406)
        # abort(401, description="Resource not found")
        return json.dumps({'result':clC.resultNotValidData}), clC.resultNotValidData, {'ContentType':'application/json'} 
        # return json.dumps({'success':True}), 200, {'ContentType':'application/json'} 
    return json.dumps({'result':ans}), ans, {'ContentType':'application/json'}
    

@app.route('/<string:API_KEY>/recipient/', methods=['POST'])  # 01-11-202318:59  
def request_recipient(API_KEY):  # 01-11-202318:59  
    print("request_recipient")
    # d =jsonify(request.json)
    print(request.method)
    request_data = request.get_json()
    print(request_data)
    ans = cl_man_req.regRequest(request , "", app, API_KEY, True)  # 10-11-202314:01  
    if ans != 0 and ans == 1:
            return json.dumps({'result':clC.resultNotValidData}), clC.resultNotValidData, {'ContentType':'application/json'} 
    
    ans = cl_man_req.request_recipient(API_KEY, request_data, app)
    # ans = 0  # d++
    if ans == 0:
        # raise InvalidAPIUsage("this mac address is not registered", status_code=406)
        # abort(401, description="Resource not found")
        return json.dumps({'result':clC.resultNotValidData}), clC.resultNotValidData, {'ContentType':'application/json'} 
        # return json.dumps({'success':True}), 200, {'ContentType':'application/json'} 
    return json.dumps({'result':clC.resultOK}), clC.resultOK, {'ContentType':'application/json'}

 
@app.route('/<string:API_KEY>/smtp/', methods=['POST'])  # 01-11-202316:35
def request_smtp(API_KEY):  # 01-11-202316:35
    print("request_smtp")
    # d =jsonify(request.json)
    print(API_KEY)
    print(request.method)
    request_data = request.get_json()
    print(request_data)
    ans = cl_man_req.regRequest(request , "", app, API_KEY, True)  # 10-11-202314:01  
    if ans != 0 and ans == 1:
            return json.dumps({'result':clC.resultNotValidData}), clC.resultNotValidData, {'ContentType':'application/json'} 
    
    ans = cl_man_req.request_smtp(API_KEY, request_data, app)
    # ans = 0  # d++
    if ans == 0:
        # raise InvalidAPIUsage("this mac address is not registered", status_code=406)
        # abort(401, description="Resource not found")
        return json.dumps({'result':clC.resultNotValidData}), clC.resultNotValidData, {'ContentType':'application/json'} 
        # return json.dumps({'success':True}), 200, {'ContentType':'application/json'} 
    return json.dumps({'result':clC.resultOK}), clC.resultOK, {'ContentType':'application/json'}


# @app.route('/<string:API_KEY>/infos/', methods=['POST'])
@app.route('/<string:API_KEY>/', methods=['POST'])  # 27-10-202314:39
def get_records_t(API_KEY):
    print("get_records_t")
    ans = cl_man_req.regRequest(request , "", app, API_KEY)  # 10-11-202314:01  
    if ans != 0 and ans == 1:
            return json.dumps({'result':clC.resultNotValidData}), clC.resultNotValidData, {'ContentType':'application/json'} 
    # print(json.dumps(request.headers))
    print(json.dumps(dict(request.headers)))
    # d =jsonify(request.json)
    print(request.method)
    request_data = request.get_json()
    print(request_data)
    print("DTF")
    print(request_data["DTF"])
    # request_data["DTS"]=request_data["DTS2"]/1000
    # request_data["DTF"]=request_data["DTF2"]/1000
    ans = cl_man_req.get_records_t(API_KEY, request_data, app)
    # ans = 0  # d++
    if ans == 0:
        # raise InvalidAPIUsage("this mac address is not registered", status_code=406)
        # abort(401, description="Resource not found")
        return json.dumps({'result':clC.resultNotValidData}), clC.resultNotValidData, {'ContentType':'application/json'} 
        # return json.dumps({'success':True}), 200, {'ContentType':'application/json'} 
    return jsonify(ans) 
    
    # if request_data:
    #     if 'language' in request_data:
    #         language = request_data['language']
    #
    # return jsonify(request.json)


@app.route('/get_logs_name_device/', methods=['POST'])  # 11-11-202310:46
def get_logs_name_device():
    print("get_logs_name_device")
    print(json.dumps(dict(request.headers)))
    print(request.method)
    try:
        request_data = request.get_json()
        print(request_data)
    
        ans = cl_man_req.get_logs_name_device(request_data, app)
        # ans = 0  # d++
        if ans == 0:
            # raise InvalidAPIUsage("this mac address is not registered", status_code=406)
            # abort(401, description="Resource not found")
            return json.dumps({'result':clC.resultNotValidData}), clC.resultNotValidData, {'ContentType':'application/json'} 
            # return json.dumps({'success':True}), 200, {'ContentType':'application/json'} 
        return jsonify(ans) 
    except Exception as inst:
        print("get_logs_name_device ini       Exception")
        print(type(inst))  # the exception type
        print(inst.args)  # arguments stored in .args
        print(inst)  # __str__ allows args to be printed directly,
        return json.dumps({'result':clC.resultNotValidData}), clC.resultNotValidData, {'ContentType':'application/json'} 


@app.route('/get_records_t_name_device/', methods=['POST'])  # 06-11-202319:04
def get_records_t_name_device():
    print("get_records_t_name_device")
    print(json.dumps(dict(request.headers)))
    print(request.method)
    try:
        request_data = request.get_json()
        print(request_data)
    
        ans = cl_man_req.get_records_t_name_device(request_data, app)
        # ans = 0  # d++
        if ans == 0:
            # raise InvalidAPIUsage("this mac address is not registered", status_code=406)
            # abort(401, description="Resource not found")
            return json.dumps({'result':clC.resultNotValidData}), clC.resultNotValidData, {'ContentType':'application/json'} 
            # return json.dumps({'success':True}), 200, {'ContentType':'application/json'} 
        return jsonify(ans) 
    except Exception as inst:
        print("get_records_t_name_device ini       Exception")
        print(type(inst))  # the exception type
        print(inst.args)  # arguments stored in .args
        print(inst)  # __str__ allows args to be printed directly,
        return json.dumps({'result':clC.resultNotValidData}), clC.resultNotValidData, {'ContentType':'application/json'} 


@app.route('/get_list_name_device/', methods=['POST'])  # 06-11-202313:03
def get_list_name_device_ByIdUserGrafana():
    print("get_list_name_device_ByIdUserGrafana")
    # print(json.dumps(request.headers))
    print(json.dumps(dict(request.headers)))
    # d =jsonify(request.json)
    print(request.method)
    try:
        request_data = request.get_json()
        print(request_data)
    
        ans = cl_man_req.get_list_name_device_ByIdUserGrafana(request_data, app)
        if ans == 0:
            # raise InvalidAPIUsage("this mac address is not registered", status_code=406)
            # abort(401, description="Resource not found")
            return json.dumps({'result':clC.resultNotValidData}), clC.resultNotValidData, {'ContentType':'application/json'} 
            # return json.dumps({'success':True}), 200, {'ContentType':'application/json'} 
        return jsonify(ans) 
    except Exception as inst:
        print ("Content-type: text/html ;\n\n")
        print
        print("get_list_name_device_ByIdUserGrafana   Exception")
        print(type(inst))  # the exception type
        print(inst.args)  # arguments stored in .args
        print(inst)  # __str__ allows args to be printed directly,
        raise InvalidAPIUsage(str(inst), status_code=clC.resultNotValidData)
        # abort(423, description="Resource not found")
        return
    

@app.route('/<string:API_KEY>/infos/')
def get_records_t0(API_KEY):  # 27-10-202314:39
    ans = cl_man_req.get_records_t(API_KEY, app)
    # ans = 0  # d++
    if ans == 0:
        # raise InvalidAPIUsage("this mac address is not registered", status_code=406)
        # abort(401, description="Resource not found")
        return json.dumps({'result':clC.resultNotValidData}), clC.resultNotValidData, {'ContentType':'application/json'} 
        # return json.dumps({'success':True}), 200, {'ContentType':'application/json'} 
    return jsonify(ans) 


@app.route('/<string:API_KEY>/')
@app.route('/<string:API_KEY>/', methods=['GET'])
def get_last_t(API_KEY):  # 26-10-202318:26  # 28-10-20236:51
    request_data = {}
    ans = cl_man_req.regRequest(request , "", app, API_KEY)  # 10-11-202314:01  
    if ans != 0 and ans == 1:
            return json.dumps({'result':clC.resultNotValidData}), clC.resultNotValidData, {'ContentType':'application/json'} 
    if 'd' in request.args:
        request_data["d"] = request.args.get('d')  
    ans = cl_man_req.get_last_t(API_KEY, request_data, app)
    # ans = 0  # d++
    if ans == 0:
        # raise InvalidAPIUsage("this mac address is not registered", status_code=406)
        # abort(401, description="Resource not found")
        return json.dumps({'result':clC.resultNotValidData}), clC.resultNotValidData, {'ContentType':'application/json'} 
        # return json.dumps({'success':True}), 200, {'ContentType':'application/json'} 
    return jsonify(ans) 


# https://p.xxxx.ru/debug/?m=7C87CED14A8C&t=10&d=0203005,
# где m – MAC адрес устройства,
# t – фактическая температура без дробной части.
# d – версия прошивки блока индикации.
# @app.route('/', methods=['GET'], defaults={'m': ''})
# @app.route('/<path:path>', methods=['GET'])
@app.route('/debug/', methods=['GET'])
def reg_t_debug():  # #05-11-202318:48
    app.logger.warning(" reg_t_debug")
    randTempOfD = 1
    randTempOfU = 10
    
    try:
        m = request.args.get('m')
        #m = m.lower()
        m = m.upper()
        t = request.args.get('t')
        t = int(t) 
        
        ts = request.args.get('ts')
        ts = int(ts) 
        
        tstep = request.args.get('tstep')
        tstep = int(tstep) 
        
        niter = request.args.get('niter')
        niter = int(niter) 
        
        # d = request.args.get('d')
        # d = d.upper()
        d = 0

    except ValueError:  # Температурой не является числом
        raise InvalidAPIUsage("wrong data", status_code=clC.resultNotValidData)
        # abort(423, description="Resource not found")
        return
    # Temperature registration
    # app.logger.error('get_tget_t')
    for iterM in range(0, niter, 1):
        time = ts + tstep * iterM
        tt = t + random.randint(randTempOfD, randTempOfU)
        ans = cl_man_req.reg_t_debug(tt, m , time, request.remote_addr, app)
      
    # ans = 0  # d++
    if ans != 0:
        if ans == 1:
            # raise InvalidAPIUsage("this mac address is not registered", status_code=406)
            # abort(401, description="Resource not found")
            return json.dumps({'result':clC.resultNotValidData}), clC.resultNotValidData, {'ContentType':'application/json'} 
            # return json.dumps({'success':True}), 200, {'ContentType':'application/json'} 
    app.logger.warning("request.remote_addr>>> %s", request.remote_addr)
    return jsonify({'t': t, 'm': m}) 
    # return 'GET You want path: %s' % path

 
# https://p.xxxx.ru/?m=7C87CED14A8C&t=10&d=0203005,
# где m – MAC адрес устройства,
# t – фактическая температура без дробной части.
# d – версия прошивки блока индикации.
# @app.route('/', methods=['GET'], defaults={'m': ''})
# @app.route('/<path:path>', methods=['GET'])
@app.route('/', methods=['GET'])
def reg_t():  # 25-10-202321:36
    app.logger.warning(" reg_t") 
    try:
        app.logger.warning("reg_t >>> %s", str(request.args))
        
        m = request.args.get("m")
        if m is None:
            raise  

        # m = request.args.get('m')
        #m = m.lower()
        m = m.upper()
        ans = cl_man_req.regRequest(request , m, app)  # 10-11-202314:01  
        if ans != 0 and ans == 1:
                return json.dumps({'result':clC.resultNotValidData}), clC.resultNotValidData, {'ContentType':'application/json'} 
        
        
        t = request.args.get('t')
        t = int(t)
        
        firmware_number = 0 
        if 'd' in request.args:
            firmware_number = request.args.get('d')        

    # except ValueError:  # Температурой не является числом
    # except Exception:
    #     raise InvalidAPIUsage("wrong data", status_code=clC.resultNotValidData)
    #     # abort(423, description="Resource not found")
    except Exception as inst:
        raise InvalidAPIUsage("wrong data", status_code=clC.resultNotValidData)
        print("reg_t import      Exception")
        print(type(inst))  # the exception type
        print(inst.args)  # arguments stored in .args
        print(inst)  # __str__ allows args to be printed directly,
    # Temperature registration
    # app.logger.error('get_tget_t')
    
    ans = cl_man_req.reg_t(t, m , firmware_number , request.remote_addr, app)
    # ans = 0  # d++
    if ans != 0:
        if ans == 1:
            # raise InvalidAPIUsage("this mac address is not registered", status_code=406)
            # abort(401, description="Resource not found")
            return json.dumps({'result':clC.resultNotValidData}), clC.resultNotValidData, {'ContentType':'application/json'} 
            # return json.dumps({'success':True}), 200, {'ContentType':'application/json'} 
    app.logger.warning("request.remote_addr>>> %s", request.remote_addr)
    return jsonify({'t': t, 'm': m}) 
    # return 'GET You want path: %s' % path

 
# http://flaskwill.com/todo/api/v1.0/tasksdd?v=op
@app.route('/', methods=['GET'], defaults={'mac': ''})
# @app.route('/<path:path>', methods=['GET'])
@app.route('/<string:mac>/api/v1.0/tasks/mac/', methods=['GET'])
def catch_mac(mac):
    v = request.args.get('v')
    return jsonify({'v': v, 'mac': mac}) 
    # return 'GET You want path: %s' % path


@app.route('/')
def hello_worldR():
    return 'Hello Flask under Apache!'

# # http://flaskwill.com/todo/api/v1.0/tasksdd?v=op
# @app.route('/', methods=['GET'], defaults={'path': ''})
# @app.route('/<path:path>', methods=['GET'])
# def catch_allGET(path):
#     v = request.args.get('v')
#     return jsonify({'path': path, 'v': v}) 
#     # return 'GET You want path: %s' % path

# @app.route('/', methods=['POST'], defaults={'path': ''})
# @app.route('/<path:path>', methods=['POST'])
# def catch_allPOST(path):
#     return 'POST You want path: %s' % path

# @app.route('/', methods=['GET', 'POST'], defaults={'path': ''})
# @app.route('/<path:path>', methods=['GET', 'POST'])
# def catch_all(path):
#     return 'You want path: %s' % path


# @app.before_request
# def before_request():
#     print("before_request() called")
#     path = request.path   
#     method = request.method   
#
#     print(path + " [" + method + "]") 


@app.after_request
def after_request(response):
    """ Logging after every request. """
    # This avoids the duplication of registry in the log,
    # since that 500 is already logged via @app.errorhandler.
    try:
        print("after_request() called %s" % (response.status_code))
        if response.status_code != 500:
            dt = datetime.datetime.now()
            ts = dt.strftime('[%Y-%b-%d %H:%M]')
            # app.logger.warning
            print('after_request %s %s %s %s %s %s' % 
                    (ts,
                    request.remote_addr,
                    request.method,
                    request.scheme,
                    request.full_path,
                    response.status))
    except Exception as inst:
        print("after_request Exception")
        print(type(inst))  # the exception type
        print(inst.args)  # arguments stored in .args
        print(inst)  # __str__ allows args to be printed directly,
        # return json.dumps({'result':clC.resultNotValidData}), clC.resultNotValidData, {'ContentType':'application/json'} 
    return response
       

@app.errorhandler(405)  # Температурой не является числом
# def method_not_allowed(e):
#     return response
class InvalidAPIUsage(Exception):
    status_code = 400

    def __init__(self, message, status_code=None, payload=None):
        super().__init__()
        self.message = message
        if status_code is not None:
            self.status_code = status_code
        self.payload = payload

    def to_dict(self):
        rv = dict(self.payload or ())
        rv['status_code'] = self.status_code
        rv['message'] = self.message
        return rv


@app.errorhandler(InvalidAPIUsage)
def invalid_api_usage(e):
    return jsonify(e.to_dict()), e.status_code
    

if __name__ == "__main__":
    app.run(debug=True)
