This commit is contained in:
DecaTec 2017-05-19 10:05:09 +02:00
Родитель e30b8d1b49
Коммит 708ce2b4f1
7 изменённых файлов: 323 добавлений и 43 удалений

Просмотреть файл

@ -387,6 +387,11 @@
<Name>Windows Mobile Extensions for the UWP</Name>
</SDKReference>
</ItemGroup>
<ItemGroup>
<Reference Include="DecaTec.WebDav">
<HintPath>..\..\Portable-WebDAV-Library\Build\Debug\netstandard1.1\DecaTec.WebDav.dll</HintPath>
</Reference>
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup>

Просмотреть файл

@ -15,6 +15,10 @@ using NextcloudClient.Types;
using DecaTec.WebDav;
using Windows.Security.Credentials;
using Windows.Security.Cryptography.Certificates;
using DecaTec.WebDav.WebDavArtifacts;
using NextcloudClient.WebDav;
using NextcloudClient.Extensions;
using DecaTec.WebDav.Tools;
namespace NextcloudClient
{
@ -67,6 +71,8 @@ namespace NextcloudClient
/// </summary>
private const string OcsServiceCloud = "cloud";
private readonly PropFind nextcloudPropFind;
#endregion
#region CONSTRUCTORS
@ -110,6 +116,40 @@ namespace NextcloudClient
url = url.TrimEnd('/');
}
// Create PropFind which contains all NC specific properties.
var propFind = PropFind.CreatePropFindWithEmptyPropertiesAll();
var prop = (Prop)propFind.Item;
XNamespace nsOc = "http://owncloud.org/ns";
var xElementList = new List<XElement>();
var xElement = new XElement(nsOc + NextcloudPropNameConstants.Checksums);
xElementList.Add(xElement);
xElement = new XElement(nsOc + NextcloudPropNameConstants.CommentsCount);
xElementList.Add(xElement);
xElement = new XElement(nsOc + NextcloudPropNameConstants.CommentsHref);
xElementList.Add(xElement);
xElement = new XElement(nsOc + NextcloudPropNameConstants.CommentsUnread);
xElementList.Add(xElement);
xElement = new XElement(nsOc + NextcloudPropNameConstants.Favorite);
xElementList.Add(xElement);
xElement = new XElement(nsOc + NextcloudPropNameConstants.FileId);
xElementList.Add(xElement);
xElement = new XElement(nsOc + NextcloudPropNameConstants.HasPreview);
xElementList.Add(xElement);
xElement = new XElement(nsOc + NextcloudPropNameConstants.Id);
xElementList.Add(xElement);
xElement = new XElement(nsOc + NextcloudPropNameConstants.OwnerDisplayName);
xElementList.Add(xElement);
xElement = new XElement(nsOc + NextcloudPropNameConstants.OwnerId);
xElementList.Add(xElement);
xElement = new XElement(nsOc + NextcloudPropNameConstants.ShareTypes);
xElementList.Add(xElement);
xElement = new XElement(nsOc + NextcloudPropNameConstants.Size);
xElementList.Add(xElement);
prop.AdditionalProperties = xElementList.ToArray();
nextcloudPropFind = propFind;
_url = url;
_httpBaseProtocolFilter = httpBaseProtocolFilter;
@ -178,25 +218,15 @@ namespace NextcloudClient
{
var resources = new List<ResourceInfo>();
var test = GetDavUri(path);
var result = await _dav.ListAsync(GetDavUri(path));
var result = await _dav.ListAsync(GetDavUri(path), nextcloudPropFind);
var baseUri = new Uri(_url);
baseUri = new Uri(baseUri, baseUri.AbsolutePath + (baseUri.AbsolutePath.EndsWith("/") ? "" : "/") + Davpath);
foreach (var item in result)
{
var res = new ResourceInfo
{
ContentType = item.IsCollection ? "dav/directory" : item.ContentType,
Created = item.CreationDate,
ETag = item.ETag,
LastModified = item.LastModified,
Name = System.Net.WebUtility.UrlDecode(item.Name),
QuotaAvailable = item.QuotaAvailableBytes,
QuotaUsed = item.QuotaUsedBytes,
Size = item.ContentLength != 0 ? item.ContentLength : item.QuotaUsedBytes,
Path = System.Net.WebUtility.UrlDecode(item.Uri.AbsoluteUri.Replace(baseUri.AbsoluteUri, ""))
};
var res = item.ToResourceInfo(baseUri);
if (!res.ContentType.Equals("dav/directory"))
{
// if resource not a directory, remove the file name from remote path.
@ -219,7 +249,7 @@ namespace NextcloudClient
var baseUri = new Uri(_url);
baseUri = new Uri(baseUri, baseUri.AbsolutePath + (baseUri.AbsolutePath.EndsWith("/") ? "" : "/") + Davpath);
var result = await _dav.ListAsync(GetDavUri(path));
var result = await _dav.ListAsync(GetDavUri(path), nextcloudPropFind);
if (result.Count <= 0)
{
@ -229,18 +259,8 @@ namespace NextcloudClient
{
if (item.Name.Equals(name))
{
var res = new ResourceInfo
{
ContentType = item.IsCollection ? "dav/directory" : item.ContentType,
Created = item.CreationDate,
ETag = item.ETag,
LastModified = item.LastModified,
Name = System.Net.WebUtility.UrlDecode(item.Name),
QuotaAvailable = item.QuotaAvailableBytes,
QuotaUsed = item.QuotaUsedBytes,
Size = item.ContentLength,
Path = item.Uri.AbsolutePath.Replace(baseUri.AbsolutePath, "")
};
var res = item.ToResourceInfo(baseUri);
if (!res.ContentType.Equals("dav/directory"))
{
// if resource not a directory, remove the file name from remote path.
@ -320,29 +340,48 @@ namespace NextcloudClient
var response = await _client.SendRequestAsync(request);
var xDoc = XDocument.Parse(response.Content.ToString());
var contentString = await response.Content.ReadAsStringAsync();
var multistatus = WebDavResponseContentParser.ParseMultistatusResponseContentString(contentString);
var favoritesList = new List<ResourceInfo>();
List<ResourceInfo> favoritesList = new List<ResourceInfo>();
foreach (XElement element in xDoc.Descendants())
foreach (var msResponse in multistatus.Response)
{
if (element.ToString().IndexOf("d:href") > -1 && element.ToString().IndexOf("d:response") < 0 )
foreach (var item in msResponse.Items)
{
var favoritePath = element.ToString().Replace("<d:href xmlns:d=\"DAV:\">/remote.php/webdav", "").Replace("</d:href>", "");
var href = item as string;
try
{
var itemFav = await GetResourceInfoByPath(Uri.UnescapeDataString(favoritePath));
if (string.IsNullOrEmpty(href) || !href.Contains(Davpath))
continue;
favoritesList.Add(itemFav);
}
catch (ResponseError e)
{
throw e;
}
var itemFav = await GetResourceInfoByPath(Uri.UnescapeDataString(href));
favoritesList.Add(itemFav);
}
}
//var xDoc = XDocument.Parse(response.Content.ToString());
//List<ResourceInfo> favoritesList = new List<ResourceInfo>();
//foreach (XElement element in xDoc.Descendants())
//{
// if (element.ToString().IndexOf("d:href") > -1 && element.ToString().IndexOf("d:response") < 0 )
// {
// var favoritePath = element.ToString().Replace("<d:href xmlns:d=\"DAV:\">/", "").Replace("</d:href>", "");
// try
// {
// var itemFav = await GetResourceInfoByPath(Uri.UnescapeDataString(favoritePath));
// favoritesList.Add(itemFav);
// }
// catch (ResponseError e)
// {
// throw e;
// }
// }
//}
return favoritesList;
}

Просмотреть файл

@ -105,6 +105,68 @@ namespace NextcloudClient.Types
return JsonConvert.SerializeObject(this);
}
#region Nextcloud specific
// See https://docs.nextcloud.com/server/12/developer_manual/client_apis/WebDAV/index.html for a list of all NC specific WebDAV properties.
/// <summary>
/// Gets or sets the ID (the fileid namespaced by the instance id, globally unique).
/// </summary>
public string Id { get; set; }
/// <summary>
/// Gets or sets the FileID (the unique id for the file within the instance).
/// </summary>
public string FileId { get; set; }
/// <summary>
/// Gets or sets IsFavorite.
/// </summary>
public bool IsFavorite { get; set; }
/// <summary>
/// Gets or sets CommentsHref (link to comments).
/// </summary>
public Uri CommentsHref { get; set; }
/// <summary>
/// Gets or sets the count of comments.
/// </summary>
public long CommentsCount { get; set; }
/// <summary>
/// Gets or sets the number of comments unread.
/// </summary>
public long CommentsUnread { get; set; }
/// <summary>
/// Gets or sets the OwnerId (the user id of the owner of a shared file).
/// </summary>
public string OwnderId { get; set; }
/// <summary>
/// Gets or sets the owner display name (the display name of the owner of a shared file).
/// </summary>
public string OwnerDisplayName { get; set; }
/// <summary>
/// Gets or sets the NextcloudShareTypes.
/// </summary>
public string ShareTypes { get; set; }
/// <summary>
/// Gets or sets the Checksums.
/// </summary>
public string Checksums { get; set; }
/// <summary>
/// Gets or sets HasPreview.
/// </summary>
public bool HasPreview { get; set; }
#endregion Nextcloud specific
#region Equals
public override bool Equals(object obj)
@ -149,6 +211,14 @@ namespace NextcloudClient.Types
if (this.ETag != null)
hashCode ^= this.ETag.GetHashCode();
if (!string.IsNullOrEmpty(this.Id))
hashCode ^= this.Id.GetHashCode();
// #TODO
if (!string.IsNullOrEmpty(this.Id))
hashCode ^= this.Id.GetHashCode();
return hashCode;
}

Просмотреть файл

@ -0,0 +1,128 @@
using DecaTec.WebDav;
using DecaTec.WebDav.Tools;
using NextcloudClient.Types;
using NextcloudClient.WebDav;
using System;
namespace NextcloudClient.Extensions
{
/// <summary>
/// Creates a <see cref="ResourceInfo"/> from a <see cref="WebDavSessionItem"/>.
/// </summary>
public static class WebDavSessionItemExtensions
{
public const string NsOc = "http://owncloud.org/ns";
public static ResourceInfo ToResourceInfo(this WebDavSessionItem item, Uri baseUri)
{
var res = new ResourceInfo
{
ContentType = item.IsFolder.HasValue ? "dav/directory" : item.ContentType,
Created = item.CreationDate ?? DateTime.MinValue,
ETag = item.ETag,
LastModified = item.LastModified ?? DateTime.MinValue,
Name = System.Net.WebUtility.UrlDecode(item.Name),
QuotaAvailable = item.QuotaAvailableBytes ?? 0,
QuotaUsed = item.QuotaUsedBytes ?? 0,
Size = item.ContentLength.HasValue && item.ContentLength.Value != 0 ? item.ContentLength.Value : item.QuotaUsedBytes ?? 0,
Path = System.Net.WebUtility.UrlDecode(item.Uri.AbsoluteUri.Replace(baseUri.AbsoluteUri, ""))
};
// NC specific properties.
var ncProps = item.AdditionalProperties;
if(ncProps != null)
{
var key = NsOc + ":" + NextcloudPropNameConstants.Checksums;
if (ncProps.ContainsKey(key))
res.Checksums = ncProps[NsOc + ":" + NextcloudPropNameConstants.Checksums];
key = NsOc + ":" + NextcloudPropNameConstants.CommentsCount;
if (ncProps.ContainsKey(key))
{
var commentsCount = ncProps[NsOc + ":" + NextcloudPropNameConstants.CommentsCount];
res.CommentsCount = string.IsNullOrEmpty(commentsCount) ? 0 : long.Parse(commentsCount);
}
key = NsOc + ":" + NextcloudPropNameConstants.CommentsHref;
if (ncProps.ContainsKey(key))
{
var commentsHref = ncProps[NsOc + ":" + NextcloudPropNameConstants.CommentsHref];
res.CommentsHref = string.IsNullOrEmpty(commentsHref) ? null : UriHelper.CombineUri(baseUri, new Uri(commentsHref, UriKind.Relative));
}
key = NsOc + ":" + NextcloudPropNameConstants.CommentsUnread;
if (ncProps.ContainsKey(key))
{
var commentsUnread = ncProps[NsOc + ":" + NextcloudPropNameConstants.CommentsUnread];
res.CommentsUnread = string.IsNullOrEmpty(commentsUnread) ? 0 : long.Parse(commentsUnread);
}
key = NsOc + ":" + NextcloudPropNameConstants.Favorite;
if (ncProps.ContainsKey(key))
{
var favorite = ncProps[NsOc + ":" + NextcloudPropNameConstants.Favorite];
res.IsFavorite = string.IsNullOrEmpty(favorite) ? false : string.CompareOrdinal(favorite, "1") == 0 ? true : false;
}
key = NsOc + ":" + NextcloudPropNameConstants.FileId;
if (ncProps.ContainsKey(key))
{
res.FileId = ncProps[NsOc + ":" + NextcloudPropNameConstants.FileId];
}
key = NsOc + ":" + NextcloudPropNameConstants.HasPreview;
if (ncProps.ContainsKey(key))
{
var hasPreview = ncProps[NsOc + ":" + NextcloudPropNameConstants.HasPreview];
res.HasPreview = string.IsNullOrEmpty(hasPreview) ? false : string.CompareOrdinal(hasPreview, "1") == 0 ? true : false;
}
key = NsOc + ":" + NextcloudPropNameConstants.Id;
if (ncProps.ContainsKey(key))
{
res.Id = ncProps[NsOc + ":" + NextcloudPropNameConstants.Id];
}
key = NsOc + ":" + NextcloudPropNameConstants.OwnerDisplayName;
if (ncProps.ContainsKey(key))
{
res.OwnerDisplayName = ncProps[NsOc + ":" + NextcloudPropNameConstants.OwnerDisplayName];
}
key = NsOc + ":" + NextcloudPropNameConstants.OwnerId;
if (ncProps.ContainsKey(key))
{
res.OwnderId = ncProps[NsOc + ":" + NextcloudPropNameConstants.OwnerId];
}
key = NsOc + ":" + NextcloudPropNameConstants.ShareTypes;
if (ncProps.ContainsKey(key))
{
res.ShareTypes = ncProps[NsOc + ":" + NextcloudPropNameConstants.ShareTypes];
}
key = NsOc + ":" + NextcloudPropNameConstants.Size;
if (ncProps.ContainsKey(key))
{
var size = ncProps[NsOc + ":" + NextcloudPropNameConstants.Size];
res.Size = string.IsNullOrEmpty(size) ? 0 : long.Parse(size);
}
}
return res;
}
}
}

Просмотреть файл

@ -155,9 +155,16 @@
<Compile Include="..\NextcloudClient\UrlBuilder.cs">
<Link>UrlBuilder.cs</Link>
</Compile>
<Compile Include="Extensions\WebDavSessionItemExtensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="WebDav\NextcloudPropNameConstants.cs" />
<EmbeddedResource Include="Properties\NextcloudClientPortable.rd.xml" />
</ItemGroup>
<ItemGroup>
<Reference Include="DecaTec.WebDav">
<HintPath>..\..\Portable-WebDAV-Library\Build\Debug\netstandard1.1\DecaTec.WebDav.dll</HintPath>
</Reference>
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup>

Просмотреть файл

@ -0,0 +1,32 @@
namespace NextcloudClient.WebDav
{
public static class NextcloudPropNameConstants
{
public const string Id = "id";
public const string FileId = "fileid";
public const string Favorite = "favorite";
public const string CommentsHref = "comments-href";
public const string CommentsCount = "comments-count";
public const string CommentsUnread = "comments-unread";
public const string OwnerId = "owner-id";
public const string OwnerDisplayName = "owner-display-name";
public const string ShareTypes = "share-types";
public const string Checksums = "checksums";
public const string HasPreview = "has-preview";
public const string Size = "size";
public const string ShareType = "share-type";
}
}

Просмотреть файл

@ -1,8 +1,7 @@
{
"dependencies": {
"Microsoft.NETCore.UniversalWindowsPlatform": "5.3.2",
"Newtonsoft.Json": "10.0.2",
"PortableWebDavLibrary": "0.8.2"
"Newtonsoft.Json": "10.0.2"
},
"frameworks": {
"uap10.0": {}