huge work for nextcloud api
This commit is contained in:
@@ -2,5 +2,6 @@
|
|||||||
<configuration>
|
<configuration>
|
||||||
<packageSources>
|
<packageSources>
|
||||||
<add key="Telerik UI for WinForms 2023.1.117" value="C:\Program Files (x86)\Progress\Telerik UI for WinForms R1 2023\Bin60\NuGet" />
|
<add key="Telerik UI for WinForms 2023.1.117" value="C:\Program Files (x86)\Progress\Telerik UI for WinForms R1 2023\Bin60\NuGet" />
|
||||||
|
<add key="Telerik UI for WinForms UI.for.WinForms.AllControls.Net60.2023.2.718" value="C:\Program Files (x86)\Progress\Telerik UI for WinForms R2 2023\Bin60\NuGet" />
|
||||||
</packageSources>
|
</packageSources>
|
||||||
</configuration>
|
</configuration>
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
using Pilz.Networking.CloudProviders.Nextcloud.Model.Apps.FilesRetention;
|
||||||
|
using Pilz.Networking.CloudProviders.Nextcloud.OCS.APIs.Apps;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps
|
||||||
|
{
|
||||||
|
public class FilesRetentionClient : ClientBase
|
||||||
|
{
|
||||||
|
public FilesRetentionClient(NextcloudClient client) : base(client)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<bool> CreateRetentionRule(RetentionRule rule)
|
||||||
|
{
|
||||||
|
var entry = rule.ToOcsData();
|
||||||
|
return Client.Ocs.GetApi<OcsApiFilesRetention>().CreateRetentionRule(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<bool> DeleteRetentionRule(int ruleID)
|
||||||
|
{
|
||||||
|
return Client.Ocs.GetApi<OcsApiFilesRetention>().DeleteRetentionRule(ruleID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RetentionRule[]?> GetRetentionRules()
|
||||||
|
{
|
||||||
|
var api = Client.Ocs.GetApi<OcsApiFilesRetention>();
|
||||||
|
var response = await api.GetRetentionRules();
|
||||||
|
|
||||||
|
if (response?.Data is not null)
|
||||||
|
{
|
||||||
|
var rules = new List<RetentionRule>();
|
||||||
|
|
||||||
|
foreach (var entry in response.Data)
|
||||||
|
rules.Add(new RetentionRule(entry));
|
||||||
|
|
||||||
|
return rules.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client
|
||||||
|
{
|
||||||
|
public abstract class ClientBase
|
||||||
|
{
|
||||||
|
public NextcloudClient Client { get; init; }
|
||||||
|
|
||||||
|
public ClientBase(NextcloudClient client)
|
||||||
|
{
|
||||||
|
Client = client;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
using Pilz.Networking.CloudProviders.Nextcloud.Model.Cloud;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Client
|
||||||
|
{
|
||||||
|
public class CloudClient : ClientBase
|
||||||
|
{
|
||||||
|
public CloudClient(NextcloudClient client) : base(client)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<UserInfo?> GetUserInfo()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(Client.CurrentLogin?.LoginName))
|
||||||
|
return GetUserInfo(Client.CurrentLogin.LoginName);
|
||||||
|
else
|
||||||
|
return Task.FromResult<UserInfo?>(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<UserInfo?> GetUserInfo(string username)
|
||||||
|
{
|
||||||
|
var result = await Client.Ocs.Cloud.GetUserMeta(username);
|
||||||
|
|
||||||
|
if (result?.Data != null)
|
||||||
|
return new UserInfo(result.Data);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
using Pilz.Networking.CloudProviders.Nextcloud.OCS.Data.Apps.FileRetention;
|
||||||
|
using Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses.Apps.FilesRetention;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Model.Apps.FilesRetention
|
||||||
|
{
|
||||||
|
public class RetentionRule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The ID for the retention rule.
|
||||||
|
/// </summary>
|
||||||
|
public int ID { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The ID for the tag that is used for this rule.
|
||||||
|
/// </summary>
|
||||||
|
public int TagID { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The unit used for the time.
|
||||||
|
/// </summary>
|
||||||
|
public RetentionTimeUnit TimeUnit { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents numer of days/weeks/months/years.
|
||||||
|
/// </summary>
|
||||||
|
public int TimeAmount { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The time used for the rule.
|
||||||
|
/// </summary>
|
||||||
|
public RetentionTimeAfter TimeAfter { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines if a background job has been generated
|
||||||
|
/// </summary>
|
||||||
|
public bool HasJob { get; init; }
|
||||||
|
|
||||||
|
public RetentionRule(int iD, int tagID, RetentionTimeUnit timeUnit, int timeAmount, RetentionTimeAfter timeAfter, bool hasJob)
|
||||||
|
{
|
||||||
|
ID = iD;
|
||||||
|
TagID = tagID;
|
||||||
|
TimeUnit = timeUnit;
|
||||||
|
TimeAmount = timeAmount;
|
||||||
|
TimeAfter = timeAfter;
|
||||||
|
HasJob = hasJob;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RetentionRule(OcsResponseDataEntryRetention data)
|
||||||
|
{
|
||||||
|
ID = data.ID ?? -1;
|
||||||
|
TagID = data.TagID ?? -1;
|
||||||
|
TimeUnit = (RetentionTimeUnit)(data.TimeUnit ?? 0);
|
||||||
|
TimeAmount = data.TimeAmount ?? -1;
|
||||||
|
TimeAfter = (RetentionTimeAfter)(data.TimeAfter ?? 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OcsDataRetentionRule ToOcsData()
|
||||||
|
{
|
||||||
|
return new OcsDataRetentionRule
|
||||||
|
{
|
||||||
|
TagID = TagID,
|
||||||
|
TimeUnit = (int)TimeUnit,
|
||||||
|
TimeAmount = TimeAmount,
|
||||||
|
TimeAfter = (int)TimeAfter
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Model.Apps.FilesRetention
|
||||||
|
{
|
||||||
|
public enum RetentionTimeAfter
|
||||||
|
{
|
||||||
|
CreationDate,
|
||||||
|
LastAccess
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Model.Apps.FilesRetention
|
||||||
|
{
|
||||||
|
public enum RetentionTimeUnit
|
||||||
|
{
|
||||||
|
Day,
|
||||||
|
Week,
|
||||||
|
Month,
|
||||||
|
Year
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Model
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Model.Cloud
|
||||||
{
|
{
|
||||||
public class UserBackendCapabilities
|
public class UserBackendCapabilities
|
||||||
{
|
{
|
||||||
@@ -5,84 +5,84 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Model
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Model.Cloud
|
||||||
{
|
{
|
||||||
public class UserInfo
|
public class UserInfo
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines if the user is enabled.
|
/// Defines if the user is enabled.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The location of the user's storage directory.
|
/// The location of the user's storage directory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? StorageLocation { get; set; }
|
public string? StorageLocation { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The uniquie user id that infos are for.
|
/// The uniquie user id that infos are for.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? ID { get; set; }
|
public string? ID { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The last time when the user has logged in to its account.
|
/// The last time when the user has logged in to its account.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime LastLogin { get; set; }
|
public DateTime LastLogin { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The backend of the user. Common values are "Database" or "LDAP".
|
/// The backend of the user. Common values are "Database" or "LDAP".
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Backend { get; set; }
|
public string? Backend { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Email address of the user.
|
/// The Email address of the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Email { get; set; }
|
public string? Email { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The displayname of the user.
|
/// The displayname of the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Displayname { get; set; }
|
public string? Displayname { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The displayname of the user.
|
/// The displayname of the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Displayname2 { get; set; }
|
public string? Displayname2 { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The phone number of the user.
|
/// The phone number of the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Phone { get; set; }
|
public string? Phone { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The address of the user.
|
/// The address of the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Address { get; set; }
|
public string? Address { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Website of the user.
|
/// The Website of the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Website { get; set; }
|
public string? Website { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The twitter profile name of the user.
|
/// The twitter profile name of the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Twitter { get; set; }
|
public string? Twitter { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the groups the user is member of.
|
/// Defines the groups the user is member of.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string[] Groups { get; set; }
|
public string[] Groups { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The configured language of the user.
|
/// The configured language of the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Language { get; set; }
|
public string? Language { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The configured location of the user.
|
/// The configured location of the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Locale { get; set; }
|
public string? Locale { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Quota informations for the user.
|
/// Quota informations for the user.
|
||||||
@@ -5,7 +5,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.Model
|
namespace Pilz.Networking.CloudProviders.Nextcloud.Model.Cloud
|
||||||
{
|
{
|
||||||
public class UserQuota
|
public class UserQuota
|
||||||
{
|
{
|
||||||
@@ -6,39 +6,62 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud;
|
using Pilz.Networking.CloudProviders.Nextcloud;
|
||||||
|
using Pilz.Networking.CloudProviders.Nextcloud.Client;
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.Model;
|
using Pilz.Networking.CloudProviders.Nextcloud.Model;
|
||||||
|
using Pilz.Networking.CloudProviders.Nextcloud.Model.Cloud;
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.OCS;
|
using Pilz.Networking.CloudProviders.Nextcloud.OCS;
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses.LoginFlowV2;
|
using Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses.LoginFlowV2;
|
||||||
|
|
||||||
namespace ConsoleApp9
|
namespace Pilz.Networking.CloudProviders.Nextcloud
|
||||||
{
|
{
|
||||||
public class NextcloudClient : IDisposable
|
public class NextcloudClient : IDisposable
|
||||||
{
|
{
|
||||||
private readonly OcsApi ocs = new();
|
private readonly List<ClientBase> clients = new();
|
||||||
|
|
||||||
|
public OcsApi Ocs { get; init; } = new();
|
||||||
public NextcloudLogin? CurrentLogin { get; private set; }
|
public NextcloudLogin? CurrentLogin { get; private set; }
|
||||||
|
|
||||||
|
public CloudClient Cloud => GetClient<CloudClient>();
|
||||||
|
|
||||||
public NextcloudClient()
|
public NextcloudClient()
|
||||||
{
|
{
|
||||||
ocs.GetOcsApiAuthCredentails += Ocs_GetOcsApiAuthCredentails;
|
Ocs.GetOcsApiAuthCredentails += Ocs_GetOcsApiAuthCredentails;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Ocs_GetOcsApiAuthCredentails(object sender, GetOcsApiAuthCredentailsEventArgs eventArgs)
|
private void Ocs_GetOcsApiAuthCredentails(object sender, GetOcsApiAuthCredentailsEventArgs eventArgs)
|
||||||
{
|
{
|
||||||
if (sender == ocs)
|
if (sender == Ocs)
|
||||||
eventArgs.Credentials = CurrentLogin.ToOcsApiAuthCredentials();
|
eventArgs.Credentials = CurrentLogin.ToOcsApiAuthCredentials();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<UserInfo?> LoginAsync(NextcloudLogin login)
|
public TClient GetClient<TClient>() where TClient : ClientBase
|
||||||
|
{
|
||||||
|
var instance = TryGetClient<TClient>();
|
||||||
|
return instance is null ? throw new NullReferenceException() : instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TClient? TryGetClient<TClient>() where TClient : ClientBase
|
||||||
|
{
|
||||||
|
TClient? instance = (TClient?)clients.FirstOrDefault(n => n is TClient);
|
||||||
|
|
||||||
|
instance ??= (TClient?)Activator.CreateInstance(typeof(TClient), new object[] { this });
|
||||||
|
|
||||||
|
if (instance is not null)
|
||||||
|
clients.Add(instance);
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<UserInfo?> Login(NextcloudLogin login)
|
||||||
{
|
{
|
||||||
// Ensure we are logged out
|
// Ensure we are logged out
|
||||||
await LogoutAsync();
|
await Logout();
|
||||||
|
|
||||||
// Temporary set user login
|
// Temporary set user login
|
||||||
CurrentLogin = login;
|
CurrentLogin = login;
|
||||||
|
|
||||||
// Try get user info & check if user is enabled
|
// Try get user info & check if user is enabled
|
||||||
var userInfo = await GetUserInfoAsync();
|
var userInfo = await Cloud.GetUserInfo();
|
||||||
var isValid = userInfo != null && userInfo.Enabled;
|
var isValid = userInfo != null && userInfo.Enabled;
|
||||||
|
|
||||||
// If invalid, reset login credentials
|
// If invalid, reset login credentials
|
||||||
@@ -48,13 +71,13 @@ namespace ConsoleApp9
|
|||||||
return userInfo;
|
return userInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<NextcloudLogin?> LoginAsync(string baseUrl, CancellationToken cancellationToken)
|
public async Task<NextcloudLogin?> Login(string baseUrl, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// Ensure we are logged out
|
// Ensure we are logged out
|
||||||
await LogoutAsync();
|
await Logout();
|
||||||
|
|
||||||
// Init the login process
|
// Init the login process
|
||||||
var initResponse = await ocs.LoginFlowV2.Init(baseUrl);
|
var initResponse = await Ocs.LoginFlowV2.Init(baseUrl);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(initResponse?.LoginUrl) && initResponse.Poll != null)
|
if (!string.IsNullOrEmpty(initResponse?.LoginUrl) && initResponse.Poll != null)
|
||||||
{
|
{
|
||||||
@@ -74,7 +97,7 @@ namespace ConsoleApp9
|
|||||||
|
|
||||||
// Poll the credentials
|
// Poll the credentials
|
||||||
if (!cancellationToken.IsCancellationRequested)
|
if (!cancellationToken.IsCancellationRequested)
|
||||||
pollResponse = await ocs.LoginFlowV2.Poll(initResponse.Poll);
|
pollResponse = await Ocs.LoginFlowV2.Poll(initResponse.Poll);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check login credentials
|
// Check login credentials
|
||||||
@@ -85,35 +108,18 @@ namespace ConsoleApp9
|
|||||||
return CurrentLogin;
|
return CurrentLogin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<UserInfo?> GetUserInfoAsync()
|
public Task Logout()
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(CurrentLogin?.LoginName))
|
return Logout(true);
|
||||||
return GetUserInfoAsync(CurrentLogin.LoginName);
|
|
||||||
else
|
|
||||||
return Task.FromResult<UserInfo?>(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<UserInfo?> GetUserInfoAsync(string username)
|
public async Task Logout(bool logoutOnServer)
|
||||||
{
|
|
||||||
var result = await ocs.Cloud.GetUserMeta(username);
|
|
||||||
|
|
||||||
if (result?.Data != null)
|
|
||||||
return new UserInfo(result.Data);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task LogoutAsync()
|
|
||||||
{
|
|
||||||
return LogoutAsync(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task LogoutAsync(bool logoutOnServer)
|
|
||||||
{
|
{
|
||||||
if (CurrentLogin != null)
|
if (CurrentLogin != null)
|
||||||
{
|
{
|
||||||
// Delete currently used app password
|
// Delete currently used app password
|
||||||
await ocs.Core.DeleteAppPassword();
|
if (logoutOnServer)
|
||||||
|
await Ocs.Core.DeleteAppPassword();
|
||||||
|
|
||||||
// Reset current login infos
|
// Reset current login infos
|
||||||
CurrentLogin = null;
|
CurrentLogin = null;
|
||||||
@@ -122,7 +128,7 @@ namespace ConsoleApp9
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
ocs.Dispose();
|
Ocs.Dispose();
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
using Pilz.Networking.CloudProviders.Nextcloud.OCS.Data.Apps.FileRetention;
|
||||||
|
using Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses;
|
||||||
|
using Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses.Apps.FilesRetention;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.APIs.Apps
|
||||||
|
{
|
||||||
|
public class OcsApiFilesRetention : OcsApiBase
|
||||||
|
{
|
||||||
|
public static readonly OcsApiUrlPath OCS_FILE_RETENTION_RULES = new("/ocs/v2.php/apps/files_retention/api/v1/retentions");
|
||||||
|
public static readonly OcsApiUrlPath OCS_FILE_RETENTION_RULE = new("/ocs/v2.php/apps/files_retention/api/v1/retentions/{0}");
|
||||||
|
|
||||||
|
public OcsApiFilesRetention(OcsApi manager) : base(manager)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> CreateRetentionRule(OcsDataRetentionRule rule)
|
||||||
|
{
|
||||||
|
var response = await Manager.MakeRequest(HttpMethod.Put, OCS_FILE_RETENTION_RULES, content: rule);
|
||||||
|
return response.IsSuccessStatusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> DeleteRetentionRule(int ruleID)
|
||||||
|
{
|
||||||
|
var response = await Manager.MakeRequest(HttpMethod.Delete, OCS_FILE_RETENTION_RULE.FillParameters(ruleID));
|
||||||
|
return response.IsSuccessStatusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<OcsResponseRetention?> GetRetentionRules()
|
||||||
|
{
|
||||||
|
return Manager.MakeRequest<OcsResponseRetention>(HttpMethod.Get, OCS_FILE_RETENTION_RULES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.APIs
|
|||||||
|
|
||||||
public Task<OcsResponseUser?> GetUserMeta(string username)
|
public Task<OcsResponseUser?> GetUserMeta(string username)
|
||||||
{
|
{
|
||||||
return Manager.MakeRequestJson<OcsResponseUser>(HttpMethod.Get, OCS_CLOUD_USER_METADATA.FillParameters(username));
|
return Manager.MakeRequest<OcsResponseUser>(HttpMethod.Get, OCS_CLOUD_USER_METADATA.FillParameters(username));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.APIs
|
|||||||
|
|
||||||
public Task<OcsResponseLoginFlowV2?> Init(string url)
|
public Task<OcsResponseLoginFlowV2?> Init(string url)
|
||||||
{
|
{
|
||||||
return Manager.MakeRequestJson<OcsResponseLoginFlowV2>(HttpMethod.Get, url + OCS_LOGIN_INIT);
|
return Manager.MakeRequest<OcsResponseLoginFlowV2>(HttpMethod.Get, url + OCS_LOGIN_INIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<OcsResponseLoginFlowV2Credentials?> Poll(OcsResponseLoginFlowV2.PollData poll)
|
public Task<OcsResponseLoginFlowV2Credentials?> Poll(OcsResponseLoginFlowV2.PollData poll)
|
||||||
@@ -25,7 +25,7 @@ namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.APIs
|
|||||||
ArgumentNullException.ThrowIfNull(poll?.Endpoint);
|
ArgumentNullException.ThrowIfNull(poll?.Endpoint);
|
||||||
ArgumentNullException.ThrowIfNull(poll?.Token);
|
ArgumentNullException.ThrowIfNull(poll?.Token);
|
||||||
|
|
||||||
return Manager.MakeRequestJson<OcsResponseLoginFlowV2Credentials?>(HttpMethod.Get, poll.Endpoint,
|
return Manager.MakeRequest<OcsResponseLoginFlowV2Credentials?>(HttpMethod.Get, poll.Endpoint,
|
||||||
parameters: new Dictionary<string, string>
|
parameters: new Dictionary<string, string>
|
||||||
{
|
{
|
||||||
{ "token", poll.Token }
|
{ "token", poll.Token }
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.Data.Apps.FileRetention
|
||||||
|
{
|
||||||
|
public class OcsDataRetentionRule : OcsData
|
||||||
|
{
|
||||||
|
|
||||||
|
[JsonProperty("tagid")]
|
||||||
|
public int? TagID { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("timeunit")]
|
||||||
|
public int? TimeUnit { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("timeamount")]
|
||||||
|
public int? TimeAmount { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("timeafter")]
|
||||||
|
public int? TimeAfter { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
12
Pilz.Networking.CloudProviders.Nextcloud/OCS/Data/OcsData.cs
Normal file
12
Pilz.Networking.CloudProviders.Nextcloud/OCS/Data/OcsData.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.Data
|
||||||
|
{
|
||||||
|
public class OcsData
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,26 +8,42 @@ using Newtonsoft.Json;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Pilz.Networking.CloudProviders.Nextcloud.OCS.APIs;
|
using Pilz.Networking.CloudProviders.Nextcloud.OCS.APIs;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using Pilz.Networking.CloudProviders.Nextcloud.OCS.Data;
|
||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.OCS
|
namespace Pilz.Networking.CloudProviders.Nextcloud.OCS
|
||||||
{
|
{
|
||||||
public class OcsApi : IDisposable
|
public class OcsApi : IDisposable
|
||||||
{
|
{
|
||||||
|
public const string CONTENT_TYPE_JSON = "application/json";
|
||||||
|
|
||||||
public event GetOcsApiAuthCredentailsEventHandler? GetOcsApiAuthCredentails;
|
public event GetOcsApiAuthCredentailsEventHandler? GetOcsApiAuthCredentails;
|
||||||
|
|
||||||
private readonly HttpClient client = new();
|
private readonly HttpClient client = new();
|
||||||
|
private readonly List<OcsApiBase> apis = new();
|
||||||
|
|
||||||
public string BaseUrl { get; set; } = string.Empty;
|
public string BaseUrl { get; set; } = string.Empty;
|
||||||
|
|
||||||
public OcsApiLoginFlowV2 LoginFlowV2 { get; init; }
|
public OcsApiLoginFlowV2 LoginFlowV2 => GetApi<OcsApiLoginFlowV2>();
|
||||||
public OcsApiCore Core { get; init; }
|
public OcsApiCore Core => GetApi<OcsApiCore>();
|
||||||
public OcsApiCloud Cloud { get; init; }
|
public OcsApiCloud Cloud => GetApi<OcsApiCloud>();
|
||||||
|
|
||||||
public OcsApi()
|
public TApi GetApi<TApi>() where TApi : OcsApiBase
|
||||||
{
|
{
|
||||||
LoginFlowV2 = new(this);
|
var instance = TryGetApi<TApi>();
|
||||||
Core = new(this);
|
return instance is null ? throw new NullReferenceException() : instance;
|
||||||
Cloud = new(this);
|
}
|
||||||
|
|
||||||
|
public TApi? TryGetApi<TApi>() where TApi : OcsApiBase
|
||||||
|
{
|
||||||
|
TApi? instance = (TApi?)apis.FirstOrDefault(n => n is TApi);
|
||||||
|
|
||||||
|
instance ??= (TApi?)Activator.CreateInstance(typeof(TApi), new object[] { this });
|
||||||
|
|
||||||
|
if (instance is not null)
|
||||||
|
apis.Add(instance);
|
||||||
|
|
||||||
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string BuildFullUrl(OcsApiUrlPath path)
|
public string BuildFullUrl(OcsApiUrlPath path)
|
||||||
@@ -35,19 +51,19 @@ namespace Pilz.Networking.CloudProviders.Nextcloud.OCS
|
|||||||
return BaseUrl + path;
|
return BaseUrl + path;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<TResponse?> MakeRequestJson<TResponse>(HttpMethod httpMethod, OcsApiUrlPath url, bool useAuthentication = true, Dictionary<string, string>? parameters = null)
|
public Task<TResponse?> MakeRequest<TResponse>(HttpMethod httpMethod, OcsApiUrlPath url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null)
|
||||||
{
|
{
|
||||||
return MakeRequestJson<TResponse>(httpMethod, BuildFullUrl(url), useAuthentication: useAuthentication, parameters: parameters);
|
return MakeRequest<TResponse>(httpMethod, BuildFullUrl(url), useAuthentication: useAuthentication, parameters: parameters, content: content);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<HttpResponseMessage> MakeRequest(HttpMethod httpMethod, OcsApiUrlPath url, bool useAuthentication = true, Dictionary<string, string>? parameters = null)
|
public Task<HttpResponseMessage> MakeRequest(HttpMethod httpMethod, OcsApiUrlPath url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null)
|
||||||
{
|
{
|
||||||
return MakeRequest(httpMethod, BuildFullUrl(url), useAuthentication: useAuthentication, parameters: parameters);
|
return MakeRequest(httpMethod, BuildFullUrl(url), useAuthentication: useAuthentication, parameters: parameters, content: content);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<TResponse?> MakeRequestJson<TResponse>(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary<string, string>? parameters = null)
|
public async Task<TResponse?> MakeRequest<TResponse>(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null)
|
||||||
{
|
{
|
||||||
using var responseInit = await MakeRequest(httpMethod, url, useAuthentication: useAuthentication, parameters: parameters);
|
using var responseInit = await MakeRequest(httpMethod, url, useAuthentication: useAuthentication, parameters: parameters, content: content);
|
||||||
|
|
||||||
if (responseInit != null)
|
if (responseInit != null)
|
||||||
{
|
{
|
||||||
@@ -58,10 +74,11 @@ namespace Pilz.Networking.CloudProviders.Nextcloud.OCS
|
|||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<HttpResponseMessage> MakeRequest(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary<string, string>? parameters = null)
|
public async Task<HttpResponseMessage> MakeRequest(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null)
|
||||||
{
|
{
|
||||||
OcsApiAuthCredentials? authentication;
|
OcsApiAuthCredentials? authentication;
|
||||||
string @params;
|
string @params;
|
||||||
|
HttpContent? httpContent;
|
||||||
|
|
||||||
// Get authentication
|
// Get authentication
|
||||||
if (useAuthentication)
|
if (useAuthentication)
|
||||||
@@ -79,6 +96,14 @@ namespace Pilz.Networking.CloudProviders.Nextcloud.OCS
|
|||||||
else
|
else
|
||||||
@params = string.Empty;
|
@params = string.Empty;
|
||||||
|
|
||||||
|
// Create content
|
||||||
|
if (content is HttpContent contentHttp)
|
||||||
|
httpContent = contentHttp;
|
||||||
|
else if (content is OcsData)
|
||||||
|
httpContent = new StringContent(JsonConvert.SerializeObject(content), null, CONTENT_TYPE_JSON);
|
||||||
|
else
|
||||||
|
httpContent = null;
|
||||||
|
|
||||||
// Send request
|
// Send request
|
||||||
var request = new HttpRequestMessage
|
var request = new HttpRequestMessage
|
||||||
{
|
{
|
||||||
@@ -86,10 +111,11 @@ namespace Pilz.Networking.CloudProviders.Nextcloud.OCS
|
|||||||
RequestUri = new Uri(url + @params),
|
RequestUri = new Uri(url + @params),
|
||||||
Headers =
|
Headers =
|
||||||
{
|
{
|
||||||
{ "Accept", "application/json" },
|
{ "Accept", CONTENT_TYPE_JSON },
|
||||||
{ "OCS-APIREQUEST", "true" },
|
{ "OCS-APIREQUEST", "true" },
|
||||||
{ "Authorization", authentication.ToBasicAuth() }
|
{ "Authorization", authentication.ToBasicAuth() }
|
||||||
},
|
},
|
||||||
|
Content = httpContent
|
||||||
};
|
};
|
||||||
|
|
||||||
return await client.SendAsync(request);
|
return await client.SendAsync(request);
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses.Apps.FilesRetention
|
||||||
|
{
|
||||||
|
public class OcsResponseDataEntryRetention : OcsResponseDataEntry
|
||||||
|
{
|
||||||
|
[JsonProperty("id")]
|
||||||
|
public int? ID { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("tagid")]
|
||||||
|
public int? TagID { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("timeunit")]
|
||||||
|
public int? TimeUnit { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("timeamount")]
|
||||||
|
public int? TimeAmount { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("timeafter")]
|
||||||
|
public int? TimeAfter { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("hasJob")]
|
||||||
|
public bool? HasJob { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses.Apps.FilesRetention
|
||||||
|
{
|
||||||
|
public class OcsResponseRetention : OcsResponse<OcsResponseDataArray<OcsResponseDataEntryRetention>>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses
|
||||||
|
{
|
||||||
|
public interface IOcsResponseData
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses
|
namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses
|
||||||
{
|
{
|
||||||
public class OcsResponse<TMeta, TData> where TMeta : OcsResponseMeta where TData : OcsResponseData
|
public class OcsResponse<TMeta, TData> where TMeta : OcsResponseMeta where TData : IOcsResponseData
|
||||||
{
|
{
|
||||||
[JsonProperty("meta")]
|
[JsonProperty("meta")]
|
||||||
public TMeta? Meta { get; set; }
|
public TMeta? Meta { get; set; }
|
||||||
@@ -16,11 +16,11 @@ namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses
|
|||||||
public TData? Data { get; set; }
|
public TData? Data { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class OcsResponse<TData> : OcsResponse<OcsResponseMeta, TData> where TData : OcsResponseData
|
public class OcsResponse<TData> : OcsResponse<OcsResponseMeta, TData> where TData : IOcsResponseData
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public class OcsResponse : OcsResponse<OcsResponseMeta, OcsResponseData>
|
public class OcsResponse : OcsResponse<OcsResponseMeta, IOcsResponseData>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses
|
namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses
|
||||||
{
|
{
|
||||||
public class OcsResponseData
|
public class OcsResponseData : IOcsResponseData
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses
|
||||||
|
{
|
||||||
|
public class OcsResponseDataArray<TEntry> : List<TEntry>, IOcsResponseData where TEntry : OcsResponseDataEntry
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Pilz.Networking.CloudProviders.Nextcloud.OCS.Responses
|
||||||
|
{
|
||||||
|
public class OcsResponseDataEntry
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||||
<IncrementVersionOnBuild>1.yyyy.Mdd.Hmm</IncrementVersionOnBuild>
|
<IncrementVersionOnBuild>1.yyyy.Mdd.Hmm</IncrementVersionOnBuild>
|
||||||
<Version>1.2023.927.1412</Version>
|
<Version>1.2023.1001.1650</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,21 +1,19 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0-windows</TargetFramework>
|
<TargetFramework>net6.0-windows</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<RootNamespace>Pilz.UI.Telerik</RootNamespace>
|
<RootNamespace>Pilz.UI.Telerik</RootNamespace>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||||
<IncrementVersionOnBuild>1.yyyy.Mdd.Hmm</IncrementVersionOnBuild>
|
<IncrementVersionOnBuild>1.yyyy.Mdd.Hmm</IncrementVersionOnBuild>
|
||||||
<Version>1.2023.914.1955</Version>
|
<Version>1.2023.914.1955</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
|
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
|
||||||
<PackageReference Include="UI.for.WinForms.AllControls.Net60" Version="2023.1.117" />
|
<PackageReference Include="UI.for.WinForms.AllControls.Net60">
|
||||||
|
<Version>2023.2.718</Version>
|
||||||
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,20 +1,18 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0-windows</TargetFramework>
|
<TargetFramework>net6.0-windows</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<UseWindowsForms>true</UseWindowsForms>
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||||
<IncrementVersionOnBuild>1.yyyy.Mdd.Hmm</IncrementVersionOnBuild>
|
<IncrementVersionOnBuild>1.yyyy.Mdd.Hmm</IncrementVersionOnBuild>
|
||||||
<Version>1.2023.914.856</Version>
|
<Version>1.2023.914.856</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="UI.for.WinForms.AllControls.Net60" Version="2023.1.117" />
|
<PackageReference Include="UI.for.WinForms.AllControls.Net60">
|
||||||
|
<Version>2023.2.718</Version>
|
||||||
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
Reference in New Issue
Block a user