Either <Error, Unit> Save(BookTransfer request)
 {
     //throw new NotImplementedException();
     //return Errors.SaveProblem;
     // Pretend it has been implemented and has been successful
     return(F.Unit());
 }
Пример #2
0
 public static int HandleSilentDownload(DownloadBookOptions options)
 {
     // This task will be all the program does. We need to do enough setup so that
     // the download code can work, then tear it down.
     Program.SetUpErrorHandling();
     try
     {
         using (var applicationContainer = new ApplicationContainer())
         {
             Program.SetUpLocalization(applicationContainer);
             Browser.SetUpXulRunner();
             Browser.XulRunnerShutdown += Program.OnXulRunnerShutdown;
             LocalizationManager.SetUILanguage(Settings.Default.UserInterfaceLanguage, false);
             var transfer = new BookTransfer(new BloomParseClient(), ProjectContext.CreateBloomS3Client(),
                                             applicationContainer.BookThumbNailer, new BookDownloadStartingEvent()) /*not hooked to anything*/;
             // Since Bloom is not a normal console app, when run from a command line, the new command prompt
             // appears at once. The extra newlines here are attempting to separate this from our output.
             Console.WriteLine("\nstarting download");
             transfer.HandleDownloadWithoutProgress(options.Url, options.DestinationPath);
             Console.WriteLine(("\ndownload complete\n"));
         }
         return(0);
     }
     catch (Exception ex)
     {
         Debug.WriteLine(ex.Message);
         Console.WriteLine(ex.Message);
         Console.WriteLine(ex.StackTrace);
         return(1);
     }
 }
Пример #3
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, ControllerActivator ctrlActivator)
        {
            ctrlActivator.loggerFactory = loggerFactory;

            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            //var routeBuilder = new RouteBuilder(app);
            //routeBuilder.MapRoute("echo", (context) =>
            //{
            //   var body = new StreamReader(context.Request.Body).ReadToEnd();

            //   // context.GetRouteData().Values
            //   return context.Response.WriteAsync(body);
            //});

            //app.UseRouter(routeBuilder.Build());

            var useCases = new UseCaseFactory(Configuration, loggerFactory);

            // demonstrates how you can just have all your logic live in functions;
            // but this fails to provide many niceties you get when using a Controller
            app.Map("/api/transferOn", a => a.Run(async ctx =>
            {
                BookTransfer transfer = await Parse <BookTransfer>(ctx.Request.Body);
                IActionResult result  = useCases.PersistTransferOn()(transfer);
                await WriteResponse(ctx.Response, result);
            }));

            app.UseMvcWithDefaultRoute();

            app.UseSwagger();
            app.UseSwaggerUi();
        }
Пример #4
0
 Validation <BookTransfer> ValidateBic(BookTransfer cmd)
 {
     if (!regex.IsMatch(cmd.Bic.ToUpper()))
     {
         return(Errors.InvalidBic);
     }
     return(cmd);
 }
Пример #5
0
 Validation <BookTransfer> ValidateDate(BookTransfer cmd)
 {
     if (cmd.Date.Date <= now.Date)
     {
         return(Invalid(Errors.TransferDateIsPast)); // could omit Invalid
     }
     return(Valid(cmd));                             // could omit Valid as implicit conversion is defined
 }
Пример #6
0
 Validation <BookTransfer> ValidateDate(BookTransfer cmd)
 {
     if (cmd.Date.Date <= now.Date)
     {
         return(Errors.TransferDateIsPast);
     }
     return(cmd);
 }
Пример #7
0
 internal string UploadOneBook(BookInstance book, LogBox progressBox, PublishView publishView, string[] languages, bool excludeNarrationAudio, bool excludeMusic, out string parseId)
 {
     using (var tempFolder = new TemporaryFolder(Path.Combine("BloomUpload", Path.GetFileName(book.FolderPath))))
     {
         BookTransfer.PrepareBookForUpload(ref book, _publishModel.BookServer, tempFolder.FolderPath, progressBox);
         return(_transferrer.FullUpload(book, progressBox, publishView, languages, excludeNarrationAudio, excludeMusic, false, out parseId));
     }
 }
