code optimization

This commit is contained in:
2024-06-05 19:15:32 +02:00
parent d4be7d0566
commit 1b49c54822
151 changed files with 4124 additions and 4673 deletions

View File

@@ -1,5 +1,4 @@
Imports System.Reflection Imports System.Reflection
Imports System.Runtime.InteropServices
Namespace SimpleHistory Namespace SimpleHistory

View File

@@ -1,6 +1,4 @@
Imports System.Reflection Namespace SimpleHistory
Namespace SimpleHistory
Public Class HistoryStack Public Class HistoryStack

View File

@@ -1,87 +1,86 @@
using System; using System;
namespace Pilz.Configuration namespace Pilz.Configuration;
public class AutoSaveConfigurationManager : ConfigurationManager
{ {
public class AutoSaveConfigurationManager : ConfigurationManager private bool addedHandler = false;
private bool enableAutoSave = false;
private string _ConfigFilePath = string.Empty;
private bool _AutoLoadConfigOnAccess = false;
public string ConfigFilePath
{ {
private bool addedHandler = false; get => _ConfigFilePath;
private bool enableAutoSave = false; set
private string _ConfigFilePath = string.Empty;
private bool _AutoLoadConfigOnAccess = false;
public string ConfigFilePath
{ {
get => _ConfigFilePath; _ConfigFilePath = value;
set if (AutoLoadConfigOnAccess)
{ Load();
_ConfigFilePath = value;
if (AutoLoadConfigOnAccess)
Load();
}
}
public bool AutoLoadConfigOnAccess
{
get => _AutoLoadConfigOnAccess;
set
{
_AutoLoadConfigOnAccess = value;
if (value)
Load();
}
}
public bool AutoSaveConfigOnExit
{
get => enableAutoSave;
set
{
if (enableAutoSave != value)
{
enableAutoSave = value;
if (enableAutoSave)
AddAutoSaveHandler();
else
RemoveAutoSaveHandler();
}
}
}
private void AddAutoSaveHandler()
{
if (!addedHandler)
{
AppDomain.CurrentDomain.ProcessExit += AutoSaveSettingsOnExit;
addedHandler = true;
}
}
private void RemoveAutoSaveHandler()
{
AppDomain.CurrentDomain.ProcessExit -= AutoSaveSettingsOnExit;
addedHandler = false;
}
private void AutoSaveSettingsOnExit(object sender, EventArgs e)
{
Save();
}
private void Save()
{
if (!string.IsNullOrEmpty(ConfigFilePath) && Configuration is not null)
Configuration.WriteToFile(ConfigFilePath);
}
private void Load()
{
if (!string.IsNullOrEmpty(ConfigFilePath))
Configuration.ReadFromFile(ConfigFilePath);
}
~AutoSaveConfigurationManager()
{
RemoveAutoSaveHandler();
} }
} }
public bool AutoLoadConfigOnAccess
{
get => _AutoLoadConfigOnAccess;
set
{
_AutoLoadConfigOnAccess = value;
if (value)
Load();
}
}
public bool AutoSaveConfigOnExit
{
get => enableAutoSave;
set
{
if (enableAutoSave != value)
{
enableAutoSave = value;
if (enableAutoSave)
AddAutoSaveHandler();
else
RemoveAutoSaveHandler();
}
}
}
private void AddAutoSaveHandler()
{
if (!addedHandler)
{
AppDomain.CurrentDomain.ProcessExit += AutoSaveSettingsOnExit;
addedHandler = true;
}
}
private void RemoveAutoSaveHandler()
{
AppDomain.CurrentDomain.ProcessExit -= AutoSaveSettingsOnExit;
addedHandler = false;
}
private void AutoSaveSettingsOnExit(object sender, EventArgs e)
{
Save();
}
private void Save()
{
if (!string.IsNullOrEmpty(ConfigFilePath) && Configuration is not null)
Configuration.WriteToFile(ConfigFilePath);
}
private void Load()
{
if (!string.IsNullOrEmpty(ConfigFilePath))
Configuration.ReadFromFile(ConfigFilePath);
}
~AutoSaveConfigurationManager()
{
RemoveAutoSaveHandler();
}
} }

View File

@@ -1,12 +1,11 @@
namespace Pilz.Configuration namespace Pilz.Configuration;
{
public abstract class ConfigurationManager
{
public SimpleConfiguration Configuration { get; private set; }
internal void SetConfiguration(SimpleConfiguration configuration) public abstract class ConfigurationManager
{ {
Configuration = configuration; public SimpleConfiguration Configuration { get; private set; }
}
internal void SetConfiguration(SimpleConfiguration configuration)
{
Configuration = configuration;
} }
} }

View File

@@ -1,88 +1,87 @@
using System.Collections; using Pilz.GeneralEventArgs;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using Pilz.GeneralEventArgs;
namespace Pilz.Configuration namespace Pilz.Configuration;
public class ConfigurationManagerList : IList<ConfigurationManager>
{ {
public class ConfigurationManagerList : IList<ConfigurationManager> public event GettingParentManagerEventHandler GettingParentManager;
public delegate void GettingParentManagerEventHandler(object sender, GetValueEventArgs<SimpleConfiguration> e);
private readonly List<ConfigurationManager> myList = new List<ConfigurationManager>();
private object GetParentManager()
{ {
public event GettingParentManagerEventHandler GettingParentManager; var args = new GetValueEventArgs<SimpleConfiguration>();
GettingParentManager?.Invoke(this, args);
public delegate void GettingParentManagerEventHandler(object sender, GetValueEventArgs<SimpleConfiguration> e); return args.Value;
private readonly List<ConfigurationManager> myList = new List<ConfigurationManager>();
private object GetParentManager()
{
var args = new GetValueEventArgs<SimpleConfiguration>();
GettingParentManager?.Invoke(this, args);
return args.Value;
}
public ConfigurationManager this[int index]
{
get => myList[index];
set => myList[index] = value;
}
public int Count => myList.Count;
public bool IsReadOnly => false;
public void Insert(int index, ConfigurationManager item)
{
myList.Insert(index, item);
item.SetConfiguration((SimpleConfiguration)GetParentManager());
}
public void RemoveAt(int index)
{
}
public void Add(ConfigurationManager item)
{
item.SetConfiguration((SimpleConfiguration)GetParentManager());
}
public void Clear()
{
foreach (ConfigurationManager item in myList)
item.SetConfiguration(null);
myList.Clear();
}
public void CopyTo(ConfigurationManager[] array, int arrayIndex)
{
myList.CopyTo(array, arrayIndex);
}
public int IndexOf(ConfigurationManager item)
{
return myList.IndexOf(item);
}
public bool Contains(ConfigurationManager item)
{
return myList.Contains(item);
}
public bool Remove(ConfigurationManager item)
{
item.SetConfiguration(null);
return myList.Remove(item);
}
public IEnumerator<ConfigurationManager> GetEnumerator()
{
return (IEnumerator<ConfigurationManager>)IEnumerable_GetEnumerator();
}
private IEnumerator IEnumerable_GetEnumerator()
{
return myList.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() => IEnumerable_GetEnumerator();
} }
public ConfigurationManager this[int index]
{
get => myList[index];
set => myList[index] = value;
}
public int Count => myList.Count;
public bool IsReadOnly => false;
public void Insert(int index, ConfigurationManager item)
{
myList.Insert(index, item);
item.SetConfiguration((SimpleConfiguration)GetParentManager());
}
public void RemoveAt(int index)
{
}
public void Add(ConfigurationManager item)
{
item.SetConfiguration((SimpleConfiguration)GetParentManager());
}
public void Clear()
{
foreach (ConfigurationManager item in myList)
item.SetConfiguration(null);
myList.Clear();
}
public void CopyTo(ConfigurationManager[] array, int arrayIndex)
{
myList.CopyTo(array, arrayIndex);
}
public int IndexOf(ConfigurationManager item)
{
return myList.IndexOf(item);
}
public bool Contains(ConfigurationManager item)
{
return myList.Contains(item);
}
public bool Remove(ConfigurationManager item)
{
item.SetConfiguration(null);
return myList.Remove(item);
}
public IEnumerator<ConfigurationManager> GetEnumerator()
{
return (IEnumerator<ConfigurationManager>)IEnumerable_GetEnumerator();
}
private IEnumerator IEnumerable_GetEnumerator()
{
return myList.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() => IEnumerable_GetEnumerator();
} }

View File

@@ -1,139 +1,138 @@
using System.IO; using Newtonsoft.Json;
using Newtonsoft.Json;
using Pilz.GeneralEventArgs; using Pilz.GeneralEventArgs;
using System.IO;
namespace Pilz.Configuration namespace Pilz.Configuration;
public static class ConfigurationSerializer
{ {
public static class ConfigurationSerializer public static event GettingJsonSerializerEventHandler GettingJsonSerializer;
public delegate void GettingJsonSerializerEventHandler(object instance, GetValueEventArgs<JsonSerializer> e);
private static JsonSerializer GetJsonSerializer(SimpleConfiguration instance)
{ {
public static event GettingJsonSerializerEventHandler GettingJsonSerializer; var args = new GetValueEventArgs<JsonSerializer>(JsonSerializer.CreateDefault());
GettingJsonSerializer?.Invoke(instance, args);
return args.Value;
}
public delegate void GettingJsonSerializerEventHandler(object instance, GetValueEventArgs<JsonSerializer> e); /// <summary>
/// Writes the given instance to a string and return it.
/// </summary>
/// <param name="instance">The configuration instance that should be serialized.</param>
/// <returns>The content of the configuration instance as string.</returns>
public static string WriteToString(SimpleConfiguration instance)
{
var tw = new StringWriter();
GetJsonSerializer(instance).Serialize(tw, instance);
string txt = tw.ToString();
tw.Close();
return txt;
}
private static JsonSerializer GetJsonSerializer(SimpleConfiguration instance) /// <summary>
{ /// Write the given instance to a given stream.
var args = new GetValueEventArgs<JsonSerializer>(JsonSerializer.CreateDefault()); /// </summary>
GettingJsonSerializer?.Invoke(instance, args); /// <param name="instance">The configuration instance that should be serialized.</param>
return args.Value; /// <param name="stream">The stream where the content should be written to.</param>
} public static void WriteToStream(SimpleConfiguration instance, Stream stream)
{
var sr = new StreamWriter(stream);
sr.Write(WriteToString(instance));
}
/// <summary> /// <summary>
/// Writes the given instance to a string and return it. /// Writes the given instance to the given filePath as text file.
/// </summary> /// </summary>
/// <param name="instance">The configuration instance that should be serialized.</param> /// <param name="instance">The configuration instance that should be serialized.</param>
/// <returns>The content of the configuration instance as string.</returns> /// <param name="filePath">The file path where the content should be written to. The file will be created or overwritten.</param>
public static string WriteToString(SimpleConfiguration instance) public static void WriteToFile(SimpleConfiguration instance, string filePath)
{ {
var tw = new StringWriter(); var fs = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite);
GetJsonSerializer(instance).Serialize(tw, instance); WriteToStream(instance, fs);
string txt = tw.ToString(); fs.Close();
tw.Close(); }
return txt;
}
/// <summary> /// <summary>
/// Write the given instance to a given stream. /// Reads a configuratin from the given string and returns an instance of it.
/// </summary> /// </summary>
/// <param name="instance">The configuration instance that should be serialized.</param> /// <typeparam name="T">The type of the configuration class to instance.</typeparam>
/// <param name="stream">The stream where the content should be written to.</param> /// <param name="content">The content of the configuration as string.</param>
public static void WriteToStream(SimpleConfiguration instance, Stream stream) /// <returns></returns>
{ public static T ReadFromString<T>(string content) where T : SimpleConfiguration
var sr = new StreamWriter(stream); {
sr.Write(WriteToString(instance)); var sr = new StringReader(content);
} T instance = (T)GetJsonSerializer(null).Deserialize(sr, typeof(T));
sr.Close();
return instance;
}
/// <summary> /// <summary>
/// Writes the given instance to the given filePath as text file. /// Read a configuration from the given string and put them to the given instance.
/// </summary> /// </summary>
/// <param name="instance">The configuration instance that should be serialized.</param> /// <param name="instance">The instance to populate with the configuration.</param>
/// <param name="filePath">The file path where the content should be written to. The file will be created or overwritten.</param> /// <param name="content">The content of the configuration as string.</param>
public static void WriteToFile(SimpleConfiguration instance, string filePath) public static void ReadFromString(SimpleConfiguration instance, string content)
{ {
var fs = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite); var sr = new StringReader(content);
WriteToStream(instance, fs); GetJsonSerializer(null).Populate(sr, content);
fs.Close(); sr.Close();
} }
/// <summary> /// <summary>
/// Reads a configuratin from the given string and returns an instance of it. /// Reads a configuratin from the given string and returns an instance of it.
/// </summary> /// </summary>
/// <typeparam name="T">The type of the configuration class to instance.</typeparam> /// <typeparam name="T">The type of the configuration class to instance.</typeparam>
/// <param name="content">The content of the configuration as string.</param> /// <param name="stream">The stream with the content of the configuration.</param>
/// <returns></returns> /// <returns></returns>
public static T ReadFromString<T>(string content) where T : SimpleConfiguration public static T ReadFromStream<T>(Stream stream) where T : SimpleConfiguration
{ {
var sr = new StringReader(content); return ReadFromString<T>(GetContentOfStream(stream));
T instance = (T)GetJsonSerializer(null).Deserialize(sr, typeof(T)); }
sr.Close();
return instance;
}
/// <summary> /// <summary>
/// Read a configuration from the given string and put them to the given instance. /// Read a configuration from the given string and put them to the given instance.
/// </summary> /// </summary>
/// <param name="instance">The instance to populate with the configuration.</param> /// <param name="instance">The instance to populate with the configuration.</param>
/// <param name="content">The content of the configuration as string.</param> /// <param name="stream">The stream with the content of the configuration.</param>
public static void ReadFromString(SimpleConfiguration instance, string content) public static void ReadFromStream(SimpleConfiguration instance, Stream stream)
{ {
var sr = new StringReader(content); ReadFromString(instance, GetContentOfStream(stream));
GetJsonSerializer(null).Populate(sr, content); }
sr.Close();
}
/// <summary> /// <summary>
/// Reads a configuratin from the given string and returns an instance of it. /// Reads a configuratin from the given string and returns an instance of it.
/// </summary> /// </summary>
/// <typeparam name="T">The type of the configuration class to instance.</typeparam> /// <typeparam name="T">The type of the configuration class to instance.</typeparam>
/// <param name="stream">The stream with the content of the configuration.</param> /// <param name="filePath">The path to the file with the content of the configuration.</param>
/// <returns></returns> /// <returns></returns>
public static T ReadFromStream<T>(Stream stream) where T : SimpleConfiguration public static T ReadFromFile<T>(string filePath) where T : SimpleConfiguration
{ {
return ReadFromString<T>(GetContentOfStream(stream)); return ReadFromString<T>(GetContentOfFile(filePath));
} }
/// <summary> /// <summary>
/// Read a configuration from the given string and put them to the given instance. /// Read a configuration from the given string and put them to the given instance.
/// </summary> /// </summary>
/// <param name="instance">The instance to populate with the configuration.</param> /// <param name="instance">The instance to populate with the configuration.</param>
/// <param name="stream">The stream with the content of the configuration.</param> /// <param name="filePath">The path to the file with the content of the configuration.</param>
public static void ReadFromStream(SimpleConfiguration instance, Stream stream) public static void ReadFromFile(SimpleConfiguration instance, string filePath)
{ {
ReadFromString(instance, GetContentOfStream(stream)); ReadFromString(instance, GetContentOfFile(filePath));
} }
/// <summary> private static string GetContentOfStream(Stream stream)
/// Reads a configuratin from the given string and returns an instance of it. {
/// </summary> var sr = new StreamReader(stream);
/// <typeparam name="T">The type of the configuration class to instance.</typeparam> return sr.ReadToEnd();
/// <param name="filePath">The path to the file with the content of the configuration.</param> }
/// <returns></returns>
public static T ReadFromFile<T>(string filePath) where T : SimpleConfiguration
{
return ReadFromString<T>(GetContentOfFile(filePath));
}
/// <summary> private static string GetContentOfFile(string filePath)
/// Read a configuration from the given string and put them to the given instance. {
/// </summary> var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
/// <param name="instance">The instance to populate with the configuration.</param> string content = GetContentOfStream(fs);
/// <param name="filePath">The path to the file with the content of the configuration.</param> fs.Close();
public static void ReadFromFile(SimpleConfiguration instance, string filePath) return content;
{
ReadFromString(instance, GetContentOfFile(filePath));
}
private static string GetContentOfStream(Stream stream)
{
var sr = new StreamReader(stream);
return sr.ReadToEnd();
}
private static string GetContentOfFile(string filePath)
{
var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
string content = GetContentOfStream(fs);
fs.Close();
return content;
}
} }
} }

View File

@@ -1,7 +1,6 @@
namespace Pilz.Configuration namespace Pilz.Configuration;
public interface IChildSettings
{ {
public interface IChildSettings void Reset();
{
void Reset();
}
} }

View File

@@ -1,11 +1,10 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Pilz.Configuration namespace Pilz.Configuration;
public interface ISettings
{ {
public interface ISettings IReadOnlyCollection<IChildSettings> Childs { get; }
{ T Get<T>() where T : IChildSettings, ISettingsIdentifier;
IReadOnlyCollection<IChildSettings> Childs { get; } void Reset();
T Get<T>() where T : IChildSettings, ISettingsIdentifier;
void Reset();
}
} }

View File

@@ -1,13 +1,6 @@
using System; namespace Pilz.Configuration;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Configuration public interface ISettingsIdentifier
{ {
public interface ISettingsIdentifier static abstract string Identifier { get; }
{
static abstract string Identifier { get; }
}
} }

View File

@@ -1,11 +1,10 @@
namespace Pilz.Configuration namespace Pilz.Configuration;
public interface ISettingsManager
{ {
public interface ISettingsManager ISettings Instance { get; }
{ void Save();
ISettings Instance { get; } void Load();
void Save(); void Reset();
void Load();
void Reset();
}
} }

View File

@@ -1,37 +1,35 @@
using System; using Newtonsoft.Json;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
namespace Pilz.Configuration namespace Pilz.Configuration;
public class Settings : ISettings
{ {
public class Settings : ISettings [JsonProperty(nameof(Settings))]
protected readonly Dictionary<string, IChildSettings> mySettings = [];
[JsonIgnore]
public IReadOnlyCollection<IChildSettings> Childs => mySettings.Values;
public T Get<T>() where T : IChildSettings, ISettingsIdentifier
{ {
[JsonProperty(nameof(Settings))] if (mySettings.TryGetValue(T.Identifier, out IChildSettings valueExisting) && valueExisting is T settingsExisting)
protected readonly Dictionary<string, IChildSettings> mySettings = []; return settingsExisting;
[JsonIgnore] if (Activator.CreateInstance<T>() is T settingsNew)
public IReadOnlyCollection<IChildSettings> Childs => mySettings.Values;
public T Get<T>() where T : IChildSettings, ISettingsIdentifier
{ {
if (mySettings.TryGetValue(T.Identifier, out IChildSettings valueExisting) && valueExisting is T settingsExisting) settingsNew.Reset();
return settingsExisting; mySettings.Add(T.Identifier, settingsNew);
return settingsNew;
if (Activator.CreateInstance<T>() is T settingsNew)
{
settingsNew.Reset();
mySettings.Add(T.Identifier, settingsNew);
return settingsNew;
}
return default;
} }
public void Reset() return default;
{ }
foreach (var s in mySettings.Values)
s.Reset(); public void Reset()
} {
foreach (var s in mySettings.Values)
s.Reset();
} }
} }

View File

@@ -1,142 +1,139 @@
using System; using Newtonsoft.Json;
using System.Collections.Generic; using System;
using System.IO; using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs; using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
namespace Pilz.Configuration namespace Pilz.Configuration;
public class SettingsManager : ISettingsManager
{ {
public class SettingsManager : ISettingsManager public event EventHandler AutoSavingSettings;
public event EventHandler SavingSettings;
public event EventHandler SavedSettings;
public event EventHandler<ErrorEventArgs> OnSerializationError;
protected ISettings defaultInstance = null;
protected bool enableAutoSave = false;
protected bool addedHandler = false;
public string ConfigFilePath { get; set; }
public ISettings Instance
{ {
public event EventHandler AutoSavingSettings; get
public event EventHandler SavingSettings;
public event EventHandler SavedSettings;
public event EventHandler<ErrorEventArgs> OnSerializationError;
protected ISettings defaultInstance = null;
protected bool enableAutoSave = false;
protected bool addedHandler = false;
public string ConfigFilePath { get; set; }
public ISettings Instance
{ {
get if (defaultInstance is null)
{ Load();
if (defaultInstance is null) return defaultInstance;
Load();
return defaultInstance;
}
} }
}
public bool AutoSaveOnExit public bool AutoSaveOnExit
{
get => enableAutoSave;
set
{ {
get => enableAutoSave; if (enableAutoSave != value)
set
{ {
if (enableAutoSave != value) enableAutoSave = value;
if (enableAutoSave)
{ {
enableAutoSave = value; if (!addedHandler)
if (enableAutoSave) AddAutoSaveHandler();
{ }
if (!addedHandler) else
AddAutoSaveHandler(); {
} if (addedHandler)
else RemoveAutoSaveHandler();
{
if (addedHandler)
RemoveAutoSaveHandler();
}
} }
} }
} }
}
public SettingsManager() public SettingsManager()
{
}
public SettingsManager(string fileName, bool autoSaveOnExit) : this()
{
ConfigFilePath = fileName;
AutoSaveOnExit = autoSaveOnExit;
}
protected void AddAutoSaveHandler()
{
AppDomain.CurrentDomain.ProcessExit += AutoSaveSettingsOnExit;
addedHandler = true;
}
protected void RemoveAutoSaveHandler()
{
AppDomain.CurrentDomain.ProcessExit -= AutoSaveSettingsOnExit;
addedHandler = false;
}
private void AutoSaveSettingsOnExit(object sender, EventArgs e)
{
AutoSavingSettings?.Invoke(this, new EventArgs());
Save();
}
public void Save()
{
if (!string.IsNullOrEmpty(ConfigFilePath) && defaultInstance is not null)
SaveInternal();
}
public void Load()
{
if (!string.IsNullOrEmpty(ConfigFilePath) && File.Exists(ConfigFilePath))
LoadInternal();
else
CreateNewInstance();
}
public void Reset()
{
Instance.Reset();
}
protected virtual void CreateNewInstance()
{
defaultInstance = new Settings();
defaultInstance.Reset();
}
protected virtual void LoadInternal()
{
defaultInstance = JsonConvert.DeserializeObject<Settings>(File.ReadAllText(ConfigFilePath), CreateJsonSerializerSettings());
}
protected virtual void SaveInternal()
{
SavingSettings?.Invoke(this, EventArgs.Empty);
File.WriteAllText(ConfigFilePath, JsonConvert.SerializeObject(defaultInstance, CreateJsonSerializerSettings()));
SavedSettings?.Invoke(this, EventArgs.Empty);
}
protected virtual JsonSerializerSettings CreateJsonSerializerSettings()
{
return new JsonSerializerSettings()
{ {
} Formatting = Formatting.Indented,
TypeNameHandling = TypeNameHandling.Auto,
Error = JsonSerializer_OnError,
};
}
public SettingsManager(string fileName, bool autoSaveOnExit) : this() protected virtual void JsonSerializer_OnError(object sender, ErrorEventArgs e)
{ {
ConfigFilePath = fileName; const string errorResolvingType = "Error resolving type specified in JSON";
AutoSaveOnExit = autoSaveOnExit;
}
protected void AddAutoSaveHandler() // Invoke event
{ OnSerializationError?.Invoke(sender, e);
AppDomain.CurrentDomain.ProcessExit += AutoSaveSettingsOnExit;
addedHandler = true;
}
protected void RemoveAutoSaveHandler() // Handle ourself
{ if (!e.ErrorContext.Handled && e.ErrorContext.Error is JsonSerializationException serializationException && serializationException.Message.StartsWith(errorResolvingType))
AppDomain.CurrentDomain.ProcessExit -= AutoSaveSettingsOnExit; e.ErrorContext.Handled = true;
addedHandler = false;
}
private void AutoSaveSettingsOnExit(object sender, EventArgs e)
{
AutoSavingSettings?.Invoke(this, new EventArgs());
Save();
}
public void Save()
{
if (!string.IsNullOrEmpty(ConfigFilePath) && defaultInstance is not null)
SaveInternal();
}
public void Load()
{
if (!string.IsNullOrEmpty(ConfigFilePath) && File.Exists(ConfigFilePath))
LoadInternal();
else
CreateNewInstance();
}
public void Reset()
{
Instance.Reset();
}
protected virtual void CreateNewInstance()
{
defaultInstance = new Settings();
defaultInstance.Reset();
}
protected virtual void LoadInternal()
{
defaultInstance = JsonConvert.DeserializeObject<Settings>(File.ReadAllText(ConfigFilePath), CreateJsonSerializerSettings());
}
protected virtual void SaveInternal()
{
SavingSettings?.Invoke(this, EventArgs.Empty);
File.WriteAllText(ConfigFilePath, JsonConvert.SerializeObject(defaultInstance, CreateJsonSerializerSettings()));
SavedSettings?.Invoke(this, EventArgs.Empty);
}
protected virtual JsonSerializerSettings CreateJsonSerializerSettings()
{
return new JsonSerializerSettings()
{
Formatting = Formatting.Indented,
TypeNameHandling = TypeNameHandling.Auto,
Error = JsonSerializer_OnError,
};
}
protected virtual void JsonSerializer_OnError(object sender, ErrorEventArgs e)
{
const string errorResolvingType = "Error resolving type specified in JSON";
// Invoke event
OnSerializationError?.Invoke(sender, e);
// Handle ourself
if (!e.ErrorContext.Handled && e.ErrorContext.Error is JsonSerializationException serializationException && serializationException.Message.StartsWith(errorResolvingType))
e.ErrorContext.Handled = true;
}
} }
} }

