import base_run
from user_resource import UserInsert, UserUpdate, UserDelete,UserAuth,UserSelectAll,UserWordInsert,UserUpdatePassword
from user_role_resource import UserRoleInsert, UserRoleUpdate, UserRoleDelete,UserRoleSelectAll
from person_resource import PersonInsert, PersonInsertNoImage, PersonUpdate, PersonDelete, PersonSelect, PersonSelectAll, PersonSend, PersonInsertWithExcel
from person_type_resource import PersonTypeInsert, PersonTypeUpdate, PersonTypeDelete
from person_group_resource import PersonGroupInsert, PersonGroupUpdate, PersonGroupDelete,PersonGroupSelectAll
from server_resource import ServerInsert, ServerUpdate, ServerDelete
from device_resource import DeviceUpdate, DeviceDelete, DeviceSelectAll,PersonToDeviceInsert

from device_type_resource import DeviceTypeInsert,DeviceTypeUpdate,DeviceTypeDelete,DeviceTypeSelectAll
from device_group_resource import DeviceGroupInsert,DeviceGroupUpdate,DeviceGroupDelete,DeviceGroupSelectAll
from device_group_relation_resource import DeviceGroupRelationInsert,DeviceGroupRelationSelectAll,DeviceGroupRelationDelete
from person_group_relation_resource import PersonGroupRelationInsert,PersonGroupRelationSelectAll,PersonGroupRelationDelete
from person_group_and_device_group_relation_resource import PersonGroupAndDeviceGroupRelationInsert,PersonGroupAndDeviceGroupRelationSelectAll,PersonGroupAndDeviceGroupRelationDelete
from grafana_access_json_resource import Grafana_Base,Grafana_Search,Grafana_Query,Grafana_Tag_Key,Grafana_Tag_Value

from punch_card_resource import PunchCardUpload, PunchCard1Upload, PunchCard2Upload,PunchCardRecord, PunchCardSend, PunchCardRecordDownload,PunchCardRecordAll, PunchCardInsert, PunchCardFirst,PunchCardRecordDownload2,PunchCardRecordDownloadGroup,PunchCardRecordDownload2Group, PunchCardRecordToday,PunchCardRecordVerson2,PunchCardRecordDownloadVerson2,PunchCardRecordDownloadGroupVerson2,PunchCardRecordDownload2Verson2,PunchCardRecordDownload2GroupVerson2,ExportShiftPunchCard
from CM26EWH_resource import CM26EWH_Personinfo,CM26EWH_subscription_aps
from version_resource import VersionSelect
#from socket_resource import Socket
from flask import Flask
from flask_restful import Api
#from flask_socketio import SocketIO
from flask_cors import CORS
import atexit
import fcntl
from flask_apscheduler import APScheduler
from datetime import datetime,timezone,timedelta
from line_model import PunchNotifyModel
from test_resource import UserFeatureInsert,UserFeatureUpdate,UserFeatureDelete,UserFeatureSelectAll
from leave_off_work_resource import LeaveOffWorkInsert,LeaveOffWorkUpdate,LeaveOffWorkDelete,LeaveOffWorkSelectAll,LeaveToWord,LeaveToExcel,LeaveToExcelPersonal,LeaveToExcelAll,LeaveToExcelAllVerson2,LeaveToWordVerson2,LeaveToExcelVerson2,LeaveToExcelPersonalVerson2,AnnualLeaveToExcel,AnnualLeaveToExcelVerson2
from holiday_resource import HolidayInsert,HolidayUpdate,HolidayDelete,HolidaySelectAll,HolidayInsertWithExcel
from leave_signing_status_resource import LeaveSigningStatusInsert,LeaveSigningStatusUpdate,LeaveSigningStatusDelete,LeaveSigningStatusSelectAll
from depart_leave_unit_resource import DepartLeaveUnitInsert,DepartLeaveUnitUpdate,DepartLeaveUnitDelete,DepartLeaveUnitSelectAll
from department_resource import DepartmentInsert,DepartmentUpdate,DepartmentDelete,DepartmentSelectAll
from overtime_resource import OvertimeInsert,OvertimeUpdate,OvertimeDelete,OverTimeSelectAll,OvertimeToWord,OvertimeToWordVerson2
from features_resource import FeaturesInsert,FeaturesUpdate,FeaturesDelete,FeaturesSelectAll
from features_role_relation_resource import FeaturesRoleRelationInsert,FeaturesRoleRelationUpdate,FeaturesRoleRelationDelete,FeaturesRoleRelationSelectAll
from features_user_relation_resource import FeaturesUserRelationInsert,FeaturesUserRelationUpdate,FeaturesUserRelationDelete,FeaturesUserRelationSelectAll
from test_resource import SetDateTime
from shift_resource import ShiftInsert,ShiftUpdate,ShiftDelete,ShiftSelectAll
from device_shift_relation_resource import DeviceShiftRelationInsert,DeviceShiftRelationUpdate,DeviceShiftRelationDelete,DeviceShiftRelationSelectAll





