Spaces:
Running
Running
File size: 7,276 Bytes
10865e1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# General utilities for MAPI and MAPI objects.
# We used to use these old names from the 'types' module...
TupleType = tuple
ListType = list
IntType = int
import pythoncom
from pywintypes import TimeType
from . import mapi, mapitags
prTable = {}
def GetPropTagName(pt):
if not prTable:
for name, value in mapitags.__dict__.items():
if name[:3] == "PR_":
# Store both the full ID (including type) and just the ID.
# This is so PR_FOO_A and PR_FOO_W are still differentiated,
# but should we get a PT_FOO with PT_ERROR set, we fallback
# to the ID.
# String types should have 3 definitions in mapitags.py
# PR_BODY = PROP_TAG( PT_TSTRING, 4096)
# PR_BODY_W = PROP_TAG( PT_UNICODE, 4096)
# PR_BODY_A = PROP_TAG( PT_STRING8, 4096)
# The following change ensures a lookup using only the the
# property id returns the conditional default.
# PT_TSTRING is a conditional assignment for either PT_UNICODE or
# PT_STRING8 and should not be returned during a lookup.
if (
mapitags.PROP_TYPE(value) == mapitags.PT_UNICODE
or mapitags.PROP_TYPE(value) == mapitags.PT_STRING8
):
if name[-2:] == "_A" or name[-2:] == "_W":
prTable[value] = name
else:
prTable[mapitags.PROP_ID(value)] = name
else:
prTable[value] = name
prTable[mapitags.PROP_ID(value)] = name
try:
try:
return prTable[pt]
except KeyError:
# Can't find it exactly - see if the raw ID exists.
return prTable[mapitags.PROP_ID(pt)]
except KeyError:
# god-damn bullshit hex() warnings: I don't see a way to get the
# old behaviour without a warning!!
ret = hex(int(pt))
# -0x8000000L -> 0x80000000
if ret[0] == "-":
ret = ret[1:]
if ret[-1] == "L":
ret = ret[:-1]
return ret
mapiErrorTable = {}
def GetScodeString(hr):
if not mapiErrorTable:
for name, value in mapi.__dict__.items():
if name[:7] in ["MAPI_E_", "MAPI_W_"]:
mapiErrorTable[value] = name
return mapiErrorTable.get(hr, pythoncom.GetScodeString(hr))
ptTable = {}
def GetMapiTypeName(propType, rawType=True):
"""Given a mapi type flag, return a string description of the type"""
if not ptTable:
for name, value in mapitags.__dict__.items():
if name[:3] == "PT_":
# PT_TSTRING is a conditional assignment
# for either PT_UNICODE or PT_STRING8 and
# should not be returned during a lookup.
if name in ["PT_TSTRING", "PT_MV_TSTRING"]:
continue
ptTable[value] = name
if rawType:
propType = propType & ~mapitags.MV_FLAG
return ptTable.get(propType, str(hex(propType)))
def GetProperties(obj, propList):
"""Given a MAPI object and a list of properties, return a list of property values.
Allows a single property to be passed, and the result is a single object.
Each request property can be an integer or a string. Of a string, it is
automatically converted to an integer via the GetIdsFromNames function.
If the property fetch fails, the result is None.
"""
bRetList = 1
if type(propList) not in [TupleType, ListType]:
bRetList = 0
propList = (propList,)
realPropList = []
rc = []
for prop in propList:
if type(prop) != IntType: # Integer
props = ((mapi.PS_PUBLIC_STRINGS, prop),)
propIds = obj.GetIDsFromNames(props, 0)
prop = mapitags.PROP_TAG(
mapitags.PT_UNSPECIFIED, mapitags.PROP_ID(propIds[0])
)
realPropList.append(prop)
hr, data = obj.GetProps(realPropList, 0)
if hr != 0:
data = None
return None
if bRetList:
return [v[1] for v in data]
else:
return data[0][1]
def GetAllProperties(obj, make_tag_names=True):
tags = obj.GetPropList(0)
hr, data = obj.GetProps(tags)
ret = []
for tag, val in data:
if make_tag_names:
hr, tags, array = obj.GetNamesFromIDs((tag,))
if type(array[0][1]) == type(""):
name = array[0][1]
else:
name = GetPropTagName(tag)
else:
name = tag
ret.append((name, val))
return ret
_MapiTypeMap = {
type(0.0): mapitags.PT_DOUBLE,
type(0): mapitags.PT_I4,
type("".encode("ascii")): mapitags.PT_STRING8, # bytes
type(""): mapitags.PT_UNICODE, # str
type(None): mapitags.PT_UNSPECIFIED,
# In Python 2.2.2, bool isn't a distinct type (type(1==1) is type(0)).
# (markh thinks the above is trying to say that in 2020, we probably *do*
# want bool in this map? :)
}
def SetPropertyValue(obj, prop, val):
if type(prop) != IntType:
props = ((mapi.PS_PUBLIC_STRINGS, prop),)
propIds = obj.GetIDsFromNames(props, mapi.MAPI_CREATE)
if val == (1 == 1) or val == (1 == 0):
type_tag = mapitags.PT_BOOLEAN
else:
type_tag = _MapiTypeMap.get(type(val))
if type_tag is None:
raise ValueError(
"Don't know what to do with '%r' ('%s')" % (val, type(val))
)
prop = mapitags.PROP_TAG(type_tag, mapitags.PROP_ID(propIds[0]))
if val is None:
# Delete the property
obj.DeleteProps((prop,))
else:
obj.SetProps(((prop, val),))
def SetProperties(msg, propDict):
"""Given a Python dictionary, set the objects properties.
If the dictionary key is a string, then a property ID is queried
otherwise the ID is assumed native.
Coded for maximum efficiency wrt server calls - ie, maximum of
2 calls made to the object, regardless of the dictionary contents
(only 1 if dictionary full of int keys)
"""
newProps = []
# First pass over the properties we should get IDs for.
for key, val in propDict.items():
if type(key) == str:
newProps.append((mapi.PS_PUBLIC_STRINGS, key))
# Query for the new IDs
if newProps:
newIds = msg.GetIDsFromNames(newProps, mapi.MAPI_CREATE)
newIdNo = 0
newProps = []
for key, val in propDict.items():
if type(key) == str:
type_val = type(val)
if type_val == str:
tagType = mapitags.PT_UNICODE
elif type_val == IntType:
tagType = mapitags.PT_I4
elif type_val == TimeType:
tagType = mapitags.PT_SYSTIME
else:
raise ValueError(
"The type of object %s(%s) can not be written"
% (repr(val), type_val)
)
key = mapitags.PROP_TAG(tagType, mapitags.PROP_ID(newIds[newIdNo]))
newIdNo = newIdNo + 1
newProps.append((key, val))
msg.SetProps(newProps)
|