View File

@@ -1,110 +1,109 @@
using System.IO; using Newtonsoft.Json;
using Newtonsoft.Json;
using Pilz.GeneralEventArgs; using Pilz.GeneralEventArgs;
using System.IO;
namespace Pilz.Configuration namespace Pilz.Configuration;
public class SimpleConfiguration
{ {
public class SimpleConfiguration [JsonIgnore]
public readonly ConfigurationManagerList Managers = new ConfigurationManagerList();
public SimpleConfiguration()
{ {
[JsonIgnore] Managers.GettingParentManager += Managers_GettingParentManager;
public readonly ConfigurationManagerList Managers = new ConfigurationManagerList(); }
public SimpleConfiguration() private void Managers_GettingParentManager(object sender, GetValueEventArgs<SimpleConfiguration> e)
{ {
Managers.GettingParentManager += Managers_GettingParentManager; if (ReferenceEquals(sender, Managers))
} e.Value = this;
}
private void Managers_GettingParentManager(object sender, GetValueEventArgs<SimpleConfiguration> e) /// <summary>
{ /// Writes this instance to a string and return it.
if (ReferenceEquals(sender, Managers)) /// </summary>
e.Value = this; /// <returns>The content of the configuration instance as string.</returns>
} public string WriteToString()
{
return ConfigurationSerializer.WriteToString(this);
}
/// <summary> /// <summary>
/// Writes this instance to a string and return it. /// Write this instance to a given stream.
/// </summary> /// </summary>
/// <returns>The content of the configuration instance as string.</returns> /// <param name="stream">The stream where the content should be written to.</param>
public string WriteToString() public void WriteToStream(Stream stream)
{ {
return ConfigurationSerializer.WriteToString(this); ConfigurationSerializer.WriteToStream(this, stream);
} }
/// <summary> /// <summary>
/// Write this instance to a given stream. /// Writes this instance to the given filePath as text file.
/// </summary> /// </summary>
/// <param name="stream">The stream where the content should be written to.</param> /// <param name="filePath">The file path where the content should be written to. The file will be created or overwritten.</param>
public void WriteToStream(Stream stream) public void WriteToFile(string filePath)
{ {
ConfigurationSerializer.WriteToStream(this, stream); ConfigurationSerializer.WriteToFile(this, filePath);
} }
/// <summary> /// <summary>
/// Writes this instance to the given filePath as text file. /// Reads a configuratin from the given string and returns an instance of it.
/// </summary> /// </summary>
/// <param name="filePath">The file path where the content should be written to. The file will be created or overwritten.</param> /// <typeparam name="T">The type of the configuration class to instance.</typeparam>
public void WriteToFile(string filePath) /// <param name="content">The content of the configuration as string.</param>
{ /// <returns></returns>
ConfigurationSerializer.WriteToFile(this, filePath); public static T ReadFromString<T>(string content) where T : SimpleConfiguration
} {
return ConfigurationSerializer.ReadFromString<T>(content);
}
/// <summary> /// <summary>
/// Reads a configuratin from the given string and returns an instance of it. /// Read a configuration from the given string and put them to this instance.
/// </summary> /// </summary>
/// <typeparam name="T">The type of the configuration class to instance.</typeparam> /// <param name="content">The content of the configuration as string.</param>
/// <param name="content">The content of the configuration as string.</param> public void ReadFromString(string content)
/// <returns></returns> {
public static T ReadFromString<T>(string content) where T : SimpleConfiguration ConfigurationSerializer.ReadFromString(this, content);
{ }
return ConfigurationSerializer.ReadFromString<T>(content);
}
/// <summary> /// <summary>
/// Read a configuration from the given string and put them to this instance. /// Reads a configuratin from the given string and returns an instance of it.
/// </summary> /// </summary>
/// <param name="content">The content of the configuration as string.</param> /// <typeparam name="T">The type of the configuration class to instance.</typeparam>
public void ReadFromString(string content) /// <param name="stream">The stream with the content of the configuration.</param>
{ /// <returns></returns>
ConfigurationSerializer.ReadFromString(this, content); public static T ReadFromStream<T>(Stream stream) where T : SimpleConfiguration
} {
return ConfigurationSerializer.ReadFromStream<T>(stream);
}
/// <summary> /// <summary>
/// Reads a configuratin from the given string and returns an instance of it. /// Read a configuration from the given string and put them to this instance.
/// </summary> /// </summary>
/// <typeparam name="T">The type of the configuration class to instance.</typeparam> /// <param name="stream">The stream with the content of the configuration.</param>
/// <param name="stream">The stream with the content of the configuration.</param> public void ReadFromStream(Stream stream)
/// <returns></returns> {
public static T ReadFromStream<T>(Stream stream) where T : SimpleConfiguration ConfigurationSerializer.ReadFromStream(this, stream);
{ }
return ConfigurationSerializer.ReadFromStream<T>(stream);
}
/// <summary> /// <summary>
/// Read a configuration from the given string and put them to this instance. /// Reads a configuratin from the given string and returns an instance of it.
/// </summary> /// </summary>
/// <param name="stream">The stream with the content of the configuration.</param> /// <typeparam name="T">The type of the configuration class to instance.</typeparam>
public void ReadFromStream(Stream stream) /// <param name="filePath">The path to the file with the content of the configuration.</param>
{ /// <returns></returns>
ConfigurationSerializer.ReadFromStream(this, stream); public static T ReadFromFile<T>(string filePath) where T : SimpleConfiguration
} {
return ConfigurationSerializer.ReadFromFile<T>(filePath);
}
/// <summary> /// <summary>
/// Reads a configuratin from the given string and returns an instance of it. /// Read a configuration from the given string and put them to this instance.
/// </summary> /// </summary>
/// <typeparam name="T">The type of the configuration class to instance.</typeparam> /// <param name="filePath">The path to the file with the content of the configuration.</param>
/// <param name="filePath">The path to the file with the content of the configuration.</param> public void ReadFromFile(string filePath)
/// <returns></returns> {
public static T ReadFromFile<T>(string filePath) where T : SimpleConfiguration ConfigurationSerializer.ReadFromFile(this, filePath);
{
return ConfigurationSerializer.ReadFromFile<T>(filePath);
}
/// <summary>
/// Read a configuration from the given string and put them to this instance.
/// </summary>
/// <param name="filePath">The path to the file with the content of the configuration.</param>
public void ReadFromFile(string filePath)
{
ConfigurationSerializer.ReadFromFile(this, filePath);
}
} }
} }

View File

@@ -1,55 +1,51 @@
using System; using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq;
using System.Management; using System.Management;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Threading.Tasks;
namespace Pilz.Cryptography namespace Pilz.Cryptography;
[EditorBrowsable(EditorBrowsableState.Never)]
public static class Helpers
{ {
[EditorBrowsable(EditorBrowsableState.Never)] private static string clientSecret = null;
public static class Helpers
public static string CalculateClientSecret()
{ {
private static string clientSecret = null; // Try getting serial number of C drive
if (clientSecret == null && RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
public static string CalculateClientSecret()
{ {
// Try getting serial number of C drive ManagementObjectSearcher searcher = new("SELECT * FROM Win32_PhysicalMedia");
if (clientSecret == null && RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) string sn = null;
foreach (var entry in searcher.Get())
{ {
ManagementObjectSearcher searcher = new("SELECT * FROM Win32_PhysicalMedia"); if (entry is ManagementObject wmi_HD && string.IsNullOrEmpty(sn) && wmi_HD["SerialNumber"] != null)
string sn = null; sn = wmi_HD["SerialNumber"].ToString()?.Trim();
foreach (var entry in searcher.Get())
{
if (entry is ManagementObject wmi_HD && string.IsNullOrEmpty(sn) && wmi_HD["SerialNumber"] != null)
sn = wmi_HD["SerialNumber"].ToString()?.Trim();
}
clientSecret = sn;
} }
// Fallback to Mashine name clientSecret = sn;
clientSecret ??= Environment.MachineName;
return clientSecret;
} }
public static string GenerateUniquieID<T>(string var) // Fallback to Mashine name
{ clientSecret ??= Environment.MachineName;
var sn = CalculateClientSecret();
var dateTime = DateTime.UtcNow.ToString("yyyyMMddHHmmssfffffff");
var type = typeof(T).ToString();
var together = sn + dateTime + type + var;
var md5 = MD5.Create(); return clientSecret;
var hash = BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(together))).Replace("-", string.Empty); }
md5.Dispose();
return hash; public static string GenerateUniquieID<T>(string var)
} {
var sn = CalculateClientSecret();
var dateTime = DateTime.UtcNow.ToString("yyyyMMddHHmmssfffffff");
var type = typeof(T).ToString();
var together = sn + dateTime + type + var;
var md5 = MD5.Create();
var hash = BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(together))).Replace("-", string.Empty);
md5.Dispose();
return hash;
} }
} }

View File

@@ -1,14 +1,7 @@
using System; namespace Pilz.Cryptography;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Cryptography public interface ICrypter
{ {
public interface ICrypter string Encrypt(string plainValue);
{ string Decrypt(string encryptedValue);
string Encrypt(string plainValue);
string Decrypt(string encryptedValue);
}
} }

View File

@@ -1,18 +1,14 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace Pilz.Cryptography namespace Pilz.Cryptography;
[JsonConverter(typeof(Json.Converters.UniquieIDStringJsonConverter))]
public interface IUniquieID
{ {
[JsonConverter(typeof(Json.Converters.UniquieIDStringJsonConverter))] bool HasID { get; }
public interface IUniquieID string ID { get; }
{
bool HasID { get; }
string ID { get; }
void GenerateIfNull(); void GenerateIfNull();
void Generate(); void Generate();
bool Equals(object obj); bool Equals(object obj);
}
} }

View File

@@ -1,14 +1,9 @@
using System; namespace Pilz.Cryptography;
using System.Collections.Generic;
using System.Text;
namespace Pilz.Cryptography /// <summary>
/// Can be implemented on objects that provides an UniquieID.
/// </summary>
public interface IUniquieIDHost
{ {
/// <summary> UniquieID ID { get; }
/// Can be implemented on objects that provides an UniquieID.
/// </summary>
public interface IUniquieIDHost
{
UniquieID ID { get; }
}
} }

View File

@@ -1,38 +1,35 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using Pilz.Cryptography; using Pilz.Cryptography;
using System; using System;
using System.Collections.Generic;
using System.Text;
namespace Pilz.Json.Converters namespace Pilz.Json.Converters;
public class UniquieIDStringJsonConverter : JsonConverter
{ {
public class UniquieIDStringJsonConverter : JsonConverter public static bool EnableCheckForDepricatedTypes { get; set; } = true;
public override bool CanConvert(Type objectType)
{ {
public static bool EnableCheckForDepricatedTypes { get; set; } = true; return typeof(IUniquieID).IsAssignableFrom(objectType);
}
public override bool CanConvert(Type objectType) public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{ {
return typeof(IUniquieID).IsAssignableFrom(objectType); var idString = serializer.Deserialize<string>(reader);
} UniquieID id;
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) if (existingValue is UniquieID existingID && (!EnableCheckForDepricatedTypes || existingID.GetType() == typeof(UniquieID)))
{ id = existingID;
var idString = serializer.Deserialize<string>(reader); else
UniquieID id; id = new UniquieID();
if (existingValue is UniquieID existingID && (!EnableCheckForDepricatedTypes || existingID.GetType() == typeof(UniquieID))) id.ID = idString;
id = existingID;
else
id = new UniquieID();
id.ID = idString; return id;
}
return id; public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
} {
serializer.Serialize(writer, ((UniquieID)value).ID);
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, ((UniquieID)value).ID);
}
} }
} }

View File

@@ -1,6 +1,4 @@
using System.Reflection; using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly // Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von // für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von

View File

@@ -1,78 +1,73 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Cryptography namespace Pilz.Cryptography;
[JsonConverter(typeof(Json.Converters.SecureStringJsonConverter))]
public class SecureString
{ {
[JsonConverter(typeof(Json.Converters.SecureStringJsonConverter))] public static ICrypter DefaultCrypter { get; set; }
public class SecureString public ICrypter Crypter { get; set; }
public string EncryptedValue { get; set; }
public string Value
{ {
public static ICrypter DefaultCrypter { get; set; } get => GetCrypter()?.Decrypt(EncryptedValue);
public ICrypter Crypter { get; set; } set => EncryptedValue = GetCrypter().Encrypt(value);
public string EncryptedValue { get; set; }
public string Value
{
get => GetCrypter()?.Decrypt(EncryptedValue);
set => EncryptedValue = GetCrypter().Encrypt(value);
}
[JsonConstructor]
private SecureString(JsonConstructorAttribute dummyAttribute)
{
}
public SecureString() :
this(string.Empty, true)
{
}
public SecureString(string value, bool isEncrypted) :
this(value, isEncrypted, null)
{
}
public SecureString(string value, bool isEncrypted, ICrypter crypter)
{
Crypter = crypter;
if (isEncrypted)
EncryptedValue = value;
else
Value = value;
}
private ICrypter GetCrypter()
{
if (Crypter == null)
{
if (DefaultCrypter == null)
DefaultCrypter = new SimpleStringCrypter(string.Empty);
Crypter = DefaultCrypter;
}
return Crypter;
}
public override string ToString() => Value;
public override bool Equals(object obj)
{
var @string = obj as SecureString;
return @string != null &&
EncryptedValue == @string.EncryptedValue;
}
public override int GetHashCode()
{
return -2303024 + EqualityComparer<string>.Default.GetHashCode(EncryptedValue);
}
public static implicit operator string(SecureString value) => value?.Value;
public static implicit operator SecureString(string value) => new SecureString(value, false);
public static bool operator ==(SecureString left, SecureString right) => left?.EncryptedValue == right?.EncryptedValue;
public static bool operator !=(SecureString left, SecureString right) => left?.EncryptedValue != right?.EncryptedValue;
} }
[JsonConstructor]
private SecureString(JsonConstructorAttribute dummyAttribute)
{
}
public SecureString() :
this(string.Empty, true)
{
}
public SecureString(string value, bool isEncrypted) :
this(value, isEncrypted, null)
{
}
public SecureString(string value, bool isEncrypted, ICrypter crypter)
{
Crypter = crypter;
if (isEncrypted)
EncryptedValue = value;
else
Value = value;
}
private ICrypter GetCrypter()
{
if (Crypter == null)
{
if (DefaultCrypter == null)
DefaultCrypter = new SimpleStringCrypter(string.Empty);
Crypter = DefaultCrypter;
}
return Crypter;
}
public override string ToString() => Value;
public override bool Equals(object obj)
{
var @string = obj as SecureString;
return @string != null &&
EncryptedValue == @string.EncryptedValue;
}
public override int GetHashCode()
{
return -2303024 + EqualityComparer<string>.Default.GetHashCode(EncryptedValue);
}
public static implicit operator string(SecureString value) => value?.Value;
public static implicit operator SecureString(string value) => new SecureString(value, false);
public static bool operator ==(SecureString left, SecureString right) => left?.EncryptedValue == right?.EncryptedValue;
public static bool operator !=(SecureString left, SecureString right) => left?.EncryptedValue != right?.EncryptedValue;
} }

View File

@@ -1,41 +1,34 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using Pilz.Cryptography; using Pilz.Cryptography;
using System; using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Json.Converters namespace Pilz.Json.Converters;
public class SecureStringJsonConverter : JsonConverter
{ {
public class SecureStringJsonConverter : JsonConverter public override bool CanConvert(Type objectType)
{ {
public override bool CanConvert(Type objectType) return typeof(SecureString).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var idString = serializer.Deserialize<string>(reader);
SecureString id;
if (existingValue is SecureString)
{ {
return typeof(SecureString).IsAssignableFrom(objectType); id = (SecureString)existingValue;
id.EncryptedValue = idString;
} }
else
id = new SecureString(idString, true);
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) return id;
{ }
var idString = serializer.Deserialize<string>(reader);
SecureString id;
if (existingValue is SecureString) public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{ {
id = (SecureString)existingValue; serializer.Serialize(writer, ((SecureString)value).EncryptedValue);
id.EncryptedValue = idString;
}
else
id = new SecureString(idString, true);
return id;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, ((SecureString)value).EncryptedValue);
}
} }
} }

View File

@@ -1,80 +1,91 @@
using System; using System;
using System.Collections.Generic; using System.IO;
/* Nicht gemergte Änderung aus Projekt "Pilz.Cryptography (net6.0)"
Vor:
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.IO; using System.IO;
Nach:
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
*/
using System.Security.Cryptography;
using System.Text;
namespace Pilz.Cryptography namespace Pilz.Cryptography;
public class SimpleStringCrypter : ICrypter
{ {
public class SimpleStringCrypter : ICrypter private readonly TripleDES TripleDes;
public Encoding TextEncoding { get; private set; } = Encoding.Default;
public SimpleStringCrypter() : this(string.Empty)
{ {
private readonly TripleDES TripleDes; }
public Encoding TextEncoding { get; private set; } = Encoding.Default;
public SimpleStringCrypter() : this(string.Empty) public SimpleStringCrypter(string key) : this(key, Encoding.Default)
{ {
} }
public SimpleStringCrypter(string key) : this(key, Encoding.Default) public SimpleStringCrypter(string key, Encoding textEncoding)
{ {
} TextEncoding = textEncoding;
TripleDes = TripleDES.Create();
TripleDes.Key = TruncateHash(key, TripleDes.KeySize / 8);
TripleDes.IV = TruncateHash(string.Empty, TripleDes.BlockSize / 8);
}
public SimpleStringCrypter(string key, Encoding textEncoding) private byte[] TruncateHash(string key, int length)
{ {
TextEncoding = textEncoding; SHA1 sha1CryptoServiceProvider = SHA1.Create();
TripleDes = TripleDES.Create(); var bytes = TextEncoding.GetBytes(key);
TripleDes.Key = TruncateHash(key,TripleDes.KeySize / 8); var array = sha1CryptoServiceProvider.ComputeHash(bytes);
TripleDes.IV = TruncateHash(string.Empty, TripleDes.BlockSize / 8);
}
private byte[] TruncateHash(string key, int length) var output = new byte[length];
{ var lowerLength = Math.Min(array.Length, output.Length);
SHA1 sha1CryptoServiceProvider = SHA1.Create();
var bytes = TextEncoding.GetBytes(key);
var array = sha1CryptoServiceProvider.ComputeHash(bytes);
var output = new byte[length]; for (int i = 0; i < lowerLength; i++)
var lowerLength = Math.Min(array.Length, output.Length); output[i] = array[i];
for (int i = 0; i < lowerLength; i++)
output[i] = array[i];
return output; return output;
} }
private string EncryptData(string plaintext) private string EncryptData(string plaintext)
{ {
var bytes = TextEncoding.GetBytes(plaintext); var bytes = TextEncoding.GetBytes(plaintext);
using var memoryStream = new MemoryStream(); using var memoryStream = new MemoryStream();
using var cryptoStream = new CryptoStream(memoryStream, TripleDes.CreateEncryptor(), CryptoStreamMode.Write); using var cryptoStream = new CryptoStream(memoryStream, TripleDes.CreateEncryptor(), CryptoStreamMode.Write);
cryptoStream.Write(bytes, 0, bytes.Length); cryptoStream.Write(bytes, 0, bytes.Length);
cryptoStream.FlushFinalBlock(); cryptoStream.FlushFinalBlock();
return Convert.ToBase64String(memoryStream.ToArray()); return Convert.ToBase64String(memoryStream.ToArray());
} }
private string DecryptData(string encryptedtext) private string DecryptData(string encryptedtext)
{ {
var array = Convert.FromBase64String(encryptedtext); var array = Convert.FromBase64String(encryptedtext);
using var memoryStream = new MemoryStream(); using var memoryStream = new MemoryStream();
using var cryptoStream = new CryptoStream(memoryStream, TripleDes.CreateDecryptor(), CryptoStreamMode.Write); using var cryptoStream = new CryptoStream(memoryStream, TripleDes.CreateDecryptor(), CryptoStreamMode.Write);
cryptoStream.Write(array, 0, array.Length); cryptoStream.Write(array, 0, array.Length);
cryptoStream.FlushFinalBlock(); cryptoStream.FlushFinalBlock();
return TextEncoding.GetString(memoryStream.ToArray()); return TextEncoding.GetString(memoryStream.ToArray());
} }
public string Encrypt(string plainValue) public string Encrypt(string plainValue)
{ {
return EncryptData(plainValue ?? string.Empty); return EncryptData(plainValue ?? string.Empty);
} }
public string Decrypt(string encryptedValue) public string Decrypt(string encryptedValue)
{ {
if (string.IsNullOrEmpty(encryptedValue)) if (string.IsNullOrEmpty(encryptedValue))
return string.Empty; return string.Empty;
else else
return DecryptData(encryptedValue); return DecryptData(encryptedValue);
}
} }
} }

View File

@@ -1,135 +1,130 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Management;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
namespace Pilz.Cryptography namespace Pilz.Cryptography;
[JsonConverter(typeof(Json.Converters.UniquieIDStringJsonConverter))]
public class UniquieID : IUniquieID
{ {
[JsonConverter(typeof(Json.Converters.UniquieIDStringJsonConverter))] protected static ulong currentSimpleID = 0;
public class UniquieID : IUniquieID
[JsonProperty(nameof(ID))]
protected string _iD;
[JsonIgnore]
public virtual bool SimpleMode { get; }
[JsonIgnore]
public virtual bool GenerateOnGet { get; }
[JsonIgnore]
public virtual bool HasID => !string.IsNullOrEmpty(_iD);
[JsonIgnore]
public virtual string ID
{ {
protected static ulong currentSimpleID = 0; get
[JsonProperty(nameof(ID))]
protected string _iD;
[JsonIgnore]
public virtual bool SimpleMode { get; }
[JsonIgnore]
public virtual bool GenerateOnGet { get; }
[JsonIgnore]
public virtual bool HasID => !string.IsNullOrEmpty(_iD);
[JsonIgnore]
public virtual string ID
{ {
get if (GenerateOnGet)
{
if (GenerateOnGet)
GenerateIfNull();
return _iD;
}
internal set
=> _iD = value;
}
public UniquieID() : this(UniquieIDGenerationMode.None)
{
}
public UniquieID(UniquieIDGenerationMode mode) : this(mode, false)
{
}
public UniquieID(UniquieIDGenerationMode mode, bool simpleMode)
{
SimpleMode = simpleMode;
if (mode == UniquieIDGenerationMode.GenerateOnInit)
GenerateIfNull(); GenerateIfNull();
else if (mode == UniquieIDGenerationMode.GenerateOnGet) return _iD;
GenerateOnGet = true;
} }
internal set
[Obsolete] => _iD = value;
public UniquieID(bool autoGenerate) : this(autoGenerate ? UniquieIDGenerationMode.GenerateOnInit : UniquieIDGenerationMode.None)
{
}
public virtual void Generate()
{
if (SimpleMode)
ID = GenerateSimple();
else
ID = GenerateDefault();
}
protected virtual string GenerateSimple()
{
return new Random().Next().ToString() + DateTime.Now.ToString("yyyyMMddHHmmssfffffff") + currentSimpleID++.ToString();
}
protected virtual string GenerateDefault()
{
return Helpers.GenerateUniquieID<UniquieID>(currentSimpleID++.ToString());
}
public virtual void GenerateIfNull()
{
if (!HasID) Generate();
}
public override string ToString()
{
return ID;
}
public override int GetHashCode()
{
return -1430039477 + EqualityComparer<string>.Default.GetHashCode(_iD);
}
public override bool Equals(object obj)
{
if (obj is UniquieID iD)
{
if (ReferenceEquals(obj, iD))
return true;
else
{
var leftHasID = iD.HasID;
var rightHasID = HasID;
if (!leftHasID && iD.GenerateOnGet)
{
iD.Generate();
leftHasID = iD.HasID;
}
if (!rightHasID && GenerateOnGet)
{
Generate();
rightHasID = HasID;
}
if (leftHasID && rightHasID)
return _iD.Equals(iD._iD);
}
}
return base.Equals(obj);
}
public static implicit operator string(UniquieID id) => id.ID;
public static implicit operator UniquieID(string id) => new UniquieID() { ID = id };
public static implicit operator UniquieID(int id) => new UniquieID() { ID = Convert.ToString(id) };
public static bool operator ==(UniquieID left, UniquieID right) => left.ID.Equals(right.ID);
public static bool operator !=(UniquieID left, UniquieID right) => !left.ID.Equals(right.ID);
} }
public UniquieID() : this(UniquieIDGenerationMode.None)
{
}
public UniquieID(UniquieIDGenerationMode mode) : this(mode, false)
{
}
public UniquieID(UniquieIDGenerationMode mode, bool simpleMode)
{
SimpleMode = simpleMode;
if (mode == UniquieIDGenerationMode.GenerateOnInit)
GenerateIfNull();
else if (mode == UniquieIDGenerationMode.GenerateOnGet)
GenerateOnGet = true;
}
[Obsolete]
public UniquieID(bool autoGenerate) : this(autoGenerate ? UniquieIDGenerationMode.GenerateOnInit : UniquieIDGenerationMode.None)
{
}
public virtual void Generate()
{
if (SimpleMode)
ID = GenerateSimple();
else
ID = GenerateDefault();
}
protected virtual string GenerateSimple()
{
return new Random().Next().ToString() + DateTime.Now.ToString("yyyyMMddHHmmssfffffff") + currentSimpleID++.ToString();
}
protected virtual string GenerateDefault()
{
return Helpers.GenerateUniquieID<UniquieID>(currentSimpleID++.ToString());
}
public virtual void GenerateIfNull()
{
if (!HasID) Generate();
}
public override string ToString()
{
return ID;
}
public override int GetHashCode()
{
return -1430039477 + EqualityComparer<string>.Default.GetHashCode(_iD);
}
public override bool Equals(object obj)
{
if (obj is UniquieID iD)
{
if (ReferenceEquals(obj, iD))
return true;
else
{
var leftHasID = iD.HasID;
var rightHasID = HasID;
if (!leftHasID && iD.GenerateOnGet)
{
iD.Generate();
leftHasID = iD.HasID;
}
if (!rightHasID && GenerateOnGet)
{
Generate();
rightHasID = HasID;
}
if (leftHasID && rightHasID)
return _iD.Equals(iD._iD);
}
}
return base.Equals(obj);
}
public static implicit operator string(UniquieID id) => id.ID;
public static implicit operator UniquieID(string id) => new UniquieID() { ID = id };
public static implicit operator UniquieID(int id) => new UniquieID() { ID = Convert.ToString(id) };
public static bool operator ==(UniquieID left, UniquieID right) => left.ID.Equals(right.ID);
public static bool operator !=(UniquieID left, UniquieID right) => !left.ID.Equals(right.ID);
} }

