tw22
This commit is contained in:
92
PST/10 ReadKulhavaPST.py
Normal file
92
PST/10 ReadKulhavaPST.py
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import win32com.client
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Your specific file path
|
||||||
|
pst_path = r'd:\Dropbox\!!!Days\Downloads Z230\PST\tkulhava.pst'
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if not os.path.exists(pst_path):
|
||||||
|
print(f"Error: File not found at {pst_path}")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Connect to Outlook
|
||||||
|
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
|
||||||
|
|
||||||
|
# 1. Add the PST to Outlook (This makes it visible in the sidebar)
|
||||||
|
print(f"Mounting PST: {pst_path}...")
|
||||||
|
outlook.AddStore(pst_path)
|
||||||
|
|
||||||
|
# 2. Find the folder object for this PST
|
||||||
|
# We search specifically for the folder that matches the filename 'tkulhava'
|
||||||
|
# or grab the last added store if the name doesn't match exactly.
|
||||||
|
pst_name = "tkulhava" # derived from filename usually
|
||||||
|
root_folder = None
|
||||||
|
|
||||||
|
# Loop through all stores to find the new one
|
||||||
|
for folder in outlook.Folders:
|
||||||
|
if pst_name.lower() in folder.Name.lower():
|
||||||
|
root_folder = folder
|
||||||
|
break
|
||||||
|
|
||||||
|
# Fallback: Just grab the last folder in the list if name didn't match
|
||||||
|
if not root_folder:
|
||||||
|
root_folder = outlook.Folders.GetLast()
|
||||||
|
|
||||||
|
print(f"Successfully opened root folder: {root_folder.Name}")
|
||||||
|
print("=" * 50)
|
||||||
|
|
||||||
|
# 3. Start the recursive walk
|
||||||
|
print_subjects_recursively(root_folder)
|
||||||
|
|
||||||
|
# 4. Cleanup: Remove the PST from Outlook
|
||||||
|
# (Comment this out if you want to keep it open in Outlook to inspect manually)
|
||||||
|
outlook.RemoveStore(root_folder)
|
||||||
|
print("\nDone. PST detached.")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"An error occurred: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
def print_subjects_recursively(folder):
|
||||||
|
"""
|
||||||
|
Recursively prints subjects of emails in a folder and its subfolders.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Print current folder name for context
|
||||||
|
# Check if folder has items
|
||||||
|
if folder.Items.Count > 0:
|
||||||
|
print(f"\n--- Folder: {folder.Name} ---")
|
||||||
|
|
||||||
|
# Iterate through items
|
||||||
|
for item in folder.Items:
|
||||||
|
try:
|
||||||
|
# Class 43 is a standard MailItem.
|
||||||
|
# Other items (meeting requests, reports) might not have a Subject or behave differently.
|
||||||
|
if item.Class == 43:
|
||||||
|
print(f"Subject: {item.Subject}")
|
||||||
|
else:
|
||||||
|
# Attempt to print subject anyway (e.g., for Meeting Items)
|
||||||
|
print(f"[{type_name(item.Class)}] Subject: {item.Subject}")
|
||||||
|
except Exception:
|
||||||
|
# Skip items that are corrupted or unreadable
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Recursion: Go deeper into subfolders
|
||||||
|
for subfolder in folder.Folders:
|
||||||
|
print_subjects_recursively(subfolder)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Skipping restricted folder '{folder.Name}': {e}")
|
||||||
|
|
||||||
|
|
||||||
|
def type_name(class_id):
|
||||||
|
# Helper to identify non-email items
|
||||||
|
if class_id == 53: return "Meeting"
|
||||||
|
if class_id == 46: return "Report"
|
||||||
|
return f"Type {class_id}"
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
142
PST/20 ReadKulhavaSavePhotos.py
Normal file
142
PST/20 ReadKulhavaSavePhotos.py
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
import win32com.client
|
||||||
|
import os
|
||||||
|
import pathlib
|
||||||
|
|
||||||
|
# --- CONFIGURATION ---
|
||||||
|
pst_path = r'd:\Dropbox\!!!Days\Downloads Z230\PST\tkulhava.pst'
|
||||||
|
output_dir = r'd:\Dropbox\!!!Days\Downloads Z230\PST\pictures'
|
||||||
|
|
||||||
|
# Image extensions to look for (case insensitive)
|
||||||
|
IMAGE_EXTENSIONS = {'.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tif', '.tiff'}
|
||||||
|
|
||||||
|
|
||||||
|
def fix_encoding(text):
|
||||||
|
"""Repairs text wrongly decoded as cp1252 instead of cp1250."""
|
||||||
|
if not text: return ""
|
||||||
|
try:
|
||||||
|
return text.encode('cp1252').decode('cp1250')
|
||||||
|
except Exception:
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
def get_unique_filepath(directory, filename):
|
||||||
|
"""
|
||||||
|
Checks if a file exists. If so, adds a counter (_1, _2) to the filename
|
||||||
|
until a unique name is found.
|
||||||
|
"""
|
||||||
|
# Clean filename of illegal characters just in case
|
||||||
|
filename = "".join(x for x in filename if x.isalnum() or x in "._- ")
|
||||||
|
|
||||||
|
path = pathlib.Path(directory) / filename
|
||||||
|
if not path.exists():
|
||||||
|
return path
|
||||||
|
|
||||||
|
# Split name and extension
|
||||||
|
stem = path.stem
|
||||||
|
suffix = path.suffix
|
||||||
|
counter = 1
|
||||||
|
|
||||||
|
while True:
|
||||||
|
new_filename = f"{stem}_{counter}{suffix}"
|
||||||
|
new_path = pathlib.Path(directory) / new_filename
|
||||||
|
if not new_path.exists():
|
||||||
|
return new_path
|
||||||
|
counter += 1
|
||||||
|
|
||||||
|
|
||||||
|
def process_item_attachments(item, save_folder):
|
||||||
|
"""Checks an item for attachments and saves pictures."""
|
||||||
|
try:
|
||||||
|
# Check if item has attachments
|
||||||
|
if item.Attachments.Count > 0:
|
||||||
|
for attachment in item.Attachments:
|
||||||
|
try:
|
||||||
|
# Get filename and extension
|
||||||
|
fname = getattr(attachment, 'FileName', '')
|
||||||
|
if not fname: continue
|
||||||
|
|
||||||
|
# Fix encoding on filename if needed (sometimes attachments inherit bad encoding)
|
||||||
|
fname = fix_encoding(fname)
|
||||||
|
|
||||||
|
ext = os.path.splitext(fname)[1].lower()
|
||||||
|
|
||||||
|
if ext in IMAGE_EXTENSIONS:
|
||||||
|
# Determine unique path
|
||||||
|
save_path = get_unique_filepath(save_folder, fname)
|
||||||
|
|
||||||
|
# Save the file
|
||||||
|
attachment.SaveAsFile(str(save_path))
|
||||||
|
print(f" [SAVED] {save_path.name}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f" [ERROR saving attachment]: {e}")
|
||||||
|
except Exception:
|
||||||
|
# Some items (like corrupted notes) fail when accessing .Attachments
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def scan_folder_recursively(folder, save_folder):
|
||||||
|
"""Recursively walks folders and processes items."""
|
||||||
|
try:
|
||||||
|
folder_name = fix_encoding(folder.Name)
|
||||||
|
|
||||||
|
# Optional: Print folder progress
|
||||||
|
if folder.Items.Count > 0:
|
||||||
|
print(f"Scanning Folder: {folder_name}...")
|
||||||
|
|
||||||
|
# Process items in this folder
|
||||||
|
for item in folder.Items:
|
||||||
|
process_item_attachments(item, save_folder)
|
||||||
|
|
||||||
|
# Recursion
|
||||||
|
for subfolder in folder.Folders:
|
||||||
|
scan_folder_recursively(subfolder, save_folder)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Skipping folder '{fix_encoding(folder.Name)}': {e}")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# 1. Ensure output directory exists
|
||||||
|
if not os.path.exists(output_dir):
|
||||||
|
os.makedirs(output_dir)
|
||||||
|
print(f"Created directory: {output_dir}")
|
||||||
|
|
||||||
|
if not os.path.exists(pst_path):
|
||||||
|
print(f"Error: PST file not found at {pst_path}")
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 2. Connect to Outlook
|
||||||
|
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
|
||||||
|
|
||||||
|
print(f"Mounting PST: {pst_path}...")
|
||||||
|
outlook.AddStore(pst_path)
|
||||||
|
|
||||||
|
# 3. Find the PST folder
|
||||||
|
pst_name = "tkulhava" # Usually derived from filename
|
||||||
|
root_folder = None
|
||||||
|
for folder in outlook.Folders:
|
||||||
|
if pst_name.lower() in folder.Name.lower():
|
||||||
|
root_folder = folder
|
||||||
|
break
|
||||||
|
|
||||||
|
if not root_folder:
|
||||||
|
root_folder = outlook.Folders.GetLast()
|
||||||
|
|
||||||
|
print(f"Opened: {fix_encoding(root_folder.Name)}")
|
||||||
|
print(f"Saving pictures to: {output_dir}")
|
||||||
|
print("=" * 50)
|
||||||
|
|
||||||
|
# 4. Start processing
|
||||||
|
scan_folder_recursively(root_folder, output_dir)
|
||||||
|
|
||||||
|
# 5. Cleanup
|
||||||
|
outlook.RemoveStore(root_folder)
|
||||||
|
print("\nDone. PST detached.")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Critical Error: {e}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user