How do I use python to create outlook events in multiple calendars - python

This is the code I've been using. It works when I want to create an appointment, but only in my main calendar. Do any of you know how to create the appointments in a secondary calendar?
import win32com.client
from win32com.client import Dispatch
outlook = win32com.client.Dispatch("Outlook.Application")
def sendMeeting():
appt = outlook.CreateItem(1) # AppointmentItem
appt.Start = "2021-5-28 16:10" # yyyy-MM-dd hh:mm
appt.Subject = "Fake meeting"
appt.Duration = 30 # In minutes (60 Minutes)
appt.Location = "The bat cave"
appt.Save()
appt.Send()

Do you mean a secondary Exchange account in the profile? Or a delegate Exchange mailbox?
In the former case, open the store from the Namespace.Stores collection, open the Calendar folder using Store.GetDefaulFolder(olFolderCalendar), create new item using MAPIFolder.Items.Add. In the latter case, you can use Namespace.GetSharedDefaultFolder(Recipient, olFolderCalendar) (where Recipient can be retrieved from Namespace.CreateRecipient).
If it is a subfolder in your primary store, you can access it from its parent folder and call MAPIFolder.Items.Add. E.g. if it is a subfolder of your default Calendar folder, use outlook.Session.GetDefaultFolder(olFolderCalendar).Folders.Item("The name"). If it is on the same level as your Calendar folder, use outlook.Session.GetDefaultFolder(olFolderCalendar).Parent.Folders.Item("The name").

Related

Outlook deletion emails through folders

I am trying to go over deletion of emails using python. I'd like to delete over different folders for emails older than 30 days.
Issue i am facing: how to use this structure to make it go through different folders? e.g. not only folder 'Clients' but also 'Reports'
import datetime
import win32com.client as win32
import datetime as dt
outlook=win32.dynamic.Dispatch('Outlook.Application').GetNamespace('MAPI')
o = win32.dynamic.Dispatch('Outlook.Application')
accounts= win32.Dispatch("Outlook.Application").Session.Accounts
root=outlook.Folders['sally_smith#gmail.com'].Folders['Inbox'].Folders['New'].Folders['Clients']
inbox = root.Items
lastWeekDateTime = dt.datetime.now() - dt.timedelta(days = 30)
messages = inbox.Restrict("[ReceivedTime] < '" +lastWeekDateTime.strftime('%d/%m/%Y')+"'")
for message in messages:
message.Delete()
It seems you need to iterate over all subfolders of the New folder. So, you can iterate over all subfolders in the following way:
Dim objCurFolder As Outlook.MAPIFolder
Dim subfolders as Outlook.Folders
subfolders=outlook.Folders['sally_smith#gmail.com'].Folders['Inbox'].Folders['New'].Folders
For Each objCurFolder In subfolders
Call ProcessCurrentFolder(objCurFolder)
Next
Where the separate method looks like that:
Private Sub ProcessCurrentFolder(ByVal objParentFolder As Outlook.MAPIFolder)
Dim objMail As Outlook.MailItem
On Error Resume Next
' Process each items in the folder
For Each objMail In objParentFolder.Items
' Do your task here ...
Next
End Sub

How do I access Online Archive mailbox using Python?

