File size: 4,824 Bytes
61cb8cf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import os
import shutil
import sys
import logging
from datetime import datetime

# Set up logging
logging.basicConfig(
    filename=f"conversion_log_{datetime.now().strftime('%Y%m%d_%H%M%S')}.log",
    level=logging.INFO,
    format="%(asctime)s - %(levelname)s - %(message)s"
)

# For DOC/DOCX conversion
try:
    from docx2pdf import convert as docx_convert
except ImportError:
    logging.error("docx2pdf not installed. Run 'pip install docx2pdf'.")
    sys.exit(1)

# For Word-based conversion
try:
    import win32com.client
except ImportError:
    logging.error("pywin32 not installed. Run 'pip install pywin32'.")
    sys.exit(1)

try:
    import comtypes.client
except ImportError:
    logging.warning("comtypes not installed. Run 'pip install comtypes' for fallback.")

def check_irm_status(filepath):
    """Check if IRM is enabled on a DOC/DOCX file."""
    try:
        word_app = win32com.client.Dispatch("Word.Application")
        doc = word_app.Documents.Open(os.path.abspath(filepath), ReadOnly=True, Visible=False)
        irm_enabled = doc.Permission.Enabled
        doc.Close()
        word_app.Quit()
        return irm_enabled
    except Exception as e:
        logging.error(f"Failed to check IRM for {filepath}: {e}")
        return None

def convert_docx_docx2pdf(filepath, output_pdf):
    """Attempt DOC/DOCX to PDF conversion using docx2pdf."""
    try:
        docx_convert(filepath, output_pdf)
        logging.info(f"Converted {filepath} to {output_pdf} using docx2pdf.")
        return True
    except Exception as e:
        logging.error(f"docx2pdf failed for {filepath}: {e}")
        return False

def convert_docx_win32(filepath, output_pdf):
    """Attempt DOC/DOCX to PDF conversion using win32com SaveAs."""
    try:
        word_app = win32com.client.Dispatch("Word.Application")
        doc = word_app.Documents.Open(os.path.abspath(filepath), ReadOnly=True, Visible=False)
        doc.SaveAs(output_pdf, FileFormat=17)  # 17 = wdFormatPDF
        doc.Close()
        word_app.Quit()
        logging.info(f"Converted {filepath} to {output_pdf} using win32com SaveAs.")
        return True
    except Exception as e:
        logging.error(f"win32com SaveAs failed for {filepath}: {e}")
        return False

def convert_docx_comtypes(filepath, output_pdf):
    """Attempt DOC/DOCX to PDF conversion using comtypes SaveAs."""
    try:
        word_app = comtypes.client.CreateObject("Word.Application")
        doc = word_app.Documents.Open(os.path.abspath(filepath), ReadOnly=True, Visible=False)
        doc.SaveAs(output_pdf, FileFormat=17)  # 17 = wdFormatPDF
        doc.Close()
        word_app.Quit()
        logging.info(f"Converted {filepath} to {output_pdf} using comtypes SaveAs.")
        return True
    except Exception as e:
        logging.error(f"comtypes SaveAs failed for {filepath}: {e}")
        return False

def main(input_dir, output_dir):
    if not os.path.isdir(input_dir):
        logging.error(f"{input_dir} is not a directory.")
        sys.exit(1)

    os.makedirs(output_dir, exist_ok=True)

    for root, _, files in os.walk(input_dir):
        rel_dir = os.path.relpath(root, input_dir)
        target_subdir = os.path.join(output_dir, rel_dir)
        os.makedirs(target_subdir, exist_ok=True)

        for file in files:
            filepath = os.path.join(root, file)
            base, ext = os.path.splitext(file)
            output_pdf = os.path.join(target_subdir, base + '.pdf')

            try:
                if ext.lower() in ['.doc', '.docx']:
                    # Check IRM status
                    irm_status = check_irm_status(filepath)
                    if irm_status is not None:
                        logging.info(f"IRM enabled for {filepath}: {irm_status}")

                    # Try docx2pdf first (simpler, faster)
                    if not convert_docx_docx2pdf(filepath, output_pdf):
                        # Fallback to win32com
                        if not convert_docx_win32(filepath, output_pdf):
                            # Fallback to comtypes if available
                            if 'comtypes' in sys.modules and not convert_docx_comtypes(filepath, output_pdf):
                                logging.warning(f"Failed to convert {filepath}. Likely IRM or strict restrictions.")
                            elif not 'comtypes' in sys.modules:
                                logging.warning(f"Failed to convert {filepath}. Install comtypes for additional fallback.")
                elif ext.lower() == '.pdf':
                    shutil.copy(filepath, output_pdf)
                    logging.info(f"Copied {filepath} to {output_pdf}")
            except Exception as e:
                logging.error(f"Error processing {filepath}: {e}")

if __name__ == "__main__":
    main("ToAdd", "ConvertedFiles")