string resource_img (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; Database_ImageResources database_imageresources; string page; Assets_Header header = Assets_Header (translate("Image resources"), request); page = header.run (); Assets_View view; string error, success; int book1, chapter1, verse1, book2, chapter2, verse2; string name = request->query ["name"]; view.set_variable ("name", name); string image = request->query ["image"]; view.set_variable ("image", image); int userid = filter_string_user_identifier (webserver_request); if (request->post.count ("submit")) { vector <string> errors; string book = request->post ["book1"]; book1 = filter_passage_interpret_book (book); if (book1 == 0) errors.push_back (translate ("Unknown starting book.")); chapter1 = convert_to_int (request->post ["chapter1"]); if (chapter1 < 0) errors.push_back (translate ("Negative starting chapter.")); if (chapter1 > 200) errors.push_back (translate ("High starting chapter.")); verse1 = convert_to_int (request->post ["verse1"]); if (chapter1 < 0) errors.push_back (translate ("Negative starting verse.")); if (chapter1 > 200) errors.push_back (translate ("High starting verse.")); book = request->post ["book2"]; book2 = filter_passage_interpret_book (book); if (book2 == 0) errors.push_back (translate ("Unknown ending book.")); chapter2 = convert_to_int (request->post ["chapter2"]); if (chapter2 < 0) errors.push_back (translate ("Negative ending chapter.")); if (chapter2 > 200) errors.push_back (translate ("High ending chapter.")); verse2 = convert_to_int (request->post ["verse2"]); if (chapter2 < 0) errors.push_back (translate ("Negative ending verse.")); if (chapter2 > 200) errors.push_back (translate ("High ending verse.")); int start = filter_passage_to_integer (Passage ("", book1, chapter1, convert_to_string (verse1))); int end = filter_passage_to_integer (Passage ("", book2, chapter2, convert_to_string (verse2))); if (start > end) { errors.push_back (translate ("The starting passage is beyond the ending passage.")); } database_imageresources.assign (name, image, book1, chapter1, verse1, book2, chapter2, verse2); Database_Volatile::setValue (userid, "imageresources", convert_to_string (end)); error = filter_string_implode (errors, " "); if (errors.empty ()) { redirect_browser (request, filter_url_build_http_query (resource_image_url (), "name", name)); return ""; } } // Retrieve passage range for this image. database_imageresources.get (name, image, book1, chapter1, verse1, book2, chapter2, verse2); if ((book1 == 0) || (book2 == 0)) { string end = Database_Volatile::getValue (userid, "imageresources"); Passage passage = filter_integer_to_passage (convert_to_int (end)); book1 = book2 = passage.book; chapter1 = chapter2 = passage.chapter; verse1 = verse2 = convert_to_int (passage.verse); if (book1 == 0) book1 = 1; if (book2 == 0) book2 = 1; } view.set_variable ("book1", Database_Books::getEnglishFromId (book1)); view.set_variable ("chapter1", convert_to_string (chapter1)); view.set_variable ("verse1", convert_to_string (verse1)); view.set_variable ("book2", Database_Books::getEnglishFromId (book2)); view.set_variable ("chapter2", convert_to_string (chapter2)); view.set_variable ("verse2", convert_to_string (verse2)); view.set_variable ("success", success); view.set_variable ("error", error); page += view.render ("resource", "img"); page += Assets_Page::footer (); return page; }
string search_similar (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; Database_Volatile database_volatile = Database_Volatile (); int myIdentifier = filter_string_user_identifier (request); string bible = request->database_config_user()->getBible (); if (request->query.count ("b")) { bible = request->query ["b"]; } if (request->query.count ("load")) { int book = Ipc_Focus::getBook (request); int chapter = Ipc_Focus::getChapter (request); int verse = Ipc_Focus::getVerse (request); // Text of the focused verse in the active Bible. // Remove all punctuation from it. string versetext = search_logic_get_bible_verse_text (bible, book, chapter, verse); vector <string> punctuation = filter_string_explode (Database_Config_Bible::getSentenceStructureEndPunctuation (bible), ' '); for (auto & sign : punctuation) { versetext = filter_string_str_replace (sign, "", versetext); } punctuation = filter_string_explode (Database_Config_Bible::getSentenceStructureMiddlePunctuation (bible), ' '); for (auto & sign : punctuation) { versetext = filter_string_str_replace (sign, "", versetext); } versetext = filter_string_trim (versetext); database_volatile.setValue (myIdentifier, "searchsimilar", versetext); return versetext; } if (request->query.count ("words")) { string words = request->query ["words"]; words = filter_string_trim (words); database_volatile.setValue (myIdentifier, "searchsimilar", words); vector <string> vwords = filter_string_explode (words, ' '); // Include items if there are no more search hits than 30% of the total number of verses in the Bible. size_t maxcount = round (0.3 * search_logic_get_verse_count (bible)); // Store how often a verse occurs in an array. // The keys are the identifiers of the search results. // The values are how often the identifiers occur in the entire focused verse. map <int, int> identifiers; for (auto & word : vwords) { // Find out how often this word occurs in the Bible. Skip if too often. vector <Passage> passages = search_logic_search_bible_text (bible, word); if (passages.size () > maxcount) continue; // Store the identifiers and their count. for (auto & passage : passages) { int id = filter_passage_to_integer (passage); if (identifiers.count (id)) identifiers [id]++; else identifiers [id] = 1; } } // Sort on occurrence from high to low. // Skip identifiers that only occur once. vector <int> ids; vector <int> counts; for (auto & element : identifiers) { int id = element.first; int count = element.second; if (count <= 1) continue; ids.push_back (id); counts.push_back (count); } quick_sort (counts, ids, 0, counts.size()); reverse (ids.begin(), ids.end()); // Output the passage identifiers to the browser. string output; for (auto & id : ids) { if (!output.empty ()) output.append ("\n"); output.append (convert_to_string (id)); } return output; } if (request->query.count ("id")) { int id = convert_to_int (request->query ["id"]); // Get the Bible and passage for this identifier. Passage passage = filter_integer_to_passage (id); string bible = request->database_config_user()->getBible (); // string bible = passage.bible; int book = passage.book; int chapter = passage.chapter; string verse = passage.verse; // Get the plain text. string text = search_logic_get_bible_verse_text (bible, book, chapter, convert_to_int (verse)); // Get search words. vector <string> words = filter_string_explode (database_volatile.getValue (myIdentifier, "searchsimilar"), ' '); // Format it. string link = filter_passage_link_for_opening_editor_at (book, chapter, verse); text = filter_string_markup_words (words, text); string output = "<div>" + link + " " + text + "</div>"; // Output to browser. return output; } string page; Assets_Header header = Assets_Header (translate("Search"), request); header.setNavigator (); header.addBreadCrumb (menu_logic_search_menu (), menu_logic_search_text ()); page = header.run (); Assets_View view; view.set_variable ("bible", bible); string script = "var searchBible = \"" + bible + "\";"; view.set_variable ("script", script); page += view.render ("search", "similar"); page += Assets_Page::footer (); return page; }