Пример #8
0
 //[HttpPost, Route("api/Chapters7/transfers/future")]
 public IActionResult BookTransfer([FromBody] BookTransfer cmd)
 => validator.Validate(cmd)
 .Map(repository.Save)
 .Match(
     Invalid: BadRequest,
     Valid: result => result.Match <IActionResult>(
         Exception: _ => StatusCode(500, Errors.UnexpectedError),
         Success: _ => Ok()));
 public IActionResult BookTransfer_v1([FromBody] BookTransfer request)
 => Handle(request)
 // Translate elevate types down to normal (leave the abstraction)
 // and handle
 // This is an outer layer adapter from the core (where we use the abstraction)
 // to the outside world
 .Match <IActionResult>(
     Right: _ => Ok(),
     Left: error => BadRequest(error));     // BadRequest from MVC framework takes an error object to return
 Either <Error, BookTransfer> ValidateDate(BookTransfer request)
 {
     // Date must be in the future
     // so this function is not pure as we have date
     if (request.Date.Date <= DateTime.Now.Date)
     {
         return(Errors.TransferDateIsPast);
     }
     return(request);
 }
Пример #11
0
        public void BookWithPeriodInTitle_DoesNotGetTruncatedPdfName()
        {
#if __MonoCS__
            Assert.That(BookTransfer.UploadPdfPath("/somewhere/Look at the sky. What do you see"),
                        Is.EqualTo("/somewhere/Look at the sky. What do you see/Look at the sky. What do you see.pdf"));
#else
            Assert.That(BookTransfer.UploadPdfPath(@"c:\somewhere\Look at the sky. What do you see"),
                        Is.EqualTo(@"c:\somewhere\Look at the sky. What do you see\Look at the sky. What do you see.pdf"));
#endif
        }
Пример #12
0
 Exceptional <Unit> Save(BookTransfer transfer)
 {
     try
     {
         ConnectionHelper.Connect(connString
                                  , c => c.Execute("INSERT ...", transfer));
     }
     catch (Exception ex) { return(ex); }
     return(Unit());
 }
Пример #13
0
 Either <Error, BookTransfer> ValidateBic(BookTransfer request)
 {
     if (!bicRegex.IsMatch(request.Bic))
     {
         return(Errors.InvalidBic);
     }
     else
     {
         return(request);
     }
 }
Пример #14
0
 public static BookTransferDao CreateBookTransferDao(this BookTransfer bookTransfer)
 => new BookTransferDao(
     bookTransfer.AmountToTransfer.Value,
     bookTransfer.BeneficiaryOfTransfer.Value,
     bookTransfer.BicCode.Value,
     bookTransfer.DateOfTransfer.Value,
     bookTransfer.DebitedAccountId.Value,
     bookTransfer.InternationalBankAccountNumber.Value,
     0,
     bookTransfer.ReferenceOfTransfer.Value,
     bookTransfer.TimestampOfTransfer.Value);
Пример #15
0
 Either <Error, BookTransfer> ValidateDate(BookTransfer request)
 {
     if (request.Date.Date <= now.Date)
     {
         return(Errors.TransferDateIsPast);
     }
     else
     {
         return(request);
     }
 }
        Either <Error, BookTransfer> ValidateBic(BookTransfer cmd)
        {
            if (!bicRegex.IsMatch(cmd.Bic))
            {
                return(Errors.InvalidBic);
            }

            else
            {
                return(cmd);
            }
        }
        Either <Error, BookTransfer> ValidateDate(BookTransfer cmd)
        {
            if (cmd.DateUtc.Date <= now.Date)
            {
                return(Errors.TransferDateIsPast);
            }

            else
            {
                return(cmd);
            }
        }
        Either <Error, BookTransfer> ValidateBic(BookTransfer request)
        {
            // if request.Bic is null this throws a null ref exception!
            // which is Exceptional and not normal control flow

            // not pure as relying on external field (bicRegex)
            if (!bicRegex.IsMatch(request.Bic))
            {
                return(Errors.InvalidBic);
            }
            return(request);
        }
