Skip to content

Commit 4018f95

Browse files
Merge from 'develop'
2 parents 7751aaa + b2587a1 commit 4018f95

37 files changed

+768
-84
lines changed

DracoonSdk/DracoonSdk.csproj

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
</Reference>
5252
<Reference Include="System" />
5353
<Reference Include="System.Core" />
54+
<Reference Include="System.Drawing" />
5455
<Reference Include="System.Net.Http.WebRequest" />
5556
<Reference Include="System.Web" />
5657
<Reference Include="System.Xml.Linq" />
@@ -86,6 +87,7 @@
8687
<Compile Include="SdkInternal\ApiModel\Requests\ApiMoveNode.cs" />
8788
<Compile Include="SdkInternal\ApiModel\Requests\ApiSetUserFileKeysRequest.cs" />
8889
<Compile Include="SdkInternal\ApiModel\Nodes\ApiUploadChunkResult.cs" />
90+
<Compile Include="SdkInternal\ApiModel\User\ApiAvatarInfo.cs" />
8991
<Compile Include="SdkInternal\ApiModel\User\ApiUserIdFileId.cs" />
9092
<Compile Include="SdkInternal\ApiModel\User\ApiUserIdPublicKey.cs" />
9193
<Compile Include="SdkInternal\ApiModel\Requests\ApiCompleteFileUpload.cs" />
@@ -127,6 +129,7 @@
127129
<Compile Include="SdkInternal\DracoonRequestExecuter.cs" />
128130
<Compile Include="SdkInternal\DracoonServerImpl.cs" />
129131
<Compile Include="SdkInternal\DracoonSharesImpl.cs" />
132+
<Compile Include="SdkInternal\DracoonUsersImpl.cs" />
130133
<Compile Include="SdkInternal\EncFileDownload.cs" />
131134
<Compile Include="SdkInternal\EncFileUpload.cs" />
132135
<Compile Include="SdkInternal\FileDownload.cs" />
@@ -169,6 +172,7 @@
169172
<Compile Include="SdkPublic\Filter\FilterParam.cs" />
170173
<Compile Include="SdkPublic\Filter\SpecificFilters\GetUploadSharesFilter.cs" />
171174
<Compile Include="SdkPublic\Filter\SpecificFilters\SearchNodesFilter.cs" />
175+
<Compile Include="SdkPublic\Model\AvatarInfo.cs" />
172176
<Compile Include="SdkPublic\Model\Classification.cs" />
173177
<Compile Include="SdkPublic\Model\CustomerAccount.cs" />
174178
<Compile Include="SdkPublic\Model\RecycleBinItem.cs" />
@@ -219,30 +223,32 @@
219223
<Compile Include="SdkPublic\SdkPublicInterfaces\INodes.cs" />
220224
<Compile Include="SdkPublic\SdkPublicInterfaces\IServer.cs" />
221225
<Compile Include="SdkPublic\SdkPublicInterfaces\IShares.cs" />
226+
<Compile Include="SdkPublic\SdkPublicInterfaces\IUsers.cs" />
222227
<Compile Include="SdkPublic\Sort\DracoonSort.cs" />
223228
<Compile Include="SdkPublic\Sort\DracoonSortOrder.cs" />
224229
<Compile Include="SdkPublic\Sort\SpecificSort\GeneralSort.cs" />
225230
<Compile Include="SdkPublic\Sort\SpecificSort\SearchNodesSort.cs" />
231+
<Compile Include="SdkPublic\Sort\SpecificSort\SharesSort.cs" />
226232
</ItemGroup>
227233
<ItemGroup>
228234
<None Include="packages.config" />
229235
</ItemGroup>
230236
<ItemGroup>
231-
<Content Include="SdkPublic\Error\ErrorDoc.xml" />
232-
<Content Include="SdkPublic\Filter\FilterDoc.xml" />
233-
<Content Include="SdkPublic\Filter\SpecificFilters\SpecificFilterDoc.xml">
237+
<None Include="SdkPublic\Error\ErrorDoc.xml" />
238+
<None Include="SdkPublic\Filter\FilterDoc.xml" />
239+
<None Include="SdkPublic\Filter\SpecificFilters\SpecificFilterDoc.xml">
234240
<SubType>Designer</SubType>
235-
</Content>
236-
<Content Include="SdkPublic\Model\ModelDoc.xml">
241+
</None>
242+
<None Include="SdkPublic\Model\ModelDoc.xml">
237243
<SubType>Designer</SubType>
238-
</Content>
239-
<Content Include="SdkPublic\Model\UserRequests\UserRequestsDoc.xml">
244+
</None>
245+
<None Include="SdkPublic\Model\UserRequests\UserRequestsDoc.xml">
240246
<SubType>Designer</SubType>
241-
</Content>
242-
<Content Include="SdkPublic\SdkPublicDoc.xml" />
243-
<Content Include="SdkPublic\SdkPublicInterfaces\SdkPublicInterfacesDoc.xml" />
244-
<Content Include="SdkPublic\Sort\Sort.xml" />
245-
<Content Include="SdkPublic\Sort\SpecificSort\SpecificSort.xml" />
247+
</None>
248+
<None Include="SdkPublic\SdkPublicDoc.xml" />
249+
<None Include="SdkPublic\SdkPublicInterfaces\SdkPublicInterfacesDoc.xml" />
250+
<None Include="SdkPublic\Sort\Sort.xml" />
251+
<None Include="SdkPublic\Sort\SpecificSort\SpecificSort.xml" />
246252
</ItemGroup>
247253
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
248254
</Project>

