Ejemplo n.º 1
0
    def restriction(self, type_, store):
        if self.field:
            # determine proptag for term, eg 'subject'
            proptag = TYPE_KEYWORD_PROPMAP[type_][self.field]
            flag = None
            subobj = None
            recipient_type = None

            # property in sub-object (attachments/recipient): use sub-restriction
            if isinstance(proptag, tuple):
                if(proptag[0]) == PR_MESSAGE_ATTACHMENTS:
                    subobj, proptag = proptag
                elif(proptag[0]) == PR_MESSAGE_RECIPIENTS:
                    subobj, proptag, recipient_type = proptag
                elif len(proptag) == 2:
                    proptag, flag = proptag

                # named property: resolve local proptag
                elif len(proptag) == 4:
                    proptag = store._name_id(proptag[:3]) | proptag[3]

            # make restriction on proptag(s)
            if isinstance(proptag, list):
                restr = SOrRestriction([
                    self.prop_restriction(proptag, flag) for proptag in proptag
                ])
            else:
                restr = self.prop_restriction(proptag, flag)

            # turn restriction into sub-restriction
            if subobj:
                if recipient_type is not None:
                    restr = SAndRestriction([
                        restr,
                        SPropertyRestriction(
                                RELOP_EQ,
                                PR_RECIPIENT_TYPE,
                                SPropValue(PR_RECIPIENT_TYPE, recipient_type)
                        )
                    ])
                restr = SSubRestriction(subobj, restr)

        else:
            defaults = [(store._name_id(proptag[:3]) | proptag[3])
                           if isinstance(proptag, tuple) else proptag
                               for proptag in DEFAULT_PROPTAGS[type_]]

            restr = SOrRestriction([
                       SContentRestriction(
                           FL_SUBSTRING | FL_IGNORECASE,
                           p,
                           SPropValue(p, self.value)
                       ) for p in defaults
                   ])

        if self.sign == '-':
            restr = SNotRestriction(restr)

        return restr
def test_optimize_doubleor(root):
    restriction = SOrRestriction([
            SOrRestriction([
                    SContentRestriction(FL_SUBSTRING | FL_IGNORECASE, PR_SUBJECT, SPropValue(PR_SUBJECT, b'unknown')),
                    SContentRestriction(FL_SUBSTRING | FL_IGNORECASE, PR_SUBJECT, SPropValue(PR_SUBJECT, b'unknown'))
                    ])
            ])
    assert_no_results(root, restriction)
Ejemplo n.º 3
0
    def search_start(self, folders, text, recurse=False):
        # specific restriction format, needed to reach indexer
        restriction = SOrRestriction([
            SContentRestriction(FL_SUBSTRING | FL_IGNORECASE,
                PR_SUBJECT_W,
                SPropValue(PR_SUBJECT_W, str(text))),
            SContentRestriction(FL_SUBSTRING | FL_IGNORECASE,
                PR_BODY_W,
                SPropValue(PR_BODY_W, str(text))),
            SContentRestriction(FL_SUBSTRING | FL_IGNORECASE,
                PR_DISPLAY_TO_W,
                SPropValue(PR_DISPLAY_TO_W, str(text))),
            SContentRestriction(FL_SUBSTRING | FL_IGNORECASE,
                PR_DISPLAY_NAME_W,
                SPropValue(PR_DISPLAY_NAME_W, str(text))),
            # TODO add all default fields..
            # BUT perform full-text search by default!
        ])
        if isinstance(folders, Folder):
            folders = [folders]

        search_flags = 0
        if recurse:
            search_flags = SEARCH_RECURSIVE
        self.mapiobj.SetSearchCriteria(restriction,
            [_bdec(f.entryid) for f in folders], search_flags)
def test_optimize_orandfalse(root):
    restriction = SOrRestriction([
            SAndRestriction([
                    SNotRestriction(SExistRestriction(PR_SUBJECT)),
                    SExistRestriction(PR_SUBJECT)
                    ])
            ])
    assert_no_results(root, restriction)
