NC WebDAV properties
This commit is contained in:
Родитель
e30b8d1b49
Коммит
708ce2b4f1
|
@ -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)' < '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)' < '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": {}
|
||||
|
|
Загрузка…
Ссылка в новой задаче