app = Flask(__name__)
# ========== views ==========
api = Api(app)
# test resource set date time
api.add_resource(SetDateTime, '/set/dt/<string:dt>')
# ========== resources ==========
api.add_resource(VersionSelect, '/version')
api.add_resource(UserInsert, '/user/insert')
api.add_resource(UserUpdate, '/user/update')
api.add_resource(UserUpdatePassword, '/user/update/password')
api.add_resource(UserDelete, '/user/delete')
api.add_resource(UserSelectAll, '/user/all')
api.add_resource(UserAuth, '/user/auth')
api.add_resource(UserRoleInsert, '/user/role/insert')
api.add_resource(UserRoleUpdate, '/user/role/update')
api.add_resource(UserRoleDelete, '/user/role/delete')
api.add_resource(UserRoleSelectAll, '/user/role/all')
api.add_resource(PersonInsert, '/person/insert')
api.add_resource(PersonInsertNoImage, '/person/insert/no/image')
api.add_resource(PersonInsertWithExcel, '/person/insert/excel')
api.add_resource(PersonUpdate, '/person/update')
api.add_resource(PersonDelete, '/person/delete')
api.add_resource(PersonSelect, '/person/select/<string:ID>')                           # Person ID
api.add_resource(PersonSend, '/person/<string:ID>')                                    # Person Image ID, ID.jpg
api.add_resource(PersonSelectAll, '/person/select/all')
api.add_resource(PersonTypeInsert, '/person/type/insert')
api.add_resource(PersonTypeUpdate, '/person/type/update')
api.add_resource(PersonTypeDelete, '/person/type/delete')
api.add_resource(PersonGroupInsert, '/person/group/insert')
api.add_resource(PersonGroupUpdate, '/person/group/update')
api.add_resource(PersonGroupDelete, '/person/group/delete')
api.add_resource(PersonGroupSelectAll, '/person/group/all')
# api.add_resource(ServerInsert, '/server/insert')
# api.add_resource(ServerUpdate, '/server/update')
# api.add_resource(ServerDelete, '/server/delete')
api.add_resource(DeviceUpdate, '/device/update')
api.add_resource(DeviceDelete, '/device/delete')
api.add_resource(DeviceSelectAll, '/device/select/all')
api.add_resource(PersonToDeviceInsert, '/person/device/insert')


# ========== 2020 08 06 Allen 更新 ==========
# 設備類型新增刪除修改
api.add_resource(DeviceTypeInsert, '/device/type/insert')
api.add_resource(DeviceTypeUpdate, '/device/type/update')
api.add_resource(DeviceTypeDelete, '/device/type/delete')
api.add_resource(DeviceTypeSelectAll, '/device/type/all')
# 設備群組新增刪除修改
api.add_resource(DeviceGroupInsert, '/device/group/insert')
api.add_resource(DeviceGroupUpdate, '/device/group/update')
api.add_resource(DeviceGroupDelete, '/device/group/delete')
api.add_resource(DeviceGroupSelectAll, '/device/group/all')
# 設備與群組關聯新增刪除
api.add_resource(DeviceGroupRelationInsert, '/device/group/relation/insert')
api.add_resource(DeviceGroupRelationDelete, '/device/group/relation/delete')
api.add_resource(DeviceGroupRelationSelectAll, '/device/group/relation/all')
# 人員與人員群組關聯新增刪除
api.add_resource(PersonGroupRelationInsert, '/person/group/relation/insert')
api.add_resource(PersonGroupRelationDelete, '/person/group/relation/delete')
api.add_resource(PersonGroupRelationSelectAll, '/person/group/relation/all')
# 人員群組與設備群組關聯新增刪除
api.add_resource(PersonGroupAndDeviceGroupRelationInsert, '/group/relation/insert')
api.add_resource(PersonGroupAndDeviceGroupRelationDelete, '/group/relation/delete')
api.add_resource(PersonGroupAndDeviceGroupRelationSelectAll, '/group/relation/all')

# ========== 2020 08 06 Allen 更新 結束 ==========

# ========== 2020 08 13 Allen 更新 ==============
# 新增 Grafana json data source 存取
api.add_resource(Grafana_Base,'/grafana/api')
api.add_resource(Grafana_Search,'/grafana/api/search')
api.add_resource(Grafana_Query,'/grafana/api/query')
api.add_resource(Grafana_Tag_Key,'/grafana/api/tag-keys')
api.add_resource(Grafana_Tag_Value,'/grafana/api/tag-values')

# ========== 2020 08 13 Allen 更新 結束 ==========

