Exemple #1
0
string search_replacepre2 (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;
  
  
  string siteUrl = Database_Config_General::getSiteURL ();
  
  
  // Get search variables from the query.
  string searchfor = request->query ["q"];
  string replacewith = request->query ["r"];
  bool casesensitive = (request->query ["c"] == "true");
  string id = request->query ["id"];
  bool searchplain = (request->query ["p"] == "true");
  
  
  // Get the Bible and passage for this identifier.
  Passage details = Passage::from_text (id);
  string bible = details.bible;
  int book = details.book;
  int chapter = details.chapter;
  string verse = details.verse;
  
  
  // Get the plain text or the USFM.
  string text;
  if (searchplain) {
    text = search_logic_get_bible_verse_text (bible, book, chapter, convert_to_int (verse));
  } else {
    text = search_logic_get_bible_verse_usfm (bible, book, chapter, convert_to_int (verse));
  }
  
  // Clickable passage.
  string link = filter_passage_link_for_opening_editor_at (book, chapter, verse);
  
  
  string oldtext = filter_string_markup_words ({searchfor}, text);
  

  string newtext (text);
  if (casesensitive) {
    newtext = filter_string_str_replace (searchfor, replacewith, newtext);
  } else {
    vector <string> needles = filter_string_search_needles (searchfor, text);
    for (auto & needle : needles) {
      newtext = filter_string_str_replace (needle, replacewith, newtext);
    }
  }
  if (replacewith != "") newtext = filter_string_markup_words ({replacewith}, newtext);
  
  
  // The id sent to the browser contains bible identifier, book, chapter, and verse.
  int bibleID = request->database_bibles()->getID (bible);
  vector <string> bits = {convert_to_string (bibleID), convert_to_string (book), convert_to_string (chapter), verse};
  string s_id = filter_string_implode (bits, "_");
  
  
  // Check whether the user has write access to the book.
  string user = request->session_logic ()->currentUser ();
  bool write = access_bible_book_write (webserver_request, user, bible, book);

  
  // Create output.
  string output;
  output.append ("<div id=\"" + s_id + "\">\n");
  output.append ("<p>");
  if (write) output.append ("<a href=\"replace\"> ✔ </a> <a href=\"delete\"> ✗ </a> ");
  output.append (link);
  output.append ("</p>\n");
  output.append ("<p>" + oldtext + "</p>\n");
  output.append ("<p>");
  if (write) output.append (newtext);
  else output.append (locale_logic_text_no_privileges_modify_book ());
  output.append ("</p>\n");
  output.append ("</div>\n");
  
  
  // Output to browser.
  return output;
}
Exemple #2
0
string search_search2 (void * webserver_request)
{
    Webserver_Request * request = (Webserver_Request *) webserver_request;


    Database_Volatile database_volatile = Database_Volatile ();


    string siteUrl = config_logic_site_url ();


    string bible = request->database_config_user()->getBible ();
    if (request->query.count ("bible")) bible = request->query ["bible"];


    bool hit_is_set = request->query.count ("h");
    bool query_is_set = request->query.count ("q");
    int identifier = convert_to_int (request->query ["i"]);
    string query = request->query ["q"];
    string hit = request->query ["h"];


    // Get one search hit.
    if (hit_is_set) {


        // Retrieve the search parameters from the volatile database.
        string query = database_volatile.getValue (identifier, "query");
        //bool casesensitive = convert_to_bool (database_volatile.getValue (identifier, "casesensitive"));
        bool plaintext = convert_to_bool (database_volatile.getValue (identifier, "plaintext"));


        // Get the Bible and passage for this identifier.
        Passage details = Passage::from_text (hit);
        string bible = details.bible;
        int book = details.book;
        int chapter = details.chapter;
        string verse = details.verse;


        // Get the plain text or USFM.
        string text;
        if (plaintext) {
            text = search_logic_get_bible_verse_text (bible, book, chapter, convert_to_int (verse));
        } else {
            text = search_logic_get_bible_verse_usfm (bible, book, chapter, convert_to_int (verse));
        }


        // Format it.
        string link = filter_passage_link_for_opening_editor_at (book, chapter, verse);
        text =  filter_string_markup_words ({query}, text);
        string output = "<div>" + link + " " + text + "</div>";


        // Output to browser.
        return output;
    }


    // Perform the initial search.
    if (query_is_set) {


        // Get extra search parameters and store them all in the volatile database.
        bool casesensitive = (request->query ["c"] == "true");
        bool plaintext = (request->query ["p"] == "true");
        bool currentbook = (request->query ["b"] == "true");
        string sharing = request->query ["s"];
        database_volatile.setValue (identifier, "query", query);
        database_volatile.setValue (identifier, "casesensitive", convert_to_string (casesensitive));
        database_volatile.setValue (identifier, "plaintext", convert_to_string (plaintext));


        // Deal with case sensitivity.
        // Deal with whether to search the plain text, or the raw USFM.
        // Fetch the initial set of hits.
        vector <Passage> passages;
        if (plaintext) {
            if (casesensitive) {
                passages = search_logic_search_bible_text_case_sensitive (bible, query);
            } else {
                passages = search_logic_search_bible_text (bible, query);
            }
        } else {
            if (casesensitive) {
                passages = search_logic_search_bible_usfm_case_sensitive (bible, query);
            } else {
                passages = search_logic_search_bible_usfm (bible, query);
            }
        }


        // Deal with possible searching in the current book only.
        if (currentbook) {
            int book = Ipc_Focus::getBook (request);
            vector <Passage> bookpassages;
            for (auto & passage : passages) {
                if (book == passage.book) {
                    bookpassages.push_back (passage);
                }
            }
            passages = bookpassages;
        }


        // Deal with how to share the results.
        vector <string> hits;
        for (auto & passage : passages) {
            hits.push_back (passage.to_text ());
        }
        if (sharing != "load") {
            vector <string> loaded_hits = filter_string_explode (database_volatile.getValue (identifier, "hits"), '\n');
            if (sharing == "add") {
                hits.insert (hits.end(), loaded_hits.begin(), loaded_hits.end());
            }
            if (sharing == "remove") {
                hits = filter_string_array_diff (loaded_hits, hits);
            }
            if (sharing == "intersect") {
                hits = array_intersect (loaded_hits, hits);
            }
            hits = array_unique (hits);
        }


        // Generate one string from the hits.
        string output = filter_string_implode (hits, "\n");


        // Store search hits in the volatile database.
        database_volatile.setValue (identifier, "hits", output);


        // Output results.
        return output;
    }


    // Build the advanced search page.
    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", "search2");
    page += Assets_Page::footer ();
    return page;
}
Exemple #3
0
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;
}
Exemple #4
0
string search_all (void * webserver_request)
{
  Webserver_Request * request = (Webserver_Request *) webserver_request;

  
  string page;
  Assets_Header header = Assets_Header (translate("Search"), request);
  header.addBreadCrumb (menu_logic_search_menu (), menu_logic_search_text ());
  page = header.run ();

  
  Assets_View view;
  
  
  // The query: The word or string to search for.
  // Put the query string into the search box.
  string queryString;
  if (request->query.count ("q")) {
    queryString = request->query ["q"];
  }
  
  
  view.set_variable ("query", queryString);

  
  // Clean the query string up.
  queryString = filter_string_trim (queryString);
  
  
  // Generate search words for emphasizing the search passages.
  vector <string> queryWords = filter_string_explode (queryString, ' ');
  
  
  Database_Notes database_notes = Database_Notes (request);

  
  string siteUrl = config_logic_site_url ();

  
  vector <string> bibles = access_bible_bibles (request);


  // Search the notes.
  vector <int> identifiers = database_notes.searchNotes (queryString, bibles);
  
  
  int noteCount = identifiers.size();
  view.set_variable ("noteCount", convert_to_string (noteCount));
  
  
  // Assemble the block of search results for the consultation notes.
  string notesblock;
  for (auto identifier : identifiers) {
    
    // The title.
    string summary = database_notes.getSummary (identifier);
    string verses = filter_passage_display_inline (database_notes.getPassages (identifier));
    string title = summary + " | " + verses;
    title = filter_string_sanitize_html (title);
    
    // The url.
    string url = siteUrl + notes_note_url () + "?id=" + convert_to_string (identifier);
    
    // The excerpt.
    string stext = database_notes.getSearchField (identifier);
    vector <string> vtext = filter_string_explode (stext, '\n');
    string excerpt;
    // Go through each line of text separately.
    for (auto & line : vtext) {
      string markedLine = filter_string_markup_words (queryWords, line);
      // If the line is marked up, add it to the excerpts.
      if (!excerpt.empty()) excerpt.append ("\n");
      if (markedLine != line) {
        excerpt.append ("<p style=\"margin-top: 0em\">" + markedLine + "</p>");
      }
    }
    
    // The html to display.
    string html = "<p style=\"margin-top: 0.75em; margin-bottom: 0em\"><a href=\"";
    html.append (url);
    html.append ("\">");
    html.append (title);
    html.append ("</a></p>");
    html.append (excerpt);
    if (!notesblock.empty ()) notesblock.append ("\n");
    notesblock.append (html);
  }
 
  
  // Display the search results for the notes.
  view.set_variable ("notesblock", notesblock);
  
  
  // Search the Bible text.
  vector <Passage> passages = search_logic_search_text (queryString, bibles);
  
  
  int textCount = passages.size ();
  view.set_variable ("textCount", convert_to_string (textCount));
  
  
  // Assemble the search results for the Bible text.
  string textblock;
  for (auto & passage : passages) {
    string bible = passage.bible;
    int book = passage.book;
    int chapter = passage.chapter;
    string verse = passage.verse;
    // The title plus link.
    string link = bible + " | " + filter_passage_link_for_opening_editor_at (book, chapter, verse);
    // The excerpt.
    string stext = search_logic_get_bible_verse_text (bible, book, chapter, convert_to_int (verse));
    vector <string> vtext = filter_string_explode (stext, '\n');
    string excerpt;
    // Go through each line of text separately.
    for (auto & line : vtext) {
      string markedLine = filter_string_markup_words (queryWords, line);
      if (markedLine != line) {
        // Store this bit of the excerpt.
        excerpt.append ("<p style=\"margin-top: 0em\">" + markedLine + "</p>\n");
      }
    }
    
    if (!textblock.empty ()) textblock.append ("\n");
    textblock.append ("<p style=\"margin-top: 0.75em; margin-bottom: 0em\">");
    textblock.append (link);
    textblock.append ("</p>");
    textblock.append (excerpt);
  }
  
  
  // Display the search results for the Bible text.
  view.set_variable ("textblock", textblock);
  
  
  page += view.render ("search", "all");
  
  
  page += Assets_Page::footer ();
  
  
  return page;
}
Exemple #5
0
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;
}