View File

@@ -1,13 +1,8 @@
using System; namespace Pilz.Cryptography;
using System.Collections.Generic;
using System.Text;
namespace Pilz.Cryptography public enum UniquieIDGenerationMode
{ {
public enum UniquieIDGenerationMode None,
{ GenerateOnGet,
None, GenerateOnInit
GenerateOnGet,
GenerateOnInit
}
} }

View File

@@ -1,6 +1,5 @@
Imports System.Windows.Forms Imports System.Windows.Forms
Imports OpenTK
Imports OpenTK.Mathematics Imports OpenTK.Mathematics
Namespace CameraN Namespace CameraN

View File

@@ -1,16 +1,32 @@
Imports System.Drawing Imports System.Drawing
' Nicht gemergte Änderung aus Projekt "Pilz.Drawing.Drawing3D.OpenGLFactory (net6.0-windows)"
' Vor:
' Imports System.Windows.Forms
' Imports Pilz.Drawing.Drawing3D.OpenGLFactory.CameraN
' Nach:
' Imports System.Windows.Forms
'
' Imports OpenTK
' Imports OpenTK.Graphics.OpenGL
' Imports OpenTK.Mathematics
' Imports OpenTK.WinForms
'
' Imports Pilz.Drawing.Drawing3D.OpenGLFactory.CameraN
Imports System.Windows.Forms Imports System.Windows.Forms
Imports Pilz.Drawing.Drawing3D.OpenGLFactory.CameraN
Imports Pilz.Drawing.Drawing3D.OpenGLFactory.RenderingN
Imports OpenTK
Imports OpenTK.Graphics.OpenGL Imports OpenTK.Graphics.OpenGL
Imports Pilz.S3DFileParser
Imports Point = System.Drawing.Point
Imports Color = System.Drawing.Color
Imports OpenTK.Mathematics Imports OpenTK.Mathematics
Imports OpenTK.WinForms Imports OpenTK.WinForms
Imports Pilz.Drawing.Drawing3D.OpenGLFactory.CameraN
Imports Pilz.Drawing.Drawing3D.OpenGLFactory.RenderingN
Imports Pilz.S3DFileParser
Imports Pilz.Win32.Mapped Imports Pilz.Win32.Mapped
Imports Color = System.Drawing.Color
Imports Point = System.Drawing.Point
Namespace PreviewN Namespace PreviewN
Public Class ModelPreview Public Class ModelPreview

View File

@@ -1,5 +1,14 @@
Imports System.Drawing
Imports OpenTK ' Nicht gemergte Änderung aus Projekt "Pilz.Drawing.Drawing3D.OpenGLFactory (net6.0-windows)"
' Vor:
' Imports System.Drawing
' Imports OpenTK
' Nach:
' Imports System.Drawing
'
' Imports OpenTK
Imports System.Drawing
Imports OpenTK.Graphics.OpenGL Imports OpenTK.Graphics.OpenGL
Namespace RenderingN Namespace RenderingN

View File

@@ -1,8 +1,18 @@
Imports System ' Nicht gemergte Änderung aus Projekt "Pilz.Drawing.Drawing3D.OpenGLFactory (net6.0-windows)"
Imports OpenTK ' Vor:
Imports OpenTK.Graphics.OpenGL ' Imports OpenTK
Imports System.Drawing ' Imports OpenTK.Graphics.OpenGL
' Imports System.Drawing
' Nach:
' Imports System.Drawing
' Imports System.Drawing.Imaging
'
' Imports OpenTK
.Drawing
Imports System.Drawing.Imaging Imports System.Drawing.Imaging
Imports OpenTK.Graphics.OpenGL
Imports Bitmap = System.Drawing.Bitmap Imports Bitmap = System.Drawing.Bitmap
Namespace RenderingN Namespace RenderingN

View File

@@ -1,9 +1,4 @@
Imports System.Drawing Imports OpenTK.Graphics.OpenGL
Imports System.Threading
Imports System.Windows.Forms
Imports OpenTK
Imports OpenTK.Graphics.OpenGL
Imports OpenTK.Mathematics Imports OpenTK.Mathematics
Imports Pilz.S3DFileParser Imports Pilz.S3DFileParser

View File

@@ -1,5 +1,4 @@
Imports System.Drawing Imports System.Drawing
Imports System.Drawing.Drawing2D
Public Module HelpfulDrawingFunctions Public Module HelpfulDrawingFunctions

View File

@@ -1,43 +1,42 @@
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
namespace Pilz.Gaming.Minecraft namespace Pilz.Gaming.Minecraft;
public static class Utils
{ {
public static class Utils public static string GetUUID(string value)
{ {
public static string GetUUID(string value) using var md5 = MD5.Create();
{
using var md5 = MD5.Create();
//extracted from the java code: //extracted from the java code:
//new GameProfile(UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8)), name)); //new GameProfile(UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8)), name));
byte[] data = md5.ComputeHash(Encoding.ASCII.GetBytes(value)); byte[] data = md5.ComputeHash(Encoding.ASCII.GetBytes(value));
//set the version to 3 -> Name based md5 hash //set the version to 3 -> Name based md5 hash
data[6] = Convert.ToByte(data[6] & 0x0f | 0x30); data[6] = Convert.ToByte(data[6] & 0x0f | 0x30);
//IETF variant //IETF variant
data[8] = Convert.ToByte(data[8] & 0x3f | 0x80); data[8] = Convert.ToByte(data[8] & 0x3f | 0x80);
//example: 069a79f4-44e9-4726-a5be-fca90e38aaf5 //example: 069a79f4-44e9-4726-a5be-fca90e38aaf5
var striped = Convert.ToHexString(data); var striped = Convert.ToHexString(data);
var components = new string[] { var components = new string[] {
striped[..].Remove(8), striped[..].Remove(8),
striped[8..].Remove(4), striped[8..].Remove(4),
striped[12..].Remove(4), striped[12..].Remove(4),
striped[16..].Remove(4), striped[16..].Remove(4),
striped[20..] striped[20..]
}; };
return string.Join('-', components).ToLower(); return string.Join('-', components).ToLower();
} }
public static string GetPlayerUUID(string username, bool offlineMode) public static string GetPlayerUUID(string username, bool offlineMode)
{ {
using var md5 = MD5.Create(); using var md5 = MD5.Create();
if (!offlineMode) if (!offlineMode)
throw new NotSupportedException("Getting player's online UUID via the Mojang API is not supported at this time."); throw new NotSupportedException("Getting player's online UUID via the Mojang API is not supported at this time.");
return GetUUID("OfflinePlayer:" + username); return GetUUID("OfflinePlayer:" + username);
}
} }
} }

View File

@@ -3,172 +3,169 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.IO.Compression; using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Pilz.IO namespace Pilz.IO;
public class EmbeddedFilesContainer
{ {
public class EmbeddedFilesContainer [JsonProperty("CompressedFiles")]
private readonly Dictionary<string, byte[]> compressedFiles = new Dictionary<string, byte[]>();
/// <summary>
/// Returns the names of all embedded files.
/// </summary>
[JsonIgnore]
public IEnumerable<string> AllFileNames
{ {
[JsonProperty("CompressedFiles")] get => compressedFiles.Keys;
private readonly Dictionary<string, byte[]> compressedFiles = new Dictionary<string, byte[]>(); }
/// <summary> /// <summary>
/// Returns the names of all embedded files. /// Embeds a file to this container.
/// </summary> /// </summary>
[JsonIgnore] /// <param name="fileName">The name how it should be called in this container.</param>
public IEnumerable<string> AllFileNames /// <param name="filePath">The file path to the file that should be embedded.</param>
{ /// <returns>Returns a <see cref="bool"/> that defines if the file as been embedded successfully.</returns>
get => compressedFiles.Keys; public Task<bool> AddFileAsync(string fileName, string filePath)
} {
return Task.Run(() => AddFile(fileName, filePath));
}
/// <summary> /// <summary>
/// Embeds a file to this container. /// Embeds a file to this container.
/// </summary> /// </summary>
/// <param name="fileName">The name how it should be called in this container.</param> /// <param name="fileName">The name how it should be called in this container.</param>
/// <param name="filePath">The file path to the file that should be embedded.</param> /// <param name="filePath">The file path to the file that should be embedded.</param>
/// <returns>Returns a <see cref="bool"/> that defines if the file as been embedded successfully.</returns> /// <returns>Returns a <see cref="bool"/> that defines if the file as been embedded successfully.</returns>
public Task<bool> AddFileAsync(string fileName, string filePath) public bool AddFile(string fileName, string filePath)
{ {
return Task.Run(() => AddFile(fileName, filePath)); bool success;
} FileStream fs = null;
MemoryStream compressed = null;
/// <summary>
/// Embeds a file to this container.
/// </summary>
/// <param name="fileName">The name how it should be called in this container.</param>
/// <param name="filePath">The file path to the file that should be embedded.</param>
/// <returns>Returns a <see cref="bool"/> that defines if the file as been embedded successfully.</returns>
public bool AddFile(string fileName, string filePath)
{
bool success;
FileStream fs = null;
MemoryStream compressed = null;
#if !DEBUG #if !DEBUG
try try
{ {
#endif #endif
fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
compressed = new MemoryStream(); compressed = new MemoryStream();
using (var compressor = new DeflateStream(compressed, CompressionLevel.Optimal, true)) using (var compressor = new DeflateStream(compressed, CompressionLevel.Optimal, true))
fs.CopyTo(compressor); fs.CopyTo(compressor);
success = true; success = true;
#if !DEBUG #if !DEBUG
} }
catch (Exception) catch (Exception)
{ {
success = false; success = false;
} }
#endif #endif
if (success) if (success)
{
var compressedBytes = compressed.ToArray();
if (compressedFiles.ContainsKey(fileName))
compressedFiles[fileName] = compressedBytes;
else
compressedFiles.Add(fileName, compressedBytes);
}
compressed?.Close();
fs?.Close();
return success;
}
/// <summary>
/// Removes a file from this container.
/// </summary>
/// <param name="fileName">The name how the file is called.</param>
public void RemoveFile(string fileName)
{ {
var compressedBytes = compressed.ToArray();
if (compressedFiles.ContainsKey(fileName)) if (compressedFiles.ContainsKey(fileName))
compressedFiles.Remove(fileName); compressedFiles[fileName] = compressedBytes;
else
compressedFiles.Add(fileName, compressedBytes);
} }
/// <summary> compressed?.Close();
/// Checks if the given file exists in this container. fs?.Close();
/// </summary>
/// <param name="fileName">The name how the file is called.</param> return success;
/// <returns>Returns if the given file exists in this container.</returns> }
public bool HasFile(string fileName)
/// <summary>
/// Removes a file from this container.
/// </summary>
/// <param name="fileName">The name how the file is called.</param>
public void RemoveFile(string fileName)
{
if (compressedFiles.ContainsKey(fileName))
compressedFiles.Remove(fileName);
}
/// <summary>
/// Checks if the given file exists in this container.
/// </summary>
/// <param name="fileName">The name how the file is called.</param>
/// <returns>Returns if the given file exists in this container.</returns>
public bool HasFile(string fileName)
{
return compressedFiles.ContainsKey(fileName);
}
/// <summary>
/// Gets a file from this container as stream.
/// </summary>
/// <param name="fileName">The name how the file is called.</param>
/// <returns>Returns a stream of the file with the given name.</returns>
public Task<Stream> GetStreamAsync(string fileName)
{
return Task.Run(() => GetStream(fileName));
}
/// <summary>
/// Gets a file from this container as stream.
/// </summary>
/// <param name="fileName">The name how the file is called.</param>
/// <returns>Returns a stream of the file with the given name.</returns>
public Stream GetStream(string fileName)
{
Stream decompressed = null;
if (compressedFiles.ContainsKey(fileName))
{ {
return compressedFiles.ContainsKey(fileName); decompressed = new MemoryStream();
DecompressToStream(decompressed, compressedFiles[fileName]);
} }
/// <summary> return decompressed;
/// Gets a file from this container as stream. }
/// </summary>
/// <param name="fileName">The name how the file is called.</param> /// <summary>
/// <returns>Returns a stream of the file with the given name.</returns> /// Saves a given file to the users temp directory.
public Task<Stream> GetStreamAsync(string fileName) /// </summary>
/// <param name="fileName">The name how the file is called.</param>
/// <returns>Returns the file path to the temp file.</returns>
public Task<string> GetLocalFilePathAsync(string fileName)
{
return Task.Run(() => GetLocalFilePath(fileName));
}
/// <summary>
/// Saves a given file to the users temp directory.
/// </summary>
/// <param name="fileName">The name how the file is called.</param>
/// <returns>Returns the file path to the temp file.</returns>
public string GetLocalFilePath(string fileName)
{
string filePath = string.Empty;
if (compressedFiles.ContainsKey(fileName))
{ {
return Task.Run(() => GetStream(fileName)); filePath = Path.GetTempFileName();
if (Path.HasExtension(fileName))
filePath = Path.ChangeExtension(filePath, Path.GetExtension(fileName));
var decompressed = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite);
DecompressToStream(decompressed, compressedFiles[fileName]);
decompressed.Flush();
decompressed.Close();
} }
/// <summary> return filePath;
/// Gets a file from this container as stream. }
/// </summary>
/// <param name="fileName">The name how the file is called.</param>
/// <returns>Returns a stream of the file with the given name.</returns>
public Stream GetStream(string fileName)
{
Stream decompressed = null;
if (compressedFiles.ContainsKey(fileName)) private void DecompressToStream(Stream decompressed, byte[] compressedData)
{ {
decompressed = new MemoryStream(); var compressed = new MemoryStream(compressedData);
DecompressToStream(decompressed, compressedFiles[fileName]); var decompressor = new DeflateStream(compressed, CompressionMode.Decompress, true);
} decompressor.CopyTo(decompressed);
decompressor.Close();
return decompressed; compressed.Close();
}
/// <summary>
/// Saves a given file to the users temp directory.
/// </summary>
/// <param name="fileName">The name how the file is called.</param>
/// <returns>Returns the file path to the temp file.</returns>
public Task<string> GetLocalFilePathAsync(string fileName)
{
return Task.Run(() => GetLocalFilePath(fileName));
}
/// <summary>
/// Saves a given file to the users temp directory.
/// </summary>
/// <param name="fileName">The name how the file is called.</param>
/// <returns>Returns the file path to the temp file.</returns>
public string GetLocalFilePath(string fileName)
{
string filePath = string.Empty;
if (compressedFiles.ContainsKey(fileName))
{
filePath = Path.GetTempFileName();
if (Path.HasExtension(fileName))
filePath = Path.ChangeExtension(filePath, Path.GetExtension(fileName));
var decompressed = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite);
DecompressToStream(decompressed, compressedFiles[fileName]);
decompressed.Flush();
decompressed.Close();
}
return filePath;
}
private void DecompressToStream(Stream decompressed, byte[] compressedData)
{
var compressed = new MemoryStream(compressedData);
var decompressor = new DeflateStream(compressed, CompressionMode.Decompress, true);
decompressor.CopyTo(decompressed);
decompressor.Close();
compressed.Close();
}
} }
} }

View File

@@ -1,14 +1,13 @@
using System; using System;
namespace Pilz.IO namespace Pilz.IO;
{
public class DataEventArgs : EventArgs
{
public readonly byte[] Data;
public DataEventArgs(byte[] bytes) : base() public class DataEventArgs : EventArgs
{ {
Data = bytes; public readonly byte[] Data;
}
public DataEventArgs(byte[] bytes) : base()
{
Data = bytes;
} }
} }

View File

@@ -1,26 +1,23 @@
using Pilz.Runtime; using Pilz.Runtime;
using Pilz.Win32.Native;
using System; using System;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Text; using System.Text;
namespace Pilz.IO namespace Pilz.IO;
{
public static class Extensions
{
static readonly int MAX_PATH = 255;
public static string GetExecutablePath(bool checkRealOS = false) public static class Extensions
{
static readonly int MAX_PATH = 255;
public static string GetExecutablePath(bool checkRealOS = false)
{
if (RuntimeInformationsEx.IsOSPlatform(OSType.Windows, checkRealOS))
{ {
if (RuntimeInformationsEx.IsOSPlatform(OSType.Windows, checkRealOS)) var sb = new StringBuilder(MAX_PATH);
{ Kernel32.GetModuleFileName(IntPtr.Zero, sb, MAX_PATH);
var sb = new StringBuilder(MAX_PATH); return sb.ToString();
Kernel32.GetModuleFileName(IntPtr.Zero, sb, MAX_PATH);
return sb.ToString();
}
else
return Process.GetCurrentProcess().MainModule.FileName;
} }
else
return Process.GetCurrentProcess().MainModule.FileName;
} }
} }

View File

@@ -1,118 +1,117 @@
using System; using System;
using System.IO; using System.IO;
namespace Pilz.IO namespace Pilz.IO;
public partial class FileLocker : IDisposable
{ {
public partial class FileLocker : IDisposable private FileStream fsLock = null;
/// <summary>
/// Defines the file path to the file that should be locked.
/// </summary>
public string FilePath { get; private set; }
/// <summary>
/// Defines the file path to the lock file that is used to identify the file lock.
/// </summary>
public string LockFile { get; private set; }
/// <summary>
/// Defines if the file is locked privatly by this instance.
/// </summary>
public bool LockedPrivate { get; private set; } = false;
/// <summary>
/// Defines if the file is locked by an other instance/program/user.
/// </summary>
public bool LockedExternal
{ {
private FileStream fsLock = null; get
/// <summary>
/// Defines the file path to the file that should be locked.
/// </summary>
public string FilePath { get; private set; }
/// <summary>
/// Defines the file path to the lock file that is used to identify the file lock.
/// </summary>
public string LockFile { get; private set; }
/// <summary>
/// Defines if the file is locked privatly by this instance.
/// </summary>
public bool LockedPrivate { get; private set; } = false;
/// <summary>
/// Defines if the file is locked by an other instance/program/user.
/// </summary>
public bool LockedExternal
{
get
{
if (LockedPrivate)
return false;
else
{
string lockFile = FilePath + ".lock";
bool isLocked = false;
if (File.Exists(lockFile))
{
try
{
var fs = new FileStream(lockFile, FileMode.Open, FileAccess.Read);
fs.Close();
}
catch (IOException)
{
isLocked = true;
}
}
return isLocked;
}
}
}
/// <summary>
/// Generate a new instance of <see cref="FileLocker"/> and locks the given file automatically.
/// </summary>
/// <param name="filePath">The file path to the file that should be locked.</param>
public FileLocker(string filePath) : this(filePath, true)
{
}
/// <summary>
/// Generate a new instance of <see cref="FileLocker"/>
/// </summary>
/// <param name="filePath">The file path to the file that should be locked.</param>
/// <param name="autoLock">Defines if the file should be locked automatically right after creating this instance.</param>
public FileLocker(string filePath, bool autoLock)
{
FilePath = filePath;
LockFile = filePath + ".lock";
if (autoLock) Lock();
}
/// <summary>
/// Locks the file, if not already locked privatly.
/// </summary>
public void Lock()
{
if (!LockedPrivate)
{
fsLock = new FileStream(LockFile, FileMode.Create, FileAccess.ReadWrite);
LockedPrivate = true;
}
}
/// <summary>
/// Unlocks the file, if locked privatly.
/// </summary>
public void Unlock()
{ {
if (LockedPrivate) if (LockedPrivate)
return false;
else
{ {
fsLock.Close(); string lockFile = FilePath + ".lock";
fsLock.Dispose(); bool isLocked = false;
fsLock = null;
File.Delete(LockFile); if (File.Exists(lockFile))
LockedPrivate = false; {
try
{
var fs = new FileStream(lockFile, FileMode.Open, FileAccess.Read);
fs.Close();
}
catch (IOException)
{
isLocked = true;
}
}
return isLocked;
} }
} }
#region IDisposable
private bool disposedValue;
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
Unlock();
}
public void Dispose()
{
Dispose(true);
disposedValue = true;
}
#endregion
} }
/// <summary>
/// Generate a new instance of <see cref="FileLocker"/> and locks the given file automatically.
/// </summary>
/// <param name="filePath">The file path to the file that should be locked.</param>
public FileLocker(string filePath) : this(filePath, true)
{
}
/// <summary>
/// Generate a new instance of <see cref="FileLocker"/>
/// </summary>
/// <param name="filePath">The file path to the file that should be locked.</param>
/// <param name="autoLock">Defines if the file should be locked automatically right after creating this instance.</param>
public FileLocker(string filePath, bool autoLock)
{
FilePath = filePath;
LockFile = filePath + ".lock";
if (autoLock) Lock();
}
/// <summary>
/// Locks the file, if not already locked privatly.
/// </summary>
public void Lock()
{
if (!LockedPrivate)
{
fsLock = new FileStream(LockFile, FileMode.Create, FileAccess.ReadWrite);
LockedPrivate = true;
}
}
/// <summary>
/// Unlocks the file, if locked privatly.
/// </summary>
public void Unlock()
{
if (LockedPrivate)
{
fsLock.Close();
fsLock.Dispose();
fsLock = null;
File.Delete(LockFile);
LockedPrivate = false;
}
}
#region IDisposable
private bool disposedValue;
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
Unlock();
}
public void Dispose()
{
Dispose(true);
disposedValue = true;
}
#endregion
} }

View File

