예제 #1
0
 def test_find_folders_with_restriction(self):
     # Exact match
     folders = list(
         FolderCollection(account=self.account, folders=[
             self.account.root
         ]).find_folders(q=Q(name='Top of Information Store')))
     self.assertEqual(len(folders), 1, sorted(f.name for f in folders))
     # Startswith
     folders = list(
         FolderCollection(account=self.account, folders=[
             self.account.root
         ]).find_folders(q=Q(name__startswith='Top of ')))
     self.assertEqual(len(folders), 1, sorted(f.name for f in folders))
     # Wrong case
     folders = list(
         FolderCollection(account=self.account, folders=[
             self.account.root
         ]).find_folders(q=Q(name__startswith='top of ')))
     self.assertEqual(len(folders), 0, sorted(f.name for f in folders))
     # Case insensitive
     folders = list(
         FolderCollection(account=self.account, folders=[
             self.account.root
         ]).find_folders(q=Q(name__istartswith='top of ')))
     self.assertEqual(len(folders), 1, sorted(f.name for f in folders))
예제 #2
0
    def test_queryset_copy(self):
        qs = QuerySet(folder_collection=FolderCollection(
            account=None, folders=[Inbox(root='XXX')]))
        qs.q = Q()
        qs.only_fields = ('a', 'b')
        qs.order_fields = ('c', 'd')
        qs.return_format = QuerySet.NONE

        # Initially, immutable items have the same id()
        new_qs = qs._copy_self()
        self.assertNotEqual(id(qs), id(new_qs))
        self.assertEqual(id(qs.folder_collection),
                         id(new_qs.folder_collection))
        self.assertEqual(id(qs._cache), id(new_qs._cache))
        self.assertEqual(qs._cache, new_qs._cache)
        self.assertNotEqual(id(qs.q), id(new_qs.q))
        self.assertEqual(qs.q, new_qs.q)
        self.assertEqual(id(qs.only_fields), id(new_qs.only_fields))
        self.assertEqual(qs.only_fields, new_qs.only_fields)
        self.assertEqual(id(qs.order_fields), id(new_qs.order_fields))
        self.assertEqual(qs.order_fields, new_qs.order_fields)
        self.assertEqual(id(qs.return_format), id(new_qs.return_format))
        self.assertEqual(qs.return_format, new_qs.return_format)

        # Set the same values, forcing a new id()
        new_qs.q = Q()
        new_qs.only_fields = ('a', 'b')
        new_qs.order_fields = ('c', 'd')
        new_qs.return_format = QuerySet.NONE

        self.assertNotEqual(id(qs), id(new_qs))
        self.assertEqual(id(qs.folder_collection),
                         id(new_qs.folder_collection))
        self.assertEqual(id(qs._cache), id(new_qs._cache))
        self.assertEqual(qs._cache, new_qs._cache)
        self.assertNotEqual(id(qs.q), id(new_qs.q))
        self.assertEqual(qs.q, new_qs.q)
        self.assertEqual(qs.only_fields, new_qs.only_fields)
        self.assertEqual(qs.order_fields, new_qs.order_fields)
        self.assertEqual(qs.return_format, new_qs.return_format)

        # Set the new values, forcing a new id()
        new_qs.q = Q(foo=5)
        new_qs.only_fields = ('c', 'd')
        new_qs.order_fields = ('e', 'f')
        new_qs.return_format = QuerySet.VALUES

        self.assertNotEqual(id(qs), id(new_qs))
        self.assertEqual(id(qs.folder_collection),
                         id(new_qs.folder_collection))
        self.assertEqual(id(qs._cache), id(new_qs._cache))
        self.assertEqual(qs._cache, new_qs._cache)
        self.assertNotEqual(id(qs.q), id(new_qs.q))
        self.assertNotEqual(qs.q, new_qs.q)
        self.assertNotEqual(id(qs.only_fields), id(new_qs.only_fields))
        self.assertNotEqual(qs.only_fields, new_qs.only_fields)
        self.assertNotEqual(id(qs.order_fields), id(new_qs.order_fields))
        self.assertNotEqual(qs.order_fields, new_qs.order_fields)
        self.assertNotEqual(id(qs.return_format), id(new_qs.return_format))
        self.assertNotEqual(qs.return_format, new_qs.return_format)
