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; } }
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"; _transfer = new BookTransfer(_parseClient, new BloomS3Client(BloomS3Client.UnitTestBucketName)); }
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); }
static int Main(string[] args1) { Logger.Init(); CheckForCorruptUserConfig(); // Bloom has several command line scenarios, without a coherent system for them. // The following is how we will do things from now on, and things can be moved // into this as time allows. See CommandLineOptions.cs. if (args1.Length > 0 && new[] {"--help", "hydrate", "download", "getfonts"}.Contains(args1[0])) //restrict using the commandline parser to cases were it should work { #if !__MonoCS__ AttachConsole(-1); #endif var exitCode = CommandLine.Parser.Default.ParseArguments(args1, new[] {typeof (HydrateParameters), typeof (DownloadBookOptions), typeof (GetUsedFontsParameters)}) .MapResult( (HydrateParameters opts) => HandlePrepareCommandLine(opts), (DownloadBookOptions opts) => DownloadBookCommand.HandleSilentDownload(opts), (GetUsedFontsParameters opts) => GetUsedFontsCommand.Handle(opts), errors => { var code = 0; foreach(var error in errors) { if(!(error is HelpVerbRequestedError)) { Debug.WriteLine(error.ToString()); Console.WriteLine(error.ToString()); code = 1; } } return code; }); return exitCode; // we're done } //Debug.Fail("Attach Now"); try { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); XWebBrowser.DefaultBrowserType = XWebBrowser.BrowserType.GeckoFx; var args = args1; if (SIL.PlatformUtilities.Platform.IsWindows) { OldVersionCheck(); } //bring in settings from any previous version if (Settings.Default.NeedUpgrade) { //see http://stackoverflow.com/questions/3498561/net-applicationsettingsbase-should-i-call-upgrade-every-time-i-load Settings.Default.Upgrade(); Settings.Default.Reload(); Settings.Default.NeedUpgrade = false; Settings.Default.MaximizeWindow = true; // this is needed to force this to be written to the file, where a user can find it to modify it by hand (our video maker) Settings.Default.Save(); StartUpWithFirstOrNewVersionBehavior = true; } if (IsInstallerLaunch(args)) { InstallerSupport.HandleSquirrelInstallEvent(args); // may exit program } // Needs to be AFTER HandleSquirrelInstallEvent, because that can happen when the program is launched by Update rather than // by the user. if (!Settings.Default.LicenseAccepted) { Browser.SetUpXulRunner(); using (var dlg = new LicenseDialog()) if (dlg.ShowDialog() != DialogResult.OK) return 1; Settings.Default.LicenseAccepted = true; Settings.Default.Save(); } #if !USING_CHORUS Settings.Default.ShowSendReceive = false; // in case someone turned it on before we disabled #endif #if DEBUG if (args.Length > 0) { // This allows us to debug things like interpreting a URL. MessageBox.Show("Attach debugger now"); } #endif // Ensures that registration settings for all channels of Bloom are stored in a common place, // so the user is not asked to register each independently. RegistrationSettingsProvider.SetProductName("Bloom"); Dictionary<string, string> propertiesThatGoWithEveryEvent = ErrorReport.GetStandardProperties(); propertiesThatGoWithEveryEvent.Remove("MachineName"); propertiesThatGoWithEveryEvent.Remove("UserName"); propertiesThatGoWithEveryEvent.Remove("UserDomainName"); propertiesThatGoWithEveryEvent.Add("channel", ApplicationUpdateSupport.ChannelName); #if DEBUG using( new DesktopAnalytics.Analytics("sje2fq26wnnk8c2kzflf", RegistrationDialog.GetAnalyticsUserInfo(), propertiesThatGoWithEveryEvent, false)) _supressRegistrationDialog = true; #else string feedbackSetting = System.Environment.GetEnvironmentVariable("FEEDBACK"); //default is to allow tracking var allowTracking = string.IsNullOrEmpty(feedbackSetting) || feedbackSetting.ToLowerInvariant() == "yes" || feedbackSetting.ToLowerInvariant() == "true"; _supressRegistrationDialog = _supressRegistrationDialog || !allowTracking; using (new DesktopAnalytics.Analytics("c8ndqrrl7f0twbf2s6cv", RegistrationDialog.GetAnalyticsUserInfo(), propertiesThatGoWithEveryEvent, allowTracking)) #endif { // do not show the registration dialog if bloom was started for a special purpose if (args.Length > 0) _supressRegistrationDialog = true; if (args.Length == 1 && args[0].ToLowerInvariant().EndsWith(".bloompack")) { SetUpErrorHandling(); using (_applicationContainer = new ApplicationContainer()) { SetUpLocalization(); var path = args[0]; // This allows local links to bloom packs. if (path.ToLowerInvariant().StartsWith("bloom://")) { path = path.Substring("bloom://".Length); if (!RobustFile.Exists(path)) { path = FileLocator.GetFileDistributedWithApplication(true, path); if (!RobustFile.Exists(path)) return 1; } } using (var dlg = new BloomPackInstallDialog(path)) { dlg.ShowDialog(); if (dlg.ExitWithoutRunningBloom) return 1; } } } if (IsBloomBookOrder(args)) { HandleDownload(args[0]); // If another instance is running, this one has served its purpose and can exit right away. Otherwise, // carry on with starting up normally. See https://silbloom.myjetbrains.com/youtrack/issue/BL-3822. if (!UniqueToken.AcquireTokenQuietly(_mutexId)) return 0; } else { // Check whether another instance of Bloom is running. That should happen only when downloading a book because // BloomLibrary starts a new Bloom process even when one is already running. But that is taken care of in the // other branch of this if/else. So quit if we find another instance of Bloom running at this point. // (A message will pop up to tell the user about this situation if it happens.) if (!UniqueToken.AcquireToken(_mutexId, "Bloom")) return 1; } OldVersionCheck(); SetUpErrorHandling(); using (_applicationContainer = new ApplicationContainer()) { if (args.Length == 2 && args[0].ToLowerInvariant() == "--upload") { // A special path to upload chunks of stuff. This is not currently documented and is not very robust. // - User must log in before running this // - For best results each bloom book needs to be part of a collection in its parent folder // - little error checking (e.g., we don't apply the usual constraints that a book must have title and licence info) SetUpLocalization(); Browser.SetUpXulRunner(); Browser.XulRunnerShutdown += OnXulRunnerShutdown; var transfer = new BookTransfer(new BloomParseClient(), ProjectContext.CreateBloomS3Client(), _applicationContainer.BookThumbNailer, new BookDownloadStartingEvent()) /*not hooked to anything*/; transfer.UploadFolder(args[1], _applicationContainer); return 1; } InstallerSupport.MakeBloomRegistryEntries(args); BookDownloadSupport.EnsureDownloadFolderExists(); SetUpLocalization(); if (args.Length == 1 && !IsInstallerLaunch(args)) { Debug.Assert(args[0].ToLowerInvariant().EndsWith(".bloomcollection")); // Anything else handled above. if (CollectionChoosing.OpenCreateCloneControl.ReportIfInvalidCollectionToEdit(args[0])) return 1; Settings.Default.MruProjects.AddNewPath(args[0]); } if (args.Length > 0 && args[0] == "--rename") { try { var pathToNewCollection = CollectionSettings.RenameCollection(args[1], args[2]); //MessageBox.Show("Your collection has been renamed."); Settings.Default.MruProjects.AddNewPath(pathToNewCollection); } catch (ApplicationException error) { SIL.Reporting.ErrorReport.NotifyUserOfProblem(error, error.Message); Environment.Exit(-1); } catch (Exception error) { SIL.Reporting.ErrorReport.NotifyUserOfProblem(error, "Bloom could not finish renaming your collection folder. Restart your computer and try again."); Environment.Exit(-1); } } Browser.SetUpXulRunner(); Browser.XulRunnerShutdown += OnXulRunnerShutdown; #if DEBUG StartDebugServer(); #endif if (!BloomIntegrityDialog.CheckIntegrity()) { Environment.Exit(-1); } LocalizationManager.SetUILanguage(Settings.Default.UserInterfaceLanguage, false); // BL-1258: sometimes the newly installed fonts are not available until after Bloom restarts // We don't even want to try to install fonts if we are installed by an admin for all users; // it will have been installed already as part of the allUsers install. if ((!InstallerSupport.SharedByAllUsers()) && FontInstaller.InstallFont("AndikaNewBasic")) return 1; Run(); } } } finally { // Check memory one final time for the benefit of developers. The user won't see anything. SIL.Windows.Forms.Reporting.MemoryManagement.CheckMemory(true, "Bloom finished and exiting", false); UniqueToken.ReleaseToken(); } return 0; }
/// <summary> /// This routine handles the old-style download requests which come as an order URL from BloomLibrary. /// Enhance: it's unfortunate that we have two command-line methods of downloading a book. However, they have /// rather different requirements: /// - this one displays a progress UI, the other doesn't. /// - this one must extract the URL from a bloom: url (which the library must produce with urlencoding), /// for the other, it's more convenient to pass an unencoded url /// - worse, this version typically goes on to fully launch Bloom; the other always shuts the program down /// when done. Thus, this version is much more tightly connected to the normal startup code. /// Note that we can't easily change the exact command line that this version deals with, because /// Bloom library generates that command line, and if we change what it generates, everyone running an /// older Bloom will be in trouble. /// Most of the core implementation of the download process is common. /// </summary> private static void HandleDownload(string order) { // We will start up just enough to download the book. This avoids the code that normally tries to keep only a single instance running. // There is probably a pathological case here where we are overwriting an existing template just as the main instance is trying to // do something with it. The time interval would be very short, because download uses a temp folder until it has the whole thing // and then copies (or more commonly moves) it over in one step, and making a book from a template involves a similarly short // step of copying the template to the new book. Hopefully users have (or will soon learn) enough sense not to // try to use a template while in the middle of downloading a new version. SetUpErrorHandling(); using(_applicationContainer = new ApplicationContainer()) { SetUpLocalization(); //JT please review: is this needed? InstallerSupport.MakeBloomRegistryEntries(args); BookDownloadSupport.EnsureDownloadFolderExists(); Browser.SetUpXulRunner(); Browser.XulRunnerShutdown += OnXulRunnerShutdown; LocalizationManager.SetUILanguage(Settings.Default.UserInterfaceLanguage, false); var transfer = new BookTransfer(new BloomParseClient(), ProjectContext.CreateBloomS3Client(), _applicationContainer.BookThumbNailer, new BookDownloadStartingEvent()) /*not hooked to anything*/; transfer.HandleBloomBookOrder(order); PathToBookDownloadedAtStartup = transfer.LastBookDownloadedPath; // BL-2143: Don't show download complete message if download was not successful if (!string.IsNullOrEmpty(PathToBookDownloadedAtStartup)) { var caption = LocalizationManager.GetString("Download.CompletedCaption", "Download complete"); var message = LocalizationManager.GetString("Download.Completed", @"Your download ({0}) is complete. You can see it in the 'Books from BloomLibrary.org' section of your Collections."); message = string.Format(message, Path.GetFileName(PathToBookDownloadedAtStartup)); MessageBox.Show(message, caption); } } }
private bool _publishWithoutAudio = false; // True if the user has said to go ahead without audio #endregion Fields #region Constructors //autofac uses this public PublishView(PublishModel model, SelectedTabChangedEvent selectedTabChangedEvent, LocalizationChangedEvent localizationChangedEvent, BookTransfer bookTransferrer, LoginDialog login, NavigationIsolator isolator) { _bookTransferrer = bookTransferrer; _loginDialog = login; _isolator = isolator; InitializeComponent(); if (this.DesignMode) return; _model = model; _model.View = this; _makePdfBackgroundWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(_makePdfBackgroundWorker_RunWorkerCompleted); _pdfViewer.PrintProgress += new System.EventHandler<PdfPrintProgressEventArgs>(OnPrintProgress); // BL-625: With mono, if a RadioButton group has its AutoCheck properties set to true, the default RadioButton.OnEnter // event checks to make sure one of the RadioButtons is checked. If none are checked, the one the mouse pointer // is over is checked, causing the CheckChanged event to fire. if (SIL.PlatformUtilities.Platform.IsMono) SetAutoCheck(false); //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 if (SIL.PlatformUtilities.Platform.IsMono) { BackgroundColorsForLinux(); } // Adding this renderer prevents a white line from showing up under the components. _menusToolStrip.Renderer = new EditingView.FixedToolStripRenderer(); GeckoPreferences.Default["pdfjs.disabled"] = false; SetupLocalization(); localizationChangedEvent.Subscribe(o => { SetupLocalization(); UpdateLayoutChoiceLabels(); UpdateSaveButton(); }); // Make this extra box available to show when wanted. _previewBox = new PictureBox(); _previewBox.Visible = false; Controls.Add(_previewBox); _previewBox.BringToFront(); }
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.SetMetadata(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", "Additional Requests: ") + 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; var allLanguages = book.AllLanguages; foreach (var lang in allLanguages.Keys) { var checkBox = new CheckBox(); checkBox.Text = _book.PrettyPrintLanguage(lang); if (allLanguages[lang]) checkBox.Checked = true; else { checkBox.Text += @" " + LocalizationManager.GetString("PublishTab.Upload.Partial", "(partial)"); } checkBox.Size = new Size(TextRenderer.MeasureText(checkBox.Text, checkBox.Font).Width + 50, checkBox.Height); checkBox.Tag = lang; checkBox.CheckStateChanged += delegate(object sender, EventArgs args) { bool someLangChecked = _languagesFlow.Controls.Cast<CheckBox>().Any(b => b.Checked); _langsLabel.ForeColor = someLangChecked ? Color.Black : Color.Red; if (_okToUploadDependsOnLangsChecked) { _okToUpload = someLangChecked; UpdateDisplay(); } }; _languagesFlow.Controls.Add(checkBox); } _creditsLabel.Text = book.BookInfo.Credits; _summaryBox.Text = book.BookInfo.Summary; try { _loginDialog.LogIn(); // See if saved credentials work. } catch (Exception e) { SIL.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); 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; } // After considering all the factors except whether any languages are selected, // if we can upload at this point, whether we can from here on depends on whether one is checked. // This test needs to come after evaluating everything else uploading depends on (except login) _okToUploadDependsOnLangsChecked = _okToUpload; if (!allLanguages.Keys.Any()) { _langsLabel.Text += " " + LocalizationManager.GetString("PublishTab.Upload.NoLangsFound", "(None found)"); _langsLabel.ForeColor = Color.Red; _okToUpload = false; } }