Initial Commit

This commit is contained in:
Mike Nolan 2023-09-02 22:53:13 -05:00
commit c85103fb21
23 changed files with 224076 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
bin
obj

3
BibleServer/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"dotnet.defaultSolution": "BibleServer.sln"
}

View File

@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Tesses.WebServer" Version="1.0.4.1" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.002.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BibleServer", "BibleServer.csproj", "{21BAD777-2FAC-44CC-A876-D2FE8F952630}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{21BAD777-2FAC-44CC-A876-D2FE8F952630}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{21BAD777-2FAC-44CC-A876-D2FE8F952630}.Debug|Any CPU.Build.0 = Debug|Any CPU
{21BAD777-2FAC-44CC-A876-D2FE8F952630}.Release|Any CPU.ActiveCfg = Release|Any CPU
{21BAD777-2FAC-44CC-A876-D2FE8F952630}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0B76D068-0C47-4D66-BB51-D3F67AC60299}
EndGlobalSection
EndGlobal

189
BibleServer/Class1.cs Normal file
View File

@ -0,0 +1,189 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Tesses.WebServer;
namespace BibleServer
{
public class MyBibleServer
{
//bigger book : book : chapter : verseNo
public Dictionary<string,ScriptureRoot> Bibles {get;set;}=new Dictionary<string, ScriptureRoot>();
public MyBibleServer()
{
foreach(var item in Directory.GetFiles(Path.Combine("data","scriptures")))
{
var name=FixName(item);
var res=JsonConvert.DeserializeObject<ScriptureRoot>(File.ReadAllText(item));
if(res != null)
{
Bibles.Add(name, res);
}
}
}
public Server GetServer()
{
RouteServer routeServer = new RouteServer();
MountableServer mountableServer=new MountableServer(new StaticServer(Path.Combine("data","www")){RedirectToRootInsteadOfNotFound=true});
mountableServer.Mount("/api/v1/",routeServer);
routeServer.Add("/GetBibles",GetBibles);
routeServer.Add("/GetBooks",GetBooks);
routeServer.Add("/GetVerse",GetVerse);
routeServer.Add("/GetChapterCount",GetChapterCount);
routeServer.Add("/GetVerseCount",GetVerseCount);
routeServer.Add("/GetVerses",GetVerses);
return mountableServer;
}
private async Task GetChapterCount(ServerContext ctx)
{
if(ctx.QueryParams.TryGetFirst("bible",out var bible))
{
if(Bibles.TryGetValue(bible,out var root))
{
if(ctx.QueryParams.TryGetFirst("book",out var bookName))
{
foreach(var book in root.Books)
{
if(book.Book == bookName)
{
await ctx.SendJsonAsync(book.Chapters.Count);
}
}
}
}
}
}
private async Task GetBooks(ServerContext ctx)
{
if(ctx.QueryParams.TryGetFirst("bible",out var bible))
{
if(Bibles.TryGetValue(bible,out var root))
{
ScriptureBooksResponse response = new ScriptureBooksResponse(bible,root);
await ctx.SendJsonAsync(response);
}
}
}
private async Task GetVerses(ServerContext ctx)
{
if(ctx.QueryParams.TryGetFirst("bible",out var bible))
{
if(Bibles.TryGetValue(bible,out var root))
{
if(ctx.QueryParams.TryGetFirst("book",out var bookName))
{
if(ctx.QueryParams.TryGetFirst("chapter",out var chapterStr))
if(int.TryParse(chapterStr,out var chapter))
foreach(var book in root.Books)
{
if(book.Book == bookName)
{
if(chapter <= book.Chapters.Count)
{
var c=book.Chapters[chapter-1];
await ctx.SendJsonAsync(c.Verses);
}
break;
}
}
}
}
}
}
private async Task GetVerse(ServerContext ctx)
{
if(ctx.QueryParams.TryGetFirst("bible",out var bible))
{
if(Bibles.TryGetValue(bible,out var root))
{
if(ctx.QueryParams.TryGetFirst("book",out var bookName))
{
if(ctx.QueryParams.TryGetFirst("chapter",out var chapterStr))
if(int.TryParse(chapterStr,out var chapter))
if(ctx.QueryParams.TryGetFirst("verse",out var verseStr))
if(int.TryParse(verseStr,out var verse))
foreach(var book in root.Books)
{
if(book.Book == bookName)
{
if(chapter <= book.Chapters.Count)
{
var c=book.Chapters[chapter-1];
if(verse <= c.Verses.Count)
{
var v = c.Verses[verse-1];
await ctx.SendJsonAsync(v);
}
//await ctx.SendJsonAsync(c.Verses);
}
break;
}
}
}
}
}
}
private async Task GetVerseCount(ServerContext ctx)
{
if(ctx.QueryParams.TryGetFirst("bible",out var bible))
{
if(Bibles.TryGetValue(bible,out var root))
{
if(ctx.QueryParams.TryGetFirst("book",out var bookName))
{
if(ctx.QueryParams.TryGetFirst("chapter",out var chapterStr))
if(int.TryParse(chapterStr,out var chapter))
foreach(var book in root.Books)
{
if(book.Book == bookName)
{
if(chapter <= book.Chapters.Count)
{
var c=book.Chapters[chapter-1];
await ctx.SendJsonAsync(c.Verses.Count);
}
break;
}
}
}
}
}
}
private async Task GetBibles(ServerContext ctx)
{
await ctx.SendJsonAsync(Bibles.Keys.ToList());
}
private string FixName(string item)
{
var n = Path.GetFileNameWithoutExtension(item).Split(new char[]{'-'});
StringBuilder builder = new StringBuilder();
for(int i = 0;i<n.Length;i++)
{
if(i > 0) builder.Append(' ');
var item2 = n[i];
for(int j = 0; j < item2.Length;j++)
{
builder.Append(j == 0 ? char.ToUpper(item2[0]) : item2[j]);
}
}
return builder.ToString();
}
}
}

