Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 8ad9ee0

Browse files
authored
Update and rename attachment.py to attachment_downloader.py
1 parent f3467d8 commit 8ad9ee0

File tree

2 files changed

+139
-48
lines changed

2 files changed

+139
-48
lines changed

‎Attachment_Downloader/attachment.py‎

Lines changed: 0 additions & 48 deletions
This file was deleted.
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
"""
2+
Gmail Attachment Downloader
3+
A script to easily search and download Gmail attachments based on search queries.
4+
"""
5+
import os
6+
import ezgmail
7+
import datetime
8+
from typing import List, Optional
9+
10+
11+
def download_attachments(result_threads: List, download_dir: Optional[str] = None) -> None:
12+
"""
13+
Download all attachments from Gmail threads that match search criteria.
14+
15+
Args:
16+
result_threads: List of GmailThread objects from search results
17+
download_dir: Directory to save attachments (defaults to current directory)
18+
19+
Raises:
20+
Exception: If there's an error during download
21+
"""
22+
# Create download directory if it doesn't exist
23+
if download_dir and not os.path.exists(download_dir):
24+
os.makedirs(download_dir)
25+
print(f"Created directory: {download_dir}")
26+
27+
# Store original working directory
28+
original_dir = os.getcwd()
29+
30+
# Change to download directory if specified
31+
if download_dir:
32+
os.chdir(download_dir)
33+
34+
count_of_results = len(result_threads)
35+
downloaded_files = 0
36+
37+
try:
38+
print(f"Starting download of attachments from {count_of_results} thread(s)...")
39+
40+
for i, thread in enumerate(result_threads):
41+
thread_count = i + 1
42+
print(f"Processing thread {thread_count}/{count_of_results}: {thread.messages[0].subject}")
43+
44+
# Check if thread has multiple messages
45+
if len(thread.messages) > 1:
46+
for j, message in enumerate(thread.messages):
47+
msg_count = j + 1
48+
print(f" - Downloading attachments from message {msg_count}/{len(thread.messages)}")
49+
downloaded = message.downloadAllAttachments()
50+
downloaded_files += len(downloaded)
51+
if downloaded:
52+
print(f" Downloaded: {', '.join(downloaded)}")
53+
else:
54+
# Thread has only one message
55+
downloaded = thread.messages[0].downloadAllAttachments()
56+
downloaded_files += len(downloaded)
57+
if downloaded:
58+
print(f" - Downloaded: {', '.join(downloaded)}")
59+
60+
print(f"\nDownload complete! {downloaded_files} file(s) downloaded.")
61+
if download_dir:
62+
print(f"Files saved to: {os.path.abspath(download_dir)}")
63+
else:
64+
print(f"Files saved to: {os.getcwd()}")
65+
66+
except Exception as e:
67+
print(f"Error occurred while downloading attachment(s): {str(e)}")
68+
raise
69+
finally:
70+
# Return to original directory if we changed it
71+
if download_dir:
72+
os.chdir(original_dir)
73+
74+
75+
def main():
76+
"""Main function to run when script is executed directly."""
77+
print("=" * 50)
78+
print("Gmail Attachment Downloader")
79+
print("=" * 50)
80+
81+
# Check if ezgmail is authenticated
82+
try:
83+
ezgmail.init()
84+
print(f"Logged in as: {ezgmail.EMAIL_ADDRESS}\n")
85+
except Exception as e:
86+
print("Authentication error. Please follow setup instructions in README.md")
87+
print(f"Error details: {str(e)}")
88+
return
89+
90+
# Get search query from user
91+
query = input("Enter search query (e.g., 'from:example@gmail.com'): ").strip()
92+
if not query:
93+
print("Search query cannot be empty. Exiting...")
94+
return
95+
96+
# Always include attachment filter in the search
97+
search_query = f"{query} has:attachment"
98+
99+
print(f"\nSearching for: {search_query}")
100+
print("This may take a moment depending on your inbox size...")
101+
102+
try:
103+
# Perform the search
104+
result_threads = ezgmail.search(search_query)
105+
106+
if not result_threads:
107+
print("\nNo results found with attachments matching your query.")
108+
return
109+
110+
# Display results
111+
print(f"\nFound {len(result_threads)} result(s) with attachments:")
112+
for i, thread in enumerate(result_threads):
113+
subject = thread.messages[0].subject
114+
date = datetime.datetime.fromtimestamp(thread.messages[0].timestamp)
115+
formatted_date = date.strftime("%Y-%m-%d %H:%M")
116+
print(f"{i+1}. [{formatted_date}] {subject}")
117+
118+
# Ask user if they want to download
119+
while True:
120+
download_confirmation = input("\nDo you want to download the attachment(s)? (y/n): ").strip().lower()
121+
if download_confirmation in ['y', 'yes']:
122+
# Ask for download directory
123+
custom_dir = input("Enter download directory (leave empty for current directory): ").strip()
124+
download_attachments(result_threads, custom_dir if custom_dir else None)
125+
break
126+
elif download_confirmation in ['n', 'no']:
127+
print("Download canceled. Exiting...")
128+
break
129+
else:
130+
print("Please enter 'y' or 'n'.")
131+
132+
except KeyboardInterrupt:
133+
print("\nOperation canceled by user.")
134+
except Exception as e:
135+
print(f"\nAn error occurred: {str(e)}")
136+
137+
138+
if __name__ == '__main__':
139+
main()

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /