Package native :: Package outlook :: Module outlook
[hide private]
[frames] | no frames]

Source Code for Module native.outlook.outlook

  1  ### BITPIM 
  2  ### 
  3  ### Copyright (C) 2004 Roger Binns <rogerb@rogerbinns.com> 
  4  ### 
  5  ### This program is free software; you can redistribute it and/or modify 
  6  ### it under the terms of the BitPim license as detailed in the LICENSE file. 
  7  ### 
  8  ### $Id: outlook.py 3022 2006-03-31 03:21:24Z djpham $ 
  9   
 10  "Be at one with Outlook" 
 11   
 12  # Reject if not on Windows 
 13  import sys 
 14  if sys.platform!="win32": 
 15     raise ImportError() 
 16   
 17  import common 
 18   
 19  # See this recipe on ASPN for how this code started 
 20  # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/173216 
 21  # Chris Somerlot also gave some insights 
 22   
 23  import outlook_com 
 24   
 25  import pywintypes 
 26   
 27  # This is the complete list of field names available 
 28  ##    Account 
 29  ##    AssistantName 
 30  ##    AssistantTelephoneNumber 
 31  ##    BillingInformation 
 32  ##    Body 
 33  ##    Business2TelephoneNumber 
 34  ##    BusinessAddress 
 35  ##    BusinessAddressCity 
 36  ##    BusinessAddressCountry 
 37  ##    BusinessAddressPostOfficeBox 
 38  ##    BusinessAddressPostalCode 
 39  ##    BusinessAddressState 
 40  ##    BusinessAddressStreet 
 41  ##    BusinessFaxNumber 
 42  ##    BusinessHomePage 
 43  ##    BusinessTelephoneNumber 
 44  ##    CallbackTelephoneNumber 
 45  ##    CarTelephoneNumber 
 46  ##    Categories 
 47  ##    Children 
 48  ##    Class 
 49  ##    Companies 
 50  ##    CompanyAndFullName 
 51  ##    CompanyLastFirstNoSpace 
 52  ##    CompanyLastFirstSpaceOnly 
 53  ##    CompanyMainTelephoneNumber 
 54  ##    CompanyName 
 55  ##    ComputerNetworkName 
 56  ##    ConversationIndex 
 57  ##    ConversationTopic 
 58  ##    CustomerID 
 59  ##    Department 
 60  ##    Email1Address 
 61  ##    Email1AddressType 
 62  ##    Email1DisplayName 
 63  ##    Email1EntryID 
 64  ##    Email2Address 
 65  ##    Email2AddressType 
 66  ##    Email2DisplayName 
 67  ##    Email2EntryID 
 68  ##    Email3Address 
 69  ##    Email3AddressType 
 70  ##    Email3DisplayName 
 71  ##    Email3EntryID 
 72  ##    EntryID 
 73  ##    FTPSite 
 74  ##    FileAs 
 75  ##    FirstName 
 76  ##    FullName 
 77  ##    FullNameAndCompany 
 78  ##    Gender 
 79  ##    GovernmentIDNumber 
 80  ##    Hobby 
 81  ##    Home2TelephoneNumber 
 82  ##    HomeAddress 
 83  ##    HomeAddressCity 
 84  ##    HomeAddressCountry 
 85  ##    HomeAddressPostOfficeBox 
 86  ##    HomeAddressPostalCode 
 87  ##    HomeAddressState 
 88  ##    HomeAddressStreet 
 89  ##    HomeFaxNumber 
 90  ##    HomeTelephoneNumber 
 91  ##    ISDNNumber 
 92  ##    Importance 
 93  ##    Initials 
 94  ##    InternetFreeBusyAddress 
 95  ##    JobTitle 
 96  ##    Journal 
 97  ##    Language 
 98  ##    LastFirstAndSuffix 
 99  ##    LastFirstNoSpace 
