Compare commits

...

4 Commits

Author SHA1 Message Date
cc579102cb [1.6.2] ProgrammLogger improved 2022-01-30 22:40:25 +01:00
e3d37988c9 [1.6.1] ProgrammLogger Fixed 2022-01-20 19:42:14 +01:00
61f26e69af [1.6.0] HttpEndpoint added 2022-01-09 23:01:53 +01:00
528dcabf59 make mirror on github.com 2021-08-22 00:12:41 +02:00
10 changed files with 768 additions and 475 deletions

View File

@ -0,0 +1,188 @@
# 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,2 +1,4 @@
# 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.Substring(logDir.Length - 1) != Path.DirectorySeparatorChar.ToString()) { if (logDir[^1..] != Path.DirectorySeparatorChar.ToString()) {
logDir += Path.DirectorySeparatorChar; logDir += Path.DirectorySeparatorChar;
} }
} }

View File

@ -49,10 +49,12 @@ 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);

59
Utils/HttpEndpoint.cs Normal file
View File

@ -0,0 +1,59 @@
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,261 +1,257 @@
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) {
foreach (String path in search_path) { if (File.Exists(path + Path.DirectorySeparatorChar + filename)) {
if (File.Exists(path + Path.DirectorySeparatorChar + filename)) { this.filename = path + Path.DirectorySeparatorChar + filename;
this.filename = path + Path.DirectorySeparatorChar + filename; this.k = new FileSystemWatcher(path, filename);
this.k = new FileSystemWatcher(path, filename); break;
break; } else if (File.Exists(path + Path.DirectorySeparatorChar + filename + ".ini")) {
} else if (File.Exists(path + Path.DirectorySeparatorChar + filename + ".ini")) { this.filename = path + Path.DirectorySeparatorChar + filename + ".ini";
this.filename = path + Path.DirectorySeparatorChar + filename + ".ini"; this.k = new FileSystemWatcher(path, filename + ".ini");
this.k = new FileSystemWatcher(path, filename + ".ini"); break;
break; } else if(File.Exists(path + Path.DirectorySeparatorChar + filename + ".conf")) {
} else if(File.Exists(path + Path.DirectorySeparatorChar + filename + ".conf")) { this.filename = path + Path.DirectorySeparatorChar + filename + ".conf";
this.filename = path + Path.DirectorySeparatorChar + filename + ".conf"; this.k = new FileSystemWatcher(path, filename + ".conf");
this.k = new FileSystemWatcher(path, filename + ".conf"); break;
break; }
} }
} if(this.filename == null) {
if(this.filename == null) { throw new ArgumentException(filename + " not found!");
throw new ArgumentException(filename + " not found!"); }
} this.k.Changed += new FileSystemEventHandler(this.ReadAgain);
this.k.Changed += new FileSystemEventHandler(this.ReadAgain); this.LoadFile();
this.LoadFile(); }
}
/// <summary>
/// <summary> /// Gibt eine InIReader-Instanz zu einer Datei zurück
/// Gibt eine InIReader-Instanz zu einer Datei zurück /// </summary>
/// </summary> /// <param name="filename">Dateiname</param>
/// <param name="filename">Dateiname</param> /// <returns></returns>
/// <returns></returns> public static InIReader GetInstance(String filename) {
public static InIReader GetInstance(String filename) if (!instances.Keys.Contains(filename)) {
{ instances.Add(filename, new InIReader(filename));
if (!instances.Keys.Contains(filename)) { }
instances.Add(filename, new InIReader(filename)); return instances[filename];
} }
return instances[filename];
} private void ReadAgain(Object sender, EventArgs e) => this.LoadFile();
private void ReadAgain(Object sender, EventArgs e) => this.LoadFile(); private void LoadFile() {
this.inifile = new Dictionary<String, Dictionary<String, String>>();
private void LoadFile() StreamReader file = new StreamReader(this.filename);
{ List<String> buf = new List<String>();
this.inifile = new Dictionary<String, Dictionary<String, String>>(); String fline = "";
StreamReader file = new StreamReader(this.filename); while (fline != null) {
List<String> buf = new List<String>(); fline = file.ReadLine();
String fline = ""; if (fline != null && fline.Length > 0 && fline.Substring(0, 1) != ";") {
while (fline != null) { buf.Add(fline);
fline = file.ReadLine(); }
if (fline != null && fline.Length > 0 && fline.Substring(0, 1) != ";") { }
buf.Add(fline); file.Close();
} Dictionary<String, String> sub = new Dictionary<String, String>();
} String cap = "";
file.Close(); foreach (String line in buf) {
Dictionary<String, String> sub = new Dictionary<String, String>(); Match match = Regex.Match(line, @"^\[[a-zA-ZäöüÄÖÜ0-9\-\._/ ]+\]\w*$", RegexOptions.IgnoreCase);
String cap = ""; if (match.Success) {
foreach (String line in buf) { if (sub.Count != 0 && cap != "") {
Match match = Regex.Match(line, @"^\[[a-zA-ZäöüÄÖÜ0-9\-\._/ ]+\]\w*$", RegexOptions.IgnoreCase); this.inifile.Add(cap, sub);
if (match.Success) { }
if (sub.Count != 0 && cap != "") { cap = line;
this.inifile.Add(cap, sub); sub = new Dictionary<String, String>();
} } else {
cap = line; if (line != "" && cap != "") {
sub = new Dictionary<String, String>(); String key = line.Substring(0, line.IndexOf('='));
} else { String value = line[(line.IndexOf('=') + 1)..];
if (line != "" && cap != "") { sub.Add(key, value);
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>
/// <summary> /// <param name="withBrackets">Default = true; false, wenn die Liste ohne Klammern sein soll.</param>
/// Gibt eine Liste an Sektionen zurück /// <returns></returns>
/// </summary> public List<String> GetSections(Boolean withBrackets = true)
/// <param name="withBrackets">Default = true; false, wenn die Liste ohne Klammern sein soll.</param> {
/// <returns></returns> if(withBrackets) {
public List<String> GetSections(Boolean withBrackets = true) return this.inifile.Keys.ToList();
{ } else {
if(withBrackets) { List<String> ret = new List<String>();
return this.inifile.Keys.ToList(); foreach (String item in this.inifile.Keys) {
} else { ret.Add(item[1..^1]);
List<String> ret = new List<String>(); }
foreach (String item in this.inifile.Keys) { return ret;
ret.Add(item[1..^1]); }
} }
return ret;
} /// <summary>
} /// Überschreibt eine InI-Datei mit der Kompletten neuen Configuration
/// </summary>
/// <summary> /// <param name="config">Neue Konfiguration</param>
/// Überschreibt eine InI-Datei mit der Kompletten neuen Configuration public void SetSections(Dictionary<String, Dictionary<String, String>> config) {
/// </summary> this.inifile.Clear();
/// <param name="config">Neue Konfiguration</param> foreach (KeyValuePair<String, Dictionary<String, String>> item in config) {
public void SetSections(Dictionary<String, Dictionary<String, String>> config) { String key = item.Key;
this.inifile.Clear(); if(!key.StartsWith("[")) {
foreach (KeyValuePair<String, Dictionary<String, String>> item in config) { key = "[" + key + "]";
String key = item.Key; }
if(!key.StartsWith("[")) { if (Regex.Match(key, @"^\[[a-zA-ZäöüÄÖÜ0-9\-\._/ ]+\]\w*$", RegexOptions.IgnoreCase).Success) {
key = "[" + key + "]"; this.inifile.Add(key, item.Value);
} }
if (Regex.Match(key, @"^\[[a-zA-ZäöüÄÖÜ0-9\-\._/ ]+\]\w*$", RegexOptions.IgnoreCase).Success) { }
this.inifile.Add(key, item.Value); this.Changed();
} }
}
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) public String GetValue(String section, String key, String @default = null) {
{ if (!section.StartsWith("[")) {
if (!section.StartsWith("[")) { section = "[" + section + "]";
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>
/// <summary> /// Setzt einen Wert in einer Sektion
/// Setzt einen Wert in einer Sektion /// </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> /// <param name="value">Wert</param>
/// <param name="value">Wert</param> public void SetValue(String section, String key, String value)
public void SetValue(String section, String key, String value) {
{ if (!section.StartsWith("[")) {
if (!section.StartsWith("[")) { section = "[" + section + "]";
section = "[" + section + "]"; }
} if (this.inifile.Keys.Contains(section)) {
if (this.inifile.Keys.Contains(section)) { if (this.inifile[section].Keys.Contains(key)) {
if (this.inifile[section].Keys.Contains(key)) { this.inifile[section][key] = value;
this.inifile[section][key] = value; } else {
} else { this.inifile[section].Add(key, value);
this.inifile[section].Add(key, value); }
} } else {
} else { Dictionary<String, String> sub = new Dictionary<String, String> {
Dictionary<String, String> sub = new Dictionary<String, String> { { key, value }
{ 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.k.Changed -= null; this.SaveSettings();
this.SaveSettings(); this.LoadFile();
this.LoadFile(); this.k.Changed += new FileSystemEventHandler(this.ReadAgain);
this.k.Changed += new FileSystemEventHandler(this.ReadAgain); }
}
private void SaveSettings()
private void SaveSettings() {
{ StreamWriter file = new StreamWriter(this.filename);
StreamWriter file = new StreamWriter(this.filename); file.BaseStream.SetLength(0);
file.BaseStream.SetLength(0); file.BaseStream.Flush();
file.BaseStream.Flush(); _ = file.BaseStream.Seek(0, SeekOrigin.Begin);
_ = file.BaseStream.Seek(0, SeekOrigin.Begin); foreach (KeyValuePair<String, Dictionary<String, String>> cap in this.inifile) {
foreach (KeyValuePair<String, Dictionary<String, String>> cap in this.inifile) { file.WriteLine(cap.Key);
file.WriteLine(cap.Key); foreach (KeyValuePair<String, String> sub in cap.Value) {
foreach (KeyValuePair<String, String> sub in cap.Value) { file.WriteLine(sub.Key + "=" + sub.Value);
file.WriteLine(sub.Key + "=" + sub.Value); }
} file.WriteLine();
file.WriteLine(); }
} file.Flush();
file.Flush(); file.Close();
file.Close(); }
}
/// <summary>
/// <summary> /// Fügt eine neue Sektion in der Ini-Datei ein.
/// Fügt eine neue Sektion in der Ini-Datei ein. /// </summary>
/// </summary> /// <param name="name">Sektionsname</param>
/// <param name="name">Sektionsname</param> /// <returns>true if added, false if error</returns>
/// <returns>true if added, false if error</returns> public Boolean AddSection(String name)
public Boolean AddSection(String name) {
{ if (!name.StartsWith("[")) {
if (!name.StartsWith("[")) { name = "[" + name + "]";
name = "[" + name + "]"; }
} if (this.inifile.Keys.Contains(name)) {
if (this.inifile.Keys.Contains(name)) { return false;
return false; }
} this.inifile.Add(name, new Dictionary<String, String>());
this.inifile.Add(name, new Dictionary<String, String>()); this.Changed();
this.Changed(); return true;
return true; }
}
/// <summary>
/// <summary> /// Löscht eine Sektion inklusive Unterpunkte aus der Ini-Datei.
/// Löscht eine Sektion inklusive Unterpunkte aus der Ini-Datei. /// </summary>
/// </summary> /// <param name="name">Sektionsname</param>
/// <param name="name">Sektionsname</param> /// <returns>true if removed, false if error</returns>
/// <returns>true if removed, false if error</returns> public Boolean RemoveSection(String name)
public Boolean RemoveSection(String name) {
{ if (!name.StartsWith("[")) {
if (!name.StartsWith("[")) { name = "[" + name + "]";
name = "[" + name + "]"; }
} if (!this.inifile.Keys.Contains(name)) {
if (!this.inifile.Keys.Contains(name)) { return false;
return false; }
} _ = this.inifile.Remove(name);
_ = this.inifile.Remove(name); this.Changed();
this.Changed(); return false;
return false; }
}
protected virtual void Dispose(Boolean disposing) {
protected virtual void Dispose(Boolean disposing) { if (disposing) {
if (disposing) { this.k.Dispose();
this.k.Dispose(); }
} }
}
public void Dispose() {
public void Dispose() { this.Dispose(true);
this.Dispose(true); GC.SuppressFinalize(this);
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,150 +1,175 @@
using System; using System;
using System.IO; using System.IO;
using System.Text; using System.Runtime.InteropServices;
using System.Text;
namespace BlubbFish.Utils {
public class ProgramLogger { namespace BlubbFish.Utils {
private FileWriter fw; public class ProgramLogger {
private ConsoleWriter stdout; private FileWriter fw;
private ConsoleWriter errout; private ConsoleWriter stdout;
private String loggerfile; private ConsoleWriter errout;
private String loggerfile;
public ProgramLogger() {
this.loggerfile = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "output.log"; public ProgramLogger(String path = null) {
this.Init(this.loggerfile); this.loggerfile = path ?? Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "output.log";
this.AttachToFw(); this.Init(this.loggerfile);
this.SetOutputs(); this.AttachToFw();
} this.SetOutputs();
}
private void SetOutputs() {
Console.SetOut(this.stdout); private void SetOutputs() {
Console.SetError(this.errout); Console.SetOut(this.stdout);
} Console.SetError(this.errout);
}
private void Init(String file) {
if(!this.IsWritable(file)) { private void Init(String file) {
Console.Error.WriteLine("Cannot write to " + file); if(!this.IsWritable(file)) {
throw new ArgumentException("Cannot write to " + file); Console.Error.WriteLine("Cannot write to " + file);
} throw new ArgumentException("Cannot write to " + file);
this.fw = new FileWriter(file); }
this.stdout = new ConsoleWriter(Console.Out, ConsoleWriterEventArgs.ConsoleType.Info); this.fw = new FileWriter(FileWriter.GetFileSteam(file, false));
this.errout = new ConsoleWriter(Console.Error, ConsoleWriterEventArgs.ConsoleType.Error); this.stdout = new ConsoleWriter(Console.Out, ConsoleWriterEventArgs.ConsoleType.Info);
} this.errout = new ConsoleWriter(Console.Error, ConsoleWriterEventArgs.ConsoleType.Error);
}
private Boolean IsWritable(String filename) {
try { private Boolean IsWritable(String filename) {
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) {
File.Move(this.loggerfile, file); if(File.Exists(file)) {
} else { this.FileCopy(this.loggerfile, file);
File.Delete(this.loggerfile); File.Delete(this.loggerfile);
} } else {
this.loggerfile = file; File.Move(this.loggerfile, file);
this.fw = new FileWriter(this.loggerfile); }
this.AttachToFw(); } else {
} File.Delete(this.loggerfile);
}
private void DisattachToFw() { this.loggerfile = file;
this.stdout.WriteEvent -= this.fw.Write; this.fw = new FileWriter(FileWriter.GetFileSteam(this.loggerfile, true));
this.stdout.WriteLineEvent -= this.fw.WriteLine; this.AttachToFw();
this.errout.WriteEvent -= this.fw.Write; }
this.errout.WriteLineEvent -= this.fw.WriteLine;
} public void Dispose() {
private void AttachToFw() { this.DisattachToFw();
this.stdout.WriteEvent += this.fw.Write; this.fw.Dispose();
this.stdout.WriteLineEvent += this.fw.WriteLine; }
this.errout.WriteEvent += this.fw.Write;
this.errout.WriteLineEvent += this.fw.WriteLine; private void FileCopy(String source, String target) {
} using FileStream fread = new FileStream(source, FileMode.Open);
} using FileStream fwrite = new FileStream(target, FileMode.Create);
using TextReader reader = new StreamReader(fread);
internal class FileWriter : StreamWriter { using TextWriter writer = new StreamWriter(fwrite);
private Boolean newline = true;
public FileWriter(String path) : base(path) { writer.Write(reader.ReadToEnd());
} 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
/**
* 1.5.0 Add GetEvent so you can call events by string; Add OwnSingeton class // Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
* 1.4.0 Add Helper to Utils // 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
/**
* 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,26 +8,47 @@
<Company>BlubbFish</Company> <Company>BlubbFish</Company>
<Authors>BlubbFish</Authors> <Authors>BlubbFish</Authors>
<PackageId>Utils.BlubbFish</PackageId> <PackageId>Utils.BlubbFish</PackageId>
<Copyright>Copyright © BlubbFish 2014 - 10.04.2021</Copyright> <Copyright>Copyright © BlubbFish 2014 - 30.01.2022</Copyright>
<AssemblyVersion>1.5.0</AssemblyVersion> <Version>1.6.2</Version>
<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.5.0 Add GetEvent so you can call events by string; Add OwnSingeton class 1.6.2 - 2022-01-30 - ProgrammLogger improved
1.4.0 Add Helper to Utils 1.6.1 - 2022-01-20 - ProgrammLogger Fixed
</PackageReleaseNotes> 1.6.0 - 2022-01-09 - HttpEndpoint added
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">