예제 #3
0
    def doStuff(credentials, yardAccount, account, done):
        #         while(True):
        account.inbox.refresh()
        yardAccount.inbox.refresh()
        print("Unread Emails in RNS Queue: " + str(account.inbox.unread_count))
        for item in account.inbox.filter(is_read=False,
                                         sender="*****@*****.**"):
            if ("Goods Released" in item.body):
                release(item.body, driver, account)
            item.flag = 1
            item.is_read = True
            #             else:
            #                 print("Unrecognized RNS Message: \n" + item.body)
            #                 popUpOK("Unrecognized RNS Message, see inbox or\nconsole window for details",16,top)
            #                 item.is_read=True
            #                 item.flag=2
            #             item.flag=1
            #             item.is_read=True
            item.save()
        q = (Q(subject__contains="Back Haul") | Q(subject__icontains="BH ")
             ) & Q(sender="*****@*****.**") & ~Q(flag=1)
        for item in yardAccount.inbox.filter(q):
            updateInfo(item.body, driver, done)
            #             print(item.flag)
            item.flag = 1
            item.save()
#             sleep(30)
#             top.after(3000, doStuff())
        print("Done\n")
        top.after(60000, doStuff, credentials, yardAccount, account, done)
예제 #4
0
    def test_q(self):
        tz = EWSTimeZone.timezone('Europe/Copenhagen')
        start = tz.localize(EWSDateTime(1950, 9, 26, 8, 0, 0))
        end = tz.localize(EWSDateTime(2050, 9, 26, 11, 0, 0))
        result = '''\
<m:Restriction xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
    <t:And xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
        <t:Or>
            <t:Contains ContainmentMode="Substring" ContainmentComparison="Exact">
                <t:FieldURI FieldURI="item:Categories"/>
                <t:Constant Value="FOO"/>
            </t:Contains>
            <t:Contains ContainmentMode="Substring" ContainmentComparison="Exact">
                <t:FieldURI FieldURI="item:Categories"/>
                <t:Constant Value="BAR"/>
            </t:Contains>
        </t:Or>
        <t:IsGreaterThan>
            <t:FieldURI FieldURI="calendar:End"/>
            <t:FieldURIOrConstant>
                <t:Constant Value="1950-09-26T08:00:00+01:00"/>
            </t:FieldURIOrConstant>
        </t:IsGreaterThan>
        <t:IsLessThan>
            <t:FieldURI FieldURI="calendar:Start"/>
            <t:FieldURIOrConstant>
                <t:Constant Value="2050-09-26T11:00:00+01:00"/>
            </t:FieldURIOrConstant>
        </t:IsLessThan>
    </t:And>
</m:Restriction>'''
        q = Q(Q(categories__contains='FOO') | Q(categories__contains='BAR'),
              start__lt=end,
              end__gt=start)
        r = Restriction(q, folders=[Calendar()], applies_to=Restriction.ITEMS)
        self.assertEqual(str(r),
                         ''.join(l.lstrip() for l in result.split('\n')))
        # Test empty Q
        q = Q()
        self.assertEqual(
            q.to_xml(folders=[Calendar()],
                     version=None,
                     applies_to=Restriction.ITEMS), None)
        with self.assertRaises(ValueError):
            Restriction(q, folders=[Calendar()], applies_to=Restriction.ITEMS)
        # Test validation
        with self.assertRaises(ValueError):
            Q(datetime_created__range=(1, ))  # Must have exactly 2 args
        with self.assertRaises(ValueError):
            Q(datetime_created__range=(1, 2, 3))  # Must have exactly 2 args
        with self.assertRaises(TypeError):
            Q(datetime_created=Build(15, 1)).clean()  # Must be serializable
        with self.assertRaises(ValueError):
            Q(datetime_created=EWSDateTime(2017, 1,
                                           1)).clean()  # Must be tz-aware date
        with self.assertRaises(ValueError):
            Q(categories__contains=[[1, 2], [3, 4]
                                    ]).clean()  # Must be single value
