예제 #1
0
        /// <summary>
        /// Exports the dictionary xhtml and css for the publication and configuration that the user had selected in the dialog.
        /// </summary>
        private void ExportDictionaryContent(string tempDirectoryToCompress, UploadToWebonaryModel model, IUploadToWebonaryView webonaryView)
        {
            webonaryView.UpdateStatus(String.Format(xWorksStrings.ExportingEntriesToWebonary, model.SelectedPublication, model.SelectedConfiguration));
            var xhtmlPath     = Path.Combine(tempDirectoryToCompress, "configured.xhtml");
            var configuration = model.Configurations[model.SelectedConfiguration];

            m_exportService.ExportDictionaryContent(xhtmlPath, configuration);
            webonaryView.UpdateStatus(xWorksStrings.ExportingEntriesToWebonaryCompleted);
        }
예제 #2
0
        public UploadToWebonaryDlg(UploadToWebonaryController controller, UploadToWebonaryModel model, Mediator mediator)
        {
            InitializeComponent();

            if (MiscUtils.IsUnix)
            {
                MinimumSize = new Size(MinimumSize.Width, MinimumSize.Height + m_additionalMinimumHeightForMono);
            }

            m_controller = controller;
            Mediator     = mediator;
            Model        = model;
            LoadFromModel();

            m_helpTopicProvider = mediator.HelpTopicProvider;

            // When a link is clicked, open a web page to the URL.
            explanationLabel.LinkClicked += (sender, args) =>
            {
                using (Process.Start(((LinkLabel)sender).Text.Substring(args.Link.Start, args.Link.Length)))
                {}
            };

            // Restore the location and size from last time we called this dialog.
            if (Mediator != null && Mediator.PropertyTable != null)
            {
                object locWnd = Mediator.PropertyTable.GetValue("UploadToWebonaryDlg_Location");
                object szWnd  = Mediator.PropertyTable.GetValue("UploadToWebonaryDlg_Size");
                if (locWnd != null && szWnd != null)
                {
                    Rectangle rect = new Rectangle((Point)locWnd, (Size)szWnd);
                    ScreenUtils.EnsureVisibleRect(ref rect);
                    DesktopBounds = rect;
                    StartPosition = FormStartPosition.Manual;
                }
            }

            // Start with output log area not shown by default
            // When a user clicks Publish, it is revealed. This is done within the context of having a resizable table of controls, and having
            // the output log area be the vertically growing control when a user increases the height of the dialog
            this.Shown += (sender, args) => { this.Height = this.Height - outputLogTextbox.Height; };

            // Handle localizable explanation area with link.
            var explanationText           = xWorksStrings.toApplyForWebonaryAccountExplanation;
            var explanationTextLink       = xWorksStrings.toApplyForWebonaryAccountLink;
            var explanationTextLinkStart  = explanationText.IndexOf("{", StringComparison.Ordinal);
            var explanationTextLinkLength = explanationTextLink.Length;

            explanationLabel.Text = string.Format(explanationText, explanationTextLink);
            // Don't blow up if a localization didn't allow for the link.
            if (explanationTextLinkStart < 0)
            {
                explanationTextLinkStart  = 0;
                explanationTextLinkLength = 0;
            }
            explanationLabel.LinkArea = new LinkArea(explanationTextLinkStart, explanationTextLinkLength);
        }