@@ -2,66 +2,65 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Pilz.IO namespace Pilz.IO;
/// <summary>
/// stellt den Erben "Server" und "Client" 2 verschiedene
/// Message-Events zur Verfügung, und ein Event-Raisendes Dispose
/// </summary>
public abstract class ManagedPipe : IDisposable
{ {
public delegate void EventHandlerWithOneArgument<T0>(T0 Sender);
/// <summary> /// <summary>
/// stellt den Erben "Server" und "Client" 2 verschiedene /// Zur Ausgabe chat-verwaltungstechnischer Status-Informationen
/// Message-Events zur Verfügung, und ein Event-Raisendes Dispose
/// </summary> /// </summary>
public abstract class ManagedPipe : IDisposable public event EventHandler<DataEventArgs> StatusMessage;
/// <summary>Zur Ausgabe von Chat-Messages</summary>
public event EventHandler<DataEventArgs> RetriveData;
public event EventHandlerWithOneArgument<ManagedPipe> Disposed;
private bool _IsDisposed = false;
protected abstract void Dispose(bool disposing);
public abstract void Send(byte[] bytes);
public abstract Task SendAsnyc(byte[] bytes);
protected void OnStatusMessage(DataEventArgs e)
{ {
public delegate void EventHandlerWithOneArgument<T0>(T0 Sender); StatusMessage?.Invoke(this, e);
}
/// <summary> protected void OnRetriveData(DataEventArgs e)
/// Zur Ausgabe chat-verwaltungstechnischer Status-Informationen {
/// </summary> RetriveData?.Invoke(this, e);
public event EventHandler<DataEventArgs> StatusMessage; }
/// <summary>Zur Ausgabe von Chat-Messages</summary>
public event EventHandler<DataEventArgs> RetriveData;
public event EventHandlerWithOneArgument<ManagedPipe> Disposed;
private bool _IsDisposed = false; public void RemoveFrom<T>(ICollection<T> Coll) where T : ManagedPipe
{
Coll.Remove((T)this);
}
protected abstract void Dispose(bool disposing); public bool IsDisposed
public abstract void Send(byte[] bytes); {
public abstract Task SendAsnyc(byte[] bytes); get
protected void OnStatusMessage(DataEventArgs e)
{ {
StatusMessage?.Invoke(this, e); return _IsDisposed;
}
protected void OnRetriveData(DataEventArgs e)
{
RetriveData?.Invoke(this, e);
}
public void RemoveFrom<T>(ICollection<T> Coll) where T : ManagedPipe
{
Coll.Remove((T)this);
}
public bool IsDisposed
{
get
{
return _IsDisposed;
}
}
public void AddTo<T>(ICollection<T> Coll) where T : ManagedPipe
{
Coll.Add((T)this);
}
public void Dispose()
{
if (_IsDisposed)
return;
_IsDisposed = true;
Dispose(true); // rufe die erzwungenen Überschreibungen von Sub Dispose(Boolean)
Disposed?.Invoke(this);
GC.SuppressFinalize(this);
} }
} }
public void AddTo<T>(ICollection<T> Coll) where T : ManagedPipe
{
Coll.Add((T)this);
}
public void Dispose()
{
if (_IsDisposed)
return;
_IsDisposed = true;
Dispose(true); // rufe die erzwungenen Überschreibungen von Sub Dispose(Boolean)
Disposed?.Invoke(this);
GC.SuppressFinalize(this);
}
} }

View File

@@ -1,90 +1,89 @@
using System; using global::System.IO.Pipes;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using global::System.IO.Pipes;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Pilz.IO namespace Pilz.IO;
public class ManagedPipeClient : ManagedPipe
{ {
public class ManagedPipeClient : ManagedPipe private PipeStream pipeStream;
private byte[] _Buf = new byte[1024];
public ManagedPipeClient(string pipeName) : this(pipeName, ".")
{ {
private PipeStream pipeStream; }
private byte[] _Buf = new byte[1024];
public ManagedPipeClient(string pipeName) : this(pipeName, ".") public ManagedPipeClient(string pipeName, string serverName) : this(pipeName, serverName, -1)
{
}
public ManagedPipeClient(string pipeName, int connectionTimeout) : this(pipeName, ".", connectionTimeout)
{
}
public ManagedPipeClient(string pipeName, string serverName, int connectionTimeout)
{
var clnt = new NamedPipeClientStream(serverName, pipeName, PipeDirection.InOut, PipeOptions.Asynchronous);
clnt.Connect(connectionTimeout);
if (!clnt.IsConnected)
{ {
throw new TimeoutException("Connection timeout!");
} }
public ManagedPipeClient(string pipeName, string serverName) : this(pipeName, serverName, -1) SetPipe(clnt);
}
public ManagedPipeClient(PipeStream pipe)
{
SetPipe(pipe);
}
private void SetPipe(PipeStream pipe)
{
pipeStream = pipe;
pipeStream.BeginRead(_Buf, 0, _Buf.Length, EndRead, null);
}
private void EndRead(IAsyncResult ar)
{
if (IsDisposed)
return;
int bytesCount = pipeStream.EndRead(ar);
if (bytesCount == 0) // leere Datenübermittlung signalisiert Verbindungsabbruch
{ {
Dispose();
return;
} }
public ManagedPipeClient(string pipeName, int connectionTimeout) : this(pipeName, ".", connectionTimeout) var list = new List<byte>();
for (int i = 0, loopTo = bytesCount - 1; i <= loopTo; i++)
list.Add(_Buf[i]);
while (bytesCount == _Buf.Length)
{ {
} bytesCount = pipeStream.Read(_Buf, 0, _Buf.Length);
for (int i = 0, loopTo1 = bytesCount - 1; i <= loopTo1; i++)
public ManagedPipeClient(string pipeName, string serverName, int connectionTimeout)
{
var clnt = new NamedPipeClientStream(serverName, pipeName, PipeDirection.InOut, PipeOptions.Asynchronous);
clnt.Connect(connectionTimeout);
if (!clnt.IsConnected)
{
throw new TimeoutException("Connection timeout!");
}
SetPipe(clnt);
}
public ManagedPipeClient(PipeStream pipe)
{
SetPipe(pipe);
}
private void SetPipe(PipeStream pipe)
{
pipeStream = pipe;
pipeStream.BeginRead(_Buf, 0, _Buf.Length, EndRead, null);
}
private void EndRead(IAsyncResult ar)
{
if (IsDisposed)
return;
int bytesCount = pipeStream.EndRead(ar);
if (bytesCount == 0) // leere Datenübermittlung signalisiert Verbindungsabbruch
{
Dispose();
return;
}
var list = new List<byte>();
for (int i = 0, loopTo = bytesCount - 1; i <= loopTo; i++)
list.Add(_Buf[i]); list.Add(_Buf[i]);
while (bytesCount == _Buf.Length)
{
bytesCount = pipeStream.Read(_Buf, 0, _Buf.Length);
for (int i = 0, loopTo1 = bytesCount - 1; i <= loopTo1; i++)
list.Add(_Buf[i]);
}
var deargs = new DataEventArgs(list.ToArray());
OnRetriveData(deargs);
pipeStream.BeginRead(_Buf, 0, _Buf.Length, EndRead, null);
} }
public override Task SendAsnyc(byte[] bytes) var deargs = new DataEventArgs(list.ToArray());
{ OnRetriveData(deargs);
return Task.Run(() => Send(bytes));
}
public override void Send(byte[] data) pipeStream.BeginRead(_Buf, 0, _Buf.Length, EndRead, null);
{ }
pipeStream.Write(data, 0, data.Length);
}
protected override void Dispose(bool disposing) public override Task SendAsnyc(byte[] bytes)
{ {
pipeStream.Dispose(); return Task.Run(() => Send(bytes));
} }
public override void Send(byte[] data)
{
pipeStream.Write(data, 0, data.Length);
}
protected override void Dispose(bool disposing)
{
pipeStream.Dispose();
} }
} }

View File

@@ -1,108 +1,107 @@
using System; using global::System.IO.Pipes;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using global::System.IO.Pipes;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Pilz.IO namespace Pilz.IO;
public class ManagedPipeServer : ManagedPipe
{ {
public class ManagedPipeServer : ManagedPipe
// Pro Verbindung (Anfrage) wird ein Client-Objekt generiert, das den Datenaustausch dieser Verbindung abwickelt
public List<ManagedPipeClient> Clients { get; private set; } = new List<ManagedPipeClient>();
private readonly string pipeName = "";
private readonly int maxNumbersOfServerInstances;
private int numberOfStartedServerInstances = 0;
public ManagedPipeServer(string pipeName) : this(pipeName, 1)
{ {
}
// Pro Verbindung (Anfrage) wird ein Client-Objekt generiert, das den Datenaustausch dieser Verbindung abwickelt public ManagedPipeServer(string pipeName, int maxNumbersOfServerInstances)
public List<ManagedPipeClient> Clients { get; private set; } = new List<ManagedPipeClient>(); {
this.pipeName = pipeName;
this.maxNumbersOfServerInstances = maxNumbersOfServerInstances;
CreateWaitingStream();
}
private readonly string pipeName = ""; private void CreateWaitingStream()
private readonly int maxNumbersOfServerInstances; {
private int numberOfStartedServerInstances = 0; if (numberOfStartedServerInstances < maxNumbersOfServerInstances)
public ManagedPipeServer(string pipeName) : this(pipeName, 1)
{ {
} var strm = new NamedPipeServerStream(pipeName, PipeDirection.InOut, maxNumbersOfServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
numberOfStartedServerInstances += 1;
public ManagedPipeServer(string pipeName, int maxNumbersOfServerInstances) strm.BeginWaitForConnection(EndAccept, strm);
{
this.pipeName = pipeName;
this.maxNumbersOfServerInstances = maxNumbersOfServerInstances;
CreateWaitingStream();
}
private void CreateWaitingStream()
{
if (numberOfStartedServerInstances < maxNumbersOfServerInstances)
{
var strm = new NamedPipeServerStream(pipeName, PipeDirection.InOut, maxNumbersOfServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
numberOfStartedServerInstances += 1;
strm.BeginWaitForConnection(EndAccept, strm);
}
}
private void EndAccept(IAsyncResult ar)
{
NamedPipeServerStream strm = (NamedPipeServerStream)ar.AsyncState;
strm.EndWaitForConnection(ar);
if (IsDisposed)
{
strm.Dispose();
return;
}
{
var withBlock = new ManagedPipeClient(strm);
withBlock.RetriveData += Client_RetriveData;
withBlock.StatusMessage += Client_StatusMessage;
withBlock.Disposed += Client_Disposed;
withBlock.AddTo(Clients);
}
CreateWaitingStream();
}
/* TODO ERROR: Skipped RegionDirectiveTrivia */
private void Client_Disposed(ManagedPipe Sender)
{
// den Client für die beendete Verbindung entfernen
Sender.RemoveFrom(Clients);
numberOfStartedServerInstances -= 1;
CreateWaitingStream();
}
private void Client_RetriveData(object sender, DataEventArgs e)
{
// einkommende ChatMessages anzeigen, und an alle versenden
OnRetriveData(e);
}
private void Client_StatusMessage(object sender, DataEventArgs e)
{
// einkommende StatusMessages durchreichen (zur Anzeige)
OnStatusMessage(e);
}
/* TODO ERROR: Skipped EndRegionDirectiveTrivia */
public override Task SendAsnyc(byte[] bytes)
{
return Task.Run(() => Send(bytes));
}
public override void Send(byte[] data)
{
foreach (ManagedPipeClient client in Clients) // an alle versenden
client.Send(data);
}
protected override void Dispose(bool disposing)
{
if (numberOfStartedServerInstances < maxNumbersOfServerInstances)
{
using (var clnt = new NamedPipeClientStream(pipeName))
{
// Herstellen einer Dummi-Verbindung, damit der ServerStream aus dem Wartezustand herauskommt.
clnt.Connect();
}
}
for (int i = Clients.Count - 1; i >= 0; i -= 1)
Clients[i].Dispose();
} }
} }
private void EndAccept(IAsyncResult ar)
{
NamedPipeServerStream strm = (NamedPipeServerStream)ar.AsyncState;
strm.EndWaitForConnection(ar);
if (IsDisposed)
{
strm.Dispose();
return;
}
{
var withBlock = new ManagedPipeClient(strm);
withBlock.RetriveData += Client_RetriveData;
withBlock.StatusMessage += Client_StatusMessage;
withBlock.Disposed += Client_Disposed;
withBlock.AddTo(Clients);
}
CreateWaitingStream();
}
/* TODO ERROR: Skipped RegionDirectiveTrivia */
private void Client_Disposed(ManagedPipe Sender)
{
// den Client für die beendete Verbindung entfernen
Sender.RemoveFrom(Clients);
numberOfStartedServerInstances -= 1;
CreateWaitingStream();
}
private void Client_RetriveData(object sender, DataEventArgs e)
{
// einkommende ChatMessages anzeigen, und an alle versenden
OnRetriveData(e);
}
private void Client_StatusMessage(object sender, DataEventArgs e)
{
// einkommende StatusMessages durchreichen (zur Anzeige)
OnStatusMessage(e);
}
/* TODO ERROR: Skipped EndRegionDirectiveTrivia */
public override Task SendAsnyc(byte[] bytes)
{
return Task.Run(() => Send(bytes));
}
public override void Send(byte[] data)
{
foreach (ManagedPipeClient client in Clients) // an alle versenden
client.Send(data);
}
protected override void Dispose(bool disposing)
{
if (numberOfStartedServerInstances < maxNumbersOfServerInstances)
{
using (var clnt = new NamedPipeClientStream(pipeName))
{
// Herstellen einer Dummi-Verbindung, damit der ServerStream aus dem Wartezustand herauskommt.
clnt.Connect();
}
}
for (int i = Clients.Count - 1; i >= 0; i -= 1)
Clients[i].Dispose();
}
} }

View File

@@ -1,5 +1,4 @@
using global::System; using global::System;
using global::System.Reflection;
using global::System.Runtime.InteropServices; using global::System.Runtime.InteropServices;
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View File

@@ -6,180 +6,179 @@ using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using System.Xml; using System.Xml;
namespace Pilz.LicenseHelper namespace Pilz.LicenseHelper;
public static class AsposeModifyInMemory
{ {
public static class AsposeModifyInMemory private static string AsposeList = "Aspose.3D.dll, Aspose.BarCode.dll, Aspose.BarCode.Compact.dll, Aspose.BarCode.WPF.dll, Aspose.Cells.GridDesktop.dll, Aspose.Cells.GridWeb.dll, Aspose.CAD.dll, Aspose.Cells.dll, Aspose.Diagram.dll, Aspose.Email.dll, Aspose.Imaging.dll, Aspose.Note.dll, Aspose.OCR.dll, Aspose.Pdf.dll, Aspose.Slides.dll, Aspose.Tasks.dll, Aspose.Words.dll";
public static void ActivateMemoryPatching()
{ {
private static string AsposeList = "Aspose.3D.dll, Aspose.BarCode.dll, Aspose.BarCode.Compact.dll, Aspose.BarCode.WPF.dll, Aspose.Cells.GridDesktop.dll, Aspose.Cells.GridWeb.dll, Aspose.CAD.dll, Aspose.Cells.dll, Aspose.Diagram.dll, Aspose.Email.dll, Aspose.Imaging.dll, Aspose.Note.dll, Aspose.OCR.dll, Aspose.Pdf.dll, Aspose.Slides.dll, Aspose.Tasks.dll, Aspose.Words.dll"; Assembly[] arr = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in arr)
public static void ActivateMemoryPatching()
{ {
Assembly[] arr = AppDomain.CurrentDomain.GetAssemblies(); if (AsposeList.IndexOf(assembly.FullName.Split(',')[0] + ".dll") != -1)
foreach (Assembly assembly in arr) ActivateForAssembly(assembly);
{ }
if (AsposeList.IndexOf(assembly.FullName.Split(',')[0] + ".dll") != -1) AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(ActivateOnLoad);
ActivateForAssembly(assembly); }
}
AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(ActivateOnLoad); private static void ActivateOnLoad(object sender, AssemblyLoadEventArgs e)
{
if (AsposeList.IndexOf(e.LoadedAssembly.FullName.Split(',')[0] + ".dll") != -1)
ActivateForAssembly(e.LoadedAssembly);
}
private static void ActivateForAssembly(Assembly assembly)
{
MethodInfo miLicensed1 = typeof(AsposeModifyInMemory).GetMethod("InvokeMe1", BindingFlags.NonPublic | BindingFlags.Static);
MethodInfo miLicensed2 = typeof(AsposeModifyInMemory).GetMethod("InvokeMe2", BindingFlags.NonPublic | BindingFlags.Static);
MethodInfo miEvaluation = null;
Dictionary<string, MethodInfo> miDict = new Dictionary<string, MethodInfo>()
{
{"System.DateTime" , miLicensed1},
{"System.Xml.XmlElement", miLicensed2}
};
Type[] arrType = null;
bool isFound = false;
int nCount = 0;
try
{
arrType = assembly.GetTypes();
}
catch (ReflectionTypeLoadException err)
{
arrType = err.Types;
} }
private static void ActivateOnLoad(object sender, AssemblyLoadEventArgs e)
foreach (Type type in arrType)
{ {
if (AsposeList.IndexOf(e.LoadedAssembly.FullName.Split(',')[0] + ".dll") != -1) if (isFound) break;
ActivateForAssembly(e.LoadedAssembly);
}
private static void ActivateForAssembly(Assembly assembly) if (type == null) continue;
{
MethodInfo miLicensed1 = typeof(AsposeModifyInMemory).GetMethod("InvokeMe1", BindingFlags.NonPublic | BindingFlags.Static);
MethodInfo miLicensed2 = typeof(AsposeModifyInMemory).GetMethod("InvokeMe2", BindingFlags.NonPublic | BindingFlags.Static);
MethodInfo miEvaluation = null;
Dictionary<string, MethodInfo> miDict = new Dictionary<string, MethodInfo>() MethodInfo[] arrMInfo = type.GetMethods(BindingFlags.NonPublic | BindingFlags.Static);
{
{"System.DateTime" , miLicensed1},
{"System.Xml.XmlElement", miLicensed2}
};
Type[] arrType = null; foreach (MethodInfo info in arrMInfo)
bool isFound = false;
int nCount = 0;
try
{
arrType = assembly.GetTypes();
}
catch (ReflectionTypeLoadException err)
{
arrType = err.Types;
}
foreach (Type type in arrType)
{ {
if (isFound) break; if (isFound) break;
if (type == null) continue; try
MethodInfo[] arrMInfo = type.GetMethods(BindingFlags.NonPublic | BindingFlags.Static);
foreach (MethodInfo info in arrMInfo)
{ {
if (isFound) break; string strMethod = info.ToString();
if ((strMethod.IndexOf("(System.Xml.XmlElement, System.String)") > 0) && (miDict.ContainsKey(info.ReturnType.ToString())))
try
{ {
string strMethod = info.ToString(); miEvaluation = info;
if ((strMethod.IndexOf("(System.Xml.XmlElement, System.String)") > 0) && (miDict.ContainsKey(info.ReturnType.ToString()))) MemoryPatching(miEvaluation, miDict[miEvaluation.ReturnType.ToString()]);
{ nCount++;
miEvaluation = info;
MemoryPatching(miEvaluation, miDict[miEvaluation.ReturnType.ToString()]);
nCount++;
if ((assembly.FullName.IndexOf("Aspose.3D") != -1) && (nCount == 2)) if ((assembly.FullName.IndexOf("Aspose.3D") != -1) && (nCount == 2))
{ {
isFound = true; isFound = true;
break; break;
}
} }
} }
catch }
{ catch
throw new InvalidOperationException("MemoryPatching for \"" + assembly.FullName + "\" failed !"); {
} throw new InvalidOperationException("MemoryPatching for \"" + assembly.FullName + "\" failed !");
} }
} }
String[] aParts = assembly.FullName.Split(',');
string fName = aParts[0];
if (fName.IndexOf("Aspose.BarCode.") != -1)
fName = "Aspose.BarCode";
else if (fName.IndexOf("Aspose.3D") != -1)
fName = "Aspose.ThreeD";
try
{
Type type2 = assembly.GetType(fName + ".License");
MethodInfo mi = type2.GetMethod("SetLicense", new Type[] { typeof(Stream) });
string LData = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPExpY2Vuc2U+CiAgPERhdGE+CiAgICA8TGljZW5zZWRUbz5MaWNlbnNlZTwvTGljZW5zZWRUbz4KICAgIDxFbWFpbFRvPmxpY2Vuc2VlQGVtYWlsLmNvbTwvRW1haWxUbz4KICAgIDxMaWNlbnNlVHlwZT5EZXZlbG9wZXIgT0VNPC9MaWNlbnNlVHlwZT4KICAgIDxMaWNlbnNlTm90ZT5MaW1pdGVkIHRvIDEwMDAgZGV2ZWxvcGVyLCB1bmxpbWl0ZWQgcGh5c2ljYWwgbG9jYXRpb25zPC9MaWNlbnNlTm90ZT4KICAgIDxPcmRlcklEPjc4NDM3ODU3Nzg1PC9PcmRlcklEPgogICAgPFVzZXJJRD4xMTk3ODkyNDM3OTwvVXNlcklEPgogICAgPE9FTT5UaGlzIGlzIGEgcmVkaXN0cmlidXRhYmxlIGxpY2Vuc2U8L09FTT4KICAgIDxQcm9kdWN0cz4KICAgICAgPFByb2R1Y3Q+QXNwb3NlLlRvdGFsIFByb2R1Y3QgRmFtaWx5PC9Qcm9kdWN0PgogICAgPC9Qcm9kdWN0cz4KICAgIDxFZGl0aW9uVHlwZT5FbnRlcnByaXNlPC9FZGl0aW9uVHlwZT4KICAgIDxTZXJpYWxOdW1iZXI+e0YyQjk3MDQ1LTFCMjktNEIzRi1CRDUzLTYwMUVGRkExNUFBOX08L1NlcmlhbE51bWJlcj4KICAgIDxTdWJzY3JpcHRpb25FeHBpcnk+MjA5OTEyMzE8L1N1YnNjcmlwdGlvbkV4cGlyeT4KICAgIDxMaWNlbnNlVmVyc2lvbj4zLjA8L0xpY2Vuc2VWZXJzaW9uPgogIDwvRGF0YT4KICA8U2lnbmF0dXJlPlFYTndiM05sTGxSdmRHRnNJRkJ5YjJSMVkzUWdSbUZ0YVd4NTwvU2lnbmF0dXJlPgo8L0xpY2Vuc2U+";
Stream stream = new MemoryStream(Convert.FromBase64String(LData));
stream.Seek(0, SeekOrigin.Begin);
mi.Invoke(Activator.CreateInstance(type2, null), new Stream[] { stream });
}
catch
{
throw new InvalidOperationException("SetLicense for \"" + assembly.FullName + "\" failed !");
}
} }
String[] aParts = assembly.FullName.Split(',');
string fName = aParts[0];
if (fName.IndexOf("Aspose.BarCode.") != -1)
fName = "Aspose.BarCode";
else if (fName.IndexOf("Aspose.3D") != -1)
fName = "Aspose.ThreeD";
private static DateTime InvokeMe1(XmlElement element, string name) try
{ {
return DateTime.MaxValue; Type type2 = assembly.GetType(fName + ".License");
MethodInfo mi = type2.GetMethod("SetLicense", new Type[] { typeof(Stream) });
string LData = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPExpY2Vuc2U+CiAgPERhdGE+CiAgICA8TGljZW5zZWRUbz5MaWNlbnNlZTwvTGljZW5zZWRUbz4KICAgIDxFbWFpbFRvPmxpY2Vuc2VlQGVtYWlsLmNvbTwvRW1haWxUbz4KICAgIDxMaWNlbnNlVHlwZT5EZXZlbG9wZXIgT0VNPC9MaWNlbnNlVHlwZT4KICAgIDxMaWNlbnNlTm90ZT5MaW1pdGVkIHRvIDEwMDAgZGV2ZWxvcGVyLCB1bmxpbWl0ZWQgcGh5c2ljYWwgbG9jYXRpb25zPC9MaWNlbnNlTm90ZT4KICAgIDxPcmRlcklEPjc4NDM3ODU3Nzg1PC9PcmRlcklEPgogICAgPFVzZXJJRD4xMTk3ODkyNDM3OTwvVXNlcklEPgogICAgPE9FTT5UaGlzIGlzIGEgcmVkaXN0cmlidXRhYmxlIGxpY2Vuc2U8L09FTT4KICAgIDxQcm9kdWN0cz4KICAgICAgPFByb2R1Y3Q+QXNwb3NlLlRvdGFsIFByb2R1Y3QgRmFtaWx5PC9Qcm9kdWN0PgogICAgPC9Qcm9kdWN0cz4KICAgIDxFZGl0aW9uVHlwZT5FbnRlcnByaXNlPC9FZGl0aW9uVHlwZT4KICAgIDxTZXJpYWxOdW1iZXI+e0YyQjk3MDQ1LTFCMjktNEIzRi1CRDUzLTYwMUVGRkExNUFBOX08L1NlcmlhbE51bWJlcj4KICAgIDxTdWJzY3JpcHRpb25FeHBpcnk+MjA5OTEyMzE8L1N1YnNjcmlwdGlvbkV4cGlyeT4KICAgIDxMaWNlbnNlVmVyc2lvbj4zLjA8L0xpY2Vuc2VWZXJzaW9uPgogIDwvRGF0YT4KICA8U2lnbmF0dXJlPlFYTndiM05sTGxSdmRHRnNJRkJ5YjJSMVkzUWdSbUZ0YVd4NTwvU2lnbmF0dXJlPgo8L0xpY2Vuc2U+";
Stream stream = new MemoryStream(Convert.FromBase64String(LData));
stream.Seek(0, SeekOrigin.Begin);
mi.Invoke(Activator.CreateInstance(type2, null), new Stream[] { stream });
}
catch
{
throw new InvalidOperationException("SetLicense for \"" + assembly.FullName + "\" failed !");
} }
}
private static XmlElement InvokeMe2(XmlElement element, string name)
private static DateTime InvokeMe1(XmlElement element, string name)
{
return DateTime.MaxValue;
}
private static XmlElement InvokeMe2(XmlElement element, string name)
{
if (element.LocalName == "License")
{ {
if (element.LocalName == "License") string License64 = "PERhdGE+PExpY2Vuc2VkVG8+R3JvdXBEb2NzPC9MaWNlbnNlZFRvPjxMaWNlbnNlVHlwZT5TaXRlIE9FTTwvTGljZW5zZVR5cGU+PExpY2Vuc2VOb3RlPkxpbWl0ZWQgdG8gMTAgZGV2ZWxvcGVyczwvTGljZW5zZU5vdGU+PE9yZGVySUQ+MTMwNzI0MDQwODQ5PC9PcmRlcklEPjxPRU0+VGhpcyBpcyBhIHJlZGlzdHJpYnV0YWJsZSBsaWNlbnNlPC9PRU0+PFByb2R1Y3RzPjxQcm9kdWN0PkFzcG9zZS5Ub3RhbDwvUHJvZHVjdD48L1Byb2R1Y3RzPjxFZGl0aW9uVHlwZT5FbnRlcnByaXNlPC9FZGl0aW9uVHlwZT48U2VyaWFsTnVtYmVyPjliNTc5NTAxLTUyNjEtNDIyMC04NjcwLWZjMmQ4Y2NkZDkwYzwvU2VyaWFsTnVtYmVyPjxTdWJzY3JpcHRpb25FeHBpcnk+MjAxNDA3MjQ8L1N1YnNjcmlwdGlvbkV4cGlyeT48TGljZW5zZVZlcnNpb24+Mi4yPC9MaWNlbnNlVmVyc2lvbj48L0RhdGE+PFNpZ25hdHVyZT5udFpocmRoL3I0QS81ZFpsU2dWYnhac0hYSFBxSjZ5UVVYa0RvaW4vS2lVZWhUUWZET0lQdHdzUlR2NmRTUVplOVdXekNnV3RGdkdROWpmR2QySmF4YUQvbkx1ZEk2R0VVajhqeVhUMG4vbWRrMEF1WVZNYlBXRjJYd3dSTnFlTmRrblYyQjhrZVFwbDJ2RzZVbnhxS2J6VVFxS2Rhc1pzZ2w1Q0xqSFVEWms9PC9TaWduYXR1cmU+";
{ element.InnerXml = new UTF8Encoding().GetString(Convert.FromBase64String(License64));
string License64 = "PERhdGE+PExpY2Vuc2VkVG8+R3JvdXBEb2NzPC9MaWNlbnNlZFRvPjxMaWNlbnNlVHlwZT5TaXRlIE9FTTwvTGljZW5zZVR5cGU+PExpY2Vuc2VOb3RlPkxpbWl0ZWQgdG8gMTAgZGV2ZWxvcGVyczwvTGljZW5zZU5vdGU+PE9yZGVySUQ+MTMwNzI0MDQwODQ5PC9PcmRlcklEPjxPRU0+VGhpcyBpcyBhIHJlZGlzdHJpYnV0YWJsZSBsaWNlbnNlPC9PRU0+PFByb2R1Y3RzPjxQcm9kdWN0PkFzcG9zZS5Ub3RhbDwvUHJvZHVjdD48L1Byb2R1Y3RzPjxFZGl0aW9uVHlwZT5FbnRlcnByaXNlPC9FZGl0aW9uVHlwZT48U2VyaWFsTnVtYmVyPjliNTc5NTAxLTUyNjEtNDIyMC04NjcwLWZjMmQ4Y2NkZDkwYzwvU2VyaWFsTnVtYmVyPjxTdWJzY3JpcHRpb25FeHBpcnk+MjAxNDA3MjQ8L1N1YnNjcmlwdGlvbkV4cGlyeT48TGljZW5zZVZlcnNpb24+Mi4yPC9MaWNlbnNlVmVyc2lvbj48L0RhdGE+PFNpZ25hdHVyZT5udFpocmRoL3I0QS81ZFpsU2dWYnhac0hYSFBxSjZ5UVVYa0RvaW4vS2lVZWhUUWZET0lQdHdzUlR2NmRTUVplOVdXekNnV3RGdkdROWpmR2QySmF4YUQvbkx1ZEk2R0VVajhqeVhUMG4vbWRrMEF1WVZNYlBXRjJYd3dSTnFlTmRrblYyQjhrZVFwbDJ2RzZVbnhxS2J6VVFxS2Rhc1pzZ2w1Q0xqSFVEWms9PC9TaWduYXR1cmU+";
element.InnerXml = new UTF8Encoding().GetString(Convert.FromBase64String(License64));
}
if (element.LocalName == "BlackList")
{
string BlackList64 = "PERhdGE+PC9EYXRhPjxTaWduYXR1cmU+cUJwMEx1cEVoM1ZnOWJjeS8vbUVXUk9KRWZmczRlY25iTHQxYlNhanU2NjY5RHlad09FakJ1eEdBdVBxS1hyd0x5bmZ5VWplYUNGQ0QxSkh2RVUxVUl5eXJOTnBSMXc2NXJIOUFyUCtFbE1lVCtIQkZ4NFMzckFVMnd6dkxPZnhGeU9DQ0dGQ2UraTdiSHlGQk44WHp6R1UwdGRPMGR1RTFoRTQ5M1RNY3pRPTwvU2lnbmF0dXJlPg==";
element.InnerXml = new UTF8Encoding().GetString(Convert.FromBase64String(BlackList64));
}
XmlNodeList elementsByTagName = element.GetElementsByTagName(name);
if (elementsByTagName.Count <= 0)
{
return null;
}
return (XmlElement)elementsByTagName[0];
} }
if (element.LocalName == "BlackList")
private static unsafe void MemoryPatching(MethodBase miEvaluation, MethodBase miLicensed)
{ {
IntPtr IntPtrEval = GetMemoryAddress(miEvaluation); string BlackList64 = "PERhdGE+PC9EYXRhPjxTaWduYXR1cmU+cUJwMEx1cEVoM1ZnOWJjeS8vbUVXUk9KRWZmczRlY25iTHQxYlNhanU2NjY5RHlad09FakJ1eEdBdVBxS1hyd0x5bmZ5VWplYUNGQ0QxSkh2RVUxVUl5eXJOTnBSMXc2NXJIOUFyUCtFbE1lVCtIQkZ4NFMzckFVMnd6dkxPZnhGeU9DQ0dGQ2UraTdiSHlGQk44WHp6R1UwdGRPMGR1RTFoRTQ5M1RNY3pRPTwvU2lnbmF0dXJlPg==";
IntPtr IntPtrLicensed = GetMemoryAddress(miLicensed); element.InnerXml = new UTF8Encoding().GetString(Convert.FromBase64String(BlackList64));
if (IntPtr.Size == 8)
*((long*)IntPtrEval.ToPointer()) = *((long*)IntPtrLicensed.ToPointer());
else
*((int*)IntPtrEval.ToPointer()) = *((int*)IntPtrLicensed.ToPointer());
} }
XmlNodeList elementsByTagName = element.GetElementsByTagName(name);
private static unsafe IntPtr GetMemoryAddress(MethodBase mb) if (elementsByTagName.Count <= 0)
{ {
RuntimeHelpers.PrepareMethod(mb.MethodHandle); return null;
}
if ((Environment.Version.Major >= 4) || ((Environment.Version.Major == 2) && (Environment.Version.MinorRevision >= 3053))) return (XmlElement)elementsByTagName[0];
{ }
return new IntPtr(((int*)mb.MethodHandle.Value.ToPointer() + 2));
}
UInt64* location = (UInt64*)(mb.MethodHandle.Value.ToPointer());
int index = (int)(((*location) >> 32) & 0xFF); private static unsafe void MemoryPatching(MethodBase miEvaluation, MethodBase miLicensed)
if (IntPtr.Size == 8) {
{ IntPtr IntPtrEval = GetMemoryAddress(miEvaluation);
ulong* classStart = (ulong*)mb.DeclaringType.TypeHandle.Value.ToPointer(); IntPtr IntPtrLicensed = GetMemoryAddress(miLicensed);
ulong* address = classStart + index + 10;
return new IntPtr(address); if (IntPtr.Size == 8)
} *((long*)IntPtrEval.ToPointer()) = *((long*)IntPtrLicensed.ToPointer());
else else
{ *((int*)IntPtrEval.ToPointer()) = *((int*)IntPtrLicensed.ToPointer());
uint* classStart = (uint*)mb.DeclaringType.TypeHandle.Value.ToPointer();
uint* address = classStart + index + 10; }
return new IntPtr(address);
}
private static unsafe IntPtr GetMemoryAddress(MethodBase mb)
{
RuntimeHelpers.PrepareMethod(mb.MethodHandle);
if ((Environment.Version.Major >= 4) || ((Environment.Version.Major == 2) && (Environment.Version.MinorRevision >= 3053)))
{
return new IntPtr(((int*)mb.MethodHandle.Value.ToPointer() + 2));
}
UInt64* location = (UInt64*)(mb.MethodHandle.Value.ToPointer());
int index = (int)(((*location) >> 32) & 0xFF);
if (IntPtr.Size == 8)
{
ulong* classStart = (ulong*)mb.DeclaringType.TypeHandle.Value.ToPointer();
ulong* address = classStart + index + 10;
return new IntPtr(address);
}
else
{
uint* classStart = (uint*)mb.DeclaringType.TypeHandle.Value.ToPointer();
uint* address = classStart + index + 10;
return new IntPtr(address);
} }
} }
} }

View File

@@ -1,6 +1,4 @@
using System.Reflection; using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly // Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von // für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von

View File

@@ -1,45 +1,39 @@
using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Model; using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention;
public class FilesRetentionClient : ClientBase
{ {
public class FilesRetentionClient : ClientBase public FilesRetentionClient(NextcloudClient client) : base(client)
{ {
public FilesRetentionClient(NextcloudClient client) : base(client) }
public bool CreateRetentionRule(RetentionRuleInfo rule)
{
var entry = rule.ToOcsData();
return Client.Ocs.GetApi<OcsApiFilesRetention>().CreateRetentionRule(entry);
}
public bool DeleteRetentionRule(int ruleID)
{
return Client.Ocs.GetApi<OcsApiFilesRetention>().DeleteRetentionRule(ruleID);
}
public RetentionRule[]? GetRetentionRules()
{
var api = Client.Ocs.GetApi<OcsApiFilesRetention>();
var response = 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();
} }
public bool CreateRetentionRule(RetentionRuleInfo rule) return null;
{
var entry = rule.ToOcsData();
return Client.Ocs.GetApi<OcsApiFilesRetention>().CreateRetentionRule(entry);
}
public bool DeleteRetentionRule(int ruleID)
{
return Client.Ocs.GetApi<OcsApiFilesRetention>().DeleteRetentionRule(ruleID);
}
public RetentionRule[]? GetRetentionRules()
{
var api = Client.Ocs.GetApi<OcsApiFilesRetention>();
var response = 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;
}
} }
} }

