Currently pushes a book's metadata to Parse.com (a mongodb service) and files to Amazon S3. We are using both because Parse offers a more structured, query-able data organization that is useful for metadata, but does not allow large enough files for some of what we need.
Ejemplo n.º 1
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;
     }
 }
Ejemplo n.º 2
0
 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));
 }
Ejemplo n.º 3
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);
 }
Ejemplo n.º 4
0
        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;
        }
Ejemplo n.º 5
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);
         }
     }
 }
Ejemplo n.º 6
0
        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;
            }
        }