using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Net; using System.Reflection; using System.Runtime.InteropServices; using System.Text.RegularExpressions; using System.Windows; using System.Windows.Documents; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Imaging; using ChatController.Core; using RestSharp; using MessageBox = System.Windows.MessageBox; using PixelFormat = System.Drawing.Imaging.PixelFormat; namespace ChatController.Utilities { public class Utils { public static string AuthToken { get; set; } public static string Tenant { get; set; } public static DateTime DefaultDate = new DateTime(1, 1, 1); public static void DownloadGroupProfilePictureAsync(string pathToProfilePicture, string key, Action callback) { var cache = OwnChatCache.GetInstance(); var cachedProfileImage = cache.GetCachedProfilePicture(key, pathToProfilePicture); if (!(cachedProfileImage is null)) { callback?.Invoke(cachedProfileImage); return; } DownloadImage(pathToProfilePicture, imageSource => { cache.AddProfilePictureToCache(key, imageSource, pathToProfilePicture); callback?.Invoke(imageSource); }); } public static void DownloadUserProfilePicturesAsync(Dictionary userIds2Uris) { var cache = OwnChatCache.GetInstance(); foreach(var userId2Uri in userIds2Uris) { if(cache.IsUserProfilePictureInCache(userId2Uri.Key)) { continue; } DownloadImage(userId2Uri.Value, imageSource => { cache.AddUserProfilePictureToCache(imageSource, userId2Uri.Key, userId2Uri.Value); }); } } private static void DownloadImage(string uri, Action callback) { var client = new RestClient(uri); var request = new RestRequest { ResponseWriter = stream => { var rotation = Rotation.Rotate0; using(var image = Image.FromStream(stream)) { if(image.PropertyIdList.Contains(0x112)) { rotation = GetRotationFromExifTag(image.GetPropertyItem(0x112).Value[0]); } var bitmap = new BitmapImage(); var localStream = new MemoryStream(); image.Save(localStream, image.RawFormat); localStream.Position = 0; bitmap.BeginInit(); bitmap.StreamSource = localStream; bitmap.Rotation = rotation; bitmap.EndInit(); bitmap.Freeze(); callback?.Invoke(bitmap); } } }; request.AddHeader(Constants.Token, AuthToken); request.AddHeader(Constants.CustomerId, Tenant); client.ExecuteAsync(request, null); } private static Rotation GetRotationFromExifTag(int value) { switch (value) { case 6: return Rotation.Rotate90; case 8: return Rotation.Rotate270; case 3: return Rotation.Rotate180; default: return Rotation.Rotate0; } } public static void DownloadImageAsync(string uri, string key, CacheCategory cacheCategory, Action callback) { if(string.IsNullOrEmpty(uri)) { callback?.Invoke(null); return; } var cache = OwnChatCache.GetInstance(); var cachedImage = cache.GetImageSourceFromCache(key, uri, cacheCategory); if(!(cachedImage is null)) { callback?.Invoke(cachedImage); return; } DownloadImage(uri, imageSource => { cache.AddImageToCache(key, imageSource, cacheCategory, uri); callback?.Invoke(imageSource); }); } public static void DownloadDocumentThumbnail(string uri, Action callback) { if (string.IsNullOrEmpty(uri)) { callback?.Invoke(null); return; } var cache = OwnChatCache.GetInstance(); if(!(cache.DocumentThumbnail is null)) { callback?.Invoke(cache.DocumentThumbnail); return; } DownloadImage(uri, imageSource => { cache.DocumentThumbnail = imageSource; callback?.Invoke(imageSource); }); } public static ImageSource GetPicturePlaceholder() { var cache = OwnChatCache.GetInstance(); if(cache.ImagePlaceholder is null) { var resultBitmapImage = new BitmapImage(); resultBitmapImage.BeginInit(); resultBitmapImage.UriSource = new Uri(Constants.ImagePlaceholderPath); resultBitmapImage.EndInit(); resultBitmapImage.Freeze(); cache.ImagePlaceholder = resultBitmapImage; } return cache.ImagePlaceholder; } public static string ReadStream(WebResponse response) { var dataStream = response.GetResponseStream(); if(dataStream is null) { return null; } var reader = new StreamReader(dataStream); var responseFromServer = reader.ReadToEnd(); dataStream.Dispose(); reader.Dispose(); dataStream.Close(); reader.Close(); return responseFromServer; } public static string GetAndCreateUserAppDataPath() { try { var localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); var companyFilePath = Path.Combine(localAppData, Resource.CompanyName); if(!Directory.Exists(companyFilePath)) { Directory.CreateDirectory(companyFilePath); } var bewoFilePath = Path.Combine(companyFilePath, Resource.ApplicationFolderName); if(!Directory.Exists(bewoFilePath)) { Directory.CreateDirectory(bewoFilePath); } return bewoFilePath; } catch(Exception exception) { MessageBox.Show("Fehler beim Anlegen des Anwendungsordners. Sie besitzen nicht die erforderlichen Rechte, bitte wenden Sie sich an Ihren Systemadministrator.\n" + exception.Message, "BeWoPlaner", MessageBoxButton.OK, MessageBoxImage.Exclamation); } return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); } public static string GenerateTempName() { const int length = 6; const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; var random = new Random(); var tempName = new string(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray()); return tempName; } public static byte[] ImageToByteArray(Image pImage) { try { using(var memoryStream = new MemoryStream()) { pImage.Save(memoryStream, ImageFormat.Bmp); return memoryStream.ToArray(); } } catch(Exception exception) { MessageBox.Show("Fehler: " + exception.Message, "Fehler", MessageBoxButton.OK); return null; } } public static ImageSource ConvertIconToImageSource(Icon pIcon) { var bitmap = new Bitmap(pIcon.Width, pIcon.Height); var graphics = Graphics.FromImage(bitmap); graphics.DrawIcon(pIcon, 0, 0); graphics.Dispose(); bitmap.Save("icon.ico", ImageFormat.Icon); var imageSource = ImageSourceForBitmap(bitmap); bitmap.Dispose(); return imageSource; } [DllImport("gdi32.dll", EntryPoint = "DeleteObject")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool DeleteObject([In] IntPtr hObject); public static ImageSource ImageSourceForBitmap(Bitmap bmp) { var handle = bmp.GetHbitmap(); try { return Imaging.CreateBitmapSourceFromHBitmap(handle, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); } finally { DeleteObject(handle); } } public static Icon ImageSourceToIcon(ImageSource pImageSource) { var bitmapSource = (BitmapSource) pImageSource; var width = bitmapSource.PixelWidth; var height = bitmapSource.PixelHeight; var newWidth = width; var newHeight = height; var x = 0; var y = 0; if(width < height) { newHeight = width; y = (height - width) / 2; } else { newWidth = height; x = (width - height) / 2; } var stride = width * ((bitmapSource.Format.BitsPerPixel + 7) / 8); var memoryBlockPointer = Marshal.AllocHGlobal(height * stride); bitmapSource.CopyPixels(new Int32Rect(x, y, newWidth, newHeight), memoryBlockPointer, newHeight * stride, stride); var bitmap = new Bitmap(newWidth, newHeight, stride, PixelFormat.Format32bppPArgb, memoryBlockPointer); return Icon.FromHandle(bitmap.GetHicon()); } public static byte[] ReadFully(Stream pStream) { using(var memStream = new MemoryStream()) { pStream.CopyTo(memStream); return memStream.ToArray(); } } public static RotateFlipType OrientationToFlipType(string orientation) { switch(int.Parse(orientation)) { case 1: return RotateFlipType.RotateNoneFlipNone; case 2: return RotateFlipType.RotateNoneFlipX; case 3: return RotateFlipType.Rotate180FlipNone; case 4: return RotateFlipType.Rotate180FlipX; case 5: return RotateFlipType.Rotate90FlipX; case 6: return RotateFlipType.Rotate90FlipNone; case 7: return RotateFlipType.Rotate270FlipX; case 8: return RotateFlipType.Rotate270FlipNone; default: return RotateFlipType.RotateNoneFlipNone; } } public static List GetVisualChildCollection(object parent) where T : Visual { var visualCollection = new List(); GetVisualChildCollection(parent as DependencyObject, visualCollection); return visualCollection; } public static void GetVisualChildCollection(DependencyObject parent, ICollection visualCollection) where T : Visual { var count = VisualTreeHelper.GetChildrenCount(parent); for(var i = 0; i < count; i++) { var child = VisualTreeHelper.GetChild(parent, i); if(child is T item) { visualCollection.Add(item); } else { GetVisualChildCollection(child, visualCollection); } } } public static int GetHeightFromThumbnailUri(string uri) { /* https://test.ownchat.de/document.png https://test.ownchat.de/profile/view-image/{customerid}/{width}/{height}/{filename} https://test.ownchat.de/message/view-image/{customerid}/{group}/{height}/{filename} */ if(uri?.Contains("/") ?? false) { var splitUri = uri.Split('/'); if(splitUri.Length>=2) { var heightStr = splitUri[splitUri.Length - 2]; if(int.TryParse(heightStr, out var height)) { return height; } } } return 100; } private static readonly Regex _UrlRegex = new Regex(@"(?#Protocol)(http(?:s?)\:(\/\/|\\\\)|(w){3}(2|3)?\.{1})(?#Subdomains)(?:(?:[-\w]+\.)+(?#TopLevel Domains)(?:com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum|travel|[a-z]{2}))(?#Port)(?::[\d]{1,5})?(?#Directories)(?:(?:(?:/(?:[-\w~!$+|.,=]|%[a-f\d]{2})+)+|/)+|\?|#)?(?#Query)(?:(?:\?(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)(?:&(?:[-\w~!$+|.,*:]|%[a-f\d{2}])+=(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)*)*(?#Anchor)(?:#(?:[-\w~!$+|.,*:=]|%[a-f\d]{2})*)?", RegexOptions.Compiled | RegexOptions.IgnoreCase); public static ObservableCollection ConvertLinksToHyperlinks(string messageText) { var result = new ObservableCollection(); if(messageText is null) { return result; } var guidString = Guid.NewGuid().ToString(); var replacementString = Guid.NewGuid().ToString(); var matches = _UrlRegex.Matches(messageText); var index2Link = new Dictionary(); for(var i = 0; i < matches.Count; i++) { var link = matches[i].Value; if(!link.Contains("http")) { link = $"http://{link}"; } var hyperlink = new Hyperlink(new Run(link)) { NavigateUri = new Uri(link, UriKind.Absolute) }; hyperlink.RequestNavigate += (s, e) => { Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri)); e.Handled = true; }; index2Link[i] = hyperlink; } var splitMessage = _UrlRegex.Replace(messageText, replacementString + guidString).Split(new[] {guidString}, StringSplitOptions.None); var linkIndex = 0; foreach(var text in splitMessage) { if(text.Equals(replacementString)) { result.Add(index2Link[linkIndex]); linkIndex++; } else if(text.StartsWith(replacementString) || text.EndsWith(replacementString)) { var splitLine = text.Split(new[] { replacementString }, StringSplitOptions.None); foreach(var partLine in splitLine) { if(string.Empty.Equals(partLine)) { result.Add(index2Link[linkIndex]); linkIndex++; } else { result.Add(new Run(partLine)); } } } else { result.Add(new Run(text)); } } return result; } } }