SOLVED ! :)
I used the following to move my mail from somewhere in my inbox into online archives with some important help mentioned below :
import win32com
import os
import sys
outlook = win32com.client.Dispatch('outlook.application')
mapi = outlook.GetNamespace("MAPI")
src = mapi.GetDefaultFolder(6).Folders["tobemoved"]
target = mapi.Folders["Online Archive - XXX"].Folders['Archive']
messages = src.Items
i = range(messages.count, 1, -1)
for x in i:
print(x)
messages(x).Move(target)
`
I have additional folder called
'Online-Archive-Same email address as "inbox" email '
that i currently can't locate it tried to use this link to figure out the enumeration of it . but no luck ..
as i must free up some disk space ill appreciate any help given.
P.S
tried the conventional way - with outlook struggling with connection issues and 22k email to be moved to be archived outlook just giving up on me :) feel free to advise anything that can resolve this issue.
You can access the Office 365 Online Archive folders like this:
Replace the example email with the exact email address you see in outlook.
import win32com.client
import win32com
app = win32com.client.gencache.EnsureDispatch("Outlook.Application")
outlook = app.GetNamespace("MAPI")
outlook_folder = outlook.Folders['Online Archive - Example#email.com'].Folders['Inbox']
item_count = outlook_folder.Items.Count
print(item_count)
180923
On the low (Extended MAPI) level (C++ or Delphi only), Online Archive is just another delegate Exchange mailbox. The only way to distinguish an archive mailbox from yet another delegate mailbox owned by some Exchange user is by reading PR_PROFILE_ALTERNATE_STORE_TYPE property in the archive store profile section - retrieve the store entry id (PR_ENTRYID), then find the matching row in the session stores table (IMAPISession::GetMsgStoresTable). For the matching row (use IMAPISession::CompareEntryIDs), retrieve PR_PROVIDER_UID property. Use its value to call IMAPISession.OpenProfileSection. Read PR_PROFILE_ALTERNATE_STORE_TYPE property from the IProfSect object and check if its value is "Archive" (unlike the store name, is not localized).
If Extended MAPI in C++ or Delphi is not an option, you can either
Try to find a matching store in the Namespace.Stores collection with the name starting with "Online Archive - " and the SMTP address of the user. Since that prefix is locale specific, that is not something I would use in production code.
Use Redemption (I am its author) - it exposes RDOExchangeMailboxStore.IsArchive property. If the archive store is not already opened in Outlook, you can also use RDOSession.GetArchiveMailbox. In VB script:
set rSession = CreateObject("Redemption.RDOSession")
rSession.MAPIOBJECT = Application.Session.MAPIOBJECT
userAddress = rSession.CurrentUser.SMTPAddress
set store = GetOpenArchiveMailboxForUser(userAddress)
if not store is Nothing Then
MsgBox "Found archive store for " & userAddress
Else
MsgBox "Could not find archive store for " & userAddress
End If
function GetOpenArchiveMailboxForUser(SmtpAddress)
set GetOpenArchiveMailboxForUser = Nothing
for each store in rSession.Stores
if TypeName(store) = "RDOExchangeMailboxStore" Then
Debug.Print store.Name & " - " & store.Owner.SMTPAddress & " - " & store.IsArchive
if store.IsArchive and LCase(store.Owner.SMTPAddress) = LCase(SmtpAddress) Then
set GetOpenArchiveMailboxForUser = store
exit for
End If
End If
next
end function

Import Outlook Calendar Appointment from One account to another in Python/VBA

Actually I am trying to Export the calendar appointment from one outlook account to another outlook account but I have trayed so many time and end-up with just extracted appointment in an excel sheet and importing the same into another account. I don't have to much knowledge of VBA but I have used via internet and got this -
Private Sub Outlook_Vba_Get_Calendar_Item_Appoinments()
Dim oWorkbook As Workbook, Calendar_To_Excel_File As String
Dim oOutlook_Calendar As Outlook.Folder, oCalendar_Items As Outlook.Items
Dim oCalendarAppointment As Outlook.AppointmentItem
Dim iRow As Double
iRow = 1
'Change path of the Target File name if required
Calendar_To_Excel_File = "D:\Sample23434.xlsx"
'Check if Output File already exists
If VBA.Dir(Calendar_To_Excel_File) = "" Then
'To Create New Workbook
Set oWorkbook = Workbooks.Add
oWorkbook.SaveAs Calendar_To_Excel_File
Else
'To Refer Already Created Workbook
Set oWorkbook = Workbooks.Open(Calendar_To_Excel_File)
End If
'Get object reference for Outlook Calendar folder
Set oOutlook_Calendar = Outlook.Application.GetNamespace("MAPI").GetDefaultFolder(olFolderCalendar)
Set oCalendar_Items = oOutlook_Calendar.Items
'Loop Thru Each Items in Outlook Calendar
For Each oCalendarAppointment In oCalendar_Items
oWorkbook.Sheets(1).Cells(iRow, 1) = oOutlook_Calendar.FolderPath
oWorkbook.Sheets(1).Cells(iRow, 2) = oCalendarAppointment.Start
oWorkbook.Sheets(1).Cells(iRow, 3) = oCalendarAppointment.End
oWorkbook.Sheets(1).Cells(iRow, 4) = oCalendarAppointment.Subject
oWorkbook.Sheets(1).Cells(iRow, 5) = oCalendarAppointment.Location
oWorkbook.Sheets(1).Cells(iRow, 6) = oCalendarAppointment.Duration
oWorkbook.Sheets(1).Cells(iRow, 7) = oCalendarAppointment.Size
'oWorkbook.Sheets(1).Cells(irow, 8) = oCalendarAppointment.Body
iRow = iRow + 1
Next
'Save Excel Workbook With Calendar Appointments
oWorkbook.Save
oWorkbook.Close False 'Close Workbook without any Warning
MsgBox "Outlook Calendar Appointments Downloaded To:" & Calendar_To_Excel_File
End Sub
If any one know how can I do this without using Excel please let me know with either Python or VBA
If you have got another account shared by a user (or just a calendar with required permissions to modify it) you could add a shared calendar to the Outlook profile and copy/move the required appointments directly without involving Excel workbooks for that.
The NameSpace.GetSharedDefaultFolder method returns a Folder object that represents the specified default folder for the specified user. This method is used in a delegation scenario, where one user has delegated access to another user for one or more of their default folders (for example, their shared Calendar folder). For example, here is how you could use it to get the shared calendar folder in Outlook:
Sub ResolveName()
Dim myNamespace As Outlook.NameSpace
Dim myRecipient As Outlook.Recipient
Dim CalendarFolder As Outlook.Folder
Set myNamespace = Application.GetNamespace("MAPI")
Set myRecipient = myNamespace.CreateRecipient("Eugene Astafiev")
myRecipient.Resolve
If myRecipient.Resolved Then
Call ShowCalendar(myNamespace, myRecipient)
End If
End Sub
Sub ShowCalendar(myNamespace, myRecipient)
Dim CalendarFolder As Outlook.Folder
Set CalendarFolder = myNamespace.GetSharedDefaultFolder(myRecipient, olFolderCalendar)
CalendarFolder.Display
End Sub
After retrieving the target folder instance you can use the AppointmentItem.Move or AppointmentItem.CopyTo methods.

Create Outlook appointment in subfolder/subcalendar with python

searched all entries on the topic and I am close to solution but help is appreciated:
I want to create calendar entries in a non-default calendar in Outlook via python. I did
import win32com.client
outlook = win32com.client.Dispatch('Outlook.Application').GetNamespace('MAPI')
calendar = outlook.Folders('myaccount#mail.com').Folders('calendar').Folders('subcalendar')
I can read entries, count entries of the subcalendar - all good.
Now I try to create a new item in this 'subcalendar' by
newapp = calendar.CreateItem(1)
newapp.Start = '2020-09-25 08:00'
newapp.Subject = 'Testentry'
newapp.Duration = 15
newapp.Save()
throwing error: AttributeError:< unknown >.CreateItem.
I am calling the object 'subcalendar' with the Method CreateItem and the correct object type...seems I am blind but do not see the solution.
Thanks for any help on this!
You can use the following code:
newapp = calendar.Items.Add()
newapp.Start = '2020-09-25 08:00'
newapp.Subject = 'Testentry'
newapp.Duration = 15
newapp.Save()
The Items.Add method creates a new Outlook item in the Items collection for the folder. If the type is not specified, the Type property of the Outlook item defaults to the type of the folder or to MailItem if the parent folder is not typed.
You may find the How To: Create a new Outlook Appointment item article helpful.

Python Caldav, all calendars have None name

I'm trying to access to all events of my calendar, hosted on Nextcloud, with python and the caldav library.
With this code:
client = caldav.DAVClient(url) #like "https://..../nextcloud/remote.php/dav/calendars
principal = client.principal()
calendars = principal.calendars()
I can access to all my calendars and iterate over it.
How I can read only a specific calendar, with the name "calendar_name"? In this case I get all calendars, even if I specify the calendar name:
client = caldav.DAVClient(url) #like "https://..../nextcloud/remote.php/dav/calendars/user/calendar_name
principal = client.principal()
calendars = principal.calendars()
If I change the last line of code with calendar_name, I get an empty array.
calendar = principal.calendar('calendar_name')
Note: I can access all calendars and events with the first code posted, but all names are "None", even if the Url is right.
The second snippet still gives you all calendars because you first grab the account (.principal()) and then you list all calendars the account has (principal.calendars()).
The third snippet probably doesn't work because the name (the display name property, not the URL path component) of the calendar quite likely isn't calendar_name but something like Calendar. Theoretically it may even be empty.
To access a single calendar using its URL this may work, didn't try:
client = caldav.DAVClient(url)
calendar = caldav.Calendar(client=client,
url="/nextcloud/remote.php/dav/calendars/user/calendar_name")
Though it may be better to do something like this for various reasons:
client = caldav.DAVClient(url)
principal = client.principal()
calendars = principal.calendars()
calendar = any(c for c in calendars if c.url == your url)
To address your actual question, you need to add more information. If you want the (relative or absolute) URL of the calendar, use something like this:
print calendar.url
If you want to explicitly retrieve the calendar display name, this may work:
print calendar.get_properties([dav.DisplayName()])
Hope this helps.

Categories

Resources