100  ##    LastFirstNoSpaceCompany 
101  ##    LastFirstSpaceOnly 
102  ##    LastFirstSpaceOnlyCompany 
103  ##    LastName 
104  ##    LastNameAndFirstName 
105  ##    MailingAddress 
106  ##    MailingAddressCity 
107  ##    MailingAddressCountry 
108  ##    MailingAddressPostOfficeBox 
109  ##    MailingAddressPostalCode 
110  ##    MailingAddressState 
111  ##    MailingAddressStreet 
112  ##    ManagerName 
113  ##    MessageClass 
114  ##    MiddleName 
115  ##    Mileage 
116  ##    MobileTelephoneNumber 
117  ##    NetMeetingAlias 
118  ##    NetMeetingServer 
119  ##    NickName 
120  ##    NoAging 
121  ##    OfficeLocation 
122  ##    OrganizationalIDNumber 
123  ##    OtherAddress 
124  ##    OtherAddressCity 
125  ##    OtherAddressCountry 
126  ##    OtherAddressPostOfficeBox 
127  ##    OtherAddressPostalCode 
128  ##    OtherAddressState 
129  ##    OtherAddressStreet 
130  ##    OtherFaxNumber 
131  ##    OtherTelephoneNumber 
132  ##    OutlookInternalVersion 
133  ##    OutlookVersion 
134  ##    PagerNumber 
135  ##    PersonalHomePage 
136  ##    PrimaryTelephoneNumber 
137  ##    Profession 
138  ##    RadioTelephoneNumber 
139  ##    ReferredBy 
140  ##    Saved 
141  ##    SelectedMailingAddress 
142  ##    Sensitivity 
143  ##    Size 
144  ##    Spouse 
145  ##    Subject 
146  ##    Suffix 
147  ##    TTYTDDTelephoneNumber 
148  ##    TelexNumber 
149  ##    Title 
150  ##    UnRead 
151  ##    User1 
152  ##    User2 
153  ##    User3 
154  ##    User4 
155  ##    UserCertificate 
156  ##    WebPage 
157  ##    YomiCompanyName 
158  ##    YomiFirstName 
159  ##YomiLastName 
160   
161 -def getcontacts(folder, keys=None):
162 """Returns a list of dicts""" 163 164 # There is a gross hack to only return email addresses if they are for SMTP 165 166 res=[] 167 for oc in range(folder.Items.Count): 168 contact=folder.Items.Item(oc+1) 169 if contact.Class == outlook_com.constants.olContact: 170 record={} 171 if keys is None: 172 keys=[] 173 for key in contact._prop_map_get_: 174 # work out if it is a property or a method (last field is None for properties) 175 if contact._prop_map_get_[key][-1] is None: 176 keys.append(key) 177 for key in keys: 178 v=getattr(contact, key) 179 if v not in (None, "", "\x00\x00"): 180 if isinstance(v, pywintypes.TimeType): # convert from com time 181 try: 182 v=int(v) 183 except ValueError: 184 # illegal time value 185 continue 186 if key=="Categories": 187 # for some idiotic reason Outlook uses comma 188 # space seperators for this field despite using 189 # semi-colon elsewhere for the same field so we 190 # munge the data 191 v=";".join([x.strip() for x in v.split(",")]) 192 if key.startswith("Email") and key.endswith("Address"): 193 keytype=key+"Type" 194 if keytype not in keys: 195 if getattr(contact, keytype)!="SMTP": 196 continue 197 198 record[key]=v 199 res.append(record) 200 return res
201
202 -def getitemdata(item, record, keys, client):
203 for k, k_out, convertor_func in keys: 204 v=getattr(item, k) 205 if v is None or v=="\x00\x00": 206 v='' 207 if convertor_func is not None: 208 # run through convertor func 209 try: 210 v=convertor_func(record, v, client) 211 except: 212 # failed conversion, skip this field 213 raise 214 # assign in dict if specified 215 if k_out is not None: 216 record[k_out]=v 217 return record
218
219 -def getdata(folder, keys=None, preset_dict={}, client=None, post_func=None):
220 """Returns a list of dicts""" 221 res=[] 222 import_errors=[] 223 if not folder.Items.Count: 224 # empty folder, just return 225 return res, import_errors 226 # prefill keys if necessary 227 if keys is None: 228 keys=[] 229 item=folder.Items.Item(1) 230 for k in item._prop_map_get_: 231 if item._prop_map_get_[k][-1] is None: 232 keys.append((k, k, None)) 233 # go through the folder and read the data 234 for i in range(folder.Items.Count): 235 item=folder.Items.Item(i+1) 236 record=preset_dict.copy() 237 try: 238 getitemdata(item, record, keys, client) 239 if post_func is None or post_func(item, record, client): 240 res.append(record) 241 except: 242 import_errors.append(record) 243 return res, import_errors
244
245 -def getfolderfromid(id, default=False, default_type='contacts'):
246 """Returns a folder object from the supplied id 247 248 @param id: The id of the folder 249 @param default: If true and the folder can't be found, then return the default""" 250 onMAPI = getmapinamespace() 251 try: 252 folder=onMAPI.GetFolderFromID(id) 253 except pywintypes.com_error,e: 254 folder=None 255 256 # ::TODO:: should be supplied default type (contacts, calendar etc) 257 if default and not folder: 258 if default_type=='calendar': 259 default_folder=outlook_com.constants.olFolderCalendar 260 elif default_type=='notes': 261 default_folder=outlook_com.constants.olFolderNotes 262 elif default_type=='tasks': 263 default_folder=outlook_com.constants.olFolderTasks 264 else: 265 # default to contacts, works as before 266 default_folder=outlook_com.constants.olFolderContacts 267 folder=onMAPI.GetDefaultFolder(default_folder) 268 return folder
269
270 -def getfoldername(folder):
271 n=[] 272 while folder: 273 try: 274 n=[folder.Name]+n 275 except AttributeError: 276 break # namespace object has no 'Name' 277 folder=folder.Parent 278 return " / ".join(n)
279
280 -def getfolderid(folder):
281 return str(folder.EntryID) # de-unicodify it
282
283 -def pickfolder():
284 return getmapinamespace().PickFolder()
285 286 _outlookappobject=None
287 -def getoutlookapp():
288 global _outlookappobject 289 if _outlookappobject is None: 290 _outlookappobject=outlook_com.Application() 291 return _outlookappobject
292 293 _mapinamespaceobject=None
294 -def getmapinamespace():
295 global _mapinamespaceobject 296 if _mapinamespaceobject is None: 297 _mapinamespaceobject=getoutlookapp().GetNamespace("MAPI") 298 return _mapinamespaceobject
299
300 -def releaseoutlook():
301 global _mapinamespaceobject 302 global _outlookappobject 303 _mapinamespaceobject=None 304 _outlookappobject=None
305 306 307 if __name__=='__main__': 308 oOutlookApp=outlook_com.Application() 309 onMAPI = oOutlookApp.GetNamespace("MAPI") 310 311 import guihelper # needed for common.strorunicode symbol 312 313 res=onMAPI.PickFolder() 314 print res 315 316 contacts=getcontacts(res) 317 keys={} 318 for item in contacts: 319 for k in item.keys(): 320 keys[k]=1 321 keys=keys.keys() 322 keys.sort() 323 324 # Print out keys so they can be pasted in elsewhere 325 for k in keys: 326 print " ('%s', )," % (k,) 327 328 import wx 329 import wx.grid 330 331 app=wx.PySimpleApp() 332 import wx.lib.colourdb 333 wx.lib.colourdb.updateColourDB() 334 335 336 f=wx.Frame(None, -1, "Outlookinfo") 337 g=wx.grid.Grid(f, -1) 338 g.CreateGrid(len(contacts)+1,len(keys)) 339 g.SetColLabelSize(0) 340 g.SetRowLabelSize(0) 341 g.SetMargins(1,0) 342 g.BeginBatch() 343 attr=wx.grid.GridCellAttr() 344 attr.SetBackgroundColour(wx.GREEN) 345 attr.SetFont(wx.Font(10,wx.SWISS, wx.NORMAL, wx.BOLD)) 346 attr.SetReadOnly(True) 347 for k in range(len(keys)): 348 g.SetCellValue(0, k, keys[k]) 349 g.SetRowAttr(0,attr) 350 # row attributes 351 oddattr=wx.grid.GridCellAttr() 352 oddattr.SetBackgroundColour("OLDLACE") 353 oddattr.SetReadOnly(True) 354 evenattr=wx.grid.GridCellAttr() 355 evenattr.SetBackgroundColour("ALICE BLUE") 356 evenattr.SetReadOnly(True) 357 for row in range(len(contacts)): 358 item=contacts[row] 359 for col in range(len(keys)): 360 key=keys[col] 361 v=item.get(key, "") 362 v=common.strorunicode(v) 363 g.SetCellValue(row+1, col, v) 364 g.SetRowAttr(row+1, (evenattr,oddattr)[row%2]) 365 366 g.AutoSizeColumns() 367 g.AutoSizeRows() 368 g.EndBatch() 369 370 f.Show(True) 371 app.MainLoop() 372