I am using python 2.7 on ubuntu 16.04.
I have been using python to read emails out of mbox files on my pc which were created by thunderbird. I now want to add messages into those mbox files. I shut down thunderbird and then I try to run my python script from the command line. The python script does not give me any error messages at all, but I do not see any new messages being added into the mbox file when I open up thunderbird.
I did look to see if I have a permissions problem. I changed the permissions of the mbox file in linux to: view content=anyone, change content=anyone, execute=anyone.
I run my python script in sudo mode.
Here is my code which I have tried:
mboxfile = "/home/jan/.thunderbird/gkzlvipz.default/ImapMail/mail.jan.info/INBOX"
print("opening: "+mboxfile)
mbox = mailbox.mbox(mboxfile)
mbox.lock()
try:
print("Trying:Begins")
msg = mailbox.mboxMessage()
msg.set_unixfrom('author Sat Feb 7 01:05:34 2020')
msg['From'] = 'info#jan.info'
msg['To'] = 'ljan#gmail.com'
msg['Subject'] = 'JL Python Sample message 1'
msg.set_payload('This is the body.\nFrom (should be escaped).\nThere are 3 lines.\n')
mbox.add(msg)
mbox.flush()
print("Trying:Ends")
except Exception as e:
# Just print(e) is cleaner and more likely what you want,
# but if you insist on printing message specifically whenever possible...
Print("Exception - FAILED")
if hasattr(e, 'message'):
print("Error 1: " + e.message)
else:
print("Error 2: " + e)
finally:
print("Finally")
mbox.unlock()
sys.exit("PYTHON ENDS: TEST EMAIL SEND FINISHED")
The output I get when I run the above script is:
*** PYTESTTHUNDERBIRD BEGINS ***
opening: /home/jan/.thunderbird/gkzlvipz.default/ImapMail/mail.jan.info/INBOX
Trying:Begins
Trying:Ends
Finally
PYTHON ENDS: TEST EMAIL SEND FINISHED
I don't know what I'm doing wrong and why I am not getting any error messages.
I'll be most grateful for any help.
Thanks.
The messages you added to the mbox file aren't showing up in Thunderbird because you didn't update the index (.msf) file for that folder.
In Thunderbird, right-click on the folder name and select "Properties". In the "General Information" tab, read the blurb next to the "[Repair Folder]" button. Then click the folder. This will cause Thunderbird to rebuild the index from scratch — including the messages you've added. (Assuming of course you didn't mess them up in the process.)
Related
I am using Pywin32 and win32com to programmatically create and save Outlook MSG files. (These are emails that will only ever be saved and never be sent across smtp.) I am able to create and save the emails, but it only works when the display() method is used. This is problematic because it creates and opens the actual Outlook email in the GUI.
When I comment out the display() method, the email message save method just runs forever and yields zero in the debug console and the email is neither created or saved.
The appearance of the Outlook emails in the GUI is not desirable as I will later programmatically create thousands of messages and cannot have them all opening in the GUI. (and having to close them!)
edit: I've done some research here display method and here .net mail class but have not found a way to suppress the GUI display of the email.
How can I create the emails to disk as msg files without them appearing in the Windows GUI as Outlook emails? Code as follows. Thank you.
import sys
import win32com.client as client
MSG_FOLDER_PATH = "d:\\Emails_Msg\\"
html_body = """
<div>
Test email 123
</div><br>
"""
recipient = "johndoe#foo.com"
cc = "janedoe#foo.com"
outlook = client.Dispatch("outlook.application")
message = outlook.CreateItem(0)
message.To = recipient
message.CC = cc
message.Subject = "foo1"
message.HTMLBody = html_body
# message display method
message.Display()
# save the message, only works if message.Display() runs
message_name = MSG_FOLDER_PATH + "foo.msg"
message.SaveAs(message_name)
The problem was that Outlook was not opened in the Windows Server. (The simple things at times!) Once it is opened, the display method is no longer needed and emails are written directly to disk.
I'm trying to get date related info from messages that Python retrieves from Outlook but for some weird reason I cannot.
It is strange because I can obtain all info about sender, email body, subject, cc, bc, attachment etc. but when it comes to properties like SentOn, CreationTime or LastModificationTime IDLE just restarts (without any warnings, errors and exceptions).
Here is sample code:
import win32com.client
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
inbox = outlook.GetDefaultFolder(6) # "6" refers to the index of a folder - in this case,
# the inbox. You can change that number to reference
# any other folder
messages = inbox.Items
message = messages.GetLast()
rec_time = message.CreationTime
body_content = message.body
subj_line = message.subject
print(rec_time, body_content, subj_line)
Output:
>>>
================= RESTART: C:/Users/XXXXX/Desktop/email.py =================
=============================== RESTART: Shell ===============================
>>>
And here outpoot when CreationTime is commented out:
Hi,
I really think that it is weird that win32 cannot read date info
Your sincerely,
Myself
Andrew
Python ver 3.7, Outlook 2016
Just tried your code and it worked with no issues. Assuming you have taken some general troubleshooting steps, i.e., restart your computer, etc. I would recommend the following steps:
Close all instances of outlook
Run Outlook in safe mode by pressing Windows Key + R and this dialog appears
input outlook /safe just as its shown in the image (above). Attempt to run your script (opening outlook in safe mode ensures no Outlook add-ins/configurations interfere)
If this doesn't work, I would recommend using a debugger (VSCode for example) and running line by line to see where your script is terminating. You shared a sample code, but if you have additional code that you didn't share - only assumptions can be made from my end, but you may have something causing this issue in your script.
My program takes entered data and creates several batch / docx files. Is there a way to take my entered data and create a file that, when clicked on, will automatically send an e-mail to a specified e-mail address from a specific Gmail account? or better yet, open chrome and prepare the e-mail to be sent text and all?
The Gmail account I would like to use is delegated (controlled by various users), and the e-mail would have to come from this account, and not my personal Gmail account that I'm signed in to as well.
edit: it doesn't have to open chrome. can be anything. as long as i can make changes before i hit send.
Create a batch file that will run a python file that you create
For example a batch file with the following line
python -m your_module.your_python_file
create a python file called your_python_file.py with the following code
import logging
from logging.handlers import SMTPHandler
if(__name__ == "__main__"):
logger = logging.getLogger()
server_email_address = 'your_gmail_address'
server_account_password = 'your_gmail_password'
destination_email_address = 'destination_email_address'
emailh = SMTPHandler(('smtp.gmail.com', 587)
,server_email_address
,destination_email_address
,'your subject'
,(server_email_address, server_account_password)
, secure=())
emailh.setLevel(logging.WARNING)
logger.addHandler(emailh)
# input the email message to send
msg = input('enter message \n')
# send the email
logger.warning(msg)
when you click on the batch file, it should open a console window and run the python code. It should prompt you for an input - the email message to be sent - then it will send the email
The aim
To send custom text messages based on data read in from a csv file. Text messages should only be sent if the recipient is new or if previous messages to the recipient successfully delivered. If the phone number from the csv file is invalid for any reason, the program should just skip to the next number.
The problem
When deployed to Heroku, only the first exception is correctly handled. No messages are sent after the second invalid phone number is processed. However, it appears to work correctly if I run the program locally from the terminal.
The code
def send_sms(num, msg):
# sends message using Twilio's REST API
message = client.messages.create(
to=num,
from_=number,
body=msg,
status_callback=url)
def prep_msg(file):
# iterate through csv file containing phone numbers
for row in file:
msg = 'test message'
num = row[7]
# look for recipient in database of previously sent messages
record = Status.query.filter_by(to=num).first()
if record == None or record.status == 'delivered':
try:
send_sms(num, msg)
except Exception:
continue
return render_template('success.html')
The answer to this was to send the messages asynchronously as a background task using one of Heroku's worker dynos.
I used the following resources to research this:
https://devcenter.heroku.com/articles/python-rq
http://python-rq.org/docs/
I'm trying to implement an authentication section into the smbserver.py from the impacket lib.
I changed the errorCode at the Line 2201 to STATUS_LOGON_FAILURE under some conditions, but my windows client keeps requesting with the same credentials like 10 times before he asks the user to enter new credentials. When I submit the windows dialog the credentials dont get sent to the script.
Heres my code section:
if not authenticateMessage['user_name'] == "testUser":
print "username not valid"
errorCode = STATUS_LOGON_FAILURE
respToken['NegResult'] = '\x02'
else:
print "logged in" + authenticateMessage['user_name']
errorCode = STATUS_SUCCESS
respToken['NegResult'] = '\x00'
Did somebody write a working authentication section there? Thanks!
The link you have provided is not the official repository for the library. Use https://github.com/CoreSecurity/impacket in the future.
The code you specified is almost right except the fact that the user_name field inside the authenticateMessage is Unicode encoded.
You can see the contents of the authenticateMessage structure by calling its dump() method (authenticateMessage.dump()).
I've replaced your code with:
authenticateMessage.dump()
respToken = SPNEGO_NegTokenResp()
if authenticateMessage['user_name'].decode('utf-16le') == "testUser":
errorCode = STATUS_SUCCESS
respToken['NegResult'] = '\x00'
else:
errorCode = STATUS_LOGON_FAILURE
respToken['NegResult'] = '\x02'
If you cloned master (https://github.com/CoreSecurity/impacket) you will see a new example called examples/smbserver.py (don't get confused with the impacket/smbserver.py library) which makes it easier to launch a simple server. Just run:
smbserver.py shareName sharePath
(e.g. smbserver.py TMP /tmp)
I made the aforementioned changes and ran the smbserver.py example and then, from a windows 7 cmd.exe prompt I ran (assuming the SMB server runs at 172.16.123.1 and the logged in username is not testUser):
start \\172.16.123.1
If you sniff the traffic you will see three attempts to login unsuccessfully and then Windows Explorer will popup a dialog box asking for new credentials. If you specify testUser as username (password can be anything) you will end up connecting to the target SMB server.