#coding:utf-8

#------------------------------
#instructions:放在移动硬盘 用于拷贝工程下的图片文件(AI存图工具)
#python version: 3.4.x
#designers: cls
#last modify: 20210430
#LOG:   current version 1.4.1
#version: 1.2   改用rsync
#version: 1.3   自己查询工程及保存文件目录
#version: 1.4   按硬盘分文件夹,判断移动硬盘挂载路径
#------------------------------

import os
import datetime
import subprocess
import json
import re
import fcntl
import select
from threading import Timer

begintime = datetime.datetime.now()

#-----------------------------------------function------------------------------------------
# 执行函数 默认20秒超时
def make_nonblock(fd):
    flags = fcntl.fcntl(fd, fcntl.F_GETFL)
    fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)

# 执行linux shell命令 有select监管
class Command_run:
    TIMEOUT_MSG = ""

    def __init__(self, cmd):
        PIPE = subprocess.PIPE
        self.proc = subprocess.Popen(
            cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        make_nonblock(self.proc.stdout)
        make_nonblock(self.proc.stderr)

    def command_run(self, timeout=3):
        timer = None
        ret = {}
        out_ret = ""
        err_ret = ""
        if timeout:
            timer = Timer(timeout, self._kill_proc, [self.proc, ])
            timer.setDaemon(True)
            timer.start()
        while True:
            out_ret += self._read(self.proc.stdout)
            err_ret += self._read(self.proc.stderr)
            if self.proc.poll() is not None:  # 不在运行状态
                break
        out_ret += self._read(self.proc.stdout)
        err_ret += self._read(self.proc.stderr)
        ret["OUT"] = out_ret
        ret["ERR"] = self.TIMEOUT_MSG + err_ret
        ret["STATUS"] = self.proc.returncode
        if timer:
            timer.cancel()
            timer.join()
        self.proc.stdout.close()
        return ret

    def _read(self, fd):
        out = ""
        if fd is None or fd.closed:
            return out
        rd, _, _ = select.select([fd], [], [], 0)
        if rd:
            out = fd.readline()
            out = out.decode(encoding='utf-8')
        return out

    def _kill_proc(self, proc):
        if proc:
            try:
                proc.kill()
                self.TIMEOUT_MSG = "timeout:"
            except OSError:
                pass
            finally:
                proc.stdout.close()

# 读取文本 back (False, '')
def ReadFile(filename):
    str_content = ""
    result = False
    try:
        # 读保存路径--------------------------------------------------------------------
        with open(filename, "r") as f:
            str_content = f.read()
            f.close()
            result = True
    except FileNotFoundError as value:
        print("没有找到文件 %s" % value)
    except KeyError:
        print("json解析错误没有找到key")
    except Exception as value:
        print("Exception:%s" % value)
    finally:
        return result, str_content

#-----------------------------------------find storage disk------------------------------------------
bcmd_blkid = Command_run("blkid").command_run()
if bcmd_blkid["STATUS"] != 0:
    print("EXIT(0): blkid STATUS ERR")
    exit(0)
bcmd_blkid = bcmd_blkid["OUT"]
isearch = re.findall(".*UUID=\"(([a-z]|[0-9]|[A-Z])+)-.*\"\sTYPE=\"ext4\"", bcmd_blkid, re.M)
if not isearch:
    print("EXIT(0): NO FOUND EXT4 DISK")
    exit(0)

#/dev/sda ext4 文件夹名称
ext4name = "autocopy_" + isearch[0][0]  #存图使用的目录名称

readback = ReadFile("/proc/mounts")
if not readback[0]:
    print("EXIT(0): NO FOUND FILE \"/proc/mounts\"")
    exit(0)
readback_str = readback[1]
isearch = re.findall("(/dev/sd\w\d+)\s(\S+)\s(\S+)\s.*", readback_str, re.M)
if not isearch:
    print("EXIT(0): NO FOUND FILE \"/dev/sd*\"")
    exit(0)
mountdir = ""   #挂载的移动硬盘文件夹
for item in isearch:
    if "ext" in item[2]:
        continue
    dev = item[0]
    if os.path.exists(dev):
        mountdir = item[1]

if not mountdir:
    print("EXIT(0): NO FOUND MOVE DISK MOUNT")
    exit(0)

finalworkspace = mountdir + "/" + ext4name
os.system("mkdir -p " + finalworkspace)

#-----------------------------------------catch pid------------------------------------------
# bcmd_ps = Command_run("ps -aux | grep autocopy.py").command_run()
# if bcmd_ps["STATUS"] != 0:
#     exit(0)
# str_cmd = bcmd_ps["OUT"]
#
# count = 0
#
# listprocess = str_cmd.split("\n")
# for item in listprocess:
#     if "python" in item and "autocopy.py" in item:
#         count += 1
#
# if count >= 2:
#     exit(0)

curtime = datetime.datetime.now()
strtime = curtime.strftime("%Y%m%d_%H")

cameracount = 0     #工程下相机文件夹的个数
productname = ""    #当前工程目录

#-----------------------------------------find import params------------------------------------------
readback_Config = ReadFile("/root/bin-AOI/Config.json")
if not readback_Config[0]:
    print("EXIT(0): NO FOUND FILE \"/root/bin-AOI/Config.json\"")
    exit(0)
str_content = readback_Config[1]
jsonmap = json.loads(str_content)  # 加载成json
TaskPath = jsonmap["TasksPath"]
CurTaskName = jsonmap["CurTaskName"]
productpath = TaskPath + CurTaskName

if not productpath:
    print("EXIT(0): NO FOUND CURRENT OBJECT NAME")
    exit(0)

for root,dirs,files in os.walk(productpath):
    for item in dirs:
        isearch = re.findall("^Camera\d+", item, re.M)
        if isearch:
            cameracount += 1
    break
    # if len(dirs) > 0:
    #     dirs

#-----------------------------------------action------------------------------------------
listcmd = []
for i in range(cameracount):
    tardir = finalworkspace + "/" + "autocopy_" + strtime + "/Camera%d" % i
    cmdmd = "mkdir -p " + tardir
    listcmd.append(cmdmd)
    cmdok = "rsync -auzt %s/Camera%d/OKOriginal " % (productpath, i) + tardir
    listcmd.append(cmdok)
    cmdng = "rsync -auzt %s/Camera%d/NGOriginal " % (productpath, i) + tardir
    listcmd.append(cmdng)
listcmd.append("sync")

for itemaction in listcmd:
    Command_run(itemaction).command_run(30)

endtime = datetime.datetime.now()

print ("copy finish runtime: %s" % (endtime - begintime))








