Skip to content

Commit

Permalink
Merge pull request #319 from ZIMkaRU/feature/add-support-for-pdf-reports
Browse files Browse the repository at this point in the history
Add support for PDF reports
  • Loading branch information
ezewer authored Feb 20, 2024
2 parents 0d19128 + cc39582 commit 967e074
Show file tree
Hide file tree
Showing 9 changed files with 149 additions and 60 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ bfx-reports-framework/config/*.json
bfx-reports-framework/config/facs/*.json
bfx-reports-framework/logs/*.log
bfx-reports-framework/csv
bfx-reports-framework/report-files
bfx-report-ui/build
bfx-report-ui/bfx-report-express/logs/*.log
bfx-report-ui/bfx-report-express/config/*.json
Expand Down
1 change: 1 addition & 0 deletions electron-builder-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ module.exports = {
'!bfx-reports-framework/*/*.sh',
'!bfx-reports-framework/*.sh',
'!bfx-reports-framework/.mocharc.json',
'!bfx-reports-framework/node_modules/phantomjs-prebuilt',

'!**/.dockerignore',
'!**/*Dockerfile*',
Expand Down
18 changes: 11 additions & 7 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const {

const {
WrongPathToUserDataError,
WrongPathToUserCsvError,
WrongPathToUserReportFilesError,
WrongSecretKeyError
} = require('./src/errors')

Expand Down Expand Up @@ -76,7 +76,9 @@ const allowedProcessMessagesSet = _getAllowedStatesSet({

'RESPONSE_GET_BACKUP_FILES_METADATA',

'RESPONSE_UPDATE_USERS_SYNC_ON_STARTUP_REQUIRED_STATE'
'RESPONSE_UPDATE_USERS_SYNC_ON_STARTUP_REQUIRED_STATE',

'REQUEST_PDF_CREATION'
]
})
const allowedProcessStatesSet = _getAllowedStatesSet({
Expand All @@ -92,14 +94,16 @@ const allowedProcessStatesSet = _getAllowedStatesSet({

'REQUEST_GET_BACKUP_FILES_METADATA',

'REQUEST_UPDATE_USERS_SYNC_ON_STARTUP_REQUIRED_STATE'
'REQUEST_UPDATE_USERS_SYNC_ON_STARTUP_REQUIRED_STATE',

'RESPONSE_PDF_CREATION'
]
})

;(async () => {
try {
const pathToUserData = process.env.PATH_TO_USER_DATA
const pathToUserCsv = process.env.PATH_TO_USER_CSV
const pathToUserReportFiles = process.env.PATH_TO_USER_REPORT_FILES
const schedulerRule = process.env.SCHEDULER_RULE
const secretKey = process.env.SECRET_KEY
const grape1DhtPort = process.env.GRAPE_1DHT_PORT
Expand All @@ -116,8 +120,8 @@ const allowedProcessStatesSet = _getAllowedStatesSet({
if (!pathToUserData) {
throw new WrongPathToUserDataError()
}
if (!pathToUserCsv) {
throw new WrongPathToUserCsvError()
if (!pathToUserReportFiles) {
throw new WrongPathToUserReportFilesError()
}

const grape = `http://127.0.0.1:${grape2ApiPort}`
Expand Down Expand Up @@ -162,7 +166,7 @@ const allowedProcessStatesSet = _getAllowedStatesSet({
'--isSchedulerEnabled=true',
'--isElectronjsEnv=true',
'--isLoggerDisabled=false',
`--csvFolder=${pathToUserCsv}`,
`--reportFolder=${pathToUserReportFiles}`,
`--tempFolder=${pathToUserData}/temp`,
`--logsFolder=${pathToUserData}/logs`,
`--dbFolder=${pathToUserData}`,
Expand Down
6 changes: 3 additions & 3 deletions src/change-reports-folder.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

const { dialog, BrowserWindow } = require('electron')

const { CSV_PATH_VERSION } = require('./const')
const { REPORT_FILES_PATH_VERSION } = require('./const')

const {
InvalidFilePathError,
Expand Down Expand Up @@ -52,8 +52,8 @@ module.exports = ({ pathToUserDocuments }) => {
await pauseApp()
const isSaved = await getConfigsKeeperByName('main')
.saveConfigs({
csvPathVersion: CSV_PATH_VERSION,
pathToUserCsv: filePaths[0]
reportFilesPathVersion: REPORT_FILES_PATH_VERSION,
pathToUserReportFiles: filePaths[0]
})

if (!isSaved) {
Expand Down
4 changes: 2 additions & 2 deletions src/const.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const DB_FILE_NAME = 'db-sqlite_sync_m0.db'
const DB_SHM_FILE_NAME = `${DB_FILE_NAME}-shm`
const DB_WAL_FILE_NAME = `${DB_FILE_NAME}-wal`
const SECRET_KEY_FILE_NAME = 'secret-key'
const CSV_PATH_VERSION = 1
const REPORT_FILES_PATH_VERSION = 1

module.exports = {
CONFIGS_FILE_NAME,
Expand All @@ -15,5 +15,5 @@ module.exports = {
DB_SHM_FILE_NAME,
DB_WAL_FILE_NAME,
SECRET_KEY_FILE_NAME,
CSV_PATH_VERSION
REPORT_FILES_PATH_VERSION
}
6 changes: 3 additions & 3 deletions src/errors/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ class WrongPathToUserDataError extends BaseError {
}
}

class WrongPathToUserCsvError extends BaseError {
constructor (message = 'ERR_WRONG_PATH_TO_USER_CSV') {
class WrongPathToUserReportFilesError extends BaseError {
constructor (message = 'ERR_WRONG_PATH_TO_USER_REPORT_FILES') {
super(message)
}
}
Expand Down Expand Up @@ -124,7 +124,7 @@ module.exports = {
AppInitializationError,
FreePortError,
WrongPathToUserDataError,
WrongPathToUserCsvError,
WrongPathToUserReportFilesError,
WrongSecretKeyError,
ReportsFolderChangingError,
SyncFrequencyChangingError,
Expand Down
60 changes: 17 additions & 43 deletions src/initialize-app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
const { app } = require('electron')
const path = require('path')

const { CSV_PATH_VERSION } = require('./const')
const { REPORT_FILES_PATH_VERSION } = require('./const')

const triggerSyncAfterUpdates = require('./trigger-sync-after-updates')
const triggerElectronLoad = require('./trigger-electron-load')
Expand Down Expand Up @@ -41,6 +41,7 @@ const enforceMacOSAppLocation = require(
const manageWorkerMessages = require(
'./manage-worker-messages'
)
const printToPDF = require('./print-to-pdf')

const pathToLayouts = path.join(__dirname, 'layouts')
const pathToLayoutAppInitErr = path
Expand All @@ -50,52 +51,26 @@ const { rule: schedulerRule } = require(
'../bfx-reports-framework/config/schedule.json'
)

const _resetCsvPath = async (
const _resetReportFilesPath = async (
configsKeeper,
opts = {}
) => {
const {
pathToUserCsv,
isRelativeCsvPath
pathToUserReportFiles
} = opts

// Need to use a new csv folder path for export
const storedPathToUserCsv = configsKeeper
.getConfigByName('pathToUserCsv')
const csvPathVersion = configsKeeper
.getConfigByName('csvPathVersion')

if (csvPathVersion === CSV_PATH_VERSION) {
return
}
if (
(
isRelativeCsvPath &&
!storedPathToUserCsv.endsWith('csv')
) ||
(
!isRelativeCsvPath &&
!storedPathToUserCsv.endsWith('bitfinex/reports')
) ||
(
!isRelativeCsvPath &&
!path.isAbsolute(storedPathToUserCsv)
) ||
(
isRelativeCsvPath &&
path.isAbsolute(storedPathToUserCsv)
)
) {
await configsKeeper.saveConfigs({
csvPathVersion: CSV_PATH_VERSION,
pathToUserCsv
})
// Need to use a new report folder path for export
const reportFilesPathVersion = configsKeeper
.getConfigByName('reportFilesPathVersion') ??
configsKeeper.getConfigByName('csvPathVersion') // For back compatibility

if (reportFilesPathVersion === REPORT_FILES_PATH_VERSION) {
return
}

await configsKeeper.saveConfigs({
csvPathVersion: CSV_PATH_VERSION
reportFilesPathVersion: REPORT_FILES_PATH_VERSION,
pathToUserReportFiles
})
}

Expand Down Expand Up @@ -153,26 +128,23 @@ const _manageConfigs = (params = {}) => {
pathToUserDocuments
} = params

const pathToUserCsv = path.join(
const pathToUserReportFiles = path.join(
pathToUserDocuments,
'bitfinex/reports'
)

const configsKeeper = configsKeeperFactory(
{ pathToUserData },
{
pathToUserCsv,
pathToUserReportFiles,
schedulerRule,
shownChangelogVer: '0.0.0',
triggeredSyncAfterUpdatesVer: '0.0.0'
}
)
_resetCsvPath(
_resetReportFilesPath(
configsKeeper,
{
pathToUserCsv,
isRelativeCsvPath: true
}
{ pathToUserReportFiles }
)
}

Expand Down Expand Up @@ -222,6 +194,8 @@ module.exports = async () => {
await triggerElectronLoad(portsMap)
await checkForUpdatesAndNotify()
await manageChangelog()

printToPDF()
} catch (err) {
await createErrorWindow(pathToLayoutAppInitErr)

Expand Down
109 changes: 109 additions & 0 deletions src/print-to-pdf/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
'use strict'

const { BrowserWindow } = require('electron')
const fs = require('fs/promises')
const path = require('path')

const ipcs = require('../ipcs')
const wins = require('../windows')

const PROCESS_MESSAGES = require(
'../../bfx-reports-framework/workers/loc.api/process.message.manager/process.messages'
)
const PROCESS_STATES = require(
'../../bfx-reports-framework/workers/loc.api/process.message.manager/process.states'
)

module.exports = () => {
ipcs.serverIpc.on('message', async (mess) => {
try {
if (mess?.state !== PROCESS_MESSAGES.REQUEST_PDF_CREATION) {
return
}

const {
templateFilePath,
template = 'No data',
format = 'portrait',
orientation = 'Letter',
uid = null
} = mess?.data ?? {}

const isTemplateFilePathUsed = (
templateFilePath &&
typeof templateFilePath === 'string'
)

const html = isTemplateFilePathUsed
? await fs.readFile(templateFilePath, { encoding: 'utf8' })
: template

if (isTemplateFilePathUsed) {
await fs.rm(templateFilePath, { force: true, maxRetries: 3 })
}

const win = new BrowserWindow({
show: false,
parent: wins.mainWindow,
webPreferences: {
nodeIntegration: true
}
})
win.loadURL(`data:text/html;charset=utf-8,${encodeURIComponent(html)}`)

await new Promise((resolve, reject) => {
win.webContents.on('did-finish-load', resolve)
win.webContents.on('did-fail-load', (e, code, err) => {
reject(err)
})
})
const buffer = await win.webContents.printToPDF({
landscape: format !== 'portrait',
pageSize: orientation,
margins: {
top: 0,
bottom: 0,
left: 0,
right: 0
},
displayHeaderFooter: true,
footerTemplate: `\
<span style="
position: absolute;
right: 10px;
bottom: 10px;
font-weight: 400;
font-size: 8px;
">
Page <span class=pageNumber></span> from <span class=totalPages></span>
</span>`
})

if (isTemplateFilePathUsed) {
const { dir, name } = path.parse(templateFilePath)
const pdfFilePath = path.format({ dir, name, ext: '.pdf' })

await fs.writeFile(pdfFilePath, buffer)

ipcs.serverIpc.send({
state: PROCESS_STATES.RESPONSE_PDF_CREATION,
data: { pdfFilePath, uid }
})

return
}

ipcs.serverIpc.send({
state: PROCESS_STATES.RESPONSE_PDF_CREATION,
data: { buffer, uid }
})
} catch (err) {
ipcs.serverIpc.send({
state: PROCESS_STATES.RESPONSE_PDF_CREATION,
data: { err, uid: mess?.data?.uid ?? null }
})

console.error(err)
}
})
}
4 changes: 2 additions & 2 deletions src/run-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ module.exports = ({
const env = {
...process.env,
PATH_TO_USER_DATA: pathToUserData,
PATH_TO_USER_CSV: mainConfsKeeper
.getConfigByName('pathToUserCsv'),
PATH_TO_USER_REPORT_FILES: mainConfsKeeper
.getConfigByName('pathToUserReportFiles'),
SCHEDULER_RULE: mainConfsKeeper
.getConfigByName('schedulerRule'),
SECRET_KEY: secretKey,
Expand Down

0 comments on commit 967e074

Please sign in to comment.