api.add_resource(PunchCardUpload, '/punch/card/upload')
api.add_resource(PunchCard1Upload, '/punch/card1/upload')
api.add_resource(PunchCard2Upload, '/punch/card2/upload')
api.add_resource(PunchCardInsert, '/punch/card/upload/<string:ID>')
api.add_resource(PunchCardRecord, '/punch/card/record')
api.add_resource(PunchCardRecordAll, '/punch/card/record/all')
api.add_resource(PunchCardRecordDownload, '/punch/card/record/<int:year>/<int:month>')
api.add_resource(PunchCardRecordDownloadGroup, '/punch/card/record/group/<int:year>/<int:month>')
api.add_resource(PunchCardRecordDownload2, '/punch/card/dayrecord')
api.add_resource(PunchCardRecordDownload2Group, '/punch/card/dayrecord/group')
api.add_resource(PunchCardSend, '/punch/card/image/<string:ID>')                       # Record Image ID, ID_yyyy_MM_dd_HH_mm_ss.jpg
api.add_resource(PunchCardFirst, '/punch/card/now')
api.add_resource(PunchCardRecordToday, '/punch/card/today')
#  ========== 2020 09 08 Allen 更新 CM26EWH 接收資料方法  ==========
api.add_resource(CM26EWH_Personinfo, '/LAPI/V1.0/System/Event/Notification/PersonInfo')
#  ========== 2020 09 08 Allen 更新 CM26EWH 接收資料方法 結束  ==========
#  ========== 請假  ==========
api.add_resource(LeaveOffWorkInsert, '/person/leave/insert')
api.add_resource(LeaveOffWorkUpdate, '/person/leave/update')
api.add_resource(LeaveOffWorkDelete, '/person/leave/delete')
api.add_resource(LeaveOffWorkSelectAll, '/person/leave/all')
api.add_resource(LeaveToWord, '/leave/word')
api.add_resource(LeaveToExcel, '/leave/excel')
api.add_resource(LeaveToExcelPersonal, '/leave/excel/personal')
api.add_resource(LeaveToExcelAll, '/leave/excel/all')
api.add_resource(AnnualLeaveToExcel, '/annual/leave/excel/all')
# ========== 簽呈狀況 ==========
api.add_resource(LeaveSigningStatusInsert, '/leave/signing/status/insert')
api.add_resource(LeaveSigningStatusUpdate, '/leave/signing/status/update')
api.add_resource(LeaveSigningStatusDelete, '/leave/signing/status/delete')
api.add_resource(LeaveSigningStatusSelectAll, '/leave/signing/status/all')
# ========== 部門請假簽呈單位 ==========
api.add_resource(DepartLeaveUnitInsert, '/depart/leave/unit/insert')
api.add_resource(DepartLeaveUnitUpdate, '/depart/leave/unit/update')
api.add_resource(DepartLeaveUnitDelete, '/depart/leave/unit/delete')
api.add_resource(DepartLeaveUnitSelectAll, '/depart/leave/unit/all')
#  ========== 例假日 ==========
api.add_resource(HolidayInsert, '/holiday/insert')
api.add_resource(HolidayInsertWithExcel, '/holiday/insert/excel')
api.add_resource(HolidayUpdate, '/holiday/update')
api.add_resource(HolidayDelete, '/holiday/delete')
api.add_resource(HolidaySelectAll, '/holiday/all')
# ========== 部門 ==========
api.add_resource(DepartmentInsert, '/department/insert')
api.add_resource(DepartmentUpdate, '/department/update')
api.add_resource(DepartmentDelete, '/department/delete')
api.add_resource(DepartmentSelectAll, '/department/all')
# ========== 加班 ==========
api.add_resource(OvertimeInsert, '/overtime/insert')
api.add_resource(OvertimeUpdate, '/overtime/update')
api.add_resource(OvertimeDelete, '/overtime/delete')
api.add_resource(OverTimeSelectAll, '/overtime/all')
api.add_resource(OvertimeToWord, '/overtime/word')
# ========== 功能 ==========
api.add_resource(FeaturesInsert, '/features/insert')
api.add_resource(FeaturesUpdate, '/features/update')
api.add_resource(FeaturesDelete, '/features/delete')
api.add_resource(FeaturesSelectAll, '/features/all')
# ========== 功能角色關係 ==========
api.add_resource(FeaturesRoleRelationInsert, '/features/role/relation/insert')
api.add_resource(FeaturesRoleRelationUpdate, '/features/role/relation/update')
api.add_resource(FeaturesRoleRelationDelete, '/features/role/relation/delete')
api.add_resource(FeaturesRoleRelationSelectAll, '/features/role/relation/all')
# ========== 功能使用者關係 ==========
api.add_resource(FeaturesUserRelationInsert, '/features/user/relation/insert')
api.add_resource(FeaturesUserRelationUpdate, '/features/user/relation/update')
api.add_resource(FeaturesUserRelationDelete, '/features/user/relation/delete')
api.add_resource(FeaturesUserRelationSelectAll, '/features/user/relation/all')
#  ========== 匯出word ==========
api.add_resource(UserWordInsert, '/user/insertword')
#  ======= 測試 ========
api.add_resource(UserFeatureInsert, '/user/feature/insert')
api.add_resource(UserFeatureUpdate, '/user/feature/update')
api.add_resource(UserFeatureDelete, '/user/feature/delete')
api.add_resource(UserFeatureSelectAll, '/user/feature/all')
# ========== 新版本-中午休息 ==========
# ===== 出勤相關 =====
api.add_resource(PunchCardRecordVerson2, '/punch/card/record/verson2')
api.add_resource(PunchCardRecordDownloadVerson2, '/punch/card/record/verson2/<int:year>/<int:month>')
api.add_resource(PunchCardRecordDownloadGroupVerson2, '/punch/card/record/group/verson2/<int:year>/<int:month>')
api.add_resource(PunchCardRecordDownload2Verson2, '/punch/card/dayrecord/verson2')
api.add_resource(PunchCardRecordDownload2GroupVerson2, '/punch/card/dayrecord/group/verson2')
# ===== 請假相關 =====
api.add_resource(LeaveToExcelAllVerson2, '/leave/excel/all/verson2')
api.add_resource(LeaveToWordVerson2, '/leave/word/verson2')
api.add_resource(LeaveToExcelVerson2, '/leave/excel/verson2')
api.add_resource(LeaveToExcelPersonalVerson2, '/leave/excel/personal/verson2')
api.add_resource(AnnualLeaveToExcelVerson2, '/annual/leave/excel/all/verson2')
# ===== 加班相關 =====
api.add_resource(OvertimeToWordVerson2, '/overtime/word/verson2')
# ========== 新版本-班別 ==========
# ========== 班別 ==========
api.add_resource(ShiftInsert, '/shift/insert')
api.add_resource(ShiftUpdate, '/shift/update')
api.add_resource(ShiftDelete, '/shift/delete')
api.add_resource(ShiftSelectAll, '/shift/all')
# ========== 設備班別關係 ==========
api.add_resource(DeviceShiftRelationInsert, '/device/shift/relation/insert')
api.add_resource(DeviceShiftRelationUpdate, '/device/shift/relation/update')
api.add_resource(DeviceShiftRelationDelete, '/device/shift/relation/delete')
api.add_resource(DeviceShiftRelationSelectAll, '/device/shift/relation/all')
# ========== 匯出TXT ==========
api.add_resource(ExportShiftPunchCard, '/device/shift/export')
# ----- Socket -----
# socketio = SocketIO(app)
# socketio.on_namespace(Socket('/test'))
CORS(app)