예제 #3
0
        public void UploadToWebonary(UploadToWebonaryModel model, IUploadToWebonaryView view)
        {
            view.UpdateStatus(xWorksStrings.ksUploadingToWebonary);
            view.SetStatusCondition(WebonaryStatusCondition.None);

            if (string.IsNullOrEmpty(model.SiteName))
            {
                view.UpdateStatus(xWorksStrings.ksErrorNoSiteName);
                view.SetStatusCondition(WebonaryStatusCondition.Error);
                return;
            }

            if (string.IsNullOrEmpty(model.UserName))
            {
                view.UpdateStatus(xWorksStrings.ksErrorNoUsername);
                view.SetStatusCondition(WebonaryStatusCondition.Error);
                return;
            }

            if (string.IsNullOrEmpty(model.Password))
            {
                view.UpdateStatus(xWorksStrings.ksErrorNoPassword);
                view.SetStatusCondition(WebonaryStatusCondition.Error);
                return;
            }

            if (string.IsNullOrEmpty(model.SelectedPublication))
            {
                view.UpdateStatus(xWorksStrings.ksErrorNoPublication);
                view.SetStatusCondition(WebonaryStatusCondition.Error);
                return;
            }

            if (string.IsNullOrEmpty(model.SelectedConfiguration))
            {
                view.UpdateStatus(xWorksStrings.ksErrorNoConfiguration);
                view.SetStatusCondition(WebonaryStatusCondition.Error);
                return;
            }

            var tempDirectoryToCompress = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            var zipBasename             = UploadFilename(model, view);

            if (zipBasename == null)
            {
                return;
            }
            var zipFileToUpload = Path.Combine(Path.GetTempPath(), zipBasename);

            Directory.CreateDirectory(tempDirectoryToCompress);
            ExportDictionaryContent(tempDirectoryToCompress, model, view);
            ExportReversalContent(tempDirectoryToCompress, model, view);
            ExportOtherFilesContent(tempDirectoryToCompress, model, view);
            CompressExportedFiles(tempDirectoryToCompress, zipFileToUpload, view);
            UploadToWebonary(zipFileToUpload, model, view);
        }
 public void UploadToWebonaryThrowsOnNullInput()
 {
     using (var controller = new MockUploadToWebonaryController(Cache, m_mediator, null, null))
     {
         var view  = new MockWebonaryDlg();
         var model = new UploadToWebonaryModel(m_mediator);
         Assert.Throws <ArgumentNullException>(() => controller.UploadToWebonary(null, model, view));
         Assert.Throws <ArgumentNullException>(() => controller.UploadToWebonary("notNull", null, view));
         Assert.Throws <ArgumentNullException>(() => controller.UploadToWebonary("notNull", model, null));
     }
 }
예제 #5
0
        /// <summary>
        /// Filename of zip file to upload to webonary, based on a particular model.
        /// If there are any characters that might cause a problem, null is returned.
        /// </summary>
        internal static string UploadFilename(UploadToWebonaryModel basedOnModel, IUploadToWebonaryView view)
        {
            if (basedOnModel == null)
            {
                throw new ArgumentNullException(nameof(basedOnModel));
            }
            if (string.IsNullOrEmpty(basedOnModel.SiteName))
            {
                throw new ArgumentException(nameof(basedOnModel));
            }
            var disallowedCharacters = MiscUtils.GetInvalidProjectNameChars(MiscUtils.FilenameFilterStrength.kFilterProjName) + "_ $.%";

            if (basedOnModel.SiteName.IndexOfAny(disallowedCharacters.ToCharArray()) >= 0)
            {
                view.UpdateStatus(xWorksStrings.ksErrorInvalidCharacters);
                view.SetStatusCondition(WebonaryStatusCondition.Error);
                return(null);
            }
            return(basedOnModel.SiteName + ".zip");
        }
예제 #6
0
 /// <summary>
 /// Exports the reversal xhtml and css for the reversals that the user had selected in the dialog
 /// </summary>
 private void ExportReversalContent(string tempDirectoryToCompress, UploadToWebonaryModel model, IUploadToWebonaryView webonaryView)
 {
     if (model.Reversals == null)
     {
         return;
     }
     foreach (var reversal in model.SelectedReversals)
     {
         var revWsRFC5646 = model.Reversals.Where(prop => prop.Value.Label == reversal).Select(prop => prop.Value.WritingSystem).FirstOrDefault();
         webonaryView.UpdateStatus(string.Format(xWorksStrings.ExportingReversalsToWebonary, reversal));
         var reversalWs = m_cache.LangProject.AnalysisWritingSystems.FirstOrDefault(ws => ws.LanguageTag == revWsRFC5646);
         // The reversalWs should always match the RFC5646 of one of the AnalysisWritingSystems, this exception is for future programming errors
         if (reversalWs == null)
         {
             throw new ApplicationException(string.Format("Could not locate reversal writing system for {0}", reversal));
         }
         var xhtmlPath     = Path.Combine(tempDirectoryToCompress, string.Format("reversal_{0}.xhtml", reversalWs.IcuLocale));
         var configuration = model.Reversals[reversal];
         m_exportService.ExportReversalContent(xhtmlPath, revWsRFC5646, configuration);
         webonaryView.UpdateStatus(xWorksStrings.ExportingReversalsToWebonaryCompleted);
     }
 }