Ejemplo n.º 5
0
    def _save_rule(store, userids, deletion):
        # remove existing rule # XXX update
        for rule in store.inbox.rules():
            if rule.mapirow[PR_RULE_PROVIDER_W] == u'Schedule+ EMS Interface' and \
               PR_RULE_ID in rule.mapirow:
                pr_rule_id = rule.mapirow[PR_RULE_ID]

                rulerows = [
                    ROWENTRY(ROW_REMOVE, [SPropValue(PR_RULE_ID, pr_rule_id)])
                ]
                table = store.inbox.mapiobj.OpenProperty(
                    PR_RULES_TABLE, IID_IExchangeModifyTable, 0, 0)
                table.ModifyTable(0, rulerows)

        # create new rule
        row = [
            SPropValue(PR_RULE_LEVEL, 0),
            SPropValue(PR_RULE_NAME_W, u"Delegate Meetingrequest service"),
            SPropValue(PR_RULE_PROVIDER_W, u"Schedule+ EMS Interface"),
            SPropValue(PR_RULE_SEQUENCE, 0),
            SPropValue(PR_RULE_STATE, 1),
            SPropValue(PR_RULE_PROVIDER_DATA, b''),
        ]

        actions = []
        userprops = []
        for userid in userids:
            user = store.server.gab.OpenEntry(userid, None, MAPI_BEST_ACCESS)
            props = user.GetProps(USERPROPS, MAPI_UNICODE)
            # Hardcode recipient type to TO
            props.append(SPropValue(PR_RECIPIENT_TYPE, MAPI_TO))
            userprops.append(props)

        actions.append(
            ACTION(ACTTYPE.OP_DELEGATE, 0, None, None, 0,
                   actFwdDelegate(userprops)))
        if deletion:
            actions.append(ACTION(ACTTYPE.OP_DELETE, 0, None, None, 0, None))
        row.append(SPropValue(PR_RULE_ACTIONS, ACTIONS(1, actions)))

        cond = SAndRestriction([
            SContentRestriction(
                FL_PREFIX, PR_MESSAGE_CLASS_W,
                SPropValue(PR_MESSAGE_CLASS_W, u"IPM.Schedule.Meeting")),
            SNotRestriction(SExistRestriction(PR_DELEGATED_BY_RULE)),
            SOrRestriction([
                SNotRestriction(SExistRestriction(PR_SENSITIVITY)),
                SPropertyRestriction(RELOP_NE, PR_SENSITIVITY,
                                     SPropValue(PR_SENSITIVITY, 2))
            ])
        ])
        row.append(SPropValue(PR_RULE_CONDITION, cond))
        rulerows = [ROWENTRY(ROW_ADD, row)]
        table = store.inbox.mapiobj.OpenProperty(PR_RULES_TABLE,
                                                 IID_IExchangeModifyTable, 0,
                                                 0)
        table.ModifyTable(0, rulerows)
Ejemplo n.º 6
0
 def restriction(self, type_, store):
     if self.op == 'AND':
         return SAndRestriction(
             [arg.restriction(type_, store) for arg in self.args])
     elif self.op == 'OR':
         return SOrRestriction(
             [arg.restriction(type_, store) for arg in self.args])
     elif self.op == 'NOT':
         return SNotRestriction(self.args[0].restriction(type_, store))
def test_optimize_ormultianndfalse(root):
    restriction = SOrRestriction([
    SAndRestriction([
            SNotRestriction(SExistRestriction(PR_SUBJECT)),
            SExistRestriction(PR_SUBJECT)
            ]),
    SAndRestriction([
            SContentRestriction(FL_SUBSTRING | FL_IGNORECASE, PR_SUBJECT, SPropValue(PR_SUBJECT, b'unknown')),
            SContentRestriction(FL_SUBSTRING | FL_IGNORECASE, PR_SUBJECT, SPropValue(PR_SUBJECT, b'unknown'))
            ])
    ])
    assert_no_results(root, restriction)
Ejemplo n.º 8
0
    def attendees(self):
        """Appointment :class:`attendees <Attendee>`."""

        # Filter out organizer from all recipients
        restriction = Restriction(
            SOrRestriction([
                SNotRestriction(SExistRestriction(PR_RECIPIENT_FLAGS)),
                SBitMaskRestriction(BMR_EQZ, PR_RECIPIENT_FLAGS,
                                    recipOrganizer)
            ]))
        for row in self.table(PR_MESSAGE_RECIPIENTS, restriction=restriction):
            yield Attendee(self.server, row)