Пример #19
0
 public void Setup()
 {
     _workFolder     = new TemporaryFolder("unittest-" + _thisTestId);
     _workFolderPath = _workFolder.FolderPath;
     Assert.AreEqual(0, Directory.GetDirectories(_workFolderPath).Count(), "Some stuff was left over from a previous test");
     Assert.AreEqual(0, Directory.GetFiles(_workFolderPath).Count(), "Some stuff was left over from a previous test");
     // Todo: Make sure the S3 unit test bucket is empty.
     // Todo: Make sure the parse.com unit test book table is empty
     _parseClient              = new BloomParseClientDouble(_thisTestId);
     _htmlThumbNailer          = new HtmlThumbNailer(new NavigationIsolator());
     _transfer                 = new BookTransfer(_parseClient, new BloomS3Client(BloomS3Client.UnitTestBucketName), new BookThumbNailer(_htmlThumbNailer), new BookDownloadStartingEvent());
     _transfer.BookDownLoaded += (sender, args) => _downloadedBooks.Add(args.BookDetails);
 }
Пример #20
0
        public BloomLibraryPublishModel(BookTransfer transferer, BookInstance book, PublishModel model)
        {
            Book          = book;
            _transferrer  = transferer;
            _publishModel = model;

            _licenseMetadata = Book.GetLicenseMetadata();
            // This is usually redundant, but might not be on old books where the license was set before the new
            // editing code was written.
            Book.SetMetadata(_licenseMetadata);
            _license = _licenseMetadata.License;

            EnsureBookAndUploaderId();
        }
Пример #21
0
        public static int Handle(UploadParameters options)
        {
            bool valid = true;

            if (String.IsNullOrWhiteSpace(options.UploadUser))
            {
                valid = String.IsNullOrWhiteSpace(options.UploadPassword);
            }
            else
            {
                valid = !String.IsNullOrWhiteSpace(options.UploadPassword);
            }
            if (!valid)
            {
                Console.WriteLine("Error: upload -u user and -p password must be used together");
                return(1);
            }
            IsUploading = true;

            // This task will be all the program does. We need to do enough setup so that
            // the upload code can work, then tear it down.
            Program.SetUpErrorHandling();
            try
            {
                using (var applicationContainer = new ApplicationContainer())
                {
                    Program.SetUpLocalization(applicationContainer);
                    Browser.SetUpXulRunner();
                    Browser.XulRunnerShutdown += Program.OnXulRunnerShutdown;
                    LocalizationManager.SetUILanguage(Settings.Default.UserInterfaceLanguage, false);
                    var transfer = new BookTransfer(new BloomParseClient(), ProjectContext.CreateBloomS3Client(),
                                                    applicationContainer.BookThumbNailer, new BookDownloadStartingEvent());

                    // Since Bloom is not a normal console app, when run from a command line, the new command prompt
                    // appears at once. The extra newlines here are attempting to separate this from our output.
                    Console.WriteLine("\nstarting upload");
                    transfer.UploadFolder(options.Path, applicationContainer, options.ExcludeNarrationAudio, options.UploadUser, options.UploadPassword, options.SingleBookshelfLevel, options.PreserveThumbnails);
                    Console.WriteLine(("\nupload complete\n"));
                }
                return(0);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
                return(1);
            }
        }
Пример #22
0
        public Harvester(HarvesterCommonOptions options)
        {
            // Note: If the same machine runs multiple BloomHarvester processes, then you need to add a suffix to this.
            this.Identifier = Environment.MachineName;

            if (options.SuppressLogs)
            {
                _logger = new ConsoleLogger();
            }
            else
            {
                EnvironmentSetting azureMonitorEnvironment = EnvironmentUtils.GetEnvOrFallback(options.LogEnvironment, options.Environment);
                _logger = new AzureMonitorLogger(azureMonitorEnvironment, this.Identifier);
            }

            EnvironmentSetting parseDBEnvironment = EnvironmentUtils.GetEnvOrFallback(options.ParseDBEnvironment, options.Environment);

            _parseClient        = new ParseClient(parseDBEnvironment);
            _parseClient.Logger = _logger;

            string downloadBucketName;
            string uploadBucketName;

            switch (parseDBEnvironment)
            {
            case EnvironmentSetting.Prod:
                downloadBucketName = BloomS3Client.ProductionBucketName;
                uploadBucketName   = HarvesterS3Client.HarvesterProductionBucketName;
                break;

            case EnvironmentSetting.Test:
                downloadBucketName = BloomS3Client.UnitTestBucketName;
                uploadBucketName   = HarvesterS3Client.HarvesterUnitTestBucketName;
                break;

            case EnvironmentSetting.Dev:
            case EnvironmentSetting.Local:
            default:
                downloadBucketName = BloomS3Client.SandboxBucketName;
                uploadBucketName   = HarvesterS3Client.HarvesterSandboxBucketName;
                break;
            }
            _transfer = new BookTransfer(_parseClient,
                                         bloomS3Client: new HarvesterS3Client(downloadBucketName),
                                         htmlThumbnailer: null,
                                         bookDownloadStartingEvent: new BookDownloadStartingEvent());

            _s3UploadClient = new HarvesterS3Client(uploadBucketName);
        }
        public BloomLibraryPublishModel(BookTransfer transferer, BookInstance book)
        {
            Book         = book;
            _transferrer = transferer;

            _licenseMetadata = Book.GetLicenseMetadata();
            // This is usually redundant, but might not be on old books where the license was set before the new
            // editing code was written.
            Book.SetMetadata(_licenseMetadata);
            _license = _licenseMetadata.License;

            EnsureBookAndUploaderId();
            WebUserId          = Settings.Default.WebUserId;
            _storedWebPassword = Settings.Default.WebPassword;
        }
