Skip to content

Commit

Permalink
add language support for VOTD
Browse files Browse the repository at this point in the history
  • Loading branch information
Haluska77 committed Oct 21, 2024
1 parent 09ed133 commit 80f1184
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 69 deletions.
161 changes: 93 additions & 68 deletions src/api/v1/functions/votd.ts
Original file line number Diff line number Diff line change
@@ -1,77 +1,102 @@
import axios from 'axios';
import axios, { AxiosError, AxiosResponse } from 'axios';
import * as cheerio from 'cheerio';
import { version } from 'os';

const URL = "https://www.bible.com/verse-of-the-day";
export const getVotd = async () => {
async function fetchData(language: string) {
const URL = `https://www.bible.com/${language}/verse-of-the-day`;
try {
const { data } = await axios.get(URL);
const $ = cheerio.load(data);

const imageArray: Array<String> = [];

// 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
}
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}`);
}
// Old way :(
else {
const versesArray: Array<String> = [];
const citationsArray: Array<String> = [];
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
return null;
}
}

export const getVotd = async (lang: string) => {
const languageList = lang.split(',');

Check failure on line 21 in src/api/v1/functions/votd.ts

View workflow job for this annotation

GitHub Actions / tests

votd.test.ts > getVotd > VOTD

TypeError: Cannot read properties of undefined (reading 'split') ❯ Module.getVotd ../src/api/v1/functions/votd.ts:21:31 ❯ votd.test.ts:6:29
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<String> = [];

// 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<String> = [];
const citationsArray: Array<String> = [];
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
}
}
}
}
} catch (err) {
console.error(err);
index++;
}
}
13 changes: 12 additions & 1 deletion src/api/v1/votd/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ const router: Router = express.Router();
* get:
* summary: Verse of the day
* tags: [Bible]
* parameters:
* - name: lang
* 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.
* You can provide list of comma separated languages. First found language is returned.
* schema:
* type: string
* example: sk,en,de
* responses:
* 200:
* description: OK
Expand All @@ -22,7 +32,8 @@ const router: Router = express.Router();
* example: OK
*/
router.get("/", async (req: Request, res: Response) => {
const data = await getVotd();
const lang = req.query.lang as string || "en";
const data = await getVotd(lang);
res.status(200).send(data);
})

Expand Down

0 comments on commit 80f1184

Please sign in to comment.