예제 #5
0
 def test_q_expr(self):
     self.assertEqual(Q().expr(), None)
     self.assertEqual((~Q()).expr(), None)
     self.assertEqual(Q(x=5).expr(), 'x == 5')
     self.assertEqual((~Q(x=5)).expr(), 'x != 5')
     q = (Q(b__contains='a', x__contains=5)
          | Q(~Q(a__contains='c'), f__gt=3, c=6)) & ~Q(y=9, z__contains='b')
     self.assertEqual(
         str(q),  # str() calls expr()
         "((b contains 'a' AND x contains 5) OR (NOT a contains 'c' AND c == 6 AND f > 3)) "
         "AND NOT (y == 9 AND z contains 'b')")
     self.assertEqual(
         repr(q),
         "Q('AND', Q('OR', Q('AND', Q(b contains 'a'), Q(x contains 5)), Q('AND', Q('NOT', Q(a contains 'c')), "
         "Q(c == 6), Q(f > 3))), Q('NOT', Q('AND', Q(y == 9), Q(z contains 'b'))))"
     )
     # Test simulated IN expression
     in_q = Q(foo__in=[1, 2, 3])
     self.assertEqual(in_q.conn_type, Q.OR)
     self.assertEqual(len(in_q.children), 3)
예제 #6
0
    def test_q_querystring(self):
        self.assertEqual(Q('this is a QS').expr(), 'this is a QS')
        self.assertEqual(Q(Q('this is a QS')), Q('this is a QS'))
        self.assertEqual(Q(Q(Q(Q('this is a QS')))), Q('this is a QS'))

        with self.assertRaises(ValueError):
            Q('this is a QS') & Q(foo='bar')
        with self.assertRaises(ValueError):
            Q(5)
예제 #7
0
    def test_q_simplification(self):
        self.assertEqual(Q(foo='bar') & Q(), Q(foo='bar'))
        self.assertEqual(Q() & Q(foo='bar'), Q(foo='bar'))

        self.assertEqual(Q('foo') & Q(), Q('foo'))
        self.assertEqual(Q() & Q('foo'), Q('foo'))
예제 #8
0
    def test_q_never(self):
        # Tests Q with conn_type NEVER. This is for cases where the user makes queries that would return an empty
        # result, but the server does not support this type of query. The only example so far is 'foo__in=[]' which
        # should always match nothing.
        self.assertEqual(
            Q(foo__in=[]), Q(conn_type=Q.NEVER)
        )  # __in with empty sequence should translate to NEVER
        self.assertTrue(Q(foo__in=[]).is_never())  # Test the flag
        self.assertEqual(~Q(foo__in=[]),
                         Q())  # Negation should translate to the no-op
        self.assertTrue(
            ~Q(foo__in=[]).is_empty())  # Negation should translate to a no-op

        # Test in combination with AND and OR
        self.assertEqual(Q(foo__in=[], bar='baz'),
                         Q(conn_type=Q.NEVER))  # NEVER removes all other args
        self.assertEqual(Q(foo__in=[]) & Q(bar='baz'),
                         Q(conn_type=Q.NEVER))  # NEVER removes all other args
        self.assertEqual(Q(foo__in=[]) | Q(bar='baz'),
                         Q(bar='baz'))  # OR removes all 'never' args
예제 #9
0
 def test_q_failures(self):
     with self.assertRaises(ValueError):
         # Invalid value
         Q(foo=None).clean(version=Version(build=EXCHANGE_2007))
예제 #10
0
 def test_q_boolean_ops(self):
     self.assertEqual((Q(foo=5) & Q(foo=6)).conn_type, Q.AND)
     self.assertEqual((Q(foo=5) | Q(foo=6)).conn_type, Q.OR)
