<reponame>recs12/b2btool
"""
Only works in mode TC.
"""

import datetime
import getpass
import os
import pathlib
import subprocess
import time

import click
import pandas as pd
from loguru import logger
import psutil

# from batch_rendering.ranges import *

user_name = getpass.getuser()


class Range:
    """All the range are inclusive"""

    def __init__(self, num):
        self.rows = list(range(num))

    def between_rows(self, start, end):
        "return a list from one row to another row specified."
        return self.rows[start-2:end-1]

    def from_row(self, row):
        "return a list from row specified."
        return self.rows[row-2:]

    def to_row(self, row):
        "return a list to row specified."
        return self.rows[:row-1]

    def unique_row(self, row):
        "return a list of single element."
        return self.rows[row-2:row-1]


def se_opened_instance():
    """Check the number of instance of solidedge."""
    return [p.name() for p in psutil.process_iter()].count("Edge.exe")

def render_one_item(items, user, password, folder_target, group, role, server, mode):
    print(f"[INFO] TC - Part Number: {items[1]}")
    item_id, revision = items[0], items[1]
    print(f"item {item_id} / {revision}")
    p1 = subprocess.run(
        f"SEToolRender {mode} -i {item_id} -v {revision} -u {user} -p {password} -g {group} -r {role} -s {server} -o {folder_target}",
        shell=True,
        check=False,
        capture_output=False,
        text=True,  # display the main macro output
        stderr=subprocess.DEVNULL,  # ignore the errors
    )

    # Logging of the error message.
    if p1.returncode != 0:
        logger.error(f"[ERROR] : {p1.stdout}")

    # check the presence of the files (json, bmp)
    bmp = os.path.join(folder_target, f"{item_id}-Rev-{revision}.bmp")
    json = os.path.join(folder_target, f"{item_id}-Rev-{revision}.json")
    file_bmp = pathlib.Path(bmp)
    file_json = pathlib.Path(json)

    if file_bmp.exists():
        logger.info(f"[OK   ] : {item_id} .bmp downloaded")
    else:
        logger.error(f"[FAIL ] : {item_id} .bmp not downloaded")

    if file_json.exists():
        logger.info(f"[OK   ] : {item_id} .json downloaded")
    else:
        logger.error(f"[FAIL ] : {item_id} .json not downloaded")

    #log error id-rev
    if not file_json.exists() or not file_bmp.exists():
        # allow copy-past of the problematic parts in the log file.
        logger.error(f"id;rev>>>{item_id};{revision}")

    # If server disconnection code 666 then tempo of 15 min.
    if p1.returncode == 666:
        time.sleep(60 * 15)


def batch_rendering(
    excel, user, password, folder_target, group, role, server, mode, debug_mode, single=False, to_row=False, from_row=False, between_rows=False
):
    """Run SEToolRendering in batch with an excel file."""

    # Ch
    if se_opened_instance() == 0:
        print("No SolidEdge session open.")
        return
    elif se_opened_instance() > 1:
        print("Only one SolidEdge session can be open to run the macro.")
        return


    # Location of the log file.
    path_log = os.path.join(folder_target, "rendering_error.log")
    logger.add(
        path_log,
        format="{time:YYYY-MM-DD at HH:mm:ss} | {level} | {message}",
        level=debug_mode,
    )
    print(f"Logging mode: {debug_mode}")
    df = pd.read_excel(
        excel,
        index_col=None,
        dtype={
            "ID": str,
            "Revision": str,
        },  # names of columns in excel must be excatly the same.
    )
    # Define the shape of the excel file.
    number_rows, number_columns = df.shape
    r = Range(number_rows)

    # Check the rows selected.
    if single:
        rows = r.unique_row(single)
    elif to_row:
        rows = r.to_row(to_row)
    elif from_row:
        rows = r.from_row(from_row)
    elif between_rows:
        rows = r.between_rows(between_rows[0], between_rows[1])
    else:
        rows = range(number_rows)

    try:
        tic = time.perf_counter()
        # For each row run a command line.
        for row in rows:
            items: list = [df.iat[row, column] for column in range(number_columns)]
            render_one_item(
                items, user, password, folder_target, group, role, server, mode
            )
            logger.info(f"[ITERATION] {row+1}/{number_rows}")

    except subprocess.CalledProcessError:
        logger.exception({row + 1})

    finally:
        toc = time.perf_counter()
        seconds = toc - tic
        logger.info(f"Time to completion: {datetime.timedelta(seconds=seconds)}")

"""
Only works in mode TC.
"""

import datetime
import getpass
import os
import pathlib
import subprocess
import time

import click
import pandas as pd
from loguru import logger
import psutil

# from batch_rendering.ranges import *

user_name = getpass.getuser()