View File

@@ -1,36 +1,30 @@
using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs; using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Model namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Model;
public class RetentionRule : RetentionRuleInfo
{ {
public class RetentionRule : RetentionRuleInfo /// <summary>
/// The ID for the retention rule.
/// </summary>
public int ID { get; init; }
/// <summary>
/// Defines if a background job has been generated
/// </summary>
public bool HasJob { get; init; }
public RetentionRule()
{ {
/// <summary> }
/// The ID for the retention rule.
/// </summary>
public int ID { get; init; }
/// <summary> public RetentionRule(OcsResponseDataEntryRetention data)
/// Defines if a background job has been generated {
/// </summary> ID = data.ID ?? -1;
public bool HasJob { get; init; } TagID = data.TagID ?? -1;
TimeUnit = (RetentionTimeUnit)(data.TimeUnit ?? 0);
public RetentionRule() TimeAmount = data.TimeAmount ?? -1;
{ TimeAfter = (RetentionTimeAfter)(data.TimeAfter ?? 0);
} HasJob = data.HasJob ?? false;
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);
HasJob = data.HasJob ?? false;
}
} }
} }

View File

@@ -1,43 +1,37 @@
using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs; using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Model namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Model;
public class RetentionRuleInfo
{ {
public class RetentionRuleInfo /// <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; }
public OcsDataRetentionRule ToOcsData()
{ {
/// <summary> return new OcsDataRetentionRule
/// 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; }
public OcsDataRetentionRule ToOcsData()
{ {
return new OcsDataRetentionRule TagID = TagID,
{ TimeUnit = (int)TimeUnit,
TagID = TagID, TimeAmount = TimeAmount,
TimeUnit = (int)TimeUnit, TimeAfter = (int)TimeAfter
TimeAmount = TimeAmount, };
TimeAfter = (int)TimeAfter
};
}
} }
} }

View File

@@ -1,14 +1,7 @@
using System; namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Model;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Model public enum RetentionTimeAfter
{ {
public enum RetentionTimeAfter CreationDate,
{ LastAccess
CreationDate,
LastAccess
}
} }

View File

@@ -1,16 +1,9 @@
using System; namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Model;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Model public enum RetentionTimeUnit
{ {
public enum RetentionTimeUnit Day,
{ Week,
Day, Month,
Week, Year
Month,
Year
}
} }

View File

@@ -1,26 +1,20 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using Pilz.Networking.CloudProviders.Nextcloud.Ocs; using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs;
public class OcsDataRetentionRule : OcsData
{ {
public class OcsDataRetentionRule : OcsData
{
[JsonProperty("tagid")] [JsonProperty("tagid")]
public int? TagID { get; set; } public int? TagID { get; set; }
[JsonProperty("timeunit")] [JsonProperty("timeunit")]
public int? TimeUnit { get; set; } public int? TimeUnit { get; set; }
[JsonProperty("timeamount")] [JsonProperty("timeamount")]
public int? TimeAmount { get; set; } public int? TimeAmount { get; set; }
[JsonProperty("timeafter")] [JsonProperty("timeafter")]
public int? TimeAfter { get; set; } public int? TimeAfter { get; set; }
}
} }

View File

@@ -1,31 +1,25 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses; using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs;
public class OcsResponseDataEntryRetention : OcsResponseDataEntry
{ {
public class OcsResponseDataEntryRetention : OcsResponseDataEntry [JsonProperty("id")]
{ public int? ID { get; set; }
[JsonProperty("id")]
public int? ID { get; set; }
[JsonProperty("tagid")] [JsonProperty("tagid")]
public int? TagID { get; set; } public int? TagID { get; set; }
[JsonProperty("timeunit")] [JsonProperty("timeunit")]
public int? TimeUnit { get; set; } public int? TimeUnit { get; set; }
[JsonProperty("timeamount")] [JsonProperty("timeamount")]
public int? TimeAmount { get; set; } public int? TimeAmount { get; set; }
[JsonProperty("timeafter")] [JsonProperty("timeafter")]
public int? TimeAfter { get; set; } public int? TimeAfter { get; set; }
[JsonProperty("hasJob")] [JsonProperty("hasJob")]
public bool? HasJob { get; set; } public bool? HasJob { get; set; }
}
} }

View File

@@ -1,14 +1,7 @@
using Newtonsoft.Json; using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs;
public class OcsResponseRetention : OcsResponse<OcsResponseDataArray<OcsResponseDataEntryRetention>>
{ {
public class OcsResponseRetention : OcsResponse<OcsResponseDataArray<OcsResponseDataEntryRetention>>
{
}
} }

View File

@@ -1,38 +1,31 @@
using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs; using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention.Ocs;
using Pilz.Networking.CloudProviders.Nextcloud.Ocs; using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.FileRetention;
public class OcsApiFilesRetention : OcsApiBase
{ {
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 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 bool CreateRetentionRule(OcsDataRetentionRule rule)
{ {
} var response = Manager.MakeRequest(HttpMethod.Post, OCS_FILE_RETENTION_RULES, content: rule);
return response.IsSuccessStatusCode;
}
public bool CreateRetentionRule(OcsDataRetentionRule rule) public bool DeleteRetentionRule(int ruleID)
{ {
var response = Manager.MakeRequest(HttpMethod.Post, OCS_FILE_RETENTION_RULES, content: rule); var response = Manager.MakeRequest(HttpMethod.Delete, OCS_FILE_RETENTION_RULE.FillParameters(ruleID));
return response.IsSuccessStatusCode; return response.IsSuccessStatusCode;
} }
public bool DeleteRetentionRule(int ruleID) public OcsResponseRetention? GetRetentionRules()
{ {
var response = Manager.MakeRequest(HttpMethod.Delete, OCS_FILE_RETENTION_RULE.FillParameters(ruleID)); return Manager.MakeRequestOcs<OcsResponseRetention>(HttpMethod.Get, OCS_FILE_RETENTION_RULES);
return response.IsSuccessStatusCode;
}
public OcsResponseRetention? GetRetentionRules()
{
return Manager.MakeRequestOcs<OcsResponseRetention>(HttpMethod.Get, OCS_FILE_RETENTION_RULES);
}
} }
} }

View File

@@ -1,116 +1,110 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
public class Column
{ {
public class Column [JsonProperty("type")]
private string? type;
[JsonProperty("subtype")]
private string? subtype;
[JsonProperty("id")]
public long ColumnId { get; set; }
[JsonProperty("tableId")]
public long TableId { get; set; }
[JsonProperty("title")]
public string? Title { get; set; }
[JsonProperty("createdBy")]
public string? CreatedBy { get; set; }
[JsonProperty("createdAt")]
public DateTime CreatedAt { get; set; }
[JsonProperty("lastEditBy")]
public string? LastEditBy { get; set; }
[JsonProperty("lastEditAt")]
public DateTime LastEditAt { get; set; }
[JsonProperty("mandatory")]
public bool Mandatory { get; set; }
[JsonProperty("description")]
public string? Description { get; set; }
[JsonProperty("numberDefault")]
public float? NumberDefault { get; set; }
[JsonProperty("numberMin")]
public float? NumberMin { get; set; }
[JsonProperty("numberMax")]
public float? NumberMax { get; set; }
[JsonProperty("numberDecimals")]
public float NumberDecimals { get; set; }
[JsonProperty("numberPrefix")]
public string? NumberPrefix { get; set; }
[JsonProperty("numberSuffix")]
public string? NumberSuffix { get; set; }
[JsonProperty("textDefault")]
public string? TextDefault { get; set; }
[JsonProperty("textAllowedPattern")]
public string? TextAllowedPattern { get; set; }
[JsonProperty("textMaxLength")]
public int? TextMaxLength { get; set; }
[JsonProperty("selectionOptions")]
public List<ColumnSelectionOption> SelectionOptions { get; } = new();
[JsonProperty("selectionDefault")]
public int? SelectionDefault { get; set; }
[JsonProperty("datetimeDefault")]
public DateTime? DatetimeDefault { get; set; }
[JsonIgnore]
public ColumnType Type
{ {
[JsonProperty("type")] get => type switch
private string? type;
[JsonProperty("subtype")]
private string? subtype;
[JsonProperty("id")]
public long ColumnId { get; set; }
[JsonProperty("tableId")]
public long TableId { get; set; }
[JsonProperty("title")]
public string? Title { get; set; }
[JsonProperty("createdBy")]
public string? CreatedBy { get; set; }
[JsonProperty("createdAt")]
public DateTime CreatedAt { get; set; }
[JsonProperty("lastEditBy")]
public string? LastEditBy { get; set; }
[JsonProperty("lastEditAt")]
public DateTime LastEditAt { get; set; }
[JsonProperty("mandatory")]
public bool Mandatory { get; set; }
[JsonProperty("description")]
public string? Description { get; set; }
[JsonProperty("numberDefault")]
public float? NumberDefault { get; set; }
[JsonProperty("numberMin")]
public float? NumberMin { get; set; }
[JsonProperty("numberMax")]
public float? NumberMax { get; set; }
[JsonProperty("numberDecimals")]
public float NumberDecimals { get; set; }
[JsonProperty("numberPrefix")]
public string? NumberPrefix { get; set; }
[JsonProperty("numberSuffix")]
public string? NumberSuffix { get; set; }
[JsonProperty("textDefault")]
public string? TextDefault { get; set; }
[JsonProperty("textAllowedPattern")]
public string? TextAllowedPattern { get; set; }
[JsonProperty("textMaxLength")]
public int? TextMaxLength { get; set; }
[JsonProperty("selectionOptions")]
public List<ColumnSelectionOption> SelectionOptions { get; } = new();
[JsonProperty("selectionDefault")]
public int? SelectionDefault { get; set; }
[JsonProperty("datetimeDefault")]
public DateTime? DatetimeDefault { get; set; }
[JsonIgnore]
public ColumnType Type
{ {
get => type switch "text" => ColumnType.Text,
{ "selection" => ColumnType.Selection,
"text" => ColumnType.Text, "datetime" => ColumnType.DateTime,
"selection" => ColumnType.Selection, _ => ColumnType.Unknown,
"datetime" => ColumnType.DateTime, };
_ => ColumnType.Unknown, set => type = value switch
};
set => type = value switch
{
ColumnType.Text => "text",
ColumnType.Selection => "selection",
ColumnType.DateTime => "datetime",
_ => "text"
};
}
[JsonIgnore]
public ColumnSubtype Subtype
{ {
get => subtype switch ColumnType.Text => "text",
{ ColumnType.Selection => "selection",
"line" => ColumnSubtype.Line, ColumnType.DateTime => "datetime",
"" => ColumnSubtype.None, _ => "text"
_ => ColumnSubtype.Unknown, };
}; }
set => subtype = value switch
{ [JsonIgnore]
ColumnSubtype.Line => "line", public ColumnSubtype Subtype
_ => "" {
}; get => subtype switch
} {
"line" => ColumnSubtype.Line,
"" => ColumnSubtype.None,
_ => ColumnSubtype.Unknown,
};
set => subtype = value switch
{
ColumnSubtype.Line => "line",
_ => ""
};
} }
} }

View File

@@ -1,18 +1,12 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
public class ColumnSelectionOption
{ {
public class ColumnSelectionOption [JsonProperty("id")]
{ public long Id { get; set; }
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("label")] [JsonProperty("label")]
public string? Label { get; set; } public string? Label { get; set; }
}
} }

View File

@@ -1,15 +1,8 @@
using System; namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model public enum ColumnSubtype
{ {
public enum ColumnSubtype None,
{ Unknown,
None, Line
Unknown,
Line
}
} }

View File

@@ -1,16 +1,9 @@
using System; namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model public enum ColumnType
{ {
public enum ColumnType Unknown,
{ Text,
Unknown, Selection,
Text, DateTime
Selection,
DateTime
}
} }

View File

@@ -1,12 +1,5 @@
using System; namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model public class Columns : List<Column>
{ {
public class Columns : List<Column>
{
}
} }

View File

@@ -1,33 +1,27 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
public class Row
{ {
public class Row [JsonProperty("id")]
{ public long RowId { get; set; } = -1;
[JsonProperty("id")]
public long RowId { get; set; } = -1;
[JsonProperty("tableId")] [JsonProperty("tableId")]
public long TableId { get; set; } = -1; public long TableId { get; set; } = -1;
[JsonProperty("createdBy")] [JsonProperty("createdBy")]
public string? CreatedBy { get; set; } public string? CreatedBy { get; set; }
[JsonProperty("createdAt")] [JsonProperty("createdAt")]
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }
[JsonProperty("lastEditBy")] [JsonProperty("lastEditBy")]
public string? LastEditBy { get; set; } public string? LastEditBy { get; set; }
[JsonProperty("lastEditAt")] [JsonProperty("lastEditAt")]
public DateTime LastEditAt { get; set; } public DateTime LastEditAt { get; set; }
[JsonProperty("data")] [JsonProperty("data")]
public List<RowData> Data { get; set; } = new(); public List<RowData> Data { get; set; } = new();
}
} }

View File

@@ -1,18 +1,12 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
public class RowData
{ {
public class RowData [JsonProperty("columnId")]
{ public long ColumnId { get; set; }
[JsonProperty("columnId")]
public long ColumnId { get; set; }
[JsonProperty("value")] [JsonProperty("value")]
public object? Value { get; set; } public object? Value { get; set; }
}
} }

View File

@@ -1,12 +1,5 @@
using System; namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model public class RowSimple : List<object>
{ {
public class RowSimple : List<object>
{
}
} }

View File

@@ -1,15 +1,9 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
public class RowUpdate
{ {
public class RowUpdate [JsonProperty("data")]
{ public Dictionary<long, object?> Data { get; set; } = new();
[JsonProperty("data")]
public Dictionary<long, object?> Data { get; set; } = new();
}
} }

View File

@@ -1,12 +1,5 @@
using System; namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model public class Rows : List<Row>
{ {
public class Rows : List<Row>
{
}
} }

View File

@@ -1,12 +1,5 @@
using System; namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model public class RowsSimple : List<RowSimple>
{ {
public class RowsSimple : List<RowSimple>
{
}
} }

View File

