Pdf Import Rewrite

Pdf Import rewritten to greatly improve QR Code detection, reduce
reliance on iTextSharp and improve thumbnails. Fixes #50
This commit is contained in:
Gary Sharp
2016-08-26 09:46:35 +10:00
parent 44f6d325db
commit 5ea9a814d6
98 changed files with 3168 additions and 3202 deletions
-102
View File
@@ -1,102 +0,0 @@
using Disco.BI.Extensions;
using Exceptionless;
using iTextSharp.text.pdf;
using System;
using System.Drawing;
using System.IO;
using System.Linq;
namespace Disco.BI.AttachmentBI
{
public static class Utilities
{
public static bool GenerateThumbnail(Stream Source, string SourceMimeType, Stream OutStream)
{
if (Source != null)
{
// GDI+ (jpg, png, gif, bmp)
if (SourceMimeType.Equals("image/jpeg", StringComparison.OrdinalIgnoreCase) || SourceMimeType.Contains("jpg") ||
SourceMimeType.Equals("image/png", StringComparison.OrdinalIgnoreCase) || SourceMimeType.Contains("png") ||
SourceMimeType.Equals("image/gif", StringComparison.OrdinalIgnoreCase) || SourceMimeType.Contains("gif") ||
SourceMimeType.Equals("image/bmp", StringComparison.OrdinalIgnoreCase) || SourceMimeType.Contains("bmp"))
{
try
{
using (Image sourceImage = Image.FromStream(Source))
{
using (Image thumbImage = sourceImage.ResizeImage(48, 48))
{
using (Image mimeTypeIcon = Disco.Properties.Resources.MimeType_img16)
thumbImage.EmbedIconOverlay(mimeTypeIcon);
thumbImage.SaveJpg(90, OutStream);
return true;
}
}
}
catch (Exception ex)
{
ex.ToExceptionless().Submit();
// Ignore Thumbnail Generation exceptions for images
}
}
// PDF
if (SourceMimeType.Equals("application/pdf", StringComparison.OrdinalIgnoreCase) || SourceMimeType.Contains("pdf"))
{
PdfReader pdfReader = new PdfReader(Source);
try
{
using (DisposableImageCollection pdfPageImages = pdfReader.PdfPageImages(1))
{
if (pdfPageImages.Count() > 0)
{
// Find Biggest Image on Page
Image biggestImage = pdfPageImages.OrderByDescending(i => i.Height * i.Width).First();
using (Image thumbImage = biggestImage.ResizeImage(48, 48, Brushes.White))
{
using (Image mimeTypeIcon = Disco.Properties.Resources.MimeType_pdf16)
thumbImage.EmbedIconOverlay(mimeTypeIcon);
thumbImage.SaveJpg(90, OutStream);
return true;
}
}
}
}
catch (Exception ex)
{
ex.ToExceptionless().Submit();
}
finally
{
if (pdfReader != null)
pdfReader.Close();
}
}
}
return false;
}
public static bool GenerateThumbnail(string SourceFilename, string SourceMimeType, string DestinationFilename)
{
using (FileStream sourceStream = new FileStream(SourceFilename, FileMode.Open, FileAccess.Read))
{
return GenerateThumbnail(sourceStream, SourceMimeType, DestinationFilename);
}
}
public static bool GenerateThumbnail(Stream Source, string SourceMimeType, string DestinationFilename)
{
bool result;
using (FileStream destinationStream = new FileStream(DestinationFilename, FileMode.Create, FileAccess.Write, FileShare.None))
{
result = GenerateThumbnail(Source, SourceMimeType, destinationStream);
}
if (!result && File.Exists(DestinationFilename))
File.Delete(DestinationFilename);
return result;
}
}
}
-31
View File
@@ -1,31 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Disco.Data.Repository;
using Disco.Data.Configuration;
namespace Disco.BI
{
public static class DataStore
{
public static string CreateLocation(DiscoDataContext Database, string SubLocation, DateTime? SubSubLocationTimestamp = null)
{
return CreateLocation(Database.DiscoConfiguration, SubLocation, SubSubLocationTimestamp);
}
public static string CreateLocation(SystemConfiguration DiscoConfiguration, string SubLocation, DateTime? SubSubLocationTimestamp = null)
{
string SubSubLocation = string.Empty;
if (SubSubLocationTimestamp.HasValue)
SubSubLocation = SubSubLocationTimestamp.Value.ToString(@"yyyy\\MM");
string storeDirectory = System.IO.Path.Combine(DiscoConfiguration.DataStoreLocation, SubLocation, SubSubLocation);
if (!System.IO.Directory.Exists(storeDirectory))
System.IO.Directory.CreateDirectory(storeDirectory);
return storeDirectory;
}
}
}
@@ -1,78 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Concurrent;
using Disco.Models.Repository;
using Disco.Data.Repository;
using Disco.BI.Extensions;
using System.Web;
using System.Drawing;
using iTextSharp.text.pdf;
namespace Disco.BI.DocumentTemplateBI
{
class DocumentTemplateQRCodeLocationCache
{
private static ConcurrentDictionary<string, List<RectangleF>> _Cache = new ConcurrentDictionary<string, List<RectangleF>>();
public static List<RectangleF> GetLocations(DocumentTemplate dt, DiscoDataContext Database)
{
// Check Cache
List<RectangleF> locations;
if (_Cache.TryGetValue(dt.Id, out locations))
{
return locations;
}
// Generate Cache
return GenerateLocations(dt, Database);
}
public static bool InvalidateLocations(DocumentTemplate dt)
{
List<RectangleF> locations;
return _Cache.TryRemove(dt.Id, out locations);
}
private static bool SetValue(string DocumentTemplateId, List<RectangleF> Locations)
{
if (_Cache.ContainsKey(DocumentTemplateId))
{
List<RectangleF> oldLocations;
if (_Cache.TryGetValue(DocumentTemplateId, out oldLocations))
{
return _Cache.TryUpdate(DocumentTemplateId, Locations, oldLocations);
}
}
return _Cache.TryAdd(DocumentTemplateId, Locations);
}
internal static List<RectangleF> GenerateLocations(DocumentTemplate dt, DiscoDataContext Database)
{
string templateFilename = dt.RepositoryFilename(Database);
PdfReader pdfReader = new PdfReader(templateFilename);
List<RectangleF> locations = new List<RectangleF>();
if (pdfReader.AcroFields.Fields.ContainsKey("DiscoAttachmentId"))
{
foreach (var pdfFieldPosition in pdfReader.AcroFields.GetFieldPositions("DiscoAttachmentId"))
{
var pdfPageSize = pdfReader.GetPageSize(pdfFieldPosition.page);
// Original Position
locations.Add(new RectangleF(
(float)System.Math.Min(1.0, System.Math.Max(0.0, (double)(pdfFieldPosition.position.Left / pdfPageSize.Width) - 0.05)),
(float)System.Math.Min(1.0, System.Math.Max(0.0, (double)((pdfPageSize.Height - pdfFieldPosition.position.Top) / pdfPageSize.Height) - 0.05)),
(float)System.Math.Min(1.0, System.Math.Max(0.0, (double)(pdfFieldPosition.position.Width / pdfPageSize.Width) + 0.1)),
(float)System.Math.Min(1.0, System.Math.Max(0.0, (double)(pdfFieldPosition.position.Height / pdfPageSize.Height) + 0.1))
));
}
}
pdfReader.Close();
// Update Cache
SetValue(dt.Id, locations);
return locations;
}
}
}
@@ -1,204 +0,0 @@
using Disco.Data.Repository;
using Disco.Models.Repository;
using Disco.Services.Interop.ActiveDirectory;
using System;
namespace Disco.BI.DocumentTemplateBI
{
public class DocumentUniqueIdentifier
{
private bool? _loadedComponentsOk;
private DocumentTemplate _documentTemplate;
private object _data;
private string _dataDescription;
public string TemplateTypeId { get; private set; }
public string DataId { get; private set; }
public string DocumentUniqueId
{
get
{
return string.Format("{0}|{1}", this.TemplateTypeId, this.DataId);
}
}
public string CreatorId { get; private set; }
public System.DateTime TimeStamp { get; private set; }
public int Page { get; private set; }
public string Tag { get; private set; }
public DocumentTemplate DocumentTemplate
{
get
{
bool flag = this._loadedComponentsOk.HasValue && this._loadedComponentsOk.Value;
if (flag)
{
return this._documentTemplate;
}
throw new System.Exception("Document Unique Identifier Components not loaded or invalid");
}
}
public object Data
{
get
{
bool flag = this._loadedComponentsOk.HasValue && this._loadedComponentsOk.Value;
if (flag)
{
return this._data;
}
throw new System.Exception("Document Unique Identifier Components not loaded or invalid");
}
}
public string DataDescription
{
get
{
bool flag = this._loadedComponentsOk.HasValue && this._loadedComponentsOk.Value;
if (flag)
{
return this._dataDescription;
}
throw new System.Exception("Document Unique Identifier Components not loaded or invalid");
}
}
public string DataScope { get; private set; }
public static bool IsDocumentUniqueIdentifier(string UniqueIdentifier)
{
return UniqueIdentifier.StartsWith("Disco|", System.StringComparison.OrdinalIgnoreCase);
}
public DocumentUniqueIdentifier(string TemplateTypeId, string DataId, string CreatorId, DateTime TimeStamp, int? Page = null, string Tag = null)
{
this.Tag = Tag;
this.TemplateTypeId = TemplateTypeId;
this.DataId = DataId;
this.CreatorId = ActiveDirectory.ParseDomainAccountId(CreatorId);
this.TimeStamp = TimeStamp;
this.Page = Page ?? 0;
}
public DocumentUniqueIdentifier(string UniqueIdentifier, string Tag)
{
if (!DocumentUniqueIdentifier.IsDocumentUniqueIdentifier(UniqueIdentifier))
{
throw new System.ArgumentException("Invalid Document Unique Identifier", "UniqueIdentifier");
}
this.Tag = Tag;
string[] s = UniqueIdentifier.Split(new char[] { '|' });
string left = s[1].ToUpper();
if (left == "AT" || left == "1")
{
if (s.Length >= 3)
{
this.TemplateTypeId = s[2];
}
if (s.Length >= 4)
{
this.DataId = s[3];
}
if (s.Length >= 5)
{
this.CreatorId = ActiveDirectory.ParseDomainAccountId(s[4]);
}
if (s.Length >= 6)
{
System.DateTime timeStamp;
if (System.DateTime.TryParse(s[5], out timeStamp))
{
this.TimeStamp = timeStamp;
}
}
if (s.Length >= 7)
{
int page = 0;
if (int.TryParse(s[6], out page))
{
this.Page = page;
}
}
return;
}
throw new System.ArgumentException(string.Format("Invalid Document Unique Identifier Version ({0})", s[1]), "UniqueIdentifier");
}
public bool LoadComponents(DiscoDataContext Database)
{
bool LoadComponents;
if (!this._loadedComponentsOk.HasValue)
{
string scopeType;
if (this.TemplateTypeId.StartsWith("--"))
{
string templateTypeId = this.TemplateTypeId;
switch (this.TemplateTypeId)
{
case "--DEVICE":
scopeType = DocumentTemplate.DocumentTemplateScopes.Device;
break;
case "--JOB":
scopeType = DocumentTemplate.DocumentTemplateScopes.Job;
break;
case "--USER":
scopeType = DocumentTemplate.DocumentTemplateScopes.User;
break;
default:
scopeType = null;
break;
}
}
else
{
this._documentTemplate = Database.DocumentTemplates.Find(this.TemplateTypeId);
if (this._documentTemplate != null)
{
scopeType = this._documentTemplate.Scope;
}
else
{
scopeType = null;
}
}
if (scopeType != null)
{
this.DataScope = scopeType;
switch (scopeType)
{
case DocumentTemplate.DocumentTemplateScopes.Device:
Device d = Database.Devices.Find(this.DataId);
if (d != null)
{
this._data = d;
this._dataDescription = d.SerialNumber;
this._loadedComponentsOk = true;
LoadComponents = true;
return LoadComponents;
}
break;
case DocumentTemplate.DocumentTemplateScopes.Job:
Job i = Database.Jobs.Find(int.Parse(this.DataId));
if (i != null)
{
this._data = i;
this._dataDescription = i.Id.ToString();
this._loadedComponentsOk = true;
LoadComponents = true;
return LoadComponents;
}
break;
case DocumentTemplate.DocumentTemplateScopes.User:
User u = Database.Users.Find(ActiveDirectory.ParseDomainAccountId(this.DataId));
if (u != null)
{
this._data = u;
this._dataDescription = u.DisplayName;
this._loadedComponentsOk = true;
LoadComponents = true;
return LoadComponents;
}
break;
default:
break;
}
}
this._loadedComponentsOk = false;
}
LoadComponents = this._loadedComponentsOk.Value;
return LoadComponents;
}
}
}
@@ -1,478 +0,0 @@
using Disco.Models.Repository;
using Disco.Services.Logging;
using Disco.Services.Logging.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace Disco.BI.DocumentTemplateBI
{
public class DocumentsLog : LogBase
{
public enum EventTypeIds
{
ImportStarting = 10,
ImportProgress,
ImportFinished,
ImportWarning = 15,
ImportError,
ImportAttachmentExpressionEvaluated = 50,
ImportPageStarting = 100,
ImportPageImageUpdate = 104,
ImportPageProgress,
ImportPageDetected = 110,
ImportPageUndetected = 115,
ImportPageError = 120,
ImportPageUndetectedStored = 150,
DocumentGenerated = 500,
DocumentGeneratedWithExpression
}
private const int _ModuleId = 40;
public static DocumentsLog Current
{
get
{
return (DocumentsLog)LogContext.LogModules[_ModuleId];
}
}
public override string ModuleDescription
{
get
{
return "Documents";
}
}
public override int ModuleId
{
get
{
return _ModuleId;
}
}
public override string ModuleName
{
get
{
return "Documents";
}
}
private static void Log(DocumentsLog.EventTypeIds EventTypeId, params object[] Args)
{
DocumentsLog.Current.Log((int)EventTypeId, Args);
}
public static void LogImportStarting(string SessionId, string DocumentName)
{
DocumentsLog.Log(DocumentsLog.EventTypeIds.ImportStarting, new object[]
{
SessionId,
DocumentName
});
}
public static void LogImportProgress(string SessionId, int? Progress, string Status)
{
DocumentsLog.Log(DocumentsLog.EventTypeIds.ImportProgress, new object[]
{
SessionId,
Progress,
Status
});
}
public static void LogImportFinished(string SessionId)
{
DocumentsLog.Log(DocumentsLog.EventTypeIds.ImportFinished, new object[]
{
SessionId
});
}
public static void LogImportWarning(string SessionId, string Message)
{
DocumentsLog.Log(DocumentsLog.EventTypeIds.ImportWarning, new object[]
{
SessionId,
Message
});
}
public static void LogImportError(string SessionId, string Message)
{
DocumentsLog.Log(DocumentsLog.EventTypeIds.ImportError, new object[]
{
SessionId,
Message
});
}
public static void LogImportAttachmentExpressionEvaluated(DocumentTemplate template, Device device, DeviceAttachment attachment, string Result)
{
DocumentsLog.Log(DocumentsLog.EventTypeIds.ImportAttachmentExpressionEvaluated, new object[]
{
template.Id,
device.SerialNumber,
attachment.Id,
Result
});
}
public static void LogImportAttachmentExpressionEvaluated(DocumentTemplate template, Job job, JobAttachment attachment, string Result)
{
DocumentsLog.Log(DocumentsLog.EventTypeIds.ImportAttachmentExpressionEvaluated, new object[]
{
template.Id,
job.Id,
attachment.Id,
Result
});
}
public static void LogImportAttachmentExpressionEvaluated(DocumentTemplate template, User user, UserAttachment attachment, string Result)
{
DocumentsLog.Log(DocumentsLog.EventTypeIds.ImportAttachmentExpressionEvaluated, new object[]
{
template.Id,
user.UserId,
attachment.Id,
Result
});
}
public static void LogImportAttachmentExpressionEvaluated(DocumentTemplate Template, object Data, object Attachment, string Result)
{
if (Data is Job)
LogImportAttachmentExpressionEvaluated(Template, (Job)Data, (JobAttachment)Attachment, Result);
else if (Data is User)
LogImportAttachmentExpressionEvaluated(Template, (User)Data, (UserAttachment)Attachment, Result);
else if (Data is Device)
LogImportAttachmentExpressionEvaluated(Template, (Device)Data, (DeviceAttachment)Attachment, Result);
else
DocumentsLog.Log(DocumentsLog.EventTypeIds.ImportAttachmentExpressionEvaluated, new object[]
{
Template.Id,
Data.ToString(),
Attachment.ToString(),
Result
});
}
public static void LogImportPageStarting(string SessionId, int PageNumber)
{
DocumentsLog.Log(DocumentsLog.EventTypeIds.ImportPageStarting, new object[]
{
SessionId,
PageNumber
});
}
public static void LogImportPageImageUpdate(string SessionId, int PageNumber)
{
DocumentsLog.Log(DocumentsLog.EventTypeIds.ImportPageImageUpdate, new object[]
{
SessionId,
PageNumber
});
}
public static void LogImportPageProgress(string SessionId, int PageNumber, int? Progress, string Status)
{
DocumentsLog.Log(DocumentsLog.EventTypeIds.ImportPageProgress, new object[]
{
SessionId,
PageNumber,
Progress,
Status
});
}
public static void LogImportPageDetected(string SessionId, int PageNumber, string DocumentTypeId, string DocumentTypeName, string TargetType, string AssignedId, string AssignedName)
{
DocumentsLog.Log(DocumentsLog.EventTypeIds.ImportPageDetected, new object[]
{
SessionId,
PageNumber,
DocumentTypeId,
DocumentTypeName,
TargetType,
AssignedId,
AssignedName
});
}
public static void LogImportPageUndetected(string SessionId, int PageNumber)
{
DocumentsLog.Log(DocumentsLog.EventTypeIds.ImportPageUndetected, new object[]
{
SessionId,
PageNumber
});
}
public static void LogImportPageError(string SessionId, int PageNumber, string Message)
{
DocumentsLog.Log(DocumentsLog.EventTypeIds.ImportPageError, new object[]
{
SessionId,
PageNumber,
Message
});
}
public static void LogImportPageUndetectedStored(string SessionId, int PageNumber)
{
DocumentsLog.Log(DocumentsLog.EventTypeIds.ImportPageUndetectedStored, new object[]
{
SessionId,
PageNumber
});
}
public static void LogDocumentGenerated(DocumentTemplate Template, Device Device, User Author, string ExpressionResult)
{
DocumentsLog.Log(DocumentsLog.EventTypeIds.DocumentGeneratedWithExpression, new object[]
{
Template.Id,
Device.SerialNumber,
Author.UserId,
ExpressionResult
});
}
public static void LogDocumentGenerated(DocumentTemplate Template, Job Job, User Author, string ExpressionResult)
{
DocumentsLog.Log(DocumentsLog.EventTypeIds.DocumentGeneratedWithExpression, new object[]
{
Template.Id,
Job.Id,
Author.UserId,
ExpressionResult
});
}
public static void LogDocumentGenerated(DocumentTemplate Template, User User, User Author, string ExpressionResult)
{
DocumentsLog.Log(DocumentsLog.EventTypeIds.DocumentGeneratedWithExpression, new object[]
{
Template.Id,
User.UserId,
Author.UserId,
ExpressionResult
});
}
public static void LogDocumentGenerated(DocumentTemplate Template, object Data, User Author, string ExpressionResult)
{
if (Data is Job)
LogDocumentGenerated(Template, (Job)Data, Author, ExpressionResult);
else if (Data is User)
LogDocumentGenerated(Template, (User)Data, Author, ExpressionResult);
else if (Data is Device)
LogDocumentGenerated(Template, (Device)Data, Author, ExpressionResult);
else
DocumentsLog.Log(DocumentsLog.EventTypeIds.DocumentGeneratedWithExpression, new object[]
{
Template.Id,
"UNKNOWN",
Author.UserId,
ExpressionResult
});
}
public static void LogDocumentGenerated(DocumentTemplate Template, Device Device, User Author)
{
DocumentsLog.Log(DocumentsLog.EventTypeIds.DocumentGenerated, new object[]
{
Template.Id,
Device.SerialNumber,
Author.UserId
});
}
public static void LogDocumentGenerated(DocumentTemplate Template, Job Job, User Author)
{
DocumentsLog.Log(DocumentsLog.EventTypeIds.DocumentGenerated, new object[]
{
Template.Id,
Job.Id,
Author.UserId
});
}
public static void LogDocumentGenerated(DocumentTemplate Template, User User, User Author)
{
DocumentsLog.Log(DocumentsLog.EventTypeIds.DocumentGenerated, new object[]
{
Template.Id,
User.UserId,
Author.UserId
});
}
public static void LogDocumentGenerated(DocumentTemplate Template, object Data, User Author)
{
if (Data is Job)
LogDocumentGenerated(Template, (Job)Data, Author);
else if (Data is User)
LogDocumentGenerated(Template, (User)Data, Author);
else if (Data is Device)
LogDocumentGenerated(Template, (Device)Data, Author);
else
DocumentsLog.Log(DocumentsLog.EventTypeIds.DocumentGenerated, new object[]
{
Template.Id,
"UNKNOWN",
Author.UserId
});
}
protected override System.Collections.Generic.List<LogEventType> LoadEventTypes()
{
return new System.Collections.Generic.List<LogEventType>
{
new LogEventType
{
Id = (int)EventTypeIds.ImportStarting,
ModuleId = _ModuleId,
Name = "Import Starting",
Format = "Starting import of document: {1} (SessionId: {0})",
Severity = (int)LogEventType.Severities.Information,
UseLive = true,
UsePersist = true,
UseDisplay = true
},
new LogEventType
{
Id = (int)EventTypeIds.ImportProgress,
ModuleId = _ModuleId,
Name = "Import Progress",
Format = "Processing: {1}% Complete; Status: {2}",
Severity = (int)LogEventType.Severities.Information,
UseLive = true,
UsePersist = false,
UseDisplay = false
},
new LogEventType
{
Id = (int)EventTypeIds.ImportFinished,
ModuleId = _ModuleId,
Name = "Import Finished",
Format = "Import of document complete (SessionId: {0})",
Severity = (int)LogEventType.Severities.Information,
UseLive = true,
UsePersist = true,
UseDisplay = true
},
new LogEventType
{
Id = (int)EventTypeIds.ImportWarning,
ModuleId = _ModuleId,
Name = "Import Warning",
Format = "Import Warning: {1} (SessionId: {0})",
Severity = (int)LogEventType.Severities.Warning,
UseLive = true,
UsePersist = true,
UseDisplay = true
},
new LogEventType
{
Id = (int)EventTypeIds.ImportError,
ModuleId = _ModuleId,
Name = "Import Error",
Format = "Import Error: {1} (SessionId: {0})",
Severity = (int)LogEventType.Severities.Error,
UseLive = true,
UsePersist = true,
UseDisplay = true
},
new LogEventType
{
Id = (int)EventTypeIds.ImportAttachmentExpressionEvaluated,
ModuleId = _ModuleId,
Name = "Import Attachment Expression Evaluated",
Format = "The import attachment expression for '{0}' was evaluated for '{1}' (attachment id: {2}) with the result: {3}",
Severity = (int)LogEventType.Severities.Information,
UseLive = true,
UsePersist = true,
UseDisplay = true
},
new LogEventType
{
Id = (int)EventTypeIds.ImportPageStarting,
ModuleId = _ModuleId,
Name = "Import Page Starting",
Format = "Starting import of page: {1} (SessionId: {0})",
Severity = (int)LogEventType.Severities.Information,
UseLive = true,
UsePersist = true,
UseDisplay = true
},
new LogEventType
{
Id = (int)EventTypeIds.ImportPageImageUpdate,
ModuleId = _ModuleId,
Name = "Import Page Image Update",
Format = null,
Severity = (int)LogEventType.Severities.Information,
UseLive = true,
UsePersist = false,
UseDisplay = false
},
new LogEventType
{
Id = (int)EventTypeIds.ImportPageProgress,
ModuleId = _ModuleId,
Name = "Import Page Progress",
Format = "Processing: Page {1}; {2}% Complete; Status: {3}",
Severity = (int)LogEventType.Severities.Information,
UseLive = true,
UsePersist = false,
UseDisplay = false
},
new LogEventType
{
Id = (int)EventTypeIds.ImportPageDetected,
ModuleId = _ModuleId,
Name = "Import Page Assigned",
Format = "Page {1} of type '{3}' assigned to {4}: '{6}'",
Severity = (int)LogEventType.Severities.Information,
UseLive = true,
UsePersist = true,
UseDisplay = true
},
new LogEventType
{
Id = (int)EventTypeIds.ImportPageUndetected,
ModuleId = _ModuleId,
Name = "Import Page Undetected",
Format = "Page {1} not detected",
Severity = (int)LogEventType.Severities.Warning,
UseLive = true,
UsePersist = true,
UseDisplay = true
},
new LogEventType
{
Id = (int)EventTypeIds.ImportPageError,
ModuleId = _ModuleId,
Name = "Import Page Error",
Format = "Page {1}, Import Error: {2}",
Severity = (int)LogEventType.Severities.Error,
UseLive = true,
UsePersist = true,
UseDisplay = true
},
new LogEventType
{
Id = (int)EventTypeIds.ImportPageUndetectedStored,
ModuleId = _ModuleId,
Name = "Import Page Undetected Stored",
Format = null,
Severity = (int)LogEventType.Severities.Information,
UseLive = true,
UsePersist = false,
UseDisplay = false
},
new LogEventType
{
Id = (int)EventTypeIds.DocumentGenerated,
ModuleId = _ModuleId,
Name = "Document Generated",
Format = "A '{0}' document was generated for '{1}' by '{2}'",
Severity = (int)LogEventType.Severities.Information,
UseLive = true,
UsePersist = true,
UseDisplay = true
},
new LogEventType
{
Id = (int)EventTypeIds.DocumentGeneratedWithExpression,
ModuleId = _ModuleId,
Name = "Document Generated with Expression",
Format = "A '{0}' document was generated for '{1}' by '{2}'. The expression returned: {3}",
Severity = (int)LogEventType.Severities.Information,
UseLive = true,
UsePersist = true,
UseDisplay = true
}
};
}
}
}
@@ -1,85 +0,0 @@
using System;
using System.IO;
using System.Web.Caching;
using Disco.Data.Repository;
using Quartz;
using Quartz.Impl;
using Quartz.Impl.Triggers;
namespace Disco.BI.DocumentTemplateBI.Importer
{
public class DocumentDropBoxMonitor : System.IDisposable
{
private IScheduler _scheduler;
private FileSystemWatcher _fsw;
private Cache _httpCache;
public const string WatcherFilter = "*.pdf";
public string DropBoxLocation { get; private set; }
public DocumentDropBoxMonitor(DiscoDataContext Database, ISchedulerFactory SchedulerFactory, Cache HttpCache)
{
if (Database == null)
throw new System.ArgumentNullException("Context");
this._httpCache = HttpCache;
var location = DataStore.CreateLocation(Database, "DocumentDropBox");
this.DropBoxLocation = location.EndsWith(@"\") ? location : string.Concat(location, @"\");
this._scheduler = SchedulerFactory.GetScheduler();
this._scheduler.Start();
}
public void ScheduleCurrentFiles(int Delay)
{
foreach (var filename in System.IO.Directory.GetFiles(this.DropBoxLocation, "*.pdf"))
{
this.ScheduleFile(filename, Delay);
}
}
public void StartWatching()
{
if (this._fsw == null)
{
this._fsw = new FileSystemWatcher(this.DropBoxLocation, "*.pdf");
this._fsw.Created += new FileSystemEventHandler(this.FSW_Created);
}
this._fsw.EnableRaisingEvents = true;
}
public void StopWatching()
{
if (this._fsw != null)
{
this._fsw.EnableRaisingEvents = false;
}
}
public void ScheduleFile(string Filename, int Delay)
{
System.Guid guid = System.Guid.NewGuid();
JobDetailImpl jd = new JobDetailImpl(guid.ToString(), typeof(DocumentImporterJob));
jd.JobDataMap.Add("Filename", Filename);
jd.JobDataMap.Add("RetryCount", 0);
jd.JobDataMap.Add("HttpCache", this._httpCache);
guid = System.Guid.NewGuid();
System.DateTimeOffset startTimeUtc = new System.DateTimeOffset(DateTime.Now.AddSeconds((double)Delay));
SimpleTriggerImpl trig = new SimpleTriggerImpl(guid.ToString(), startTimeUtc);
this._scheduler.ScheduleJob(jd, trig);
}
private void FSW_Created(object sender, FileSystemEventArgs e)
{
if ((e.ChangeType & WatcherChangeTypes.Deleted) != WatcherChangeTypes.Deleted)
this.ScheduleFile(e.FullPath, 5);
}
public void Dispose()
{
this.StopWatching();
if (this._fsw != null)
this._fsw.Dispose();
if (this._scheduler != null)
this._scheduler.Shutdown(false);
}
}
}
@@ -1,64 +0,0 @@
using Disco.Data.Repository;
using Disco.Services.Logging;
using Quartz;
using Quartz.Impl;
using Disco.Services.Tasks;
namespace Disco.BI.DocumentTemplateBI.Importer
{
public class DocumentImporterCleanCacheJob : ScheduledTask
{
public override string TaskName { get { return "Document Importer - Clean Cache Task"; } }
public override bool SingleInstanceTask { get { return true; } }
public override bool CancelInitiallySupported { get { return false; } }
public override bool LogExceptionsOnly { get { return true; } }
public override void InitalizeScheduledTask(DiscoDataContext Database)
{
// Trigger Daily @ 12:30am
TriggerBuilder triggerBuilder = TriggerBuilder.Create().WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(0, 30));
this.ScheduleTask(triggerBuilder);
}
protected override void ExecuteTask()
{
string dataStoreLocation;
using (DiscoDataContext database = new DiscoDataContext())
{
dataStoreLocation = DataStore.CreateLocation(database, "Cache\\DocumentDropBox_SessionPages");
}
int deleteCount = 0;
int errorCount = 0;
System.IO.DirectoryInfo dataStoreInfo = new System.IO.DirectoryInfo(dataStoreLocation);
System.DateTime today = System.DateTime.Today;
foreach (System.IO.FileInfo file in dataStoreInfo.GetFiles())
{
try
{
if (file.CreationTime < today)
{
file.Delete();
deleteCount++;
}
}
catch
{
errorCount++;
}
}
SystemLog.LogInformation(
string.Format("Cleared DocumentDropBox_SessionPages Cache, Deleted {0} File/s, with {1} Error/s", deleteCount, errorCount),
deleteCount,
errorCount
);
}
}
}
@@ -1,123 +0,0 @@
using Disco.Data.Repository;
using Exceptionless;
using Quartz;
using Quartz.Impl.Triggers;
using System;
using System.IO;
using System.Web.Caching;
namespace Disco.BI.DocumentTemplateBI.Importer
{
[PersistJobDataAfterExecution]
public class DocumentImporterJob : IJob
{
void IJob.Execute(IJobExecutionContext context)
{
string sessionId = context.JobDetail.JobDataMap["SessionId"] as string;
if (string.IsNullOrEmpty(sessionId))
{
sessionId = Guid.NewGuid().ToString();
context.JobDetail.JobDataMap["SessionId"] = sessionId;
}
string filename = context.JobDetail.JobDataMap["Filename"] as string;
int retryCount = (int)context.JobDetail.JobDataMap["RetryCount"];
Cache httpCache = context.JobDetail.JobDataMap["HttpCache"] as Cache;
var friendlyFilename = filename;
if (!string.IsNullOrEmpty(friendlyFilename))
friendlyFilename = System.IO.Path.GetFileName(friendlyFilename);
DocumentsLog.LogImportStarting(sessionId, friendlyFilename);
if (!File.Exists(filename))
{
DocumentsLog.LogImportWarning(sessionId, string.Format("File not found: {0}", filename));
DocumentsLog.LogImportFinished(sessionId);
context.Scheduler.DeleteJob(context.JobDetail.Key);
return;
}
try
{
using (DiscoDataContext database = new DiscoDataContext())
{
if (retryCount < 18)
{
context.JobDetail.JobDataMap["RetryCount"] = (++retryCount);
bool processResult = Interop.Pdf.PdfImporter.ProcessPdfAttachment(filename, database, sessionId, httpCache);
if (processResult)
{
// Import Successful - Delete
if (File.Exists(filename))
File.Delete(filename);
}
else
{
// Import Failed - Move to Errors Folder
if (File.Exists(filename))
{
try
{
string folderError = DataStore.CreateLocation(database, "DocumentDropBox_Errors");
string filenameError = Path.Combine(folderError, Path.GetFileName(filename));
int filenameErrorCount = 0;
while (File.Exists(filenameError))
{
filenameError = Path.Combine(folderError, string.Format("{0} ({1}){2}", Path.GetFileNameWithoutExtension(filename), ++filenameErrorCount, Path.GetExtension(filename)));
}
File.Move(filename, filenameError);
}
catch (Exception ex)
{
ex.ToExceptionless().Submit();
// Ignore Errors
}
}
}
}
else
{
// To Many Errors
DocumentsLog.LogImportError(sessionId, string.Format("To many errors occurred trying to import '{1}' (SessionId: {0})", sessionId, friendlyFilename));
// Move to Errors Folder
if (File.Exists(filename))
{
try
{
string folderError = DataStore.CreateLocation(database, "DocumentDropBox_Errors");
string filenameError = Path.Combine(folderError, Path.GetFileName(filename));
int filenameErrorCount = 0;
while (File.Exists(filenameError))
{
filenameError = Path.Combine(folderError, string.Format("{0} ({1}){2}", Path.GetFileNameWithoutExtension(filename), ++filenameErrorCount, Path.GetExtension(filename)));
}
File.Move(filename, filenameError);
}
catch
{
// Ignore Errors
}
}
}
}
DocumentsLog.LogImportFinished(sessionId);
// All Done
context.Scheduler.DeleteJob(context.JobDetail.Key);
}
catch (Exception ex)
{
ex.ToExceptionless().Submit();
DocumentsLog.LogImportWarning(sessionId, string.Format("{0}; Will try again in 10 Seconds", ex.Message));
// Reschedule Job for 10 seconds
SimpleTriggerImpl trig = new SimpleTriggerImpl(Guid.NewGuid().ToString(), new DateTimeOffset(DateTime.Now.AddSeconds(10)));
context.Scheduler.RescheduleJob(context.Trigger.Key, trig);
}
}
}
}
@@ -1,27 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Spring.Expressions.Parser.antlr;
namespace Disco.BI.Expressions
{
public class EvaluateExpressionParseException
{
public string Expression { get; set; }
public int PositionRow { get; set; }
public int PositionColumn { get; set; }
public string Message { get; set; }
internal static EvaluateExpressionParseException FromRecognitionException(RecognitionException e, string Expression)
{
return new EvaluateExpressionParseException()
{
Expression = Expression,
Message = e.Message,
PositionRow = e.getLine(),
PositionColumn = e.getColumn()
};
}
}
}
@@ -1,84 +0,0 @@
using System;
using System.Collections;
using System.Runtime.CompilerServices;
using Spring.Expressions.Parser.antlr;
namespace Disco.BI.Expressions
{
public class EvaluateExpressionPart : IExpressionPart
{
private Spring.Expressions.IExpression _Expression;
private RecognitionException _ExpressionParseException;
private EvaluateExpressionParseException _EvaluateParseException;
public string RawSource { get; set; }
public string Source { get; set; }
public bool ErrorsAllowed { get; set; }
public bool IsDynamic { get { return true; } set { return; } }
public EvaluateExpressionParseException ParseException
{
get
{
if (_ExpressionParseException == null)
return null;
else
if (_EvaluateParseException == null)
_EvaluateParseException = EvaluateExpressionParseException.FromRecognitionException(_ExpressionParseException, this.Source);
return _EvaluateParseException;
}
}
public bool ParseError
{
get { return (_ExpressionParseException != null); }
}
public string ParseErrorMessage
{
get
{
if (ParseError)
return ParseException.Message;
else
return null;
}
}
public EvaluateExpressionPart(string Source)
{
this.RawSource = Source;
if (Source.StartsWith("{") && Source.EndsWith("}"))
Source = Source.Substring(1, Source.Length - 2);
if (Source[0] == '~')
{
this.ErrorsAllowed = true;
this.Source = Source.Substring(1);
}
else
{
this.ErrorsAllowed = false;
this.Source = Source;
}
try
{
this._Expression = Spring.Expressions.Expression.Parse(this.Source);
}
catch (RecognitionException ex)
{
this._ExpressionParseException = ex;
}
}
object IExpressionPart.Evaluate(object ExpressionContext, System.Collections.IDictionary Variables)
{
if (this._ExpressionParseException == null)
{
return this._Expression.GetValue(ExpressionContext, Variables);
}
throw this._ExpressionParseException;
}
}
}
-259
View File
@@ -1,259 +0,0 @@
using Disco.Data.Repository;
using Disco.Models.BI.DocumentTemplates;
using Disco.Models.Repository;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Text;
using Disco.Models.BI.Expressions;
namespace Disco.BI.Expressions
{
public sealed class Expression : System.Collections.Generic.List<IExpressionPart>
{
public string Name { get; private set; }
public string Source { get; private set; }
public bool IsDynamic { get; private set; }
public int Ordinal { get; private set; }
private Expression(string Name, string Source, int Ordinal)
{
this.Name = Name;
this.Source = Source;
this.Ordinal = Ordinal;
}
public static void InitializeExpressions()
{
Spring.Core.TypeResolution.TypeRegistry.RegisterType("DataExt", typeof(Extensions.DataExt));
Spring.Core.TypeResolution.TypeRegistry.RegisterType("UserExt", typeof(Extensions.UserExt));
Spring.Core.TypeResolution.TypeRegistry.RegisterType("DeviceExt", typeof(Extensions.DeviceExt));
Spring.Core.TypeResolution.TypeRegistry.RegisterType("ImageExt", typeof(Extensions.ImageExt));
}
public T EvaluateFirst<T>(object ExpressionContext, System.Collections.IDictionary Variables)
{
T result = default(T);
if (this.Count > 0)
{
try
{
object expressionResult = this[0].Evaluate(ExpressionContext, Variables);
if (expressionResult != null)
{
if (expressionResult is T)
{
result = (T)expressionResult;
}
else
{
throw new InvalidOperationException("Expression returned an invalid type");
}
}
}
catch (System.Exception ex)
{
throw new InvalidOperationException("Expression evaluation resulted in an error", ex);
}
}
return result;
}
public Tuple<string, bool, object> Evaluate(object ExpressionContext, System.Collections.IDictionary Variables)
{
System.Text.StringBuilder resultValue = new System.Text.StringBuilder();
object resultObject = null;
bool resultError = false;
foreach (var expressionPart in this)
{
try
{
object partValue = expressionPart.Evaluate(ExpressionContext, Variables);
if (partValue != null)
{
// Check for Result Objects
if (partValue is IImageExpressionResult)
resultObject = partValue;
else
resultValue.Append(partValue.ToString());
}
}
catch (System.Exception ex)
{
if (!expressionPart.ErrorsAllowed)
{
resultValue.Append("## ERROR # ");
resultValue.Append(ex.Message);
resultValue.Append(" ##");
resultError = true;
}
}
}
return new Tuple<string, bool, object>(resultValue.ToString(), resultError, resultObject);
}
public static Expression TokenizeSingleDynamic(string Name, string ExpressionSource, int Ordinal)
{
Expression e = new Expression(Name, ExpressionSource, Ordinal);
if (ExpressionSource != null && !string.IsNullOrWhiteSpace(ExpressionSource))
e.Add(new EvaluateExpressionPart(ExpressionSource));
e.IsDynamic = true;
return e;
}
public static Expression Tokenize(string Name, string ExpressionSource, int Ordinal)
{
Expression e = new Expression(Name, ExpressionSource, Ordinal);
if (!ExpressionSource.Contains("{") || !ExpressionSource.Contains("}"))
{
e.Add(new TextExpressionPart(ExpressionSource));
}
else
{
System.Text.StringBuilder token = new System.Text.StringBuilder();
bool tokenEval = false;
int tokenEvalDepth = 0;
foreach (char c in ExpressionSource)
{
switch (c)
{
case '{':
{
if (!tokenEval)
{
if (token.Length > 0)
{
e.Add(new TextExpressionPart(token.ToString()));
token = new System.Text.StringBuilder();
}
tokenEval = true;
tokenEvalDepth = 0;
}
tokenEvalDepth++;
token.Append(c);
break;
}
case '}':
{
token.Append(c);
if (tokenEval)
{
tokenEvalDepth--;
if (tokenEvalDepth <= 0)
{
if (token.Length != 2 && (token.Length != 3 || token[1] != '@'))
{
e.Add(new EvaluateExpressionPart(token.ToString()));
e.IsDynamic = true;
token = new System.Text.StringBuilder();
}
tokenEval = false;
}
}
break;
}
default:
{
token.Append(c);
break;
}
}
}
if (token.Length > 0)
{
e.Add(new TextExpressionPart(token.ToString()));
}
}
return e;
}
public static IDictionary StandardVariables(DocumentTemplate AttachmentType, DiscoDataContext Database, User User, System.DateTime TimeStamp, DocumentState DocumentState)
{
return new Hashtable
{
{
"DataContext",
Database
},
{
"User",
User
},
{
"TimeStamp",
TimeStamp
},
{
"AttachmentType",
AttachmentType
},
{
"State",
DocumentState
}
};
}
public static Dictionary<string, string> StandardVariableTypes()
{
return new Dictionary<string, string>
{
{
"#DataContext",
typeof(DiscoDataContext).AssemblyQualifiedName
},
{
"#User",
typeof(User).AssemblyQualifiedName
},
{
"#TimeStamp",
typeof(System.DateTime).AssemblyQualifiedName
},
{
"#AttachmentType",
typeof(DocumentTemplate).AssemblyQualifiedName
},
{
"#State",
typeof(DocumentState).AssemblyQualifiedName
}
};
}
public static Dictionary<string, string> ExtensionLibraryTypes()
{
return new Dictionary<string, string>
{
{
"DataExt",
typeof(Extensions.DataExt).AssemblyQualifiedName
},
{
"DeviceExt",
typeof(Extensions.DeviceExt).AssemblyQualifiedName
},
{
"ImageExt",
typeof(Extensions.ImageExt).AssemblyQualifiedName
},
{
"UserExt",
typeof(Extensions.UserExt).AssemblyQualifiedName
}
};
}
}
}
-103
View File
@@ -1,103 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Concurrent;
namespace Disco.BI.Expressions
{
public static class ExpressionCache
{
private static ConcurrentDictionary<string, ConcurrentDictionary<string, Expression>> _Cache = new ConcurrentDictionary<string, ConcurrentDictionary<string, Expression>>();
public delegate Expression CreateValueDelegate();
public static ConcurrentDictionary<string, Expression> GetModule(string Module, bool Create = false)
{
ConcurrentDictionary<string, Expression> moduleCache;
if (_Cache.TryGetValue(Module, out moduleCache))
return moduleCache;
else
{
if (Create)
{
moduleCache = new ConcurrentDictionary<string, Expression>();
_Cache.TryAdd(Module, moduleCache);
return moduleCache;
}
else
return null;
}
}
private static Expression GetModuleValue(string Module, string Key, CreateValueDelegate CreateValue)
{
ConcurrentDictionary<string, Expression> moduleCache = GetModule(Module, (CreateValue != null));
if (moduleCache != null)
{
Expression expression;
if (moduleCache.TryGetValue(Key, out expression))
{
return expression;
}
if (CreateValue != null)
{
expression = CreateValue();
Expression oldExpression;
if (moduleCache.TryGetValue(Key, out oldExpression))
moduleCache.TryUpdate(Key, expression, oldExpression);
else
moduleCache.TryAdd(Key, expression);
return expression;
}
}
return null;
}
public static Expression GetValue(string Module, string Key, CreateValueDelegate CreateValue)
{
return GetModuleValue(Module, Key, CreateValue);
}
public static Expression GetValue(string Module, string Key)
{
return GetModuleValue(Module, Key, null);
}
public static bool InvalidModule(string Module)
{
ConcurrentDictionary<string, Expression> moduleCache;
return _Cache.TryRemove(Module, out moduleCache);
}
public static bool InvalidateKey(string Module, string Key)
{
Expression expression;
ConcurrentDictionary<string, Expression> moduleCache = GetModule(Module, false);
if (moduleCache != null)
{
bool removeResult = moduleCache.TryRemove(Key, out expression);
if (moduleCache.Count == 0)
InvalidModule(Module);
return removeResult;
}
else
return false;
}
public static bool SetValue(string Module, string Key, Expression Expression)
{
ConcurrentDictionary<string, Expression> moduleCache = GetModule(Module, true);
if (moduleCache.ContainsKey(Key))
{
Expression oldExpression;
if (moduleCache.TryGetValue(Key, out oldExpression))
{
return moduleCache.TryUpdate(Key, Expression, oldExpression);
}
}
return moduleCache.TryAdd(Key, Expression);
}
}
}
@@ -1,39 +0,0 @@
using Disco.BI.Extensions;
using Disco.Data.Repository;
using Disco.Services.Tasks;
using Quartz;
using System;
using System.Linq;
namespace Disco.BI.Expressions
{
public class ExpressionCachePreloadTask : ScheduledTask
{
public override string TaskName { get { return "Expression Cache - Preload Task"; } }
public override bool SingleInstanceTask { get { return true; } }
public override bool CancelInitiallySupported { get { return false; } }
public override bool LogExceptionsOnly { get { return true; } }
public override void InitalizeScheduledTask(DiscoDataContext Database)
{
// Run in Background 5 Second after Scheduled (on App Startup)
TriggerBuilder triggerBuilder = TriggerBuilder.Create().StartAt(new DateTimeOffset(DateTime.Now).AddSeconds(5));
this.ScheduleTask(triggerBuilder);
}
protected override void ExecuteTask()
{
// Cache Document Template Filter Expressions
using (DiscoDataContext database = new DiscoDataContext())
{
foreach (var documentTemplate in database.DocumentTemplates.Where(dt => dt.FilterExpression != null && dt.FilterExpression != string.Empty))
{
if (!string.IsNullOrWhiteSpace(documentTemplate.FilterExpression))
documentTemplate.FilterExpressionFromCache();
}
}
}
}
}
@@ -1,58 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace Disco.BI.Expressions
{
public class ExpressionTypeDescriptor
{
public string ExpressionType { get; set; }
public string Name { get; set; }
public List<ExpressionTypeMemberDescriptor> Members { get; set; }
public static ExpressionTypeDescriptor Build(System.Type t, bool StaticDeclaredMembersOnly = true)
{
ExpressionTypeDescriptor i = new ExpressionTypeDescriptor
{
ExpressionType = t.AssemblyQualifiedName,
Name = t.Name
};
i.Members = new System.Collections.Generic.List<ExpressionTypeMemberDescriptor>();
System.Reflection.MemberInfo[] members;
if (StaticDeclaredMembersOnly)
members = t.GetMembers(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);
else
members = t.GetMembers(BindingFlags.Public | BindingFlags.Instance);
for (int j = 0; j < members.Length; j++)
{
System.Reflection.MemberInfo member = members[j];
if (member is System.Reflection.PropertyInfo)
{
System.Reflection.PropertyInfo pi = (System.Reflection.PropertyInfo)member;
if (!pi.IsSpecialName && pi.CanRead)
{
i.Members.Add(ExpressionTypeMemberDescriptor.Build(pi));
}
}
if (member is System.Reflection.MethodInfo)
{
System.Reflection.MethodInfo mi2 = (System.Reflection.MethodInfo)member;
if (!mi2.IsSpecialName)
{
i.Members.Add(ExpressionTypeMemberDescriptor.Build(mi2));
}
}
}
i.Members = (
from mi in i.Members
orderby mi.Name
select mi).ToList();
return i;
}
}
}
@@ -1,61 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace Disco.BI.Expressions
{
public class ExpressionTypeMemberDescriptor
{
public const string FunctionKind = "function";
public const string PropertyKind = "property";
public const string ParameterKind = "parameter";
public string Kind {get;set;}
public string Name {get;set;}
public string ReturnType {get;set;}
public string ReturnExpressionType{get;set;}
public List<ExpressionTypeMemberDescriptor> Parameters{get;set;}
public static ExpressionTypeMemberDescriptor Build(System.Reflection.MethodInfo m)
{
ExpressionTypeMemberDescriptor md = new ExpressionTypeMemberDescriptor
{
Kind = "function",
Name = m.Name,
ReturnType = m.ReturnType.Name,
ReturnExpressionType = m.ReturnType.AssemblyQualifiedName
};
md.Parameters = (
from mdp in m.GetParameters()
select ExpressionTypeMemberDescriptor.Build(mdp)).ToList<ExpressionTypeMemberDescriptor>();
return md;
}
public static ExpressionTypeMemberDescriptor Build(System.Reflection.PropertyInfo p)
{
ExpressionTypeMemberDescriptor md = new ExpressionTypeMemberDescriptor
{
Kind = "property",
Name = p.Name,
ReturnType = p.PropertyType.Name,
ReturnExpressionType = p.PropertyType.AssemblyQualifiedName
};
md.Parameters = (
from mdp in p.GetIndexParameters()
select ExpressionTypeMemberDescriptor.Build(mdp)).ToList<ExpressionTypeMemberDescriptor>();
return md;
}
public static ExpressionTypeMemberDescriptor Build(System.Reflection.ParameterInfo pi)
{
return new ExpressionTypeMemberDescriptor
{
Kind = "parameter",
Name = pi.Name,
ReturnType = pi.ParameterType.Name,
ReturnExpressionType = pi.ParameterType.AssemblyQualifiedName
};
}
}
}
@@ -1,176 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Collections;
using System.Data.Odbc;
namespace Disco.BI.Expressions.Extensions
{
public static class DataExt
{
#region SqlClient
private static SqlConnection BuildSqlConnection(string Server, string Database, string Username, string Password)
{
SqlConnectionStringBuilder dbConnectionStringBuilder = new SqlConnectionStringBuilder();
dbConnectionStringBuilder.ApplicationName = "Disco";
dbConnectionStringBuilder.DataSource = Server;
dbConnectionStringBuilder.InitialCatalog = Database;
dbConnectionStringBuilder.MultipleActiveResultSets = true;
dbConnectionStringBuilder.PersistSecurityInfo = true;
if (Username == null || Password == null)
dbConnectionStringBuilder.IntegratedSecurity = true;
else
{
dbConnectionStringBuilder.UserID = Username;
dbConnectionStringBuilder.Password = Password;
}
return new SqlConnection(dbConnectionStringBuilder.ConnectionString);
}
private static void BuildSqlParameters(SqlCommand dbCommand, Hashtable SqlParameters)
{
if (SqlParameters != null)
{
foreach (var sqlParameterKey in SqlParameters.Keys)
{
string key = sqlParameterKey.ToString();
if (!key.StartsWith("@"))
key = string.Concat("@", key);
dbCommand.Parameters.AddWithValue(key, SqlParameters[sqlParameterKey]);
}
}
}
public static DataTable QuerySqlDatabase(string Server, string Database, string Username, string Password, string SqlQuery, Hashtable SqlParameters)
{
using (SqlConnection dbConnection = BuildSqlConnection(Server, Database, Username, Password))
{
using (SqlCommand dbCommand = new SqlCommand(SqlQuery, dbConnection))
{
BuildSqlParameters(dbCommand, SqlParameters);
using (SqlDataAdapter dbAdapter = new SqlDataAdapter(dbCommand))
{
var dbTable = new DataTable();
dbAdapter.Fill(dbTable);
return dbTable;
}
}
}
}
public static DataTable QuerySqlDatabase(string Server, string Database, string SqlQuery, Hashtable SqlParameters)
{
return QuerySqlDatabase(Server, Database, null, null, SqlQuery, SqlParameters);
}
public static DataTable QuerySqlDatabase(string Server, string Database, string SqlQuery)
{
return QuerySqlDatabase(Server, Database, null, null, SqlQuery, null);
}
public static object QuerySqlDatabaseScalar(string Server, string Database, string Username, string Password, string SqlQuery, Hashtable SqlParameters)
{
using (SqlConnection dbConnection = BuildSqlConnection(Server, Database, Username, Password))
{
using (SqlCommand dbCommand = new SqlCommand(SqlQuery, dbConnection))
{
BuildSqlParameters(dbCommand, SqlParameters);
try
{
dbConnection.Open();
return dbCommand.ExecuteScalar();
}
catch (Exception)
{
throw;
}
finally
{
dbConnection.Close();
}
}
}
}
public static object QuerySqlDatabaseScalar(string Server, string Database, string SqlQuery, Hashtable SqlParameters)
{
return QuerySqlDatabaseScalar(Server, Database, null, null, SqlQuery, SqlParameters);
}
public static object QuerySqlDatabaseScalar(string Server, string Database, string SqlQuery)
{
return QuerySqlDatabaseScalar(Server, Database, null, null, SqlQuery, null);
}
#endregion
#region ODBC
private static OdbcConnection BuildOdbcConnection(string ConnectionString)
{
return new OdbcConnection(ConnectionString);
}
private static void BuildOdbcParameters(OdbcCommand dbCommand, Hashtable OdbcParameters)
{
if (OdbcParameters != null)
{
foreach (var odbcParameterKey in OdbcParameters.Keys)
{
string key = odbcParameterKey.ToString();
dbCommand.Parameters.AddWithValue(key, OdbcParameters[odbcParameterKey]);
}
}
}
public static DataTable QueryOdbcDatabase(string ConnectionString, string OdbcQuery, Hashtable OdbcParameters)
{
using (OdbcConnection dbConnection = BuildOdbcConnection(ConnectionString))
{
using (OdbcCommand dbCommand = new OdbcCommand(OdbcQuery, dbConnection))
{
BuildOdbcParameters(dbCommand, OdbcParameters);
using (OdbcDataAdapter dbAdapter = new OdbcDataAdapter(dbCommand))
{
var dbTable = new DataTable();
dbAdapter.Fill(dbTable);
return dbTable;
}
}
}
}
public static DataTable QueryOdbcDatabase(string ConnectionString, string OdbcQuery)
{
return QueryOdbcDatabase(ConnectionString, OdbcQuery, null);
}
public static object QueryOdbcDatabaseScalar(string ConnectionString, string OdbcQuery, Hashtable OdbcParameters)
{
using (OdbcConnection dbConnection = BuildOdbcConnection(ConnectionString))
{
using (OdbcCommand dbCommand = new OdbcCommand(OdbcQuery, dbConnection))
{
BuildOdbcParameters(dbCommand, OdbcParameters);
try
{
dbConnection.Open();
return dbCommand.ExecuteScalar();
}
catch (Exception)
{
throw;
}
finally
{
dbConnection.Close();
}
}
}
}
public static object QueryOdbcDatabaseScalar(string ConnectionString, string OdbcQuery)
{
return QueryOdbcDatabaseScalar(ConnectionString, OdbcQuery, null);
}
#endregion
}
}
@@ -1,49 +0,0 @@
using Disco.BI.Extensions;
using Disco.Models.Repository;
using Disco.Services.Interop.ActiveDirectory;
using System;
using System.Linq;
namespace Disco.BI.Expressions.Extensions
{
public static class DeviceExt
{
public static object GetActiveDirectoryObjectValue(Device Device, string PropertyName, int Index = 0)
{
var adMachineAccount = Device.ActiveDirectoryAccount(PropertyName);
if (adMachineAccount != null)
return adMachineAccount.GetPropertyValues<object>(PropertyName).Skip(Index).FirstOrDefault();
else
return null;
}
public static string GetActiveDirectoryStringValue(Device Device, string PropertyName, int Index = 0)
{
var objectValue = GetActiveDirectoryObjectValue(Device, PropertyName, Index);
string stringValue = objectValue as string;
if (stringValue == null && objectValue != null)
stringValue = objectValue.ToString();
return stringValue;
}
public static int GetActiveDirectoryIntegerValue(Device Device, string PropertyName, int Index = 0)
{
var objectValue = GetActiveDirectoryObjectValue(Device, PropertyName, Index);
if (objectValue == null)
return default(int);
else
{
int intValue;
try
{
intValue = (int)Convert.ChangeType(objectValue, typeof(int));
}
catch (Exception)
{
throw;
}
return intValue;
}
}
}
}
@@ -1,140 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Disco.Models.BI.Expressions;
using Disco.BI.Expressions.Extensions.ImageResultImplementations;
using Disco.Models.Repository;
using Disco.BI.Extensions;
using Disco.Data.Repository;
using System.Collections;
using System.IO;
using System.Drawing;
namespace Disco.BI.Expressions.Extensions
{
public static class ImageExt
{
public static FileImageExpressionResult ImageFromFile(string AbsoluteFilePath)
{
return new FileImageExpressionResult(AbsoluteFilePath);
}
public static FileImageExpressionResult ImageFromDataStoreFile(string RelativeFilePath)
{
var configCache = new Disco.Data.Configuration.SystemConfiguration(null);
string DataStoreLocation = configCache.DataStoreLocation;
string AbsoluteFilePath = System.IO.Path.Combine(DataStoreLocation, RelativeFilePath);
return new FileImageExpressionResult(AbsoluteFilePath);
}
public static FileImageExpressionResult JobAttachmentFirstImage(Job Job, DiscoDataContext Database)
{
var attachment = Job.JobAttachments.FirstOrDefault(ja => ja.MimeType.StartsWith("image/", StringComparison.OrdinalIgnoreCase));
if (attachment != null)
{
var filename = attachment.RepositoryFilename(Database);
return new FileImageExpressionResult(filename);
}
else
return null;
}
public static FileImageExpressionResult JobAttachmentLastImage(Job Job, DiscoDataContext Database)
{
var attachment = Job.JobAttachments.LastOrDefault(ja => ja.MimeType.StartsWith("image/", StringComparison.OrdinalIgnoreCase));
if (attachment != null)
{
var filename = attachment.RepositoryFilename(Database);
return new FileImageExpressionResult(filename);
}
else
return null;
}
public static FileImageExpressionResult JobAttachmentImage(JobAttachment JobAttachment, DiscoDataContext Database)
{
if (JobAttachment == null)
throw new ArgumentNullException("JobAttachment");
if (!JobAttachment.MimeType.StartsWith("image/", StringComparison.OrdinalIgnoreCase))
throw new ArgumentException("Invalid Image MimeType for Attachment");
var filename = JobAttachment.RepositoryFilename(Database);
return new FileImageExpressionResult(filename);
}
public static FileMontageImageExpressionResult JobAttachmentImageMontage(Job Job, DiscoDataContext Database)
{
if (Job == null)
throw new ArgumentNullException("Job");
if (Job.JobAttachments == null)
throw new ArgumentException("Job.JobAttachments is null", "Job");
var attachments = Job.JobAttachments.Where(a => a.MimeType.StartsWith("image/", StringComparison.OrdinalIgnoreCase)).ToList();
if (attachments.Count > 0)
{
var attachmentFilepaths = attachments.Select(a => a.RepositoryFilename(Database)).ToList();
return new FileMontageImageExpressionResult(attachmentFilepaths);
}
else
return null;
}
public static FileMontageImageExpressionResult JobAttachmentsImageMontage(ArrayList JobAttachments, DiscoDataContext Database)
{
if (JobAttachments == null)
throw new ArgumentNullException("JobAttachments");
var attachments = JobAttachments.Cast<JobAttachment>().Where(a => a.MimeType.StartsWith("image/", StringComparison.OrdinalIgnoreCase)).ToList();
if (attachments.Count > 0)
{
var attachmentFilepaths = attachments.Select(a => a.RepositoryFilename(Database)).ToList();
return new FileMontageImageExpressionResult(attachmentFilepaths);
}
else
return null;
}
public static BitmapImageExpressionResult ImageFromStream(Stream ImageStream)
{
if (ImageStream == null)
throw new ArgumentNullException("ImageStream");
return new BitmapImageExpressionResult(Bitmap.FromStream(ImageStream));
}
public static BitmapImageExpressionResult ImageFromByteArray(byte[] ImageByteArray)
{
if (ImageByteArray == null)
throw new ArgumentNullException("ImageByteArray");
return new BitmapImageExpressionResult(Bitmap.FromStream(new MemoryStream(ImageByteArray)));
}
public static BitmapImageExpressionResult DeviceModelImage(DeviceModel DeviceModel)
{
if (DeviceModel == null)
throw new ArgumentNullException("DeviceModel");
using (Stream deviceModelImage = DeviceModel.Image())
{
if (deviceModelImage == null)
return null;
else
return ImageFromStream(deviceModelImage);
}
//if (DeviceModel.Image == null || DeviceModel.Image.Length == 0)
// return null;
//return ImageFromByteArray(DeviceModel.Image);
}
public static BitmapImageExpressionResult OrganisationLogo()
{
var configCache = new Disco.Data.Configuration.SystemConfiguration(null);
BitmapImageExpressionResult result;
using (var orgLogo = configCache.OrganisationLogo)
{
result = ImageFromStream(orgLogo);
}
result.LosslessFormat = true;
return result;
}
}
}
@@ -1,70 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Disco.Models.BI.Expressions;
using System.IO;
using System.Drawing;
using Disco.BI.Extensions;
namespace Disco.BI.Expressions.Extensions.ImageResultImplementations
{
public abstract class BaseImageExpressionResult : IImageExpressionResult
{
public byte Quality { get; set; }
public bool LosslessFormat { get; set; }
public bool ShowField { get; set; }
public string BackgroundColour { get; set; }
public bool BackgroundPreferTransparent { get; set; }
public BaseImageExpressionResult()
{
this.LosslessFormat = false;
this.Quality = 90;
this.ShowField = false;
this.BackgroundPreferTransparent = true;
}
public abstract Stream GetImage(int Width, int Height);
protected Stream RenderImage(Image SourceImage, int Width, int Height)
{
if (SourceImage == null)
throw new ArgumentNullException("SourceImage");
if (Width <= 0)
throw new ArgumentOutOfRangeException("Width", "Width must be > 0");
if (Height <= 0)
throw new ArgumentOutOfRangeException("Height", "Height must be > 0");
Brush backgroundBrush = null;
if (!LosslessFormat || !BackgroundPreferTransparent)
{
if (string.IsNullOrEmpty(this.BackgroundColour))
backgroundBrush = Brushes.White;
else
backgroundBrush = new SolidBrush(ColorTranslator.FromHtml(this.BackgroundColour));
}
using (Image resizedImage = SourceImage.ResizeImage(Width, Height, backgroundBrush))
{
return OutputImage(resizedImage);
}
}
protected Stream OutputImage(Image SourceImage)
{
MemoryStream imageStream = new MemoryStream();
if (LosslessFormat)
{ // Lossless Format - PNG
SourceImage.SavePng(imageStream);
}
else
{ // Lossy Format - JPG
byte quality = Math.Min((byte)100, Math.Max((byte)1, this.Quality));
SourceImage.SaveJpg(quality, imageStream);
}
imageStream.Position = 0;
return imageStream;
}
}
}
@@ -1,27 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;
namespace Disco.BI.Expressions.Extensions.ImageResultImplementations
{
public class BitmapImageExpressionResult : BaseImageExpressionResult
{
public Image Image { get; set; }
public BitmapImageExpressionResult(Image Image)
{
if (Image == null)
throw new ArgumentNullException("Image");
this.Image = Image;
}
public override Stream GetImage(int Width, int Height)
{
return this.RenderImage(this.Image, Width, Height);
}
}
}
@@ -1,32 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;
namespace Disco.BI.Expressions.Extensions.ImageResultImplementations
{
public class FileImageExpressionResult : BaseImageExpressionResult
{
public string AbsoluteFilePath { get; set; }
public FileImageExpressionResult(string AbsoluteFilePath)
{
if (string.IsNullOrWhiteSpace(AbsoluteFilePath))
throw new ArgumentNullException("AbsoluteFilePath");
if (!File.Exists(AbsoluteFilePath))
throw new FileNotFoundException("Image not found", AbsoluteFilePath);
this.AbsoluteFilePath = AbsoluteFilePath;
}
public override Stream GetImage(int Width, int Height)
{
using (Image SourceImage = Bitmap.FromFile(this.AbsoluteFilePath))
{
return this.RenderImage(SourceImage, Width, Height);
}
}
}
}
@@ -1,181 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;
using System.Drawing.Drawing2D;
using Disco.BI.Extensions;
namespace Disco.BI.Expressions.Extensions.ImageResultImplementations
{
public class FileMontageImageExpressionResult : BaseImageExpressionResult
{
public List<string> AbsoluteFilePaths { get; set; }
public bool MontageHorizontalLayout { get; set; }
public bool MontageVerticalLayout { get; set; }
public bool MontageTableLayout { get; set; }
public int Padding { get; set; }
public FileMontageImageExpressionResult(List<string> AbsoluteFilePaths)
{
if (AbsoluteFilePaths == null)
throw new ArgumentNullException("AbsoluteFilePaths");
if (AbsoluteFilePaths.Count == 0)
throw new ArgumentException("AbsoluteFilePaths is empty", "AbsoluteFilePaths");
this.AbsoluteFilePaths = AbsoluteFilePaths;
this.MontageTableLayout = true;
this.Padding = 4;
}
public override Stream GetImage(int Width, int Height)
{
List<Image> Images = new List<Image>();
try
{
// Load Images
foreach (string imageFilePath in this.AbsoluteFilePaths)
Images.Add(Bitmap.FromFile(imageFilePath));
// Build Montage
using (Bitmap montageImage = new Bitmap(Width, Height))
{
using (Graphics montageGraphics = Graphics.FromImage(montageImage))
{
montageGraphics.CompositingQuality = CompositingQuality.HighQuality;
montageGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
montageGraphics.SmoothingMode = SmoothingMode.HighQuality;
// Draw Background
if (!LosslessFormat || !BackgroundPreferTransparent)
{
Brush backgroundBrush = Brushes.White;
if (!string.IsNullOrEmpty(this.BackgroundColour))
backgroundBrush = new SolidBrush(ColorTranslator.FromHtml(this.BackgroundColour));
montageGraphics.FillRectangle(backgroundBrush, montageGraphics.VisibleClipBounds);
}
if (this.MontageHorizontalLayout)
DoHorizontalLayout(Images, montageGraphics);
else
if (this.MontageVerticalLayout)
DoVirticalLayout(Images, montageGraphics);
else
DoTableLayout(Images, montageGraphics);
}
return this.OutputImage(montageImage);
}
}
catch (Exception) { throw; }
finally
{
// Dispose of any Images
if (Images != null)
foreach (Image i in Images)
i.Dispose();
}
}
private void DoHorizontalLayout(List<Image> Images, Graphics MontageGraphics)
{
float imageScale;
float imagePosition = 0;
int imagesWidthTotal = Images.Sum(i => i.Width);
int imagesHeightMax = Images.Max(i => i.Height);
int imagesPadding = ((Images.Count - 1) * this.Padding);
imageScale = (float)(MontageGraphics.VisibleClipBounds.Width - imagesPadding) / (float)imagesWidthTotal;
if ((MontageGraphics.VisibleClipBounds.Height / (float)imagesHeightMax) < imageScale)
imageScale = (float)MontageGraphics.VisibleClipBounds.Height / (float)imagesHeightMax;
foreach (Image image in Images)
{
MontageGraphics.DrawImageResized(image, imageScale, imagePosition, 0);
imagePosition += (imageScale * image.Width) + this.Padding;
}
}
private void DoVirticalLayout(List<Image> Images, Graphics MontageGraphics)
{
float imageScale;
float imagePosition = 0;
int imagesWidthMax = Images.Max(i => i.Width);
int imagesHeightTotal = Images.Sum(i => i.Height);
int imagesPadding = ((Images.Count - 1) * this.Padding);
imageScale = (float)(MontageGraphics.VisibleClipBounds.Height - imagesPadding) / (float)imagesHeightTotal;
if ((MontageGraphics.VisibleClipBounds.Width / (float)imagesWidthMax) < imageScale)
imageScale = (float)MontageGraphics.VisibleClipBounds.Width / (float)imagesWidthMax;
foreach (Image image in Images)
{
MontageGraphics.DrawImageResized(image, imageScale, 0, imagePosition);
imagePosition += (imageScale * image.Height) + this.Padding;
}
}
private void DoTableLayout(List<Image> Images, Graphics MontageGraphics)
{
var stageSize = MontageGraphics.VisibleClipBounds.Size.ToSize();
var itemAverageSize = new SizeF(Images.Average(i => (float)i.Size.Width), Images.Average(i => (float)i.Size.Height));
var calculatedLayout = CalculateColumnCount(stageSize, itemAverageSize, Images.Count);
SizeF cellSize = new SizeF((MontageGraphics.VisibleClipBounds.Width - ((calculatedLayout.Item1 - 1) * this.Padding)) / calculatedLayout.Item1,
(MontageGraphics.VisibleClipBounds.Height - ((calculatedLayout.Item2 - 1) * this.Padding)) / calculatedLayout.Item2);
int imageIndex = 0;
for (int rowIndex = 0; rowIndex < calculatedLayout.Item2; rowIndex++)
{
for (int columnIndex = 0; columnIndex < calculatedLayout.Item1; columnIndex++)
{
if (imageIndex < Images.Count)
{
var image = Images[imageIndex];
var cellPoint = new PointF((cellSize.Width * columnIndex) + (this.Padding * columnIndex), (cellSize.Height * rowIndex) + (this.Padding * rowIndex));
MontageGraphics.Clip = new Region(new RectangleF(cellPoint, cellSize));
MontageGraphics.DrawImageResized(image);
imageIndex++;
}
else
break;
}
}
}
private Tuple<int, int, double> CalculateColumnCount(Size StageSize, SizeF ItemAverageSize, int ItemCount)
{
double? bestUsedSpace = null;
int bestColumnCount = 1;
int bestRowCount = 1;
double bestItemRatio = 1;
for (int columnCount = 1; columnCount <= ItemCount; columnCount++)
{
int rowCount = (int)Math.Ceiling((double)ItemCount / (double)columnCount);
int requiredWidthPadding = (columnCount - 1) * this.Padding;
int requiredHeightPadding = (rowCount - 1) * this.Padding;
Size usableStageSize = new Size(StageSize.Width - requiredWidthPadding, StageSize.Height - requiredHeightPadding);
double stageWidthRatio = (float)usableStageSize.Width / (float)usableStageSize.Height;
double stageHeightRatio = (float)usableStageSize.Height / (float)usableStageSize.Width;
int requiredWidth = (int)Math.Ceiling(ItemAverageSize.Width * columnCount);
int requiredHeight = (int)Math.Ceiling(ItemAverageSize.Height * rowCount);
int usedSpace = requiredWidth * requiredHeight;
int stageArea = Math.Max((requiredWidth * (int)Math.Ceiling(requiredWidth * stageHeightRatio)),
(requiredHeight * (int)Math.Ceiling(requiredHeight * stageWidthRatio)));
double usedStageSpace = (double)usedSpace / stageArea;
if (bestUsedSpace == null || bestUsedSpace < usedStageSpace)
{
bestUsedSpace = usedStageSpace;
bestColumnCount = columnCount;
bestRowCount = rowCount;
bestItemRatio = Math.Min((double)usableStageSize.Width / (double)requiredWidth, (double)usableStageSize.Height / (double)requiredHeight);
}
}
return new Tuple<int, int, double>(bestColumnCount, bestRowCount, bestItemRatio);
}
}
}
@@ -1,74 +0,0 @@
using Disco.BI.Extensions;
using Disco.Models.Repository;
using Disco.Services.Users;
using System;
using System.Linq;
namespace Disco.BI.Expressions.Extensions
{
public static class UserExt
{
#region Active Directory Extensions
public static object GetActiveDirectoryObjectValue(User User, string PropertyName, int Index = 0)
{
var adUserAccount = User.ActiveDirectoryAccount(PropertyName);
if (adUserAccount != null)
return adUserAccount.GetPropertyValues<object>(PropertyName).Skip(Index).FirstOrDefault();
else
return null;
}
public static string GetActiveDirectoryStringValue(User User, string PropertyName, int Index = 0)
{
var objectValue = GetActiveDirectoryObjectValue(User, PropertyName, Index);
string stringValue = objectValue as string;
if (stringValue == null && objectValue != null)
stringValue = objectValue.ToString();
return stringValue;
}
public static int GetActiveDirectoryIntegerValue(User User, string PropertyName, int Index = 0)
{
var objectValue = GetActiveDirectoryObjectValue(User, PropertyName, Index);
if (objectValue == null)
return default(int);
else
{
int intValue;
try
{
intValue = (int)Convert.ChangeType(objectValue, typeof(int));
}
catch (Exception)
{
throw;
}
return intValue;
}
}
#endregion
#region Authorization Testing Extensions
public static bool HasAuthorization(User User, string Claim)
{
var authorization = UserService.GetAuthorization(User.UserId);
return authorization.Has(Claim);
}
public static bool HasAuthorizationAll(User User, params string[] Claims)
{
var authorization = UserService.GetAuthorization(User.UserId);
return authorization.HasAll(Claims);
}
public static bool HasAuthorizationAny(User User, params string[] Claims)
{
var authorization = UserService.GetAuthorization(User.UserId);
return authorization.HasAny(Claims);
}
#endregion
}
}
@@ -1,16 +0,0 @@
using System;
using System.Collections;
namespace Disco.BI.Expressions
{
public interface IExpressionPart
{
string RawSource { get; set; }
string Source { get; set; }
bool ErrorsAllowed { get; set; }
bool ParseError { get; }
string ParseErrorMessage { get; }
bool IsDynamic { get; set; }
object Evaluate(object ExpressionContext, System.Collections.IDictionary Variables);
}
}
@@ -1,74 +0,0 @@
using System;
using System.Collections;
namespace Disco.BI.Expressions
{
public class TextExpressionPart : IExpressionPart
{
private string _Source;
bool IExpressionPart.ErrorsAllowed
{
get
{
return false;
}
set
{
return;
}
}
string IExpressionPart.Source
{
get
{
return this._Source;
}
set
{
return;
}
}
string IExpressionPart.RawSource
{
get
{
return this._Source;
}
set
{
return;
}
}
bool IExpressionPart.IsDynamic
{
get
{
return false;
}
set
{
return;
}
}
public bool ParseError
{
get { return false; }
}
public string ParseErrorMessage
{
get { return null; }
}
public TextExpressionPart(string Source)
{
this._Source = Source;
}
object IExpressionPart.Evaluate(object ExpressionContext, System.Collections.IDictionary Variables)
{
return this._Source;
}
}
}
@@ -7,6 +7,7 @@ using Disco.Data.Repository;
using Disco.Services.Users;
using Disco.Services.Authorization;
using Disco.BI.DocumentTemplateBI.ManagedGroups;
using Disco.Services;
namespace Disco.BI.Extensions
{
@@ -1,209 +0,0 @@
using Disco.BI.DocumentTemplateBI;
using Disco.Data.Repository;
using Disco.Models.Repository;
using Disco.Services.Logging;
using Disco.Services.Users;
using Exceptionless;
using System;
using System.IO;
namespace Disco.BI.Extensions
{
public static class AttachmentExtensions
{
public static bool ImportPdfAttachment(this DocumentUniqueIdentifier UniqueIdentifier, DiscoDataContext Database, System.IO.Stream PdfContent, byte[] PdfThumbnail)
{
UniqueIdentifier.LoadComponents(Database);
DocumentTemplate documentTemplate = UniqueIdentifier.DocumentTemplate;
string filename;
string comments;
object attachment;
if (documentTemplate == null)
{
filename = string.Format("{0}_{1:yyyyMMdd-HHmmss}.pdf", UniqueIdentifier.DataId.Replace('\\', '_'), UniqueIdentifier.TimeStamp);
comments = string.Format("Uploaded: {0:s}", UniqueIdentifier.TimeStamp);
}
else
{
filename = string.Format("{0}_{1:yyyyMMdd-HHmmss}.pdf", UniqueIdentifier.TemplateTypeId, UniqueIdentifier.TimeStamp);
comments = string.Format("Generated: {0:s}", UniqueIdentifier.TimeStamp);
}
User creatorUser = UserService.GetUser(UniqueIdentifier.CreatorId, Database);
if (creatorUser == null)
{
// No Creator User (or Username invalid)
creatorUser = UserService.CurrentUser;
}
switch (UniqueIdentifier.DataScope)
{
case DocumentTemplate.DocumentTemplateScopes.Device:
Device d = (Device)UniqueIdentifier.Data;
attachment = d.CreateAttachment(Database, creatorUser, filename, DocumentTemplate.PdfMimeType, comments, PdfContent, documentTemplate, PdfThumbnail);
break;
case DocumentTemplate.DocumentTemplateScopes.Job:
Job j = (Job)UniqueIdentifier.Data;
attachment = j.CreateAttachment(Database, creatorUser, filename, DocumentTemplate.PdfMimeType, comments, PdfContent, documentTemplate, PdfThumbnail);
break;
case DocumentTemplate.DocumentTemplateScopes.User:
User u = (User)UniqueIdentifier.Data;
attachment = u.CreateAttachment(Database, creatorUser, filename, DocumentTemplate.PdfMimeType, comments, PdfContent, documentTemplate, PdfThumbnail);
break;
default:
return false;
}
if (documentTemplate != null && !string.IsNullOrWhiteSpace(documentTemplate.OnImportAttachmentExpression))
{
try
{
var expressionResult = documentTemplate.EvaluateOnAttachmentImportExpression(attachment, Database, creatorUser, UniqueIdentifier.TimeStamp);
DocumentsLog.LogImportAttachmentExpressionEvaluated(documentTemplate, UniqueIdentifier.Data, attachment, expressionResult);
}
catch (Exception ex)
{
SystemLog.LogException("Document Importer - OnImportAttachmentExpression", ex);
}
}
return true;
}
public static string RepositoryFilename(this DeviceAttachment da, DiscoDataContext Database)
{
return Path.Combine(DataStore.CreateLocation(Database, "DeviceAttachments", da.Timestamp), string.Format("{0}_{1}_file", da.DeviceSerialNumber, da.Id));
}
public static string RepositoryFilename(this JobAttachment ja, DiscoDataContext Database)
{
return Path.Combine(DataStore.CreateLocation(Database, "JobAttachments", ja.Timestamp), string.Format("{0}_{1}_file", ja.JobId, ja.Id));
}
public static string RepositoryFilename(this UserAttachment ua, DiscoDataContext Database)
{
return Path.Combine(DataStore.CreateLocation(Database, "UserAttachments", ua.Timestamp), string.Format("{0}_{1}_file", ua.UserId.Replace('\\', '_'), ua.Id));
}
private static string RepositoryThumbnailFilenameInternal(string DirectoryPath, string Filename)
{
return Path.Combine(DirectoryPath, Filename);
}
public static string RepositoryThumbnailFilename(this DeviceAttachment da, DiscoDataContext Database)
{
return RepositoryThumbnailFilenameInternal(DataStore.CreateLocation(Database, "DeviceAttachments", da.Timestamp), string.Format("{0}_{1}_thumb.jpg", da.DeviceSerialNumber, da.Id));
}
public static string RepositoryThumbnailFilename(this JobAttachment ja, DiscoDataContext Database)
{
return RepositoryThumbnailFilenameInternal(DataStore.CreateLocation(Database, "JobAttachments", ja.Timestamp), string.Format("{0}_{1}_thumb.jpg", ja.JobId, ja.Id));
}
public static string RepositoryThumbnailFilename(this UserAttachment ua, DiscoDataContext Database)
{
return RepositoryThumbnailFilenameInternal(DataStore.CreateLocation(Database, "UserAttachments", ua.Timestamp), string.Format("{0}_{1}_thumb.jpg", ua.UserId.Replace('\\', '_'), ua.Id));
}
public static void RepositoryDelete(this DeviceAttachment da, DiscoDataContext Database)
{
RepositoryDelete(da.RepositoryFilename(Database), da.RepositoryThumbnailFilename(Database));
}
public static void RepositoryDelete(this JobAttachment ja, DiscoDataContext Database)
{
RepositoryDelete(ja.RepositoryFilename(Database), ja.RepositoryThumbnailFilename(Database));
}
public static void RepositoryDelete(this UserAttachment ua, DiscoDataContext Database)
{
RepositoryDelete(ua.RepositoryFilename(Database), ua.RepositoryThumbnailFilename(Database));
}
private static void RepositoryDelete(params string[] filePaths)
{
foreach (string filePath in filePaths)
{
if (File.Exists(filePath))
File.Delete(filePath);
}
}
public static string SaveAttachment(this DeviceAttachment da, DiscoDataContext Database, Stream FileContent)
{
string filePath = da.RepositoryFilename(Database);
SaveAttachment(filePath, FileContent);
return filePath;
}
public static string SaveAttachment(this JobAttachment ja, DiscoDataContext Database, Stream FileContent)
{
string filePath = ja.RepositoryFilename(Database);
SaveAttachment(filePath, FileContent);
return filePath;
}
public static string SaveAttachment(this UserAttachment ua, DiscoDataContext Database, Stream FileContent)
{
string filePath = ua.RepositoryFilename(Database);
SaveAttachment(filePath, FileContent);
return filePath;
}
public static string SaveThumbnailAttachment(this DeviceAttachment da, DiscoDataContext Database, byte[] FileContent)
{
string filePath = da.RepositoryThumbnailFilename(Database);
File.WriteAllBytes(filePath, FileContent);
return filePath;
}
public static string SaveThumbnailAttachment(this JobAttachment ja, DiscoDataContext Database, byte[] FileContent)
{
string filePath = ja.RepositoryThumbnailFilename(Database);
File.WriteAllBytes(filePath, FileContent);
return filePath;
}
public static string SaveThumbnailAttachment(this UserAttachment ua, DiscoDataContext Database, byte[] FileContent)
{
string filePath = ua.RepositoryThumbnailFilename(Database);
File.WriteAllBytes(filePath, FileContent);
return filePath;
}
private static void SaveAttachment(string FilePath, Stream FileContent)
{
using (FileStream sw = new FileStream(FilePath, FileMode.Create, FileAccess.Write, FileShare.None))
{
FileContent.CopyTo(sw);
sw.Flush();
sw.Close();
}
}
public static string GenerateThumbnail(this DeviceAttachment da, DiscoDataContext Database)
{
string filePath = da.RepositoryThumbnailFilename(Database);
AttachmentBI.Utilities.GenerateThumbnail(da.RepositoryFilename(Database), da.MimeType, filePath);
return filePath;
}
public static string GenerateThumbnail(this JobAttachment ja, DiscoDataContext Database)
{
string filePath = ja.RepositoryThumbnailFilename(Database);
AttachmentBI.Utilities.GenerateThumbnail(ja.RepositoryFilename(Database), ja.MimeType, filePath);
return filePath;
}
public static string GenerateThumbnail(this UserAttachment ua, DiscoDataContext Database)
{
string filePath = ua.RepositoryThumbnailFilename(Database);
AttachmentBI.Utilities.GenerateThumbnail(ua.RepositoryFilename(Database), ua.MimeType, filePath);
return filePath;
}
public static string GenerateThumbnail(this DeviceAttachment da, DiscoDataContext Database, Stream SourceFile)
{
string filePath = da.RepositoryThumbnailFilename(Database);
AttachmentBI.Utilities.GenerateThumbnail(SourceFile, da.MimeType, filePath);
return filePath;
}
public static string GenerateThumbnail(this JobAttachment ja, DiscoDataContext Database, Stream SourceFile)
{
string filePath = ja.RepositoryThumbnailFilename(Database);
AttachmentBI.Utilities.GenerateThumbnail(SourceFile, ja.MimeType, filePath);
return filePath;
}
public static string GenerateThumbnail(this UserAttachment ua, DiscoDataContext Database, Stream SourceFile)
{
string filePath = ua.RepositoryThumbnailFilename(Database);
AttachmentBI.Utilities.GenerateThumbnail(SourceFile, ua.MimeType, filePath);
return filePath;
}
}
}
@@ -1,5 +1,6 @@
using Disco.Data.Repository;
using Disco.Models.Repository;
using Disco.Services;
using Disco.Services.Authorization;
using Disco.Services.Interop.ActiveDirectory;
using Disco.Services.Users;
+19 -57
View File
@@ -1,15 +1,16 @@
using System.Linq;
using Disco.Data.Configuration;
using Disco.Data.Repository;
using Disco.Models.BI.DocumentTemplates;
using Disco.Models.Repository;
using System.Collections.Generic;
using System;
using System.IO;
using Disco.Services.Users;
using Disco.Models.Services.Documents;
using Disco.Services;
using Disco.Services.Authorization;
using Disco.Services.Expressions;
using Disco.Services.Interop.ActiveDirectory;
using Disco.Services.Users;
using Exceptionless;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Disco.BI.Extensions
{
@@ -21,15 +22,15 @@ namespace Disco.BI.Extensions
if (Domain == null)
throw new ArgumentNullException("Domain");
DeviceProfile deviceProfile = device.DeviceProfile;
Expressions.Expression computerNameTemplateExpression = null;
computerNameTemplateExpression = Expressions.ExpressionCache.GetValue(DeviceProfileExtensions.ComputerNameExpressionCacheModule, deviceProfile.Id.ToString(), () =>
var deviceProfile = device.DeviceProfile;
Expression computerNameTemplateExpression = null;
computerNameTemplateExpression = ExpressionCache.GetValue(DeviceProfileExtensions.ComputerNameExpressionCacheModule, deviceProfile.Id.ToString(), () =>
{
// Removed 2012-06-14 G# - Properties moved to DeviceProfile model & DB Migrated in DBv3.
//return Expressions.Expression.TokenizeSingleDynamic(null, deviceProfile.Configuration(context).ComputerNameTemplate, 0);
return Expressions.Expression.TokenizeSingleDynamic(null, deviceProfile.ComputerNameTemplate, 0);
return Expression.TokenizeSingleDynamic(null, deviceProfile.ComputerNameTemplate, 0);
});
System.Collections.IDictionary evaluatorVariables = Expressions.Expression.StandardVariables(null, Database, UserService.CurrentUser, System.DateTime.Now, null);
var evaluatorVariables = Expression.StandardVariables(null, Database, UserService.CurrentUser, DateTime.Now, null);
string rendered;
try
{
@@ -42,53 +43,22 @@ namespace Disco.BI.Extensions
}
if (rendered == null || rendered.Length > 24)
{
throw new System.InvalidOperationException("The rendered computer name would be invalid or longer than 24 characters");
throw new InvalidOperationException("The rendered computer name would be invalid or longer than 24 characters");
}
return string.Format(@"{0}\{1}", Domain.NetBiosName, rendered);
}
public static System.Collections.Generic.List<DocumentTemplate> AvailableDocumentTemplates(this Device d, DiscoDataContext Database, User User, System.DateTime TimeStamp)
public static List<DocumentTemplate> AvailableDocumentTemplates(this Device d, DiscoDataContext Database, User User, DateTime TimeStamp)
{
List<DocumentTemplate> ats = Database.DocumentTemplates
.Where(at => at.Scope == Disco.Models.Repository.DocumentTemplate.DocumentTemplateScopes.Device).ToList();
.Where(at => at.Scope == DocumentTemplate.DocumentTemplateScopes.Device).ToList();
return ats.Where(at => at.FilterExpressionMatches(d, Database, User, TimeStamp, DocumentState.DefaultState())).ToList();
}
public static bool UpdateLastNetworkLogonDate(this Device Device)
{
return Disco.Services.Interop.ActiveDirectory.ADNetworkLogonDatesUpdateTask.UpdateLastNetworkLogonDate(Device);
}
public static DeviceAttachment CreateAttachment(this Device Device, DiscoDataContext Database, User CreatorUser, string Filename, string MimeType, string Comments, Stream Content, DocumentTemplate DocumentTemplate = null, byte[] PdfThumbnail = null)
{
if (string.IsNullOrEmpty(MimeType) || MimeType.Equals("unknown/unknown", StringComparison.OrdinalIgnoreCase))
MimeType = Interop.MimeTypes.ResolveMimeType(Filename);
DeviceAttachment da = new DeviceAttachment()
{
DeviceSerialNumber = Device.SerialNumber,
TechUserId = CreatorUser.UserId,
Filename = Filename,
MimeType = MimeType,
Timestamp = DateTime.Now,
Comments = Comments
};
if (DocumentTemplate != null)
da.DocumentTemplateId = DocumentTemplate.Id;
Database.DeviceAttachments.Add(da);
Database.SaveChanges();
da.SaveAttachment(Database, Content);
Content.Position = 0;
if (PdfThumbnail == null)
da.GenerateThumbnail(Database, Content);
else
da.SaveThumbnailAttachment(Database, PdfThumbnail);
return da;
return ADNetworkLogonDatesUpdateTask.UpdateLastNetworkLogonDate(Device);
}
public static Device AddOffline(this Device d, DiscoDataContext Database)
@@ -189,15 +159,7 @@ namespace Disco.BI.Extensions
return newDua;
}
public static ADMachineAccount ActiveDirectoryAccount(this Device Device, params string[] AdditionalProperties)
{
if (ActiveDirectory.IsValidDomainAccountId(Device.DeviceDomainId))
return ActiveDirectory.RetrieveADMachineAccount(Device.DeviceDomainId, AdditionalProperties: AdditionalProperties);
else
return null;
}
public static string ReasonMessage(this Disco.Models.Repository.DecommissionReasons r)
public static string ReasonMessage(this DecommissionReasons r)
{
switch (r)
{
@@ -220,7 +182,7 @@ namespace Disco.BI.Extensions
}
}
public static string ReasonMessage(this Disco.Models.Repository.DecommissionReasons? r)
public static string ReasonMessage(this DecommissionReasons? r)
{
if (!r.HasValue)
return "Not Decommissioned";
@@ -1,79 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Disco.Data.Repository;
using Disco.Models.Repository;
using System.IO;
using System.Drawing;
using Disco.Data.Repository;
using Disco.Services.Users;
using Disco.Services;
using Disco.Services.Authorization;
using Disco.Services.Users;
using System;
using System.IO;
using System.Linq;
namespace Disco.BI.Extensions
{
public static class DeviceModelExtensions
{
public static bool ImageImport(this DeviceModel deviceModel, Stream ImageStream)
{
try
{
using (Bitmap inputBitmap = new Bitmap(ImageStream))
{
using (Image outputBitmap = inputBitmap.ResizeImage(256, 256))
{
using (MemoryStream ms = new MemoryStream())
{
outputBitmap.SavePng(ms);
ms.Position = 0;
var deviceModelImagePath = deviceModel.ImageFilePath();
using (var storeStream = new FileStream(deviceModelImagePath, FileMode.Create, FileAccess.Write, FileShare.None))
{
ms.CopyTo(storeStream);
}
//deviceModel.Image = ms.ToArray();
}
}
}
return true;
}
catch (Exception)
{
return false;
}
}
public static FileStream Image(this DeviceModel deviceModel)
{
var deviceModelImagePath = deviceModel.ImageFilePath();
if (File.Exists(deviceModelImagePath))
return new FileStream(deviceModelImagePath, FileMode.Open, FileAccess.Read, FileShare.Read);
else
return null;
}
public static string ImageFilePath(this DeviceModel deviceModel)
{
var configCache = new Disco.Data.Configuration.SystemConfiguration(null);
var deviceModelImagesDataStore = DataStore.CreateLocation(configCache, "DeviceModelImages");
return Path.Combine(deviceModelImagesDataStore, string.Format("{0}.png", deviceModel.Id));
}
public static string ImageHash(this DeviceModel deviceModel)
{
var deviceModelImagePath = deviceModel.ImageFilePath();
if (File.Exists(deviceModelImagePath))
return File.GetLastWriteTimeUtc(deviceModelImagePath).ToBinary().ToString();
else
return "-1";
}
#region Actions
public static bool CanDelete(this DeviceModel dm, DiscoDataContext Database)
{
@@ -3,6 +3,7 @@ using Disco.Models.BI.Config;
using Disco.Models.Repository;
using Disco.Services.Authorization;
using Disco.Services.Devices.ManagedGroups;
using Disco.Services.Expressions;
using Disco.Services.Interop.ActiveDirectory;
using Disco.Services.Users;
using System;
@@ -16,7 +17,7 @@ namespace Disco.BI.Extensions
public static void ComputerNameInvalidateCache(this DeviceProfile deviceProfile)
{
Expressions.ExpressionCache.InvalidateKey(ComputerNameExpressionCacheModule, deviceProfile.Id.ToString());
ExpressionCache.InvalidateKey(ComputerNameExpressionCacheModule, deviceProfile.Id.ToString());
}
public static OrganisationAddress DefaultOrganisationAddressDetails(this DeviceProfile deviceProfile, DiscoDataContext Database)
@@ -1,48 +1,27 @@
using Disco.BI.DocumentTemplateBI;
using Disco.BI.DocumentTemplateBI.ManagedGroups;
using Disco.BI.Expressions;
using Disco.Data.Repository;
using Disco.Models.BI.DocumentTemplates;
using Disco.Models.Repository;
using Disco.Models.Services.Documents;
using Disco.Services;
using Disco.Services.Documents;
using Disco.Services.Expressions;
using Disco.Services.Interop.ActiveDirectory;
using iTextSharp.text.pdf;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
namespace Disco.BI.Extensions
{
public static class DocumentTemplateExtensions
{
private const string DocumentTemplateExpressionCacheTemplate = "DocumentTemplate_{0}";
public static string RepositoryFilename(this DocumentTemplate dt, DiscoDataContext Database)
{
return System.IO.Path.Combine(DataStore.CreateLocation(Database, "DocumentTemplates"), string.Format("{0}.pdf", dt.Id));
}
public static string SavePdfTemplate(this DocumentTemplate dt, DiscoDataContext Database, Stream TemplateFile)
{
string filePath = dt.RepositoryFilename(Database);
using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
TemplateFile.CopyTo(fs);
}
Expressions.ExpressionCache.InvalidModule(string.Format(DocumentTemplateExpressionCacheTemplate, dt.Id));
return filePath;
}
public static DisposableImageCollection PdfPageImages(this PdfReader pdfReader, int PageNumber)
{
return Interop.Pdf.PdfImporter.GetPageImages(pdfReader, PageNumber);
}
internal const string CacheTemplate = "DocumentTemplate_{0}";
public static ConcurrentDictionary<string, Expression> PdfExpressionsFromCache(this DocumentTemplate dt, DiscoDataContext Database)
{
string cacheModuleKey = string.Format(DocumentTemplateExpressionCacheTemplate, dt.Id);
var module = Expressions.ExpressionCache.GetModule(cacheModuleKey);
string cacheModuleKey = string.Format(CacheTemplate, dt.Id);
var module = ExpressionCache.GetModule(cacheModuleKey);
if (module == null)
{
// Cache
@@ -52,199 +31,46 @@ namespace Disco.BI.Extensions
foreach (string pdfFieldKey in pdfReader.AcroFields.Fields.Keys)
{
var pdfFieldValue = pdfReader.AcroFields.GetField(pdfFieldKey);
Expressions.ExpressionCache.SetValue(cacheModuleKey, pdfFieldKey, Expressions.Expression.Tokenize(pdfFieldKey, pdfFieldValue, pdfFieldOrdinal));
ExpressionCache.SetValue(cacheModuleKey, pdfFieldKey, Expression.Tokenize(pdfFieldKey, pdfFieldValue, pdfFieldOrdinal));
pdfFieldOrdinal++;
}
pdfReader.Close();
module = Expressions.ExpressionCache.GetModule(cacheModuleKey, true);
module = ExpressionCache.GetModule(cacheModuleKey, true);
}
return module;
}
public static List<BI.Expressions.Expression> ExtractPdfExpressions(this DocumentTemplate dt, DiscoDataContext Database)
public static List<Expression> ExtractPdfExpressions(this DocumentTemplate dt, DiscoDataContext Database)
{
return dt.PdfExpressionsFromCache(Database).Values.OrderBy(e => e.Ordinal).ToList();
}
public static System.IO.Stream GeneratePdfBulk(this DocumentTemplate dt, DiscoDataContext Database, User CreatorUser, System.DateTime Timestamp, params string[] DataObjectsIds)
public static System.IO.Stream GeneratePdfBulk(this DocumentTemplate dt, DiscoDataContext Database, User CreatorUser, DateTime Timestamp, params string[] DataObjectsIds)
{
return Interop.Pdf.PdfGenerator.GenerateBulkFromTemplate(dt, Database, CreatorUser, Timestamp, DataObjectsIds);
}
public static System.IO.Stream GeneratePdfBulk(this DocumentTemplate dt, DiscoDataContext Database, User CreatorUser, System.DateTime Timestamp, params object[] DataObjects)
public static System.IO.Stream GeneratePdfBulk(this DocumentTemplate dt, DiscoDataContext Database, User CreatorUser, DateTime Timestamp, params IAttachmentTarget[] DataObjects)
{
return Interop.Pdf.PdfGenerator.GenerateBulkFromTemplate(dt, Database, CreatorUser, Timestamp, DataObjects);
}
public static System.IO.Stream GeneratePdf(this DocumentTemplate dt, DiscoDataContext Database, object Data, User CreatorUser, System.DateTime TimeStamp, DocumentState State, bool FlattenFields = false)
public static System.IO.Stream GeneratePdf(this DocumentTemplate dt, DiscoDataContext Database, IAttachmentTarget Target, User CreatorUser, DateTime TimeStamp, DocumentState State, bool FlattenFields = false)
{
bool generateExpression = !string.IsNullOrEmpty(dt.OnGenerateExpression);
string generateExpressionResult = null;
if (generateExpression)
generateExpressionResult = dt.EvaluateOnGenerateExpression(Data, Database, CreatorUser, TimeStamp, State);
generateExpressionResult = dt.EvaluateOnGenerateExpression(Target, Database, CreatorUser, TimeStamp, State);
var pdfStream = Interop.Pdf.PdfGenerator.GenerateFromTemplate(dt, Database, Data, CreatorUser, TimeStamp, State, FlattenFields);
var pdfStream = Interop.Pdf.PdfGenerator.GenerateFromTemplate(dt, Database, Target, CreatorUser, TimeStamp, State, FlattenFields);
if (generateExpression)
DocumentsLog.LogDocumentGenerated(dt, Data, CreatorUser, generateExpressionResult);
DocumentsLog.LogDocumentGenerated(dt, Target, CreatorUser, generateExpressionResult);
else
DocumentsLog.LogDocumentGenerated(dt, Data, CreatorUser);
DocumentsLog.LogDocumentGenerated(dt, Target, CreatorUser);
return pdfStream;
}
public static Expression FilterExpressionFromCache(this DocumentTemplate dt)
{
return ExpressionCache.GetValue("DocumentTemplate_FilterExpression", dt.Id, () => { return Expression.TokenizeSingleDynamic(null, dt.FilterExpression, 0); });
}
public static void FilterExpressionInvalidateCache(this DocumentTemplate dt)
{
ExpressionCache.InvalidateKey("DocumentTemplate_FilterExpression", dt.Id);
}
public static bool FilterExpressionMatches(this DocumentTemplate dt, object Data, DiscoDataContext Database, User User, System.DateTime TimeStamp, DocumentState State)
{
if (!string.IsNullOrEmpty(dt.FilterExpression))
{
Expression compiledExpression = dt.FilterExpressionFromCache();
System.Collections.IDictionary evaluatorVariables = Expression.StandardVariables(dt, Database, User, TimeStamp, State);
try
{
object er = compiledExpression.EvaluateFirst<object>(Data, evaluatorVariables);
if (er is bool)
{
return (bool)er;
}
bool erBool;
if (bool.TryParse(er.ToString(), out erBool))
{
return erBool;
}
}
catch
{
return false;
}
}
return true;
}
public static Expression OnImportAttachmentExpressionFromCache(this DocumentTemplate dt)
{
return ExpressionCache.GetValue("DocumentTemplate_OnImportExpression", dt.Id, () => { return Expression.TokenizeSingleDynamic(null, dt.OnImportAttachmentExpression, 0); });
}
public static void OnImportAttachmentExpressionInvalidateCache(this DocumentTemplate dt)
{
ExpressionCache.InvalidateKey("DocumentTemplate_OnImportExpression", dt.Id);
}
public static string EvaluateOnAttachmentImportExpression(this DocumentTemplate dt, object Data, DiscoDataContext Database, User User, System.DateTime TimeStamp)
{
if (!string.IsNullOrEmpty(dt.OnImportAttachmentExpression))
{
Expression compiledExpression = dt.OnImportAttachmentExpressionFromCache();
System.Collections.IDictionary evaluatorVariables = Expression.StandardVariables(dt, Database, User, TimeStamp, null);
try
{
object result = compiledExpression.EvaluateFirst<object>(Data, evaluatorVariables);
if (result == null)
return null;
else
return result.ToString();
}
catch
{
throw;
}
}
return null;
}
public static Expression OnGenerateExpressionFromCache(this DocumentTemplate dt)
{
return ExpressionCache.GetValue("DocumentTemplate_OnGenerateExpression", dt.Id, () => { return Expression.TokenizeSingleDynamic(null, dt.OnGenerateExpression, 0); });
}
public static void OnGenerateExpressionInvalidateCache(this DocumentTemplate dt)
{
ExpressionCache.InvalidateKey("DocumentTemplate_OnGenerateExpression", dt.Id);
}
public static string EvaluateOnGenerateExpression(this DocumentTemplate dt, object Data, DiscoDataContext Database, User User, System.DateTime TimeStamp, DocumentState State)
{
if (!string.IsNullOrEmpty(dt.OnGenerateExpression))
{
Expression compiledExpression = dt.OnGenerateExpressionFromCache();
System.Collections.IDictionary evaluatorVariables = Expression.StandardVariables(dt, Database, User, TimeStamp, State);
try
{
object result = compiledExpression.EvaluateFirst<object>(Data, evaluatorVariables);
return result.ToString();
}
catch
{
throw;
}
}
return null;
}
public static string GetDataId(this DocumentTemplate dt, object Data)
{
if (Data is string)
{
return (string)Data;
}
else
{
switch (dt.Scope)
{
case Models.Repository.DocumentTemplate.DocumentTemplateScopes.Device:
if (!(Data is Device))
throw new ArgumentException("This Document Template is configured for Devices only", "Data");
Device d = (Device)Data;
return d.SerialNumber;
case Models.Repository.DocumentTemplate.DocumentTemplateScopes.Job:
if (!(Data is Job))
throw new ArgumentException("This Document Template is configured for Jobs only", "Data");
Job d2 = (Job)Data;
return d2.Id.ToString();
case Models.Repository.DocumentTemplate.DocumentTemplateScopes.User:
if (!(Data is User))
throw new ArgumentException("This Document Template is configured for Users only", "Data");
User d3 = (User)Data;
return d3.UserId;
default:
throw new InvalidOperationException("Invalid Document Template Scope");
}
}
}
public static string UniqueIdentifier(string DocumentTemplateId, string DataId, string CreatorId, System.DateTime Timestamp)
{
return string.Format("Disco|1|{0}|{1}|{2}|{3:s}",
DocumentTemplateId,
DataId,
CreatorId,
Timestamp
);
}
public static string UniqueIdentifier(this DocumentTemplate dt, object Data, string CreatorId, System.DateTime Timestamp)
{
return string.Format("Disco|1|{0}|{1}|{2}|{3:s}",
dt.Id,
dt.GetDataId(System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(Data)),
CreatorId,
Timestamp
);
}
public static string UniquePageIdentifier(this DocumentTemplate dt, object Data, string CreatorId, System.DateTime Timestamp, int Page)
{
return string.Format("Disco|1|{0}|{1}|{2}|{3:s}|{4}",
dt.Id,
dt.GetDataId(System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(Data)),
CreatorId,
Timestamp,
Page
);
}
public static List<RectangleF> QRCodeLocations(this DocumentTemplate dt, DiscoDataContext Database)
{
return DocumentTemplateBI.DocumentTemplateQRCodeLocationCache.GetLocations(dt, Database);
}
public static void Delete(this DocumentTemplate dt, DiscoDataContext Database)
{
// Find & Rename all references
@@ -13,6 +13,7 @@ using Disco.Services.Plugins.Features.RepairProvider;
using PublishJobResult = Disco.Models.Services.Interop.DiscoServices.PublishJobResult;
using DiscoServicesJobs = Disco.Services.Interop.DiscoServices.Jobs;
using Disco.Services;
namespace Disco.BI.Extensions
{
@@ -176,7 +177,7 @@ namespace Disco.BI.Extensions
null,
FaultDescription,
SendAttachments,
Disco.BI.Extensions.AttachmentExtensions.RepositoryFilename);
AttachmentDataStoreExtensions.RepositoryFilename);
if (!publishJobResult.Success)
throw new Exception(string.Format("Disco ICT Online Services failed with the following message: ", publishJobResult.ErrorMessage));
@@ -398,7 +399,7 @@ namespace Disco.BI.Extensions
null,
RepairDescription,
SendAttachments,
Disco.BI.Extensions.AttachmentExtensions.RepositoryFilename);
AttachmentDataStoreExtensions.RepositoryFilename);
if (!publishJobResult.Success)
throw new Exception(string.Format("Disco ICT Online Services failed with the following message: ", publishJobResult.ErrorMessage));
+7 -39
View File
@@ -1,50 +1,18 @@
using System;
using Disco.Data.Repository;
using Disco.Models.Repository;
using Disco.Models.Services.Documents;
using Disco.Services;
using Disco.Services.Authorization;
using Disco.Services.Plugins;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Disco.Models.Repository;
using Disco.Data.Repository;
using System.IO;
using Disco.Models.BI.DocumentTemplates;
using Disco.Services.Plugins;
using Disco.Models.BI.Job;
using Disco.Services.Authorization;
namespace Disco.BI.Extensions
{
public static class JobExtensions
{
public static JobAttachment CreateAttachment(this Job Job, DiscoDataContext Database, User CreatorUser, string Filename, string MimeType, string Comments, Stream Content, DocumentTemplate DocumentTemplate = null, byte[] PdfThumbnail = null)
{
if (string.IsNullOrEmpty(MimeType) || MimeType.Equals("unknown/unknown", StringComparison.OrdinalIgnoreCase))
MimeType = Interop.MimeTypes.ResolveMimeType(Filename);
JobAttachment ja = new JobAttachment()
{
JobId = Job.Id,
TechUserId = CreatorUser.UserId,
Filename = Filename,
MimeType = MimeType,
Timestamp = DateTime.Now,
Comments = Comments
};
if (DocumentTemplate != null)
ja.DocumentTemplateId = DocumentTemplate.Id;
Database.JobAttachments.Add(ja);
Database.SaveChanges();
ja.SaveAttachment(Database, Content);
Content.Position = 0;
if (PdfThumbnail == null)
ja.GenerateThumbnail(Database, Content);
else
ja.SaveThumbnailAttachment(Database, PdfThumbnail);
return ja;
}
public static List<DocumentTemplate> AvailableDocumentTemplates(this Job j, DiscoDataContext Database, User User, DateTime TimeStamp)
{
var dts = Database.DocumentTemplates.Include("JobSubTypes")
+5 -42
View File
@@ -1,48 +1,15 @@
using System;
using Disco.Data.Repository;
using Disco.Models.Repository;
using Disco.Models.Services.Documents;
using Disco.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Disco.Models.Repository;
using Disco.Data.Repository;
using System.IO;
using Disco.Models.BI.DocumentTemplates;
using Disco.Services.Interop.ActiveDirectory;
namespace Disco.BI.Extensions
{
public static class UserExtensions
{
public static UserAttachment CreateAttachment(this User User, DiscoDataContext Database, User CreatorUser, string Filename, string MimeType, string Comments, Stream Content, DocumentTemplate DocumentTemplate = null, byte[] PdfThumbnail = null)
{
if (string.IsNullOrEmpty(MimeType) || MimeType.Equals("unknown/unknown", StringComparison.OrdinalIgnoreCase))
MimeType = Interop.MimeTypes.ResolveMimeType(Filename);
UserAttachment ua = new UserAttachment()
{
UserId = User.UserId,
TechUserId = CreatorUser.UserId,
Filename = Filename,
MimeType = MimeType,
Timestamp = DateTime.Now,
Comments = Comments
};
if (DocumentTemplate != null)
ua.DocumentTemplateId = DocumentTemplate.Id;
Database.UserAttachments.Add(ua);
Database.SaveChanges();
ua.SaveAttachment(Database, Content);
Content.Position = 0;
if (PdfThumbnail == null)
ua.GenerateThumbnail(Database, Content);
else
ua.SaveThumbnailAttachment(Database, PdfThumbnail);
return ua;
}
public static List<DocumentTemplate> AvailableDocumentTemplates(this User u, DiscoDataContext Database, User User, DateTime TimeStamp)
{
var dts = Database.DocumentTemplates.Include("JobSubTypes")
@@ -57,10 +24,6 @@ namespace Disco.BI.Extensions
{
return u.DeviceUserAssignments.Where(dua => !dua.UnassignedDate.HasValue).ToList();
}
public static ADUserAccount ActiveDirectoryAccount(this User User, params string[] AdditionalProperties)
{
return ActiveDirectory.RetrieveADUserAccount(User.UserId, AdditionalProperties);
}
public static bool CanCreateJob(this User u)
{
+1 -235
View File
@@ -22,240 +22,6 @@ namespace Disco.BI.Extensions
return sr.ReadToEnd();
}
}
#region Image Extensions
public static Bitmap RotateImage(this Image Source, float Angle, Brush BackgroundColor = null, bool ResizeIfOver45Deg = true)
{
int destWidth = Source.Width;
int destHeight = Source.Height;
bool resizedDest = false;
if (ResizeIfOver45Deg && ((Angle > 45 && Angle < 135) || (Angle < -45 && Angle > -135)))
{
destWidth = Source.Height;
destHeight = Source.Width;
resizedDest = true;
}
Bitmap destination = new Bitmap(destWidth, destHeight);
destination.SetResolution(Source.HorizontalResolution, Source.VerticalResolution);
using (Graphics destinationGraphics = Graphics.FromImage(destination))
{
destinationGraphics.CompositingQuality = CompositingQuality.HighQuality;
destinationGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
destinationGraphics.SmoothingMode = SmoothingMode.HighQuality;
if (BackgroundColor != null)
destinationGraphics.FillRectangle(BackgroundColor, destinationGraphics.VisibleClipBounds);
float offsetWidth = destWidth / 2;
float offsetHeight = destHeight / 2;
destinationGraphics.TranslateTransform(offsetWidth, offsetHeight);
destinationGraphics.RotateTransform(Angle);
RectangleF destinationLocation;
if (resizedDest)
destinationLocation = new RectangleF(
offsetHeight * -1, offsetWidth * -1,
destHeight, destWidth);
else
destinationLocation = new RectangleF(
offsetWidth * -1, offsetHeight * -1,
destWidth, destHeight);
destinationGraphics.DrawImage(Source, destinationLocation, new RectangleF(0, 0, Source.Width, Source.Height), GraphicsUnit.Pixel);
}
return destination;
}
public static Bitmap ResizeImage(this Image Source, int Width, int Height, Brush BackgroundColor = null)
{
Bitmap destination = new Bitmap(Width, Height);
destination.SetResolution(72, 72);
using (Graphics destinationGraphics = Graphics.FromImage(destination))
{
destinationGraphics.CompositingQuality = CompositingQuality.HighQuality;
destinationGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
destinationGraphics.SmoothingMode = SmoothingMode.HighQuality;
if (BackgroundColor != null)
destinationGraphics.FillRectangle(BackgroundColor, destinationGraphics.VisibleClipBounds);
float ratio = Math.Min((float)(destination.Width) / (float)(Source.Width), (float)(destination.Height) / (float)(Source.Height));
destinationGraphics.DrawImageResized(Source, ratio);
}
return destination;
}
public static void DrawImageResized(this Graphics graphics, Image SourceImage, float? Scale = null, float LocationX = -1, float LocationY = -1)
{
RectangleF clipBounds = graphics.VisibleClipBounds;
if (Scale == null) // Calculate Scale
Scale = Math.Min(clipBounds.Width / SourceImage.Width, clipBounds.Height / SourceImage.Height);
float newWidth = SourceImage.Width * Scale.Value;
float newHeight = SourceImage.Height * Scale.Value;
float newLeft = LocationX;
float newTop = LocationY;
if (newLeft < 0 || newTop < 0)
{
if (newWidth < clipBounds.Width)
newLeft = (clipBounds.Width - newWidth) / 2;
else
newLeft = 0;
if (newHeight < clipBounds.Height)
newTop = (clipBounds.Height - newHeight) / 2;
else
newTop = 0;
}
newLeft += clipBounds.Left;
newTop += clipBounds.Top;
graphics.DrawImage(SourceImage, new RectangleF(newLeft, newTop, newWidth, newHeight), new RectangleF(0, 0, SourceImage.Width, SourceImage.Height), GraphicsUnit.Pixel);
}
public static void EmbedIconOverlay(this Image Source, Image Icon)
{
int top = Math.Max(0, Source.Height - Icon.Height);
int left = Math.Max(0, Source.Width - Icon.Width);
using (Graphics sourceGraphics = Graphics.FromImage(Source))
{
sourceGraphics.DrawImage(Icon, left, top);
}
}
public static void SavePng(this Image Source, string Filename)
{
using (FileStream outStream = new FileStream(Filename, FileMode.Create, FileAccess.Write, FileShare.None))
{
SavePng(Source, outStream);
outStream.Flush();
outStream.Close();
}
}
public static void SavePng(this Image Source, Stream OutStream)
{
Source.Save(OutStream, ImageFormat.Png);
}
public static Stream SavePng(this Image Source)
{
MemoryStream outStream = new MemoryStream();
Source.SavePng(outStream);
outStream.Position = 0;
return outStream;
}
public static Stream SaveJpg(this Image Source, int Quality)
{
MemoryStream outStream = new MemoryStream();
Source.SaveJpg(Quality, outStream);
outStream.Position = 0;
return outStream;
}
public static void SaveJpg(this Image Source, int Quality, string Filename)
{
using (FileStream outStream = new FileStream(Filename, FileMode.Create, FileAccess.Write, FileShare.None))
{
SaveJpg(Source, Quality, outStream);
outStream.Flush();
outStream.Close();
}
}
public static void SaveJpg(this Image Source, int Quality, Stream OutStream)
{
ImageCodecInfo jpgCodec = ImageCodecInfo.GetImageEncoders().Where(c => c.MimeType.Equals("image/jpeg", StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
if (jpgCodec != null)
{
if (Quality < 0 || Quality > 100)
throw new ArgumentOutOfRangeException("Quality", "Quality must be a positive integer <= 100");
using (EncoderParameters ep = new EncoderParameters(1))
{
ep.Param[0] = new EncoderParameter(Encoder.Quality, Quality);
Source.Save(OutStream, jpgCodec, ep);
}
}
else
{
// Fallback
Source.Save(OutStream, ImageFormat.Jpeg);
}
}
public static ImageMontage BuildImageMontage(this IEnumerable<Image> Images, int MaxHeight = -1, int MaxWidth = -1, bool EnforceDimensions = false)
{
if (EnforceDimensions && (MaxHeight < 0 || MaxWidth < 0))
throw new ArgumentOutOfRangeException("EnforceDimensions", "Dimensions can only be enforced when a MaxHeight and MaxWidth is supplied");
Dictionary<Image, int> imageLocations = new Dictionary<Image, int>();
double imageScale = 1.0;
int totalHeight = Images.Max(i => i.Height);
int totalWidth = Images.Sum(i => i.Width);
if (MaxHeight > 0 && totalHeight > MaxHeight)
{
imageScale = (double)MaxHeight / (double)totalHeight;
}
if (MaxWidth > 0 && totalWidth > MaxWidth)
{
imageScale = System.Math.Min(imageScale, (double)MaxWidth / (double)totalWidth);
}
int scaledHeight = EnforceDimensions ? MaxHeight : (int)System.Math.Round((double)totalHeight * imageScale);
int scaledWidth = EnforceDimensions ? MaxWidth : (int)System.Math.Round((double)totalWidth * imageScale);
System.Drawing.Bitmap imageResult = new System.Drawing.Bitmap(scaledWidth, scaledHeight);
imageResult.SetResolution(72f, 72f);
using (Graphics g = Graphics.FromImage(imageResult))
{
g.FillRectangle(Brushes.White, new Rectangle(Point.Empty, imageResult.Size));
int imageResultNextOffset = 0;
foreach (Image i in Images)
{
Rectangle imagePosition = new Rectangle(imageResultNextOffset, 0, (int)System.Math.Round((double)i.Width * imageScale), (int)System.Math.Round((double)i.Height * imageScale));
System.Drawing.Rectangle imageSize = new System.Drawing.Rectangle(0, 0, i.Width, i.Height);
g.DrawImage(i, imagePosition, imageSize, System.Drawing.GraphicsUnit.Pixel);
imageLocations[i] = imageResultNextOffset;
imageResultNextOffset += imagePosition.Width;
}
}
return new ImageMontage() { Montage = imageResult, MontageScale = imageScale, MontageSourceImageOffsets = imageLocations };
}
public class ImageMontage : IDisposable
{
public Image Montage { get; set; }
public double MontageScale { get; set; }
public Dictionary<Image, int> MontageSourceImageOffsets { get; set; }
public void Dispose()
{
if (Montage != null)
{
Montage.Dispose();
Montage = null;
}
if (MontageSourceImageOffsets != null)
{
MontageSourceImageOffsets.Clear();
MontageSourceImageOffsets = null;
}
}
}
public static Color InterpolateColours(this Color Start, Color End, double Progress)
{
if (Progress > 1 || Progress < 0)
throw new ArgumentOutOfRangeException("Progress", "Progress must be >= 0 && <= 1");
return Color.FromArgb(
(byte)(Start.A * (1 - Progress) + (End.A * Progress)),
(byte)(Start.R * (1 - Progress) + (End.R * Progress)),
(byte)(Start.G * (1 - Progress) + (End.G * Progress)),
(byte)(Start.B * (1 - Progress) + (End.B * Progress))
);
}
#endregion
}
}
-85
View File
@@ -1,85 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
namespace Disco.BI.Interop
{
public static class MimeTypes
{
public static string ResolveMimeType(string Filename)
{
string fileExtension;
if (Filename.Contains("."))
fileExtension = Filename.Substring(Filename.LastIndexOf(".") + 1).ToLower();
else
fileExtension = Filename.ToLower();
// Try Known Mime Types
switch (fileExtension)
{
case "pdf":
return "application/pdf";
case "doc":
return "application/msword";
case "docx":
return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
case "docm":
return "application/vnd.ms-word.document.macroEnabled.12";
case "xml":
return "text/xml";
case "xls":
return "application/vnd.ms-excel";
case "xlsx":
return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
case "xlsm":
return "application/vnd.ms-excel.sheet.macroEnabled.12";
case "csv":
return "application/vnd.ms-excel";
case "jpg":
return "image/jpeg";
case "gif":
return "image/gif";
case "png":
return "image/png";
case "bmp":
return "image/bmp";
case "avi":
return "video/avi";
case "mpeg":
case "mpg":
return "video/mpeg";
case "mp3":
return "audio/mpeg";
case "mp4":
return "video/mp4";
case "wmv":
return "video/x-ms-wmv";
case "mov":
return "video/quicktime";
}
// Check System Registry
try
{
RegistryKey regExtensionKey = Registry.ClassesRoot.OpenSubKey("." + fileExtension);
if (regExtensionKey != null)
{
string regExtensionContentType = regExtensionKey.GetValue("Content Type") as string;
if (regExtensionContentType != null)
{
return regExtensionContentType;
}
}
}
catch
{
// Ignore Errors
}
// Return Default
return "unknown/unknown";
}
}
}
+13 -12
View File
@@ -1,9 +1,10 @@
using Disco.BI.Expressions;
using Disco.BI.Extensions;
using Disco.BI.Extensions;
using Disco.Data.Repository;
using Disco.Models.BI.DocumentTemplates;
using Disco.Models.BI.Expressions;
using Disco.Models.Repository;
using Disco.Models.Services.Documents;
using Disco.Services;
using Disco.Services.Expressions;
using Disco.Services.Interop.ActiveDirectory;
using Disco.Services.Users;
using iTextSharp.text.pdf;
@@ -19,14 +20,14 @@ namespace Disco.BI.Interop.Pdf
public static class PdfGenerator
{
public static System.IO.Stream GenerateBulkFromTemplate(DocumentTemplate dt, DiscoDataContext Database, User CreatorUser, System.DateTime Timestamp, params object[] DataObjects)
public static Stream GenerateBulkFromTemplate(DocumentTemplate dt, DiscoDataContext Database, User CreatorUser, System.DateTime Timestamp, params IAttachmentTarget[] DataObjects)
{
if (DataObjects.Length > 0)
{
List<Stream> generatedPdfs = new List<Stream>(DataObjects.Length);
using (Models.BI.DocumentTemplates.DocumentState state = Models.BI.DocumentTemplates.DocumentState.DefaultState())
using (var state = DocumentState.DefaultState())
{
foreach (object d in DataObjects)
foreach (var d in DataObjects)
{
generatedPdfs.Add(dt.GeneratePdf(Database, d, CreatorUser, Timestamp, state, true));
state.SequenceNumber++;
@@ -48,9 +49,9 @@ namespace Disco.BI.Interop.Pdf
return null;
}
public static System.IO.Stream GenerateBulkFromTemplate(DocumentTemplate dt, DiscoDataContext Database, User CreatorUser, System.DateTime Timestamp, params string[] DataObjectsIds)
public static Stream GenerateBulkFromTemplate(DocumentTemplate dt, DiscoDataContext Database, User CreatorUser, DateTime Timestamp, params string[] DataObjectsIds)
{
object[] DataObjects;
IAttachmentTarget[] DataObjects;
switch (dt.Scope)
{
@@ -62,7 +63,7 @@ namespace Disco.BI.Interop.Pdf
DataObjects = Database.Jobs.Where(j => intDataObjectsIds.Contains(j.Id)).ToArray();
break;
case DocumentTemplate.DocumentTemplateScopes.User:
DataObjects = new object[DataObjectsIds.Length];
DataObjects = new IAttachmentTarget[DataObjectsIds.Length];
for (int idIndex = 0; idIndex < DataObjectsIds.Length; idIndex++)
{
string dataObjectId = DataObjectsIds[idIndex];
@@ -79,7 +80,7 @@ namespace Disco.BI.Interop.Pdf
return GenerateBulkFromTemplate(dt, Database, CreatorUser, Timestamp, DataObjects);
}
public static System.IO.Stream GenerateFromTemplate(DocumentTemplate dt, DiscoDataContext Database, object Data, User CreatorUser, System.DateTime TimeStamp, DocumentState State, bool FlattenFields = false)
public static Stream GenerateFromTemplate(DocumentTemplate dt, DiscoDataContext Database, IAttachmentTarget Data, User CreatorUser, DateTime TimeStamp, DocumentState State, bool FlattenFields = false)
{
// Validate Data
switch (dt.Scope)
@@ -124,7 +125,7 @@ namespace Disco.BI.Interop.Pdf
if (pdfFieldKey.Equals("DiscoAttachmentId", StringComparison.OrdinalIgnoreCase))
{
AcroFields.Item fields = pdfStamper.AcroFields.Fields[pdfFieldKey];
string fieldValue = dt.UniqueIdentifier(Data, CreatorUser.UserId, TimeStamp);
string fieldValue = dt.CreateUniqueIdentifier(Database, Data, CreatorUser, TimeStamp, 0).ToJson();
if (FlattenFields)
pdfStamper.AcroFields.SetField(pdfFieldKey, String.Empty);
else
@@ -134,7 +135,7 @@ namespace Disco.BI.Interop.Pdf
for (int pdfFieldOrdinal = 0; pdfFieldOrdinal < fields.Size; pdfFieldOrdinal++)
{
AcroFields.FieldPosition pdfFieldPosition = pdfFieldPositions[pdfFieldOrdinal];
string pdfBarcodeContent = dt.UniquePageIdentifier(Data, CreatorUser.UserId, TimeStamp, pdfFieldPosition.page);
string pdfBarcodeContent = dt.CreateUniqueIdentifier(Database, Data, CreatorUser, TimeStamp, pdfFieldPosition.page).ToQRCodeString();
BarcodeQRCode pdfBarcode = new BarcodeQRCode(pdfBarcodeContent, (int)pdfFieldPosition.position.Width, (int)pdfFieldPosition.position.Height, null);
iTextSharp.text.Image pdfBarcodeImage = pdfBarcode.GetImage();
pdfBarcodeImage.SetAbsolutePosition(pdfFieldPosition.position.Left, pdfFieldPosition.position.Bottom);
-977
View File
@@ -1,977 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using iTextSharp.text.pdf;
using System.IO;
using System.Drawing;
using Disco.BI.DocumentTemplateBI.Importer;
using Disco.BI.DocumentTemplateBI;
using System.Drawing.Drawing2D;
using com.google.zxing;
using com.google.zxing.multi.qrcode;
using Disco.Data.Repository;
using System.Web.Caching;
using Disco.BI.Extensions;
using Disco.Models.Repository;
using System.Collections;
using com.google.zxing.common;
using BitMiracle.LibTiff.Classic;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace Disco.BI.Interop.Pdf
{
public static class PdfImporter
{
public static RectangleF CalculateLocationRatio(this Result zxingResult, int ImageWidth, int ImageHeight)
{
var orderedPoints = zxingResult.ResultPoints.OrderBy(p => p.X * p.Y).ToArray();
var topLeftPoint = orderedPoints.First();
var bottomRightPoint = orderedPoints.Last();
var x = topLeftPoint.X;
var y = topLeftPoint.Y;
var width = bottomRightPoint.X - x;
var height = bottomRightPoint.Y - y;
return new RectangleF(
(float)System.Math.Min(1.0, System.Math.Max(0.0, (double)(x / ImageWidth) - 0.05)),
(float)System.Math.Min(1.0, System.Math.Max(0.0, (double)(y / ImageHeight) - 0.05)),
(float)System.Math.Min(1.0, System.Math.Max(0.0, (double)(width / ImageWidth) + 0.1)),
(float)System.Math.Min(1.0, System.Math.Max(0.0, (double)(height / ImageHeight) + 0.1))
);
}
private class DetectImageResult : IDisposable
{
public Result Result { get; set; }
public Point ResultOffset { get; set; }
public double ResultScale { get; set; }
public float CalculateRotation()
{
var p1 = this.Result.ResultPoints[0];
var p2 = this.Result.ResultPoints[1];
double rotOpposite = p1.X - p2.X;
double rotAdjacent = p1.Y - p2.Y;
float rotation = 0;
if (rotOpposite != 0 || rotAdjacent != 0)
{
rotation = (float)(Math.Atan2(rotOpposite, rotAdjacent) * (180 / Math.PI)); // Degrees
}
return rotation;
}
public void Dispose()
{
// Do Nothing; yet...
}
}
private class DetectStateHints
{
public List<Tuple<RectangleF, Rotation>> PriorDetections { get; set; }
public DetectStateHints()
{
this.PriorDetections = new List<Tuple<RectangleF, Rotation>>();
}
}
private enum Rotation
{
None = 0,
Degrees90 = 1,
DegreesNeg90 = 2,
Degrees180 = 3
}
private class DetectPageResult : IDisposable
{
public int PageNumber { get; set; }
public DocumentUniqueIdentifier DetectedIdentifier { get; set; }
public Disco.BI.Extensions.UtilityExtensions.ImageMontage ThumbnailImage { get; set; }
public MemoryStream AttachmentThumbnailImage { get; set; }
public Disco.BI.Extensions.UtilityExtensions.ImageMontage UndetectedPageImage { get; set; }
public void DrawThumbnailImageResult(DetectImageResult Result, Image DetectedImage)
{
if (Result.Result.ResultPoints.Length == 4)
{ // Draw Square on Thumbnail
using (Graphics thumbnailGraphics = Graphics.FromImage(ThumbnailImage.Montage))
{
var thumbnailOffset = ThumbnailImage.MontageSourceImageOffsets[DetectedImage];
var linePoints = Result.Result.ResultPoints.Select(p => new Point((int)(thumbnailOffset + ((Result.ResultOffset.X + p.X) * Result.ResultScale * ThumbnailImage.MontageScale)), (int)((p.Y + Result.ResultOffset.Y) * Result.ResultScale * ThumbnailImage.MontageScale))).ToArray();
using (GraphicsPath graphicsPath = new GraphicsPath())
{
for (int linePointIndex = 0; linePointIndex < (linePoints.Length - 1); linePointIndex++)
graphicsPath.AddLine(linePoints[linePointIndex], linePoints[linePointIndex + 1]);
graphicsPath.AddLine(linePoints[linePoints.Length - 1], linePoints[0]);
using (SolidBrush graphicsBrush = new SolidBrush(Color.FromArgb(128, 255, 0, 0)))
thumbnailGraphics.FillPath(graphicsBrush, graphicsPath);
using (Pen graphicsPen = new Pen(Color.FromArgb(200, 255, 0, 0), 2))
thumbnailGraphics.DrawPath(graphicsPen, graphicsPath);
}
}
}
}
public void Dispose()
{
if (ThumbnailImage != null)
{
ThumbnailImage.Dispose();
ThumbnailImage = null;
}
if (AttachmentThumbnailImage != null)
{
AttachmentThumbnailImage.Dispose();
AttachmentThumbnailImage = null;
}
if (UndetectedPageImage != null)
{
UndetectedPageImage.Dispose();
UndetectedPageImage = null;
}
}
}
private static Tuple<Result, Rectangle, Rotation> DetectImageFromSegment(Bitmap pageImage, QRCodeMultiReader zxingReader, Hashtable zxingReaderHints, RectangleF LocationPercentage, Rotation Rotation)
{
System.Drawing.Rectangle region;
switch (Rotation)
{
case Rotation.None: // Original Position
region = new Rectangle(
(int)(pageImage.Width * LocationPercentage.Left),
(int)(pageImage.Height * LocationPercentage.Top),
(int)(pageImage.Width * LocationPercentage.Width),
(int)(pageImage.Height * LocationPercentage.Height));
break;
case Rotation.Degrees90: // Clockwise 90 degrees
region = new Rectangle(
(int)(pageImage.Width - (pageImage.Width * (LocationPercentage.Top + LocationPercentage.Height))),
(int)(pageImage.Height * LocationPercentage.Left),
(int)(pageImage.Width * LocationPercentage.Height),
(int)(pageImage.Height * LocationPercentage.Width));
break;
case Rotation.DegreesNeg90: // Anti-clockwise 90 degrees
region = new Rectangle(
(int)(pageImage.Width * LocationPercentage.Top),
(int)(pageImage.Height - (pageImage.Height * (LocationPercentage.Left + LocationPercentage.Width))),
(int)(pageImage.Width * LocationPercentage.Height),
(int)(pageImage.Height * LocationPercentage.Width));
break;
case Rotation.Degrees180: // 180 degrees
region = new Rectangle(
(int)(pageImage.Width - (pageImage.Width * (LocationPercentage.Left + LocationPercentage.Width))),
(int)(pageImage.Height - (pageImage.Height * (LocationPercentage.Top + LocationPercentage.Height))),
(int)(pageImage.Width * LocationPercentage.Width),
(int)(pageImage.Height * LocationPercentage.Height));
break;
default:
throw new InvalidOperationException("Unknown Rotation");
}
LuminanceSource zxingSource;
using (Bitmap pageImageRegion = new Bitmap(region.Width, region.Height))
{
pageImageRegion.SetResolution(pageImage.HorizontalResolution, pageImage.VerticalResolution);
using (Graphics pageImageRegionGraphics = Graphics.FromImage(pageImageRegion))
{
pageImageRegionGraphics.DrawImage(pageImage, 0, 0, region, GraphicsUnit.Pixel);
}
zxingSource = new BitmapLuminanceSource(pageImageRegion);
}
var zxingHB = new HybridBinarizer(zxingSource);
var zxingBB = new BinaryBitmap(zxingHB);
try
{
var zxingResult = zxingReader.decode(zxingBB, zxingReaderHints);
if (zxingResult != null)
return new Tuple<Result, Rectangle, Rotation>(zxingResult, region, Rotation);
}
catch (ReaderException)
{
// Ignore Location Errors
}
return null;
}
private static DetectImageResult DetectImage(DiscoDataContext Database, Bitmap pageImageOriginal, string SessionId, IEnumerable<DocumentTemplate> detectDocumentTemplates, DetectStateHints StateHints)
{
Bitmap pageImage = pageImageOriginal;
double pageImageModifiedScale = 1;
try
{
// Resize if Resolution > 80; Set to 72 Dpi
if (pageImage.HorizontalResolution > 80 || pageImage.VerticalResolution > 80)
{
pageImageModifiedScale = pageImage.HorizontalResolution / 72;
int newWidth = (int)((72 / pageImage.HorizontalResolution) * pageImage.Width);
int newHeight = (int)((72 / pageImage.VerticalResolution) * pageImage.Height);
pageImage = pageImage.ResizeImage(newWidth, newHeight);
}
Tuple<Result, Rectangle, Rotation> result = default(Tuple<Result, Rectangle, Rotation>);
QRCodeMultiReader zxingMfr = new QRCodeMultiReader();
Hashtable zxingMfrHints = new Hashtable();
zxingMfrHints.Add(DecodeHintType.TRY_HARDER, true);
// Look in previously found locations
if (StateHints.PriorDetections.Count > 0)
{
foreach (var previousLocation in StateHints.PriorDetections)
{
result = DetectImageFromSegment(pageImage, zxingMfr, zxingMfrHints,
previousLocation.Item1, previousLocation.Item2);
if (result != null)
break;
}
}
if (result == null)
{
// Try the whole image
var zxingSource = new BitmapLuminanceSource(pageImage);
var zxingHB = new HybridBinarizer(zxingSource);
var zxingBB = new BinaryBitmap(zxingHB);
try
{
var zxingResult = zxingMfr.decode(zxingBB, zxingMfrHints);
if (zxingResult != null)
{
result = new Tuple<Result, Rectangle, Rotation>(zxingResult, new Rectangle(0, 0, pageImage.Width, pageImage.Height), Rotation.None);
StateHints.PriorDetections.Insert(0, new Tuple<RectangleF, Rotation>(
result.Item1.CalculateLocationRatio(pageImage.Width, pageImage.Height)
, Rotation.None));
}
}
catch (ReaderException)
{
// Ignore Errors
}
}
if (result == null)
{
// Look in 'Known' locations
for (int rotationIndex = 0; rotationIndex < 4; rotationIndex++)
{
foreach (DocumentTemplate dt in detectDocumentTemplates)
{
var locationBag = dt.QRCodeLocations(Database);
foreach (var location in locationBag)
{
result = DetectImageFromSegment(pageImage, zxingMfr, zxingMfrHints,
location, (Rotation)rotationIndex);
StateHints.PriorDetections.Insert(0, new Tuple<RectangleF, Rotation>(location, (Rotation)rotationIndex));
}
if (result != null)
break;
}
if (result != null)
break;
}
}
if (result != null)
return new DetectImageResult() { Result = result.Item1, ResultOffset = result.Item2.Location, ResultScale = pageImageModifiedScale };
else
return null;
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (pageImageOriginal != pageImage)
pageImage.Dispose();
}
}
private static DetectPageResult DetectPage(DiscoDataContext Database, PdfReader pdfReader, int PageNumber, string SessionId, string DataStoreSessionCacheLocation, IEnumerable<DocumentTemplate> detectDocumentTemplates, DetectStateHints StateHints)
{
DetectPageResult result = new DetectPageResult() { PageNumber = PageNumber };
DocumentsLog.LogImportPageProgress(SessionId, PageNumber, 10, "Loading Page Images");
using (DisposableImageCollection pageImages = pdfReader.PdfPageImages(PageNumber))
{
if (pageImages.Count > 0)
{
result.ThumbnailImage = pageImages.BuildImageMontage(256, 256);
var pageThumbnailFilename = Path.Combine(DataStoreSessionCacheLocation, string.Format("{0}-{1}", SessionId, PageNumber));
result.ThumbnailImage.Montage.SavePng(pageThumbnailFilename);
DocumentsLog.LogImportPageImageUpdate(SessionId, PageNumber);
double pageProgressInterval = 90 / pageImages.Count;
foreach (var pageImageOriginal in pageImages)
{
DocumentsLog.LogImportPageProgress(SessionId, PageNumber, (int)(10 + (pageProgressInterval * pageImages.IndexOf(pageImageOriginal))), String.Format("Processing Page Image {0} of {1}", pageImages.IndexOf(pageImageOriginal) + 1, pageImages.Count));
using (var zxingResult = DetectImage(Database, pageImageOriginal, SessionId, detectDocumentTemplates, StateHints))
{
if (zxingResult != null)
{
if (DocumentUniqueIdentifier.IsDocumentUniqueIdentifier(zxingResult.Result.Text))
{
float imageRotation = zxingResult.CalculateRotation();
result.DrawThumbnailImageResult(zxingResult, pageImageOriginal);
if (imageRotation != 0)
{
var preImageRotation = result.ThumbnailImage.Montage;
result.ThumbnailImage.Montage = result.ThumbnailImage.Montage.RotateImage(imageRotation);
preImageRotation.Dispose();
}
result.ThumbnailImage.Montage.SavePng(pageThumbnailFilename);
DocumentsLog.LogImportPageImageUpdate(SessionId, PageNumber);
result.AttachmentThumbnailImage = new MemoryStream();
using (var attachmentThumbImage = pageImages.BuildImageMontage(48, 48, true))
{
using (Image mimeTypeIcon = Disco.Properties.Resources.MimeType_pdf16)
attachmentThumbImage.Montage.EmbedIconOverlay(mimeTypeIcon);
if (imageRotation != 0)
{
var preImageRotation = attachmentThumbImage.Montage;
attachmentThumbImage.Montage = attachmentThumbImage.Montage.RotateImage(imageRotation, Brushes.White);
preImageRotation.Dispose();
}
attachmentThumbImage.Montage.SaveJpg(95, result.AttachmentThumbnailImage);
}
result.DetectedIdentifier = new DocumentUniqueIdentifier(zxingResult.Result.Text, PageNumber.ToString());
return result;
}
}
}
}
// Page Unassigned
result.UndetectedPageImage = pageImages.BuildImageMontage(700, 700);
}
return result;
}
}
public static bool ProcessPdfAttachment(string Filename, DiscoDataContext Database, string SessionId, Cache HttpCache)
{
var dataStoreUnassignedLocation = DataStore.CreateLocation(Database, "DocumentDropBox_Unassigned");
DocumentsLog.LogImportProgress(SessionId, 0, "Reading File");
using (FileStream fs = new FileStream(Filename, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
var pdfReader = new PdfReader(fs);
var pdfPagesAssigned = new Dictionary<int, Tuple<DocumentUniqueIdentifier, byte[]>>();
var dataStoreSessionPagesCacheLocation = DataStore.CreateLocation(Database, "Cache\\DocumentDropBox_SessionPages");
var detectDocumentTemplates = Database.DocumentTemplates.ToArray();
double progressInterval = 70 / pdfReader.NumberOfPages;
DetectStateHints detectStateHints = new DetectStateHints();
for (int PageNumber = 1; PageNumber <= pdfReader.NumberOfPages; PageNumber++)
{
DocumentsLog.LogImportProgress(SessionId, (int)(PageNumber * progressInterval), string.Format("Processing Page {0} of {1}", PageNumber, pdfReader.NumberOfPages));
DocumentsLog.LogImportPageStarting(SessionId, PageNumber);
using (var pageResult = DetectPage(Database, pdfReader, PageNumber, SessionId, dataStoreSessionPagesCacheLocation, detectDocumentTemplates, detectStateHints))
{
if (pageResult.DetectedIdentifier != null)
{
var docId = pageResult.DetectedIdentifier;
pdfPagesAssigned.Add(PageNumber, new Tuple<DocumentUniqueIdentifier, byte[]>(docId, pageResult.AttachmentThumbnailImage.ToArray()));
docId.LoadComponents(Database);
DocumentsLog.LogImportPageDetected(SessionId, PageNumber, docId.TemplateTypeId, docId.DocumentTemplate.Description, docId.DocumentTemplate.Scope, docId.DataId, docId.DataDescription);
}
else
{
// Undetected Page - Write Preview-Images while still in Memory
DocumentsLog.LogImportPageUndetected(SessionId, PageNumber);
// Thumbnail:
string unassignedImageThumbnailFilename = Path.Combine(dataStoreUnassignedLocation, string.Format("{0}_{1}_thumbnail.png", SessionId, PageNumber));
if (pageResult.ThumbnailImage != null)
pageResult.ThumbnailImage.Montage.SavePng(unassignedImageThumbnailFilename);
else
Disco.Properties.Resources.MimeType_pdf48.SavePng(unassignedImageThumbnailFilename);
// Large Preview
string unassignedImageFilename = Path.Combine(dataStoreUnassignedLocation, string.Format("{0}_{1}.jpg", SessionId, PageNumber));
if (pageResult.UndetectedPageImage != null)
pageResult.UndetectedPageImage.Montage.SaveJpg(90, unassignedImageFilename);
else
Disco.Properties.Resources.MimeType_pdf48.SaveJpg(90, unassignedImageFilename);
}
}
}
// Write out Assigned Documents
var assignedDocuments = pdfPagesAssigned.GroupBy(u => u.Value.Item1.DocumentUniqueId).ToList();
if (assignedDocuments.Count > 0)
{
progressInterval = 20 / assignedDocuments.Count;
foreach (var documentPortion in assignedDocuments)
{
DocumentsLog.LogImportProgress(SessionId, (int)(70 + (assignedDocuments.IndexOf(documentPortion) * progressInterval)), string.Format("Importing Documents {0} of {1}", assignedDocuments.IndexOf(documentPortion) + 1, assignedDocuments.Count));
var documentPortionInfo = documentPortion.First().Value;
var documentPortionIdentifier = documentPortionInfo.Item1;
var documentPortionThumbnail = documentPortionInfo.Item2;
if (!documentPortionIdentifier.LoadComponents(Database))
{
// Unknown Document Unique Id
foreach (var dp in documentPortion)
{
var tag = int.Parse(dp.Value.Item1.Tag);
if (pdfPagesAssigned.ContainsKey(tag))
pdfPagesAssigned.Remove(tag);
}
}
else
{
using (MemoryStream msBuilder = new MemoryStream())
{
var pdfDoc = new iTextSharp.text.Document();
var pdfCopy = new PdfCopy(pdfDoc, msBuilder);
pdfDoc.Open();
pdfCopy.CloseStream = false;
foreach (var dp in documentPortion.OrderBy(dg => dg.Value.Item1.Page))
{
var pageSize = pdfReader.GetPageSizeWithRotation(dp.Key);
var page = pdfCopy.GetImportedPage(pdfReader, dp.Key);
pdfDoc.SetPageSize(pageSize);
pdfDoc.NewPage();
pdfCopy.AddPage(page);
}
pdfDoc.Close();
pdfCopy.Close();
msBuilder.Position = 0;
var attachmentSuccess = documentPortionIdentifier.ImportPdfAttachment(Database, msBuilder, documentPortionThumbnail);
if (!attachmentSuccess)
{ // Unable to add Attachment
foreach (var dp in documentPortion)
{
var tag = int.Parse(dp.Value.Item1.Tag);
if (pdfPagesAssigned.ContainsKey(tag))
pdfPagesAssigned.Remove(tag);
}
}
}
}
}
}
// Write out Unassigned Pages
List<int> pdfPagesUnassigned = new List<int>();
for (int PageNumber = 1; PageNumber <= pdfReader.NumberOfPages; PageNumber++)
if (!pdfPagesAssigned.ContainsKey(PageNumber))
pdfPagesUnassigned.Add(PageNumber);
if (pdfPagesUnassigned.Count > 0)
{
progressInterval = 10 / pdfPagesUnassigned.Count;
//dataStoreUnassignedLocation
foreach (var PageNumber in pdfPagesUnassigned)
{
DocumentsLog.LogImportProgress(SessionId, (int)(90 + (pdfPagesUnassigned.IndexOf(PageNumber) * progressInterval)), string.Format("Processing Undetected Documents {0} of {1}", pdfPagesUnassigned.IndexOf(PageNumber) + 1, pdfPagesUnassigned.Count));
using (MemoryStream msBuilder = new MemoryStream())
{
var pdfDoc = new iTextSharp.text.Document();
var pdfCopy = new PdfCopy(pdfDoc, msBuilder);
pdfDoc.Open();
pdfCopy.CloseStream = false;
var pageSize = pdfReader.GetPageSizeWithRotation(PageNumber);
var page = pdfCopy.GetImportedPage(pdfReader, PageNumber);
pdfDoc.SetPageSize(pageSize);
pdfDoc.NewPage();
pdfCopy.AddPage(page);
pdfDoc.Close();
pdfCopy.Close();
File.WriteAllBytes(Path.Combine(dataStoreUnassignedLocation, string.Format("{0}_{1}.pdf", SessionId, PageNumber)), msBuilder.ToArray());
DocumentsLog.LogImportPageUndetectedStored(SessionId, PageNumber);
}
}
}
}
DocumentsLog.LogImportProgress(SessionId, 100, "Finished Importing Document");
return true;
}
public static bool ProcessPdfAttachment(string Filename, DiscoDataContext Database, string DocumentTemplateId, string DataId, string UserId, DateTime Timestamp)
{
using (FileStream fs = new FileStream(Filename, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
DocumentUniqueIdentifier identifier = new DocumentUniqueIdentifier(DocumentTemplateId, DataId, UserId, Timestamp);
identifier.LoadComponents(Database);
return identifier.ImportPdfAttachment(Database, fs, null);
}
}
public static DisposableImageCollection GetPageImages(PdfReader pdfReader, int PageNumber)
{
var pageImages = new DisposableImageCollection();
var pdfPage = pdfReader.GetPageN(PageNumber);
PdfDictionary pdfPageResouces = (PdfDictionary)((PdfDictionary)pdfPage.GetDirectObject(PdfName.RESOURCES)).GetDirectObject(PdfName.XOBJECT);
foreach (var pdfResKey in pdfPageResouces.Keys)
{
var pdfRes = pdfPageResouces.GetDirectObject(pdfResKey);
if (pdfRes.IsStream())
{
var pdfResStream = (PdfStream)pdfRes;
var pdfResSubType = pdfResStream.Get(PdfName.SUBTYPE);
if (pdfResSubType != null && pdfResSubType == PdfName.IMAGE)
{
if (pdfResStream.Get(PdfName.FILTER) == PdfName.CCITTFAXDECODE)
{ // TIFF
// Try Using GDI+ for TIFF...
var width = ((PdfNumber)(pdfResStream.Get(PdfName.WIDTH))).IntValue;
var height = ((PdfNumber)(pdfResStream.Get(PdfName.HEIGHT))).IntValue;
var bpc = ((PdfNumber)(pdfResStream.Get(PdfName.BITSPERCOMPONENT))).IntValue;
var compressionMethod = Compression.CCITTFAX3;
var decodeParams = pdfResStream.GetAsDict(PdfName.DECODEPARMS);
if (decodeParams != null && decodeParams.Contains(PdfName.K) && decodeParams.GetAsNumber(PdfName.K).IntValue < 0)
compressionMethod = Compression.CCITTFAX4;
using (MemoryStream tiffStream = PdfToTiffStream(PdfReader.GetStreamBytesRaw((PRStream)pdfResStream), width, height, bpc, compressionMethod))
{
pageImages.Add((Bitmap)Bitmap.FromStream(tiffStream));
}
continue;
}
if (pdfResStream.Get(PdfName.FILTER) == PdfName.DCTDECODE)
{ // JPG
using (MemoryStream jpgStream = new MemoryStream(PdfReader.GetStreamBytesRaw((PRStream)pdfResStream)))
{
pageImages.Add((Bitmap)Bitmap.FromStream(jpgStream, true, true));
}
continue;
}
}
}
}
return pageImages;
}
private static MemoryStream PdfToTiffStream(byte[] PdfStream, int Width, int Height, int BitsPerComponent, Compression CompressionMethod)
{
var ms = new MemoryStream();
Tiff tif = Tiff.ClientOpen("in-memory", "w", ms, new TiffStream());
tif.SetField(TiffTag.IMAGEWIDTH, Width);
tif.SetField(TiffTag.IMAGELENGTH, Height);
tif.SetField(TiffTag.COMPRESSION, CompressionMethod);
tif.SetField(TiffTag.BITSPERSAMPLE, BitsPerComponent);
tif.SetField(TiffTag.SAMPLESPERPIXEL, 1);
tif.WriteRawStrip(0, PdfStream, PdfStream.Length);
tif.Flush();
return ms;
}
}
/*
* Copyright 2012 ZXing.Net authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/// <summary>
/// The base class for luminance sources which supports
/// cropping and rotating based upon the luminance values.
/// </summary>
public abstract class BaseLuminanceSource : LuminanceSource
{
/// <summary>
///
/// </summary>
protected sbyte[] luminances;
/// <summary>
/// Initializes a new instance of the <see cref="BaseLuminanceSource"/> class.
/// </summary>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
protected BaseLuminanceSource(int width, int height)
: base(width, height)
{
luminances = new sbyte[width * height];
}
/// <summary>
/// Initializes a new instance of the <see cref="BaseLuminanceSource"/> class.
/// </summary>
/// <param name="luminanceArray">The luminance array.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
protected BaseLuminanceSource(sbyte[] luminanceArray, int width, int height)
: base(width, height)
{
luminances = luminanceArray;
//Buffer.BlockCopy(luminanceArray, 0, luminances, 0, width * height);
}
/// <summary>
/// Fetches one row of luminance data from the underlying platform's bitmap. Values range from
/// 0 (black) to 255 (white). It is preferable for implementations of this method
/// to only fetch this row rather than the whole image, since no 2D Readers may be installed and
/// getMatrix() may never be called.
/// </summary>
/// <param name="y">The row to fetch, 0 &lt;= y &lt; Height.</param>
/// <param name="row">An optional preallocated array. If null or too small, it will be ignored.
/// Always use the returned object, and ignore the .length of the array.</param>
/// <returns>
/// An array containing the luminance data.
/// </returns>
override public sbyte[] getRow(int y, sbyte[] row)
{
int width = Width;
if (row == null || row.Length < width)
{
row = new sbyte[width];
}
//for (int i = 0; i < width; i++)
// row[i] = luminances[y * width + i];
Buffer.BlockCopy(luminances, y * width, row, 0, width);
return row;
}
public override sbyte[] Matrix
{
get { return luminances; }
}
/// <summary>
/// Returns a new object with rotated image data by 90 degrees counterclockwise.
/// Only callable if {@link #isRotateSupported()} is true.
/// </summary>
/// <returns>
/// A rotated version of this object.
/// </returns>
public override LuminanceSource rotateCounterClockwise()
{
var rotatedLuminances = new sbyte[Width * Height];
var newWidth = Height;
var newHeight = Width;
var localLuminances = Matrix;
for (var yold = 0; yold < Height; yold++)
{
for (var xold = 0; xold < Width; xold++)
{
var ynew = xold;
var xnew = newWidth - yold - 1;
rotatedLuminances[ynew * newWidth + xnew] = localLuminances[yold * Width + xold];
}
}
return CreateLuminanceSource(rotatedLuminances, newWidth, newHeight);
}
/// <summary>
/// </summary>
/// <returns> Whether this subclass supports counter-clockwise rotation.</returns>
public override bool RotateSupported
{
get
{
return true;
}
}
/// <summary>
/// Returns a new object with cropped image data. Implementations may keep a reference to the
/// original data rather than a copy. Only callable if CropSupported is true.
/// </summary>
/// <param name="left">The left coordinate, 0 &lt;= left &lt; Width.</param>
/// <param name="top">The top coordinate, 0 &lt;= top &lt;= Height.</param>
/// <param name="width">The width of the rectangle to crop.</param>
/// <param name="height">The height of the rectangle to crop.</param>
/// <returns>
/// A cropped version of this object.
/// </returns>
public override LuminanceSource crop(int left, int top, int width, int height)
{
if (left + width > Width || top + height > Height)
{
throw new ArgumentException("Crop rectangle does not fit within image data.");
}
var croppedLuminances = new sbyte[width * height];
for (int yold = top, ynew = 0; yold < height; yold++, ynew++)
{
for (int xold = left, xnew = 0; xold < width; xold++, xnew++)
{
croppedLuminances[ynew * width + xnew] = luminances[yold * Width + xold];
}
}
return CreateLuminanceSource(croppedLuminances, width, height);
}
/// <summary>
/// </summary>
/// <returns> Whether this subclass supports cropping.</returns>
public override bool CropSupported
{
get
{
return true;
}
}
/// <summary>
/// Should create a new luminance source with the right class type.
/// The method is used in methods crop and rotate.
/// </summary>
/// <param name="newLuminances">The new luminances.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <returns></returns>
protected abstract LuminanceSource CreateLuminanceSource(sbyte[] newLuminances, int width, int height);
}
public partial class BitmapLuminanceSource : BaseLuminanceSource
{
/// <summary>
/// Initializes a new instance of the <see cref="BitmapLuminanceSource"/> class.
/// </summary>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
protected BitmapLuminanceSource(int width, int height)
: base(width, height)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="BitmapLuminanceSource"/> class
/// with the image of a Bitmap instance
/// </summary>
/// <param name="bitmap">The bitmap.</param>
public BitmapLuminanceSource(Bitmap bitmap)
: base(bitmap.Width, bitmap.Height)
{
var height = bitmap.Height;
var width = bitmap.Width;
// In order to measure pure decoding speed, we convert the entire image to a greyscale array
luminances = new sbyte[width * height];
// The underlying raster of image consists of bytes with the luminance values
#if WindowsCE
var data = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
#else
var data = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
#endif
try
{
var stride = Math.Abs(data.Stride);
var pixelWidth = stride / width;
if (pixelWidth > 4)
{
// old slow way for unsupported bit depth
Color c;
for (int y = 0; y < height; y++)
{
int offset = y * width;
for (int x = 0; x < width; x++)
{
c = bitmap.GetPixel(x, y);
luminances[offset + x] = (sbyte)(0.3 * c.R + 0.59 * c.G + 0.11 * c.B + 0.01);
}
}
}
else
{
var strideStep = data.Stride;
var buffer = new byte[stride];
var ptrInBitmap = data.Scan0;
#if !WindowsCE
// prepare palette for 1 and 8 bit indexed bitmaps
var luminancePalette = new sbyte[bitmap.Palette.Entries.Length];
for (var index = 0; index < bitmap.Palette.Entries.Length; index++)
{
var color = bitmap.Palette.Entries[index];
luminancePalette[index] = (sbyte)(0.3 * color.R +
0.59 * color.G +
0.11 * color.B + 0.01);
}
if (bitmap.PixelFormat == PixelFormat.Format32bppArgb ||
bitmap.PixelFormat == PixelFormat.Format32bppPArgb)
{
pixelWidth = 40;
}
#endif
for (int y = 0; y < height; y++)
{
// copy a scanline not the whole bitmap because of memory usage
Marshal.Copy(ptrInBitmap, buffer, 0, stride);
#if NET40
ptrInBitmap = IntPtr.Add(ptrInBitmap, strideStep);
#else
ptrInBitmap = new IntPtr(ptrInBitmap.ToInt64() + strideStep);
#endif
var offset = y * width;
switch (pixelWidth)
{
#if !WindowsCE
case 0:
for (int x = 0; x * 8 < width; x++)
{
for (int subX = 0; subX < 8 && 8 * x + subX < width; subX++)
{
var index = (buffer[x] >> (7 - subX)) & 1;
luminances[offset + 8 * x + subX] = luminancePalette[index];
}
}
break;
case 1:
for (int x = 0; x < width; x++)
{
luminances[offset + x] = luminancePalette[buffer[x]];
}
break;
#endif
case 2:
// should be RGB565 or RGB555, assume RGB565
{
for (int index = 0, x = 0; index < 2 * width; index += 2, x++)
{
var byte1 = buffer[index];
var byte2 = buffer[index + 1];
var b5 = byte1 & 0x1F;
var g5 = (((byte1 & 0xE0) >> 5) | ((byte2 & 0x03) << 3)) & 0x1F;
var r5 = (byte2 >> 2) & 0x1F;
var r8 = (r5 * 527 + 23) >> 6;
var g8 = (g5 * 527 + 23) >> 6;
var b8 = (b5 * 527 + 23) >> 6;
luminances[offset + x] = (sbyte)(0.3 * r8 + 0.59 * g8 + 0.11 * b8 + 0.01);
}
}
break;
case 3:
for (int x = 0; x < width; x++)
{
var luminance = (sbyte)(0.3 * buffer[x * 3] +
0.59 * buffer[x * 3 + 1] +
0.11 * buffer[x * 3 + 2] + 0.01);
luminances[offset + x] = luminance;
}
break;
case 4:
// 4 bytes without alpha channel value
for (int x = 0; x < width; x++)
{
var luminance = (sbyte)(0.30 * buffer[x * 4] +
0.59 * buffer[x * 4 + 1] +
0.11 * buffer[x * 4 + 2] + 0.01);
luminances[offset + x] = luminance;
}
break;
case 40:
// with alpha channel; some barcodes are completely black if you
// only look at the r, g and b channel but the alpha channel controls
// the view
for (int x = 0; x < width; x++)
{
var luminance = (sbyte)(0.30 * buffer[x * 4] +
0.59 * buffer[x * 4 + 1] +
0.11 * buffer[x * 4 + 2] + 0.01);
// calculating the resulting luminance based upon a white background
// var alpha = buffer[x * pixelWidth + 3] / 255.0;
// luminance = (byte)(luminance * alpha + 255 * (1 - alpha));
var alpha = buffer[x * 4 + 3];
luminance = (sbyte)(((luminance * alpha) >> 8) + (255 * (255 - alpha) >> 8));
luminances[offset + x] = luminance;
}
break;
default:
throw new NotSupportedException();
}
}
}
}
finally
{
bitmap.UnlockBits(data);
}
}
/// <summary>
/// Should create a new luminance source with the right class type.
/// The method is used in methods crop and rotate.
/// </summary>
/// <param name="newLuminances">The new luminances.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <returns></returns>
protected override LuminanceSource CreateLuminanceSource(sbyte[] newLuminances, int width, int height)
{
return new BitmapLuminanceSource(width, height) { luminances = newLuminances };
}
}
}
-34
View File
@@ -64,9 +64,6 @@
<Reference Include="Renci.SshNet">
<HintPath>..\..\..\Resources\Libraries\SshNet\Renci.SshNet.dll</HintPath>
</Reference>
<Reference Include="Spring.Core">
<HintPath>..\Resources\Libraries\Spring.NET\Spring.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
@@ -106,33 +103,16 @@
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="zxing">
<HintPath>..\Resources\Libraries\ZXing\zxing.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="BI\DataStore.cs" />
<Compile Include="BI\AttachmentBI\Utilities.cs" />
<Compile Include="BI\DeviceBI\BatchUtilities.cs" />
<Compile Include="BI\DeviceBI\DeviceModelBI.cs" />
<Compile Include="BI\DeviceBI\Migration\LogMacAddressImporting.cs" />
<Compile Include="BI\DisposableImageCollection.cs" />
<Compile Include="BI\DocumentTemplateBI\DocumentTemplateQRCodeLocationCache.cs" />
<Compile Include="BI\DocumentTemplateBI\ManagedGroups\DocumentTemplateUsersManagedGroup.cs" />
<Compile Include="BI\DocumentTemplateBI\ManagedGroups\DocumentTemplateDevicesManagedGroup.cs" />
<Compile Include="BI\DocumentTemplateBI\ManagedGroups\DocumentTemplateManagedGroups.cs" />
<Compile Include="BI\Expressions\EvaluateExpressionParseException.cs" />
<Compile Include="BI\Expressions\ExpressionCachePreloadTask.cs" />
<Compile Include="BI\Expressions\Extensions\DataExt.cs" />
<Compile Include="BI\Expressions\Extensions\DeviceExt.cs" />
<Compile Include="BI\Expressions\Extensions\ImageExt.cs" />
<Compile Include="BI\Expressions\Extensions\ImageResultImplementations\BaseImageExpressionResult.cs" />
<Compile Include="BI\Expressions\Extensions\ImageResultImplementations\FileMontageImageExpressionResult.cs" />
<Compile Include="BI\Expressions\Extensions\ImageResultImplementations\FileImageExpressionResult.cs" />
<Compile Include="BI\Expressions\Extensions\ImageResultImplementations\BitmapImageExpressionResult.cs" />
<Compile Include="BI\Expressions\Extensions\UserExt.cs" />
<Compile Include="BI\Extensions\AttachmentActionExtensions.cs" />
<Compile Include="BI\Extensions\AttachmentExtensions.cs" />
<Compile Include="BI\Extensions\AuthorizationRoleExtensions.cs" />
<Compile Include="BI\Extensions\ClientServicesExtensions.cs" />
<Compile Include="BI\Extensions\UserFlagActionExtensions.cs" />
@@ -154,21 +134,7 @@
<Compile Include="BI\DeviceBI\EnrolmentLog.cs" />
<Compile Include="BI\Extensions\DocumentTemplateExtensions.cs" />
<Compile Include="BI\DocumentTemplateBI\Utilities.cs" />
<Compile Include="BI\DocumentTemplateBI\DocumentUniqueIdentifier.cs" />
<Compile Include="BI\Expressions\EvaluateExpressionPart.cs" />
<Compile Include="BI\Expressions\Expression.cs" />
<Compile Include="BI\Expressions\ExpressionTypeDescriptor.cs" />
<Compile Include="BI\Expressions\ExpressionTypeMemberDescriptor.cs" />
<Compile Include="BI\Expressions\IExpressionPart.cs" />
<Compile Include="BI\Expressions\TextExpressionPart.cs" />
<Compile Include="BI\DocumentTemplateBI\Importer\DocumentDropBoxMonitor.cs" />
<Compile Include="BI\DocumentTemplateBI\Importer\DocumentImporterJob.cs" />
<Compile Include="BI\DocumentTemplateBI\Importer\DocumentImporterCleanCacheJob.cs" />
<Compile Include="BI\DocumentTemplateBI\DocumentsLog.cs" />
<Compile Include="BI\Expressions\ExpressionCache.cs" />
<Compile Include="BI\Interop\MimeTypes.cs" />
<Compile Include="BI\Interop\Pdf\PdfGenerator.cs" />
<Compile Include="BI\Interop\Pdf\PdfImporter.cs" />
<Compile Include="BI\JobBI\Statistics\DailyOpenedClosed.cs" />
<Compile Include="BI\JobBI\Utilities.cs" />
<Compile Include="BI\Extensions\UtilityExtensions.cs" />