Skip to content

Commit f9bcf72

Browse files
committed
Some fixes to return types, Attachments, Features, References added to driver
1 parent 02d2f3f commit f9bcf72

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1381
-145
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@ obj
44

55
gitana.json
66
Program.cs
7-
*.nupkg
7+
*.nupkg
8+
9+
*.DotSettings.user

Folder.DotSettings.user

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
2-
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=0d9aa4ff_002D9d1d_002D4f5f_002D94d5_002D3523baf3e2c6/@EntryIndexedValue">&lt;SessionState ContinuousTestingIsOn="False" ContinuousTestingMode="0" FrameworkVersion="{x:Null}" IsLocked="False" Name="TestAssociateUnassociate" PlatformMonoPreference="{x:Null}" PlatformType="{x:Null}" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
3-
&lt;TestAncestor&gt;
4-
&lt;TestId&gt;xUnit::EE65E1B0-7C2A-642D-B2D4-209341220643::.NETCoreApp,Version=v3.1::CloudCMS.Tests.AssociationTest.TestAssociateUnassociate&lt;/TestId&gt;
5-
&lt;/TestAncestor&gt;
2+
3+
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=c710a6a7_002D6bc8_002D4f32_002D8868_002Db3542a0927fe/@EntryIndexedValue">&lt;SessionState ContinuousTestingIsOn="False" ContinuousTestingMode="0" FrameworkVersion="{x:Null}" IsLocked="False" Name="TestAttachmentBytes" PlatformMonoPreference="{x:Null}" PlatformType="{x:Null}" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
4+
&lt;ProjectFolder&gt;EE65E1B0-7C2A-642D-B2D4-209341220643/d:tests&lt;/ProjectFolder&gt;
65
&lt;/SessionState&gt;</s:String></wpf:ResourceDictionary>

cloudcms-csharp-driver.csproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<RootNamespace>CloudCMS</RootNamespace>
77

88
<PackageId>cloudcms</PackageId>
9-
<PackageVersion>1.0.3</PackageVersion>
9+
<PackageVersion>1.1.0</PackageVersion>
1010
<Title>CloudCMS Driver</Title>
1111
<Description>C# .NET driver for CloudCMS</Description>
1212
<Summary>C# .NET driver for CloudCMS</Summary>
@@ -16,14 +16,18 @@
1616
<PackageIconUrl>https://github.com/gitana/cloudcms-csharp-driver/blob/master/icon.png?raw=true</PackageIconUrl>
1717
<PackageLicenseFile>LICENSE</PackageLicenseFile>
1818
<IsPackable>true</IsPackable>
19+
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
20+
<AssemblyVersion>1.1.0</AssemblyVersion>
1921
</PropertyGroup>
2022

2123
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
24+
<EmbeddedResource Include="res\**\*" />
2225
<None Update="gitana.json" CopyToOutputDirectory="PreserveNewest" />
2326
</ItemGroup>
2427

2528
<ItemGroup>
2629
<None Include="LICENSE" Pack="true" PackagePath="" />
30+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
2731
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
2832
<PackageReference Include="xunit" Version="2.4.1" />
2933
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />

res/cloudcms.png

11.5 KB
Loading

res/headphones.png

1.54 KB
Loading

src/CloudCMSDriver.cs

Lines changed: 97 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@
88
using System.Collections.Generic;
99
using Newtonsoft.Json;
1010
using Newtonsoft.Json.Linq;
11-
using CloudCMS.Platforms;
12-
using CloudCMS.Exceptions;
11+
using CloudCMS;
1312

