/// <summary> /// Get a json of the book's settings. /// </summary> private void HandleBookSettings(ApiRequest request) { switch (request.HttpMethod) { case HttpMethods.Get: dynamic settings = new ExpandoObject(); settings.isRecordedAsLockedDown = _bookSelection.CurrentSelection.RecordedAsLockedDown; settings.unlockShellBook = _bookSelection.CurrentSelection.TemporarilyUnlocked; settings.currentToolBoxTool = _bookSelection.CurrentSelection.BookInfo.CurrentTool; request.ReplyWithJson((object)settings); break; case HttpMethods.Post: //note: since we only have this one value, it's not clear yet whether the panel involved here will be more of a //an "edit settings", or a "book settings", or a combination of them. settings = DynamicJson.Parse(request.RequiredPostJson()); _bookSelection.CurrentSelection.TemporarilyUnlocked = settings["unlockShellBook"]; _pageRefreshEvent.Raise(PageRefreshEvent.SaveBehavior.SaveBeforeRefresh); request.Succeeded(); break; default: throw new ArgumentOutOfRangeException(); } }
/// <summary> /// Get a json of the book's settings. /// </summary> private void HandleBookSettings(ApiRequest request) { switch (request.HttpMethod) { case HttpMethods.Get: dynamic settings = new ExpandoObject(); settings.isRecordedAsLockedDown = _bookSelection.CurrentSelection.RecordedAsLockedDown; settings.unlockShellBook = _bookSelection.CurrentSelection.TemporarilyUnlocked; settings.currentToolBoxTool = _bookSelection.CurrentSelection.BookInfo.CurrentTool; settings.isTemplateBook = GetIsBookATemplate(); request.ReplyWithJson((object)settings); break; case HttpMethods.Post: //note: since we only have this one value, it's not clear yet whether the panel involved here will be more of a //an "edit settings", or a "book settings", or a combination of them. settings = DynamicJson.Parse(request.RequiredPostJson()); _bookSelection.CurrentSelection.TemporarilyUnlocked = settings["unlockShellBook"]; _pageRefreshEvent.Raise(PageRefreshEvent.SaveBehavior.SaveBeforeRefresh); if(((DynamicJson)settings).IsDefined("isTemplateBook")) { UpdateBookTemplateMode(settings.isTemplateBook); } request.Succeeded(); break; default: throw new ArgumentOutOfRangeException(); } }
private void HandleAddPage(ApiRequest request) { var page = GetPageTemplate(request); if (page != null) { _templateInsertionCommand.Insert(page as Page); request.Succeeded(); return; } }
/// <summary> /// Get a json of the book's settings. /// </summary> private void HandleBookSettings(ApiRequest request) { switch (request.HttpMethod) { case HttpMethods.Get: dynamic settings = new ExpandoObject(); settings.isRecordedAsLockedDown = _bookSelection.CurrentSelection.RecordedAsLockedDown; settings.unlockShellBook = _bookSelection.CurrentSelection.TemporarilyUnlocked; settings.currentToolBoxTool = _bookSelection.CurrentSelection.BookInfo.CurrentTool; #if UserControlledTemplate settings.isTemplateBook = GetIsBookATemplate(); #endif request.ReplyWithJson((object)settings); break; case HttpMethods.Post: //note: since we only have this one value, it's not clear yet whether the panel involved here will be more of a //an "edit settings", or a "book settings", or a combination of them. settings = DynamicJson.Parse(request.RequiredPostJson()); _bookSelection.CurrentSelection.TemporarilyUnlocked = settings["unlockShellBook"]; // This first refresh saves any changes. _pageRefreshEvent.Raise(PageRefreshEvent.SaveBehavior.SaveBeforeRefresh); #if UserControlledTemplate UpdateBookTemplateMode(settings.isTemplateBook); // Now we need to update the active version of the page with possible new template settings // It's a bit wasteful to raise this twice...but we need to save any changes the user made to the page, // and we have no access to put the editable DOM into the right template/non-template state. _pageRefreshEvent.Raise(PageRefreshEvent.SaveBehavior.JustRedisplay); #endif request.Succeeded(); break; default: throw new ArgumentOutOfRangeException(); } }
public void HandleRequest(ApiRequest request) { if (CurrentBook == null) { Debug.Fail("BL-836 reproduction?"); // ReSharper disable once HeuristicUnreachableCode request.Failed("CurrentBook is null"); return; } if (request.CurrentCollectionSettings == null) { Debug.Fail("BL-836 reproduction?"); // ReSharper disable once HeuristicUnreachableCode request.Failed("CurrentBook.CollectionSettings is null"); return; } var lastSegment = request.LocalPath().Split(new char[] { '/' }).Last(); switch (lastSegment) { case "test": request.Succeeded(); break; case "readerToolSettings": if (request.HttpMethod == HttpMethods.Get) { request.ReplyWithJson(GetReaderSettings(request.CurrentCollectionSettings)); } else { var path = DecodableReaderTool.GetReaderToolsSettingsFilePath(request.CurrentCollectionSettings); var content = request.RequiredPostJson(); RobustFile.WriteAllText(path, content, Encoding.UTF8); request.Succeeded(); } break; //note, this endpoint is confusing because it appears that ultimately we only use the word list out of this file (see "sampleTextsList"). //This ends up being written to a ReaderToolsWords-xyz.json (matching its use, if not it contents). case "synphonyLanguageData": //This is the "post". There is no direct "get", but the name of the file is given in the "sampleTextList" reply, below: SaveSynphonyLanguageData(request.RequiredPostJson()); request.Succeeded(); break; case "sampleTextsList": //note, as part of this reply, we send the path of the "ReaderToolsWords-xyz.json" which is *written* by the "synphonyLanguageData" endpoint above request.ReplyWithText(GetSampleTextsList(request.CurrentCollectionSettings.SettingsFilePath)); break; case "sampleFileContents": request.ReplyWithText(GetTextFileContents(request.RequiredParam("fileName"), WordFileType.SampleFile)); break; case "textOfContentPages": request.ReplyWithText(GetTextOfContentPagesAsJson()); break; case "makeLetterAndWordList": MakeLetterAndWordList(request.RequiredPostValue("settings"), request.RequiredPostValue("allWords")); request.Succeeded(); break; case "openTextsFolder": OpenTextsFolder(); request.Succeeded(); break; case "chooseAllowedWordsListFile": lock (request) { request.ReplyWithText(ShowSelectAllowedWordsFileDialog()); } break; case "allowedWordsList": switch (request.HttpMethod) { case HttpMethods.Delete: RecycleAllowedWordListFile(request.RequiredParam("fileName")); request.Succeeded(); break; case HttpMethods.Get: var fileName = request.RequiredParam("fileName"); request.ReplyWithText(RemoveEmptyAndDupes(GetTextFileContents(fileName, WordFileType.AllowedWordsFile))); break; default: request.Failed("Http verb not handled"); break; } break; default: request.Failed("Don't understand '" + lastSegment + "' in " + request.LocalPath()); break; } }
private void HandleEndRecord(ApiRequest request) { #if __MonoCS__ #else if (Recorder.RecordingState != RecordingState.Recording) { //usually, this is a result of us getting the "end" before we actually started, because it was too quick if(TestForTooShortAndSendFailIfSo(request)) { _startRecordingTimer.Enabled = false;//we don't want it firing in a few milliseconds from now return; } //but this would handle it if there was some other reason request.Failed("Got endRecording, but was not recording"); return; } try { Debug.WriteLine("Stop recording"); Recorder.Stopped += Recorder_Stopped; //note, this doesn't actually stop... more like... starts the stopping. It does mark the time //we requested to stop. A few seconds later (2, looking at the library code today), it will //actually close the file and raise the Stopped event Recorder.Stop(); request.Succeeded(); //ReportSuccessfulRecordingAnalytics(); } catch (Exception) { //swallow it. One reason (based on HearThis comment) is that they didn't hold it down long enough, we detect this below. } TestForTooShortAndSendFailIfSo(request); #endif }
// Does this page have any audio at all? Used to enable 'Listen to the whole page'. private void HandleEnableListenButton(ApiRequest request) { var ids = request.RequiredParam("ids"); foreach (var id in ids.Split(',')) { if (RobustFile.Exists(GetPathToSegment(id))) { request.Succeeded(); return; } } request.Failed("no audio"); }
/// <summary> /// Delete a file (typically a recording, as requested by the Clear button in the talking book tool) /// </summary> /// <param name="fileUrl"></param> private void HandleDeleteSegment(ApiRequest request) { var path = GetPathToSegment(request.RequiredParam("id")); if(!RobustFile.Exists(path)) { request.Succeeded(); } else { try { RobustFile.Delete(path); request.Succeeded(); } catch(IOException e) { var msg = string.Format( LocalizationManager.GetString("Errors.ProblemDeletingFile", "Bloom had a problem deleting this file: {0}"), path); ErrorReport.NotifyUserOfProblem(e, msg + Environment.NewLine + e.Message); } } }
public void HandleCurrentRecordingDevice(ApiRequest request) { #if __MonoCS__ #else if(request.HttpMethod == HttpMethods.Post) { var name = request.RequiredPostString(); foreach (var dev in RecordingDevice.Devices) { if(dev.ProductName == name) { RecordingDevice = dev; request.Succeeded(); return; } } request.Failed("Could not find the device named " + name); } else request.Failed("Only Post is currently supported"); #endif }
private void HandleChangeLayout(ApiRequest request) { var templatePage = GetPageTemplate(request); if (templatePage != null) { var pageToChange = /*PageChangingLayout ??*/ _pageSelection.CurrentSelection; var book = _pageSelection.CurrentSelection.Book; book.UpdatePageToTemplate(book.OurHtmlDom, templatePage.GetDivNodeForThisPage(), pageToChange.Id); // The Page objects are cached in the page list and may be used if we issue another // change layout command. We must update their lineage so the right "current layout" // will be shown if the user changes the layout of the same page again. var pageChanged = pageToChange as Page; if (pageChanged != null) pageChanged.UpdateLineage(new[] { templatePage.Id }); _pageRefreshEvent.Raise(PageRefreshEvent.SaveBehavior.JustRedisplay); request.Succeeded(); } }