예제 #7
0
 ///<summary>This stub is intended for other files related to front- and backmatter (things not really managed by FLEx itself)</summary>
 private void ExportOtherFilesContent(string tempDirectoryToCompress, UploadToWebonaryModel logTextbox, object outputLogTextbox)
 {
     //TODO: Copy the user selected other files into the temp directory and normalize filenames to NFC
 }
예제 #8
0
        internal void UploadToWebonary(string zipFileToUpload, UploadToWebonaryModel model, IUploadToWebonaryView view)
        {
            if (zipFileToUpload == null)
            {
                throw new ArgumentNullException("zipFileToUpload");
            }
            if (model == null)
            {
                throw new ArgumentNullException("model");
            }
            if (view == null)
            {
                throw new ArgumentNullException("view");
            }

            view.UpdateStatus(xWorksStrings.ksConnectingToWebonary);
            var targetURI = DestinationURI(model.SiteName);

            using (var client = CreateWebClient())
            {
                var credentials = string.Format("{0}:{1}", model.UserName, model.Password);
                client.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(new UTF8Encoding().GetBytes(credentials)));
                client.Headers.Add("user-agent", string.Format("FieldWorks Language Explorer v.{0}", Assembly.GetExecutingAssembly().GetName().Version));
                client.Headers[HttpRequestHeader.Accept] = "*/*";

                byte[] response = null;
                try
                {
                    response = client.UploadFileToWebonary(targetURI, zipFileToUpload);
                }
                catch (WebonaryClient.WebonaryException e)
                {
                    if (e.StatusCode == HttpStatusCode.Redirect)
                    {
                        view.UpdateStatus(xWorksStrings.ksErrorWebonarySiteName);
                    }
                    else
                    {
                        view.UpdateStatus(string.Format(xWorksStrings.ksErrorCannotConnectToWebonary,
                                                        Environment.NewLine, e.StatusCode, e.Message));
                    }
                    view.SetStatusCondition(WebonaryStatusCondition.Error);
                    return;
                }
                var responseText = Encoding.ASCII.GetString(response);

                if (client.ResponseStatusCode == HttpStatusCode.Found)
                {
                    view.UpdateStatus(xWorksStrings.ksErrorWebonarySiteName);
                    view.SetStatusCondition(WebonaryStatusCondition.Error);
                }
                else if (responseText.Contains("Upload successful"))
                {
                    if (!responseText.Contains("error"))
                    {
                        view.UpdateStatus(xWorksStrings.ksWebonaryUploadSuccessful);
                        view.SetStatusCondition(WebonaryStatusCondition.Success);
                        return;
                    }

                    view.UpdateStatus(xWorksStrings.ksWebonaryUploadSuccessfulErrorProcessing);
                    view.SetStatusCondition(WebonaryStatusCondition.Error);
                }

                if (responseText.Contains("Wrong username or password"))
                {
                    view.UpdateStatus(xWorksStrings.ksErrorUsernameOrPassword);
                    view.SetStatusCondition(WebonaryStatusCondition.Error);
                }
                else if (responseText.Contains("User doesn't have permission to import data"))
                {
                    view.UpdateStatus(xWorksStrings.ksErrorUserDoesntHavePermissionToImportData);
                    view.SetStatusCondition(WebonaryStatusCondition.Error);
                }
                else                 // Unknown error, display the server response, but cut it off at 100 characters
                {
                    view.UpdateStatus(string.Format("{0}{1}{2}{1}", xWorksStrings.ksResponseFromServer, Environment.NewLine,
                                                    responseText.Substring(0, Math.Min(100, responseText.Length))));
                }
            }
        }
