Skip to content

Commit cc794ee

Browse files
author
Christian Furr
committed
i did it
0 parents  commit cc794ee

File tree

6 files changed

+35057
-0
lines changed

6 files changed

+35057
-0
lines changed

.gitignore

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Dependencies
2+
node_modules/
3+
4+
# Environment files
5+
.env
6+
.env.local
7+
.env.*.local
8+
9+
# Logs
10+
logs
11+
*.log
12+
npm-debug.log*
13+
yarn-debug.log*
14+
yarn-error.log*
15+
16+
# Runtime data
17+
pids
18+
*.pid
19+
*.seed
20+
*.pid.lock
21+
22+
# Directory for instrumented libs generated by jscoverage/JSCover
23+
lib-cov
24+
25+
# Coverage directory used by tools like istanbul
26+
coverage
27+
28+
# nyc test coverage
29+
.nyc_output
30+
31+
# IDEs and editors
32+
.idea/
33+
.vscode/
34+
*.swp
35+
*.swo
36+
.DS_Store
37+
Thumbs.db

bok.json

Lines changed: 34587 additions & 0 deletions
Large diffs are not rendered by default.

bun.lock

Lines changed: 228 additions & 0 deletions
Large diffs are not rendered by default.

index.html

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Daily Book of Mormon API</title>
7+
<script src="https://cdn.tailwindcss.com"></script>
8+
</head>
9+
<body class="bg-gray-100 min-h-screen">
10+
<div class="container mx-auto px-4 py-8">
11+
<!-- Hero Section -->
12+
<header class="text-center mb-12">
13+
<h1 class="text-4xl font-bold text-gray-800 mb-4">Daily Book of Mormon API</h1>
14+
<p class="text-lg text-gray-600">A simple and efficient API for accessing Book of Mormon verses</p>
15+
</header>
16+
17+
<!-- API Routes Section -->
18+
<div class="grid md:grid-cols-2 gap-6 mb-12">
19+
<!-- Daily Verse -->
20+
<div class="bg-white rounded-lg shadow-md p-6">
21+
<h2 class="text-xl font-semibold text-gray-800 mb-3">Daily Verse</h2>
22+
<p class="text-gray-600 mb-4">Get a new verse every day</p>
23+
<div class="bg-gray-100 rounded p-3">
24+
<code class="text-sm text-blue-600">GET /daily</code>
25+
</div>
26+
</div>
27+
28+
<!-- Random Verse -->
29+
<div class="bg-white rounded-lg shadow-md p-6">
30+
<h2 class="text-xl font-semibold text-gray-800 mb-3">Random Verse</h2>
31+
<p class="text-gray-600 mb-4">Get a random verse from the Book of Mormon</p>
32+
<div class="bg-gray-100 rounded p-3">
33+
<code class="text-sm text-blue-600">GET /random</code>
34+
</div>
35+
</div>
36+
37+
<!-- Specific Verse -->
38+
<div class="bg-white rounded-lg shadow-md p-6">
39+
<h2 class="text-xl font-semibold text-gray-800 mb-3">Specific Verse</h2>
40+
<p class="text-gray-600 mb-4">Get a specific verse by book, chapter, and verse number</p>
41+
<div class="bg-gray-100 rounded p-3">
42+
<code class="text-sm text-blue-600">GET /:book/:chapter/:verse</code>
43+
</div>
44+
<p class="text-sm text-gray-500 mt-2">Example: /nephi1/3/7</p>
45+
</div>
46+
47+
<!-- Available Books -->
48+
<div class="bg-white rounded-lg shadow-md p-6">
49+
<h2 class="text-xl font-semibold text-gray-800 mb-3">Available Books</h2>
50+
<p class="text-gray-600 mb-4">Get a list of all available books and their chapters</p>
51+
<div class="bg-gray-100 rounded p-3">
52+
<code class="text-sm text-blue-600">GET /books</code>
53+
</div>
54+
</div>
55+
</div>
56+
57+
<!-- Footer -->
58+
<footer class="text-center py-8 border-t border-gray-200">
59+
<p class="text-gray-600 mb-2">Created by Christian Furr</p>
60+
<a href="https://github.com/MakashiDev" target="_blank" class="inline-flex items-center text-blue-600 hover:text-blue-800">
61+
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
62+
<path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/>
63+
</svg>
64+
GitHub
65+
</a>
66+
</footer>
67+
</div>
68+
</body>
69+
</html>