Пример #24
0
 Exceptional <Unit> Save(BookTransfer transfer)
 {
     // try/catch is as small as possible
     // immediately translate to functional style wrapping the result in an Exceptional
     try
     {
         // would end up with a 500 and generic error code to client
         // full error logged on server
         //throw new Exception("asdf");
         //ConnectionHelper.Connect(connString
         //, c => c.Execute("INSERT ...", transfer));
     }
     catch (Exception ex) { return(ex); }
     return(Unit());
 }
 public void Setup()
 {
     _workFolder     = new TemporaryFolder("unittest");
     _workFolderPath = _workFolder.FolderPath;
     Assert.AreEqual(0, Directory.GetDirectories(_workFolderPath).Count(), "Some stuff was left over from a previous test");
     Assert.AreEqual(0, Directory.GetFiles(_workFolderPath).Count(), "Some stuff was left over from a previous test");
     // Todo: Make sure the S3 unit test bucket is empty.
     // Todo: Make sure the parse.com unit test book table is empty
     _parseClient = new BloomParseClient();
     // These substitute keys target the "silbloomlibraryunittests" application so testing won't interfere with the real one.
     _parseClient.ApiKey         = "HuRkXoF5Z3hv8f3qHE4YAIrDjwNk4VID9gFxda1U";
     _parseClient.ApplicationKey = "r1H3zle1Iopm1IB30S4qEtycvM4xYjZ85kRChjkM";
     _htmlThumbNailer            = new HtmlThumbNailer(new NavigationIsolator());
     _transfer = new BookTransfer(_parseClient, new BloomS3Client(BloomS3Client.UnitTestBucketName), _htmlThumbNailer, new BookDownloadStartingEvent());
     _transfer.BookDownLoaded += (sender, args) => _downloadedBooks.Add(args.BookDetails);
 }
Пример #26
0
        public delegate PublishView Factory();        //autofac uses this

        public PublishView(PublishModel model,
                           SelectedTabChangedEvent selectedTabChangedEvent, LocalizationChangedEvent localizationChangedEvent, BookTransfer bookTransferrer, LoginDialog login)
        {
            _bookTransferrer = bookTransferrer;
            _loginDialog     = login;

            InitializeComponent();

            if (this.DesignMode)
            {
                return;
            }

            _model      = model;
            _model.View = this;

            _makePdfBackgroundWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(_makePdfBackgroundWorker_RunWorkerCompleted);

            //NB: just triggering off "VisibilityChanged" was unreliable. So now we trigger
            //off the tab itself changing, either to us or away from us.
            selectedTabChangedEvent.Subscribe(c =>
            {
                if (c.To == this)
                {
                    Activate();
                }
                else if (c.To != this && IsMakingPdf)
                {
                    _makePdfBackgroundWorker.CancelAsync();
                }
            });

            //TODO: find a way to call this just once, at the right time:

            //			DeskAnalytics.Track("Publish");

//#if DEBUG
//          var linkLabel = new LinkLabel() {Text = "DEBUG"};
//			linkLabel.Click+=new EventHandler((x,y)=>_model.DebugCurrentPDFLayout());
//          tableLayoutPanel1.Controls.Add(linkLabel);
//#endif

            _menusToolStrip.Renderer = new EditingView.FixedToolStripRenderer();
            GeckoPreferences.Default["pdfjs.disabled"] = false;
            SetupLocalization();
            localizationChangedEvent.Subscribe(o => SetupLocalization());
        }
