Skip to content

Commit

Permalink
Bump version
Browse files Browse the repository at this point in the history
  • Loading branch information
ecederstrand committed May 29, 2021
1 parent 45da45f commit 2beab63
Show file tree
Hide file tree
Showing 25 changed files with 1,003 additions and 199 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Change Log
==========

HEAD
----
4.4.0
-----
- Add `Folder.move()` to move folders to a different parent folder.


Expand Down
24 changes: 18 additions & 6 deletions docs/exchangelib/ewsdatetime.html
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,12 @@ <h1 class="title">Module <code>exchangelib.ewsdatetime</code></h1>

@classmethod
def from_dateutil(cls, tz):
key = &#39;/&#39;.join(tz._filename.split(&#39;/&#39;)[-2:])
return cls(key)
# Objects returned by dateutil.tz.tzlocal() and dateutil.tz.gettz() are not supported. They
# don&#39;t contain enough information to reliably match them with a CLDR timezone.
if hasattr(tz, &#39;_filename&#39;):
key = &#39;/&#39;.join(tz._filename.split(&#39;/&#39;)[-2:])
return cls(key)
return cls(tz.tzname(datetime.datetime.now()))

@classmethod
def from_zoneinfo(cls, tz):
Expand Down Expand Up @@ -914,8 +918,12 @@ <h3>Methods</h3>

@classmethod
def from_dateutil(cls, tz):
key = &#39;/&#39;.join(tz._filename.split(&#39;/&#39;)[-2:])
return cls(key)
# Objects returned by dateutil.tz.tzlocal() and dateutil.tz.gettz() are not supported. They
# don&#39;t contain enough information to reliably match them with a CLDR timezone.
if hasattr(tz, &#39;_filename&#39;):
key = &#39;/&#39;.join(tz._filename.split(&#39;/&#39;)[-2:])
return cls(key)
return cls(tz.tzname(datetime.datetime.now()))

@classmethod
def from_zoneinfo(cls, tz):
Expand Down Expand Up @@ -1008,8 +1016,12 @@ <h3>Static methods</h3>
</summary>
<pre><code class="python">@classmethod
def from_dateutil(cls, tz):
key = &#39;/&#39;.join(tz._filename.split(&#39;/&#39;)[-2:])
return cls(key)</code></pre>
# Objects returned by dateutil.tz.tzlocal() and dateutil.tz.gettz() are not supported. They
# don&#39;t contain enough information to reliably match them with a CLDR timezone.
if hasattr(tz, &#39;_filename&#39;):
key = &#39;/&#39;.join(tz._filename.split(&#39;/&#39;)[-2:])
return cls(key)
return cls(tz.tzname(datetime.datetime.now()))</code></pre>
</details>
</dd>
<dt id="exchangelib.ewsdatetime.EWSTimeZone.from_ms_id"><code class="name flex">
Expand Down
54 changes: 49 additions & 5 deletions docs/exchangelib/folders/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ <h1 class="title">Module <code>exchangelib.folders.base</code></h1>
from ..queryset import SearchableMixIn, DoesNotExist
from ..services import CreateFolder, UpdateFolder, DeleteFolder, EmptyFolder, GetUserConfiguration, \
CreateUserConfiguration, UpdateUserConfiguration, DeleteUserConfiguration, SubscribeToPush, SubscribeToPull, \
Unsubscribe, GetEvents, GetStreamingEvents
Unsubscribe, GetEvents, GetStreamingEvents, MoveFolder
from ..services.get_user_configuration import ALL
from ..util import TNS, require_id
from ..version import Version, EXCHANGE_2007_SP1, EXCHANGE_2010
Expand Down Expand Up @@ -372,7 +372,17 @@ <h1 class="title">Module <code>exchangelib.folders.base</code></h1>
# Don&#39;t check changekey value. It may not change on no-op updates
self.changekey = changekey
self.root.update_folder(self) # Update the folder in the cache
return None
return self

def move(self, to_folder):
res = MoveFolder(account=self.account).get(folders=[self], to_folder=to_folder)
folder_id, changekey = res.id, res.changekey
if self.id != folder_id:
raise ValueError(&#39;ID mismatch&#39;)
# Don&#39;t check changekey value. It may not change on no-op moves
self.changekey = changekey
self.parent_folder_id = ParentFolderId(id=to_folder.id, changekey=to_folder.changekey)
self.root.update_folder(self) # Update the folder in the cache

def delete(self, delete_type=HARD_DELETE):
if delete_type not in DELETE_TYPE_CHOICES:
Expand Down Expand Up @@ -494,6 +504,7 @@ <h1 class="title">Module <code>exchangelib.folders.base</code></h1>
# Apparently, the changekey may get updated
for f in self.FIELDS:
setattr(self, f.name, getattr(fresh_folder, f.name))
return self

@require_id
def get_user_configuration(self, name, properties=ALL):
Expand Down Expand Up @@ -1246,7 +1257,17 @@ <h2 class="section-title" id="header-classes">Classes</h2>
# Don&#39;t check changekey value. It may not change on no-op updates
self.changekey = changekey
self.root.update_folder(self) # Update the folder in the cache
return None
return self

def move(self, to_folder):
res = MoveFolder(account=self.account).get(folders=[self], to_folder=to_folder)
folder_id, changekey = res.id, res.changekey
if self.id != folder_id:
raise ValueError(&#39;ID mismatch&#39;)
# Don&#39;t check changekey value. It may not change on no-op moves
self.changekey = changekey
self.parent_folder_id = ParentFolderId(id=to_folder.id, changekey=to_folder.changekey)
self.root.update_folder(self) # Update the folder in the cache

def delete(self, delete_type=HARD_DELETE):
if delete_type not in DELETE_TYPE_CHOICES:
Expand Down Expand Up @@ -1368,6 +1389,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
# Apparently, the changekey may get updated
for f in self.FIELDS:
setattr(self, f.name, getattr(fresh_folder, f.name))
return self

@require_id
def get_user_configuration(self, name, properties=ALL):
Expand Down Expand Up @@ -2244,6 +2266,26 @@ <h3>Methods</h3>
return FolderCollection(account=self.account, folders=self._glob(pattern))</code></pre>
</details>
</dd>
<dt id="exchangelib.folders.base.BaseFolder.move"><code class="name flex">
<span>def <span class="ident">move</span></span>(<span>self, to_folder)</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def move(self, to_folder):
res = MoveFolder(account=self.account).get(folders=[self], to_folder=to_folder)
folder_id, changekey = res.id, res.changekey
if self.id != folder_id:
raise ValueError(&#39;ID mismatch&#39;)
# Don&#39;t check changekey value. It may not change on no-op moves
self.changekey = changekey
self.parent_folder_id = ParentFolderId(id=to_folder.id, changekey=to_folder.changekey)
self.root.update_folder(self) # Update the folder in the cache</code></pre>
</details>
</dd>
<dt id="exchangelib.folders.base.BaseFolder.none"><code class="name flex">
<span>def <span class="ident">none</span></span>(<span>self)</span>
</code></dt>
Expand Down Expand Up @@ -2358,7 +2400,8 @@ <h3>Methods</h3>
raise ValueError(&#39;ID mismatch&#39;)
# Apparently, the changekey may get updated
for f in self.FIELDS:
setattr(self, f.name, getattr(fresh_folder, f.name))</code></pre>
setattr(self, f.name, getattr(fresh_folder, f.name))
return self</code></pre>
</details>
</dd>
<dt id="exchangelib.folders.base.BaseFolder.save"><code class="name flex">
Expand Down Expand Up @@ -2401,7 +2444,7 @@ <h3>Methods</h3>
# Don&#39;t check changekey value. It may not change on no-op updates
self.changekey = changekey
self.root.update_folder(self) # Update the folder in the cache
return None</code></pre>
return self</code></pre>
</details>
</dd>
<dt id="exchangelib.folders.base.BaseFolder.streaming_subscription"><code class="name flex">
Expand Down Expand Up @@ -3389,6 +3432,7 @@ <h4><code><a title="exchangelib.folders.base.BaseFolder" href="#exchangelib.fold
<li><code><a title="exchangelib.folders.base.BaseFolder.item_model_from_tag" href="#exchangelib.folders.base.BaseFolder.item_model_from_tag">item_model_from_tag</a></code></li>
<li><code><a title="exchangelib.folders.base.BaseFolder.item_sync_state" href="#exchangelib.folders.base.BaseFolder.item_sync_state">item_sync_state</a></code></li>
<li><code><a title="exchangelib.folders.base.BaseFolder.localized_names" href="#exchangelib.folders.base.BaseFolder.localized_names">localized_names</a></code></li>
<li><code><a title="exchangelib.folders.base.BaseFolder.move" href="#exchangelib.folders.base.BaseFolder.move">move</a></code></li>
<li><code><a title="exchangelib.folders.base.BaseFolder.name" href="#exchangelib.folders.base.BaseFolder.name">name</a></code></li>
<li><code><a title="exchangelib.folders.base.BaseFolder.none" href="#exchangelib.folders.base.BaseFolder.none">none</a></code></li>
<li><code><a title="exchangelib.folders.base.BaseFolder.normalize_fields" href="#exchangelib.folders.base.BaseFolder.normalize_fields">normalize_fields</a></code></li>
Expand Down
39 changes: 36 additions & 3 deletions docs/exchangelib/folders/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1229,7 +1229,17 @@ <h3>Inherited members</h3>
# Don&#39;t check changekey value. It may not change on no-op updates
self.changekey = changekey
self.root.update_folder(self) # Update the folder in the cache
return None
return self

def move(self, to_folder):
res = MoveFolder(account=self.account).get(folders=[self], to_folder=to_folder)
folder_id, changekey = res.id, res.changekey
if self.id != folder_id:
raise ValueError(&#39;ID mismatch&#39;)
# Don&#39;t check changekey value. It may not change on no-op moves
self.changekey = changekey
self.parent_folder_id = ParentFolderId(id=to_folder.id, changekey=to_folder.changekey)
self.root.update_folder(self) # Update the folder in the cache

def delete(self, delete_type=HARD_DELETE):
if delete_type not in DELETE_TYPE_CHOICES:
Expand Down Expand Up @@ -1351,6 +1361,7 @@ <h3>Inherited members</h3>
# Apparently, the changekey may get updated
for f in self.FIELDS:
setattr(self, f.name, getattr(fresh_folder, f.name))
return self

@require_id
def get_user_configuration(self, name, properties=ALL):
Expand Down Expand Up @@ -2227,6 +2238,26 @@ <h3>Methods</h3>
return FolderCollection(account=self.account, folders=self._glob(pattern))</code></pre>
</details>
</dd>
<dt id="exchangelib.folders.BaseFolder.move"><code class="name flex">
<span>def <span class="ident">move</span></span>(<span>self, to_folder)</span>
</code></dt>
<dd>
<div class="desc"></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">def move(self, to_folder):
res = MoveFolder(account=self.account).get(folders=[self], to_folder=to_folder)
folder_id, changekey = res.id, res.changekey
if self.id != folder_id:
raise ValueError(&#39;ID mismatch&#39;)
# Don&#39;t check changekey value. It may not change on no-op moves
self.changekey = changekey
self.parent_folder_id = ParentFolderId(id=to_folder.id, changekey=to_folder.changekey)
self.root.update_folder(self) # Update the folder in the cache</code></pre>
</details>
</dd>
<dt id="exchangelib.folders.BaseFolder.none"><code class="name flex">
<span>def <span class="ident">none</span></span>(<span>self)</span>
</code></dt>
Expand Down Expand Up @@ -2341,7 +2372,8 @@ <h3>Methods</h3>
raise ValueError(&#39;ID mismatch&#39;)
# Apparently, the changekey may get updated
for f in self.FIELDS:
setattr(self, f.name, getattr(fresh_folder, f.name))</code></pre>
setattr(self, f.name, getattr(fresh_folder, f.name))
return self</code></pre>
</details>
</dd>
<dt id="exchangelib.folders.BaseFolder.save"><code class="name flex">
Expand Down Expand Up @@ -2384,7 +2416,7 @@ <h3>Methods</h3>
# Don&#39;t check changekey value. It may not change on no-op updates
self.changekey = changekey
self.root.update_folder(self) # Update the folder in the cache
return None</code></pre>
return self</code></pre>
</details>
</dd>
<dt id="exchangelib.folders.BaseFolder.streaming_subscription"><code class="name flex">
Expand Down Expand Up @@ -10362,6 +10394,7 @@ <h4><code><a title="exchangelib.folders.BaseFolder" href="#exchangelib.folders.B
<li><code><a title="exchangelib.folders.BaseFolder.item_model_from_tag" href="#exchangelib.folders.BaseFolder.item_model_from_tag">item_model_from_tag</a></code></li>
<li><code><a title="exchangelib.folders.BaseFolder.item_sync_state" href="#exchangelib.folders.BaseFolder.item_sync_state">item_sync_state</a></code></li>
<li><code><a title="exchangelib.folders.BaseFolder.localized_names" href="#exchangelib.folders.BaseFolder.localized_names">localized_names</a></code></li>
<li><code><a title="exchangelib.folders.BaseFolder.move" href="#exchangelib.folders.BaseFolder.move">move</a></code></li>
<li><code><a title="exchangelib.folders.BaseFolder.name" href="#exchangelib.folders.BaseFolder.name">name</a></code></li>
<li><code><a title="exchangelib.folders.BaseFolder.none" href="#exchangelib.folders.BaseFolder.none">none</a></code></li>
<li><code><a title="exchangelib.folders.BaseFolder.normalize_fields" href="#exchangelib.folders.BaseFolder.normalize_fields">normalize_fields</a></code></li>
Expand Down
50 changes: 42 additions & 8 deletions docs/exchangelib/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ <h1 class="title">Package <code>exchangelib</code></h1>
from .transport import BASIC, DIGEST, NTLM, GSSAPI, SSPI, OAUTH2, CBA
from .version import Build, Version

__version__ = &#39;4.3.0&#39;
__version__ = &#39;4.4.0&#39;

__all__ = [
&#39;__version__&#39;,
Expand Down Expand Up @@ -5558,8 +5558,12 @@ <h3>Methods</h3>

@classmethod
def from_dateutil(cls, tz):
key = &#39;/&#39;.join(tz._filename.split(&#39;/&#39;)[-2:])
return cls(key)
# Objects returned by dateutil.tz.tzlocal() and dateutil.tz.gettz() are not supported. They
# don&#39;t contain enough information to reliably match them with a CLDR timezone.
if hasattr(tz, &#39;_filename&#39;):
key = &#39;/&#39;.join(tz._filename.split(&#39;/&#39;)[-2:])
return cls(key)
return cls(tz.tzname(datetime.datetime.now()))

@classmethod
def from_zoneinfo(cls, tz):
Expand Down Expand Up @@ -5652,8 +5656,12 @@ <h3>Static methods</h3>
</summary>
<pre><code class="python">@classmethod
def from_dateutil(cls, tz):
key = &#39;/&#39;.join(tz._filename.split(&#39;/&#39;)[-2:])
return cls(key)</code></pre>
# Objects returned by dateutil.tz.tzlocal() and dateutil.tz.gettz() are not supported. They
# don&#39;t contain enough information to reliably match them with a CLDR timezone.
if hasattr(tz, &#39;_filename&#39;):
key = &#39;/&#39;.join(tz._filename.split(&#39;/&#39;)[-2:])
return cls(key)
return cls(tz.tzname(datetime.datetime.now()))</code></pre>
</details>
</dd>
<dt id="exchangelib.EWSTimeZone.from_ms_id"><code class="name flex">
Expand Down Expand Up @@ -12081,7 +12089,7 @@ <h3>Inherited members</h3>
property_id = 3
property_type = 'Binary'</p>
<p>CalendarItem.register('global_object_id', GlobalObjectId)
account.calendar.filter(global_object_id=GlobalObjectId(UID('261cbc18-1f65-5a0a-bd11-23b1e224cc2f')))</p></div>
account.calendar.filter(global_object_id=UID('261cbc18-1f65-5a0a-bd11-23b1e224cc2f'))</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
Expand All @@ -12095,7 +12103,7 @@ <h3>Inherited members</h3>
property_type = &#39;Binary&#39;

CalendarItem.register(&#39;global_object_id&#39;, GlobalObjectId)
account.calendar.filter(global_object_id=GlobalObjectId(UID(&#39;261cbc18-1f65-5a0a-bd11-23b1e224cc2f&#39;)))
account.calendar.filter(global_object_id=UID(&#39;261cbc18-1f65-5a0a-bd11-23b1e224cc2f&#39;))
&#34;&#34;&#34;

_HEADER = binascii.hexlify(bytearray((
Expand Down Expand Up @@ -12126,12 +12134,35 @@ <h3>Inherited members</h3>
encoding = b&#39;&#39;.join([
cls._HEADER, cls._EXCEPTION_REPLACEMENT_TIME, cls._CREATION_TIME, cls._RESERVED, length, payload
])
return super().__new__(cls, codecs.decode(encoding, &#39;hex&#39;))</code></pre>
return super().__new__(cls, codecs.decode(encoding, &#39;hex&#39;))

@classmethod
def to_global_object_id(cls, uid):
&#34;&#34;&#34;Converts a UID as returned by EWS to GlobalObjectId format&#34;&#34;&#34;
return binascii.unhexlify(uid)</code></pre>
</details>
<h3>Ancestors</h3>
<ul class="hlist">
<li>builtins.bytes</li>
</ul>
<h3>Static methods</h3>
<dl>
<dt id="exchangelib.UID.to_global_object_id"><code class="name flex">
<span>def <span class="ident">to_global_object_id</span></span>(<span>uid)</span>
</code></dt>
<dd>
<div class="desc"><p>Converts a UID as returned by EWS to GlobalObjectId format</p></div>
<details class="source">
<summary>
<span>Expand source code</span>
</summary>
<pre><code class="python">@classmethod
def to_global_object_id(cls, uid):
&#34;&#34;&#34;Converts a UID as returned by EWS to GlobalObjectId format&#34;&#34;&#34;
return binascii.unhexlify(uid)</code></pre>
</details>
</dd>
</dl>
</dd>
<dt id="exchangelib.Version"><code class="flex name class">
<span>class <span class="ident">Version</span></span>
Expand Down Expand Up @@ -13100,6 +13131,9 @@ <h4><code><a title="exchangelib.TentativelyAcceptItem" href="#exchangelib.Tentat
</li>
<li>
<h4><code><a title="exchangelib.UID" href="#exchangelib.UID">UID</a></code></h4>
<ul class="">
<li><code><a title="exchangelib.UID.to_global_object_id" href="#exchangelib.UID.to_global_object_id">to_global_object_id</a></code></li>
</ul>
</li>
<li>
<h4><code><a title="exchangelib.Version" href="#exchangelib.Version">Version</a></code></h4>
Expand Down
Loading

0 comments on commit 2beab63

Please sign in to comment.