package.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "daily-bok",
3+
"version": "1.0.0",
4+
"description": "Daily Book of Mormon Verse API",
5+
"main": "server.js",
6+
"scripts": {
7+
"start": "node server.js",
8+
"dev": "nodemon server.js"
9+
},
10+
"dependencies": {
11+
"express": "^4.18.2",
12+
"cors": "^2.8.5"
13+
},
14+
"devDependencies": {
15+
"nodemon": "^3.0.1"
16+
}
17+
}

server.js

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
const express = require('express');
2+
const cors = require('cors');
3+
const fs = require('fs');
4+
const path = require('path');
5+
6+
const app = express();
7+
app.use(cors());
8+
app.use(express.static(__dirname));
9+
10+
// Load the Book of Mormon data
11+
const bokData = JSON.parse(fs.readFileSync(path.join(__dirname, 'bok.json'), 'utf8'));
12+
13+
// Helper function to get a random verse from the entire book
14+
function getRandomVerse() {
15+
const books = bokData.books;
16+
const randomBook = books[Math.floor(Math.random() * books.length)];
17+
const randomChapter = randomBook.chapters[Math.floor(Math.random() * randomBook.chapters.length)];
18+
const randomVerse = randomChapter.verses[Math.floor(Math.random() * randomChapter.verses.length)];
19+
return randomVerse;
20+
}
21+
22+
// Helper function to get today's verse (changes daily)
23+
function getDailyVerse() {
24+
const startDate = new Date('2024-01-01').getTime();
25+
const today = new Date().getTime();
26+
const daysSinceStart = Math.floor((today - startDate) / (1000 * 60 * 60 * 24));
27+
28+
let totalVerses = [];
29+
bokData.books.forEach(book => {
30+
book.chapters.forEach(chapter => {
31+
totalVerses = totalVerses.concat(chapter.verses);
32+
});
33+
});
34+
35+
const verseIndex = daysSinceStart % totalVerses.length;
36+
return totalVerses[verseIndex];
37+
}
38+
39+
// Get daily verse
40+
app.get('/daily', (req, res) => {
41+
try {
42+
const verse = getDailyVerse();
43+
res.json(verse);
44+
} catch (error) {
45+
res.status(500).json({ error: 'Error getting daily verse' });
46+
}
47+
});
48+
49+
// Get random verse
50+
app.get('/random', (req, res) => {
51+
try {
52+
const verse = getRandomVerse();
53+
res.json(verse);
54+
} catch (error) {
55+
res.status(500).json({ error: 'Error getting random verse' });
56+
}
57+
});
58+
59+
// Get specific verse by path
60+
app.get('/:book/:chapter/:verse', (req, res) => {
61+
try {
62+
const { book, chapter, verse } = req.params;
63+
64+
// Handle special cases like "nephi2" -> "2 Nephi"
65+
let bookName = book.toLowerCase();
66+
if (bookName.includes('nephi')) {
67+
if (bookName === 'nephi2' || bookName === '2nephi') {
68+
bookName = '2 Nephi';
69+
} else if (bookName === 'nephi3' || bookName === '3nephi') {
70+
bookName = '3 Nephi';
71+
} else if (bookName === 'nephi4' || bookName === '4nephi') {
72+
bookName = '4 Nephi';
73+
} else {
74+
bookName = '1 Nephi';
75+
}
76+
}
77+
78+
const foundBook = bokData.books.find(b =>
79+
b.book.toLowerCase() === bookName ||
80+
b.book.toLowerCase().replace(/\s+/g, '') === bookName
81+
);
82+
83+
if (!foundBook) {
84+
return res.status(404).json({ error: 'Book not found' });
85+
}
86+
87+
const foundChapter = foundBook.chapters.find(c => c.chapter === parseInt(chapter));
88+
if (!foundChapter) {
89+
return res.status(404).json({ error: 'Chapter not found' });
90+
}
91+
92+
const foundVerse = foundChapter.verses.find(v => v.verse === parseInt(verse));
93+
if (!foundVerse) {
94+
return res.status(404).json({ error: 'Verse not found' });
95+
}
96+
97+
res.json(foundVerse);
98+
} catch (error) {
99+
res.status(500).json({ error: 'Error getting verse' });
100+
}
101+
});
102+
103+
// Get all available books
104+
app.get('/books', (req, res) => {
105+
try {
106+
const books = bokData.books.map(book => ({
107+
name: book.book,
108+
chapters: book.chapters.length
109+
}));
110+
res.json(books);
111+
} catch (error) {
112+
res.status(500).json({ error: 'Error getting books' });
113+
}
114+
});
115+
116+
const PORT = process.env.PORT || 3000;
117+
app.listen(PORT, () => {
118+
console.log(`Server is running on port ${PORT}`);
119+
});

0 commit comments

Comments
 (0)