예제 #11
0
    def test_q_inversion(self):
        version = Version(build=EXCHANGE_2007)
        account = mock_account(version=version,
                               protocol=mock_protocol(
                                   version=version,
                                   service_endpoint='example.com'))
        root = Root(account=account)
        self.assertEqual((~Q(foo=5)).op, Q.NE)
        self.assertEqual((~Q(foo__not=5)).op, Q.EQ)
        self.assertEqual((~Q(foo__lt=5)).op, Q.GTE)
        self.assertEqual((~Q(foo__lte=5)).op, Q.GT)
        self.assertEqual((~Q(foo__gt=5)).op, Q.LTE)
        self.assertEqual((~Q(foo__gte=5)).op, Q.LT)
        # Test not not Q on a non-leaf
        self.assertEqual(Q(foo__contains=('bar', 'baz')).conn_type, Q.AND)
        self.assertEqual((~Q(foo__contains=('bar', 'baz'))).conn_type, Q.NOT)
        self.assertEqual((~~Q(foo__contains=('bar', 'baz'))).conn_type, Q.AND)
        self.assertEqual(Q(foo__contains=('bar', 'baz')),
                         ~~Q(foo__contains=('bar', 'baz')))
        # Test generated XML of 'Not' statement when there is only one child. Skip 't:And' between 't:Not' and 't:Or'.
        result = '''\
<m:Restriction xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
    <t:Not xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
        <t:Or>
            <t:IsEqualTo>
                <t:FieldURI FieldURI="item:Subject"/>
                <t:FieldURIOrConstant>
                    <t:Constant Value="bar"/>
                </t:FieldURIOrConstant>
            </t:IsEqualTo>
            <t:IsEqualTo>
                <t:FieldURI FieldURI="item:Subject"/>
                <t:FieldURIOrConstant>
                    <t:Constant Value="baz"/>
                </t:FieldURIOrConstant>
            </t:IsEqualTo>
        </t:Or>
    </t:Not>
</m:Restriction>'''
        q = ~(Q(subject='bar') | Q(subject='baz'))
        self.assertEqual(
            xml_to_str(
                q.to_xml(folders=[Calendar(root=root)],
                         version=version,
                         applies_to=Restriction.ITEMS)),
            ''.join(s.lstrip() for s in result.split('\n')))
예제 #12
0
 def test_magic(self):
     self.assertEqual(str(Q()), 'Q()')
예제 #13
0
 def test_q_failures(self):
     with self.assertRaises(ValueError):
         # Invalid value
         Q(foo=None).clean()
예제 #14
0
# WARNING: Filtering on the 'body' field is not fully supported by EWS. There seems to be a window
# before some internal search index is populated where case-sensitive or case-insensitive filtering
# for substrings in the body element incorrectly returns an empty result, and sometimes the result
# stays empty.

# filter() also supports EWS QueryStrings. Just pass the string to filter(). QueryStrings cannot
# be combined with other filters. We make no attempt at validating the syntax of the QueryString
# - we just pass the string verbatim to EWS.
#
# Read more about the QueryString syntax here:
# https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/querystring-querystringtype
a.inbox.filter('subject:XXX')

# filter() also supports Q objects that are modeled after Django Q objects, for building complex
# boolean logic search expressions.
q = (Q(subject__iexact='foo')
     | Q(subject__contains='bar')) & ~Q(subject__startswith='baz')
a.inbox.filter(q)

# In this example, we filter by categories so we only get the items created by us.
a.calendar.filter(
    start__lt=a.default_timezone.localize(EWSDateTime(2019, 1, 1)),
    end__gt=a.default_timezone.localize(EWSDateTime(2019, 1, 31)),
    categories__contains=['foo', 'bar'],
)

# By default, EWS returns only the master recurring item. If you want recurring calendar
# items to be expanded, use calendar.view(start=..., end=...) instead.
items = a.calendar.view(
    start=a.default_timezone.localize(EWSDateTime(2019, 1, 31)),
    end=a.default_timezone.localize(EWSDateTime(2019, 1, 31)) +