138
139
Webserver_Request * request = static_cast<Webserver_Request *>(webserver_request);
142
141
// Determine the type of the resource.
143
bool isBible = resource_logic_is_bible (resource);
144
bool isUsfm = resource_logic_is_usfm (resource);
145
bool isExternal = resource_logic_is_external (resource);
146
bool isImage = resource_logic_is_image (resource);
147
bool isLexicon = resource_logic_is_lexicon (resource);
148
bool isSword = resource_logic_is_sword (resource);
149
bool isBibleGateway = resource_logic_is_biblegateway (resource);
150
bool isStudyLight = resource_logic_is_studylight (resource);
151
bool isComparative = resource_logic_is_comparative (resource);
142
bool is_bible = resource_logic_is_bible (resource);
143
bool is_usfm = resource_logic_is_usfm (resource);
144
bool is_external = resource_logic_is_external (resource);
145
bool is_image = resource_logic_is_image (resource);
146
bool is_lexicon = resource_logic_is_lexicon (resource);
147
bool is_sword = resource_logic_is_sword (resource);
148
bool is_bible_gateway = resource_logic_is_biblegateway (resource);
149
bool is_study_light = resource_logic_is_studylight (resource);
150
bool is_comparative = resource_logic_is_comparative (resource);
151
bool is_translated = resource_logic_is_translated(resource);
153
153
// Handle a comparative resource.
154
154
// This type of resource is special.
155
155
// It is not one resource, but made out of two resources.
156
156
// It fetches data from two resources and combines that into one.
157
if (is_comparative) {
158
158
#ifdef HAVE_CLOUD
159
html = resource_logic_cloud_get_comparison (webserver_request, resource, book, chapter, verse, add_verse_numbers);
159
return resource_logic_cloud_get_comparison (webserver_request, resource, book, chapter, verse, add_verse_numbers);
161
161
#ifdef HAVE_CLIENT
162
html = resource_logic_client_fetch_cache_from_cloud (resource, book, chapter, verse);
162
return resource_logic_client_fetch_cache_from_cloud (resource, book, chapter, verse);
166
// Handle a translated resource.
167
// This type of resource is special.
168
// It consists of any of the other types of resources, as the base resource.
169
// It gets that data, and then has that translated.
172
return resource_logic_cloud_get_translation (webserver_request, resource, book, chapter, verse, add_verse_numbers);
175
return resource_logic_client_fetch_cache_from_cloud (resource, book, chapter, verse);
167
179
Database_Mappings database_mappings;
169
181
// Retrieve versification system of the active Bible.
173
185
// Determine the versification system of the current resource.
174
186
string resource_versification;
175
if (isBible || isUsfm) {
187
if (is_bible || is_usfm) {
176
188
resource_versification = Database_Config_Bible::getVersificationSystem (bible);
177
} else if (isExternal) {
189
} else if (is_external) {
178
190
resource_versification = resource_external_mapping (resource);
179
} else if (isImage) {
180
} else if (isLexicon) {
191
} else if (is_image) {
192
} else if (is_lexicon) {
181
193
resource_versification = database_mappings.original ();
182
194
if (resource == KJV_LEXICON_NAME) resource_versification = english ();
183
} else if (isSword) {
184
resource_versification = english ();
185
} else if (isBibleGateway) {
186
resource_versification = english ();
187
} else if (isStudyLight) {
195
} else if (is_sword) {
196
resource_versification = english ();
197
} else if (is_bible_gateway) {
198
resource_versification = english ();
199
} else if (is_study_light) {
188
200
resource_versification = english ();
227
239
if (resource_versification != database_mappings.original ()) {
228
240
passages.clear ();
229
241
for (auto & related_passage : related_passages) {
230
vector <Passage> mapped_passages = database_mappings.translate (database_mappings.original (), resource_versification, related_passage.book, related_passage.chapter, convert_to_int (related_passage.verse));
242
vector <Passage> mapped_passages = database_mappings.translate (database_mappings.original (), resource_versification, related_passage.m_book, related_passage.m_chapter, convert_to_int (related_passage.m_verse));
231
243
passages.insert (passages.end (), mapped_passages.begin (), mapped_passages.end ());
238
252
for (auto passage : passages) {
239
253
string possible_included_passage;
240
if (add_verse_numbers) possible_included_passage = passage.verse + " ";
241
if (add_passages_in_full) possible_included_passage = filter_passage_display (passage.book, passage.chapter, passage.verse) + " ";
242
if (isImage) possible_included_passage.clear ();
254
if (add_verse_numbers) possible_included_passage = passage.m_verse + " ";
255
if (add_passages_in_full) possible_included_passage = filter_passage_display (passage.m_book, passage.m_chapter, passage.m_verse) + " ";
256
if (is_image) possible_included_passage.clear ();
243
257
html.append (possible_included_passage);
244
html.append (resource_logic_get_verse (webserver_request, resource, passage.book, passage.chapter, convert_to_int (passage.verse)));
258
html.append (resource_logic_get_verse (webserver_request, resource, passage.m_book, passage.m_chapter, convert_to_int (passage.m_verse)));
278
292
string chapter_usfm;
279
293
if (isBible) chapter_usfm = request->database_bibles()->getChapter (resource, book, chapter);
280
294
if (isLocalUsfm) chapter_usfm = database_usfmresources.getUsfm (resource, book, chapter);
281
string verse_usfm = usfm_get_verse_text (chapter_usfm, verse);
295
string verse_usfm = filter::usfm::get_verse_text (chapter_usfm, verse);
282
296
string stylesheet = styles_logic_standard_sheet ();
283
297
Filter_Text filter_text = Filter_Text (resource);
284
298
filter_text.html_text_standard = new Html_Text ("");
383
397
for (auto search_replace_set : search_replace_sets) {
384
398
vector <string> search_replace = filter_string_explode(search_replace_set, '=');
385
399
if (search_replace.size() == 2) {
386
string search = search_replace[0];
387
if (search.empty()) continue;
388
string replace = search_replace[1];
389
base = filter_string_str_replace(search, replace, base);
390
update = filter_string_str_replace(search, replace, update);
400
string search_item = search_replace[0];
401
if (search_item.empty()) continue;
402
string replace_item = search_replace[1];
403
base = filter_string_str_replace(search_item, replace_item, base);
404
update = filter_string_str_replace(search_item, replace_item, update);
425
string resource_logic_cloud_get_translation (void * webserver_request,
426
const string & resource, int book, int chapter, int verse,
427
bool add_verse_numbers)
429
// This function gets passed the resource title only.
430
// So get all defined translated resources and look for the one with this title.
431
// And then get the additional properties belonging to this resource.
432
string title, original_resource, source_language, target_language;
433
vector <string> resources = Database_Config_General::getTranslatedResources ();
434
for (const auto & input : resources) {
435
resource_logic_parse_translated_resource (input, &title, &original_resource, &source_language, &target_language);
436
if (title == resource) break;
439
// Get the html of the resources to be translated.
440
string original_text = resource_logic_get_html (webserver_request, original_resource, book, chapter, verse, add_verse_numbers);
441
// Clean all html elements away from the text to get a better and cleaner translation.
442
original_text = filter_string_html2text (original_text);
444
// If the original text is empty, do not even send it to Google Translate, for saving resources.
445
if (original_text.empty()) return string();
447
// Run it through Google Translate.
448
auto [ translation_success, translated_text, translation_error] = filter::google::translate (original_text, source_language.c_str(), target_language.c_str());
451
if (translation_success) return translated_text;
452
Database_Logs::log (translation_error);
453
return "Failed to translate";
411
457
// This runs on the server.
412
458
// It gets the html or text contents for a $resource for serving it to a client.
413
459
string resource_logic_get_contents_for_client (string resource, int book, int chapter, int verse)
415
461
// Determine the type of the current resource.
416
bool isExternal = resource_logic_is_external (resource);
417
bool isUsfm = resource_logic_is_usfm (resource);
418
bool isSword = resource_logic_is_sword (resource);
419
bool isBibleGateway = resource_logic_is_biblegateway (resource);
420
bool isStudyLight = resource_logic_is_studylight (resource);
421
bool isComparative = resource_logic_is_comparative (resource);
462
bool is_external = resource_logic_is_external (resource);
463
bool is_usfm = resource_logic_is_usfm (resource);
464
bool is_sword = resource_logic_is_sword (resource);
465
bool is_bible_gateway = resource_logic_is_biblegateway (resource);
466
bool is_study_light = resource_logic_is_studylight (resource);
467
bool is_comparative = resource_logic_is_comparative (resource);
468
bool is_translated = resource_logic_is_translated(resource);
424
471
// The server fetches it from the web.
425
472
return resource_external_cloud_fetch_cache_extract (resource, book, chapter, verse);
429
476
// Fetch from database and convert to html.
430
477
Database_UsfmResources database_usfmresources;
431
478
string chapter_usfm = database_usfmresources.getUsfm (resource, book, chapter);
432
string verse_usfm = usfm_get_verse_text (chapter_usfm, verse);
479
string verse_usfm = filter::usfm::get_verse_text (chapter_usfm, verse);
433
480
string stylesheet = styles_logic_standard_sheet ();
434
481
Filter_Text filter_text = Filter_Text (resource);
435
482
filter_text.html_text_standard = new Html_Text ("");
438
485
return filter_text.html_text_standard->get_inner_html ();
442
489
// Fetch it from a SWORD module.
443
490
string sword_module = sword_logic_get_remote_module (resource);
444
491
string sword_source = sword_logic_get_source (resource);
445
492
return sword_logic_get_text (sword_source, sword_module, book, chapter, verse);
448
if (isBibleGateway) {
495
if (is_bible_gateway) {
449
496
// The server fetches it from the web.
450
497
return resource_logic_bible_gateway_get (resource, book, chapter, verse);
500
if (is_study_light) {
454
501
// The server fetches it from the web.
455
502
return resource_logic_study_light_get (resource, book, chapter, verse);
505
if (is_comparative) {
459
506
// Handle a comparative resource.
460
507
// This type of resource is special.
461
508
// It is not one resource, but made out of two resources.
464
511
return resource_logic_cloud_get_comparison (&request, resource, book, chapter, verse, false);
515
// Handle a translated resource.
516
// This passes the resource title only
517
Webserver_Request request;
518
return resource_logic_cloud_get_translation (&request, resource, book, chapter, verse, false);
467
521
// Nothing found.
468
return translate ("Bibledit Cloud could not localize this resource");
522
return translate ("Bibledit Cloud could not locate this resource");
750
804
if (resource_logic_create_cache_running) return;
751
805
resource_logic_create_cache_running = true;
807
// Get the signatures of the resources to cache.
808
vector <string> signatures = Database_Config_General::getResourcesToCache ();
753
809
// If there's nothing to cache, bail out.
754
vector <string> signatures = Database_Config_General::getResourcesToCache ();
755
810
if (signatures.empty ()) return;
757
// Resource and book to cache.
812
// A signature is the resource title, then a space, and then the book number.
813
// Remove this signature and store the remainder back into the configuration.
758
814
string signature = signatures [0];
759
815
signatures.erase (signatures.begin ());
760
816
Database_Config_General::setResourcesToCache (signatures);
1721
1777
int ending_chapter = starting_chapter;
1722
1778
colon_pos = last_word.find(":");
1723
1779
if (colon_pos != string::npos) {
1724
string ch_fragment = last_word.substr(0, colon_pos);
1725
ending_chapter = convert_to_int(ch_fragment);
1726
string check = convert_to_string(ending_chapter);
1727
if (ch_fragment != check) return false;
1780
string chapter_fragment = last_word.substr(0, colon_pos);
1781
ending_chapter = convert_to_int(chapter_fragment);
1782
check = convert_to_string(ending_chapter);
1783
if (chapter_fragment != check) return false;
1728
1784
last_word.erase(0, colon_pos + 1);
1977
2033
vector <string> bits = {resource_logic_comparative_resource() + title, base, update, remove, replace, convert_to_true_false(diacritics), convert_to_true_false(casefold), convert_to_true_false(cache)};
1978
2034
return filter_string_implode(bits, "|");
2038
bool resource_logic_is_translated (const string & resource)
2040
return resource_logic_parse_translated_resource(resource);
2044
string resource_logic_translated_resource ()
2046
return "Translated ";
2050
bool resource_logic_parse_translated_resource (const string & input,
2052
string * original_resource,
2053
string * source_language,
2054
string * target_language,
2057
// The definite check whether this is a translated resource
2058
// is to check that "Translated " is the first part of the input.
2059
if (input.find(resource_logic_translated_resource()) != 0) return false;
2061
// Do a forgiving parsing of the properties of this resource.
2062
if (title) title->clear();
2063
if (original_resource) original_resource->clear();
2064
if (source_language) source_language->clear();
2065
if (target_language) target_language->clear();
2066
if (cache) * cache = false;
2067
vector <string> bits = filter_string_explode(input, '|');
2068
if (bits.size() > 0) if (title) title->assign (bits[0]);
2069
if (bits.size() > 1) if (original_resource) original_resource->assign(bits[1]);
2070
if (bits.size() > 2) if (source_language) source_language->assign(bits[2]);
2071
if (bits.size() > 3) if (target_language) target_language->assign(bits[3]);
2072
if (bits.size() > 4) if (cache) * cache = convert_to_bool(bits[4]);
2079
string resource_logic_assemble_translated_resource (string title,
2080
string original_resource,
2081
string source_language,
2082
string target_language,
2085
// Check whether the "Translated " flag already is included in the given $title.
2086
size_t pos = title.find (resource_logic_translated_resource ());
2087
if (pos != string::npos) {
2088
title.erase (pos, resource_logic_translated_resource ().length());
2090
// Ensure the "Translated " flag is always included right at the start.
2091
vector <string> bits = {resource_logic_translated_resource() + title, original_resource, source_language, target_language, convert_to_true_false(cache)};
2092
return filter_string_implode(bits, "|");
2096
string resource_logic_translated_resources_list_path ()
2098
return filter_url_create_root_path ({database_logic_databases (), "client", "translated_resources.txt"});
2102
// Get the list of Translated resources on a client device.
2103
vector <string> resource_logic_translated_resources_get_list_on_client ()
2105
string path = resource_logic_translated_resources_list_path ();
2106
string contents = filter_url_file_get_contents (path);
2107
return filter_string_explode (contents, '\n');