1413
namespace CloudCMS
1514
{
@@ -118,30 +117,82 @@ public async Task<JObject> DeleteAsync(string uri, IDictionary<string, string> q
118117
return await RequestAsync(uri, method, queryParams);
119118
}
120119

120+
public async Task<Stream> DownloadAsync(string uri)
121+
{
122+
HttpResponseMessage response = await _requestAsync(uri, HttpMethod.Get);
123+
return await response.Content.ReadAsStreamAsync();
124+
}
125+
126+
public async Task<byte[]> DownloadBytesAsync(string uri)
127+
{
128+
HttpResponseMessage response = await _requestAsync(uri, HttpMethod.Get);
129+
return await response.Content.ReadAsByteArrayAsync();
130+
}
131+
132+
public async Task UploadAsync(string uri, byte[] bytes, string mimetype, IDictionary<string, string> paramMap=null)
133+
{
134+
paramMap ??= new Dictionary<string, string>();
135+
HttpContent content = GenerateUploadContent(bytes, mimetype);
136+
await _requestAsync(uri, HttpMethod.Post, paramMap, content);
137+
}
138+
139+
public async Task UploadAsync(string uri, Stream stream, string mimetype, IDictionary<string, string> paramMap=null)
140+
{
141+
paramMap ??= new Dictionary<string, string>();
142+
HttpContent content = GenerateUploadContent(stream, mimetype);
143+
await _requestAsync(uri, HttpMethod.Post, paramMap, content);
144+
}
145+
146+
public async Task UploadAsync(string uri, IDictionary<string, string> paramMap, IDictionary<string, AttachmentContent> payloads)
147+
{
148+
HttpContent content = GenerateUploadContent(payloads);
149+
await _requestAsync(uri, HttpMethod.Post, paramMap, content);
150+
}
151+
152+
private HttpContent GenerateUploadContent(byte[] bytes, string mimetype)
153+
{
154+
return new AttachmentContent(bytes, mimetype);
155+
}
156+
157+
private HttpContent GenerateUploadContent(Stream stream, string mimetype)
158+
{
159+
return new AttachmentContent(stream, mimetype);
160+
161+
}
162+
163+
private HttpContent GenerateUploadContent(IDictionary<string, AttachmentContent> payloads)
164+
{
165+
MultipartFormDataContent multi = new MultipartFormDataContent();
166+
foreach (var kv in payloads)
167+
{
168+
string filename = kv.Key;
169+
AttachmentContent payload = kv.Value;
170+
171+
multi.Add(payload, filename, filename);
172+
}
173+
174+
return multi;
175+
}
176+
177+
121178
public async Task<JObject> RequestAsync(string uri, HttpMethod method, IDictionary<string, string> queryParams = null, HttpContent body = null)
122179
{
123-
using (HttpClient client = new HttpClient())
180+
HttpResponseMessage response = await _requestAsync(uri, method, queryParams, body);
181+
string responseString = await response.Content.ReadAsStringAsync();
182+
if (!response.IsSuccessStatusCode)
124183
{
125-
var uriBuilder = new UriBuilder(Config.baseURL + uri);
184+
throw new CloudCMSRequestException(responseString);
185+
}
126186

127-
var query = HttpUtility.ParseQueryString(uriBuilder.Query);
128-
// Add "full" parameter unless already set
129-
if (query["full"] == null)
130-
{
131-
query["full"] = "true";
132-
}
133-
// Add all params to query string
134-
if (queryParams != null)
135-
{
136-
foreach(var kvp in queryParams)
137-
{
138-
query[kvp.Key] = kvp.Value;
139-
}
140-
}
141-
uriBuilder.Query = query.ToString();
187+
return JObject.Parse(responseString);
188+
}
189+
190+
private async Task<HttpResponseMessage> _requestAsync(string uri, HttpMethod method, IDictionary<string, string> queryParams = null, HttpContent body = null)
191+
{
192+
using (HttpClient client = new HttpClient())
193+
{
194+
var url = BuildUrl(uri, queryParams);
142195

143-
string url = uriBuilder.ToString();
144-
145196
HttpRequestMessage request = new HttpRequestMessage(method, url);
146197
if (body != null)
147198
{
@@ -157,16 +208,36 @@ public async Task<JObject> RequestAsync(string uri, HttpMethod method, IDictiona
157208
client.DefaultRequestHeaders.Authorization = auth;
158209

159210
HttpResponseMessage response = await client.SendAsync(request);
160-
string responseString = await response.Content.ReadAsStringAsync();
161-
if (!response.IsSuccessStatusCode)
211+
return response;
212+
}
213+
}
214+
215+
private string BuildUrl(string uri, IDictionary<string, string> queryParams)
216+
{
217+
var uriBuilder = new UriBuilder(Config.baseURL + uri);
218+
219+
var query = HttpUtility.ParseQueryString(uriBuilder.Query);
220+
// Add "full" parameter unless already set
221+
if (query["full"] == null)
222+
{
223+
query["full"] = "true";
224+
}
225+
226+
// Add all params to query string
227+
if (queryParams != null)
228+
{
229+
foreach (var kvp in queryParams)
162230
{
163-
throw new CloudCMSRequestException(responseString);
231+
query[kvp.Key] = kvp.Value;
164232
}
165-
166-
return JObject.Parse(responseString);
167233
}
234+
235+
uriBuilder.Query = query.ToString() ?? "";
236+
237+
return uriBuilder.ToString();
168238
}
169239

240+
170241
private async Task GetTokenAsync()
171242
{
172243
using(HttpClient client = new HttpClient())

src/attachments/Attachment.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System.IO;
2+
using System.Runtime.Serialization;
3+
using System.Threading.Tasks;
4+
using Newtonsoft.Json.Linq;
5+
6+
namespace CloudCMS
7+
{
8+
public class Attachment : IAttachment
9+
{
10+
public string Id { get; }
11+
public string ObjectId { get; }
12+
public long Length { get; }
13+
public string Filename { get; }
14+
public string ContentType { get; }
15+
16+
private IAttachable _attachable;
17+
18+
public Attachment(IAttachable attachable, JObject obj)
19+
{
20+
Id = obj.GetValue("attachmentId").ToString();
21+
ObjectId = obj.GetValue("objectId").ToString();
22+
Length = obj.GetValue("length").ToObject<long>();
23+
ContentType = obj.GetValue("contentType").ToString();
24+
Filename = obj.GetValue("filename").ToString();
25+
26+
_attachable = attachable;
27+
}
28+
29+
public Task<Stream> StreamAsync()
30+
{
31+
return _attachable.DownloadAttachmentAsync(Id);
32+
}
33+
34+
public Task<byte[]> DownloadAsync()
35+
{
36+
return _attachable.DownloadAttachmentBytesAsync(Id);
37+
}
38+
}
39+
}

src/attachments/AttachmentContent.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using System.IO;
2+
using System.Net;
3+
using System.Net.Http;
4+
using System.Net.Http.Headers;
5+
using System.Threading.Tasks;
6+
7+
namespace CloudCMS
8+
{
9+
public class AttachmentContent : HttpContent
10+
{
11+
private HttpContent _content;
12+
private long _length;
13+
14+
public AttachmentContent(byte[] bytes, string mimetype)
15+
{
16+
_content = new ByteArrayContent(bytes);
17+
this.Headers.ContentType = new MediaTypeHeaderValue(mimetype);
18+
19+
_length = bytes.Length;
20+
}
21+
22+
public AttachmentContent(Stream stream, string mimetype)
23+
{
24+
_content = new StreamContent(stream);
25+
this.Headers.ContentType = new MediaTypeHeaderValue(mimetype);
26+
27+
_length = stream.Length;
28+
}
29+
30+
protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context)
31+
{
32+
byte[] contentBytes = await _content.ReadAsByteArrayAsync();
33+
await stream.WriteAsync(contentBytes);
34+
}
35+
36+
protected override bool TryComputeLength(out long length)
37+
{
38+
length = _length;
39+
return true;
40+
}
41+
}
42+
}

src/attachments/AttachmentUtil.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System.Collections.Generic;
2+
using Newtonsoft.Json.Linq;
3+
using Xunit.Abstractions;
4+
5+
namespace CloudCMS
6+
{
7+
public class AttachmentUtil
8+
{
9+
public static List<IAttachment> AttachmentList(IAttachable attachable, JObject response)
10+
{
11+
JArray nodeArray = (JArray) response.SelectToken("rows");
12+
return AttachmentList(attachable, nodeArray);
13+
}
14+
public static List<IAttachment> AttachmentList(IAttachable attachable, JArray attachmentArray)
15+
{
16+
List<IAttachment> attachments = new List<IAttachment>();
17+
foreach(var attachmentJson in attachmentArray)
18+
{
19+
JObject attachmentObj = (JObject) attachmentJson;
20+
IAttachment attachment = Attachment(attachable, attachmentObj);
21+
attachments.Add(attachment);
22+
}
23+
24+
return attachments;
25+
}
26+
27+
public static IAttachment Attachment(IAttachable attachable, JObject attachmentObj)
28+
{
29+
return new Attachment(attachable, attachmentObj);
30+
}
31+
}
32+
}

src/attachments/IAttachable.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System.Collections.Generic;
2+
using System.IO;
3+
using System.Net.Http;
4+
using System.Threading.Tasks;
5+
6+
namespace CloudCMS
7+
{
8+
public interface IAttachable
9+
{
10+
Task UploadAttachmentAsync(byte[] bytes, string mimeType);
11+
Task UploadAttachmentAsync(string attachmentId, byte[] bytes, string mimeType, string filename=null);
12+
13+
Task UploadAttachmentAsync(Stream stream, string mimeType);
14+
Task UploadAttachmentAsync(string attachmentId, Stream stream, string mimeType, string filename=null);
15+
16+
Task UploadAttachmentsAsync(IDictionary<string, AttachmentContent> attachments);
17+
Task UploadAttachmentsAsync(IDictionary<string, string> paramMap, IDictionary<string, AttachmentContent> attachments);
18+
19+
Task<Stream> DownloadAttachmentAsync();
20+
Task<Stream> DownloadAttachmentAsync(string attachmentId);
21+
Task<byte[]> DownloadAttachmentBytesAsync();
22+
Task<byte[]> DownloadAttachmentBytesAsync(string attachmentId);
23+
24+
Task<List<IAttachment>> ListAttachments();
25+
26+
string GetDownloadUri();
27+
string GetDownloadUri(string attachmentId);
28+
29+
Task DeleteAttachmentAsync();
30+
Task DeleteAttachmentAsync(string attachmentId);
31+
}
32+
}

0 commit comments

Comments
 (0)