From a6ec79089bdedf4669e3831ec94fb085435ff92d Mon Sep 17 00:00:00 2001 From: jarekrzdbk Date: Tue, 23 Aug 2016 15:29:45 +0300 Subject: [PATCH 1/5] added Create Google Doc activity --- .../Activities/Create_Google_Doc_v1.cs | 236 ++++++++++++++++++ terminalGoogle/Interfaces/IGoogleDrive.cs | 4 +- terminalGoogle/Services/GoogleDrive.cs | 14 ++ terminalGoogle/Startup.cs | 1 + terminalGoogle/terminalGoogle.csproj | 1 + 5 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 terminalGoogle/Activities/Create_Google_Doc_v1.cs diff --git a/terminalGoogle/Activities/Create_Google_Doc_v1.cs b/terminalGoogle/Activities/Create_Google_Doc_v1.cs new file mode 100644 index 0000000000..f68ffefae4 --- /dev/null +++ b/terminalGoogle/Activities/Create_Google_Doc_v1.cs @@ -0,0 +1,236 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Fr8.Infrastructure.Data.Control; +using Fr8.Infrastructure.Data.Crates; +using Fr8.Infrastructure.Data.DataTransferObjects; +using Fr8.Infrastructure.Data.Managers; +using Fr8.Infrastructure.Data.Manifests; +using Fr8.Infrastructure.Data.Manifests.Helpers; +using Fr8.Infrastructure.Data.States; +using Fr8.TerminalBase.Errors; +using Fr8.TerminalBase.Infrastructure; +using Google.GData.Client; +using Newtonsoft.Json; +using terminalGoogle.Actions; +using terminalGoogle.DataTransferObjects; +using terminalGoogle.Interfaces; +using Fr8.TerminalBase.Services; +using System.Globalization; +using System.Text; +using Fr8.Infrastructure.Data.Constants; +using System.IO; + +namespace terminalGoogle.Activities +{ + public class Create_Google_Doc_v1 : BaseGoogleTerminalActivity + { + public static ActivityTemplateDTO ActivityTemplateDTO = new ActivityTemplateDTO + { + Id = new Guid("DAFD6823-CF54-4DD4-A618-D89A967EB885"), + Name = "Create_Google_Doc", + Label = "Create Google Doc", + Version = "1", + Terminal = TerminalData.TerminalDTO, + NeedsAuthentication = true, + MinPaneWidth = 300, + Categories = new[] + { + ActivityCategories.Forward, + TerminalData.GooogleActivityCategoryDTO + } + }; + protected override ActivityTemplateDTO MyTemplate => ActivityTemplateDTO; + + public class ActivityUi : StandardConfigurationControlsCM + { + public CrateChooser UpstreamCrateChooser { get; set; } + + public DropDownList ExistingFilesList { get; set; } + + public RadioButtonOption UseIncomingDataOption { get; set; } + + public RadioButtonOption UseStoredFileOption { get; set; } + + public RadioButtonGroup ContentSelectionGroup { get; set; } + + public TextSource NewFileName { get; set; } + + public ActivityUi(UiBuilder uiBuilder) + { + NewFileName = uiBuilder.CreateSpecificOrUpstreamValueChooser("Title", nameof(NewFileName), addRequestConfigEvent: true, requestUpstream: true, availability: AvailabilityType.RunTime); + NewFileName.IsCollapsed = false; + Controls.Add(NewFileName); + + UpstreamCrateChooser = new CrateChooser + { + Label = "Crate to store", + Name = nameof(UpstreamCrateChooser), + Required = true, + RequestUpstream = true, + SingleManifestOnly = true, + }; + + ExistingFilesList = new DropDownList + { + Name = nameof(ExistingFilesList), + Events = new List { ControlEvent.RequestConfig } + }; + + UseIncomingDataOption = new RadioButtonOption + { + Selected = true, + Name = nameof(UseIncomingDataOption), + Value = "Use Incoming Data", + Controls = new List { UpstreamCrateChooser } + }; + + UseStoredFileOption = new RadioButtonOption() + { + Selected = false, + Name = nameof(UseStoredFileOption), + Value = "Use Excisting File", + Controls = new List { ExistingFilesList } + }; + + ContentSelectionGroup = new RadioButtonGroup + { + GroupName = nameof(ContentSelectionGroup), + Name = nameof(ContentSelectionGroup), + Events = new List { ControlEvent.RequestConfig }, + Radios = new List + { + UseIncomingDataOption, + UseStoredFileOption + } + }; + + Controls.Add(ContentSelectionGroup); + } + } + + private const string SelectedDocCrateLabel = "Selected Doc"; + + private readonly IGoogleDrive _googleDrive; + + public Create_Google_Doc_v1(ICrateManager crateManager, IGoogleIntegration googleIntegration, IGoogleDrive googleDrive) + : base(crateManager, googleIntegration) + { + _googleDrive = googleDrive; + } + + private GoogleAuthDTO GetGoogleAuthToken() + { + return JsonConvert.DeserializeObject(AuthorizationToken.Token); + } + + public override async Task Initialize() + { + ActivityUI.ExistingFilesList.ListItems = await GetCurrentUsersFiles(); + } + + public override async Task FollowUp() + { + } + + protected override Task Validate() + { + ValidationManager.ValidateTextSourceNotEmpty(ActivityUI.NewFileName, "Title for Document must be specified"); + + if(ActivityUI.UseIncomingDataOption.Selected == true) + { + ValidationManager.ValidateCrateChooserNotEmpty(ActivityUI.UpstreamCrateChooser, "File must be specified"); + } + + if(ActivityUI.UseStoredFileOption.Selected == true) + { + ValidationManager.ValidateDropDownListNotEmpty(ActivityUI.ExistingFilesList, "File must be specified"); + } + + return Task.FromResult(0); + } + + public override async Task Run() + { + byte[] body = null; + string fileName = null; + + if(ActivityUI.UseIncomingDataOption.Selected == true) + { + var crateToProcess = FindCrateToProcess(); + if (crateToProcess == null) + { + throw new ActivityExecutionException($"Failed to run {ActivityPayload.Name} because specified upstream crate was not found in payload"); + } + + var content = crateToProcess.Get(); + body = Convert.FromBase64String(content.TextRepresentation); + fileName = content.Filename; + } + else if(ActivityUI.UseStoredFileOption.Selected == true) + { + var fileSelector = ActivityUI.ExistingFilesList; + if (string.IsNullOrEmpty(fileSelector.Value)) + { + RaiseError("No File was selected on design time", ActivityErrorCode.DESIGN_TIME_DATA_MISSING); + return; + } + //let's download this file + var file = await HubCommunicator.DownloadFile(int.Parse(fileSelector.Value)); + if (file == null || file.Length < 1) + { + RaiseError("Unable to download file from Hub"); + return; + } + fileName = fileSelector.selectedKey; + + using (var reader = new MemoryStream()) + { + file.CopyTo(reader); + body = reader.ToArray(); + } + } + + try + { + var file = await _googleDrive.CreateFile(ActivityUI.NewFileName.TextValue, + body, GetMimeType(fileName), GetGoogleAuthToken()); + + } + catch (GDataRequestException ex) + { + if (ex.InnerException.Message.IndexOf("(401) Unauthorized") > -1) + { + throw new AuthorizationTokenExpiredOrInvalidException(); + } + + throw; + } + } + + private static string GetMimeType(string fileName) + { + string mimeType = "application/unknown"; + string ext = System.IO.Path.GetExtension(fileName).ToLower(); + Microsoft.Win32.RegistryKey regKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext); + if (regKey != null && regKey.GetValue("Content Type") != null) + mimeType = regKey.GetValue("Content Type").ToString(); + return mimeType; + } + + private async Task> GetCurrentUsersFiles() + { + //Leave only XLSX files as activity fails to rewrite XLS files + var curAccountFileList = (await HubCommunicator.GetFiles()).Where(x => (x.OriginalFileName?.EndsWith(".doc", StringComparison.InvariantCultureIgnoreCase) ?? true)|| (x.OriginalFileName?.EndsWith(".docx", StringComparison.InvariantCultureIgnoreCase) ?? true)); + //TODO where tags == Docusign files + return curAccountFileList.Select(c => new ListItem() { Key = c.OriginalFileName, Value = c.Id.ToString(CultureInfo.InvariantCulture) }).ToList(); + } + + private Crate FindCrateToProcess() + { + var desiredCrateDescription = ActivityUI.UpstreamCrateChooser.CrateDescriptions.Single(x => x.Selected); + return Payload.FirstOrDefault(x => x.Label == desiredCrateDescription.Label && x.ManifestType.Type == desiredCrateDescription.ManifestType); + } + } +} \ No newline at end of file diff --git a/terminalGoogle/Interfaces/IGoogleDrive.cs b/terminalGoogle/Interfaces/IGoogleDrive.cs index 7c67dcea57..f83248e5a0 100644 --- a/terminalGoogle/Interfaces/IGoogleDrive.cs +++ b/terminalGoogle/Interfaces/IGoogleDrive.cs @@ -10,5 +10,7 @@ public interface IGoogleDrive Task CreateDriveService(GoogleAuthDTO authDTO); bool FileExist(DriveService driveService, string filename, out string link); Task> GetGoogleForms(GoogleAuthDTO authDTO); - } + Task CreateFile(string title, byte[] body, string mimeType, GoogleAuthDTO authDTO); + + } } \ No newline at end of file diff --git a/terminalGoogle/Services/GoogleDrive.cs b/terminalGoogle/Services/GoogleDrive.cs index 945e8ca88a..92df274426 100644 --- a/terminalGoogle/Services/GoogleDrive.cs +++ b/terminalGoogle/Services/GoogleDrive.cs @@ -77,6 +77,20 @@ public async Task DownloadFile(string fileId, GoogleAuthDTO authDTO) return fileContent; } + public async Task CreateFile(string title, byte[] body, string mimeType, GoogleAuthDTO authDTO) + { + var driveService = await CreateDriveService(authDTO); + var doc = new Google.Apis.Drive.v2.Data.File(); + doc.Title = title; + doc.MimeType = mimeType; + var stream = new System.IO.MemoryStream(body); + + var request = driveService.Files.Insert(doc, stream, mimeType); + await request.UploadAsync(); + return request.ResponseBody; + } + + public async Task> GetGoogleForms(GoogleAuthDTO authDTO) { var driveService = await CreateDriveService(authDTO); diff --git a/terminalGoogle/Startup.cs b/terminalGoogle/Startup.cs index ad7036469d..129e3c8ead 100644 --- a/terminalGoogle/Startup.cs +++ b/terminalGoogle/Startup.cs @@ -56,6 +56,7 @@ protected override void RegisterActivities() ActivityStore.RegisterActivity(Monitor_Form_Responses_v1.ActivityTemplateDTO); ActivityStore.RegisterActivity(Save_To_Google_Sheet_v1.ActivityTemplateDTO); ActivityStore.RegisterActivity(Monitor_Gmail_Inbox_v1.ActivityTemplateDTO); + ActivityStore.RegisterActivity(Create_Google_Doc_v1.ActivityTemplateDTO); } } } diff --git a/terminalGoogle/terminalGoogle.csproj b/terminalGoogle/terminalGoogle.csproj index 29df308c03..cfadc36ffc 100644 --- a/terminalGoogle/terminalGoogle.csproj +++ b/terminalGoogle/terminalGoogle.csproj @@ -304,6 +304,7 @@ + From 7d1b471aeb594823abc222f1ab1b0b8150206c8c Mon Sep 17 00:00:00 2001 From: jarekrzdbk Date: Tue, 23 Aug 2016 15:34:10 +0300 Subject: [PATCH 2/5] added Word terminal --- .../icons/web_services/ms-word-icon-64x64.png | Bin 0 -> 832 bytes Fr8Infrastructure.NET/Data/Control/Control.cs | 3 + Views/AngularTemplate/FilePicker.cshtml | 2 +- .../Activities/Load_Excel_File_v1.cs | 1 + terminalWord/Activities/Load_Word_File_v1.cs | 141 ++++++++++ terminalWord/App_Start/RouteConfig.cs | 13 + terminalWord/App_Start/SwaggerConfig.cs | 246 ++++++++++++++++++ .../Controllers/ActivityController.cs | 13 + .../Controllers/TerminalController.cs | 13 + terminalWord/Global.asax | 1 + terminalWord/Global.asax.cs | 7 + terminalWord/Properties/AssemblyInfo.cs | 35 +++ terminalWord/Startup.cs | 52 ++++ terminalWord/TerminalData.cs | 25 ++ terminalWord/Web.Debug.config | 30 +++ terminalWord/Web.Release.config | 31 +++ terminalWord/Web.config | 97 +++++++ terminalWord/favicon.ico | Bin 0 -> 32038 bytes terminalWord/index.html | 11 + terminalWord/packages.config | 30 +++ terminalWord/terminalWord.csproj | 238 +++++++++++++++++ 21 files changed, 988 insertions(+), 1 deletion(-) create mode 100644 Content/icons/web_services/ms-word-icon-64x64.png create mode 100644 terminalWord/Activities/Load_Word_File_v1.cs create mode 100644 terminalWord/App_Start/RouteConfig.cs create mode 100644 terminalWord/App_Start/SwaggerConfig.cs create mode 100644 terminalWord/Controllers/ActivityController.cs create mode 100644 terminalWord/Controllers/TerminalController.cs create mode 100644 terminalWord/Global.asax create mode 100644 terminalWord/Global.asax.cs create mode 100644 terminalWord/Properties/AssemblyInfo.cs create mode 100644 terminalWord/Startup.cs create mode 100644 terminalWord/TerminalData.cs create mode 100644 terminalWord/Web.Debug.config create mode 100644 terminalWord/Web.Release.config create mode 100644 terminalWord/Web.config create mode 100644 terminalWord/favicon.ico create mode 100644 terminalWord/index.html create mode 100644 terminalWord/packages.config create mode 100644 terminalWord/terminalWord.csproj diff --git a/Content/icons/web_services/ms-word-icon-64x64.png b/Content/icons/web_services/ms-word-icon-64x64.png new file mode 100644 index 0000000000000000000000000000000000000000..bc2ab64f8f3796cdda4a8725101e18d2345c5e81 GIT binary patch literal 832 zcmV-G1Hb%0SZxRrHI?c*2wM*htvvwImBGbo zs-USZ46#TEg6r4iY->D#hIln>RD+F1Hb7!?rJCVzLH8R2AfRS2re+pr6K6JF8`9Us zs_X$=?N2)EwG=9Q055NMm(&;nP)tABZ{K0Z(Hr&x;Li~N0zd$m37}AU?Ggax1mLUM zmI5sG&3w+nSq4W#Sb1U!3{S*eS{g`Sq2 zbv^qVq4&TxGXX5T{s2b?9_ljY{KIG4a~gmt^1aI`=en(L3^Jdxx_oP(L%%;534nKm zuKZ~5kS;I1`vQAUjQ{pNZrt3>W3J_4TnyN!2Kq(~nAbgc@)phvO}pCBOmnaCdWMkz zPN!#J;^~rWko-5&$)TXJK?|QD0x{Pr~slQw}V?Z5j=L2fdbt2+XJiiCmrs zJ*q=_6CkhQMlAsz2=Qw#rnrZb^>C`IS*N{iy<@IA6naCe0NoD9Q@+0WfX} z9nnO~B$f{#fB+Bx0zd%xZG-?200KY&_@$r1F>9Yp01^QJ0000< KMNUMnLSTX`4sK@v literal 0 HcmV?d00001 diff --git a/Fr8Infrastructure.NET/Data/Control/Control.cs b/Fr8Infrastructure.NET/Data/Control/Control.cs index e1857d70e2..61f00db5cf 100644 --- a/Fr8Infrastructure.NET/Data/Control/Control.cs +++ b/Fr8Infrastructure.NET/Data/Control/Control.cs @@ -399,6 +399,9 @@ public TextBlock() public class FilePicker : ControlDefinitionDTO { + [JsonProperty("fileextensions")] + public string FileExtensions { get; set; } + public FilePicker() { Type = ControlTypes.FilePicker; diff --git a/Views/AngularTemplate/FilePicker.cshtml b/Views/AngularTemplate/FilePicker.cshtml index 191172ad97..a023a8b1c5 100644 --- a/Views/AngularTemplate/FilePicker.cshtml +++ b/Views/AngularTemplate/FilePicker.cshtml @@ -1,5 +1,5 @@ 
Select File + accept="{{field.fileextensions}}" ngf-max-size='20MB' ngf-min-height='100'>Select File {{field.value == null ? 'No file selected' : field.value|formatInput}}
diff --git a/terminalExcel/Activities/Load_Excel_File_v1.cs b/terminalExcel/Activities/Load_Excel_File_v1.cs index 975f2c37bf..5898ef1ef6 100644 --- a/terminalExcel/Activities/Load_Excel_File_v1.cs +++ b/terminalExcel/Activities/Load_Excel_File_v1.cs @@ -33,6 +33,7 @@ public ActivityUi() { FilePicker = new FilePicker { + FileExtensions = ".xls,.xlsx", Label = "Select an Excel file", Name = nameof(FilePicker), Required = true, diff --git a/terminalWord/Activities/Load_Word_File_v1.cs b/terminalWord/Activities/Load_Word_File_v1.cs new file mode 100644 index 0000000000..14b038c399 --- /dev/null +++ b/terminalWord/Activities/Load_Word_File_v1.cs @@ -0,0 +1,141 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using Fr8.Infrastructure.Data.Constants; +using Fr8.Infrastructure.Data.Control; +using Fr8.Infrastructure.Data.Crates; +using Fr8.Infrastructure.Data.DataTransferObjects; +using Fr8.Infrastructure.Data.Managers; +using Fr8.Infrastructure.Data.Manifests; +using Fr8.Infrastructure.Data.States; +using Fr8.TerminalBase.BaseClasses; +using Fr8.TerminalBase.Errors; +using RestSharp.Extensions; + +namespace terminalWord.Activities +{ + public class Load_Word_File_v1 : TerminalActivity + { + public static ActivityTemplateDTO ActivityTemplateDTO = new ActivityTemplateDTO + { + Id = new Guid("8BBB1FE4-58F0-4342-B0E2-65CECB21F5DC"), + Name = "Load_Word_File", + Label = "Load Word File", + Version = "1", + MinPaneWidth = 300, + Terminal = TerminalData.TerminalDTO, + Categories = new[] + { + ActivityCategories.Receive, + TerminalData.ActivityCategoryDTO + } + }; + protected override ActivityTemplateDTO MyTemplate => ActivityTemplateDTO; + + private const string FileCrateLabel = "File uploaded by Load Word"; + + private const string ConfigurationCrateLabel = "Selected File"; + + private const string ExternalObjectHandlesLabel = "External Object Handles"; + + public class ActivityUi : StandardConfigurationControlsCM + { + public FilePicker FilePicker { get; set; } + + public TextBlock UploadedFileDescription { get; set; } + + public TextBlock ActivityDescription { get; set; } + + public ActivityUi() + { + FilePicker = new FilePicker + { + FileExtensions= ".doc,.docx", + Label = "Select a Word file", + Name = nameof(FilePicker), + Required = true, + Events = new List { ControlEvent.RequestConfig }, + }; + Controls.Add(FilePicker); + UploadedFileDescription = new TextBlock + { + Name = nameof(UploadedFileDescription), + IsHidden = true + }; + Controls.Add(UploadedFileDescription); + } + public void MarkFileAsUploaded(string fileName, string filePath) + { + FilePicker.Value = filePath; + UploadedFileDescription.Value = $"Uploaded file: {fileName}"; + UploadedFileDescription.IsHidden = false; + } + + public void ClearFileDescription() + { + UploadedFileDescription.Value = string.Empty; + UploadedFileDescription.IsHidden = true; + } + } + private readonly Fr8.Infrastructure.Interfaces.IRestfulServiceClient _restfulServiceClient; + public Load_Word_File_v1(ICrateManager crateManager, Fr8.Infrastructure.Interfaces.IRestfulServiceClient restfulServiceClient) + : base(crateManager) + { + _restfulServiceClient = restfulServiceClient; + } + + public override async Task Initialize() + { + CrateSignaller.MarkAvailableAtRuntime(FileCrateLabel); + } + + public override Task FollowUp() + { + return Task.FromResult(0); + } + + protected override Task Validate() + { + if(string.IsNullOrEmpty(ActivityUI.FilePicker.Value)) + { + ValidationManager.SetError("File must be specified", ActivityUI.FilePicker); + } + return Task.FromResult(0); + } + + public async Task GetFileAsByteArray(string selectedFilePath) + { + var fileAsByteArray = await RetrieveFile(selectedFilePath); + fileAsByteArray.Position = 0; + return fileAsByteArray.ReadAsBytes(); + } + private async Task RetrieveFile(string filePath) + { + var ext = System.IO.Path.GetExtension(filePath); + if (ext != ".doc" && ext != ".docx") + { + throw new ArgumentException("Expected '.doc' or '.docx'", "selectedFile"); + } + return await _restfulServiceClient.DownloadAsync(new Uri(filePath)); + } + + public override async Task Run() + { + var byteArray = await GetFileAsByteArray(ActivityUI.FilePicker.Value); + + var fileDescription = new StandardFileDescriptionCM + { + + TextRepresentation = Convert.ToBase64String(byteArray), + Filetype = System.IO.Path.GetExtension(ActivityUI.FilePicker.Value), + Filename = System.IO.Path.GetFileName(ActivityUI.FilePicker.Value) + }; + + Payload.Add(Crate.FromContent(FileCrateLabel, fileDescription)); + } + } +} \ No newline at end of file diff --git a/terminalWord/App_Start/RouteConfig.cs b/terminalWord/App_Start/RouteConfig.cs new file mode 100644 index 0000000000..564cf9e5c9 --- /dev/null +++ b/terminalWord/App_Start/RouteConfig.cs @@ -0,0 +1,13 @@ +using System.Web.Http; +using Fr8.TerminalBase.BaseClasses; + +namespace terminalWord +{ + public static class RoutesConfig + { + public static void Register(HttpConfiguration config) + { + BaseTerminalWebApiConfig.Register("terminalWord", config); + } + } +} \ No newline at end of file diff --git a/terminalWord/App_Start/SwaggerConfig.cs b/terminalWord/App_Start/SwaggerConfig.cs new file mode 100644 index 0000000000..7d4576f45c --- /dev/null +++ b/terminalWord/App_Start/SwaggerConfig.cs @@ -0,0 +1,246 @@ +using System.Web.Http; +using WebActivatorEx; +using terminalWord; +using Swashbuckle.Application; + +//[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")] + +namespace terminalWord +{ + public class SwaggerConfig + { + public static void Register(HttpConfiguration configuration) + { + var thisAssembly = typeof(SwaggerConfig).Assembly; + + GlobalConfiguration.Configuration + .EnableSwagger(c => + { + // By default, the service root url is inferred from the request used to access the docs. + // However, there may be situations (e.g. proxy and load-balanced environments) where this does not + // resolve correctly. You can workaround this by providing your own code to determine the root URL. + // + //c.RootUrl(req => GetRootUrlFromAppConfig()); + + // If schemes are not explicitly provided in a Swagger 2.0 document, then the scheme used to access + // the docs is taken as the default. If your API supports multiple schemes and you want to be explicit + // about them, you can use the "Schemes" option as shown below. + // + //c.Schemes(new[] { "http", "https" }); + + // Use "SingleApiVersion" to describe a single version API. Swagger 2.0 includes an "Info" object to + // hold additional metadata for an API. Version and title are required but you can also provide + // additional fields by chaining methods off SingleApiVersion. + // + c.SingleApiVersion("v1", "terminalWord"); + + // If your API has multiple versions, use "MultipleApiVersions" instead of "SingleApiVersion". + // In this case, you must provide a lambda that tells Swashbuckle which actions should be + // included in the docs for a given API version. Like "SingleApiVersion", each call to "Version" + // returns an "Info" builder so you can provide additional metadata per API version. + // + //c.MultipleApiVersions( + // (apiDesc, targetApiVersion) => ResolveVersionSupportByRouteConstraint(apiDesc, targetApiVersion), + // (vc) => + // { + // vc.Version("v2", "Swashbuckle Dummy API V2"); + // vc.Version("v1", "Swashbuckle Dummy API V1"); + // }); + + // You can use "BasicAuth", "ApiKey" or "OAuth2" options to describe security schemes for the API. + // See https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md for more details. + // NOTE: These only define the schemes and need to be coupled with a corresponding "security" property + // at the document or operation level to indicate which schemes are required for an operation. To do this, + // you'll need to implement a custom IDocumentFilter and/or IOperationFilter to set these properties + // according to your specific authorization implementation + // + //c.BasicAuth("basic") + // .Description("Basic HTTP Authentication"); + // + // NOTE: You must also configure 'EnableApiKeySupport' below in the SwaggerUI section + //c.ApiKey("apiKey") + // .Description("API Key Authentication") + // .Name("apiKey") + // .In("header"); + // + //c.OAuth2("oauth2") + // .Description("OAuth2 Implicit Grant") + // .Flow("implicit") + // .AuthorizationUrl("http://petstore.swagger.wordnik.com/api/oauth/dialog") + // //.TokenUrl("https://tempuri.org/token") + // .Scopes(scopes => + // { + // scopes.Add("read", "Read access to protected resources"); + // scopes.Add("write", "Write access to protected resources"); + // }); + + // Set this flag to omit descriptions for any actions decorated with the Obsolete attribute + //c.IgnoreObsoleteActions(); + + // Each operation be assigned one or more tags which are then used by consumers for various reasons. + // For example, the swagger-ui groups operations according to the first tag of each operation. + // By default, this will be controller name but you can use the "GroupActionsBy" option to + // override with any value. + // + //c.GroupActionsBy(apiDesc => apiDesc.HttpMethod.ToString()); + + // You can also specify a custom sort order for groups (as defined by "GroupActionsBy") to dictate + // the order in which operations are listed. For example, if the default grouping is in place + // (controller name) and you specify a descending alphabetic sort order, then actions from a + // ProductsController will be listed before those from a CustomersController. This is typically + // used to customize the order of groupings in the swagger-ui. + // + //c.OrderActionGroupsBy(new DescendingAlphabeticComparer()); + + // If you annotate Controllers and API Types with + // Xml comments (http://msdn.microsoft.com/en-us/library/b2s063f7(v=vs.110).aspx), you can incorporate + // those comments into the generated docs and UI. You can enable this by providing the path to one or + // more Xml comment files. + // + //c.IncludeXmlComments(GetXmlCommentsPath()); + + // Swashbuckle makes a best attempt at generating Swagger compliant JSON schemas for the various types + // exposed in your API. However, there may be occasions when more control of the output is needed. + // This is supported through the "MapType" and "SchemaFilter" options: + // + // Use the "MapType" option to override the Schema generation for a specific type. + // It should be noted that the resulting Schema will be placed "inline" for any applicable Operations. + // While Swagger 2.0 supports inline definitions for "all" Schema types, the swagger-ui tool does not. + // It expects "complex" Schemas to be defined separately and referenced. For this reason, you should only + // use the "MapType" option when the resulting Schema is a primitive or array type. If you need to alter a + // complex Schema, use a Schema filter. + // + //c.MapType(() => new Schema { type = "integer", format = "int32" }); + + // If you want to post-modify "complex" Schemas once they've been generated, across the board or for a + // specific type, you can wire up one or more Schema filters. + // + //c.SchemaFilter(); + + // In a Swagger 2.0 document, complex types are typically declared globally and referenced by unique + // Schema Id. By default, Swashbuckle does NOT use the full type name in Schema Ids. In most cases, this + // works well because it prevents the "implementation detail" of type namespaces from leaking into your + // Swagger docs and UI. However, if you have multiple types in your API with the same class name, you'll + // need to opt out of this behavior to avoid Schema Id conflicts. + // + //c.UseFullTypeNameInSchemaIds(); + + // Alternatively, you can provide your own custom strategy for inferring SchemaId's for + // describing "complex" types in your API. + // + //c.SchemaId(t => t.FullName.Contains('`') ? t.FullName.Substring(0, t.FullName.IndexOf('`')) : t.FullName); + + // Set this flag to omit schema property descriptions for any type properties decorated with the + // Obsolete attribute + //c.IgnoreObsoleteProperties(); + + // In accordance with the built in JsonSerializer, Swashbuckle will, by default, describe enums as integers. + // You can change the serializer behavior by configuring the StringToEnumConverter globally or for a given + // enum type. Swashbuckle will honor this change out-of-the-box. However, if you use a different + // approach to serialize enums as strings, you can also force Swashbuckle to describe them as strings. + // + //c.DescribeAllEnumsAsStrings(); + + // Similar to Schema filters, Swashbuckle also supports Operation and Document filters: + // + // Post-modify Operation descriptions once they've been generated by wiring up one or more + // Operation filters. + // + //c.OperationFilter(); + // + // If you've defined an OAuth2 flow as described above, you could use a custom filter + // to inspect some attribute on each action and infer which (if any) OAuth2 scopes are required + // to execute the operation + // + //c.OperationFilter(); + + // Post-modify the entire Swagger document by wiring up one or more Document filters. + // This gives full control to modify the final SwaggerDocument. You should have a good understanding of + // the Swagger 2.0 spec. - https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md + // before using this option. + // + //c.DocumentFilter(); + + // In contrast to WebApi, Swagger 2.0 does not include the query string component when mapping a URL + // to an action. As a result, Swashbuckle will raise an exception if it encounters multiple actions + // with the same path (sans query string) and HTTP method. You can workaround this by providing a + // custom strategy to pick a winner or merge the descriptions for the purposes of the Swagger docs + // + //c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); + + // Wrap the default SwaggerGenerator with additional behavior (e.g. caching) or provide an + // alternative implementation for ISwaggerProvider with the CustomProvider option. + // + //c.CustomProvider((defaultProvider) => new CachingSwaggerProvider(defaultProvider)); + }) + .EnableSwaggerUi(c => + { + // Use the "InjectStylesheet" option to enrich the UI with one or more additional CSS stylesheets. + // The file must be included in your project as an "Embedded Resource", and then the resource's + // "Logical Name" is passed to the method as shown below. + // + //c.InjectStylesheet(containingAssembly, "Swashbuckle.Dummy.SwaggerExtensions.testStyles1.css"); + + // Use the "InjectJavaScript" option to invoke one or more custom JavaScripts after the swagger-ui + // has loaded. The file must be included in your project as an "Embedded Resource", and then the resource's + // "Logical Name" is passed to the method as shown above. + // + //c.InjectJavaScript(thisAssembly, "Swashbuckle.Dummy.SwaggerExtensions.testScript1.js"); + + // The swagger-ui renders boolean data types as a dropdown. By default, it provides "true" and "false" + // strings as the possible choices. You can use this option to change these to something else, + // for example 0 and 1. + // + //c.BooleanValues(new[] { "0", "1" }); + + // By default, swagger-ui will validate specs against swagger.io's online validator and display the result + // in a badge at the bottom of the page. Use these options to set a different validator URL or to disable the + // feature entirely. + //c.SetValidatorUrl("http://localhost/validator"); + //c.DisableValidator(); + + // Use this option to control how the Operation listing is displayed. + // It can be set to "None" (default), "List" (shows operations for each resource), + // or "Full" (fully expanded: shows operations and their details). + // + //c.DocExpansion(DocExpansion.List); + + // Specify which HTTP operations will have the 'Try it out!' option. An empty paramter list disables + // it for all operations. + // + //c.SupportedSubmitMethods("GET", "HEAD"); + + // Use the CustomAsset option to provide your own version of assets used in the swagger-ui. + // It's typically used to instruct Swashbuckle to return your version instead of the default + // when a request is made for "index.html". As with all custom content, the file must be included + // in your project as an "Embedded Resource", and then the resource's "Logical Name" is passed to + // the method as shown below. + // + //c.CustomAsset("index", containingAssembly, "YourWebApiProject.SwaggerExtensions.index.html"); + + // If your API has multiple versions and you've applied the MultipleApiVersions setting + // as described above, you can also enable a select box in the swagger-ui, that displays + // a discovery URL for each version. This provides a convenient way for users to browse documentation + // for different API versions. + // + //c.EnableDiscoveryUrlSelector(); + + // If your API supports the OAuth2 Implicit flow, and you've described it correctly, according to + // the Swagger 2.0 specification, you can enable UI support as shown below. + // + //c.EnableOAuth2Support( + // clientId: "test-client-id", + // clientSecret: null, + // realm: "test-realm", + // appName: "Swagger UI" + // //additionalQueryStringParams: new Dictionary() { { "foo", "bar" } } + //); + + // If your API supports ApiKey, you can override the default values. + // "apiKeyIn" can either be "query" or "header" + // + //c.EnableApiKeySupport("apiKey", "header"); + }); + } + } +} diff --git a/terminalWord/Controllers/ActivityController.cs b/terminalWord/Controllers/ActivityController.cs new file mode 100644 index 0000000000..28b64796ae --- /dev/null +++ b/terminalWord/Controllers/ActivityController.cs @@ -0,0 +1,13 @@ +using Fr8.TerminalBase.BaseClasses; +using Fr8.TerminalBase.Services; + +namespace terminalWord.Controllers +{ + public class ActivityController : DefaultActivityController + { + public ActivityController(IActivityExecutor activityExecutor) + : base(activityExecutor) + { + } + } +} \ No newline at end of file diff --git a/terminalWord/Controllers/TerminalController.cs b/terminalWord/Controllers/TerminalController.cs new file mode 100644 index 0000000000..beed4b4b67 --- /dev/null +++ b/terminalWord/Controllers/TerminalController.cs @@ -0,0 +1,13 @@ +using Fr8.TerminalBase.BaseClasses; +using Fr8.TerminalBase.Services; + +namespace terminalWord.Controllers +{ + public class TerminalController : DefaultTerminalController + { + public TerminalController(IActivityStore activityStore, IHubDiscoveryService hubDiscovery) + : base(activityStore, hubDiscovery) + { + } + } +} \ No newline at end of file diff --git a/terminalWord/Global.asax b/terminalWord/Global.asax new file mode 100644 index 0000000000..2ae86aee55 --- /dev/null +++ b/terminalWord/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.cs" Inherits="terminalWord.WebApiApplication" Language="C#" %> diff --git a/terminalWord/Global.asax.cs b/terminalWord/Global.asax.cs new file mode 100644 index 0000000000..b8b830c341 --- /dev/null +++ b/terminalWord/Global.asax.cs @@ -0,0 +1,7 @@ +namespace terminalWord +{ + public class WebApiApplication : System.Web.HttpApplication + { + + } +} diff --git a/terminalWord/Properties/AssemblyInfo.cs b/terminalWord/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..855bddfe47 --- /dev/null +++ b/terminalWord/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("$projectsafename$")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("$projectsafename")] +[assembly: AssemblyCopyright("Copyright © terminalWord 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("3b6ebeb4-7cd4-4008-aaab-a3c4cdc77655")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/terminalWord/Startup.cs b/terminalWord/Startup.cs new file mode 100644 index 0000000000..c6ec36b2ef --- /dev/null +++ b/terminalWord/Startup.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Web.Http.Dispatcher; +using Fr8.TerminalBase.BaseClasses; +using Microsoft.Owin; +using Owin; +using terminalWord.Controllers; +using terminalWord; + +[assembly: OwinStartup(typeof(Startup))] + +namespace terminalWord +{ + public class Startup : BaseConfiguration + { + public Startup() + : base(TerminalData.TerminalDTO) + { + } + + public void Configuration(IAppBuilder app) + { + Configuration(app, false); + } + + public void Configuration(IAppBuilder app, bool selfHost) + { + ConfigureProject(selfHost, null); + SwaggerConfig.Register(_configuration); + RoutesConfig.Register(_configuration); + ConfigureFormatters(); + app.UseWebApi(_configuration); + if (!selfHost) + { + StartHosting(); + } + } + + protected override void RegisterActivities() + { + ActivityStore.RegisterActivity(Activities.Load_Word_File_v1.ActivityTemplateDTO); + } + + public override ICollection GetControllerTypes(IAssembliesResolver assembliesResolver) + { + return new Type[] { + typeof(ActivityController), + typeof(TerminalController), + }; + } + } +} diff --git a/terminalWord/TerminalData.cs b/terminalWord/TerminalData.cs new file mode 100644 index 0000000000..e35c8eeabd --- /dev/null +++ b/terminalWord/TerminalData.cs @@ -0,0 +1,25 @@ +using Fr8.Infrastructure.Data.DataTransferObjects; +using Fr8.Infrastructure.Data.States; +using Fr8.Infrastructure.Utilities.Configuration; + +namespace terminalWord +{ + public static class TerminalData + { + public static ActivityCategoryDTO ActivityCategoryDTO = new ActivityCategoryDTO + { + Name = "Word", + IconPath = "/Content/icons/web_services/ms-word-icon-64x64.png", + Type = "WebService" + }; + + public static TerminalDTO TerminalDTO = new TerminalDTO + { + Endpoint = CloudConfigurationManager.GetSetting("terminalWord.TerminalEndpoint"), + TerminalStatus = TerminalStatus.Active, + Name = "terminalWord", + Label = "Word", + Version = "1" + }; + } +} \ No newline at end of file diff --git a/terminalWord/Web.Debug.config b/terminalWord/Web.Debug.config new file mode 100644 index 0000000000..680849f611 --- /dev/null +++ b/terminalWord/Web.Debug.config @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/terminalWord/Web.Release.config b/terminalWord/Web.Release.config new file mode 100644 index 0000000000..943c9c0de7 --- /dev/null +++ b/terminalWord/Web.Release.config @@ -0,0 +1,31 @@ + + + + + + + + + + + diff --git a/terminalWord/Web.config b/terminalWord/Web.config new file mode 100644 index 0000000000..0600d234ee --- /dev/null +++ b/terminalWord/Web.config @@ -0,0 +1,97 @@ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/terminalWord/favicon.ico b/terminalWord/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..a3a799985c43bc7309d701b2cad129023377dc71 GIT binary patch literal 32038 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 + + + + + + This is the home page of the Fr8Demo Terminal Service, one of the many terminals being developed. + + + + diff --git a/terminalWord/packages.config b/terminalWord/packages.config new file mode 100644 index 0000000000..f5502e330d --- /dev/null +++ b/terminalWord/packages.config @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/terminalWord/terminalWord.csproj b/terminalWord/terminalWord.csproj new file mode 100644 index 0000000000..dd3bef34a3 --- /dev/null +++ b/terminalWord/terminalWord.csproj @@ -0,0 +1,238 @@ + + + + + + Debug + AnyCPU + + + 2.0 + {C808A1BB-26EC-4EF9-8592-10176BF1E558} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + terminalWord + terminalWord + v4.5 + false + true + + + + + + + + + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + ..\packages\AutoMapper.4.0.4\lib\net45\AutoMapper.dll + True + + + ..\packages\FluentValidation.5.6.2.0\lib\Net45\FluentValidation.dll + True + + + ..\packages\log4net.2.0.5\lib\net45-full\log4net.dll + True + + + ..\packages\Microsoft.ApplicationInsights.2.0.0\lib\net45\Microsoft.ApplicationInsights.dll + True + + + + ..\packages\Moq.4.2.1507.0118\lib\net40\Moq.dll + True + + + ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll + True + + + ..\packages\libphonenumber-csharp.7.2.5\lib\PhoneNumbers.dll + True + + + ..\packages\PusherServer.3.0.0\lib\net35\PusherServer.dll + True + + + ..\packages\RestSharp.105.0.1\lib\net4\RestSharp.dll + True + + + ..\packages\structuremap.3.1.6.186\lib\net40\StructureMap.dll + True + + + ..\packages\structuremap.3.1.6.186\lib\net40\StructureMap.Net4.dll + True + + + ..\packages\Swashbuckle.Core.5.4.0\lib\net40\Swashbuckle.Core.dll + True + + + + + + ..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll + True + + + ..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll + True + + + + + + + + + + + + + + True + ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll + + + + + ..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll + + + + + ..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll + + + ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll + + + + ..\packages\WebActivatorEx.2.0\lib\net40\WebActivatorEx.dll + True + + + ..\packages\YamlDotNet.3.8.0\lib\net35\YamlDotNet.dll + True + + + + + ..\packages\Owin.1.0\lib\net40\Owin.dll + + + ..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll + + + ..\packages\Microsoft.Owin.Host.SystemWeb.3.0.1\lib\net45\Microsoft.Owin.Host.SystemWeb.dll + + + ..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll + + + + + + + + + + Global.asax + + + + + + + + + + + Designer + + + Web.config + + + Web.config + + + + + + + + + + + {bba91af2-7636-41b6-87c4-c1575ae8b04b} + Fr8Infrastructure.NET + + + {bf96675e-6baf-4ac9-b247-1551d62e8c44} + Fr8TerminalBase.NET + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + + + + True + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + \ No newline at end of file From 316b6bef2f22f070e9e0424bc71035ab186cbc05 Mon Sep 17 00:00:00 2001 From: jarekrzdbk Date: Tue, 23 Aug 2016 18:46:56 +0300 Subject: [PATCH 3/5] fixed test --- .../Integration/Terminal_Discover_v1_Tests.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Tests/terminalGoogleTests/Integration/Terminal_Discover_v1_Tests.cs b/Tests/terminalGoogleTests/Integration/Terminal_Discover_v1_Tests.cs index dc3e68f3e5..57760c4223 100644 --- a/Tests/terminalGoogleTests/Integration/Terminal_Discover_v1_Tests.cs +++ b/Tests/terminalGoogleTests/Integration/Terminal_Discover_v1_Tests.cs @@ -31,18 +31,20 @@ public async Task Terminal_Google_Discover() Assert.IsNotNull(googleTerminalDiscoveryResponse, "Terminal Google discovery did not happen."); Assert.IsNotNull(googleTerminalDiscoveryResponse.Activities, "Google terminal does not have actions."); - Assert.AreEqual(4, googleTerminalDiscoveryResponse.Activities.Count, "Google terminal expected 4 actions."); + Assert.AreEqual(5, googleTerminalDiscoveryResponse.Activities.Count, "Google terminal expected 5 actions."); Assert.AreEqual("terminalGoogle", googleTerminalDiscoveryResponse.Definition.Name); Assert.AreEqual("Google", googleTerminalDiscoveryResponse.Definition.Label); Assert.AreEqual(googleTerminalDiscoveryResponse.Activities.Any(a => a.Name == "Get_Google_Sheet_Data"), true, "Action Get_Google_Sheet_Data was not loaded"); Assert.AreEqual(googleTerminalDiscoveryResponse.Activities.Any(a => a.Name == "Monitor_Form_Responses"), true, "Action Monitor_Form_Responses was not loaded"); Assert.AreEqual(googleTerminalDiscoveryResponse.Activities.Any(a => a.Name == "Save_To_Google_Sheet"), true, "Action Save_To_Google_Sheet was not loaded"); Assert.AreEqual(googleTerminalDiscoveryResponse.Activities.Any(a => a.Name == "Monitor_Gmail_Inbox"), true, "Action Monitor_Gmail_Inbox was not loaded"); + Assert.AreEqual(googleTerminalDiscoveryResponse.Activities.Any(a => a.Name == "Create_Google_Doc"), true, "Action Create_Google_Doc was not loaded"); //Check Activities Categories Assert.True(googleTerminalDiscoveryResponse.Activities.Single(a => a.Name == "Get_Google_Sheet_Data").Categories.Any(x => x.Id == ActivityCategories.ReceiveId), "Activity Get_Google_Sheet_Data is not of Category Receivers"); Assert.True(googleTerminalDiscoveryResponse.Activities.Single(a => a.Name == "Monitor_Form_Responses").Categories.Any(x => x.Id == ActivityCategories.MonitorId), "Activity Monitor_Form_Responses is not of Category Monitors"); Assert.True(googleTerminalDiscoveryResponse.Activities.Single(a => a.Name == "Save_To_Google_Sheet").Categories.Any(x => x.Id == ActivityCategories.ForwardId), "Activity Save_To_Google_Sheet is not of Category Forwarders"); Assert.True(googleTerminalDiscoveryResponse.Activities.Single(a => a.Name == "Monitor_Gmail_Inbox").Categories.Any(x => x.Id == ActivityCategories.MonitorId), "Activity Monitor_Gmail_Inbox is not of Category Monitors"); + Assert.True(googleTerminalDiscoveryResponse.Activities.Single(a => a.Name == "Create_Google_Doc").Categories.Any(x => x.Id == ActivityCategories.ForwardId), "Activity Create_Google_Doc is not of Category Forwarders"); } } } From 1dd298cc63b606a539a164748e97743224b851df Mon Sep 17 00:00:00 2001 From: jarekrzdbk Date: Tue, 23 Aug 2016 20:16:26 +0300 Subject: [PATCH 4/5] added FileUtils --- terminalUtilities/Excel/ExcelUtils.cs | 16 ++--- terminalUtilities/Files/FileUtils.cs | 71 ++++++++++++++++++++ terminalUtilities/terminalUtilities.csproj | 1 + terminalWord/Activities/Load_Word_File_v1.cs | 26 ++----- terminalWord/terminalWord.csproj | 4 ++ 5 files changed, 88 insertions(+), 30 deletions(-) create mode 100644 terminalUtilities/Files/FileUtils.cs diff --git a/terminalUtilities/Excel/ExcelUtils.cs b/terminalUtilities/Excel/ExcelUtils.cs index 6e911c7a39..85e5a47515 100644 --- a/terminalUtilities/Excel/ExcelUtils.cs +++ b/terminalUtilities/Excel/ExcelUtils.cs @@ -15,6 +15,7 @@ using OfficeOpenXml; using StructureMap; using RestSharp.Extensions; +using terminalUtilities.Files; namespace terminalUtilities.Excel { @@ -22,11 +23,13 @@ public class ExcelUtils { private readonly IRestfulServiceClient _restfulServiceClient; private readonly ICrateManager _crateManager; + private readonly FileUtils _fileUtils; - public ExcelUtils(IRestfulServiceClient restfulServiceClient, ICrateManager crateManager) + public ExcelUtils(IRestfulServiceClient restfulServiceClient, ICrateManager crateManager, FileUtils fileUtils) { _restfulServiceClient = restfulServiceClient; _crateManager = crateManager; + _fileUtils = fileUtils; } public static void ConvertToCsv(string pathToExcel, string pathToCsv) @@ -263,9 +266,7 @@ public static Dictionary>> GetTabularData(byt public async Task GetExcelFileAsByteArray(string selectedFilePath) { - var fileAsByteArray = await RetrieveFile(selectedFilePath); - fileAsByteArray.Position = 0; - return fileAsByteArray.ReadAsBytes(); + return await _fileUtils.GetFileAsByteArray(selectedFilePath, ".xls", ".xlsx"); } public async Task GetExcelFile(string selectedFilePath, bool isFirstRowAsColumnNames = true) @@ -334,12 +335,7 @@ public StandardTableDataCM GetExcelFile(byte[] fileAsByteArray, string selectedF private async Task RetrieveFile(string filePath) { - var ext = Path.GetExtension(filePath); - if (ext != ".xls" && ext != ".xlsx") - { - throw new ArgumentException("Expected '.xls' or '.xlsx'", "selectedFile"); - } - return await _restfulServiceClient.DownloadAsync(new Uri(filePath)); + return await _fileUtils.RetrieveFile(filePath, ".xls", ".xlsx"); } public static List CreateTableCellPayloadObjects(Dictionary>> rowsDictionary, string[] headersArray = null, bool includeHeadersAsFirstRow = false) diff --git a/terminalUtilities/Files/FileUtils.cs b/terminalUtilities/Files/FileUtils.cs new file mode 100644 index 0000000000..6ed4ed3d48 --- /dev/null +++ b/terminalUtilities/Files/FileUtils.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Excel; +using Fr8.Infrastructure.Data.Crates; +using Fr8.Infrastructure.Data.DataTransferObjects; +using Fr8.Infrastructure.Data.Managers; +using Fr8.Infrastructure.Data.Manifests; +using Fr8.Infrastructure.Data.States; +using Fr8.Infrastructure.Interfaces; +using OfficeOpenXml; +using StructureMap; +using RestSharp.Extensions; + +namespace terminalUtilities.Files +{ + public class FileUtils + { + private readonly IRestfulServiceClient _restfulServiceClient; + + public FileUtils(IRestfulServiceClient restfulServiceClient, ICrateManager crateManager) + { + _restfulServiceClient = restfulServiceClient; + } + + + public async Task GetFileAsByteArray(string selectedFilePath, params string[] extensions) + { + var fileAsByteArray = await RetrieveFile(selectedFilePath, extensions); + fileAsByteArray.Position = 0; + return fileAsByteArray.ReadAsBytes(); + } + public async Task RetrieveFile(string filePath, params string[] extensions) + { + var ext = System.IO.Path.GetExtension(filePath); + string exception = "Expected "; + bool hasException = false; + foreach (var extension in extensions) + { + if(ext == extension) + { + hasException = false; + break; + } + if (ext != extension) + { + hasException = true; + if (extensions.First() == extension) + { + exception += extension; + } + else + { + exception += " or " + extension; + } + } + } + if (hasException == true) + { + throw new ArgumentException(exception, "selectedFile"); + } + + return await _restfulServiceClient.DownloadAsync(new Uri(filePath)); + } + } +} + diff --git a/terminalUtilities/terminalUtilities.csproj b/terminalUtilities/terminalUtilities.csproj index f9d222c36e..5a57909666 100644 --- a/terminalUtilities/terminalUtilities.csproj +++ b/terminalUtilities/terminalUtilities.csproj @@ -155,6 +155,7 @@ + diff --git a/terminalWord/Activities/Load_Word_File_v1.cs b/terminalWord/Activities/Load_Word_File_v1.cs index 14b038c399..da4c38a8f1 100644 --- a/terminalWord/Activities/Load_Word_File_v1.cs +++ b/terminalWord/Activities/Load_Word_File_v1.cs @@ -15,6 +15,7 @@ using Fr8.TerminalBase.BaseClasses; using Fr8.TerminalBase.Errors; using RestSharp.Extensions; +using terminalUtilities.Files; namespace terminalWord.Activities { @@ -81,11 +82,12 @@ public void ClearFileDescription() UploadedFileDescription.IsHidden = true; } } - private readonly Fr8.Infrastructure.Interfaces.IRestfulServiceClient _restfulServiceClient; - public Load_Word_File_v1(ICrateManager crateManager, Fr8.Infrastructure.Interfaces.IRestfulServiceClient restfulServiceClient) + + private readonly FileUtils _fileUtils; + public Load_Word_File_v1(ICrateManager crateManager, FileUtils fileUtils) : base(crateManager) { - _restfulServiceClient = restfulServiceClient; + _fileUtils = fileUtils; } public override async Task Initialize() @@ -107,25 +109,9 @@ protected override Task Validate() return Task.FromResult(0); } - public async Task GetFileAsByteArray(string selectedFilePath) - { - var fileAsByteArray = await RetrieveFile(selectedFilePath); - fileAsByteArray.Position = 0; - return fileAsByteArray.ReadAsBytes(); - } - private async Task RetrieveFile(string filePath) - { - var ext = System.IO.Path.GetExtension(filePath); - if (ext != ".doc" && ext != ".docx") - { - throw new ArgumentException("Expected '.doc' or '.docx'", "selectedFile"); - } - return await _restfulServiceClient.DownloadAsync(new Uri(filePath)); - } - public override async Task Run() { - var byteArray = await GetFileAsByteArray(ActivityUI.FilePicker.Value); + var byteArray = await _fileUtils.GetFileAsByteArray(ActivityUI.FilePicker.Value, ".doc", ".docx"); var fileDescription = new StandardFileDescriptionCM { diff --git a/terminalWord/terminalWord.csproj b/terminalWord/terminalWord.csproj index dd3bef34a3..52b60a66f6 100644 --- a/terminalWord/terminalWord.csproj +++ b/terminalWord/terminalWord.csproj @@ -198,6 +198,10 @@ {bf96675e-6baf-4ac9-b247-1551d62e8c44} Fr8TerminalBase.NET + + {E46B602A-287B-450F-B455-5EED20C93EB7} + terminalUtilities + 10.0 From 8dac03f6ddfc6fc3cd11ece2d626494e4c3f07b9 Mon Sep 17 00:00:00 2001 From: jarekrzdbk Date: Tue, 23 Aug 2016 20:16:56 +0300 Subject: [PATCH 5/5] modified GetCurrentUsersFiles method --- .../Activities/Create_Google_Doc_v1.cs | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/terminalGoogle/Activities/Create_Google_Doc_v1.cs b/terminalGoogle/Activities/Create_Google_Doc_v1.cs index f68ffefae4..f2614c2dda 100644 --- a/terminalGoogle/Activities/Create_Google_Doc_v1.cs +++ b/terminalGoogle/Activities/Create_Google_Doc_v1.cs @@ -127,7 +127,7 @@ private GoogleAuthDTO GetGoogleAuthToken() public override async Task Initialize() { - ActivityUI.ExistingFilesList.ListItems = await GetCurrentUsersFiles(); + ActivityUI.ExistingFilesList.ListItems = await GetCurrentUsersFiles(".doc",".docx"); } public override async Task FollowUp() @@ -219,11 +219,29 @@ private static string GetMimeType(string fileName) return mimeType; } - private async Task> GetCurrentUsersFiles() + private async Task> GetCurrentUsersFiles(params string[] extensions) { - //Leave only XLSX files as activity fails to rewrite XLS files - var curAccountFileList = (await HubCommunicator.GetFiles()).Where(x => (x.OriginalFileName?.EndsWith(".doc", StringComparison.InvariantCultureIgnoreCase) ?? true)|| (x.OriginalFileName?.EndsWith(".docx", StringComparison.InvariantCultureIgnoreCase) ?? true)); - //TODO where tags == Docusign files + var curAccountFileList = await HubCommunicator.GetFiles(); + if(extensions != null) + { + curAccountFileList = curAccountFileList.Where(f => + { + bool result = true; + foreach (var ext in extensions) + { + if (f.OriginalFileName.EndsWith(ext, StringComparison.InvariantCultureIgnoreCase)) + { + result = true; + } + else + { + result = false; + } + } + return result; + }); + } + return curAccountFileList.Select(c => new ListItem() { Key = c.OriginalFileName, Value = c.Id.ToString(CultureInfo.InvariantCulture) }).ToList(); }