Ejemplo n.º 9
0
    def occurrences(self, start=None, end=None):
        if start and end:
            startstamp = time.mktime(start.timetuple())
            endstamp = time.mktime(end.timetuple())

            # XXX use shortcuts and default type (database) to avoid MAPI snake wrestling
            NAMED_PROPS = [
                MAPINAMEID(PSETID_Appointment, MNID_ID, x)
                for x in (33293, 33294, 33315)
            ]
            ids = self.mapiobj.GetIDsFromNames(NAMED_PROPS, 0)
            startdate = ids[0] | PT_SYSTIME
            enddate = ids[1] | PT_SYSTIME
            recurring = ids[2] | PT_BOOLEAN

            # only look at non-recurring items which overlap and all recurring items
            restriction = SOrRestriction([
                SAndRestriction([
                    SPropertyRestriction(
                        RELOP_GT, enddate,
                        SPropValue(enddate, unixtime(startstamp))),
                    SPropertyRestriction(
                        RELOP_LT, startdate,
                        SPropValue(startdate, unixtime(endstamp))),
                ]),
                SAndRestriction([
                    SPropertyRestriction(RELOP_EQ, recurring,
                                         SPropValue(recurring, True))
                ])
            ])

            table = Table(
                self.server,
                self.mapiobj,
                self.mapiobj.GetContentsTable(MAPI_DEFERRED_ERRORS),
                PR_CONTAINER_CONTENTS,
                columns=[PR_ENTRYID],
            )
            table.mapitable.Restrict(restriction, 0)
            for row in table.rows():
                entryid = _benc(row[0].value)
                for occurrence in self.item(entryid).occurrences(start, end):
                    yield occurrence

        else:
            for item in self:
                for occurrence in item.occurrences(start, end):
                    yield occurrence
Ejemplo n.º 10
0
def GetGab(session):
    ab = session.OpenAddressBook(0, None, 0)
    root = ab.OpenEntry(None, None, 0)
    table = root.GetHierarchyTable(0)
    table.SetColumns([PR_ENTRYID], TBL_BATCH)
    restriction = SOrRestriction([
        SPropertyRestriction(RELOP_EQ, PR_DISPLAY_TYPE,
                             SPropValue(PR_DISPLAY_TYPE, DT_GLOBAL)),
        SAndRestriction([
            SExistRestriction(PR_EMS_AB_CONTAINERID),
            SPropertyRestriction(RELOP_EQ, PR_EMS_AB_CONTAINERID,
                                 SPropValue(PR_EMS_AB_CONTAINERID, 0))
        ])
    ])
    table.FindRow(restriction, BOOKMARK_BEGINNING, 0)
    eid = table.QueryRows(1, 0)[0][0].Value
    return ab.OpenEntry(eid, None, 0)