@@ -1,86 +1,79 @@
using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model; using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
using Pilz.Networking.CloudProviders.Nextcloud.Ocs; using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables;
public class OcsApiTables : OcsApiBase
{ {
public class OcsApiTables : OcsApiBase public static readonly OcsApiUrlPath OCS_TABLES_TABLE_ROWS = new("/apps/tables/api/1/tables/{0}/rows");
public static readonly OcsApiUrlPath OCS_TABLES_VIEW_ROWS = new("/apps/tables/api/1/views/{0}/rows");
public static readonly OcsApiUrlPath OCS_TABLES_TABLE_ROWS_SIMPLE = new("/apps/tables/api/1/tables/{0}/rows/simple");
public static readonly OcsApiUrlPath OCS_TABLES_TABLE_COLUMNS = new("/apps/tables/api/1/tables/{0}/columns");
public static readonly OcsApiUrlPath OCS_TABLES_VIEW_COLUMNS = new("/apps/tables/api/1/views/{0}/columns");
public static readonly OcsApiUrlPath OCS_TABLES_ROW = new("/apps/tables/api/1/rows/{0}");
public static readonly OcsApiUrlPath OCS_TABLES_COLUMN = new("/apps/tables/api/1/column/{0}");
public OcsApiTables(OcsApi manager) : base(manager)
{ {
public static readonly OcsApiUrlPath OCS_TABLES_TABLE_ROWS = new("/apps/tables/api/1/tables/{0}/rows"); }
public static readonly OcsApiUrlPath OCS_TABLES_VIEW_ROWS = new("/apps/tables/api/1/views/{0}/rows");
public static readonly OcsApiUrlPath OCS_TABLES_TABLE_ROWS_SIMPLE = new("/apps/tables/api/1/tables/{0}/rows/simple");
public static readonly OcsApiUrlPath OCS_TABLES_TABLE_COLUMNS = new("/apps/tables/api/1/tables/{0}/columns");
public static readonly OcsApiUrlPath OCS_TABLES_VIEW_COLUMNS = new("/apps/tables/api/1/views/{0}/columns");
public static readonly OcsApiUrlPath OCS_TABLES_ROW = new("/apps/tables/api/1/rows/{0}");
public static readonly OcsApiUrlPath OCS_TABLES_COLUMN = new("/apps/tables/api/1/column/{0}");
public OcsApiTables(OcsApi manager) : base(manager) public RowsSimple? GetRowsSimple(long tableId)
{ {
} return Manager.MakeRequest<RowsSimple>(HttpMethod.Get, OCS_TABLES_TABLE_ROWS_SIMPLE.FillParameters(tableId));
}
public RowsSimple? GetRowsSimple(long tableId) public Rows? GetRows(long tableId)
{ {
return Manager.MakeRequest<RowsSimple>(HttpMethod.Get, OCS_TABLES_TABLE_ROWS_SIMPLE.FillParameters(tableId)); return Manager.MakeRequest<Rows>(HttpMethod.Get, OCS_TABLES_TABLE_ROWS.FillParameters(tableId));
} }
public Rows? GetRows(long tableId) public Rows? GetViewRows(long viewId)
{ {
return Manager.MakeRequest<Rows>(HttpMethod.Get, OCS_TABLES_TABLE_ROWS.FillParameters(tableId)); return Manager.MakeRequest<Rows>(HttpMethod.Get, OCS_TABLES_VIEW_ROWS.FillParameters(viewId));
} }
public Rows? GetViewRows(long viewId) public Row? GetRow(long rowId)
{ {
return Manager.MakeRequest<Rows>(HttpMethod.Get, OCS_TABLES_VIEW_ROWS.FillParameters(viewId)); return Manager.MakeRequest<Row>(HttpMethod.Get, OCS_TABLES_ROW.FillParameters(rowId));
} }
public Row? GetRow(long rowId) public Columns? GetColumns(long tableId)
{ {
return Manager.MakeRequest<Row>(HttpMethod.Get, OCS_TABLES_ROW.FillParameters(rowId)); return Manager.MakeRequest<Columns>(HttpMethod.Get, OCS_TABLES_TABLE_COLUMNS.FillParameters(tableId));
} }
public Columns? GetColumns(long tableId) public Columns? GetViewColumns(long viewId)
{ {
return Manager.MakeRequest<Columns>(HttpMethod.Get, OCS_TABLES_TABLE_COLUMNS.FillParameters(tableId)); return Manager.MakeRequest<Columns>(HttpMethod.Get, OCS_TABLES_VIEW_COLUMNS.FillParameters(viewId));
} }
public Columns? GetViewColumns(long viewId) public Column? GetColumn(long columnId)
{ {
return Manager.MakeRequest<Columns>(HttpMethod.Get, OCS_TABLES_VIEW_COLUMNS.FillParameters(viewId)); return Manager.MakeRequest<Column>(HttpMethod.Get, OCS_TABLES_COLUMN.FillParameters(columnId));
} }
public Column? GetColumn(long columnId) public Row? DeleteRow(long rowId)
{ {
return Manager.MakeRequest<Column>(HttpMethod.Get, OCS_TABLES_COLUMN.FillParameters(columnId)); return Manager.MakeRequest<Row>(HttpMethod.Delete, OCS_TABLES_ROW.FillParameters(rowId));
} }
public Row? DeleteRow(long rowId) public Column? DeleteColumn(long columnId)
{ {
return Manager.MakeRequest<Row>(HttpMethod.Delete, OCS_TABLES_ROW.FillParameters(rowId)); return Manager.MakeRequest<Column>(HttpMethod.Delete, OCS_TABLES_COLUMN.FillParameters(columnId));
} }
public Column? DeleteColumn(long columnId) public Row? UpdateRow(long rowId, RowUpdate values)
{ {
return Manager.MakeRequest<Column>(HttpMethod.Delete, OCS_TABLES_COLUMN.FillParameters(columnId)); return Manager.MakeRequest<Row>(HttpMethod.Put, OCS_TABLES_ROW.FillParameters(rowId), content: values);
} }
public Row? UpdateRow(long rowId, RowUpdate values) public Row? CreateRow(long tableId, RowUpdate values)
{ {
return Manager.MakeRequest<Row>(HttpMethod.Put, OCS_TABLES_ROW.FillParameters(rowId), content: values); return Manager.MakeRequest<Row>(HttpMethod.Post, OCS_TABLES_TABLE_ROWS.FillParameters(tableId), content: values);
} }
public Row? CreateRow(long tableId, RowUpdate values) public Row? CreateViewRow(long viewId, RowUpdate values)
{ {
return Manager.MakeRequest<Row>(HttpMethod.Post, OCS_TABLES_TABLE_ROWS.FillParameters(tableId), content: values); return Manager.MakeRequest<Row>(HttpMethod.Post, OCS_TABLES_VIEW_ROWS.FillParameters(viewId), content: values);
}
public Row? CreateViewRow(long viewId, RowUpdate values)
{
return Manager.MakeRequest<Row>(HttpMethod.Post, OCS_TABLES_VIEW_ROWS.FillParameters(viewId), content: values);
}
} }
} }

View File

@@ -1,81 +1,75 @@
using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model; using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables;
public class TablesClient : ClientBase
{ {
public class TablesClient : ClientBase public TablesClient(NextcloudClient client) : base(client)
{ {
public TablesClient(NextcloudClient client) : base(client) }
{
}
public RowsSimple? GetRowsSimple(long tableId) public RowsSimple? GetRowsSimple(long tableId)
{ {
return Client.Ocs.GetApi<OcsApiTables>().GetRowsSimple(tableId); return Client.Ocs.GetApi<OcsApiTables>().GetRowsSimple(tableId);
} }
public Rows? GetRows(long tableId) public Rows? GetRows(long tableId)
{ {
return Client.Ocs.GetApi<OcsApiTables>().GetRows(tableId); return Client.Ocs.GetApi<OcsApiTables>().GetRows(tableId);
} }
public Rows? GetViewRows(long viewId) public Rows? GetViewRows(long viewId)
{ {
return Client.Ocs.GetApi<OcsApiTables>().GetViewRows(viewId); return Client.Ocs.GetApi<OcsApiTables>().GetViewRows(viewId);
} }
public Row? GetRow(long rowId) public Row? GetRow(long rowId)
{ {
return Client.Ocs.GetApi<OcsApiTables>().GetRow(rowId); return Client.Ocs.GetApi<OcsApiTables>().GetRow(rowId);
} }
public Columns? GetColumns(long tableId) public Columns? GetColumns(long tableId)
{ {
return Client.Ocs.GetApi<OcsApiTables>().GetColumns(tableId); return Client.Ocs.GetApi<OcsApiTables>().GetColumns(tableId);
} }
public Columns? GetViewColumns(long viewId) public Columns? GetViewColumns(long viewId)
{ {
return Client.Ocs.GetApi<OcsApiTables>().GetViewColumns(viewId); return Client.Ocs.GetApi<OcsApiTables>().GetViewColumns(viewId);
} }
public Column? GetColumn(long columnId) public Column? GetColumn(long columnId)
{ {
return Client.Ocs.GetApi<OcsApiTables>().GetColumn(columnId); return Client.Ocs.GetApi<OcsApiTables>().GetColumn(columnId);
} }
public bool DeleteRow(long rowId) public bool DeleteRow(long rowId)
{ {
return DeleteRowAdv(rowId) is not null; return DeleteRowAdv(rowId) is not null;
} }
public Row? DeleteRowAdv(long rowId) public Row? DeleteRowAdv(long rowId)
{ {
return Client.Ocs.GetApi<OcsApiTables>().DeleteRow(rowId); return Client.Ocs.GetApi<OcsApiTables>().DeleteRow(rowId);
} }
public bool DeleteColumn(long columnId) public bool DeleteColumn(long columnId)
{ {
return DeleteColumnAdv(columnId) is not null; return DeleteColumnAdv(columnId) is not null;
} }
public Column? DeleteColumnAdv(long columnId) public Column? DeleteColumnAdv(long columnId)
{ {
return Client.Ocs.GetApi<OcsApiTables>().DeleteColumn(columnId); return Client.Ocs.GetApi<OcsApiTables>().DeleteColumn(columnId);
} }
public Row? UpdateRow(long rowId, RowUpdate values) public Row? UpdateRow(long rowId, RowUpdate values)
{ {
return Client.Ocs.GetApi<OcsApiTables>().UpdateRow(rowId, values); return Client.Ocs.GetApi<OcsApiTables>().UpdateRow(rowId, values);
} }
public Row? CreateRow(long tableId, RowUpdate values) public Row? CreateRow(long tableId, RowUpdate values)
{ {
return Client.Ocs.GetApi<OcsApiTables>().CreateRow(tableId, values); return Client.Ocs.GetApi<OcsApiTables>().CreateRow(tableId, values);
}
} }
} }

View File

@@ -1,20 +1,22 @@
using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables; namespace Pilz.Networking.CloudProviders.Nextcloud.Client;
using Pilz.Networking.CloudProviders.Nextcloud.Client.Apps.Tables.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
/* Nicht gemergte Änderung aus Projekt "Pilz.Networking.CloudProviders.Nextcloud (net6.0)"
Vor:
namespace Pilz.Networking.CloudProviders.Nextcloud.Client namespace Pilz.Networking.CloudProviders.Nextcloud.Client
{ {
public abstract class ClientBase public abstract class ClientBase
{ Nach:
protected NextcloudClient Client { get; init; } namespace Pilz.Networking.CloudProviders.Nextcloud.Client;
protected ClientBase(NextcloudClient client) public abstract class ClientBase
{ */
Client = client; public abstract class ClientBase
} {
protected NextcloudClient Client { get; init; }
protected ClientBase(NextcloudClient client)
{
Client = client;
} }
} }

View File

@@ -1,34 +1,28 @@
using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Model; using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud;
public class CloudClient : ClientBase
{ {
public class CloudClient : ClientBase public CloudClient(NextcloudClient client) : base(client)
{ {
public CloudClient(NextcloudClient client) : base(client) }
{
}
public UserInfo? GetUserInfo()
{
if (!string.IsNullOrEmpty(Client.CurrentLogin?.LoginName))
return GetUserInfo(Client.CurrentLogin.LoginName);
else
return null;
}
public UserInfo? GetUserInfo(string username)
{
var result = Client.Ocs.Cloud.GetUserMeta(username);
if (result?.Data != null)
return new UserInfo(result.Data);
public UserInfo? GetUserInfo()
{
if (!string.IsNullOrEmpty(Client.CurrentLogin?.LoginName))
return GetUserInfo(Client.CurrentLogin.LoginName);
else
return null; return null;
} }
public UserInfo? GetUserInfo(string username)
{
var result = Client.Ocs.Cloud.GetUserMeta(username);
if (result?.Data != null)
return new UserInfo(result.Data);
return null;
} }
} }

View File

@@ -1,22 +1,14 @@
using Newtonsoft.Json; namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Model public class UserBackendCapabilities
{ {
public class UserBackendCapabilities /// <summary>
{ /// Defines if the display name can be changed.
/// <summary> /// </summary>
/// Defines if the display name can be changed. public bool SetDisplayName { get; set; }
/// </summary>
public bool SetDisplayName { get; set; }
/// <summary> /// <summary>
/// Defines if the password can be changed. /// Defines if the password can be changed.
/// </summary> /// </summary>
public bool SetPassword { get; set; } public bool SetPassword { get; set; }
}
} }

View File

@@ -1,131 +1,125 @@
using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Ocs; using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Ocs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Model namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Model;
public class UserInfo
{ {
public class UserInfo /// <summary>
/// Defines if the user is enabled.
/// </summary>
public bool Enabled { get; init; }
/// <summary>
/// The location of the user's storage directory.
/// </summary>
public string? StorageLocation { get; init; }
/// <summary>
/// The uniquie user id that infos are for.
/// </summary>
public string? ID { get; init; }
/// <summary>
/// The last time when the user has logged in to its account.
/// </summary>
public DateTime LastLogin { get; init; }
/// <summary>
/// The backend of the user. Common values are "Database" or "LDAP".
/// </summary>
public string? Backend { get; init; }
/// <summary>
/// The Email address of the user.
/// </summary>
public string? Email { get; init; }
/// <summary>
/// The displayname of the user.
/// </summary>
public string? Displayname { get; init; }
/// <summary>
/// The displayname of the user.
/// </summary>
public string? Displayname2 { get; init; }
/// <summary>
/// The phone number of the user.
/// </summary>
public string? Phone { get; init; }
/// <summary>
/// The address of the user.
/// </summary>
public string? Address { get; init; }
/// <summary>
/// The Website of the user.
/// </summary>
public string? Website { get; init; }
/// <summary>
/// The twitter profile name of the user.
/// </summary>
public string? Twitter { get; init; }
/// <summary>
/// Defines the groups the user is member of.
/// </summary>
public string[] Groups { get; init; }
/// <summary>
/// The configured language of the user.
/// </summary>
public string? Language { get; init; }
/// <summary>
/// The configured location of the user.
/// </summary>
public string? Locale { get; init; }
/// <summary>
/// Quota informations for the user.
/// </summary>
public UserQuota Quota { get; } = new();
/// <summary>
/// Backend capabilities of the user.
/// </summary>
public UserBackendCapabilities BackendCapabilities { get; } = new();
public UserInfo(OcsResponseDataUser responseData)
{ {
/// <summary> Enabled = Convert.ToBoolean(responseData.Enabled);
/// Defines if the user is enabled. StorageLocation = responseData.StorageLocation;
/// </summary> ID = responseData.ID;
public bool Enabled { get; init; } LastLogin = responseData.LastLogin.UnixTimeMillisecondsToDateTime();
Backend = responseData.Backend;
Email = responseData.Email;
Displayname = responseData.Displayname;
Displayname2 = responseData.Displayname2;
Phone = responseData.Phone;
Address = responseData.Address;
Website = responseData.Website;
Twitter = responseData.Twitter;
Groups = responseData.Groups ?? Array.Empty<string>();
Language = responseData.Language;
Locale = responseData.Locale;
/// <summary> if (responseData.Quota != null)
/// The location of the user's storage directory.
/// </summary>
public string? StorageLocation { get; init; }
/// <summary>
/// The uniquie user id that infos are for.
/// </summary>
public string? ID { get; init; }
/// <summary>
/// The last time when the user has logged in to its account.
/// </summary>
public DateTime LastLogin { get; init; }
/// <summary>
/// The backend of the user. Common values are "Database" or "LDAP".
/// </summary>
public string? Backend { get; init; }
/// <summary>
/// The Email address of the user.
/// </summary>
public string? Email { get; init; }
/// <summary>
/// The displayname of the user.
/// </summary>
public string? Displayname { get; init; }
/// <summary>
/// The displayname of the user.
/// </summary>
public string? Displayname2 { get; init; }
/// <summary>
/// The phone number of the user.
/// </summary>
public string? Phone { get; init; }
/// <summary>
/// The address of the user.
/// </summary>
public string? Address { get; init; }
/// <summary>
/// The Website of the user.
/// </summary>
public string? Website { get; init; }
/// <summary>
/// The twitter profile name of the user.
/// </summary>
public string? Twitter { get; init; }
/// <summary>
/// Defines the groups the user is member of.
/// </summary>
public string[] Groups { get; init; }
/// <summary>
/// The configured language of the user.
/// </summary>
public string? Language { get; init; }
/// <summary>
/// The configured location of the user.
/// </summary>
public string? Locale { get; init; }
/// <summary>
/// Quota informations for the user.
/// </summary>
public UserQuota Quota { get; } = new();
/// <summary>
/// Backend capabilities of the user.
/// </summary>
public UserBackendCapabilities BackendCapabilities { get; } = new();
public UserInfo(OcsResponseDataUser responseData)
{ {
Enabled = Convert.ToBoolean(responseData.Enabled); Quota.Free = responseData.Quota.Free ?? 0;
StorageLocation = responseData.StorageLocation; Quota.Used = responseData.Quota.Used ?? 0;
ID = responseData.ID; Quota.Total = responseData.Quota.Total ?? 0;
LastLogin = responseData.LastLogin.UnixTimeMillisecondsToDateTime(); Quota.Relative = responseData.Quota.Relative ?? 0.0F;
Backend = responseData.Backend; Quota.Quota = responseData.Quota.Quota ?? 0;
Email = responseData.Email; }
Displayname = responseData.Displayname;
Displayname2 = responseData.Displayname2;
Phone = responseData.Phone;
Address = responseData.Address;
Website = responseData.Website;
Twitter = responseData.Twitter;
Groups = responseData.Groups ?? Array.Empty<string>();
Language = responseData.Language;
Locale = responseData.Locale;
if (responseData.Quota != null) if (responseData.BackendCapabilities != null)
{ {
Quota.Free = responseData.Quota.Free ?? 0; BackendCapabilities.SetDisplayName = Convert.ToBoolean(responseData.BackendCapabilities.SetDisplayName);
Quota.Used = responseData.Quota.Used ?? 0; BackendCapabilities.SetPassword = Convert.ToBoolean(responseData.BackendCapabilities.SetPassword);
Quota.Total = responseData.Quota.Total ?? 0;
Quota.Relative = responseData.Quota.Relative ?? 0.0F;
Quota.Quota = responseData.Quota.Quota ?? 0;
}
if (responseData.BackendCapabilities != null)
{
BackendCapabilities.SetDisplayName = Convert.ToBoolean(responseData.BackendCapabilities.SetDisplayName);
BackendCapabilities.SetPassword = Convert.ToBoolean(responseData.BackendCapabilities.SetPassword);
}
} }
} }
} }

View File

@@ -1,37 +1,29 @@
using Newtonsoft.Json; namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Model public class UserQuota
{ {
public class UserQuota /// <summary>
{ /// Amount of free bytes left.
/// <summary> /// </summary>
/// Amount of free bytes left. public long Free { get; set; }
/// </summary>
public long Free { get; set; }
/// <summary> /// <summary>
/// Amount of already used bytes. /// Amount of already used bytes.
/// </summary> /// </summary>
public long Used { get; set; } public long Used { get; set; }
/// <summary> /// <summary>
/// Total amount of all bytes (free + used). /// Total amount of all bytes (free + used).
/// </summary> /// </summary>
public long Total { get; set; } public long Total { get; set; }
/// <summary> /// <summary>
/// Relative amount of used quota in percent. /// Relative amount of used quota in percent.
/// </summary> /// </summary>
public float Relative { get; set; } public float Relative { get; set; }
/// <summary> /// <summary>
/// Total amount of bytes available. /// Total amount of bytes available.
/// </summary> /// </summary>
public long Quota { get; set; } public long Quota { get; set; }
}
} }

View File

@@ -1,91 +1,85 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses; using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Ocs namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Ocs;
public class OcsResponseDataUser : OcsResponseData
{ {
public class OcsResponseDataUser : OcsResponseData public class ResponseQuota
{ {
public class ResponseQuota [JsonProperty("free")]
{ public long? Free { get; set; }
[JsonProperty("free")]
public long? Free { get; set; }
[JsonProperty("used")] [JsonProperty("used")]
public long? Used { get; set; } public long? Used { get; set; }
[JsonProperty("total")] [JsonProperty("total")]
public long? Total { get; set; } public long? Total { get; set; }
[JsonProperty("relative")] [JsonProperty("relative")]
public float? Relative { get; set; } public float? Relative { get; set; }
[JsonProperty("quota")]
public long? Quota { get; set; }
}
public class ResponseBackendCapabilities
{
[JsonProperty("setDisplayName")]
public bool? SetDisplayName { get; set; }
[JsonProperty("setPassword")]
public bool? SetPassword { get; set; }
}
[JsonProperty("enabled")]
public bool? Enabled { get; set; }
[JsonProperty("storageLocation")]
public string? StorageLocation { get; set; }
[JsonProperty("id")]
public string? ID { get; set; }
[JsonProperty("lastLogin")]
public long? LastLogin { get; set; }
[JsonProperty("backend")]
public string? Backend { get; set; }
[JsonProperty("quota")] [JsonProperty("quota")]
public ResponseQuota? Quota { get; set; } public long? Quota { get; set; }
[JsonProperty("email")]
public string? Email { get; set; }
[JsonProperty("displayname")]
public string? Displayname { get; set; }
[JsonProperty("display-name")]
public string? Displayname2 { get; set; }
[JsonProperty("phone")]
public string? Phone { get; set; }
[JsonProperty("address")]
public string? Address { get; set; }
[JsonProperty("website")]
public string? Website { get; set; }
[JsonProperty("twitter")]
public string? Twitter { get; set; }
[JsonProperty("groups")]
public string[]? Groups { get; set; }
[JsonProperty("language")]
public string? Language { get; set; }
[JsonProperty("locale")]
public string? Locale { get; set; }
[JsonProperty("backendCapabilities")]
public ResponseBackendCapabilities? BackendCapabilities { get; set; }
} }
public class ResponseBackendCapabilities
{
[JsonProperty("setDisplayName")]
public bool? SetDisplayName { get; set; }
[JsonProperty("setPassword")]
public bool? SetPassword { get; set; }
}
[JsonProperty("enabled")]
public bool? Enabled { get; set; }
[JsonProperty("storageLocation")]
public string? StorageLocation { get; set; }
[JsonProperty("id")]
public string? ID { get; set; }
[JsonProperty("lastLogin")]
public long? LastLogin { get; set; }
[JsonProperty("backend")]
public string? Backend { get; set; }
[JsonProperty("quota")]
public ResponseQuota? Quota { get; set; }
[JsonProperty("email")]
public string? Email { get; set; }
[JsonProperty("displayname")]
public string? Displayname { get; set; }
[JsonProperty("display-name")]
public string? Displayname2 { get; set; }
[JsonProperty("phone")]
public string? Phone { get; set; }
[JsonProperty("address")]
public string? Address { get; set; }
[JsonProperty("website")]
public string? Website { get; set; }
[JsonProperty("twitter")]
public string? Twitter { get; set; }
[JsonProperty("groups")]
public string[]? Groups { get; set; }
[JsonProperty("language")]
public string? Language { get; set; }
[JsonProperty("locale")]
public string? Locale { get; set; }
[JsonProperty("backendCapabilities")]
public ResponseBackendCapabilities? BackendCapabilities { get; set; }
} }

View File

@@ -1,14 +1,7 @@
using Newtonsoft.Json; using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Ocs namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Ocs;
public class OcsResponseUser : OcsResponse<OcsResponseDataUser>
{ {
public class OcsResponseUser : OcsResponse<OcsResponseDataUser>
{
}
} }

View File

@@ -1,24 +1,18 @@
using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Ocs; using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Ocs;
using Pilz.Networking.CloudProviders.Nextcloud.Ocs; using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud;
public class OcsApiCloud : OcsApiBase
{ {
public class OcsApiCloud : OcsApiBase public readonly static OcsApiUrlPath OCS_CLOUD_USER_METADATA = new("/ocs/v1.php/cloud/users/{0}");
public OcsApiCloud(OcsApi manager) : base(manager)
{ {
public readonly static OcsApiUrlPath OCS_CLOUD_USER_METADATA = new("/ocs/v1.php/cloud/users/{0}"); }
public OcsApiCloud(OcsApi manager) : base(manager) public OcsResponseUser? GetUserMeta(string username)
{ {
} return Manager.MakeRequestOcs<OcsResponseUser>(HttpMethod.Get, OCS_CLOUD_USER_METADATA.FillParameters(username));
public OcsResponseUser? GetUserMeta(string username)
{
return Manager.MakeRequestOcs<OcsResponseUser>(HttpMethod.Get, OCS_CLOUD_USER_METADATA.FillParameters(username));
}
} }
} }

View File