Пример #27
0
        public void DuplicateIdTest()
        {
            // SUT (use workFolder as the root directory)
            BookTransfer.BulkRepairInstanceIds(_workFolderPath);

            // Verification
            var book1 = _foldersToDispose[3];
            var book2 = _foldersToDispose[4];
            var book3 = _foldersToDispose[5];
            var book4 = _foldersToDispose[6];
            var book5 = _foldersToDispose[7];

            Assert.That(GetInstanceIdFromMetadataFile(book1), Is.Not.EqualTo(_guid1), "book1 should have changed guid1");
            Assert.That(GetInstanceIdFromMetadataFile(book2), Is.Not.EqualTo(_guid1), "book2 should have changed guid1");
            Assert.That(GetInstanceIdFromMetadataFile(book1), Is.Not.EqualTo(GetInstanceIdFromMetadataFile(book2)), "book1 should have different guid than book2");
            Assert.That(GetInstanceIdFromMetadataFile(book3), Is.EqualTo(_guid1), "book3 should have guid1");
            Assert.That(GetInstanceIdFromMetadataFile(book4), Is.EqualTo(_guid2), "book4 should have guid2");
            Assert.That(GetInstanceIdFromMetadataFile(book4), Is.Not.EqualTo(GetInstanceIdFromMetadataFile(book5)), "book4 should have different guid than book5");
        }
Пример #28
0
        public LibraryListView(LibraryModel model, BookSelection bookSelection, SelectedTabChangedEvent selectedTabChangedEvent, LocalizationChangedEvent localizationChangedEvent,
                               HistoryAndNotesDialog.Factory historyAndNotesDialogFactory, BookTransfer bookTransferrer)
        {
            _model         = model;
            _bookSelection = bookSelection;
            localizationChangedEvent.Subscribe(unused => LoadSourceCollectionButtons());
            _historyAndNotesDialogFactory = historyAndNotesDialogFactory;
            _bookTransferrer          = bookTransferrer;
            _buttonsNeedingSlowUpdate = new ConcurrentQueue <Button>();
            selectedTabChangedEvent.Subscribe(OnSelectedTabChanged);
            InitializeComponent();
            _primaryCollectionFlow.HorizontalScroll.Visible = false;

            _primaryCollectionFlow.Controls.Clear();
            _primaryCollectionFlow.HorizontalScroll.Visible = false;
            _sourceBooksFlow.Controls.Clear();
            _sourceBooksFlow.HorizontalScroll.Visible = false;

            if (!_model.ShowSourceCollections)
            {
                splitContainer1.Panel2Collapsed = true;
            }

            _headerFont         = new Font(SystemFonts.DialogFont.FontFamily, (float)10.0, FontStyle.Bold);
            _editableBookFont   = new Font(SystemFonts.DialogFont.FontFamily, (float)9.0);          //, FontStyle.Bold);
            _collectionBookFont = new Font(SystemFonts.DialogFont.FontFamily, (float)9.0);

            //enhance: move to model
            bookSelection.SelectionChanged += new EventHandler(OnBookSelectionChanged);

            _settingsProtectionHelper.ManageComponent(_openFolderOnDisk);

            _showHistoryMenu.Visible = _showNotesMenu.Visible = Settings.Default.ShowSendReceive;

            if (Settings.Default.ShowExperimentalCommands)
            {
                _settingsProtectionHelper.ManageComponent(_exportToXMLForInDesignToolStripMenuItem);                //we are restriting it because it opens a folder from which the user could do damage
            }
            _exportToXMLForInDesignToolStripMenuItem.Visible = Settings.Default.ShowExperimentalCommands;
        }
