diff --git a/src/components/Settings.js b/src/components/Settings.js
index d9ccf71..2ce4e06 100644
--- a/src/components/Settings.js
+++ b/src/components/Settings.js
@@ -19,6 +19,7 @@ import ExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary";
import ExpansionPanelDetails from "@material-ui/core/ExpansionPanelDetails";
import Typography from "@material-ui/core/Typography";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
+import * as auto_export from "../util/auto_export";
const numberFormat = require("../util/getNumberFormat")
const { dialog, getCurrentWindow } = require('electron').remote;
@@ -47,7 +48,8 @@ class SettingsModal extends React.Component {
langCodeValue: "",
langCode: "",
langVersion: "",
- folderPath: ""
+ folderPath: "",
+ backupFrequency: ""
},
refSetting: {
bibleName: "",
@@ -116,10 +118,14 @@ class SettingsModal extends React.Component {
settingData.langCode = doc.targetLang;
settingData.langCodeValue = doc.targetLang;
settingData.langVersion = doc.targetVersion;
- settingData.folderPath = doc.targetPath;
- }, (err) => {
+ settingData.folderPath = doc.targetPath;
+ settingData.backupFrequency = (doc.backupFrequency) === undefined ? "daily" : doc.backupFrequency;
+ if (settingData.langCodeValue && settingData.langVersion && settingData.backupFrequency !== "none") {
+ auto_export.initializeBackUp();
+ }
+ }, (err) => {
// console.log(err);
- });
+ });
}
loadReference = () => {
@@ -241,14 +247,15 @@ class SettingsModal extends React.Component {
saveSetting = () => {
if (this.target_setting() === false) return;
- const currentTrans = AutographaStore.currentTrans;
- const {langCode, langVersion, folderPath} = this.state.settingData;
+ const currentTrans = AutographaStore.currentTrans;
+ const {langCode, langVersion, folderPath, backupFrequency} = this.state.settingData;
const settingData = {
_id: 'targetBible',
targetLang: langCode.toLowerCase(),
targetVersion: langVersion,
targetPath: folderPath,
- langScript: AutographaStore.scriptDirection.toUpperCase()
+ langScript: AutographaStore.scriptDirection.toUpperCase(),
+ backupFrequency: backupFrequency
}
db.get('targetBible').then((doc) => {
settingData._rev = doc._rev;
@@ -261,7 +268,11 @@ class SettingsModal extends React.Component {
}, (err) => {
swal(currentTrans["dynamic-msg-trans-data"], currentTrans["dynamic-msg-went-wrong"], "success");
});
- });
+ });
+
+ if (langCode && langVersion && backupFrequency !== "none") {
+ auto_export.initializeBackUp();
+ }
}
openFileDialogSettingData = (event) => {
@@ -752,6 +763,9 @@ class SettingsModal extends React.Component {
onChangeScriptDir = (value) => {
AutographaStore.scriptDirection = value;
+ }
+ onChangeBackupSetting = (value) => {
+ this.setState({ settingData: { ...this.state.settingData, backupFrequency: value} });
}
onChangeRefScriptDir = (value) => {
AutographaStore.refScriptDirection = value;
@@ -945,7 +959,7 @@ class SettingsModal extends React.Component {
let closeSetting = () => AutographaStore.showModalSettings = false
const { show } = this.props;
- const { langCodeValue, langVersion, folderPath } = this.state.settingData;
+ const { langCodeValue, langVersion, folderPath, backupFrequency } = this.state.settingData;
const { bibleName, refVersion, refLangCode, refFolderPath } = this.state.refSetting;
const listCode = this.state._listArray;
@@ -1057,7 +1071,7 @@ class SettingsModal extends React.Component {
}
-
+
+
+
+ this.onChangeBackupSetting(value)}
+ >
+ }
+ style={{width: "70%"}}
+ />
+ }
+ style={{width: "70%", marginLeft: "25px"}}
+ />
+ }
+ style={{width: "70%", marginLeft: "25px"}}
+ />
+
+
+
{ (message)=>
{
+ try {
+ // Initial Backup call
+ backUp();
+ const delay = 60000 * 60; // 60 minutes/1 hour
+ setInterval(async () => {
+ backUp();
+ }, delay);
+ } catch(e) {
+ console.log(e);
+ }
+}
+
+async function backUp() {
+ let targetLangDoc = await db.get('targetBible');
+ const outputPath = targetLangDoc.targetPath;
+ const directory = path.join(Array.isArray(outputPath) ? outputPath[0] : outputPath,"auto-backup");
+ const nameElements = [
+ targetLangDoc && targetLangDoc.targetLang,
+ targetLangDoc && targetLangDoc.targetVersion
+ ].filter(Boolean);
+ const foldername = nameElements.join("_");
+ const dirPath = path.join(directory, foldername);
+ if (!fs.existsSync(dirPath)){
+ fs.mkdirSync(dirPath, { recursive: true });
+ }
+ await fs.readdir(dirPath, (err, folders) => {
+ if (folders.length >= 1) {
+ let folderName = (folders[(folders.length)-1]).split('_');
+ var d = new Date();
+ let timeStamp = [ d && getTimeStamp(d) ].filter(Boolean);
+ let currentTime = timeStamp[0].split('_');
+ let days = calculateDays(currentTime,folderName);
+ if (days >= 1 && (targetLangDoc.backupFrequency).toLowerCase() === "daily") {
+ buildFilePath(new Date(), dirPath);
+ folderHandling (folders, dirPath);
+ } else if (days >= 7 && (targetLangDoc.backupFrequency).toLowerCase() === "weekly") {
+ buildFilePath(new Date(), dirPath);
+ folderHandling (folders, dirPath);
+ } else {
+ return null;
+ }
+
+ } else {
+ buildFilePath(new Date(), dirPath);
+ }
+ });
+}
+
+async function exportAllBooks(dir) {
+ let doc = await db.get('targetBible');
+ constants.bookCodeList.forEach(async(value, index) => {
+ let book={};
+ book.bookNumber = (index+1).toString();
+ book.bookName = AutographaStore.editBookNamesMode ? AutographaStore.translatedBookNames[index] : constants.booksList[index];
+ book.bookCode = value;
+ book.outputPath = doc.targetPath;
+ await toUsfm(book, dir);
+ })
+}
+
+export const toUsfm = async (book, dir) => {
+ const usfmDoc = await toUsfmDoc(book, false);
+ const filename = (book.bookCode) + '.usfm';
+ const filePath = path.join(dir, filename);
+ writeUsfm(usfmDoc, filePath);
+};
+
+async function toUsfmDoc(book, returnNullForEmptyBook=false) {
+ try {
+ const usfmContent = [];
+ var isEmpty = true;
+ usfmContent.push('\\id ' + book.bookCode);
+ usfmContent.push('\\mt ' + book.bookName);
+ const doc = await db.get(book.bookNumber);
+ for (const chapter of doc.chapters) {
+ usfmContent.push('\n\\c ' + chapter.chapter);
+ usfmContent.push('\\p');
+ let i = 0;
+ let verseNumber;
+ let verses;
+ for (const verse of chapter.verses) {
+ i = i + 1;
+ if (i < (chapter.verses).length && chapter.verses[i].joint_verse) {
+ // Finding out the join verses and get their verse number(s)
+ verseNumber = chapter.verses[i].joint_verse + "-" + chapter.verses[i].verse_number;
+ verses = chapter.verses[(chapter.verses[i].joint_verse)-1].verse;
+ continue;
+ } else {
+ if (verseNumber) {
+ // Push join verse number (1-3) and content.
+ let newVerse = addMtag(verses);
+ usfmContent.push('\\v ' + verseNumber + ' ' + newVerse);
+ verseNumber = undefined;
+ verses = undefined;
+ } else {
+ // Push verse number and content.
+ let newVerse = addMtag(verse.verse);
+ usfmContent.push('\\v ' + verse.verse_number + ' ' + newVerse);
+ }
+ isEmpty = isEmpty && !verse.verse;
+ }
+ }
+ }
+ return (returnNullForEmptyBook && isEmpty)
+ ? null
+ : usfmContent.join('\n');
+ } catch(err) {
+ console.log(err);
+ }
+}
+
+function addMtag(verses) {
+ let newVerse = verses;
+ if(verses.indexOf('\n') !== -1 ){
+ newVerse = verses.trim().replace(new RegExp(/[\n\r]/, 'gu'), '\n\\m ')
+ verses = newVerse
+ }
+ return newVerse;
+}
+
+async function buildFilePath(date, dirPath) {
+ const dateElement = [ date && getTimeStamp(date) ].filter(Boolean);
+ const dir = path.join(dirPath, dateElement[0]);
+ if (!fs.existsSync(dir)){
+ fs.mkdirSync(dir, { recursive: true });
+ }
+ exportAllBooks(dir);
+}
+
+function folderHandling (folders, dirPath) {
+ if (folders.length >= 5) {
+ var files = fs.readdirSync(path.join(dirPath, folders[0]));
+ files.forEach(file => {
+ fs.unlinkSync(path.join(dirPath, folders[0], file));
+ });
+ fs.rmdir(path.join(dirPath, folders[0]), function(err, result) {
+ if(err) console.log('error', err);
+ });
+ }
+}
+
+function writeUsfm(usfmDoc, filePath) {
+ if (usfmDoc && filePath) {
+ fs.writeFileSync(filePath, usfmDoc, 'utf8', function(err, result) {
+ if(err) console.log('error', err);
+ });
+ }
+}
+
+function getTimeStamp(date) {
+ var months = ["January","February","March","April","May","June","July","August","September","October","November","December"];
+ var year = date.getFullYear(),
+ month = ((date.getMonth() + 1) < 10 ? '0' : '') + (date.getMonth() + 1),
+ day = (date.getDate() < 10 ? '0' : '') + date.getDate(),
+ hour = (date.getHours() < 10 ? '0' : '') + date.getHours(),
+ minute = (date.getMinutes() < 10 ? '0' : '') + date.getMinutes(),
+ second = (date.getSeconds() < 10 ? '0' : '') + date.getSeconds();
+
+ return (months[parseInt(month)-1] + " " + day + "-" + year.toString() + "_" + hour + ":" + minute + ":" + second).toString();
+}
+
+function calculateDays(currDate, preDate)
+ {
+ var currTime = new Date(currDate[0] + " " + currDate[1]);
+ var preTime = new Date(preDate[0] + " " + preDate[1]);
+ var difference = Math.abs(currTime.getTime() - preTime.getTime()) / 1000;
+ // var hour = Math.floor(difference / 3600) % 24;
+ // var minutes = Math.floor(difference / 60) % 60;
+ var days = Math.floor(difference / 86400);
+ return days;
+ }