Files
lnreader/src/services/updates.js
T
2021-09-10 09:21:13 +05:30

250 lines
8.3 KiB
JavaScript

import * as SQLite from "expo-sqlite";
const db = SQLite.openDatabase("lnreader.db");
import { getLibrary } from "../database/queries/LibraryQueries";
import { fetchChapters, fetchNovel } from "../services/Source/source";
import * as Notifications from "expo-notifications";
import BackgroundService from "react-native-background-actions";
import { showToast } from "../hooks/showToast";
import { downloadChapter } from "../database/queries/ChapterQueries";
Notifications.setNotificationHandler({
handleNotification: async () => {
return {
shouldShowAlert: true,
shouldPlaySound: true,
shouldSetBadge: true,
};
},
});
const updateNovelDetails = async (novel, novelId) => {
db.transaction((tx) => {
tx.executeSql(
"UPDATE novels SET novelName = ?, novelCover = ?, novelSummary = ?, author = ?, artist = ?, genre = ?, status = ? WHERE novelId = ?",
[
novel.novelName,
novel.novelCover,
novel.novelSummary,
novel.author,
novel.artist,
novel.genre,
novel.status,
novelId,
],
(txObj, res) => {},
(txObj, error) => console.log("Error ", error)
);
});
};
export const updateNovel = async (sourceId, novelUrl, novelId) => {
let novel = await fetchNovel(sourceId, novelUrl);
await updateNovelDetails(novel, novelId);
db.transaction((tx) => {
novel.chapters.map((chapter) =>
tx.executeSql(
"INSERT OR IGNORE INTO chapters (chapterUrl, chapterName, releaseDate, novelId) values (?, ?, ?, ?)",
[
chapter.chapterUrl,
chapter.chapterName,
chapter.releaseDate,
novelId,
],
(txObj, { insertId }) => {
if (insertId !== -1) {
tx.executeSql(
"INSERT OR IGNORE INTO updates (chapterId, novelId, updateTime) values (?, ?, (datetime('now','localtime')))",
[insertId, novelId],
(txObj, res) => {
// console.log(
// "Inserted Chapter Id -> " +
// insertId +
// " Novel Id " +
// novelId
// );
},
(txObj, error) => console.log("Error ", error)
);
}
},
(txObj, error) => console.log("Error ", error)
)
);
});
};
export const updateNovelChapters = async (
sourceId,
novelUrl,
novelId,
updateSettings
) => {
let chapters = await fetchChapters(sourceId, novelUrl);
const { downloadNewChapters = false } = updateSettings;
db.transaction((tx) => {
chapters.map((chapter) =>
tx.executeSql(
"INSERT OR IGNORE INTO chapters (chapterUrl, chapterName, releaseDate, novelId) values (?, ?, ?, ?)",
[
chapter.chapterUrl,
chapter.chapterName,
chapter.releaseDate,
novelId,
],
(txObj, { insertId }) => {
if (insertId !== -1) {
downloadNewChapters &&
downloadChapter(
sourceId,
novelUrl,
chapter.chapterUrl,
insertId
);
tx.executeSql(
"INSERT OR IGNORE INTO updates (chapterId, novelId, updateTime) values (?, ?, (datetime('now','localtime')))",
[insertId, novelId],
(txObj, res) => {},
(txObj, error) => console.log("Error ", error)
);
}
},
(txObj, error) => console.log("Error ", error)
)
);
});
};
const sleep = (time) =>
new Promise((resolve) => setTimeout(() => resolve(), time));
export const updateAllNovels = async (updateSettings) => {
let libraryNovels = await getLibrary();
const { onlyUpdateOngoingNovels = false } = updateSettings;
if (onlyUpdateOngoingNovels) {
libraryNovels = libraryNovels.filter(
(item) => item.status !== "Completed"
);
}
const options = {
taskName: "Library Update",
taskTitle: "Updating library",
taskDesc: "(0/" + libraryNovels.length + ")",
taskIcon: {
name: "notification_icon",
type: "drawable",
},
color: "#00adb5",
parameters: {
delay: 1000,
},
linkingURI: "lnreader://updates",
progressBar: {
max: libraryNovels.length,
value: 0,
},
};
const veryIntensiveTask = async (taskData) =>
await new Promise(async (resolve) => {
for (
let i = 0;
BackgroundService.isRunning() && i < libraryNovels.length;
i++
) {
try {
if (BackgroundService.isRunning()) {
/**
* Update chapters
*/
await updateNovelChapters(
libraryNovels[i].sourceId,
libraryNovels[i].novelUrl,
libraryNovels[i].novelId,
updateSettings
);
/**
* Update notification
*/
await BackgroundService.updateNotification({
taskTitle: libraryNovels[i].novelName,
taskDesc:
"(" +
(i + 1) +
"/" +
libraryNovels.length +
")",
progressBar: {
max: libraryNovels.length,
value: i + 1,
},
});
/**
* When updating library is finished
*/
if (libraryNovels.length === i + 1) {
resolve();
Notifications.scheduleNotificationAsync({
content: {
title: "Library Updated",
body:
libraryNovels.length +
" novels updated",
},
trigger: null,
});
}
const nextNovelIndex = i + 1;
if (
nextNovelIndex in libraryNovels &&
libraryNovels[nextNovelIndex].sourceId ===
libraryNovels[i].sourceId
) {
await sleep(taskData.delay);
}
}
} catch (error) {
showToast(
libraryNovels[i].novelName + ": " + error.message
);
continue;
}
}
});
if (libraryNovels.length > 0) {
await BackgroundService.start(veryIntensiveTask, options);
}
};
export const parseChapterNumber = (chapterName) => {
chapterName = chapterName.toLowerCase();
chapterName = chapterName.replace(/volume (\d+)/, "");
const basic = chapterName.match(/ch (\d+)/);
const occurrence = chapterName.match(/\d+/);
if (basic) {
return basic[0];
} else if (occurrence) {
return occurrence[0];
} else {
return 0;
}
};