Ejemplo n.º 11
0
    def restriction(self, type_, store):
        if self.field:
            # determine proptag for term, eg 'subject'
            proptag = TYPE_KEYWORD_PROPMAP[type_][self.field]
            flag = None
            subobj = None
            recipient_type = None

            # property in sub-object (attachments/recipient): use sub-restriction
            if isinstance(proptag, tuple) and len(proptag) == 2:
                if(proptag[0]) == PR_MESSAGE_ATTACHMENTS:
                    subobj, proptag = proptag
                elif(proptag[0]) == PR_MESSAGE_RECIPIENTS:
                    subobj, recipient_type = proptag
                    proptag = PR_DISPLAY_NAME_W # TODO email
                else:
                    proptag, flag = proptag

            # named property: resolve local proptag
            elif isinstance(proptag, tuple) and len(proptag) == 4:
                proptag = store._name_id(proptag[:3]) | proptag[3]

            # comparison operator
            if self.op in ('<', '>', '>=', '<=', '<>'):
                if PROP_TYPE(proptag) == PT_SYSTIME:
                    d = dateutil.parser.parse(self.value, dayfirst=True)
                    d = datetime_to_filetime(d)
                    restr = SPropertyRestriction(
                                OP_RELOP[self.op],
                                proptag,
                                SPropValue(proptag, d)
                            )
                else:
                    value = self.value
                    unit = ''
                    if [x for x in ('KB', 'MB', 'GB') if value.endswith(x)]:
                        value, unit = value[:-2], value[-2:]

                    if PROP_TYPE(proptag) in (PT_FLOAT, PT_DOUBLE):
                        value = float(value)
                    else:
                        value = int(value)

                    if unit == 'KB':
                        value *= 1024
                    elif unit == 'MB':
                        value *= 1024**2
                    elif unit == 'GB':
                        value *= 1024**3

                    restr = SPropertyRestriction(
                                OP_RELOP[self.op],
                                proptag,
                                SPropValue(proptag, value)
                            )

            # contains/equals operator
            elif self.op in (':', '='):
                if PROP_TYPE(proptag) == PT_UNICODE:
                    restr = SContentRestriction(
                                FL_SUBSTRING | FL_IGNORECASE,
                                proptag,
                                SPropValue(proptag, self.value)
                            )

                elif flag or PROP_TYPE(proptag) == PT_BOOLEAN:
                    if flag:
                        restr = SBitMaskRestriction(
                                    BMR_NEZ if self.value in ('yes', 'true') else BMR_EQZ,
                                    proptag,
                                    flag
                                )
                    else:
                        restr = SPropertyRestriction(
                                    RELOP_EQ,
                                    proptag,
                                    SPropValue(proptag, self.value in ('yes', 'true'))
                                )

                elif PROP_TYPE(proptag) == PT_MV_UNICODE:
                    proptag2 = (proptag ^ PT_MV_UNICODE) | PT_UNICODE # funky!
                    restr = SContentRestriction(
                                FL_SUBSTRING | FL_IGNORECASE,
                                proptag,
                                SPropValue(proptag2, self.value)
                            )

                elif PROP_TYPE(proptag) in (PT_SHORT, PT_LONG, PT_LONGLONG, PT_FLOAT, PT_DOUBLE):
                    conv = float if PROP_TYPE(proptag) in (PT_FLOAT, PT_DOUBLE) else int
                    if '..' in self.value:
                        val1, val2 = self.value.split('..')
                        restr = SAndRestriction([
                            SPropertyRestriction(
                                RELOP_GE,
                                proptag,
                                SPropValue(proptag, conv(val1))
                            ),
                            SPropertyRestriction(
                                RELOP_LT,
                                proptag,
                                SPropValue(proptag, conv(val2))
                            )
                        ])
                    else:
                        restr = SPropertyRestriction(
                                    RELOP_EQ,
                                    proptag,
                                    SPropValue(proptag, conv(self.value))
                                )

                elif PROP_TYPE(proptag) == PT_SYSTIME:
                    if self.value == 'today':
                        d = datetime.datetime.now().date()
                        d2 = d + datetime.timedelta(days=1)
                        restr = _interval_restriction(proptag, d, d2)

                    elif self.value == 'yesterday':
                        d2 = datetime.datetime.now().date()
                        d = d2 - datetime.timedelta(days=1)
                        restr = _interval_restriction(proptag, d, d2)

                    elif self.value == 'this week':
                        d2 = datetime.datetime.now()
                        d = d2.date() - datetime.timedelta(days=d2.weekday())
                        restr = _interval_restriction(proptag, d, d2)

                    elif self.value == 'this month':
                        d2 = datetime.datetime.now()
                        d = d2.date() - datetime.timedelta(days=d2.day-1)
                        restr = _interval_restriction(proptag, d, d2)

                    elif self.value == 'last month':
                        now = datetime.datetime.now()
                        d2 = now.date() - datetime.timedelta(days=now.day-1)
                        d = (d2 - datetime.timedelta(days=1)).replace(day=1)
                        restr = _interval_restriction(proptag, d, d2)

                    elif self.value == 'this year':
                        d2 = datetime.datetime.now()
                        d = datetime.datetime(d2.year, 1, 1)
                        restr = _interval_restriction(proptag, d, d2)

                    elif self.value == 'last year':
                        now = datetime.datetime.now()
                        d2 = datetime.datetime(now.year, 1, 1)
                        d = datetime.datetime(d2.year-1, 1, 1)
                        restr = _interval_restriction(proptag, d, d2)

                    elif '..' in self.value:
                        date1, date2 = self.value.split('..') # TODO hours etc
                        d = dateutil.parser.parse(date1, dayfirst=True)
                        d2 = dateutil.parser.parse(date2, dayfirst=True)
                        restr = _interval_restriction(proptag, d, d2)

                    else:
                        d = dateutil.parser.parse(self.value, dayfirst=True) # TODO hours etc
                        d2 = d + datetime.timedelta(days=1)
                        restr = _interval_restriction(proptag, d, d2)

            # turn restriction into sub-restriction
            if subobj:
                if recipient_type is not None:
                    restr = SAndRestriction([
                        restr,
                        SPropertyRestriction(
                                RELOP_EQ,
                                PR_RECIPIENT_TYPE,
                                SPropValue(PR_RECIPIENT_TYPE, recipient_type)
                        )
                    ])
                restr = SSubRestriction(subobj, restr)

        else:
            defaults = [(store._name_id(proptag[:3]) | proptag[3])
                           if isinstance(proptag, tuple) else proptag
                               for proptag in DEFAULT_PROPTAGS[type_]]
            restr = SOrRestriction([
                       SContentRestriction(
                           FL_SUBSTRING | FL_IGNORECASE,
                           p,
                           SPropValue(p, self.value)
                       ) for p in defaults
                   ])

        if self.sign == '-':
            restr = SNotRestriction(restr)

        return restr