# 排程任務物件
def aps_test(x):
    offset = timezone(timedelta(hours=8))
    dt_now=datetime.now(tz=offset)
    dt_from=dt_now.replace(hour=0, minute=0,second=0)
    dt_to=dt_now.replace(hour=23, minute=59,second=59)
    unrecord_table=Grafana_Query.get_group_unrecord_table(Grafana_Query(),dt_from,dt_to,"2")
    notify=PunchNotifyModel(token='nDry7rwKe7dx2DP0Y8jlNUp6H6BBtG5JNoekcycIN7r')
    if(len(unrecord_table[0]['rows'])==0):
        msg="全部正常出席"
    else:
        msg=""
    for row in unrecord_table[0]['rows']:
        msg+=row[1]+"\n"
    notify.BroadcastMsg(dt_now,"未出席名單",msg)
#  ========== 2020 09 08 Allen 修正 APScheduler 重新加載問題  ==========
#  ========== 使用 全局鎖 鎖定進程只執行一次 ==========  
f = open("scheduler.lock", "wb")
try:
    fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)    
    # 例項化APScheduler
    scheduler=APScheduler()
    # 任務清單
    #scheduler.add_job("job1",func=aps_test, args=('定時任務',), trigger='cron',day_of_week='mon-fri', hour='8', minute="41", second="0")
    #scheduler.add_job("CM26EWH_subscription_aps",func=CM26EWH_subscription_aps, args=('持續訂閱更新',), trigger='interval',seconds=55)
    # 把任務列表放進flask
    scheduler.init_app(app) 
    scheduler.start()
except:
    pass
def unlock():
    fcntl.flock(f, fcntl.LOCK_UN)
    f.close()
atexit.register(unlock)
#  ========== 2020 09 08 Allen 修正 APScheduler 重新加載問題  結束 ==========

# ========== api server start ==========
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000)
