Compare commits

..

No commits in common. "master" and "v1.5.0" have entirely different histories.

10 changed files with 475 additions and 768 deletions

View File

@ -1,188 +0,0 @@
# Changelog
## 1.6.2 - 2022-01-30 - ProgrammLogger improved
### New Features
* ProgrammLogger can now have a path while init, so not need to move the file
* Make it possible that two instances can use the same logfile
* IniReader GetValue can now have a default that returns if no setting is found
### Bugfixes
### Changes
* Codingstyles
## 1.6.1 - 2022-01-20 - ProgrammLogger Fixed
### New Features
### Bugfixes
* Unhandled exception. System.IO.IOException: The file '/var/log/zwaybot/debug.log' already exists.
### Changes
## 1.6.0 - 2022-01-09 - HttpEndpoint added
### New Features
* Add HttpEndpoint
### Bugfixes
### Changes
* Change Readme that its link to the normal repo
* Codingstyles
* Fixing history
## 1.5.0 - 2021-04-10 - Add GetEvent so you can call events by string; Add OwnSingeton class
### New Features
* More allowed Chars for Chapters in inifile
* Add Contribution, Licence and readme
* Adding netcore
* Add changelog
* Filedhelper to helpter
* CmdArgs improvements
* Make netcore to default
* Add OwnSingleton
### Bugfixes
* WriteLine in Programmlogger sometimes make nonesense
* Writeline event are wrong
### Changes
* Remove the binary files
* Move all Classes to subfolder
* Codingstyles
## 1.4.0 - 2018-11-27 - Add Helper to Utils
### New Features
* Add Helper
### Bugfixes
### Changes
## 1.1.3 - 2018-10-02 - Improve CmdArgs
### New Features
* CmdArgs now throw extensions if there is something wrong
### Bugfixes
### Changes
## 1.1.2 - 2018-09-11 - Tiny Codingstyles
### New Features
### Bugfixes
### Changes
* Codingstyles
## 1.1.1 - 2018-05-29 - ProgrammLogger neets to cleanup
### New Features
* Delete the Mess behind
### Bugfixes
### Changes
## 1.1.0 - 2018-05-15 - ProgrammLogger
### New Features
* Add Programmlogger
### Bugfixes
### Changes
* Codingstyles
## 1.0.7.0 - 2018-05-08 - Yet another IniReader improvemnt round again
### New Features
### Bugfixes
### Changes
* Move searchpath to its own function
## 1.0.6.0 - 2017-12-22 - Yet another IniReader improvemnt round
### New Features
* Posibillity to add complete sections to an ini file
### Bugfixes
### Changes
## 1.0.5.2 - 2017-09-26 - And Improve IniReader again
### New Features
* IniReader returns the Sections with or without Brackets now
### Bugfixes
### Changes
## 1.0.5.1 - 2017-09-24 - Improve IniReader again
### New Features
### Bugfixes
* IniReader now supports umlaute
* IniReader matches with Brackets and without
### Changes
## 1.0.5.0 - 2017-08-09 - Improve IniReader
### New Features
* IniReader can now return a whole segemt
### Bugfixes
### Changes
## 1.0.4.1 - 2017-08-08 - Cleanup OwnView
### New Features
### Bugfixes
### Changes
* remove Init from OwnView
## 1.0.4.0 - 2017-04-30 - More Updater
### New Features
* continue Development of Updater
### Bugfixes
### Changes
## 1.0.3.2 - 2017-04-26 - Next Updater
### New Features
* continue Development of Updater
### Bugfixes
### Changes
## 1.0.3.1 - 2017-04-25 - EventArgsHelper
### New Features
* Add EventArgsHelper
### Bugfixes
### Changes
* Codingstyles
* Moves LogEventArgs to EventArgsHelper
* Moves UpdaterEventArgs to EventArgsHelper
## 1.0.2.6 - 2017-04-24 - Better Updater
### New Features
* Add Updater
* Add Disposable Interface
* Using LogEventArgs now for Logging
* Make UpdaterEventArgs as Child of EventArgs
* Updater now using Ownobject as Parent
* Add VersionsInfo to Updater
* Updater spawns a Background Task to Check for Updates
### Bugfixes
### Changes
## 1.0.2.5 - 2017-04-19 - Logging in OwnObject
### New Features
* Add Logging to OwnObject
### Bugfixes
* Avoid nullpointer exception in FileMutex
### Changes
* Codingstyles
## 1.0.2.3 - 2017-04-16 - OwnModel better
### New Features
* Add Remove observer on OwnModel
### Bugfixes
### Changes
* Codingstyles
## 1.0.2.2 - 2017-03-09 - Make it nice
### New Features
### Bugfixes
### Changes
* Codingstyles
## 1.0.2.1 - 2017-03-09 - Filemutex
### New Features
* Add Filemutex
### Bugfixes
* Filelogger backet on wrong pos
### Changes
## 1.0.0.1 - 2016-12-03 - Filelogger improvements
### New Features
* Check Directory and if not exist add it
* Now logs with timestamp
* Can select logdir
* Add Abstract dispose to OwnController
### Bugfixes
### Changes
## 1.0.0.0 - 2015-11-16 - Init
### New Features
* Add CmdArgs, FileLogger, IniReader, OwnController, OwnModel, OwnObject, OwnView,
### Bugfixes
### Changes