class Range:
    """All the range are inclusive"""

    def __init__(self, num):
        self.rows = list(range(num))

    def between_rows(self, start, end):
        "return a list from one row to another row specified."
        return self.rows[start-2:end-1]

    def from_row(self, row):
        "return a list from row specified."
        return self.rows[row-2:]

    def to_row(self, row):
        "return a list to row specified."
        return self.rows[:row-1]

    def unique_row(self, row):
        "return a list of single element."
        return self.rows[row-2:row-1]


def se_opened_instance():
    """Check the number of instance of solidedge."""
    return [p.name() for p in psutil.process_iter()].count("Edge.exe")

def render_one_item(items, user, password, folder_target, group, role, server, mode):
    print(f"[INFO] TC - Part Number: {items[1]}")
    item_id, revision = items[0], items[1]
    print(f"item {item_id} / {revision}")
    p1 = subprocess.run(
        f"SEToolRender {mode} -i {item_id} -v {revision} -u {user} -p {password} -g {group} -r {role} -s {server} -o {folder_target}",
        shell=True,
        check=False,
        capture_output=False,
        text=True,  # display the main macro output
        stderr=subprocess.DEVNULL,  # ignore the errors
    )

    # Logging of the error message.
    if p1.returncode != 0:
        logger.error(f"[ERROR] : {p1.stdout}")

    # check the presence of the files (json, bmp)
    bmp = os.path.join(folder_target, f"{item_id}-Rev-{revision}.bmp")
    json = os.path.join(folder_target, f"{item_id}-Rev-{revision}.json")
    file_bmp = pathlib.Path(bmp)
    file_json = pathlib.Path(json)

    if file_bmp.exists():
        logger.info(f"[OK   ] : {item_id} .bmp downloaded")
    else:
        logger.error(f"[FAIL ] : {item_id} .bmp not downloaded")

    if file_json.exists():
        logger.info(f"[OK   ] : {item_id} .json downloaded")
    else:
        logger.error(f"[FAIL ] : {item_id} .json not downloaded")

    #log error id-rev
    if not file_json.exists() or not file_bmp.exists():
        # allow copy-past of the problematic parts in the log file.
        logger.error(f"id;rev>>>{item_id};{revision}")

    # If server disconnection code 666 then tempo of 15 min.
    if p1.returncode == 666:
        time.sleep(60 * 15)


def batch_rendering(
    excel, user, password, folder_target, group, role, server, mode, debug_mode, single=False, to_row=False, from_row=False, between_rows=False
):
    """Run SEToolRendering in batch with an excel file."""

    # Ch
    if se_opened_instance() == 0:
        print("No SolidEdge session open.")
        return
    elif se_opened_instance() > 1:
        print("Only one SolidEdge session can be open to run the macro.")
        return


    # Location of the log file.
    path_log = os.path.join(folder_target, "rendering_error.log")
    logger.add(
        path_log,
        format="{time:YYYY-MM-DD at HH:mm:ss} | {level} | {message}",
        level=debug_mode,
    )
    print(f"Logging mode: {debug_mode}")
    df = pd.read_excel(
        excel,
        index_col=None,
        dtype={
            "ID": str,
            "Revision": str,
        },  # names of columns in excel must be excatly the same.
    )
    # Define the shape of the excel file.
    number_rows, number_columns = df.shape
    r = Range(number_rows)

    # Check the rows selected.
    if single:
        rows = r.unique_row(single)
    elif to_row:
        rows = r.to_row(to_row)
    elif from_row:
        rows = r.from_row(from_row)
    elif between_rows:
        rows = r.between_rows(between_rows[0], between_rows[1])
    else:
        rows = range(number_rows)

    try:
        tic = time.perf_counter()
        # For each row run a command line.
        for row in rows:
            items: list = [df.iat[row, column] for column in range(number_columns)]
            render_one_item(
                items, user, password, folder_target, group, role, server, mode
            )
            logger.info(f"[ITERATION] {row+1}/{number_rows}")

    except subprocess.CalledProcessError:
        logger.exception({row + 1})

    finally:
        toc = time.perf_counter()
        seconds = toc - tic
        logger.info(f"Time to completion: {datetime.timedelta(seconds=seconds)}")
Only works in mode TC. # from batch_rendering.ranges import * All the range are inclusive Check the number of instance of solidedge. # display the main macro output # ignore the errors # Logging of the error message. # check the presence of the files (json, bmp) #log error id-rev # allow copy-past of the problematic parts in the log file. # If server disconnection code 666 then tempo of 15 min. Run SEToolRendering in batch with an excel file. # Ch # Location of the log file. # names of columns in excel must be excatly the same. # Define the shape of the excel file. # Check the rows selected. # For each row run a command line.