@@ -1,24 +1,34 @@
using System;
using System.Collections.Generic; /* Nicht gemergte Änderung aus Projekt "Pilz.Networking.CloudProviders.Nextcloud (net6.0)"
using System.Linq; Vor:
using System.Text; using System;
Nach:
using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
using System;
*/
using
/* Nicht gemergte Änderung aus Projekt "Pilz.Networking.CloudProviders.Nextcloud (net6.0)"
Vor:
using System.Threading.Tasks; using System.Threading.Tasks;
using Pilz.Networking.CloudProviders.Nextcloud.Ocs; using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
Nach:
using System.Threading.Tasks;
*/
Pilz.Networking.CloudProviders.Nextcloud.Ocs;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Core namespace Pilz.Networking.CloudProviders.Nextcloud.Client.Core;
public class OcsApiCore : OcsApiBase
{ {
public class OcsApiCore : OcsApiBase public static readonly OcsApiUrlPath OCS_CORE_APPPASSWORD = "/ocs/v2.php/core/apppassword";
public OcsApiCore(OcsApi manager) : base(manager)
{ {
public static readonly OcsApiUrlPath OCS_CORE_APPPASSWORD = "/ocs/v2.php/core/apppassword"; }
public OcsApiCore(OcsApi manager) : base(manager) public bool DeleteAppPassword()
{ {
} using var msg = Manager.MakeRequest(HttpMethod.Delete, OCS_CORE_APPPASSWORD);
return msg != null && msg.IsSuccessStatusCode;
public bool DeleteAppPassword()
{
using var msg = Manager.MakeRequest(HttpMethod.Delete, OCS_CORE_APPPASSWORD);
return msg != null && msg.IsSuccessStatusCode;
}
} }
} }

View File

@@ -1,40 +1,34 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2.Ocs namespace Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2.Ocs;
public class OcsResponseLoginFlowV2
{ {
public class OcsResponseLoginFlowV2 public class PollData
{ {
public class PollData /// <summary>
{ /// The login token that has been created for the login process.
/// <summary> /// It can be used to poll the login state.
/// The login token that has been created for the login process. /// </summary>
/// It can be used to poll the login state. [JsonProperty("token")]
/// </summary> public string? Token { get; set; }
[JsonProperty("token")]
public string? Token { get; set; }
/// <summary>
///
/// </summary>
[JsonProperty("endpoint")]
public string? Endpoint { get; set; }
}
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
[JsonProperty("poll")] [JsonProperty("endpoint")]
public PollData? Poll { get; set; } public string? Endpoint { get; set; }
/// <summary>
/// The temporary login url that should be used for login.
/// </summary>
[JsonProperty("login")]
public string? LoginUrl { get; set; }
} }
/// <summary>
///
/// </summary>
[JsonProperty("poll")]
public PollData? Poll { get; set; }
/// <summary>
/// The temporary login url that should be used for login.
/// </summary>
[JsonProperty("login")]
public string? LoginUrl { get; set; }
} }

View File

@@ -1,30 +1,24 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2.Ocs namespace Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2.Ocs;
public class OcsResponseLoginFlowV2Credentials
{ {
public class OcsResponseLoginFlowV2Credentials /// <summary>
{ /// The server url the login credentials are for.
/// <summary> /// </summary>
/// The server url the login credentials are for. [JsonProperty("server")]
/// </summary> public string? Server { get; set; }
[JsonProperty("server")]
public string? Server { get; set; }
/// <summary> /// <summary>
/// The login name (username or password) used for the login. /// The login name (username or password) used for the login.
/// </summary> /// </summary>
[JsonProperty("loginName")] [JsonProperty("loginName")]
public string? LoginName { get; set; } public string? LoginName { get; set; }
/// <summary> /// <summary>
/// The app password that has been generated. /// The app password that has been generated.
/// </summary> /// </summary>
[JsonProperty("appPassword")] [JsonProperty("appPassword")]
public string? AppPassword { get; set; } public string? AppPassword { get; set; }
}
} }

View File

@@ -1,36 +1,30 @@
using Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2.Ocs; using Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2.Ocs;
using Pilz.Networking.CloudProviders.Nextcloud.Ocs; using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2 namespace Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2;
public class OcsApiLoginFlowV2 : OcsApiBase
{ {
public class OcsApiLoginFlowV2 : OcsApiBase private const string OCS_LOGIN_INIT = "/index.php/login/v2";
public OcsApiLoginFlowV2(OcsApi manager) : base(manager)
{ {
private const string OCS_LOGIN_INIT = "/index.php/login/v2"; }
public OcsApiLoginFlowV2(OcsApi manager) : base(manager) public OcsResponseLoginFlowV2? Init(string url)
{ {
} return Manager.MakeRequest<OcsResponseLoginFlowV2>(HttpMethod.Post, url + OCS_LOGIN_INIT);
}
public OcsResponseLoginFlowV2? Init(string url) public OcsResponseLoginFlowV2Credentials? Poll(OcsResponseLoginFlowV2.PollData poll)
{ {
return Manager.MakeRequest<OcsResponseLoginFlowV2>(HttpMethod.Post, url + OCS_LOGIN_INIT); ArgumentNullException.ThrowIfNull(poll?.Endpoint);
} ArgumentNullException.ThrowIfNull(poll?.Token);
public OcsResponseLoginFlowV2Credentials? Poll(OcsResponseLoginFlowV2.PollData poll) return Manager.MakeRequest<OcsResponseLoginFlowV2Credentials?>(HttpMethod.Post, poll.Endpoint,
{ parameters: new Dictionary<string, string>
ArgumentNullException.ThrowIfNull(poll?.Endpoint); {
ArgumentNullException.ThrowIfNull(poll?.Token); { "token", poll.Token }
});
return Manager.MakeRequest<OcsResponseLoginFlowV2Credentials?>(HttpMethod.Post, poll.Endpoint,
parameters: new Dictionary<string, string>
{
{ "token", poll.Token }
});
}
} }
} }

View File

@@ -1,46 +1,41 @@
using Pilz.Networking.CloudProviders.Nextcloud.Ocs; using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud namespace Pilz.Networking.CloudProviders.Nextcloud;
public static class Extensions
{ {
public static class Extensions public static string ToBasicAuth(this OcsApiAuthCredentials? credentials)
{ {
public static string ToBasicAuth(this OcsApiAuthCredentials? credentials) if (credentials != null)
{ {
if (credentials != null) var creds = $"{credentials?.LoginName}:{credentials?.AppPassword}";
{ var bytes = Encoding.UTF8.GetBytes(creds);
var creds = $"{credentials?.LoginName}:{credentials?.AppPassword}"; return "Basic " + Convert.ToBase64String(bytes);
var bytes = Encoding.UTF8.GetBytes(creds);
return "Basic " + Convert.ToBase64String(bytes);
}
return string.Empty;
} }
public static OcsApiAuthCredentials? ToOcsApiAuthCredentials(this NextcloudLogin? login) return string.Empty;
{ }
if (!string.IsNullOrEmpty(login?.LoginName) && !string.IsNullOrEmpty(login?.AppPassword))
return new OcsApiAuthCredentials(login.LoginName, login.AppPassword);
return null;
}
public static OcsApiUrlPath FillParameters(this OcsApiUrlPath path, params object?[] @params) public static OcsApiAuthCredentials? ToOcsApiAuthCredentials(this NextcloudLogin? login)
{ {
return (OcsApiUrlPath)string.Format(path, @params); if (!string.IsNullOrEmpty(login?.LoginName) && !string.IsNullOrEmpty(login?.AppPassword))
} return new OcsApiAuthCredentials(login.LoginName, login.AppPassword);
return null;
}
public static DateTime UnixTimeMillisecondsToDateTime(this long? value) public static OcsApiUrlPath FillParameters(this OcsApiUrlPath path, params object?[] @params)
{ {
return DateTimeOffset.FromUnixTimeMilliseconds(value ?? 0).DateTime; return (OcsApiUrlPath)string.Format(path, @params);
} }
public static long ToUnixTimeMilliseconds(this DateTime value) public static DateTime UnixTimeMillisecondsToDateTime(this long? value)
{ {
return new DateTimeOffset(value).ToUnixTimeMilliseconds(); return DateTimeOffset.FromUnixTimeMilliseconds(value ?? 0).DateTime;
} }
public static long ToUnixTimeMilliseconds(this DateTime value)
{
return new DateTimeOffset(value).ToUnixTimeMilliseconds();
} }
} }

View File

@@ -1,4 +1,14 @@
using System; using Pilz.Networking.CloudProviders.Nextcloud.Client;
using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud;
using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Model;
using Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2.Ocs;
/* Nicht gemergte Änderung aus Projekt "Pilz.Networking.CloudProviders.Nextcloud (net6.0)"
Vor:
using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
Nach:
using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics; using System.Diagnostics;
@@ -6,150 +16,147 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Pilz.Networking.CloudProviders.Nextcloud.Client; */
using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud;
using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud.Model;
using Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2.Ocs;
using Pilz.Networking.CloudProviders.Nextcloud.Ocs; using Pilz.Networking.CloudProviders.Nextcloud.Ocs;
using System.Diagnostics;
namespace Pilz.Networking.CloudProviders.Nextcloud namespace Pilz.Networking.CloudProviders.Nextcloud;
public class NextcloudClient : IDisposable
{ {
public class NextcloudClient : IDisposable private readonly List<ClientBase> clients = new();
private NextcloudLogin? currentLogin;
public OcsApi Ocs { get; init; } = new();
public NextcloudLogin? CurrentLogin
{ {
private readonly List<ClientBase> clients = new(); get => currentLogin;
private NextcloudLogin? currentLogin; private set
public OcsApi Ocs { get; init; } = new();
public NextcloudLogin? CurrentLogin
{ {
get => currentLogin; currentLogin = value;
private set Ocs.BaseUrl = value?.Server ?? string.Empty;
{
currentLogin = value;
Ocs.BaseUrl = value?.Server ?? string.Empty;
}
}
public CloudClient Cloud => GetClient<CloudClient>();
public NextcloudClient()
{
Ocs.GetOcsApiAuthCredentails += Ocs_GetOcsApiAuthCredentails;
}
private void Ocs_GetOcsApiAuthCredentails(object sender, GetOcsApiAuthCredentailsEventArgs eventArgs)
{
if (sender == Ocs)
eventArgs.Credentials = CurrentLogin.ToOcsApiAuthCredentials();
}
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 UserInfo? Login(NextcloudLogin login)
{
return Login(login, true);
}
public UserInfo? Login(NextcloudLogin login, bool checkUser)
{
// Ensure we are logged out
Logout(false);
// Temporary set user login
CurrentLogin = login;
if (checkUser)
{
// Try get user info & check if user is enabled
var userInfo = Cloud.GetUserInfo();
var isValid = userInfo != null /*&& userInfo.Enabled*/; // Enabled is false for some (new) users but they still are able to login??
// If invalid, reset login credentials
if (!isValid)
CurrentLogin = null;
return userInfo;
}
return null;
}
public NextcloudLogin? Login(string baseUrl, CancellationToken cancellationToken)
{
// Ensure we are logged out
Logout(false);
// Init the login process
var initResponse = Ocs.LoginFlowV2.Init(baseUrl);
if (!string.IsNullOrEmpty(initResponse?.LoginUrl) && initResponse.Poll != null)
{
// Open the browser
Process.Start(new ProcessStartInfo
{
FileName = initResponse.LoginUrl,
UseShellExecute = true
});
// Poll for credentails in intervals
OcsResponseLoginFlowV2Credentials? pollResponse = null;
while (!cancellationToken.IsCancellationRequested && pollResponse is null)
{
// Wait 5 seconds
Thread.Sleep(5000);
// Poll the credentials
if (!cancellationToken.IsCancellationRequested)
pollResponse = Ocs.LoginFlowV2.Poll(initResponse.Poll);
}
// Check login credentials
if (pollResponse is not null)
CurrentLogin = new(pollResponse);
}
return CurrentLogin;
}
public void Logout()
{
Logout(false);
}
public void Logout(bool logoutOnServer)
{
if (CurrentLogin != null)
{
// Delete currently used app password
if (logoutOnServer)
Ocs.Core.DeleteAppPassword();
// Reset current login infos
CurrentLogin = null;
}
}
public void Dispose()
{
Ocs.Dispose();
GC.SuppressFinalize(this);
} }
} }
public CloudClient Cloud => GetClient<CloudClient>();
public NextcloudClient()
{
Ocs.GetOcsApiAuthCredentails += Ocs_GetOcsApiAuthCredentails;
}
private void Ocs_GetOcsApiAuthCredentails(object sender, GetOcsApiAuthCredentailsEventArgs eventArgs)
{
if (sender == Ocs)
eventArgs.Credentials = CurrentLogin.ToOcsApiAuthCredentials();
}
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 UserInfo? Login(NextcloudLogin login)
{
return Login(login, true);
}
public UserInfo? Login(NextcloudLogin login, bool checkUser)
{
// Ensure we are logged out
Logout(false);
// Temporary set user login
CurrentLogin = login;
if (checkUser)
{
// Try get user info & check if user is enabled
var userInfo = Cloud.GetUserInfo();
var isValid = userInfo != null /*&& userInfo.Enabled*/; // Enabled is false for some (new) users but they still are able to login??
// If invalid, reset login credentials
if (!isValid)
CurrentLogin = null;
return userInfo;
}
return null;
}
public NextcloudLogin? Login(string baseUrl, CancellationToken cancellationToken)
{
// Ensure we are logged out
Logout(false);
// Init the login process
var initResponse = Ocs.LoginFlowV2.Init(baseUrl);
if (!string.IsNullOrEmpty(initResponse?.LoginUrl) && initResponse.Poll != null)
{
// Open the browser
Process.Start(new ProcessStartInfo
{
FileName = initResponse.LoginUrl,
UseShellExecute = true
});
// Poll for credentails in intervals
OcsResponseLoginFlowV2Credentials? pollResponse = null;
while (!cancellationToken.IsCancellationRequested && pollResponse is null)
{
// Wait 5 seconds
Thread.Sleep(5000);
// Poll the credentials
if (!cancellationToken.IsCancellationRequested)
pollResponse = Ocs.LoginFlowV2.Poll(initResponse.Poll);
}
// Check login credentials
if (pollResponse is not null)
CurrentLogin = new(pollResponse);
}
return CurrentLogin;
}
public void Logout()
{
Logout(false);
}
public void Logout(bool logoutOnServer)
{
if (CurrentLogin != null)
{
// Delete currently used app password
if (logoutOnServer)
Ocs.Core.DeleteAppPassword();
// Reset current login infos
CurrentLogin = null;
}
}
public void Dispose()
{
Ocs.Dispose();
GC.SuppressFinalize(this);
}
} }

View File

@@ -1,39 +1,32 @@
using Newtonsoft.Json; using Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2.Ocs;
using Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2.Ocs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud namespace Pilz.Networking.CloudProviders.Nextcloud;
public class NextcloudLogin
{ {
public class NextcloudLogin /// <summary>
/// The server url the login credentials are for.
/// </summary>
public string? Server { get; set; }
/// <summary>
/// The login name (username or password) used for the login.
/// </summary>
public string? LoginName { get; set; }
/// <summary>
/// The app password that has been generated.
/// </summary>
public string? AppPassword { get; set; }
public NextcloudLogin()
{ {
/// <summary> }
/// The server url the login credentials are for.
/// </summary>
public string? Server { get; set; }
/// <summary> public NextcloudLogin(OcsResponseLoginFlowV2Credentials response)
/// The login name (username or password) used for the login. {
/// </summary> Server = response.Server;
public string? LoginName { get; set; } LoginName = response.LoginName;
AppPassword = response.AppPassword;
/// <summary>
/// The app password that has been generated.
/// </summary>
public string? AppPassword { get; set; }
public NextcloudLogin()
{
}
public NextcloudLogin(OcsResponseLoginFlowV2Credentials response)
{
Server = response.Server;
LoginName = response.LoginName;
AppPassword = response.AppPassword;
}
} }
} }

View File

@@ -1,15 +1,8 @@
using System; namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs public delegate void GetOcsApiAuthCredentailsEventHandler(object sender, GetOcsApiAuthCredentailsEventArgs eventArgs);
public class GetOcsApiAuthCredentailsEventArgs : EventArgs
{ {
public delegate void GetOcsApiAuthCredentailsEventHandler(object sender, GetOcsApiAuthCredentailsEventArgs eventArgs); public OcsApiAuthCredentials? Credentials { get; set; }
public class GetOcsApiAuthCredentailsEventArgs : EventArgs
{
public OcsApiAuthCredentials? Credentials { get; set; }
}
} }

View File

@@ -1,218 +1,226 @@
using System; /* Nicht gemergte Änderung aus Projekt "Pilz.Networking.CloudProviders.Nextcloud (net6.0)"
Vor:
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using Newtonsoft.Json; using Newtonsoft.Json;
using System.Diagnostics; Nach:
using System.Net; using Newtonsoft.Json;
using System.Net.Sockets;
using System.Xml.Linq;
using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud; using Pilz.Networking.CloudProviders.Nextcloud.Client.Cloud;
using Pilz.Networking.CloudProviders.Nextcloud.Client.Core; using Pilz.Networking.CloudProviders.Nextcloud.Client.Core;
using Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2; using Pilz.Networking.CloudProviders.Nextcloud.Client.LoginFlowV2;
using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses; using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
using System;
using System.Json;
*/
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs /* Nicht gemergte Änderung aus Projekt "Pilz.Networking.CloudProviders.Nextcloud (net6.0)"
Vor:
using
Nach:
using
*/
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;
private readonly HttpClient client = new();
private readonly List<OcsApiBase> apis = new();
public string BaseUrl { get; set; } = string.Empty;
public OcsApiLoginFlowV2 LoginFlowV2 => GetApi<OcsApiLoginFlowV2>();
public OcsApiCore Core => GetApi<OcsApiCore>();
public OcsApiCloud Cloud => GetApi<OcsApiCloud>();
public TApi GetApi<TApi>() where TApi : OcsApiBase
{ {
public const string CONTENT_TYPE_JSON = "application/json"; var instance = TryGetApi<TApi>();
return instance is null ? throw new NullReferenceException() : instance;
}
public event GetOcsApiAuthCredentailsEventHandler? GetOcsApiAuthCredentails; public TApi? TryGetApi<TApi>() where TApi : OcsApiBase
{
TApi? instance = (TApi?)apis.FirstOrDefault(n => n is TApi);
private readonly HttpClient client = new(); instance ??= (TApi?)Activator.CreateInstance(typeof(TApi), new object[] { this });
private readonly List<OcsApiBase> apis = new();
public string BaseUrl { get; set; } = string.Empty; if (instance is not null)
apis.Add(instance);
public OcsApiLoginFlowV2 LoginFlowV2 => GetApi<OcsApiLoginFlowV2>(); return instance;
public OcsApiCore Core => GetApi<OcsApiCore>(); }
public OcsApiCloud Cloud => GetApi<OcsApiCloud>();
public TApi GetApi<TApi>() where TApi : OcsApiBase public string BuildFullUrl(OcsApiUrlPath path)
{
return BaseUrl + path;
}
/// <summary>
/// Makes an request with the given arguments and deserialize it to the given type.
/// </summary>
/// <typeparam name="TResponse"></typeparam>
/// <param name="httpMethod"></param>
/// <param name="url"></param>
/// <param name="useAuthentication"></param>
/// <param name="parameters"></param>
/// <param name="content"></param>
/// <returns>Returns the given OcsResponse type from the deserialized OcsApiResponse content.</returns>
public TResponse? MakeRequestOcs<TResponse>(HttpMethod httpMethod, OcsApiUrlPath url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null) where TResponse : IOcsResponse
{
return MakeRequestOcs<TResponse>(httpMethod, BuildFullUrl(url), useAuthentication: useAuthentication, parameters: parameters, content: content);
}
/// <summary>
/// Makes an request with the given arguments and deserialize it to the given type.
/// </summary>
/// <typeparam name="TResponse"></typeparam>
/// <param name="httpMethod"></param>
/// <param name="url"></param>
/// <param name="useAuthentication"></param>
/// <param name="parameters"></param>
/// <param name="content"></param>
/// <returns>Returns the given OcsResponse type from the deserialized OcsApiResponse content.</returns>
public TResponse? MakeRequestOcs<TResponse>(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null) where TResponse : IOcsResponse
{
var response = MakeRequest<OcsApiResponse<TResponse>?>(httpMethod, url, useAuthentication: useAuthentication, parameters: parameters, content: content);
if (response != null)
return response.Ocs;
return default;
}
/// <summary>
/// Makes an request with the given arguments and deserialize it to the given type.
/// </summary>
/// <typeparam name="TResponse"></typeparam>
/// <param name="httpMethod"></param>
/// <param name="url"></param>
/// <param name="useAuthentication"></param>
/// <param name="parameters"></param>
/// <param name="content"></param>
/// <returns>Returns the deserialized content of type given type.</returns>
public TResponse? MakeRequest<TResponse>(HttpMethod httpMethod, OcsApiUrlPath url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null)
{
return MakeRequest<TResponse>(httpMethod, BuildFullUrl(url), useAuthentication: useAuthentication, parameters: parameters, content: content);
}
/// <summary>
/// Makes an request with the given arguments and deserialize it to the given type.
/// </summary>
/// <typeparam name="TResponse"></typeparam>
/// <param name="httpMethod"></param>
/// <param name="url"></param>
/// <param name="useAuthentication"></param>
/// <param name="parameters"></param>
/// <param name="content"></param>
/// <returns>Returns the deserialized content of type given type.</returns>
public TResponse? MakeRequest<TResponse>(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null)
{
using var responseInit = MakeRequest(httpMethod, url, useAuthentication: useAuthentication, parameters: parameters, content: content);
if (responseInit != null)
{ {
var instance = TryGetApi<TApi>(); try
return instance is null ? throw new NullReferenceException() : instance;
}
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)
{
return BaseUrl + path;
}
/// <summary>
/// Makes an request with the given arguments and deserialize it to the given type.
/// </summary>
/// <typeparam name="TResponse"></typeparam>
/// <param name="httpMethod"></param>
/// <param name="url"></param>
/// <param name="useAuthentication"></param>
/// <param name="parameters"></param>
/// <param name="content"></param>
/// <returns>Returns the given OcsResponse type from the deserialized OcsApiResponse content.</returns>
public TResponse? MakeRequestOcs<TResponse>(HttpMethod httpMethod, OcsApiUrlPath url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null) where TResponse : IOcsResponse
{
return MakeRequestOcs<TResponse>(httpMethod, BuildFullUrl(url), useAuthentication: useAuthentication, parameters: parameters, content: content);
}
/// <summary>
/// Makes an request with the given arguments and deserialize it to the given type.
/// </summary>
/// <typeparam name="TResponse"></typeparam>
/// <param name="httpMethod"></param>
/// <param name="url"></param>
/// <param name="useAuthentication"></param>
/// <param name="parameters"></param>
/// <param name="content"></param>
/// <returns>Returns the given OcsResponse type from the deserialized OcsApiResponse content.</returns>
public TResponse? MakeRequestOcs<TResponse>(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null) where TResponse : IOcsResponse
{
var response = MakeRequest<OcsApiResponse<TResponse>?>(httpMethod, url, useAuthentication: useAuthentication, parameters: parameters, content: content);
if (response != null)
return response.Ocs;
return default;
}
/// <summary>
/// Makes an request with the given arguments and deserialize it to the given type.
/// </summary>
/// <typeparam name="TResponse"></typeparam>
/// <param name="httpMethod"></param>
/// <param name="url"></param>
/// <param name="useAuthentication"></param>
/// <param name="parameters"></param>
/// <param name="content"></param>
/// <returns>Returns the deserialized content of type given type.</returns>
public TResponse? MakeRequest<TResponse>(HttpMethod httpMethod, OcsApiUrlPath url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null)
{
return MakeRequest<TResponse>(httpMethod, BuildFullUrl(url), useAuthentication: useAuthentication, parameters: parameters, content: content);
}
/// <summary>
/// Makes an request with the given arguments and deserialize it to the given type.
/// </summary>
/// <typeparam name="TResponse"></typeparam>
/// <param name="httpMethod"></param>
/// <param name="url"></param>
/// <param name="useAuthentication"></param>
/// <param name="parameters"></param>
/// <param name="content"></param>
/// <returns>Returns the deserialized content of type given type.</returns>
public TResponse? MakeRequest<TResponse>(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null)
{
using var responseInit = MakeRequest(httpMethod, url, useAuthentication: useAuthentication, parameters: parameters, content: content);
if (responseInit != null)
{ {
try var bodyInit = responseInit.Content.ReadAsStringAsync().Result;
{ return JsonConvert.DeserializeObject<TResponse>(bodyInit);
var bodyInit = responseInit.Content.ReadAsStringAsync().Result;
return JsonConvert.DeserializeObject<TResponse>(bodyInit);
}
catch(FormatException) { }
catch(JsonSerializationException) { }
} }
catch (FormatException) { }
return default; catch (JsonSerializationException) { }
} }
/// <summary> return default;
/// Makes an request with the given arguments. }
/// </summary>
/// <param name="httpMethod"></param> /// <summary>
/// <param name="url"></param> /// Makes an request with the given arguments.
/// <param name="useAuthentication"></param> /// </summary>
/// <param name="parameters"></param> /// <param name="httpMethod"></param>
/// <param name="content"></param> /// <param name="url"></param>
/// <returns>Returns a HttpResponseMessage as result.</returns> /// <param name="useAuthentication"></param>
public HttpResponseMessage MakeRequest(HttpMethod httpMethod, OcsApiUrlPath url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null) /// <param name="parameters"></param>
/// <param name="content"></param>
/// <returns>Returns a HttpResponseMessage as result.</returns>
public 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, content: content);
}
/// <summary>
/// Makes an request with the given arguments.
/// </summary>
/// <param name="httpMethod"></param>
/// <param name="url"></param>
/// <param name="useAuthentication"></param>
/// <param name="parameters"></param>
/// <param name="content"></param>
/// <returns>Returns a HttpResponseMessage as result.</returns>
public HttpResponseMessage MakeRequest(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null)
{
OcsApiAuthCredentials? authentication;
string @params;
HttpContent? httpContent;
// Get authentication
if (useAuthentication)
{ {
return MakeRequest(httpMethod, BuildFullUrl(url), useAuthentication: useAuthentication, parameters: parameters, content: content); var args = new GetOcsApiAuthCredentailsEventArgs();
GetOcsApiAuthCredentails?.Invoke(this, args);
authentication = args.Credentials;
} }
else
authentication = null;
/// <summary> // Parse params
/// Makes an request with the given arguments. if (parameters != null)
/// </summary> @params = "?" + string.Join("&", parameters.Select(p => $"{p.Key}={p.Value}"));
/// <param name="httpMethod"></param> else
/// <param name="url"></param> @params = string.Empty;
/// <param name="useAuthentication"></param>
/// <param name="parameters"></param> // Create content
/// <param name="content"></param> if (content is HttpContent contentHttp)
/// <returns>Returns a HttpResponseMessage as result.</returns> httpContent = contentHttp;
public HttpResponseMessage MakeRequest(HttpMethod httpMethod, string url, bool useAuthentication = true, Dictionary<string, string>? parameters = null, object? content = null) else if (content is OcsData || content is not null)
{ {
OcsApiAuthCredentials? authentication; var stringContent = JsonConvert.SerializeObject(content);
string @params; httpContent = new StringContent(stringContent, null, CONTENT_TYPE_JSON);
HttpContent? httpContent;
// Get authentication
if (useAuthentication)
{
var args = new GetOcsApiAuthCredentailsEventArgs();
GetOcsApiAuthCredentails?.Invoke(this, args);
authentication = args.Credentials;
}
else
authentication = null;
// Parse params
if (parameters != null)
@params = "?" + string.Join("&", parameters.Select(p => $"{p.Key}={p.Value}"));
else
@params = string.Empty;
// Create content
if (content is HttpContent contentHttp)
httpContent = contentHttp;
else if (content is OcsData || content is not null)
{
var stringContent = JsonConvert.SerializeObject(content);
httpContent = new StringContent(stringContent, null, CONTENT_TYPE_JSON);
}
else
httpContent = null;
// Send request
var request = new HttpRequestMessage
{
Method = httpMethod ?? HttpMethod.Post,
RequestUri = new Uri(url + @params),
Headers =
{
{ "Accept", CONTENT_TYPE_JSON },
{ "OCS-APIREQUEST", "true" },
//{ "Authorization", authentication.ToBasicAuth() }
},
Content = httpContent
};
// Add authorization
if (authentication != null)
request.Headers.Add("Authorization", authentication.ToBasicAuth());
return client.Send(request);
} }
else
httpContent = null;
public void Dispose() // Send request
var request = new HttpRequestMessage
{ {
client.Dispose(); Method = httpMethod ?? HttpMethod.Post,
GC.SuppressFinalize(this); RequestUri = new Uri(url + @params),
} Headers =
{
{ "Accept", CONTENT_TYPE_JSON },
{ "OCS-APIREQUEST", "true" },
//{ "Authorization", authentication.ToBasicAuth() }
},
Content = httpContent
};
// Add authorization
if (authentication != null)
request.Headers.Add("Authorization", authentication.ToBasicAuth());
return client.Send(request);
}
public void Dispose()
{
client.Dispose();
GC.SuppressFinalize(this);
} }
} }