View File

@ -1,4 +1,2 @@
# BlubbFish.Utils (Utils) # BlubbFish.Utils (Utils)
Library containing helpfull utils Library containing helpfull utils
Maybe you find this Repo on Github. This is a mirror from [here](https://git.blubbfish.net/vs_utils/Utils).

View File

@ -43,7 +43,7 @@ namespace BlubbFish.Utils
_ = Directory.CreateDirectory(v); _ = Directory.CreateDirectory(v);
logDir = v; logDir = v;
} }
if (logDir[^1..] != Path.DirectorySeparatorChar.ToString()) { if (logDir.Substring(logDir.Length - 1) != Path.DirectorySeparatorChar.ToString()) {
logDir += Path.DirectorySeparatorChar; logDir += Path.DirectorySeparatorChar;
} }
} }

View File

@ -49,12 +49,10 @@ namespace BlubbFish.Utils {
FieldInfo field = o.GetType().GetField(name); FieldInfo field = o.GetType().GetField(name);
return field.IsPublic ? field.GetValue(o) : null; return field.IsPublic ? field.GetValue(o) : null;
} }
public static Object GetField(this Type o, String name) { public static Object GetField(this Type o, String name) {
FieldInfo field = o.GetField(name); FieldInfo field = o.GetField(name);
return field.IsPublic ? field.GetValue(o) : null; return field.IsPublic ? field.GetValue(o) : null;
} }
public static T GetEvent<T>(this Object o, String name) { public static T GetEvent<T>(this Object o, String name) {
FieldInfo field = o.GetType().GetField(name, BindingFlags.Instance | BindingFlags.NonPublic); FieldInfo field = o.GetType().GetField(name, BindingFlags.Instance | BindingFlags.NonPublic);
return (T)field?.GetValue(o); return (T)field?.GetValue(o);

View File

@ -1,59 +0,0 @@
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace BlubbFish.Utils {
public class HttpEndpoint {
private readonly HttpClient client = new HttpClient();
private readonly String server = "";
public enum RequestMethod {
GET,
POST,
PUT
}
public HttpEndpoint(String server, String auth = null) {
this.server = server;
if(auth != null) {
this.client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(auth);
}
}
public HttpEndpoint(String server, (String scheme, String parameter) auth) {
this.server = server;
this.client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(auth.scheme, auth.parameter);
}
public async Task<String> RequestString(String address, String json = "", Boolean withoutput = true, RequestMethod method = RequestMethod.GET) {
String ret = null;
try {
HttpResponseMessage response = null;
if(method == RequestMethod.POST || method == RequestMethod.PUT) {
HttpContent content = new StringContent(json);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
//content.Headers.Add("Content-Type", "application/json");
if(method == RequestMethod.POST) {
response = await this.client.PostAsync(this.server + address, content);
} else if(method == RequestMethod.PUT) {
response = await this.client.PutAsync(this.server + address, content);
}
content.Dispose();
} else if(method == RequestMethod.GET) {
response = await this.client.GetAsync(this.server + address);
}
if(!response.IsSuccessStatusCode) {
throw new Exception(response.StatusCode + ": " + response.ReasonPhrase);
}
if(withoutput && response != null) {
ret = await response.Content.ReadAsStringAsync();
}
} catch(Exception e) {
throw new WebException(String.Format("Error while opening resource: \"{0}\" Method {1} Data {2} Fehler {3}", this.server + address, method, json, e.Message));
}
return ret;
}
}
}

View File

@ -1,257 +1,261 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
namespace BlubbFish.Utils { namespace BlubbFish.Utils {
public class InIReader : IDisposable public class InIReader : IDisposable
{ {
private Dictionary<String, Dictionary<String, String>> inifile; private Dictionary<String, Dictionary<String, String>> inifile;
private readonly FileSystemWatcher k; private readonly FileSystemWatcher k;
private readonly String filename; private readonly String filename;
private static readonly List<String> search_path = new List<String>() { private static readonly List<String> search_path = new List<String>() {
Directory.GetCurrentDirectory() Directory.GetCurrentDirectory()
}; };
private static readonly Dictionary<String, InIReader> instances = new Dictionary<String, InIReader>(); private static readonly Dictionary<String, InIReader> instances = new Dictionary<String, InIReader>();
public static void SetSearchPath(List<String> directorys) => search_path.AddRange(directorys); public static void SetSearchPath(List<String> directorys) => search_path.AddRange(directorys);
public static Boolean ConfigExist(String filename) { public static Boolean ConfigExist(String filename) {
foreach (String path in search_path) { foreach (String path in search_path) {
if (File.Exists(path + Path.DirectorySeparatorChar + filename)) { if (File.Exists(path + Path.DirectorySeparatorChar + filename)) {
return true; return true;
} else if (File.Exists(path + Path.DirectorySeparatorChar + filename + ".ini")) { } else if (File.Exists(path + Path.DirectorySeparatorChar + filename + ".ini")) {
return true; return true;
} else if (File.Exists(path + Path.DirectorySeparatorChar + filename + ".conf")) { } else if (File.Exists(path + Path.DirectorySeparatorChar + filename + ".conf")) {
return true; return true;
} }
} }
return false; return false;
} }
private InIReader(String filename) { private InIReader(String filename)
foreach (String path in search_path) { {
if (File.Exists(path + Path.DirectorySeparatorChar + filename)) { foreach (String path in search_path) {
this.filename = path + Path.DirectorySeparatorChar + filename; if (File.Exists(path + Path.DirectorySeparatorChar + filename)) {
this.k = new FileSystemWatcher(path, filename); this.filename = path + Path.DirectorySeparatorChar + filename;
break; this.k = new FileSystemWatcher(path, filename);
} else if (File.Exists(path + Path.DirectorySeparatorChar + filename + ".ini")) { break;
this.filename = path + Path.DirectorySeparatorChar + filename + ".ini"; } else if (File.Exists(path + Path.DirectorySeparatorChar + filename + ".ini")) {
this.k = new FileSystemWatcher(path, filename + ".ini"); this.filename = path + Path.DirectorySeparatorChar + filename + ".ini";
break; this.k = new FileSystemWatcher(path, filename + ".ini");
} else if(File.Exists(path + Path.DirectorySeparatorChar + filename + ".conf")) { break;
this.filename = path + Path.DirectorySeparatorChar + filename + ".conf"; } else if(File.Exists(path + Path.DirectorySeparatorChar + filename + ".conf")) {
this.k = new FileSystemWatcher(path, filename + ".conf"); this.filename = path + Path.DirectorySeparatorChar + filename + ".conf";
break; this.k = new FileSystemWatcher(path, filename + ".conf");
} break;
} }
if(this.filename == null) { }
throw new ArgumentException(filename + " not found!"); if(this.filename == null) {
} throw new ArgumentException(filename + " not found!");
this.k.Changed += new FileSystemEventHandler(this.ReadAgain); }
this.LoadFile(); this.k.Changed += new FileSystemEventHandler(this.ReadAgain);
} this.LoadFile();
}
/// <summary>
/// Gibt eine InIReader-Instanz zu einer Datei zurück /// <summary>
/// </summary> /// Gibt eine InIReader-Instanz zu einer Datei zurück
/// <param name="filename">Dateiname</param> /// </summary>
/// <returns></returns> /// <param name="filename">Dateiname</param>
public static InIReader GetInstance(String filename) { /// <returns></returns>
if (!instances.Keys.Contains(filename)) { public static InIReader GetInstance(String filename)
instances.Add(filename, new InIReader(filename)); {
} if (!instances.Keys.Contains(filename)) {
return instances[filename]; instances.Add(filename, new InIReader(filename));
} }
return instances[filename];
private void ReadAgain(Object sender, EventArgs e) => this.LoadFile(); }
private void LoadFile() { private void ReadAgain(Object sender, EventArgs e) => this.LoadFile();
this.inifile = new Dictionary<String, Dictionary<String, String>>();
StreamReader file = new StreamReader(this.filename); private void LoadFile()
List<String> buf = new List<String>(); {
String fline = ""; this.inifile = new Dictionary<String, Dictionary<String, String>>();
while (fline != null) { StreamReader file = new StreamReader(this.filename);
fline = file.ReadLine(); List<String> buf = new List<String>();
if (fline != null && fline.Length > 0 && fline.Substring(0, 1) != ";") { String fline = "";
buf.Add(fline); while (fline != null) {
} fline = file.ReadLine();
} if (fline != null && fline.Length > 0 && fline.Substring(0, 1) != ";") {
file.Close(); buf.Add(fline);
Dictionary<String, String> sub = new Dictionary<String, String>(); }
String cap = ""; }
foreach (String line in buf) { file.Close();
Match match = Regex.Match(line, @"^\[[a-zA-ZäöüÄÖÜ0-9\-\._/ ]+\]\w*$", RegexOptions.IgnoreCase); Dictionary<String, String> sub = new Dictionary<String, String>();
if (match.Success) { String cap = "";
if (sub.Count != 0 && cap != "") { foreach (String line in buf) {
this.inifile.Add(cap, sub); Match match = Regex.Match(line, @"^\[[a-zA-ZäöüÄÖÜ0-9\-\._/ ]+\]\w*$", RegexOptions.IgnoreCase);
} if (match.Success) {
cap = line; if (sub.Count != 0 && cap != "") {
sub = new Dictionary<String, String>(); this.inifile.Add(cap, sub);
} else { }
if (line != "" && cap != "") { cap = line;
String key = line.Substring(0, line.IndexOf('=')); sub = new Dictionary<String, String>();
String value = line[(line.IndexOf('=') + 1)..]; } else {
sub.Add(key, value); if (line != "" && cap != "") {
} String key = line.Substring(0, line.IndexOf('='));
} String value = line.Substring(line.IndexOf('=') + 1);
} sub.Add(key, value);
if (sub.Count != 0 && cap != "") { }
this.inifile.Add(cap, sub); }
} }
} if (sub.Count != 0 && cap != "") {
this.inifile.Add(cap, sub);
/// <summary> }
/// Gibt eine Liste an Sektionen zurück }
/// </summary>
/// <param name="withBrackets">Default = true; false, wenn die Liste ohne Klammern sein soll.</param> /// <summary>
/// <returns></returns> /// Gibt eine Liste an Sektionen zurück
public List<String> GetSections(Boolean withBrackets = true) /// </summary>
{ /// <param name="withBrackets">Default = true; false, wenn die Liste ohne Klammern sein soll.</param>
if(withBrackets) { /// <returns></returns>
return this.inifile.Keys.ToList(); public List<String> GetSections(Boolean withBrackets = true)
} else { {
List<String> ret = new List<String>(); if(withBrackets) {
foreach (String item in this.inifile.Keys) { return this.inifile.Keys.ToList();
ret.Add(item[1..^1]); } else {
} List<String> ret = new List<String>();
return ret; foreach (String item in this.inifile.Keys) {
} ret.Add(item[1..^1]);
} }
return ret;
/// <summary> }
/// Überschreibt eine InI-Datei mit der Kompletten neuen Configuration }
/// </summary>
/// <param name="config">Neue Konfiguration</param> /// <summary>
public void SetSections(Dictionary<String, Dictionary<String, String>> config) { /// Überschreibt eine InI-Datei mit der Kompletten neuen Configuration
this.inifile.Clear(); /// </summary>
foreach (KeyValuePair<String, Dictionary<String, String>> item in config) { /// <param name="config">Neue Konfiguration</param>
String key = item.Key; public void SetSections(Dictionary<String, Dictionary<String, String>> config) {
if(!key.StartsWith("[")) { this.inifile.Clear();
key = "[" + key + "]"; foreach (KeyValuePair<String, Dictionary<String, String>> item in config) {
} String key = item.Key;
if (Regex.Match(key, @"^\[[a-zA-ZäöüÄÖÜ0-9\-\._/ ]+\]\w*$", RegexOptions.IgnoreCase).Success) { if(!key.StartsWith("[")) {
this.inifile.Add(key, item.Value); key = "[" + key + "]";
} }
} if (Regex.Match(key, @"^\[[a-zA-ZäöüÄÖÜ0-9\-\._/ ]+\]\w*$", RegexOptions.IgnoreCase).Success) {
this.Changed(); this.inifile.Add(key, item.Value);
} }
}
this.Changed();
}
public Dictionary<String, String> GetSection(String section) => this.inifile.Keys.Contains(section) ? public Dictionary<String, String> GetSection(String section) => this.inifile.Keys.Contains(section) ?
this.inifile[section] : this.inifile.Keys.Contains("[" + section + "]") ? this.inifile[section] : this.inifile.Keys.Contains("[" + section + "]") ?
this.inifile["[" + section + "]"] : new Dictionary<String, String>(); this.inifile["[" + section + "]"] : new Dictionary<String, String>();
/// <summary> /// <summary>
/// Gibt einen einzelnen Wert zurück /// Gibt einen einzelnen Wert zurück
/// </summary> /// </summary>
/// <param name="section">Name der Sektion</param> /// <param name="section">Name der Sektion</param>
/// <param name="key">Name des Wertes</param> /// <param name="key">Name des Wertes</param>
/// <returns></returns> /// <returns></returns>
public String GetValue(String section, String key, String @default = null) { public String GetValue(String section, String key)
if (!section.StartsWith("[")) { {
section = "[" + section + "]"; if (!section.StartsWith("[")) {
} section = "[" + section + "]";
return this.inifile.Keys.Contains(section) && this.inifile[section].Keys.Contains(key) ? this.inifile[section][key] : @default; }
} return this.inifile.Keys.Contains(section) && this.inifile[section].Keys.Contains(key) ? this.inifile[section][key] : null;
}
/// <summary>
/// Setzt einen Wert in einer Sektion /// <summary>
/// </summary> /// Setzt einen Wert in einer Sektion
/// <param name="section">Name der Sektion</param> /// </summary>
/// <param name="key">Name des Wertes</param> /// <param name="section">Name der Sektion</param>
/// <param name="value">Wert</param> /// <param name="key">Name des Wertes</param>
public void SetValue(String section, String key, String value) /// <param name="value">Wert</param>
{ public void SetValue(String section, String key, String value)
if (!section.StartsWith("[")) { {
section = "[" + section + "]"; if (!section.StartsWith("[")) {
} section = "[" + section + "]";
if (this.inifile.Keys.Contains(section)) { }
if (this.inifile[section].Keys.Contains(key)) { if (this.inifile.Keys.Contains(section)) {
this.inifile[section][key] = value; if (this.inifile[section].Keys.Contains(key)) {
} else { this.inifile[section][key] = value;
this.inifile[section].Add(key, value); } else {
} this.inifile[section].Add(key, value);
} else { }
Dictionary<String, String> sub = new Dictionary<String, String> { } else {
{ key, value } Dictionary<String, String> sub = new Dictionary<String, String> {
}; { key, value }
this.inifile.Add(section, sub); };
} this.inifile.Add(section, sub);
this.Changed(); }
} this.Changed();
}
private void Changed()
{ private void Changed()
this.k.Changed -= null; {
this.SaveSettings(); this.k.Changed -= null;
this.LoadFile(); this.SaveSettings();
this.k.Changed += new FileSystemEventHandler(this.ReadAgain); this.LoadFile();
} this.k.Changed += new FileSystemEventHandler(this.ReadAgain);
}
private void SaveSettings()
{ private void SaveSettings()
StreamWriter file = new StreamWriter(this.filename); {
file.BaseStream.SetLength(0); StreamWriter file = new StreamWriter(this.filename);
file.BaseStream.Flush(); file.BaseStream.SetLength(0);
_ = file.BaseStream.Seek(0, SeekOrigin.Begin); file.BaseStream.Flush();
foreach (KeyValuePair<String, Dictionary<String, String>> cap in this.inifile) { _ = file.BaseStream.Seek(0, SeekOrigin.Begin);
file.WriteLine(cap.Key); foreach (KeyValuePair<String, Dictionary<String, String>> cap in this.inifile) {
foreach (KeyValuePair<String, String> sub in cap.Value) { file.WriteLine(cap.Key);
file.WriteLine(sub.Key + "=" + sub.Value); foreach (KeyValuePair<String, String> sub in cap.Value) {
} file.WriteLine(sub.Key + "=" + sub.Value);
file.WriteLine(); }
} file.WriteLine();
file.Flush(); }
file.Close(); file.Flush();
} file.Close();
}
/// <summary>
/// Fügt eine neue Sektion in der Ini-Datei ein. /// <summary>
/// </summary> /// Fügt eine neue Sektion in der Ini-Datei ein.
/// <param name="name">Sektionsname</param> /// </summary>
/// <returns>true if added, false if error</returns> /// <param name="name">Sektionsname</param>
public Boolean AddSection(String name) /// <returns>true if added, false if error</returns>
{ public Boolean AddSection(String name)
if (!name.StartsWith("[")) { {
name = "[" + name + "]"; if (!name.StartsWith("[")) {
} name = "[" + name + "]";
if (this.inifile.Keys.Contains(name)) { }
return false; if (this.inifile.Keys.Contains(name)) {
} return false;
this.inifile.Add(name, new Dictionary<String, String>()); }
this.Changed(); this.inifile.Add(name, new Dictionary<String, String>());
return true; this.Changed();
} return true;
}
/// <summary>
/// Löscht eine Sektion inklusive Unterpunkte aus der Ini-Datei. /// <summary>
/// </summary> /// Löscht eine Sektion inklusive Unterpunkte aus der Ini-Datei.
/// <param name="name">Sektionsname</param> /// </summary>
/// <returns>true if removed, false if error</returns> /// <param name="name">Sektionsname</param>
public Boolean RemoveSection(String name) /// <returns>true if removed, false if error</returns>
{ public Boolean RemoveSection(String name)
if (!name.StartsWith("[")) { {
name = "[" + name + "]"; if (!name.StartsWith("[")) {
} name = "[" + name + "]";
if (!this.inifile.Keys.Contains(name)) { }
return false; if (!this.inifile.Keys.Contains(name)) {
} return false;
_ = this.inifile.Remove(name); }
this.Changed(); _ = this.inifile.Remove(name);
return false; this.Changed();
} return false;
}
protected virtual void Dispose(Boolean disposing) {
if (disposing) { protected virtual void Dispose(Boolean disposing) {
this.k.Dispose(); if (disposing) {
} this.k.Dispose();
} }
}
public void Dispose() {
this.Dispose(true); public void Dispose() {
GC.SuppressFinalize(this); this.Dispose(true);
} GC.SuppressFinalize(this);
} }
} }
}

View File

@ -1,25 +1,25 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace BlubbFish.Utils { namespace BlubbFish.Utils {
public abstract class OwnModel<T> where T : class public abstract class OwnModel<T> where T : class
{ {
private static readonly Lazy<T> _instance = new Lazy<T>(() => CreateInstanceOfT()); private static readonly Lazy<T> _instance = new Lazy<T>(() => CreateInstanceOfT());
private readonly List<OwnView> observer = new List<OwnView>(); private readonly List<OwnView> observer = new List<OwnView>();
public static T Instance => _instance.Value; public static T Instance => _instance.Value;
private static T CreateInstanceOfT() => Activator.CreateInstance(typeof(T), true) as T; private static T CreateInstanceOfT() => Activator.CreateInstance(typeof(T), true) as T;
public void SetObserver(OwnView view) public void SetObserver(OwnView view)
{ {
this.observer.Add(view); this.observer.Add(view);
view.Update(); view.Update();
} }
public void RemoveObserver(OwnView view) => _ = this.observer.Remove(view); public void RemoveObserver(OwnView view) => _ = this.observer.Remove(view);
protected void Update() => this.observer.ForEach(delegate (OwnView view) { protected void Update() => this.observer.ForEach(delegate (OwnView view) {
view.Update(); view.Update();
}); });
abstract protected void Init(); abstract protected void Init();
abstract public void Dispose(); abstract public void Dispose();
} }
} }

View File

@ -1,175 +1,150 @@
using System; using System;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Text;
using System.Text;
namespace BlubbFish.Utils {
namespace BlubbFish.Utils { public class ProgramLogger {
public class ProgramLogger { private FileWriter fw;
private FileWriter fw; private ConsoleWriter stdout;
private ConsoleWriter stdout; private ConsoleWriter errout;
private ConsoleWriter errout; private String loggerfile;
private String loggerfile;
public ProgramLogger() {
public ProgramLogger(String path = null) { this.loggerfile = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "output.log";
this.loggerfile = path ?? Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "output.log"; this.Init(this.loggerfile);
this.Init(this.loggerfile); this.AttachToFw();
this.AttachToFw(); this.SetOutputs();
this.SetOutputs(); }
}
private void SetOutputs() {
private void SetOutputs() { Console.SetOut(this.stdout);
Console.SetOut(this.stdout); Console.SetError(this.errout);
Console.SetError(this.errout); }
}
private void Init(String file) {
private void Init(String file) { if(!this.IsWritable(file)) {
if(!this.IsWritable(file)) { Console.Error.WriteLine("Cannot write to " + file);
Console.Error.WriteLine("Cannot write to " + file); throw new ArgumentException("Cannot write to " + file);
throw new ArgumentException("Cannot write to " + file); }
} this.fw = new FileWriter(file);
this.fw = new FileWriter(FileWriter.GetFileSteam(file, false)); this.stdout = new ConsoleWriter(Console.Out, ConsoleWriterEventArgs.ConsoleType.Info);
this.stdout = new ConsoleWriter(Console.Out, ConsoleWriterEventArgs.ConsoleType.Info); this.errout = new ConsoleWriter(Console.Error, ConsoleWriterEventArgs.ConsoleType.Error);
this.errout = new ConsoleWriter(Console.Error, ConsoleWriterEventArgs.ConsoleType.Error); }
}
private Boolean IsWritable(String filename) {
private Boolean IsWritable(String filename) { try {
try {
using FileStream fstream = new FileStream(filename, FileMode.Append); using FileStream fstream = new FileStream(filename, FileMode.Append);
using TextWriter writer = new StreamWriter(fstream); using TextWriter writer = new StreamWriter(fstream);
writer.Write(""); writer.Write("");
} catch (UnauthorizedAccessException) { } catch (UnauthorizedAccessException) {
return false; return false;
} }
return true; return true;
} }
public void SetPath(String file) { public void SetPath(String file) {
if(file == null) { if(file == null) {
return; return;
} }
if (!this.IsWritable(file)) { if (!this.IsWritable(file)) {
Console.Error.WriteLine("Cannot write to " + file); Console.Error.WriteLine("Cannot write to " + file);
throw new ArgumentException("Cannot write to " + file); throw new ArgumentException("Cannot write to " + file);
} }
this.DisattachToFw(); this.DisattachToFw();
this.fw.Close(); this.fw.Close();
if(new FileInfo(this.loggerfile).Length > 0) { if(new FileInfo(this.loggerfile).Length > 0) {
if(File.Exists(file)) { File.Move(this.loggerfile, file);
this.FileCopy(this.loggerfile, file); } else {
File.Delete(this.loggerfile); File.Delete(this.loggerfile);
} else { }
File.Move(this.loggerfile, file); this.loggerfile = file;
} this.fw = new FileWriter(this.loggerfile);
} else { this.AttachToFw();
File.Delete(this.loggerfile); }
}
this.loggerfile = file; private void DisattachToFw() {
this.fw = new FileWriter(FileWriter.GetFileSteam(this.loggerfile, true)); this.stdout.WriteEvent -= this.fw.Write;
this.AttachToFw(); this.stdout.WriteLineEvent -= this.fw.WriteLine;
} this.errout.WriteEvent -= this.fw.Write;
this.errout.WriteLineEvent -= this.fw.WriteLine;
public void Dispose() { }
this.DisattachToFw(); private void AttachToFw() {
this.fw.Dispose(); this.stdout.WriteEvent += this.fw.Write;
} this.stdout.WriteLineEvent += this.fw.WriteLine;
this.errout.WriteEvent += this.fw.Write;
private void FileCopy(String source, String target) { this.errout.WriteLineEvent += this.fw.WriteLine;
using FileStream fread = new FileStream(source, FileMode.Open); }
using FileStream fwrite = new FileStream(target, FileMode.Create); }
using TextReader reader = new StreamReader(fread);
using TextWriter writer = new StreamWriter(fwrite); internal class FileWriter : StreamWriter {
private Boolean newline = true;
writer.Write(reader.ReadToEnd()); public FileWriter(String path) : base(path) {
writer.Flush(); }
writer.Close();
reader.Close();
}
private void DisattachToFw() {
this.stdout.WriteEvent -= this.fw.Write;
this.stdout.WriteLineEvent -= this.fw.WriteLine;
this.errout.WriteEvent -= this.fw.Write;
this.errout.WriteLineEvent -= this.fw.WriteLine;
}
private void AttachToFw() {
this.stdout.WriteEvent += this.fw.Write;
this.stdout.WriteLineEvent += this.fw.WriteLine;
this.errout.WriteEvent += this.fw.Write;
this.errout.WriteLineEvent += this.fw.WriteLine;
}
}
internal class FileWriter : StreamWriter {
private Boolean newline = true;
public FileWriter(FileStream fs) : base(fs) {
}
public static FileStream GetFileSteam(String path, Boolean append) => File.Open(path, append ? FileMode.Append : FileMode.Create, FileAccess.Write, RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? FileShare.Write : FileShare.ReadWrite);
public override Encoding Encoding => Encoding.UTF8; public override Encoding Encoding => Encoding.UTF8;
public override Boolean AutoFlush { get => true; set => base.AutoFlush = value; } public override Boolean AutoFlush { get => true; set => base.AutoFlush = value; }
private void Write(String value, TextWriter origstream, ConsoleWriterEventArgs.ConsoleType type) { private void Write(String value, TextWriter origstream, ConsoleWriterEventArgs.ConsoleType type) {
String text; String text;
if (this.newline) { if (this.newline) {
text = "[" + DateTime.Now.ToString("o") + "]-" + type.ToString() + ": " + value; text = "[" + DateTime.Now.ToString("o") + "]-" + type.ToString() + ": " + value;
this.newline = false; this.newline = false;
} else { } else {
text = value; text = value;
} }
origstream.Write(text); origstream.Write(text);
base.Write(text); base.Write(text);
base.Flush(); base.Flush();
} }
private void WriteLine(String value, TextWriter origstream, ConsoleWriterEventArgs.ConsoleType type) { private void WriteLine(String value, TextWriter origstream, ConsoleWriterEventArgs.ConsoleType type) {
String text = this.newline ? "[" + DateTime.Now.ToString("o") + "]-" + type.ToString() + ": " + value : value; String text = this.newline ? "[" + DateTime.Now.ToString("o") + "]-" + type.ToString() + ": " + value : value;
this.newline = true; this.newline = true;
origstream.WriteLine(text); origstream.WriteLine(text);
base.WriteLine(text); base.WriteLine(text);
base.Flush(); base.Flush();
} }
internal void Write(Object sender, ConsoleWriterEventArgs e) => this.Write(e.Value, e.Writer, e.StreamType); internal void Write(Object sender, ConsoleWriterEventArgs e) => this.Write(e.Value, e.Writer, e.StreamType);
internal void WriteLine(Object sender, ConsoleWriterEventArgs e) => this.WriteLine(e.Value, e.Writer, e.StreamType); internal void WriteLine(Object sender, ConsoleWriterEventArgs e) => this.WriteLine(e.Value, e.Writer, e.StreamType);
} }
internal class ConsoleWriterEventArgs : EventArgs { internal class ConsoleWriterEventArgs : EventArgs {
public String Value { get; private set; } public String Value { get; private set; }
public TextWriter Writer { get; private set; } public TextWriter Writer { get; private set; }
public ConsoleType StreamType { get; private set; } public ConsoleType StreamType { get; private set; }
public enum ConsoleType { public enum ConsoleType {
Info, Info,
Error Error
} }
public ConsoleWriterEventArgs(String value, TextWriter writer, ConsoleType type) { public ConsoleWriterEventArgs(String value, TextWriter writer, ConsoleType type) {
this.Value = value; this.Value = value;
this.Writer = writer; this.Writer = writer;
this.StreamType = type; this.StreamType = type;
} }
} }
internal class ConsoleWriter : TextWriter { internal class ConsoleWriter : TextWriter {
private readonly TextWriter stream; private readonly TextWriter stream;
private readonly ConsoleWriterEventArgs.ConsoleType streamtype; private readonly ConsoleWriterEventArgs.ConsoleType streamtype;
public ConsoleWriter(TextWriter writer, ConsoleWriterEventArgs.ConsoleType type) { public ConsoleWriter(TextWriter writer, ConsoleWriterEventArgs.ConsoleType type) {
this.stream = writer; this.stream = writer;
this.streamtype = type; this.streamtype = type;
} }
public override Encoding Encoding => Encoding.UTF8; public override Encoding Encoding => Encoding.UTF8;
public override void Write(String value) => this.WriteEvent?.Invoke(this, new ConsoleWriterEventArgs(value, this.stream, this.streamtype)); public override void Write(String value) => this.WriteEvent?.Invoke(this, new ConsoleWriterEventArgs(value, this.stream, this.streamtype));
//base.Write(value); //base.Write(value);
public override void WriteLine(String value) => this.WriteLineEvent?.Invoke(this, new ConsoleWriterEventArgs(value, this.stream, this.streamtype)); public override void WriteLine(String value) => this.WriteLineEvent?.Invoke(this, new ConsoleWriterEventArgs(value, this.stream, this.streamtype));
//base.WriteLine(value); //base.WriteLine(value);
public event EventHandler<ConsoleWriterEventArgs> WriteEvent; public event EventHandler<ConsoleWriterEventArgs> WriteEvent;
public event EventHandler<ConsoleWriterEventArgs> WriteLineEvent; public event EventHandler<ConsoleWriterEventArgs> WriteLineEvent;
} }
} }

View File

@ -1,45 +1,45 @@
#if !NETCOREAPP #if !NETCOREAPP
using System.Reflection; using System.Reflection;
using System.Resources; using System.Resources;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
// Allgemeine Informationen über eine Assembly werden über die folgenden // Allgemeine Informationen über eine Assembly werden über die folgenden
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
// die mit einer Assembly verknüpft sind. // die mit einer Assembly verknüpft sind.
[assembly: AssemblyTitle("Utils")] [assembly: AssemblyTitle("Utils")]
[assembly: AssemblyDescription("Provides useful classes for other projects")] [assembly: AssemblyDescription("Provides useful classes for other projects")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("BlubbFish")] [assembly: AssemblyCompany("BlubbFish")]
[assembly: AssemblyProduct("Utils")] [assembly: AssemblyProduct("Utils")]
[assembly: AssemblyCopyright("Copyright © BlubbFish 2014 - 10.04.2021")] [assembly: AssemblyCopyright("Copyright © BlubbFish 2014 - 10.04.2021")]
[assembly: AssemblyTrademark("BlubbFish")] [assembly: AssemblyTrademark("BlubbFish")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("de-DE")] [assembly: NeutralResourcesLanguage("de-DE")]
// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
[assembly: ComVisible(false)]
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
[assembly: Guid("6f20376a-5c71-4979-9932-13c105d1c6e6")]
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
//
// Hauptversion
// Nebenversion
// Buildnummer
// Revision
//
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
// übernehmen, indem Sie "*" eingeben:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.5.0")]
[assembly: AssemblyFileVersion("1.5.0")]
#endif
/**
// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar * 1.5.0 Add GetEvent so you can call events by string; Add OwnSingeton class
// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von * 1.4.0 Add Helper to Utils
// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
[assembly: ComVisible(false)]
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
[assembly: Guid("6f20376a-5c71-4979-9932-13c105d1c6e6")]
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
//
// Hauptversion
// Nebenversion
// Buildnummer
// Revision
//
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
// übernehmen, indem Sie "*" eingeben:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.5.0")]
[assembly: AssemblyFileVersion("1.5.0")]
#endif
/**
* 1.5.0 Add GetEvent so you can call events by string; Add OwnSingeton class
* 1.4.0 Add Helper to Utils
*/ */

View File

@ -8,47 +8,26 @@
<Company>BlubbFish</Company> <Company>BlubbFish</Company>
<Authors>BlubbFish</Authors> <Authors>BlubbFish</Authors>
<PackageId>Utils.BlubbFish</PackageId> <PackageId>Utils.BlubbFish</PackageId>
<Copyright>Copyright © BlubbFish 2014 - 30.01.2022</Copyright> <Copyright>Copyright © BlubbFish 2014 - 10.04.2021</Copyright>
<Version>1.6.2</Version> <AssemblyVersion>1.5.0</AssemblyVersion>
<FileVersion>1.5.0</FileVersion>
<NeutralLanguage>de-DE</NeutralLanguage> <NeutralLanguage>de-DE</NeutralLanguage>
<PackageLicenseFile>LICENSE</PackageLicenseFile> <PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageProjectUrl>http://git.blubbfish.net/vs_utils/Utils</PackageProjectUrl> <PackageProjectUrl>http://git.blubbfish.net/vs_utils/Utils</PackageProjectUrl>
<RepositoryUrl>http://git.blubbfish.net/vs_utils/Utils.git</RepositoryUrl> <RepositoryUrl>http://git.blubbfish.net/vs_utils/Utils.git</RepositoryUrl>
<RepositoryType>git</RepositoryType> <RepositoryType>git</RepositoryType>
<Version>1.5.0</Version>
<PackageReleaseNotes> <PackageReleaseNotes>
1.6.2 - 2022-01-30 - ProgrammLogger improved 1.5.0 Add GetEvent so you can call events by string; Add OwnSingeton class
1.6.1 - 2022-01-20 - ProgrammLogger Fixed 1.4.0 Add Helper to Utils
1.6.0 - 2022-01-09 - HttpEndpoint added </PackageReleaseNotes>
1.5.0 - 2021-04-10 - Add GetEvent so you can call events by string; Add OwnSingeton class
1.4.0 - 2018-11-27 - Add Helper to Utils
1.1.3 - 2018-10-02 - Improve CmdArgs
1.1.2 - 2018-09-11 - Tiny Codingstyles
1.1.1 - 2018-05-29 - ProgrammLogger neets to cleanup
1.1.0 - 2018-05-15 - ProgrammLogger
1.0.7.0 - 2018-05-08 - Yet another IniReader improvemnt round again
1.0.6.0 - 2017-12-22 - Yet another IniReader improvemnt round
1.0.5.2 - 2017-09-26 - And Improve IniReader again
1.0.5.1 - 2017-09-24 - Improve IniReader again
1.0.5.0 - 2017-08-09 - Improve IniReader
1.0.4.1 - 2017-08-08 - Cleanup OwnView
1.0.4.0 - 2017-04-30 - More Updater
1.0.3.2 - 2017-04-26 - Next Updater
1.0.3.1 - 2017-04-25 - EventArgsHelper
1.0.2.6 - 2017-04-24 - Better Updater
1.0.2.5 - 2017-04-19 - Logging in OwnObject
1.0.2.3 - 2017-04-16 - OwnModel better
1.0.2.2 - 2017-03-09 - Make it nice
1.0.2.1 - 2017-03-09 - Filemutex
1.0.0.1 - 2016-12-03 - Filelogger improvements
1.0.0.0 - 2015-11-16 - Init
</PackageReleaseNotes>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Content Include="../CHANGELOG.md" /> <Content Include="../CHANGELOG.md" />
<Content Include="../CONTRIBUTING.md" /> <Content Include="../CONTRIBUTING.md" />
<Content Include="../LICENSE" /> <Content Include="../LICENSE" />
<Content Include="../README.md" /> <Content Include="../README.md" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\LICENSE"> <None Include="..\LICENSE">