DracoonSdk/DracoonSdk.nuspec

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
<metadata>
44
<id>$id$</id>
55
<version>$version$</version>
6-
<title>Dracoon SDK</title>
7-
<authors>dracoon developers</authors>
6+
<title>DRACOON SDK</title>
7+
<authors>DRACOON developers</authors>
88
<owners>dracoon</owners>
99
<licenseUrl>https://www.apache.org/licenses/LICENSE-2.0.txt</licenseUrl>
1010
<projectUrl>https://github.com/dracoon/dracoon-csharp-sdk</projectUrl>
1111
<iconUrl>https://raw.githubusercontent.com/dracoon/dracoon-csharp-sdk/master/DracoonSdk/DracoonSdk_NugetImage.png</iconUrl>
1212
<requireLicenseAcceptance>false</requireLicenseAcceptance>
13-
<description>The Dracoon SDK for C#.</description>
14-
<copyright>Copyright ©2018 Dracoon GmbH</copyright>
15-
<tags>dracoon rest api sdk</tags>
13+
<description>The DRACOON SDK for C#.</description>
14+
<copyright>Copyright ©2018 DRACOON GmbH</copyright>
15+
<tags>DRACOON rest api sdk</tags>
1616
<dependencies>
1717
<dependency id="Dracoon.Crypto.Sdk" version="1.0.2"/>
1818
<dependency id="Newtonsoft.Json" version="11.0.2"/>

DracoonSdk/Properties/AssemblyInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,5 @@
3434
// [assembly: AssemblyVersion("1.0.*")]
3535
[assembly: AssemblyVersion("1.0.0.0")]
3636
[assembly: AssemblyFileVersion("1.0.0.0")]
37-
[assembly: AssemblyInformationalVersion("1.0.0-beta1")]
37+
[assembly: AssemblyInformationalVersion("1.0.0-beta2")]
3838
[assembly: InternalsVisibleTo("Dracoon.Sdk.Test")]

