2019-04-02 13:43:30 +02:00
using System ;
2020-06-17 19:36:52 +02:00
using System.Collections.Generic ;
2021-09-07 19:32:10 +02:00
using System.Collections.ObjectModel ;
using System.Diagnostics ;
2019-04-02 13:43:30 +02:00
using System.Drawing ;
using System.Drawing.Imaging ;
using System.IO ;
2019-05-14 13:37:20 +02:00
using System.Linq ;
2019-04-02 13:43:30 +02:00
using System.Net ;
2019-05-14 13:37:20 +02:00
using System.Runtime.InteropServices ;
2021-09-07 19:32:10 +02:00
using System.Text.RegularExpressions ;
2019-05-14 13:37:20 +02:00
using System.Windows ;
2021-09-07 19:32:10 +02:00
using System.Windows.Documents ;
2019-05-14 13:37:20 +02:00
using System.Windows.Interop ;
2019-04-02 13:43:30 +02:00
using System.Windows.Media ;
using System.Windows.Media.Imaging ;
2021-07-14 19:33:50 +02:00
using ChatController.Core ;
2020-04-17 13:01:23 +02:00
using RestSharp ;
2019-05-14 13:37:20 +02:00
using PixelFormat = System . Drawing . Imaging . PixelFormat ;
2019-04-02 13:43:30 +02:00
namespace ChatController.Utilities
{
public class Utils
{
2020-06-17 19:36:52 +02:00
public static string AuthToken { get ; set ; }
2023-07-24 18:04:56 +02:00
2020-06-17 19:36:52 +02:00
public static string Tenant { get ; set ; }
public static DateTime DefaultDate = new DateTime ( 1 , 1 , 1 ) ;
2019-04-04 13:00:10 +02:00
2023-07-24 18:04:56 +02:00
public static void DownloadUserProfilePicturesSync ( Dictionary < long , string > userIds2Uris )
2022-05-27 11:50:37 +02:00
{
foreach ( var userId2Uri in userIds2Uris )
{
2023-07-24 18:04:56 +02:00
DownloadImageSync ( userId2Uri . Value , userId2Uri . Key , null ) ;
2022-05-27 11:50:37 +02:00
}
}
2023-07-24 18:04:56 +02:00
/// <summary>
/// Lädt ein Bild aus einer Nachricht herunter.
/// </summary>
/// <param name="uri">Uri zum Bild</param>
/// <param name="callback">Callback-Methode, die nach dem Herunterladen des Bildes aufgerufen wird und das Bild zurückgibt. Fügt das Bild der GUI hinzu.</param>
2021-09-07 19:32:10 +02:00
private static void DownloadImage ( string uri , Action < ImageSource > callback )
{
var client = new RestClient ( uri ) ;
2021-07-14 19:33:50 +02:00
var request = new RestRequest
{
ResponseWriter = stream = >
2020-06-17 19:36:52 +02:00
{
2022-06-03 16:40:47 +02:00
var rotation = Rotation . Rotate0 ;
2020-06-17 19:36:52 +02:00
2022-06-03 16:40:47 +02:00
using ( var image = Image . FromStream ( stream ) )
{
if ( image . PropertyIdList . Contains ( 0x112 ) )
{
rotation = GetRotationFromExifTag ( image . GetPropertyItem ( 0x112 ) . Value [ 0 ] ) ;
}
2020-06-17 19:36:52 +02:00
2022-06-03 16:40:47 +02:00
var bitmap = new BitmapImage ( ) ;
2020-06-17 19:36:52 +02:00
2022-06-03 16:40:47 +02:00
var localStream = new MemoryStream ( ) ;
2020-06-17 19:36:52 +02:00
2022-06-03 16:40:47 +02:00
image . Save ( localStream , image . RawFormat ) ;
2020-06-17 19:36:52 +02:00
2022-06-03 16:40:47 +02:00
localStream . Position = 0 ;
bitmap . BeginInit ( ) ;
bitmap . StreamSource = localStream ;
bitmap . Rotation = rotation ;
bitmap . EndInit ( ) ;
bitmap . Freeze ( ) ;
callback ? . Invoke ( bitmap ) ;
}
2021-07-14 19:33:50 +02:00
}
} ;
2020-06-17 19:36:52 +02:00
2021-07-14 19:33:50 +02:00
request . AddHeader ( Constants . Token , AuthToken ) ;
request . AddHeader ( Constants . CustomerId , Tenant ) ;
2022-06-03 16:40:47 +02:00
client . ExecuteAsync ( request , null ) ;
}
private static Rotation GetRotationFromExifTag ( int value )
{
2023-07-24 18:04:56 +02:00
switch ( value )
2022-06-03 16:40:47 +02:00
{
case 6 :
return Rotation . Rotate90 ;
case 8 :
return Rotation . Rotate270 ;
case 3 :
return Rotation . Rotate180 ;
default :
return Rotation . Rotate0 ;
}
2020-06-17 19:36:52 +02:00
}
2021-07-14 19:33:50 +02:00
public static void DownloadImageAsync ( string uri , string key , CacheCategory cacheCategory , Action < ImageSource > callback )
2020-06-17 19:36:52 +02:00
{
2021-07-14 19:33:50 +02:00
if ( string . IsNullOrEmpty ( uri ) )
{
callback ? . Invoke ( null ) ;
return ;
}
2023-07-24 18:04:56 +02:00
2021-07-14 19:33:50 +02:00
var cache = OwnChatCache . GetInstance ( ) ;
var cachedImage = cache . GetImageSourceFromCache ( key , uri , cacheCategory ) ;
2022-07-28 19:18:15 +02:00
if ( ! ( cachedImage is null ) )
2021-07-14 19:33:50 +02:00
{
callback ? . Invoke ( cachedImage ) ;
return ;
}
2020-06-17 19:36:52 +02:00
2021-09-07 19:32:10 +02:00
DownloadImage ( uri , imageSource = >
2020-06-17 19:36:52 +02:00
{
2021-09-07 19:32:10 +02:00
cache . AddImageToCache ( key , imageSource , cacheCategory , uri ) ;
callback ? . Invoke ( imageSource ) ;
} ) ;
2019-04-02 13:43:30 +02:00
}
2022-07-28 19:18:15 +02:00
public static void DownloadDocumentThumbnail ( string uri , Action < ImageSource > callback )
{
2023-07-24 18:04:56 +02:00
if ( string . IsNullOrEmpty ( uri ) )
2022-07-28 19:18:15 +02:00
{
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 ) ;
} ) ;
}
2021-07-14 19:33:50 +02:00
public static ImageSource GetPicturePlaceholder ( )
2019-04-02 13:43:30 +02:00
{
2022-07-28 19:18:15 +02:00
var cache = OwnChatCache . GetInstance ( ) ;
2019-04-02 13:43:30 +02:00
2022-07-28 19:18:15 +02:00
if ( cache . ImagePlaceholder is null )
{
var resultBitmapImage = new BitmapImage ( ) ;
2019-04-02 13:43:30 +02:00
2022-07-28 19:18:15 +02:00
resultBitmapImage . BeginInit ( ) ;
resultBitmapImage . UriSource = new Uri ( Constants . ImagePlaceholderPath ) ;
resultBitmapImage . EndInit ( ) ;
resultBitmapImage . Freeze ( ) ;
cache . ImagePlaceholder = resultBitmapImage ;
}
return cache . ImagePlaceholder ;
2019-04-02 13:43:30 +02:00
}
2021-07-14 19:33:50 +02:00
2019-04-02 13:43:30 +02:00
public static string ReadStream ( WebResponse response )
{
var dataStream = response . GetResponseStream ( ) ;
2022-07-28 19:18:15 +02:00
if ( dataStream is null )
2019-04-02 13:43:30 +02:00
{
return null ;
}
var reader = new StreamReader ( dataStream ) ;
var responseFromServer = reader . ReadToEnd ( ) ;
dataStream . Dispose ( ) ;
reader . Dispose ( ) ;
dataStream . Close ( ) ;
reader . Close ( ) ;
return responseFromServer ;
}
2019-05-14 13:37:20 +02:00
public static string GetAndCreateUserAppDataPath ( )
{
2023-03-03 21:23:48 +01:00
var localAppData = Environment . GetFolderPath ( Environment . SpecialFolder . LocalApplicationData ) ;
var companyFilePath = Path . Combine ( localAppData , Resource . CompanyName ) ;
2019-05-14 13:37:20 +02:00
2023-03-03 21:23:48 +01:00
if ( ! Directory . Exists ( companyFilePath ) )
{
Directory . CreateDirectory ( companyFilePath ) ;
}
2019-05-14 13:37:20 +02:00
2023-03-03 21:23:48 +01:00
var bewoFilePath = Path . Combine ( companyFilePath , Resource . ApplicationFolderName ) ;
2019-05-14 13:37:20 +02:00
2023-03-03 21:23:48 +01:00
if ( ! Directory . Exists ( bewoFilePath ) )
2019-05-14 13:37:20 +02:00
{
2023-03-03 21:23:48 +01:00
Directory . CreateDirectory ( bewoFilePath ) ;
2019-05-14 13:37:20 +02:00
}
2023-03-03 21:23:48 +01:00
return bewoFilePath ;
2019-05-14 13:37:20 +02:00
}
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 )
{
2023-03-03 21:23:48 +01:00
using ( var memoryStream = new MemoryStream ( ) )
2019-05-14 13:37:20 +02:00
{
2023-03-03 21:23:48 +01:00
pImage . Save ( memoryStream , ImageFormat . Bmp ) ;
return memoryStream . ToArray ( ) ;
2019-05-14 13:37:20 +02:00
}
}
2021-07-14 19:33:50 +02:00
public static ImageSource ConvertIconToImageSource ( Icon pIcon )
2019-05-14 13:37:20 +02:00
{
var bitmap = new Bitmap ( pIcon . Width , pIcon . Height ) ;
2023-07-24 18:04:56 +02:00
2019-05-14 13:37:20 +02:00
var graphics = Graphics . FromImage ( bitmap ) ;
graphics . DrawIcon ( pIcon , 0 , 0 ) ;
graphics . Dispose ( ) ;
bitmap . Save ( "icon.ico" , ImageFormat . Icon ) ;
var imageSource = ImageSourceForBitmap ( bitmap ) ;
2023-07-24 18:04:56 +02:00
2019-05-14 13:37:20 +02:00
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 )
{
2023-07-24 18:04:56 +02:00
var bitmapSource = ( BitmapSource ) pImageSource ;
2019-05-14 13:37:20 +02:00
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 ) ;
2023-07-24 18:04:56 +02:00
2019-05-14 13:37:20 +02:00
var bitmap = new Bitmap ( newWidth , newHeight , stride , PixelFormat . Format32bppPArgb , memoryBlockPointer ) ;
return Icon . FromHandle ( bitmap . GetHicon ( ) ) ;
}
public static byte [ ] ReadFully ( Stream pStream )
{
2022-07-28 19:18:15 +02:00
using ( var memStream = new MemoryStream ( ) )
2019-05-14 13:37:20 +02:00
{
pStream . CopyTo ( memStream ) ;
return memStream . ToArray ( ) ;
}
}
public static RotateFlipType OrientationToFlipType ( string orientation )
{
2022-07-28 19:18:15 +02:00
switch ( int . Parse ( orientation ) )
2019-05-14 13:37:20 +02:00
{
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 ;
}
}
2020-06-17 19:36:52 +02:00
public static List < T > GetVisualChildCollection < T > ( object parent ) where T : Visual
{
var visualCollection = new List < T > ( ) ;
GetVisualChildCollection ( parent as DependencyObject , visualCollection ) ;
return visualCollection ;
}
public static void GetVisualChildCollection < T > ( DependencyObject parent , ICollection < T > 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 ) ;
}
}
}
2021-07-14 19:33:50 +02:00
public static int GetHeightFromThumbnailUri ( string uri )
2020-06-17 19:36:52 +02:00
{
2021-07-14 19:33:50 +02:00
/ *
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}
* /
2020-06-17 19:36:52 +02:00
2022-07-28 19:18:15 +02:00
if ( uri ? . Contains ( "/" ) ? ? false )
2021-07-14 19:33:50 +02:00
{
var splitUri = uri . Split ( '/' ) ;
2020-06-17 19:36:52 +02:00
2023-07-24 18:04:56 +02:00
if ( splitUri . Length > = 2 )
2021-07-14 19:33:50 +02:00
{
var heightStr = splitUri [ splitUri . Length - 2 ] ;
2020-06-17 19:36:52 +02:00
2021-07-14 19:33:50 +02:00
if ( int . TryParse ( heightStr , out var height ) )
{
return height ;
}
}
2020-06-17 19:36:52 +02:00
}
2021-07-14 19:33:50 +02:00
return 100 ;
2020-06-17 19:36:52 +02:00
}
2021-09-07 19:32:10 +02:00
2023-07-25 12:30:04 +02:00
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 ) ;
2021-09-07 19:32:10 +02:00
public static ObservableCollection < Inline > ConvertLinksToHyperlinks ( string messageText )
{
var result = new ObservableCollection < Inline > ( ) ;
2022-07-28 19:18:15 +02:00
if ( messageText is null )
2021-09-07 19:32:10 +02:00
{
return result ;
}
var guidString = Guid . NewGuid ( ) . ToString ( ) ;
var replacementString = Guid . NewGuid ( ) . ToString ( ) ;
2023-07-25 12:30:04 +02:00
var matches = UrlRegex . Matches ( messageText ) ;
2021-09-07 19:32:10 +02:00
var index2Link = new Dictionary < int , Hyperlink > ( ) ;
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 ;
}
2023-07-25 12:30:04 +02:00
var splitMessage = UrlRegex . Replace ( messageText , replacementString + guidString ) . Split ( new [ ] { guidString } , StringSplitOptions . None ) ;
2021-09-07 19:32:10 +02:00
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 ;
}
2023-07-24 18:04:56 +02:00
public static ImageSource DownloadImageSync ( string uri , long? userId , int? groupId )
{
var cache = OwnChatCache . GetInstance ( ) ;
if ( cache . IsAvatarInCache ( uri , userId , groupId ) )
{
return cache . GetAvatar ( uri , userId , groupId ) ;
}
var request = WebRequest . Create ( uri ) ;
request . Credentials = CredentialCache . DefaultCredentials ;
request . Headers [ Constants . Token ] = AuthToken ;
request . Headers [ Constants . CustomerId ] = Tenant ;
using ( var response = request . GetResponse ( ) )
{
2023-07-25 12:30:04 +02:00
var responseStream = response . GetResponseStream ( ) ;
2023-07-24 18:04:56 +02:00
if ( responseStream is null )
{
return null ;
}
var rotation = Rotation . Rotate0 ;
using ( var image = Image . FromStream ( responseStream ) )
{
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 ( ) ;
cache . AddAvatar ( uri , bitmap , userId , groupId ) ;
return cache . GetAvatar ( uri , userId , groupId ) ;
}
}
}
2019-04-02 13:43:30 +02:00
}
}