View File

@ -0,0 +1,13 @@
using System.Collections.Generic;
using Newtonsoft.Json;
namespace BibleServer
{
public class ScriptureBook
{
[JsonProperty("book")]
public string Book {get;set;}
[JsonProperty("chapters")]
public List<ScriptureChapter> Chapters {get;set;}
}
}

View File

@ -0,0 +1,14 @@
namespace BibleServer
{
public class ScriptureBookResponse
{
public ScriptureBookResponse(ScriptureBook book)
{
BookName = book.Book;
Chapters=book.Chapters.Count;
}
public string BookName {get;set;}
public int Chapters {get;set;}
}
}

View File

@ -0,0 +1,18 @@
using System.Collections.Generic;
namespace BibleServer
{
internal class ScriptureBooksResponse
{
public ScriptureBooksResponse(string bible,ScriptureRoot root)
{
Bible= bible;
foreach(var item in root.Books)
{
Books.Add(item.Book);
}
}
public string Bible {get;set;}
public List<string> Books {get;set;}=new List<string>();
}
}

View File

@ -0,0 +1,17 @@
using System.Collections.Generic;
using Newtonsoft.Json;
namespace BibleServer
{
public class ScriptureChapter
{
[JsonProperty("chapter")]
public int Chapter {get;set;}
[JsonProperty("reference")]
public string Reference {get;set;}
[JsonProperty("verses")]
public List<ScriptureVerse> Verses {get;set;}
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Tesses.WebServer;
namespace BibleServer
{
public class ScriptureRoot
{
[JsonProperty("books")]
public List<ScriptureBook> Books {get;set;}=new List<ScriptureBook>();
}
}

View File

@ -0,0 +1,15 @@
using Newtonsoft.Json;
namespace BibleServer
{
public class ScriptureVerse
{
[JsonProperty("reference")]
public string Reference {get;set;}
[JsonProperty("text")]
public string Text {get;set;}
[JsonProperty("verse")]
public int Verse {get;set;}
}
}

View File

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Tesses.WebServer.EasyServer" Version="1.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BibleServer\BibleServer.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,5 @@
using BibleServer;
using Tesses.WebServer;
MyBibleServer myBibleServer = new MyBibleServer();
myBibleServer.GetServer().StartServer(7777);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,66 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Scripture Viewer</title>
<link rel="stylesheet" href="./bulma.min.css">
</head>
<body>
<section class="hero is-primary">
<div class="hero-body">
<p class="title">
Scripture Viewer
</p>
<p class="subtitle">
Read The Bible in browser
</p>
</div>
</section>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li><a href="./">Home</a></li>
<li class="is-active"><a href="#" id="bible_link" aria-current="page">Bible</a></li>
</ul>
</nav>
<article class="tile is-child notification">
<p class="title">Books</p>
<p class="subtitle" id="subtitle">List of Books in the...</p>
<div class="content" id="books">
</div>
</article>
<script>
const books = document.getElementById('books');
const bible_link = document.getElementById('bible_link');
const subtitle = document.getElementById('subtitle');
//List Of Books in the
function init()
{
const params = new Proxy(new URLSearchParams(window.location.search), {
get: (searchParams, prop) => searchParams.get(prop),
});
// Get the value of "some_key" in eg "https://example.com/?some_key=some_value"
let bible = params.bible; // "some_value"
bible_link.innerText=bible;
subtitle.innerText = `List of Books in the ${bible}`;
fetch(`./api/v1/GetBooks${window.location.search}`).then(e=>e.json()).then(e=>{
e.Books.forEach(element => {
var b = document.createElement('a');
b.href = `./book?bible=${encodeURIComponent(bible)}&book=${encodeURIComponent(element)}`;
b.innerText = element;
b.classList.add('button');
b.classList.add('is-primary');
books.appendChild(b);
//books.appendChild(document.createElement('br'))
});
});
}
init();
</script>
</body>
</html>

View File

@ -0,0 +1,80 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Scripture Viewer</title>
<link rel="stylesheet" href="./bulma.min.css">
</head>
<body>
<section class="hero is-primary">
<div class="hero-body">
<p class="title">
Scripture Viewer
</p>
<p class="subtitle">
Read The Bible in browser
</p>
</div>
</section>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li><a href="./">Home</a></li>
<li><a href="./" id="bible_link">Bible</a></li>
<li class="is-active"><a href="#" id="book_link" aria-current="page">Book</a></li>
</ul>
</nav>
<article class="tile is-child notification ">
<p class="title">Chapter Select</p>
<p class="subtitle" id="subtitle">Select a chapter from...</p>
<div class="content" id="chapters">
</div>
</article>
<script>
const chapters = document.getElementById('chapters');
const subtitle = document.getElementById('subtitle');
const bible_link = document.getElementById('bible_link');
const book_link = document.getElementById('book_link');
//List Of Books in the
function init()
{
const params = new Proxy(new URLSearchParams(window.location.search), {
get: (searchParams, prop) => searchParams.get(prop),
});
// Get the value of "some_key" in eg "https://example.com/?some_key=some_value"
let bible = params.bible; // "some_value"
let book = params.book;
bible_link.href=`./bible?bible=${encodeURIComponent(bible)}`;
bible_link.innerText=bible;
book_link.innerText=book;
subtitle.innerText = `Select a chapter from ${book}`;
fetch(`./api/v1/GetChapterCount${window.location.search}`).then(e=>e.json()).then(e=>{
/* e.Books.forEach(element => {
var b = document.createElement('a');
b.href = `./book?bible=${encodeURIComponent(bible)}&book=${encodeURIComponent(element)}`;
b.innerText = element;
books.appendChild(b);
books.appendChild(document.createElement('br'))
});*/
for(i=0;i<e;i++)
{
var link = document.createElement('a');
link.classList.add('button');
link.classList.add('is-primary');
link.href=`./chapter${window.location.search}&chapter=${i+1}`;
link.innerText = (i+1);
chapters.appendChild(link);
}
});
}
init();
</script>
</body>
</html>

1
BibleServerCli/data/www/bulma.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,149 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Scripture Viewer</title>
<link rel="stylesheet" href="./bulma.min.css">
</head>
<body>
<section class="hero is-primary">
<div class="hero-body">
<p class="title">
Scripture Viewer
</p>
<p class="subtitle">
Read The Bible in browser
</p>
</div>
</section>
<nav class="breadcrumb" aria-label="breadcrumbs">
<ul>
<li><a href="./">Home</a></li>
<li><a href="./" id="bible_link">Bible</a></li>
<li><a href="./" id="book_link">Book</a></li>
<li class="is-active"><a href="#" id="chapter_link" aria-current="page">Chapter</a></li>
</ul>
</nav>
<div id="navigator">
</div>
<div id="verses">
</div>
<script>
const verses = document.getElementById('verses');
const chapternavigator = document.getElementById('navigator');
const chapters = document.getElementById('chapters');
const subtitle = document.getElementById('subtitle');
const bible_link = document.getElementById('bible_link');
const book_link = document.getElementById('book_link');
//List Of Books in the
function init()
{
const params = new Proxy(new URLSearchParams(window.location.search), {
get: (searchParams, prop) => searchParams.get(prop),
});
// Get the value of "some_key" in eg "https://example.com/?some_key=some_value"
let bible = params.bible; // "some_value"
let book = params.book;
let chapter = params.chapter;
bible_link.href=`./bible?bible=${encodeURIComponent(bible)}`;
bible_link.innerText=bible;
book_link.innerText=book;
book_link.href = `./book?bible=${encodeURIComponent(bible)}&book=${encodeURIComponent(book)}`;
fetch(`./api/v1/GetChapterCount${window.location.search}`).then(e=>e.json()).then(e=>{
var firstLink = document.createElement('a');
firstLink.innerText = "First";
firstLink.href = `./chapter?bible=${encodeURIComponent(bible)}&book=${encodeURIComponent(book)}&chapter=1`;
chapternavigator.appendChild(firstLink);
chapternavigator.append(" | ");
if(chapter > 1)
{
var prev = document.createElement('a');
prev.innerText = "Prev";
prev.href = `./chapter?bible=${encodeURIComponent(bible)}&book=${encodeURIComponent(book)}&chapter=${chapter-1}`;
chapternavigator.appendChild(prev);
chapternavigator.append(" | ");
}
else
{
var prev = document.createElement('span');
prev.innerText = "Prev";
chapternavigator.appendChild(prev);
chapternavigator.append(" | ");
}
if(chapter < e)
{
var prev = document.createElement('a');
prev.innerText = "Next";
prev.href = `./chapter?bible=${encodeURIComponent(bible)}&book=${encodeURIComponent(book)}&chapter=${parseInt(chapter)+1}`;
chapternavigator.appendChild(prev);
chapternavigator.append(" | ");
}
else
{
var prev = document.createElement('span');
prev.innerText = "Next";
chapternavigator.appendChild(prev);
chapternavigator.append(" | ");
}
var lastLink = document.createElement('a');
lastLink.innerText = "Last";
lastLink.href = `./chapter?bible=${encodeURIComponent(bible)}&book=${encodeURIComponent(book)}&chapter=${e}`;
chapternavigator.appendChild(lastLink);
fetch(`./api/v1/GetVerses?bible=${encodeURIComponent(bible)}&book=${encodeURIComponent(book)}&chapter=${chapter}`).then(f=>f.json()).then(f=>{
var i = 1;
f.forEach(element => {
generate_verse_element(element,bible,book,chapter,i);
i++;
});
});
});
}
function generate_verse_element(element,bible,book,chapter,i)
{
/*<div class="card">
<div class="card-content">
<p class="title">
Genesis 1:1
</p>
<p class="subtitle">
</p>
</div>
</div>*/
var card = document.createElement('div');
card.id = `verse-${i}`;
card.classList.add('card');
var card_content = document.createElement('div');
card_content.classList.add('card-content');
var title = document.createElement('p');
title.classList.add('title');
title.innerText = element.reference;
var subtitle = document.createElement('p');
subtitle.classList.add('subtitle');
subtitle.innerText = element.text;
card_content.appendChild(title);
card_content.appendChild(subtitle);
card.appendChild(card_content);
verses.appendChild(card);
}
init();
</script>
</body>
</html>

View File

@ -0,0 +1,45 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Scripture Viewer</title>
<link rel="stylesheet" href="./bulma.min.css">
</head>
<body>
<section class="hero is-primary">
<div class="hero-body">
<p class="title">
Scripture Viewer
</p>
<p class="subtitle">
Read The Bible in browser
</p>
</div>
</section>
<article class="tile is-child notification is-primary">
<p class="title">Scriptures</p>
<p class="subtitle">List Of Scriptures</p>
<div class="content" id="scriptures">
</div>
</article>
<script defer>
const scriptures=document.getElementById('scriptures');
fetch('./api/v1/GetBibles').then(e=>e.json()).then(e=>{
e.forEach(element => {
var b = document.createElement('a');
b.href = `./bible?bible=${encodeURIComponent(element)}`;
b.innerText = element;
scriptures.appendChild(b);
scriptures.appendChild(document.createElement('br'))
});
});
</script>
</body>
</html>