string editone_preview (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; bool touch = request->session_logic ()->touchEnabled (); string page; Assets_Header header = Assets_Header (translate("Preview"), request); header.setNavigator (); header.setEditorStylesheet (); if (touch) header.jQueryTouchOn (); header.addBreadCrumb (menu_logic_translate_menu (), menu_logic_translate_text ()); header.refresh (5, "index"); page = header.run (); Assets_View view; // Get active Bible, and check read access to it. // If needed, change Bible to one it has read access to. string bible = access_bible_clamp (request, request->database_config_user()->getBible ()); string cls = Filter_Css::getClass (bible); string font = Fonts_Logic::getTextFont (bible); int direction = Database_Config_Bible::getTextDirection (bible); int lineheight = Database_Config_Bible::getLineHeight (bible); int letterspacing = Database_Config_Bible::getLetterSpacing (bible); view.set_variable ("custom_class", cls); view.set_variable ("custom_css", Filter_Css::getCss (cls, Fonts_Logic::getFontPath (font), direction, lineheight, letterspacing)); int book = Ipc_Focus::getBook (webserver_request); int chapter = Ipc_Focus::getChapter (webserver_request); //int verse = Ipc_Focus::getVerse (webserver_request); string stylesheet = request->database_config_user()->getStylesheet (); string usfm = request->database_bibles()->getChapter (bible, book, chapter); Editor_Usfm2Html editor_usfm2html; editor_usfm2html.load (usfm); editor_usfm2html.stylesheet (stylesheet); editor_usfm2html.run (); string html = editor_usfm2html.get (); view.set_variable ("html", html); page += view.render ("editone", "preview"); page += Assets_Page::footer (); return page; }
string basic_index (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; Assets_Header header = Assets_Header ("Settings", webserver_request); string page = header.run (); Assets_View view; if (request->query.count ("changebible")) { string changebible = request->query ["changebible"]; if (changebible == "") { Dialog_List dialog_list = Dialog_List ("index", translate("Select which Bible to make the active one for editing"), "", ""); vector <string> bibles = access_bible_bibles (request); for (auto & bible : bibles) { dialog_list.add_row (bible, "changebible", bible); } page += dialog_list.run(); return page; } else { request->database_config_user()->setBible (changebible); // Going to another Bible, ensure that the focused book exists there. int book = Ipc_Focus::getBook (request); vector <int> books = request->database_bibles()->getBooks (changebible); if (find (books.begin(), books.end(), book) == books.end()) { if (!books.empty ()) book = books [0]; else book = 0; Ipc_Focus::set (request, book, 1, 1); } } } string bible = access_bible_clamp (request, request->database_config_user()->getBible ()); view.set_variable ("bible", bible); #ifdef CLIENT_PREPARED view.enable_zone ("client"); if (client_logic_client_enabled ()) { view.enable_zone ("connected"); } #else view.enable_zone ("cloud"); #endif page += view.render ("basic", "index"); page += Assets_Page::footer (); return page; }
string bible_abbreviations (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; string page; Assets_Header header = Assets_Header (translate("Abbreviations"), webserver_request); header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ()); header.addBreadCrumb (bible_manage_url (), menu_logic_bible_manage_text ()); page = header.run (); Assets_View view; string success_message; string error_message; // The name of the Bible. string bible = access_bible_clamp (request, request->query ["bible"]); view.set_variable ("bible", filter_string_sanitize_html (bible)); // Data submission. if (request->post.count ("submit")) { string data = request->post ["data"]; data = filter_string_trim (data); if (data != "") { if (unicode_string_is_valid (data)) { Database_Config_Bible::setBookAbbreviations (bible, data); success_message = translate("The abbreviations were saved."); } else { error_message = translate("Please supply valid Unicode UTF-8 text."); } } else { success_message = translate("Nothing was saved."); } } string data = Database_Config_Bible::getBookAbbreviations (bible); data = filter_abbreviations_display (data); view.set_variable ("data", data); view.set_variable ("success_message", success_message); view.set_variable ("error_message", error_message); page += view.render ("bible", "abbreviations"); page += Assets_Page::footer (); return page; }
string checks_settings (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; string page; Assets_Header header = Assets_Header (translate("Manage Checks"), webserver_request); header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ()); page = header.run (); Assets_View view; if (request->query.count ("bible")) { string bible = request->query["bible"]; if (bible == "") { Dialog_List dialog_list = Dialog_List ("settings", translate("Select which Bible to manage"), "", ""); vector <string> bibles = access_bible_bibles (webserver_request); for (auto bible : bibles) { dialog_list.add_row (bible, "bible", bible); } page += dialog_list.run(); return page; } else { request->database_config_user()->setBible (bible); } } string bible = access_bible_clamp (webserver_request, request->database_config_user()->getBible ()); if (request->query.count ("run")) { checks_logic_start (bible); view.set_variable ("success", translate("Will run the checks. See the Journal for progress.")); } string checkbox = request->post ["checkbox"]; bool checked = convert_to_bool (request->post ["checked"]); if (checkbox == "doublespacesusfm") { Database_Config_Bible::setCheckDoubleSpacesUsfm (bible, checked); } view.set_variable ("doublespacesusfm", get_checkbox_status (Database_Config_Bible::getCheckDoubleSpacesUsfm (bible))); if (checkbox == "fullstopheadings") { Database_Config_Bible::setCheckFullStopInHeadings (bible, checked); } view.set_variable ("fullstopheadings", get_checkbox_status (Database_Config_Bible::getCheckFullStopInHeadings (bible))); if (checkbox == "spacebeforepunctuation") { Database_Config_Bible::setCheckSpaceBeforePunctuation (bible, checked); } view.set_variable ("spacebeforepunctuation", get_checkbox_status (Database_Config_Bible::getCheckSpaceBeforePunctuation (bible))); if (checkbox == "sentencestructure") { Database_Config_Bible::setCheckSentenceStructure (bible, checked); } view.set_variable ("sentencestructure", get_checkbox_status (Database_Config_Bible::getCheckSentenceStructure (bible))); if (checkbox == "paragraphstructure") { Database_Config_Bible::setCheckParagraphStructure (bible, checked); } view.set_variable ("paragraphstructure", get_checkbox_status (Database_Config_Bible::getCheckParagraphStructure (bible))); if (checkbox == "booksversification") { Database_Config_Bible::setCheckBooksVersification (bible, checked); } view.set_variable ("booksversification", get_checkbox_status (Database_Config_Bible::getCheckBooksVersification (bible))); if (checkbox == "chaptersversesversification") { Database_Config_Bible::setCheckChaptesVersesVersification (bible, checked); } view.set_variable ("chaptersversesversification", get_checkbox_status (Database_Config_Bible::getCheckChaptesVersesVersification (bible))); if (checkbox == "wellformedusfm") { Database_Config_Bible::setCheckWellFormedUsfm (bible, checked); } view.set_variable ("wellformedusfm", get_checkbox_status (Database_Config_Bible::getCheckWellFormedUsfm (bible))); if (checkbox == "punctuationatendverse") { Database_Config_Bible::setCheckMissingPunctuationEndVerse (bible, checked); } view.set_variable ("punctuationatendverse", get_checkbox_status (Database_Config_Bible::getCheckMissingPunctuationEndVerse (bible))); if (checkbox == "patterns") { Database_Config_Bible::setCheckPatterns (bible, checked); } view.set_variable ("patterns", get_checkbox_status (Database_Config_Bible::getCheckPatterns (bible))); if (checkbox == "pairs") { Database_Config_Bible::setCheckMatchingPairs (bible, checked); } view.set_variable ("pairs", get_checkbox_status (Database_Config_Bible::getCheckMatchingPairs (bible))); view.set_variable ("bible", bible); #ifdef HAVE_CLIENT view.enable_zone ("client"); #else view.enable_zone ("cloud"); #endif page += view.render ("checks", "settings"); page += Assets_Page::footer (); return page; }
string editverse_index (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; bool touch = request->session_logic ()->touchEnabled (); if (request->query.count ("switchbook") && request->query.count ("switchchapter")) { int switchbook = convert_to_int (request->query ["switchbook"]); int switchchapter = convert_to_int (request->query ["switchchapter"]); Ipc_Focus::set (request, switchbook, switchchapter, 1); Navigation_Passage::recordHistory (request, switchbook, switchchapter, 1); } string page; Assets_Header header = Assets_Header (translate("Edit USFM"), request); header.setNavigator (); if (touch) header.jQueryTouchOn (); header.notifItOn (); header.addBreadCrumb (menu_logic_translate_menu (), menu_logic_translate_text ()); page = header.run (); Assets_View view; if (request->query.count ("changebible")) { string changebible = request->query ["changebible"]; if (changebible == "") { Dialog_List dialog_list = Dialog_List ("index", translate("Select which Bible to open in the editor"), "", ""); vector <string> bibles = access_bible_bibles (request); for (auto bible : bibles) { dialog_list.add_row (bible, "changebible", bible); } page += dialog_list.run(); return page; } else { request->database_config_user()->setBible (changebible); } } // Get active Bible, and check read access to it. // If needed, change Bible to one it has read access to. string bible = access_bible_clamp (request, request->database_config_user()->getBible ()); if (request->query.count ("bible")) bible = access_bible_clamp (request, request->query ["bible"]); view.set_variable ("bible", bible); // Store the active Bible in the page's javascript. view.set_variable ("navigationCode", Navigation_Passage::code (bible)); string chapterLoaded = locale_logic_text_loaded (); string chapterSaving = locale_logic_text_saving (); string chapterSaved = locale_logic_text_saved (); string chapterRetrying = locale_logic_text_retrying (); string script = "var verseEditorVerseLoaded = '" + chapterLoaded + "';\n" "var verseEditorVerseSaving = '" + chapterSaving + "';\n" "var verseEditorVerseSaved = '" + chapterSaved + "';\n" "var verseEditorChapterRetrying = '" + chapterRetrying + "';\n" "var verseEditorWriteAccess = true;" "var unsentBibleDataTimeoutWarning = '" + bible_logic_unsent_unreceived_data_warning (false) + "';\n"; config_logic_swipe_enabled (webserver_request, script); view.set_variable ("script", script); string cls = Filter_Css::getClass (bible); string font = Fonts_Logic::getTextFont (bible); int direction = Database_Config_Bible::getTextDirection (bible); int lineheight = Database_Config_Bible::getLineHeight (bible); int letterspacing = Database_Config_Bible::getLetterSpacing (bible); view.set_variable ("custom_class", cls); view.set_variable ("custom_css", Filter_Css::getCss (cls, Fonts_Logic::getFontPath (font), direction, lineheight, letterspacing)); // Whether to enable fast Bible editor switching. if (request->database_config_user ()->getFastEditorSwitchingAvailable ()) { view.enable_zone ("fastswitcheditor"); } page += view.render ("editverse", "index"); page += Assets_Page::footer (); return page; }
string edit_index (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; bool touch = request->session_logic ()->touchEnabled (); if (request->query.count ("switchbook") && request->query.count ("switchchapter")) { int switchbook = convert_to_int (request->query ["switchbook"]); int switchchapter = convert_to_int (request->query ["switchchapter"]); int switchverse = 1; if (request->query.count ("switchverse")) switchverse = convert_to_int (request->query ["switchverse"]); Ipc_Focus::set (request, switchbook, switchchapter, switchverse); Navigation_Passage::recordHistory (request, switchbook, switchchapter, switchverse); } string page; Assets_Header header = Assets_Header (translate("Edit"), request); header.setNavigator (); header.setEditorStylesheet (); if (touch) header.jQueryTouchOn (); header.notifItOn (); header.addBreadCrumb (menu_logic_translate_menu (), menu_logic_translate_text ()); page = header.run (); if (request->query.count ("changebible")) { string changebible = request->query ["changebible"]; if (changebible == "") { Dialog_List dialog_list = Dialog_List ("index", translate("Select which Bible to open in the editor"), "", ""); vector <string> bibles = access_bible_bibles (request); for (auto & bible : bibles) { dialog_list.add_row (bible, "changebible", bible); } page += dialog_list.run(); return page; } else { request->database_config_user()->setBible (changebible); // Going to another Bible, ensure that the focused book exists there. int book = Ipc_Focus::getBook (request); vector <int> books = request->database_bibles()->getBooks (changebible); if (find (books.begin(), books.end(), book) == books.end()) { if (!books.empty ()) book = books [0]; else book = 0; Ipc_Focus::set (request, book, 1, 1); } } } Assets_View view; // Active Bible, and check access. string bible = access_bible_clamp (request, request->database_config_user()->getBible ()); if (request->query.count ("bible")) bible = access_bible_clamp (request, request->query ["bible"]); view.set_variable ("bible", bible); // Store the active Bible in the page's javascript. view.set_variable ("navigationCode", Navigation_Passage::code (bible)); int verticalCaretPosition = request->database_config_user ()->getVerticalCaretPosition (); string script = "var editorChapterLoaded = '" + locale_logic_text_loaded () + "';\n" "var editorChapterSaving = '" + locale_logic_text_saving () + "';\n" "var editorChapterSaved = '" + locale_logic_text_saved () + "';\n" "var editorChapterRetrying = '" + locale_logic_text_retrying () + "';\n" "var editorChapterReformat = '" + locale_logic_text_reformat () + "';\n" "var editorWriteAccess = true;\n" "var verticalCaretPosition = " + convert_to_string (verticalCaretPosition) + ";\n" "var unsentBibleDataTimeoutWarning = '" + bible_logic_unsent_unreceived_data_warning (false) + "';\n"; config_logic_swipe_enabled (webserver_request, script); view.set_variable ("script", script); string clss = Filter_Css::getClass (bible); string font = Fonts_Logic::getTextFont (bible); int direction = Database_Config_Bible::getTextDirection (bible); int lineheight = Database_Config_Bible::getLineHeight (bible); int letterspacing = Database_Config_Bible::getLetterSpacing (bible); view.set_variable ("custom_class", clss); view.set_variable ("custom_css", Filter_Css::getCss (clss, Fonts_Logic::getFontPath (font), direction, lineheight, letterspacing)); // In basic mode the editor has no controls and fewer indicators. // In basic mode, the user can just edit text, and cannot style it. bool basic_mode = config_logic_basic_mode (webserver_request); if (!basic_mode) view.enable_zone ("advancedmode"); // Whether to enable fast Bible editor switching. if (!basic_mode && request->database_config_user ()->getFastEditorSwitchingAvailable ()) { view.enable_zone ("fastswitcheditor"); } // Whether to enable the styles button. if (request->database_config_user ()->getEnableStylesButtonVisualEditors ()) { view.enable_zone ("stylesbutton"); } page += view.render ("edit", "index"); page += Assets_Page::footer (); return page; }
string notes_notes (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; Database_Notes database_notes (webserver_request); string bible = access_bible_clamp (webserver_request, request->database_config_user()->getBible()); int book = Ipc_Focus::getBook (webserver_request); int chapter = Ipc_Focus::getChapter (webserver_request); int verse = Ipc_Focus::getVerse (webserver_request); int passage_selector = request->database_config_user()->getConsultationNotesPassageSelector(); int edit_selector = request->database_config_user()->getConsultationNotesEditSelector(); int non_edit_selector = request->database_config_user()->getConsultationNotesNonEditSelector(); string status_selector = request->database_config_user()->getConsultationNotesStatusSelector(); string bible_selector = request->database_config_user()->getConsultationNotesBibleSelector(); string assignment_selector = request->database_config_user()->getConsultationNotesAssignmentSelector(); bool subscription_selector = request->database_config_user()->getConsultationNotesSubscriptionSelector(); int severity_selector = request->database_config_user()->getConsultationNotesSeveritySelector(); int text_selector = request->database_config_user()->getConsultationNotesTextSelector(); string search_text = request->database_config_user()->getConsultationNotesSearchText(); int passage_inclusion_selector = request->database_config_user()->getConsultationNotesPassageInclusionSelector(); int text_inclusion_selector = request->database_config_user()->getConsultationNotesTextInclusionSelector(); // The Bibles the current user has access to. vector <string> bibles = access_bible_bibles (webserver_request, request->session_logic()->currentUser ()); // The admin disables notes selection on Bibles, // so the admin sees all notes, including notes referring to non-existing Bibles. if (request->session_logic ()->currentLevel () == Filter_Roles::admin ()) bibles.clear (); vector <int> identifiers = database_notes.selectNotes (bibles, book, chapter, verse, passage_selector, edit_selector, non_edit_selector, status_selector, bible_selector, assignment_selector, subscription_selector, severity_selector, text_selector, search_text, -1); // In case there aren't too many notes, there's enough time to sort them in passage order. if (identifiers.size () <= 200) { vector <int> passage_sort_keys; for (auto & identifier : identifiers) { int passage_sort_key = 0; vector <float> numeric_passages; vector <Passage> passages = database_notes.getPassages (identifier); for (auto & passage : passages) { numeric_passages.push_back (filter_passage_to_integer (passage)); } if (!numeric_passages.empty ()) { float average = accumulate (numeric_passages.begin (), numeric_passages.end (), 0) / numeric_passages.size (); passage_sort_key = round (average); } passage_sort_keys.push_back (passage_sort_key); } quick_sort (passage_sort_keys, identifiers, 0, identifiers.size ()); } string notesblock; for (auto & identifier : identifiers) { string summary = database_notes.getSummary (identifier); vector <Passage> passages = database_notes.getPassages (identifier); string verses = filter_passage_display_inline (passages); // A simple way to make it easier to see the individual notes in the list, // when the summaries of some notes are long, is to display the passage first. summary.insert (0, verses + " | "); string verse_text; if (passage_inclusion_selector) { vector <Passage> passages = database_notes.getPassages (identifier); for (auto & passage : passages) { string usfm = request->database_bibles()->getChapter (bible, passage.book, passage.chapter); string text = usfm_get_verse_text (usfm, convert_to_int (passage.verse)); if (!verse_text.empty ()) verse_text.append ("<br>"); verse_text.append (text); } } string content; if (text_inclusion_selector) { content = database_notes.getContents (identifier); } notesblock.append ("<a name=\"note" + convert_to_string (identifier) + "\"></a>\n"); notesblock.append ("<p><a href=\"note?id=" + convert_to_string (identifier) + "\">" + summary + "</a></p>\n"); if (!verse_text.empty ()) notesblock.append ("<p>" + verse_text + "</p>\n"); if (!content.empty ()) notesblock.append ("<p>" + content + "</p>\n"); } if (identifiers.empty ()) { return translate("This selection does not display any notes."); } return notesblock; }
string bible_book (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; string page; Assets_Header header = Assets_Header (translate("Book"), webserver_request); header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ()); header.addBreadCrumb (bible_manage_url (), menu_logic_bible_manage_text ()); page = header.run (); Assets_View view; string success_message; string error_message; // The name of the Bible. string bible = access_bible_clamp (request, request->query["bible"]); view.set_variable ("bible", filter_string_sanitize_html (bible)); // The book. int book = convert_to_int (request->query ["book"]); view.set_variable ("book", convert_to_string (book)); string book_name = Database_Books::getEnglishFromId (book); view.set_variable ("book_name", filter_string_sanitize_html (book_name)); // Whether the user has write access to this Bible book. bool write_access = access_bible_book_write (request, "", bible, book); if (write_access) view.enable_zone ("write_access"); // Delete chapter. string deletechapter = request->query ["deletechapter"]; if (deletechapter != "") { string confirm = request->query ["confirm"]; if (confirm == "") { Dialog_Yes dialog_yes = Dialog_Yes ("book", translate("Would you like to delete this chapter?")); dialog_yes.add_query ("bible", bible); dialog_yes.add_query ("book", convert_to_string (book)); dialog_yes.add_query ("deletechapter", deletechapter); page += dialog_yes.run (); return page; } if (confirm == "yes") { if (write_access) Bible_Logic::deleteChapter (bible, book, convert_to_int (deletechapter)); } } // Add chapter. if (request->query.count ("createchapter")) { Dialog_Entry dialog_entry = Dialog_Entry ("book", translate("Please enter the number for the new chapter"), "", "createchapter", ""); dialog_entry.add_query ("bible", bible); dialog_entry.add_query ("book", convert_to_string (book)); page += dialog_entry.run (); return page; } if (request->post.count ("createchapter")) { int createchapter = convert_to_int (request->post ["entry"]); vector <int> chapters = request->database_bibles ()->getChapters (bible, book); // Only create the chapters if it does not yet exist. if (find (chapters.begin(), chapters.end(), createchapter) == chapters.end()) { vector <string> feedback; bool result = true; if (write_access) result = book_create (bible, book, createchapter, feedback); string message = filter_string_implode (feedback, " "); if (result) success_message = message; else error_message = message; } else { error_message = translate ("This chapter already exists"); } } // Available chapters. vector <int> chapters = request->database_bibles ()->getChapters (bible, book); string chapterblock; for (auto & chapter : chapters) { chapterblock.append ("<a href=\"chapter?bible="); chapterblock.append (bible); chapterblock.append ("&book="); chapterblock.append (convert_to_string (book)); chapterblock.append ("&chapter="); chapterblock.append (convert_to_string (chapter)); chapterblock.append ("\">"); chapterblock.append (convert_to_string (chapter)); chapterblock.append ("</a>\n"); } view.set_variable ("chapterblock", chapterblock); view.set_variable ("success_message", success_message); view.set_variable ("error_message", error_message); if (!client_logic_client_enabled ()) view.enable_zone ("server"); page += view.render ("bible", "book"); page += Assets_Page::footer (); return page; }
string bible_import_usfm (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; string page; page = Assets_Page::header (translate ("Import USFM"), webserver_request, ""); Assets_View view = Assets_View (); string success_message; string error_message; // The name of the Bible. string bible = access_bible_clamp (request, request->query["bible"]); view.set_variable ("bible", filter_string_sanitize_html (bible)); // Whether the user has write access to this Bible. bool write_access = access_bible_write (request, bible); if (write_access) view.enable_zone ("write_access"); // USFM data submission. if (request->post.count ("submit")) { // Submission may take long if there's a lot of data or the network is slow. string data = request->post ["data"]; data = filter_url_tag_to_plus (data); data = filter_string_trim (data); if (data != "") { if (unicode_string_is_valid (data)) { string datafile = filter_url_tempfile (); filter_url_file_put_contents (datafile, data); success_message = translate("Import has started. See Journal for progress."); tasks_logic_queue (IMPORTUSFM, { datafile, bible }); } else { error_message = translate("Please supply valid Unicode UTF-8 text."); } } else { success_message = translate("Nothing was imported."); } } // File upload. if (request->post.count ("upload")) { string datafile = filter_url_tempfile () + request->post ["filename"]; string data = request->post ["data"]; if (!data.empty ()) { filter_url_file_put_contents (datafile, data); success_message = translate("Import has started. See Journal for progress."); tasks_logic_queue (IMPORTUSFM, { datafile, bible }); } else { error_message = translate ("Nothing was uploaded"); } } view.set_variable ("success_message", success_message); view.set_variable ("error_message", error_message); page += view.render ("bible", "import_usfm"); page += Assets_Page::footer (); return page; }
string bible_import (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; string page; Assets_Header header = Assets_Header (translate("Import"), webserver_request); header.setNavigator (); header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ()); header.addBreadCrumb (bible_manage_url (), menu_logic_bible_manage_text ()); page = header.run (); Assets_View view; string success_message; string error_message; // The name of the Bible. string bible = access_bible_clamp (request, request->query["bible"]); view.set_variable ("bible", filter_string_sanitize_html (bible)); int book = Ipc_Focus::getBook (webserver_request); int chapter = Ipc_Focus::getChapter (webserver_request); // Whether the user has write access to this Bible. bool write_access = access_bible_write (request, bible); if (write_access) view.enable_zone ("write_access"); // USFM data submission. if (request->post.count ("submit")) { // Submission may take long if there's a lot of data or the network is slow. string data = request->post ["data"]; data = filter_url_tag_to_plus (data); data = filter_string_trim (data); if (data != "") { if (unicode_string_is_valid (data)) { string datafile = filter_url_tempfile (); filter_url_file_put_contents (datafile, data); success_message = translate("Import has started. See Journal for progress."); tasks_logic_queue (IMPORTBIBLE, { datafile, bible, convert_to_string (book), convert_to_string (chapter) }); } else { error_message = translate("Please supply valid Unicode UTF-8 text."); } } else { success_message = translate("Nothing was imported."); } // User imported something into this Bible: Set it as the default Bible. request->database_config_user()->setBible (bible); } // File upload. if (request->post.count ("upload")) { string datafile = filter_url_tempfile () + request->post ["filename"]; string data = request->post ["data"]; if (!data.empty ()) { filter_url_file_put_contents (datafile, data); success_message = translate("Import has started. See Journal for progress."); tasks_logic_queue (IMPORTBIBLE, { datafile, bible, convert_to_string (book), convert_to_string (chapter) }); } else { error_message = translate ("Nothing was uploaded"); } // User imported something into this Bible: Set it as the default Bible. request->database_config_user()->setBible (bible); } #ifdef HAVE_UPLOAD view.enable_zone ("enable_upload"); #else view.enable_zone ("disable_upload"); #endif view.set_variable ("success_message", success_message); view.set_variable ("error_message", error_message); page += view.render ("bible", "import"); page += Assets_Page::footer (); return page; }
string sprint_index (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; Database_Sprint database_sprint; string page; Assets_Header header = Assets_Header (translate("Sprint"), request); header.addBreadCrumb (menu_logic_tools_menu (), menu_logic_tools_text ()); page = header.run (); Assets_View view; if (request->query.count ("previoussprint")) { int month = request->database_config_user()->getSprintMonth (); int year = request->database_config_user()->getSprintYear (); filter_date_get_previous_month (month, year); request->database_config_user()->setSprintMonth (month); request->database_config_user()->setSprintYear (year); } if (request->query.count ("currentprint")) { request->database_config_user()->setSprintMonth (filter_date_numerical_month (filter_date_seconds_since_epoch ())); request->database_config_user()->setSprintYear (filter_date_numerical_year (filter_date_seconds_since_epoch ())); } if (request->query.count ("nextsprint")) { int month = request->database_config_user()->getSprintMonth (); int year = request->database_config_user()->getSprintYear (); filter_date_get_next_month (month, year); request->database_config_user()->setSprintMonth (month); request->database_config_user()->setSprintYear (year); } string bible = access_bible_clamp (webserver_request, request->database_config_user()->getBible ()); int month = request->database_config_user()->getSprintMonth (); int year = request->database_config_user()->getSprintYear (); if (request->post.count ("id")) { string id = request->post ["id"]; string checked = request->post ["checked"]; if (id.length () >= 9) { // Remove "task". id.erase (0, 4); // Convert the fragment to an integer. int identifier = convert_to_int (id); // Find the fragment "box". size_t pos = id.find ("box"); if (pos != string::npos) { // Remove the fragment "box". id.erase (0, pos + 3); // Convert the box to an integer. int box = convert_to_int (id); string categorytext = Database_Config_Bible::getSprintTaskCompletionCategories (bible); vector <string> categories = filter_string_explode (categorytext, '\n'); int category_count = categories.size (); float category_percentage = 100 / category_count; int percentage; bool on = (checked == "true"); if (on) percentage = round ((box + 1) * category_percentage); else percentage = round (box * category_percentage); database_sprint.updateComplete (identifier, percentage); } } return ""; } if (request->post.count ("add")) { string title = request->post ["add"]; database_sprint.storeTask (bible, year, month, title); view.set_variable ("success", translate("New task added")); // Focus the entry for adding tasks only in case a new task was added. view.set_variable ("autofocus", "autofocus"); } if (request->query.count ("mail")) { string mail = request->query ["mail"]; sprint_burndown (bible, true); view.set_variable ("success", translate("The information was mailed to the subscribers")); } if (request->query.count ("bible")) { bible = request->query ["bible"]; if (bible == "") { Dialog_List dialog_list = Dialog_List ("index", translate("Select which Bible to display the Sprint for"), "", ""); vector <string> bibles = access_bible_bibles (request); for (auto & bible : bibles) { dialog_list.add_row (bible, "bible", bible); } page += dialog_list.run(); return page; } else { request->database_config_user()->setBible (bible); } } bible = access_bible_clamp (webserver_request, request->database_config_user()->getBible ()); int id = convert_to_int (request->query ["id"]); if (request->query.count ("remove")) { database_sprint.deleteTask (id); view.set_variable ("success", translate("The task was removed")); } if (request->query.count ("moveback")) { filter_date_get_previous_month (month, year); database_sprint.updateMonthYear (id, month, year); view.set_variable ("success", translate("The task was moved to the previous sprint")); request->database_config_user()->setSprintMonth (month); request->database_config_user()->setSprintYear (year); } if (request->query.count ("moveforward")) { filter_date_get_next_month (month, year); database_sprint.updateMonthYear (id, month, year); view.set_variable ("success", translate("The task was moved to the next sprint")); request->database_config_user()->setSprintMonth (month); request->database_config_user()->setSprintYear (year); } if (request->post.count ("categories")) { string categories = request->post ["categories"]; vector <string> categories2; categories = filter_string_trim (categories); vector <string> vcategories = filter_string_explode (categories, '\n'); for (auto category : vcategories) { category = filter_string_trim (category); if (category != "") categories2.push_back (category); } categories = filter_string_implode (categories2, "\n"); Database_Config_Bible::setSprintTaskCompletionCategories (bible, categories); } view.set_variable ("bible", bible); view.set_variable ("sprint", locale_logic_month (month) + " " + convert_to_string (year)); string categorytext = Database_Config_Bible::getSprintTaskCompletionCategories (bible); view.set_variable ("categorytext", categorytext); vector <string> vcategories = filter_string_explode (categorytext, '\n'); string categories; for (auto category : vcategories) { categories.append ("<td>" + category + "</td>\n"); } view.set_variable ("categories", categories); string tasks; vector <int> vtasks = database_sprint.getTasks (bible, year, month); for (auto & id : vtasks) { string title = filter_string_sanitize_html (database_sprint.getTitle (id)); int percentage = database_sprint.getComplete (id); tasks.append ("<tr id=\"a" + convert_to_string (id) + "\">\n"); tasks.append ("<td><a href=\"?id=" + convert_to_string (id) + "&remove=\">" + emoji_wastebasket () + "</a></td>\n"); tasks.append ("<td></td>\n"); tasks.append ("<td><a href=\"?id=" + convert_to_string (id) + "&moveback=\"> « </a></td>\n"); tasks.append ("<td>" + title + "</td>\n"); int category_count = vcategories.size(); float category_percentage = 100 / category_count; for (size_t i2 = 0; i2 < vcategories.size (); i2++) { int high = round ((i2 + 1) * category_percentage); tasks.append ("<td>\n"); tasks.append ("<input type=\"checkbox\" id=\"task"); tasks.append (convert_to_string (id)); tasks.append ("box"); tasks.append (convert_to_string (i2)); tasks.append ("\""); if (percentage >= high) tasks.append (" checked"); else tasks.append (""); tasks.append (">"); tasks.append ("</td>\n"); } tasks.append ("<td><a href=\"?id=" + convert_to_string (id) + "&moveforward=\"> » </a></td>\n"); tasks.append ("</tr>\n"); } view.set_variable ("tasks", tasks); view.set_variable ("chart", sprint_create_burndown_chart (bible, year, month)); page += view.render ("sprint", "index"); page += Assets_Page::footer (); return page; }
string Consistency_Logic::response () { // The request. Webserver_Request * request = (Webserver_Request *) webserver_request; // The resources to display in the Consistency tool. vector <string> resources = request->database_config_user()->getConsistencyResources (); string bible = access_bible_clamp (webserver_request, request->database_config_user()->getBible ()); resources.insert (resources.begin (), bible); // The passages entered in the Consistency tool. string s_passages = Database_Volatile::getValue (id, "passages"); s_passages = filter_string_trim (s_passages); vector <string> passages = filter_string_explode (s_passages, '\n'); // The translations entered in the Consistency tool. string s_translations = Database_Volatile::getValue (id, "translations"); s_translations = filter_string_trim (s_translations); vector <string> translations = filter_string_explode (s_translations, '\n'); // Contains the response to display. vector <string> response; // Go through the passages interpreting them. Passage previousPassage = Passage ("", 1, 1, "1"); for (auto line : passages) { // Clean line. line = filter_string_trim (line); // Skip empty line. if (line.empty ()) continue; // Remove verse text remaining with the passage(s) only. line = omit_verse_text (line); vector <string> range_sequence = filter_passage_handle_sequences_ranges (line); for (auto line : range_sequence) { Passage passage = filter_passage_interpret_passage (previousPassage, line); if (passage.book != 0) { int book = passage.book; int chapter = passage.chapter; string verse = passage.verse; line = filter_passage_link_for_opening_editor_at (book, chapter, verse); line += " "; // Check whether the chapter identifier has changed for this reference. // If so, set a flag so the data can be re-assembled for this verse. // If there was no change, then the data can be fetched from the volatile database. bool redoPassage = false; string passageKey = convert_to_string (book) + "." + convert_to_string (chapter) + "." + verse; int currentChapterId = request->database_bibles()->getChapterId (resources [0], book, chapter); int storedChapterId = convert_to_int (Database_Volatile::getValue (id, passageKey + ".id")); if (currentChapterId != storedChapterId) { Database_Volatile::setValue (id, passageKey + ".id", convert_to_string (currentChapterId)); redoPassage = true; } // Go through each resource. for (auto resource : resources) { // Produce new verse text if the passage is to be redone, or else fetch the existing text. string text; if (redoPassage) { text = verseText (resource, book, chapter, convert_to_int (verse)); if (!translations.empty ()) { text = filter_string_markup_words (translations, text); } Database_Volatile::setValue (id, passageKey + "." + resource, text); } else { text = Database_Volatile::getValue (id, passageKey + "." + resource); } // Formatting. if (resources.size () > 1) { line += "<br>"; } line += text; } response.push_back (line); previousPassage = passage; } else { response.push_back ("<span class=\"error\">" + translate("Unknown passage") + " " + line + "</span>"); } } } string output; for (auto line : response) { output += "<div>" + line + "</div>\n"; } return output; }