From e0fb48c2f33c2f2a9bee40dc12a88d962305bded Mon Sep 17 00:00:00 2001 From: Glowstudent777 <55334764+Glowstudent777@users.noreply.github.com> Date: Tue, 31 Dec 2024 19:50:11 -0600 Subject: [PATCH] core module --- .gitmodules | 3 + jest.config.js | 6 - src/api/v1/db/books.json | 466 ---------------------------------- src/api/v1/db/versions.json | 30 --- src/api/v1/functions/verse.ts | 63 ----- src/api/v1/functions/votd.ts | 102 -------- src/api/v1/verse/verse.ts | 2 +- src/api/v1/votd/index.ts | 20 +- 8 files changed, 14 insertions(+), 678 deletions(-) create mode 100644 .gitmodules delete mode 100644 jest.config.js delete mode 100644 src/api/v1/db/books.json delete mode 100644 src/api/v1/db/versions.json delete mode 100644 src/api/v1/functions/verse.ts delete mode 100644 src/api/v1/functions/votd.ts diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..728891a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "core"] + path = src/api/v1/core + url = https://github.com/Glowstudent777/YouVersion-Core diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index fe4961a..0000000 --- a/jest.config.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - preset: "ts-jest", - testEnvironment: "node", - testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'] -}; \ No newline at end of file diff --git a/src/api/v1/db/books.json b/src/api/v1/db/books.json deleted file mode 100644 index d92c8eb..0000000 --- a/src/api/v1/db/books.json +++ /dev/null @@ -1,466 +0,0 @@ -{ - "books": [ - { - "book": "Genesis", - "aliases": [ - "GEN" - ], - "chapters": 50 - }, - { - "book": "Exodus", - "aliases": [ - "EXO" - ], - "chapters": 40 - }, - { - "book": "Leviticus", - "aliases": [ - "LEV" - ], - "chapters": 27 - }, - { - "book": "Numbers", - "aliases": [ - "NUM" - ], - "chapters": 36 - }, - { - "book": "Deuteronomy", - "aliases": [ - "DEU" - ], - "chapters": 34 - }, - { - "book": "Joshua", - "aliases": [ - "JOS" - ], - "chapters": 24 - }, - { - "book": "Judges", - "aliases": [ - "JDG" - ], - "chapters": 21 - }, - { - "book": "Ruth", - "aliases": [ - "RUT" - ], - "chapters": 4 - }, - { - "book": "1st Samuel", - "aliases": [ - "1SA" - ], - "chapters": 31 - }, - { - "book": "2nd Samuel", - "aliases": [ - "2SA" - ], - "chapters": 24 - }, - { - "book": "1st Kings", - "aliases": [ - "1KI" - ], - "chapters": 22 - }, - { - "book": "2nd Kings", - "aliases": [ - "2KI" - ], - "chapters": 25 - }, - { - "book": "1st Chronicles", - "aliases": [ - "1CH" - ], - "chapters": 29 - }, - { - "book": "2nd Chronicles", - "aliases": [ - "2CH" - ], - "chapters": 36 - }, - { - "book": "Ezra", - "aliases": [ - "EZR" - ], - "chapters": 10 - }, - { - "book": "Nehemiah", - "aliases": [ - "NEH" - ], - "chapters": 13 - }, - { - "book": "Esther", - "aliases": [ - "EST" - ], - "chapters": 10 - }, - { - "book": "Job", - "aliases": [ - "JOB" - ], - "chapters": 42 - }, - { - "book": "Psalms", - "aliases": [ - "PSA" - ], - "chapters": 150 - }, - { - "book": "Proverbs", - "aliases": [ - "PRO" - ], - "chapters": 31 - }, - { - "book": "Ecclesiastes", - "aliases": [ - "ECC" - ], - "chapters": 12 - }, - { - "book": "Song of Songs", - "aliases": [ - "SNG" - ], - "chapters": 8 - }, - { - "book": "Isaiah", - "aliases": [ - "ISA" - ], - "chapters": 66 - }, - { - "book": "Jeremiah", - "aliases": [ - "JER" - ], - "chapters": 52 - }, - { - "book": "Lamentations", - "aliases": [ - "LAM" - ], - "chapters": 5 - }, - { - "book": "Ezekiel", - "aliases": [ - "EZK" - ], - "chapters": 48 - }, - { - "book": "Daniel", - "aliases": [ - "DAN" - ], - "chapters": 12 - }, - { - "book": "Hosea", - "aliases": [ - "HOS" - ], - "chapters": 14 - }, - { - "book": "Joel", - "aliases": [ - "JOL" - ], - "chapters": 3 - }, - { - "book": "Amos", - "aliases": [ - "AMO" - ], - "chapters": 9 - }, - { - "book": "Obadiah", - "aliases": [ - "OBA" - ], - "chapters": 1 - }, - { - "book": "Jonah", - "aliases": [ - "JON" - ], - "chapters": 4 - }, - { - "book": "Micah", - "aliases": [ - "MIC" - ], - "chapters": 7 - }, - { - "book": "Nahum", - "aliases": [ - "NAM" - ], - "chapters": 3 - }, - { - "book": "Habakkuk", - "aliases": [ - "HAB" - ], - "chapters": 3 - }, - { - "book": "Zephaniah", - "aliases": [ - "ZEP" - ], - "chapters": 3 - }, - { - "book": "Haggai", - "aliases": [ - "HAG" - ], - "chapters": 2 - }, - { - "book": "Zechariah", - "aliases": [ - "ZEC" - ], - "chapters": 14 - }, - { - "book": "Malachi", - "aliases": [ - "MAL" - ], - "chapters": 4 - }, - { - "book": "Matthew", - "aliases": [ - "MAT" - ], - "chapters": 28 - }, - { - "book": "Mark", - "aliases": [ - "MRK" - ], - "chapters": 16 - }, - { - "book": "Luke", - "aliases": [ - "LUK" - ], - "chapters": 24 - }, - { - "book": "John", - "aliases": [ - "JHN" - ], - "chapters": 21 - }, - { - "book": "Acts", - "aliases": [ - "ACT" - ], - "chapters": 28 - }, - { - "book": "Romans", - "aliases": [ - "ROM" - ], - "chapters": 16 - }, - { - "book": "1st Corinthians", - "aliases": [ - "1CO" - ], - "chapters": 16 - }, - { - "book": "2nd Corinthians", - "aliases": [ - "2CO" - ], - "chapters": 13 - }, - { - "book": "Galatians", - "aliases": [ - "GAL" - ], - "chapters": 6 - }, - { - "book": "Ephesians", - "aliases": [ - "EPH" - ], - "chapters": 6 - }, - { - "book": "Philippians", - "aliases": [ - "PHP" - ], - "chapters": 4 - }, - { - "book": "Colossians", - "aliases": [ - "COL" - ], - "chapters": 4 - }, - { - "book": "1st Thessalonians", - "aliases": [ - "1TH" - ], - "chapters": 5 - }, - { - "book": "2nd Thessalonians", - "aliases": [ - "2TH" - ], - "chapters": 3 - }, - { - "book": "1st Timothy", - "aliases": [ - "1TI" - ], - "chapters": 6 - }, - { - "book": "2nd Timothy", - "aliases": [ - "2TI" - ], - "chapters": 4 - }, - { - "book": "Titus", - "aliases": [ - "TIT" - ], - "chapters": 3 - }, - { - "book": "Philemon", - "aliases": [ - "PHM" - ], - "chapters": 1 - }, - { - "book": "Hebrews", - "aliases": [ - "HEB" - ], - "chapters": 13 - }, - { - "book": "James", - "aliases": [ - "JAS" - ], - "chapters": 5 - }, - { - "book": "1st Peter", - "aliases": [ - "1PE" - ], - "chapters": 5 - }, - { - "book": "2nd Peter", - "aliases": [ - "2PE" - ], - "chapters": 3 - }, - { - "book": "1st John", - "aliases": [ - "1JN" - ], - "chapters": 5 - }, - { - "book": "2nd John", - "aliases": [ - "2JN" - ], - "chapters": 1 - }, - { - "book": "3rd John", - "aliases": [ - "3JN" - ], - "chapters": 1 - }, - { - "book": "Jude", - "aliases": [ - "JUD" - ], - "chapters": 1 - }, - { - "book": "Revelation", - "aliases": [ - "REV" - ], - "chapters": 22 - } - ] -} diff --git a/src/api/v1/db/versions.json b/src/api/v1/db/versions.json deleted file mode 100644 index dcbc4b0..0000000 --- a/src/api/v1/db/versions.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "ASV": 12, - "AMP": 1588, - "AMPC": 8, - "CPDV": 42, - - "ICL00D": 1196, - "KJV": 1, - "NIV": 111, - "NLT": 116, - "NR06": 122, - "VULG": 823, - - - "B21": 15, - "BKR": 44, - "SNC": 162, - "CSP": 509, - - "bibel.heute": 877, - "Hfa": 73, - "DELUT": 51, - "LUTheute": 3100, - - "SLB": 644, - "NPK": 3835, - "SEB": 465, - "SEBDT": 464, - "SSV": 163 -} diff --git a/src/api/v1/functions/verse.ts b/src/api/v1/functions/verse.ts deleted file mode 100644 index 054badf..0000000 --- a/src/api/v1/functions/verse.ts +++ /dev/null @@ -1,63 +0,0 @@ -import axios from 'axios'; -import * as cheerio from 'cheerio'; - -const versions = require('../db/versions.json'); -const bookList = require('../db/books.json'); -const baseURL = "https://www.bible.com/bible"; - -type bookType = { - book: String, - aliases: Array, - chapters: Number -} - -export const getVerse = async (book: string, chapter: string, verses: string, version: string) => { - let versionFinder: any = { - version: Object.keys(versions)[Object.keys(versions).indexOf(version.toLocaleString().toLocaleUpperCase())] ??= "NIV", - id: versions[version.toString().toLocaleUpperCase()] ??= 1, - } - - let bookFinder = bookList.books.find((o: bookType) => o.book.toLowerCase() === book.toLowerCase()) || bookList.books.find((o: bookType) => o.aliases.includes(book.toUpperCase())); - if (!bookFinder) return { code: 400, message: `Could not find book '${book}' by name or alias.` } - - let URL = `${baseURL}/${versionFinder.id}/${bookFinder.aliases[0]}.${chapter}.${verses}`; - - try { - const { data } = await axios.get(URL); - const $ = cheerio.load(data); - - const unavailable = $("p:contains('No Available Verses')").text(); - if (unavailable) return { code: 400, message: "Verse not found" }; - - // Nextjs way :) - const nextWay = $("script#__NEXT_DATA__").eq(0); - if (nextWay) { - let json = JSON.parse(nextWay.html() || ""); - const verse = json.props.pageProps.verses[0].content; - const reference = json.props.pageProps.verses[0].reference.human - - return { - citation: `${reference}`, - passage: verse, - } - } - // Old way :( - else { - const versesArray: Array = []; - const wrapper = $(".text-17"); - - await wrapper.each((i, p) => { - let unformattedVerse = $(p).eq(0).text(); - let formattedVerse = unformattedVerse.replace(/\n/g, ' '); - versesArray.push(formattedVerse) - }) - - return { - citation: `${bookFinder.book} ${chapter}:${verses}`, - passage: versesArray[0] - } - } - } catch (err) { - console.error(err); - } -} diff --git a/src/api/v1/functions/votd.ts b/src/api/v1/functions/votd.ts deleted file mode 100644 index 7ffc05f..0000000 --- a/src/api/v1/functions/votd.ts +++ /dev/null @@ -1,102 +0,0 @@ -import axios, { AxiosError, AxiosResponse } from 'axios'; -import * as cheerio from 'cheerio'; -import { version } from 'os'; - -async function fetchData(language: string) { - const URL = `https://www.bible.com/${language}/verse-of-the-day`; - try { - const response = await axios.get(URL); - return response; - } catch (error) { - if (error instanceof AxiosError) { - console.error(`Error for language '${language}': ${error.response?.status}`); - } else if (error instanceof Error) { - console.error(`Network error for language '${language}': ${error.message}`); - } - return null; - } -} - -export const getVotd = async (lang: string) => { - const languageList = lang.split(','); - let index = 0; - let responseStatus = 0; - let data: AxiosResponse | null = null; - - while (index < languageList.length && responseStatus !== 200) { - const language = languageList[index].trim(); - - data = await fetchData(language); - if (data) { - responseStatus = data.status; - if (responseStatus === 200) { - const $ = cheerio.load(data.data); - - const imageArray: Array = []; - - // Nextjs way :) - const nextWay = $("script#__NEXT_DATA__").eq(0); - if (nextWay != null) { - let json = JSON.parse(nextWay.html() || ""); - const verse = json.props.pageProps.verses[0].content.replace(/\n/g, ' '); - const reference = json.props.pageProps.verses[0].reference.human; - const version = json.props.pageProps.versionData.abbreviation; - - const images = $("a.block"); - await images.each((i, p) => { - let image = `https://www.bible.com${$(p).find('img').attr()?.src}` - imageArray.push(image); - }) - - return { - citation: `${reference}`, - passage: verse, - images: imageArray ?? [], - version: version - } - } - // Old way :( - else { - const versesArray: Array = []; - const citationsArray: Array = []; - let version; - - const verses = $("a.text-text-light.w-full.no-underline"); - const citations = $("p.text-gray-25"); - const images = $("a.block"); - - await citations.each((i, p) => { - let citation = $(p).eq(0).text(); - - // cut the ending (ESV), (NIV), etc and store it in version - version = citation.slice(-4).replace(/[()]/g, ''); - - // cut the version from the citation - citation = citation.slice(0, -6); - - citationsArray.push(citation) - }) - - await verses.each((i, p) => { - let unformattedVerse = $(p).eq(0).text(); - let formattedVerse = unformattedVerse.replace(/\n/g, ' '); - versesArray.push(formattedVerse) - }) - - await images.each((i, p) => { - let image = `https://www.bible.com${$(p).find('img').attr()?.src}` - imageArray.push(image); - }) - - return { - citation: citationsArray[0], - passage: versesArray[0], - image: imageArray ?? [], - version: version - } - } - } - } - index++; - } -} diff --git a/src/api/v1/verse/verse.ts b/src/api/v1/verse/verse.ts index 39faa2c..1ee9827 100644 --- a/src/api/v1/verse/verse.ts +++ b/src/api/v1/verse/verse.ts @@ -1,7 +1,7 @@ import express, { Request, Response, Router } from 'express' import axios from 'axios'; import * as cheerio from 'cheerio'; -import { getVerse } from '../functions/verse'; +import { getVerse } from '../core/functions/verse'; // Router const router: Router = express.Router(); diff --git a/src/api/v1/votd/index.ts b/src/api/v1/votd/index.ts index 9d8ff6d..f5ec057 100644 --- a/src/api/v1/votd/index.ts +++ b/src/api/v1/votd/index.ts @@ -1,7 +1,7 @@ -import express, { Request, Response, Router } from 'express' -import axios from 'axios'; -import * as cheerio from 'cheerio'; -import { getVotd } from '../functions/votd'; +import express, { Request, Response, Router } from "express"; +import axios from "axios"; +import * as cheerio from "cheerio"; +import { getVotd } from "../core/functions/votd"; // Router const router: Router = express.Router(); @@ -17,7 +17,7 @@ const router: Router = express.Router(); * in: query * required: false * description: | - * Language code for the verse of the day (e.g., sk, en, fr, de). Defaults to 'en' if not provided. + * Language code for the verse of the day (e.g., sk, en, fr, de). Defaults to 'en' if not provided. * You can provide list of comma separated languages. First found language is returned. * schema: * type: string @@ -32,9 +32,9 @@ const router: Router = express.Router(); * example: OK */ router.get("/", async (req: Request, res: Response) => { - const lang = req.query.lang as string || "en"; - const data = await getVotd(lang); - res.status(200).send(data); -}) + const lang = (req.query.lang as string) || "en"; + const data = await getVotd(lang); + res.status(200).send(data); +}); -module.exports = router; \ No newline at end of file +module.exports = router;