View File

@@ -1,21 +1,13 @@
using System; namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs public struct OcsApiAuthCredentials
{ {
public struct OcsApiAuthCredentials public string LoginName { get; set; }
{ public string AppPassword { get; set; }
public string LoginName { get; set; }
public string AppPassword { get; set; }
public OcsApiAuthCredentials(string loginName, string appPassword) public OcsApiAuthCredentials(string loginName, string appPassword)
{ {
LoginName = loginName; LoginName = loginName;
AppPassword = appPassword; AppPassword = appPassword;
}
} }
} }

View File

@@ -1,18 +1,11 @@
using System; namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs public abstract class OcsApiBase
{ {
public abstract class OcsApiBase protected OcsApi Manager { get; init; }
{
protected OcsApi Manager { get; init; }
protected OcsApiBase(OcsApi manager) protected OcsApiBase(OcsApi manager)
{ {
Manager = manager; Manager = manager;
}
} }
} }

View File

@@ -1,17 +1,10 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses; using Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs;
public class OcsApiResponse<TOcsResponse> where TOcsResponse : IOcsResponse
{ {
public class OcsApiResponse<TOcsResponse> where TOcsResponse : IOcsResponse [JsonProperty("ocs")]
{ public TOcsResponse? Ocs { get; set; }
[JsonProperty("ocs")]
public TOcsResponse? Ocs { get; set; }
}
} }

View File

@@ -1,31 +1,24 @@
using System; namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs public readonly struct OcsApiUrlPath
{ {
public readonly struct OcsApiUrlPath private readonly string path;
public OcsApiUrlPath()
{ {
private readonly string path; path = string.Empty;
}
public OcsApiUrlPath() public OcsApiUrlPath(string path)
{ {
path = string.Empty; this.path = path;
} }
public OcsApiUrlPath(string path) public static implicit operator string(OcsApiUrlPath o) => o.path;
{ public static implicit operator OcsApiUrlPath(string o) => new(o);
this.path = path;
}
public static implicit operator string(OcsApiUrlPath o) => o.path; public override readonly string ToString()
public static implicit operator OcsApiUrlPath(string o) => new(o); {
return path;
public override readonly string ToString()
{
return path;
}
} }
} }

View File

@@ -1,12 +1,5 @@
using System; namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs public class OcsData
{ {
public class OcsData
{
}
} }

View File

@@ -1,12 +1,5 @@
using System; namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses public interface IOcsResponse
{ {
public interface IOcsResponse
{
}
} }

View File

@@ -1,12 +1,5 @@
using System; namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses public interface IOcsResponseData
{ {
public interface IOcsResponseData
{
}
} }

View File

@@ -1,12 +1,5 @@
using System; namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses public interface IOcsResponseMeta
{ {
public interface IOcsResponseMeta
{
}
} }

View File

@@ -1,26 +1,20 @@
using Newtonsoft.Json; 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 namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
public class OcsResponse<TMeta, TData> : IOcsResponse where TMeta : IOcsResponseMeta where TData : IOcsResponseData
{ {
public class OcsResponse<TMeta, TData> : IOcsResponse where TMeta : IOcsResponseMeta where TData : IOcsResponseData [JsonProperty("meta")]
{ public TMeta? Meta { get; set; }
[JsonProperty("meta")]
public TMeta? Meta { get; set; }
[JsonProperty("data")] [JsonProperty("data")]
public TData? Data { get; set; } public TData? Data { get; set; }
} }
public class OcsResponse<TData> : OcsResponse<OcsResponseMeta, TData> where TData : IOcsResponseData public class OcsResponse<TData> : OcsResponse<OcsResponseMeta, TData> where TData : IOcsResponseData
{ {
} }
public class OcsResponse : OcsResponse<OcsResponseMeta, OcsResponseData> public class OcsResponse : OcsResponse<OcsResponseMeta, OcsResponseData>
{ {
}
} }

View File

@@ -1,12 +1,5 @@
using System; namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses public class OcsResponseData : IOcsResponseData
{ {
public class OcsResponseData : IOcsResponseData
{
}
} }

View File

@@ -1,12 +1,5 @@
using System; namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
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
{ {
public class OcsResponseDataArray<TEntry> : List<TEntry>, IOcsResponseData where TEntry : OcsResponseDataEntry
{
}
} }

View File

@@ -1,12 +1,5 @@
using System; namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses public class OcsResponseDataEntry
{ {
public class OcsResponseDataEntry
{
}
} }

View File

@@ -1,21 +1,15 @@
using Newtonsoft.Json; 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 namespace Pilz.Networking.CloudProviders.Nextcloud.Ocs.Responses;
public class OcsResponseMeta : IOcsResponseMeta
{ {
public class OcsResponseMeta : IOcsResponseMeta [JsonProperty("status")]
{ public string? Status { get; set; }
[JsonProperty("status")]
public string? Status { get; set; }
[JsonProperty("statuscode")] [JsonProperty("statuscode")]
public int? StatusCode { get; set; } public int? StatusCode { get; set; }
[JsonProperty("message")] [JsonProperty("message")]
public string? Message { get; set; } public string? Message { get; set; }
}
} }

View File

@@ -1,5 +1,6 @@
Imports System.IO Imports System.IO
Imports System.Net Imports System.Net
Imports Newtonsoft.Json.Linq Imports Newtonsoft.Json.Linq
Public MustInherit Class ConnectionManagerBase Public MustInherit Class ConnectionManagerBase

View File

@@ -1,8 +1,14 @@
Imports System.IO Imports System.Net
Imports System.Net
Imports System.Net.NetworkInformation ' Nicht gemergte Änderung aus Projekt "Pilz.Networking (net8.0-windows)"
' Vor:
' Imports System.Net.Sockets
' Imports Newtonsoft.Json.Linq
' Nach:
' Imports System.Net.Sockets
'
' Imports Newtonsoft.Json.Linq
Imports System.Net.Sockets Imports System.Net.Sockets
Imports Newtonsoft.Json.Linq
Public Class TCPManager Public Class TCPManager
Inherits ConnectionManagerBase Inherits ConnectionManagerBase

View File

@@ -1,9 +1,15 @@
Imports System.IO Imports System.Net
Imports System.Net
Imports System.Net.NetworkInformation
Imports System.Net.Sockets Imports System.Net.Sockets
' Nicht gemergte Änderung aus Projekt "Pilz.Networking (net8.0-windows)"
' Vor:
' Imports System.Threading
' Imports Newtonsoft.Json.Linq
' Nach:
' Imports System.Threading
'
' Imports Newtonsoft.Json.Linq
Imports System.Threading Imports System.Threading
Imports Newtonsoft.Json.Linq
Public Class UDPManager Public Class UDPManager
Inherits ConnectionManagerBase Inherits ConnectionManagerBase

View File

@@ -1,125 +1,121 @@
using System.Drawing; using Telerik.WinControls;
using System.Reflection;
using Telerik.WinControls;
using Telerik.WinControls.Elements;
using Telerik.WinControls.UI; using Telerik.WinControls.UI;
namespace Pilz.Plugins.Advanced.UI.Telerik namespace Pilz.Plugins.Advanced.UI.Telerik;
public static class Extensions
{ {
public static class Extensions public static Icon? ToIcon(this Image image)
{ {
public static Icon? ToIcon(this Image image) if (image is Bitmap bitmap)
{ return Icon.FromHandle(bitmap.GetHicon());
if (image is Bitmap bitmap) return null;
return Icon.FromHandle(bitmap.GetHicon()); }
return null;
}
public static RadMenuItem GetAsItem(this PluginModuleBase module) public static RadMenuItem GetAsItem(this PluginModuleBase module)
{ {
return GetAsItem(module, true); return GetAsItem(module, true);
} }
public static RadMenuItem GetAsItem(this PluginModuleBase module, bool addDefaultHandler) public static RadMenuItem GetAsItem(this PluginModuleBase module, bool addDefaultHandler)
{ {
return GetAsItem(module, addDefaultHandler ? RadMenuItem_RMMethod_Click : null); return GetAsItem(module, addDefaultHandler ? RadMenuItem_RMMethod_Click : null);
} }
public static RadMenuItem GetAsItem(this PluginFunction function) public static RadMenuItem GetAsItem(this PluginFunction function)
{ {
return GetAsItem(function, true); return GetAsItem(function, true);
} }
public static RadMenuItem GetAsItem(this PluginFunction function, bool addDefaultHandler) public static RadMenuItem GetAsItem(this PluginFunction function, bool addDefaultHandler)
{ {
return GetAsItem(function, addDefaultHandler ? RadMenuItem_RMFunction_Click : null); return GetAsItem(function, addDefaultHandler ? RadMenuItem_RMFunction_Click : null);
} }
public static RadMenuItem GetAsItem(this PluginFeature module, EventHandler? clickHandler) public static RadMenuItem GetAsItem(this PluginFeature module, EventHandler? clickHandler)
{
var item = new RadMenuItem
{ {
var item = new RadMenuItem Text = module.Name,
Image = module.Icon as Image,
SvgImage = module.Icon as RadSvgImage,
Tag = module,
Visibility = module.Enabled ? ElementVisibility.Visible : ElementVisibility.Collapsed
};
if (clickHandler is not null)
item.Click += clickHandler;
return item;
}
/// <summary>
/// Inserts all items to an item collection.
/// </summary>
/// <param name="features"></param>
/// <param name="itemsCollection">Examples:<br/>
/// - <see cref="RadMenuItem.Items"/><br/>
/// - <see cref="RadSplitButtonElement.Items"/><br/>
/// - <see cref="RadDropDownButtonElement.Items"/><br/>
/// - <see cref="RadContextMenu.Items"/><br/>
/// - <see cref="RadRibbonBarGroup.Items"/><br/></param>
/// <param name="addDefaultHandler">Will add a default click handler that executes the feature.<br/>
/// You usually don't set customClickHandler if you set this parameter to <see cref="true"/>.</param>
/// <param name="customClickHandler">Adds a custom click handler. If addDefaultHandler is true, it will only work on <see cref="PluginFeature"/>s.<br/>
/// You usually don't set addDefaultHandler to true if you set this parameter to something not null.</param>
public static void InsertItemsTo(this IEnumerable<PluginFeature> features, RadItemOwnerCollection itemsCollection, bool addDefaultHandler = false, EventHandler? customClickHandler = null, FeatureInsertMode insertMode = FeatureInsertMode.Default, int? customDefault = null, int? customTop = null, int? customBottom = null, FeatureInsertPosition insertSplitter = FeatureInsertPosition.None)
{
var insertDefault = customDefault ?? (insertMode.HasFlag(FeatureInsertMode.DefaultStart) ? 0 : itemsCollection.Count);
var insertTop = customTop ?? (insertMode.HasFlag(FeatureInsertMode.InsertTop) || insertMode.HasFlag(FeatureInsertMode.DefaultStart) ? 0 : insertDefault);
var insertBottom = customBottom ?? (insertMode.HasFlag(FeatureInsertMode.InsertBottom) || insertMode.HasFlag(FeatureInsertMode.DefaultEnd) ? itemsCollection.Count : insertDefault);
foreach (var feature in features)
{
RadMenuItem item;
if (feature is PluginFunction function)
item = function.GetAsItem(addDefaultHandler);
else if (feature is PluginModuleBase module)
item = module.GetAsItem(addDefaultHandler);
else
item = feature.GetAsItem(null);
if (!addDefaultHandler && customClickHandler != null)
item.Click += customClickHandler;
switch (feature.Prioritization)
{ {
Text = module.Name, case FeaturePrioritization.High:
Image = module.Icon as Image, if (insertDefault >= insertTop) insertDefault++;
SvgImage = module.Icon as RadSvgImage, if (insertBottom >= insertTop) insertBottom++;
Tag = module, // ...
Visibility = module.Enabled ? ElementVisibility.Visible : ElementVisibility.Collapsed itemsCollection.Insert(insertTop++, item);
}; break;
case FeaturePrioritization.Default:
if (clickHandler is not null) if (insertBottom >= insertDefault) insertBottom++;
item.Click += clickHandler; if (insertTop >= insertDefault) insertTop++;
// ...
return item; itemsCollection.Insert(insertDefault++, item);
} break;
case FeaturePrioritization.Low:
/// <summary> if (insertTop >= insertBottom) insertTop++;
/// Inserts all items to an item collection. if (insertDefault >= insertBottom) insertDefault++;
/// </summary> // ...
/// <param name="features"></param> itemsCollection.Insert(insertBottom++, item);
/// <param name="itemsCollection">Examples:<br/> break;
/// - <see cref="RadMenuItem.Items"/><br/>
/// - <see cref="RadSplitButtonElement.Items"/><br/>
/// - <see cref="RadDropDownButtonElement.Items"/><br/>
/// - <see cref="RadContextMenu.Items"/><br/>
/// - <see cref="RadRibbonBarGroup.Items"/><br/></param>
/// <param name="addDefaultHandler">Will add a default click handler that executes the feature.<br/>
/// You usually don't set customClickHandler if you set this parameter to <see cref="true"/>.</param>
/// <param name="customClickHandler">Adds a custom click handler. If addDefaultHandler is true, it will only work on <see cref="PluginFeature"/>s.<br/>
/// You usually don't set addDefaultHandler to true if you set this parameter to something not null.</param>
public static void InsertItemsTo(this IEnumerable<PluginFeature> features, RadItemOwnerCollection itemsCollection, bool addDefaultHandler = false, EventHandler? customClickHandler = null, FeatureInsertMode insertMode = FeatureInsertMode.Default, int? customDefault = null, int? customTop = null, int? customBottom = null, FeatureInsertPosition insertSplitter = FeatureInsertPosition.None)
{
var insertDefault = customDefault ?? (insertMode.HasFlag(FeatureInsertMode.DefaultStart) ? 0 : itemsCollection.Count);
var insertTop = customTop ?? (insertMode.HasFlag(FeatureInsertMode.InsertTop) || insertMode.HasFlag(FeatureInsertMode.DefaultStart) ? 0 : insertDefault);
var insertBottom = customBottom ?? (insertMode.HasFlag(FeatureInsertMode.InsertBottom) || insertMode.HasFlag(FeatureInsertMode.DefaultEnd) ? itemsCollection.Count : insertDefault);
foreach (var feature in features)
{
RadMenuItem item;
if (feature is PluginFunction function)
item = function.GetAsItem(addDefaultHandler);
else if (feature is PluginModuleBase module)
item = module.GetAsItem(addDefaultHandler);
else
item = feature.GetAsItem(null);
if (!addDefaultHandler && customClickHandler != null)
item.Click += customClickHandler;
switch (feature.Prioritization)
{
case FeaturePrioritization.High:
if (insertDefault >= insertTop) insertDefault++;
if (insertBottom >= insertTop) insertBottom++;
// ...
itemsCollection.Insert(insertTop++, item);
break;
case FeaturePrioritization.Default:
if (insertBottom >= insertDefault) insertBottom++;
if (insertTop >= insertDefault) insertTop++;
// ...
itemsCollection.Insert(insertDefault++, item);
break;
case FeaturePrioritization.Low:
if (insertTop >= insertBottom) insertTop++;
if (insertDefault >= insertBottom) insertDefault++;
// ...
itemsCollection.Insert(insertBottom++, item);
break;
}
} }
} }
}
private static void RadMenuItem_RMMethod_Click(object? sender, EventArgs e) private static void RadMenuItem_RMMethod_Click(object? sender, EventArgs e)
{ {
if (sender is RadMenuItem item && item.Tag is PluginModule function) if (sender is RadMenuItem item && item.Tag is PluginModule function)
function.ShowUI(); function.ShowUI();
} }
private static void RadMenuItem_RMFunction_Click(object? sender, EventArgs e) private static void RadMenuItem_RMFunction_Click(object? sender, EventArgs e)
{ {
if (sender is RadMenuItem item && item.Tag is PluginFunction function) if (sender is RadMenuItem item && item.Tag is PluginFunction function)
function.Execute(); function.Execute();
}
} }
} }

View File

@@ -1,39 +1,35 @@
using Pilz.Plugins.Advanced.UI; using Pilz.UI.Telerik;
using Pilz.UI.Telerik;
using Pilz.UI.Telerik.Dialogs; using Pilz.UI.Telerik.Dialogs;
using System.Drawing;
using System.Windows.Forms;
using Telerik.WinControls; using Telerik.WinControls;
namespace Pilz.Plugins.Advanced.UI.Telerik namespace Pilz.Plugins.Advanced.UI.Telerik;
public abstract class PluginModule : PluginModule<PluginModuleUI>
{ {
public abstract class PluginModule : PluginModule<PluginModuleUI> /// <summary>
/// Wrapper for the <see cref="PluginFeature.Icon"/> property to directly use it as <see cref="RadSvgImage"/>.
/// </summary>
public RadSvgImage? SvgImage
{ {
/// <summary> get => base.Icon as RadSvgImage;
/// Wrapper for the <see cref="PluginFeature.Icon"/> property to directly use it as <see cref="RadSvgImage"/>. set => base.Icon = value;
/// </summary> }
public RadSvgImage? SvgImage
{
get => base.Icon as RadSvgImage;
set => base.Icon = value;
}
protected PluginModule(string moduleType, string moduleIdentifier) : base(moduleType, moduleIdentifier) protected PluginModule(string moduleType, string moduleIdentifier) : base(moduleType, moduleIdentifier)
{ {
} }
protected PluginModule(string moduleType, string moduleIdentifier, string moduleName) : base(moduleType, moduleIdentifier, moduleName) protected PluginModule(string moduleType, string moduleIdentifier, string moduleName) : base(moduleType, moduleIdentifier, moduleName)
{ {
} }
public override void ShowUI() public override void ShowUI()
{
if (CreateNewUI() is PluginModuleUI ui)
{ {
if (CreateNewUI() is PluginModuleUI ui) ui.BackColor = Color.Transparent;
{ DialogBase.Show(ui, Name!, SvgImage!.ToImage().ToIcon()!);
ui.BackColor = Color.Transparent;
DialogBase.Show(ui, Name!, SvgImage!.ToImage().ToIcon()!);
}
} }
} }
} }

View File

@@ -1,22 +1,15 @@
using Pilz.UI.Telerik.Dialogs; using Pilz.UI.Telerik.Dialogs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Pilz.Plugins.Advanced.UI.Telerik namespace Pilz.Plugins.Advanced.UI.Telerik;
public class PluginModuleUI : FlyoutBase, ILoadContent
{ {
public class PluginModuleUI : FlyoutBase, ILoadContent public PluginModuleUI()
{ {
public PluginModuleUI() ActionPanelVisible = false;
{ }
ActionPanelVisible = false;
}
public virtual void LoadContent() public virtual void LoadContent()
{ {
}
} }
} }

View File

@@ -1,39 +1,32 @@
using System; namespace Pilz.Plugins.Advanced.UI;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Plugins.Advanced.UI [Flags]
public enum FeatureInsertMode
{ {
[Flags] /// <summary>
public enum FeatureInsertMode /// Features will be inserted at the end of the collection.
{ /// </summary>
/// <summary> Default = 0,
/// Features will be inserted at the end of the collection. /// <summary>
/// </summary> /// Features will be inserted at the end of the collection.
Default = 0, /// This is the default behavior and equals <see cref="Default"/>. Will only be used if not set <see cref="UseCustomDefault"/>.
/// <summary> /// </summary>
/// Features will be inserted at the end of the collection. DefaultEnd = Default,
/// This is the default behavior and equals <see cref="Default"/>. Will only be used if not set <see cref="UseCustomDefault"/>. /// <summary>
/// </summary> /// Features will be inserted at the start of the collection.
DefaultEnd = Default, /// Will only be used if not set <see cref="UseCustomDefault"/>.
/// <summary> /// </summary>
/// Features will be inserted at the start of the collection. DefaultStart = 1,
/// Will only be used if not set <see cref="UseCustomDefault"/>. /// <summary>
/// </summary> /// Features with prioritization <see cref="FeaturePrioritization.High"/> will be inserted at the top (or left).
DefaultStart = 1, /// </summary>
/// <summary> InsertTop = 1 << 2,
/// Features with prioritization <see cref="FeaturePrioritization.High"/> will be inserted at the top (or left). /// <summary>
/// </summary> /// Features with prioritization <see cref="FeaturePrioritization.Low"/> will be inserted at the bottom (or right).
InsertTop = 1 << 2, /// </summary>
/// <summary> InsertBottom = 1 << 3,
/// Features with prioritization <see cref="FeaturePrioritization.Low"/> will be inserted at the bottom (or right). /// <summary>
/// </summary> /// Features with prioritization other then <see cref="FeaturePrioritization.Default"/> will be inserted at the top or bottom.
InsertBottom = 1 << 3, /// </summary>
/// <summary> InsertTopAndBottom = InsertTop | InsertBottom,
/// Features with prioritization other then <see cref="FeaturePrioritization.Default"/> will be inserted at the top or bottom.
/// </summary>
InsertTopAndBottom = InsertTop | InsertBottom,
}
} }

Some files were not shown because too many files have changed in this diff Show More