DracoonSdk/SdkInternal/ApiConfig.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,26 @@ internal class ApiConfig {
2222

2323
#region User-Endpoint
2424

25+
#region Minimum version requirements
26+
27+
internal const string ApiAvatarFunctions = "4.11.0";
28+
29+
#endregion
30+
2531
#region GET
2632

2733
internal const string ApiGetUserAccount = ApiPrefix + "/user/account";
2834
internal const string ApiGetCustomerAccount = ApiPrefix + "/user/account/customer";
2935
internal const string ApiGetUserKeyPair = ApiPrefix + "/user/account/keypair";
3036
internal const string ApiGetAuthenticatedPing = ApiPrefix + "/user/ping";
37+
internal const string ApiGetAvatar = ApiPrefix + "/user/account/avatar";
38+
internal const string ApiDeleteAvatar = ApiPrefix + "/user/account/avatar";
3139

3240
#endregion
3341
#region POST
3442

3543
internal const string ApiPostUserKeyPair = ApiPrefix + "/user/account/keypair";
44+
internal const string ApiPostAvatar = ApiPrefix + "/user/account/avatar";
3645

3746
#endregion
3847
#region DELETE
@@ -144,6 +153,16 @@ internal class ApiConfig {
144153

145154
#endregion
146155

156+
#region Resources-Endpoint
157+
158+
#region GET
159+
160+
internal const string ApiResourcesGetAvatar = ApiPrefix + "/resources/users/{userId}/avatar/{uuid}";
161+
162+
#endregion
163+
164+
#endregion
165+
147166
internal static Uri BuildApiUrl(Uri baseUrl, params string[] pathSegments) {
148167
UriBuilder uriBuilder = new UriBuilder(baseUrl);
149168
for (int i = 0; i < pathSegments.Length; i++) {

DracoonSdk/SdkInternal/ApiModel/Nodes/ApiNode.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,18 @@ public ApiEncryptionInfo EncryptionInfo {
9595
public int? CountChildren {
9696
get; set;
9797
}
98+
[JsonProperty("cntRooms", NullValueHandling = NullValueHandling.Ignore)]
99+
public int? CountRooms {
100+
get; set;
101+
}
102+
[JsonProperty("cntFolders", NullValueHandling = NullValueHandling.Ignore)]
103+
public int? CountFolders {
104+
get; set;
105+
}
106+
[JsonProperty("cntFiles", NullValueHandling = NullValueHandling.Ignore)]
107+
public int? CountFiles {
108+
get; set;
109+
}
98110
[JsonProperty("cntDeletedVersions", NullValueHandling = NullValueHandling.Ignore)]
99111
public int? CountDeletedVersions {
100112
get; set;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using Newtonsoft.Json;
2+
3+
namespace Dracoon.Sdk.SdkInternal.ApiModel {
4+
internal class ApiAvatarInfo {
5+
[JsonProperty("avatarUri", NullValueHandling = NullValueHandling.Ignore)]
6+
public string AvatarUri {
7+
get; set;
8+
}
9+
[JsonProperty("avatarUUID", NullValueHandling = NullValueHandling.Ignore)]
10+
public string AvatarUUID {
11+
get; set;
12+
}
13+
[JsonProperty("isCustomAvatar", NullValueHandling = NullValueHandling.Ignore)]
14+
public bool IsCustomAvatar {
15+
get; set;
16+
}
17+
}
18+
}

DracoonSdk/SdkInternal/ApiModel/User/ApiUserInfo.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,9 @@ public long Id {
1010
public string DisplayName {
1111
get; set;
1212
}
13+
[JsonProperty("avatarUuid", NullValueHandling = NullValueHandling.Ignore)]
14+
public string AvatarUUID {
15+
get; set;
16+
}
1317
}
1418
}

DracoonSdk/SdkInternal/DracoonAccountImpl.cs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@
77
using Dracoon.Crypto.Sdk.Model;
88
using static Dracoon.Sdk.SdkInternal.DracoonRequestExecuter;
99
using Dracoon.Sdk.Error;
10+
using System.Drawing;
11+
using System.Net;
12+
using System.IO;
13+
using System.Drawing.Imaging;
14+
using System.Linq;
15+
using Newtonsoft.Json;
16+
using System.Text;
1017

1118
namespace Dracoon.Sdk.SdkInternal {
1219
internal class DracoonAccountImpl : IAccount {
@@ -88,5 +95,72 @@ public void ValidateTokenValidity() {
8895
RestRequest request = client.RequestBuilder.GetAuthenticatedPing();
8996
client.RequestExecutor.DoSyncApiCall<VoidResponse>(request, RequestType.GetAuthenticatedPing);
9097
}
98+
99+
#region Avatar functions
100+
101+
public Image GetAvatar() {
102+
ApiAvatarInfo apiAvatarInfo = GetApiAvatarInfoInternally();
103+
104+
using (WebClient avatarClient = client.RequestBuilder.ProvideAvatarDownloadWebClient()) {
105+
byte[] avatarImageBytes = client.RequestExecutor.ExecuteWebClientDownload(avatarClient, new Uri(apiAvatarInfo.AvatarUri), RequestType.GetUserAvatar);
106+
MemoryStream ms = new MemoryStream(avatarImageBytes);
107+
return Image.FromStream(ms);
108+
}
109+
}
110+
111+
public AvatarInfo GetAvatarInfo() {
112+
ApiAvatarInfo apiAvatarInfo = GetApiAvatarInfoInternally();
113+
return UserMapper.FromApiAvatarInfo(apiAvatarInfo);
114+
}
115+
116+
private ApiAvatarInfo GetApiAvatarInfoInternally() {
117+
client.RequestExecutor.CheckApiServerVersion();
118+
client.RequestExecutor.CheckApiServerVersion(ApiConfig.ApiAvatarFunctions);
119+
120+
RestRequest request = client.RequestBuilder.GetAvatar();
121+
ApiAvatarInfo apiAvatarInfo = client.RequestExecutor.DoSyncApiCall<ApiAvatarInfo>(request, RequestType.GetUserAvatar);
122+
return apiAvatarInfo;
123+
}
124+
125+
public AvatarInfo ResetAvatar() {
126+
client.RequestExecutor.CheckApiServerVersion();
127+
client.RequestExecutor.CheckApiServerVersion(ApiConfig.ApiAvatarFunctions);
128+
129+
RestRequest request = client.RequestBuilder.DeleteAvatar();
130+
ApiAvatarInfo defaultAvatarInfo = client.RequestExecutor.DoSyncApiCall<ApiAvatarInfo>(request, RequestType.DeleteUserAvatar);
131+
return UserMapper.FromApiAvatarInfo(defaultAvatarInfo);
132+
}
133+
134+
public AvatarInfo UpdateAvatar(Image newAvatar) {
135+
client.RequestExecutor.CheckApiServerVersion();
136+
client.RequestExecutor.CheckApiServerVersion(ApiConfig.ApiAvatarFunctions);
137+
138+
byte[] avatarBytes = null;
139+
using (MemoryStream ms = new MemoryStream()) {
140+
newAvatar.Save(ms, newAvatar.RawFormat);
141+
avatarBytes = ms.ToArray();
142+
}
143+
144+
#region Build multipart
145+
ImageCodecInfo info = ImageCodecInfo.GetImageDecoders().First(c => c.FormatID == newAvatar.RawFormat.Guid);
146+
147+
string formDataBoundary = "---------------------------" + Guid.NewGuid();
148+
byte[] packageHeader = ApiConfig.encoding.GetBytes(string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\n\r\n", formDataBoundary, "file", "avatarImage"));
149+
byte[] packageFooter = ApiConfig.encoding.GetBytes(string.Format("\r\n--" + formDataBoundary + "--"));
150+
byte[] multipartFormatedChunkData = new byte[packageHeader.Length + packageFooter.Length + avatarBytes.Length];
151+
Buffer.BlockCopy(packageHeader, 0, multipartFormatedChunkData, 0, packageHeader.Length);
152+
Buffer.BlockCopy(avatarBytes, 0, multipartFormatedChunkData, packageHeader.Length, avatarBytes.Length);
153+
Buffer.BlockCopy(packageFooter, 0, multipartFormatedChunkData, packageHeader.Length + avatarBytes.Length, packageFooter.Length);
154+
#endregion
155+
156+
ApiAvatarInfo resultAvatarInfo;
157+
using (WebClient avatarClient = client.RequestBuilder.ProvideAvatarUploadWebClient(formDataBoundary)) {
158+
byte[] resultAvatarInfoBytes = client.RequestExecutor.ExecuteWebClientChunkUpload(avatarClient, new Uri(client.ServerUri, ApiConfig.ApiPostAvatar), multipartFormatedChunkData, RequestType.PostUserAvatar);
159+
resultAvatarInfo = JsonConvert.DeserializeObject<ApiAvatarInfo>(Encoding.UTF8.GetString(resultAvatarInfoBytes));
160+
}
161+
return UserMapper.FromApiAvatarInfo(resultAvatarInfo);
162+
}
163+
164+
#endregion
91165
}
92166
}

0 commit comments

Comments
 (0)