Пример #29
0
        public BloomLibraryPublishControl(PublishView parentView, BookTransfer bookTransferrer, LoginDialog login, Book.Book book)
        {
            _parentView      = parentView;
            _bookTransferrer = bookTransferrer;
            _loginDialog     = login;
            _book            = book;
            InitializeComponent();
            _originalLoginText = _loginLink.Text;             // Before anything might modify it (but after InitializeComponent creates it).
            _titleLabel.Text   = book.BookInfo.Title;

            _progressBox.ShowDetailsMenuItem         = true;
            _progressBox.ShowCopyToClipboardMenuItem = true;
            _progressBox.LinkClicked += _progressBox_LinkClicked;

            var metadata = book.GetLicenseMetadata();

            // This is usually redundant, but might not be on old books where the license was set before the new
            // editing code was written.
            book.UpdateLicenseMetdata(metadata);
            var license = metadata.License;

            if (license == null || (license is NullLicense && string.IsNullOrWhiteSpace(metadata.CopyrightNotice)))
            {
                // A null license and no copyright indicates they never even opened the ClearShare dialog to choose a license.
                _usingCcControls        = false;
                _usingNotesLabel        = false;
                _licenseSuggestion.Text = _pleaseSetThis;
                _okToUpload             = false;
            }
            else if (license is CreativeCommonsLicense)
            {
                _creativeCommonsLink.Text = license.Token.ToUpperInvariant();
                _usingNotesSuggestion     = false;
                if (string.IsNullOrWhiteSpace(license.RightsStatement))
                {
                    _licenseNotesLabel.Hide();
                }
                else
                {
                    _licenseNotesLabel.Text = LocalizationManager.GetString("PublishTab.Upload.AdditionalRequests", "AdditionalRequests: ") + license.RightsStatement;
                }
            }
            else if (license is NullLicense)
            {
                _usingCcControls        = false;
                _licenseNotesLabel.Text = LocalizationManager.GetString("PublishTab.Upload.AllReserved", "All rights reserved (Contact the Copyright holder for any permissions.)");
                if (!string.IsNullOrWhiteSpace(license.RightsStatement))
                {
                    _licenseNotesLabel.Text += Environment.NewLine + license.RightsStatement;
                }
                _licenseSuggestion.Text = LocalizationManager.GetString("PublishTab.Upload.SuggestAssignCC", "Suggestion: Assigning a Creative Commons License makes it easy for you to clearly grant certain permissions to everyone.");
            }
            else
            {
                // So far, this means it must be custom license (with non-blank rights...actually, currently, the palaso dialog will not allow a custom license with no rights statement).
                _usingCcControls        = false;
                _licenseNotesLabel.Text = license.RightsStatement;
                _licenseSuggestion.Text = LocalizationManager.GetString("PublishTab.Upload.SuggestChangeCC", "Suggestion: Creative Commons Licenses make it much easier for others to use your book, even if they aren't fluent in the language of your custom license.");
            }

            _copyrightLabel.Text = book.BookInfo.Copyright;

            _languagesLabel.Text = string.Join(", ", book.AllLanguages.Select(lang => _book.PrettyPrintLanguage(lang)).ToArray());

            _creditsLabel.Text = book.BookInfo.Credits;
            _summaryBox.Text   = book.BookInfo.Summary;

            try
            {
                _loginDialog.LogIn();                 // See if saved credentials work.
            }
            catch (Exception e)
            {
                Palaso.Reporting.ErrorReport.NotifyUserOfProblem(e,
                                                                 LocalizationManager.GetString("PublishTab.Upload.LoginFailure",
                                                                                               "Bloom could not log in to BloomLibrary.org using your saved credentials. Please check your network connection."));
            }
            _optional1.Left = _summaryBox.Right - _optional1.Width;             // right-align these (even if localization changes their width)
            RequireValue(_copyrightLabel);
            RequireValue(_titleLabel);
            RequireValue(_languagesLabel);

            if (BookTransfer.UseSandbox)
            {
                var oldTextWidth = TextRenderer.MeasureText(_uploadButton.Text, _uploadButton.Font).Width;
                _uploadButton.Text = LocalizationManager.GetString("PublishTab.Upload.UploadSandbox", "Upload Book (to Sandbox)");
                var neededWidth = TextRenderer.MeasureText(_uploadButton.Text, _uploadButton.Font).Width;
                _uploadButton.Width += neededWidth - oldTextWidth;
            }
        }
Пример #30
0
 Validation <BookTransfer> Validate(BookTransfer cmd)
 => ValidateBic(cmd).Bind(ValidateDate);