initial commit
This commit is contained in:
276
Api/UploadApi.cs
Normal file
276
Api/UploadApi.cs
Normal file
@@ -0,0 +1,276 @@
|
||||
using BitMiracle.LibTiff.Classic;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SkiaSharp;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
namespace Library.Api;
|
||||
|
||||
[Route( "Api/Upload/[action]/{id?}" )]
|
||||
public class UploadApi : APIController
|
||||
{
|
||||
private readonly string m_TempDirectory;
|
||||
|
||||
public UploadApi( ILogger<UserApi> logger , IConfiguration configuration )
|
||||
: base( logger , configuration )
|
||||
{
|
||||
m_TempDirectory = configuration.GetValue<string>( "TempDirectory" ) ?? string.Empty;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult StartUpload( )
|
||||
{
|
||||
Trace( "/Api/Repository/StartUpload" );
|
||||
string session = Guid.NewGuid( ).ToString( ).Replace( "-" , null );
|
||||
using FileStream stream = new( m_TempDirectory + session! , FileMode.CreateNew , FileAccess.Write , FileShare.None );
|
||||
return Success( session! );
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult UploadChunk( string? session , string? payload , long offset )
|
||||
{
|
||||
if ( session == null )
|
||||
return Error( "Invalid call. (session)" );
|
||||
|
||||
if ( !ValidateOffset( session , offset ) )
|
||||
return Error( "Invalid call. (Bad offset)" );
|
||||
|
||||
byte[]? bytes = Base64DecodeSafe( payload );
|
||||
if ( bytes == null )
|
||||
return Error( "Invalid call. (Bad payload)" );
|
||||
|
||||
using FileStream stream = new( m_TempDirectory + session! , FileMode.Append , FileAccess.Write , FileShare.None );
|
||||
stream.Write( bytes , 0 , bytes.Length );
|
||||
return Success( "OK" );
|
||||
}
|
||||
|
||||
private static byte[]? PreprocessMP4( string form_file )
|
||||
{
|
||||
byte[] file_bytes = System.IO.File.ReadAllBytes( form_file );
|
||||
if ( file_bytes.Length < 100 )
|
||||
return null;
|
||||
|
||||
return file_bytes;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult SaveMP4Attachment( string? session , long offset , int id )
|
||||
{
|
||||
if ( session == null )
|
||||
return Error( "Invalid call. (Invalid parameters)" );
|
||||
|
||||
/* if ( !ValidateOffset( session , offset ) )
|
||||
return Error( "Invalid call. (Bad offset)" );
|
||||
*/
|
||||
byte [] ? pdf_data_array = PreprocessMP4( m_TempDirectory + session! );
|
||||
if ( pdf_data_array == null )
|
||||
return Error( "Invalid file" );
|
||||
|
||||
SqlDataReader reader = PrepareSQL(@"update gnm_rec set uuid = REPLACE(NEWID( ),'-',''),data_format='mp4' OUTPUT INSERTED.uuid WHERE id = @id")
|
||||
.AddParameter( "@id" , id )
|
||||
.ExecuteReader( );
|
||||
|
||||
if ( !reader.Read( ) )
|
||||
return Error( "No such attachment!" );
|
||||
|
||||
string? new_uuid = reader.String( 0 );
|
||||
if ( string.IsNullOrEmpty( new_uuid ) )
|
||||
return Error( "No such attachment!" );
|
||||
|
||||
string original = GetDataDirectory( ) + new_uuid + ".mp4";
|
||||
System.IO.File.WriteAllBytes( original , pdf_data_array );
|
||||
|
||||
return Success( new_uuid );
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult SaveCoverImage( string? session , long offset , int id )
|
||||
{
|
||||
if ( session == null )
|
||||
return Error( "Invalid call. (Invalid parameters)" );
|
||||
|
||||
if ( !ValidateOffset( session , offset ) )
|
||||
return Error( "Invalid call. (Bad offset)" );
|
||||
|
||||
using SKBitmap? bitmap = PreprocessImage( m_TempDirectory + session! );
|
||||
if ( bitmap == null )
|
||||
return Error( "Invalid image" );
|
||||
|
||||
SqlDataReader reader = PrepareSQL(@"update gnm set uuid = REPLACE(NEWID( ),'-',''),data_format='jpg' OUTPUT INSERTED.uuid WHERE id = @id")
|
||||
.AddParameter( "@id" , id )
|
||||
.ExecuteReader( );
|
||||
|
||||
if ( !reader.Read( ) )
|
||||
return Error( "No such book!" );
|
||||
|
||||
string? new_uuid = reader.String( 0 );
|
||||
if ( string.IsNullOrEmpty( new_uuid ) )
|
||||
return Error( "No such book!" );
|
||||
|
||||
string original = GetDataDirectory( ) + new_uuid + ".jpg";
|
||||
|
||||
using SKData bitmap_data = bitmap.Encode( SKEncodedImageFormat.Jpeg , 80 );
|
||||
byte [] bitmap_data_array = bitmap_data.ToArray( );
|
||||
System.IO.File.WriteAllBytes( original , bitmap_data_array );
|
||||
|
||||
return Success( new_uuid );
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult SavePDFAttachment( string? session , long offset , int id )
|
||||
{
|
||||
if ( session == null )
|
||||
return Error( "Invalid call. (Invalid parameters)" );
|
||||
|
||||
if ( !ValidateOffset( session , offset ) )
|
||||
return Error( "Invalid call. (Bad offset)" );
|
||||
|
||||
byte [] ? pdf_data_array = PreprocessPDF( m_TempDirectory + session! );
|
||||
if ( pdf_data_array == null )
|
||||
return Error( "Invalid file" );
|
||||
|
||||
SqlDataReader reader = PrepareSQL(@"update gnm_rec set uuid = REPLACE(NEWID( ),'-',''),data_format='pdf' OUTPUT INSERTED.uuid WHERE id = @id")
|
||||
.AddParameter( "@id" , id )
|
||||
.ExecuteReader( );
|
||||
|
||||
if ( !reader.Read( ) )
|
||||
return Error( "No such attachment!" );
|
||||
|
||||
string? new_uuid = reader.String( 0 );
|
||||
if ( string.IsNullOrEmpty( new_uuid ) )
|
||||
return Error( "No such attachment!" );
|
||||
|
||||
string original = GetDataDirectory( ) + new_uuid + ".pdf";
|
||||
System.IO.File.WriteAllBytes( original , pdf_data_array );
|
||||
|
||||
return Success( new_uuid );
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IActionResult SaveImageAttachment( string? session , long offset , int id )
|
||||
{
|
||||
if ( session == null )
|
||||
return Error( "Invalid call. (Invalid parameters)" );
|
||||
|
||||
if ( !ValidateOffset( session , offset ) )
|
||||
return Error( "Invalid call. (Bad offset)" );
|
||||
|
||||
using SKBitmap? bitmap = PreprocessImage( m_TempDirectory + session! );
|
||||
if ( bitmap == null )
|
||||
return Error( "Invalid image" );
|
||||
|
||||
SqlDataReader reader = PrepareSQL(@"update gnm_rec set uuid = REPLACE(NEWID( ),'-',''),data_format='jpg' OUTPUT INSERTED.uuid WHERE id = @id")
|
||||
.AddParameter( "@id" , id )
|
||||
.ExecuteReader( );
|
||||
|
||||
if ( !reader.Read( ) )
|
||||
return Error( "No such attachment!" );
|
||||
|
||||
string? new_uuid = reader.String( 0 );
|
||||
if ( string.IsNullOrEmpty( new_uuid ) )
|
||||
return Error( "No such attachment!" );
|
||||
|
||||
string original = GetDataDirectory( ) + new_uuid + ".jpg";
|
||||
|
||||
using SKData bitmap_data = bitmap.Encode( SKEncodedImageFormat.Jpeg , 80 );
|
||||
byte [] bitmap_data_array = bitmap_data.ToArray( );
|
||||
System.IO.File.WriteAllBytes( original , bitmap_data_array );
|
||||
|
||||
return Success( new_uuid );
|
||||
}
|
||||
|
||||
private static byte[]? Base64DecodeSafe( string? b )
|
||||
{
|
||||
if ( b == null )
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
return Convert.FromBase64String( b! );
|
||||
}
|
||||
catch ( Exception )
|
||||
{
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool ValidateOffset( string session , long expected )
|
||||
{
|
||||
try
|
||||
{
|
||||
FileInfo fi = new( m_TempDirectory + session );
|
||||
return fi.Length == expected;
|
||||
}
|
||||
catch ( Exception )
|
||||
{
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static SKBitmap? PreprocessImage( string local_file )
|
||||
{
|
||||
SKBitmap? bitmap = SKBitmap.Decode( local_file );
|
||||
if ( bitmap == null )
|
||||
{
|
||||
bitmap = ConvertTiffToSKBitmap( local_file );
|
||||
if ( bitmap == null )
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( bitmap!.IsEmpty || bitmap.IsNull || bitmap.Width < 16 || bitmap.Height < 16 )
|
||||
return null;
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
private static SKBitmap? ConvertTiffToSKBitmap( string local_file )
|
||||
{
|
||||
SKColor[] pixels;
|
||||
int width, height;
|
||||
// open a Tiff stored in the memory stream, and grab its pixels
|
||||
using ( Tiff tifImg = Tiff.ClientOpen( local_file , "r" , null , new TiffStream( ) ) )
|
||||
{
|
||||
FieldValue[] value = tifImg.GetField(TiffTag.IMAGEWIDTH);
|
||||
width = value[0].ToInt( );
|
||||
|
||||
value = tifImg.GetField( TiffTag.IMAGELENGTH );
|
||||
height = value[0].ToInt( );
|
||||
|
||||
// Read the image into the memory buffer
|
||||
int[] raster = new int[width * height];
|
||||
if ( !tifImg.ReadRGBAImageOriented( width , height , raster , Orientation.TOPLEFT ) )
|
||||
{
|
||||
// Not a valid TIF image.
|
||||
}
|
||||
// store the pixels
|
||||
pixels = new SKColor[width * height];
|
||||
for ( int y = 0 ; y < height ; y++ )
|
||||
{
|
||||
for ( int x = 0 ; x < width ; x++ )
|
||||
{
|
||||
int arrayOffset = y * width + x;
|
||||
int rgba = raster[arrayOffset];
|
||||
pixels[arrayOffset] = new SKColor( (byte)Tiff.GetR( rgba ) , (byte)Tiff.GetG( rgba ) , (byte)Tiff.GetB( rgba ) , (byte)Tiff.GetA( rgba ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new SKBitmap( width , height )
|
||||
{
|
||||
Pixels = pixels
|
||||
};
|
||||
}
|
||||
|
||||
private static byte[]? PreprocessPDF( string form_file )
|
||||
{
|
||||
byte[] file_bytes = System.IO.File.ReadAllBytes( form_file );
|
||||
if ( file_bytes.Length < 10 )
|
||||
return null;
|
||||
|
||||
if ( file_bytes[0] != (byte)'%' || file_bytes[1] != (byte)'P' || file_bytes[2] != 'D' || file_bytes[3] != 'F' )
|
||||
return null;
|
||||
|
||||
return file_bytes;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user