예제 #9
0
        internal void UploadToWebonary(string zipFileToUpload, UploadToWebonaryModel model, IUploadToWebonaryView view)
        {
            if (zipFileToUpload == null)
            {
                throw new ArgumentNullException("zipFileToUpload");
            }
            if (model == null)
            {
                throw new ArgumentNullException("model");
            }
            if (view == null)
            {
                throw new ArgumentNullException("view");
            }

            view.UpdateStatus("Connecting to Webonary.");
            var targetURI = DestinationURI(model.SiteName);

            using (var client = CreateWebClient())
            {
                var credentials = string.Format("{0}:{1}", model.UserName, model.Password);
                client.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(new UTF8Encoding().GetBytes(credentials)));
                client.Headers.Add("user-agent", string.Format("FieldWorks Language Explorer v.{0}", Assembly.GetExecutingAssembly().GetName().Version));
                client.Headers[HttpRequestHeader.Accept] = "*/*";

                byte[] response = null;
                try
                {
                    response = client.UploadFileToWebonary(targetURI, zipFileToUpload);
                }
                catch (WebonaryClient.WebonaryException e)
                {
                    if (e.StatusCode == HttpStatusCode.Redirect)
                    {
                        view.UpdateStatus("Error: There has been an error accessing webonary. Is your sitename correct?");
                    }
                    else
                    {
                        const string errorMessage = "Unable to connect to Webonary.  Please check your username and password and your Internet connection.";
                        view.UpdateStatus(string.Format("An error occurred uploading your data: {0}{1}{2}:{3}",
                                                        errorMessage, Environment.NewLine, e.StatusCode, e.Message));
                    }
                    view.SetStatusCondition(WebonaryStatusCondition.Error);
                    return;
                }
                var responseText = Encoding.ASCII.GetString(response);

                if (client.ResponseStatusCode == HttpStatusCode.Found)
                {
                    view.UpdateStatus("Error: There has been an error accessing webonary. Is your sitename correct?");
                    view.SetStatusCondition(WebonaryStatusCondition.Error);
                }
                else if (responseText.Contains("Upload successful"))
                {
                    if (!responseText.Contains("error"))
                    {
                        view.UpdateStatus("Upload successful. " +
                                          "Preparing your data for publication. " +
                                          "This may take several minutes to a few hours depending on the size of your dictionary. " +
                                          "You will receive an email when the process is complete. " +
                                          "You can examine the progress on the admin page of your Webonary site. " +
                                          "You may now safely close this dialog.");
                        view.SetStatusCondition(WebonaryStatusCondition.Success);
                        return;
                    }

                    view.UpdateStatus("The upload was successful; however, there were errors processing your data.");
                    view.SetStatusCondition(WebonaryStatusCondition.Error);
                }

                if (responseText.Contains("Wrong username or password"))
                {
                    view.UpdateStatus("Error: Wrong username or password");
                    view.SetStatusCondition(WebonaryStatusCondition.Error);
                }
                else if (responseText.Contains("User doesn't have permission to import data"))
                {
                    view.UpdateStatus("Error: User doesn't have permission to import data");
                    view.SetStatusCondition(WebonaryStatusCondition.Error);
                }
                else                 // Unknown error, display the server response, but cut it off at 100 characters
                {
                    view.UpdateStatus(string.Format("Response from server:{0}{1}{0}", Environment.NewLine,
                                                    responseText.Substring(0, Math.Min(100, responseText.Length))));
                }
            }
        }
 public void DecryptPassword_NullAndEmptyDoNotCrash()
 {
     Assert.DoesNotThrow(() => UploadToWebonaryModel.DecryptPassword(null));
     Assert.DoesNotThrow(() => UploadToWebonaryModel.DecryptPassword(string.Empty));
 }