Ejemplo n.º 12
0
    def occurrences(self,
                    start=None,
                    end=None,
                    page_start=None,
                    page_limit=None,
                    order=None):
        count = 0
        pos = 0
        if start and end:
            startstamp = time.mktime(start.timetuple())
            endstamp = time.mktime(end.timetuple())

            # XXX use shortcuts and default type (database) to avoid MAPI snake wrestling
            NAMED_PROPS = [
                MAPINAMEID(PSETID_Appointment, MNID_ID, x)
                for x in (33285, 33293, 33294, 33315, 33301, 33333, 33334)
            ]
            ids = self.mapiobj.GetIDsFromNames(NAMED_PROPS, MAPI_CREATE)
            busystatus = ids[0] | PT_LONG
            startdate = ids[1] | PT_SYSTIME
            enddate = ids[2] | PT_SYSTIME
            recurring = ids[3] | PT_BOOLEAN
            all_day = ids[4] | PT_BOOLEAN
            clip_start = ids[5] | PT_SYSTIME
            clip_end = ids[6] | PT_SYSTIME

            restriction = SOrRestriction([
                # non-recurring: normal start/end
                SAndRestriction([
                    SPropertyRestriction(
                        RELOP_GT, enddate,
                        SPropValue(enddate, unixtime(startstamp))),
                    SPropertyRestriction(
                        RELOP_LT, startdate,
                        SPropValue(startdate, unixtime(endstamp))),
                ]),
                # recurring: range start/end
                SAndRestriction([
                    SPropertyRestriction(
                        RELOP_GT, clip_end,
                        SPropValue(clip_end, unixtime(startstamp))),
                    SPropertyRestriction(
                        RELOP_LT, clip_start,
                        SPropValue(clip_start, unixtime(endstamp))),
                ]),
                # exceptions: exception start/end in attachment
                SAndRestriction([
                    SPropertyRestriction(RELOP_EQ, recurring,
                                         SPropValue(recurring, True)),
                    SSubRestriction(
                        PR_MESSAGE_ATTACHMENTS,
                        SAndRestriction([
                            SPropertyRestriction(
                                RELOP_LT, PR_EXCEPTION_STARTTIME,
                                SPropValue(PR_EXCEPTION_STARTTIME,
                                           unixtime(endstamp))),
                            SPropertyRestriction(
                                RELOP_GT, PR_EXCEPTION_ENDTIME,
                                SPropValue(PR_EXCEPTION_ENDTIME,
                                           unixtime(startstamp))),
                        ]))
                ])
            ])

            columns = [
                PR_ENTRYID,
                PR_SUBJECT_W,  # watch out: table unicode data is max 255 chars
                PR_LAST_MODIFICATION_TIME,
                PR_CHANGE_KEY,
                startdate,
                enddate,
                recurring,
                all_day,
                busystatus
            ]

            table = Table(
                self.server,
                self.mapiobj,
                self.mapiobj.GetContentsTable(MAPI_DEFERRED_ERRORS),
                PR_CONTAINER_CONTENTS,
                columns=columns,
            )
            table.mapitable.Restrict(restriction, 0)
            for row in table.rows():
                item = _item.Item(self,
                                  entryid=row[0].value,
                                  content_flag=self.content_flag,
                                  cache=dict(zip(columns, row)))
                for occurrence in item.occurrences(start, end):
                    if page_start is None or pos >= page_start:
                        yield occurrence
                        count += 1
                    if page_limit is not None and count >= page_limit:
                        break
                    pos += 1
                if page_limit is not None and count >= page_limit:
                    break

        else:
            for item in self:
                for occurrence in item.occurrences(start, end):
                    if page_start is None or pos >= page_start:
                        yield occurrence
                        count += 1
                    if page_limit is not None and count >= page_limit:
                        break
                    pos += 1
                if page_limit is not None and count >= page_limit:
                    break