Browse Source

Build & Electron refactoring.

tags/v1.4.4
Ivan Bravo Bravo 11 months ago
parent
commit
9fe79f333e
37 changed files with 828 additions and 765 deletions
  1. 39
    0
      src/.babelrc
  2. 0
    7
      src/.env
  3. 17
    0
      src/.env-cmdrc.js
  4. 2
    1
      src/.eslintrc.js
  5. 3
    0
      src/.gitignore
  6. 16
    3
      src/.vscode/launch.json
  7. 60
    8
      src/.vscode/tasks.json
  8. 2
    0
      src/components/Nudity/Upload.vue
  9. 2
    3
      src/components/UI/AppUpdate.vue
  10. 0
    6
      src/electron/scripts/index.js
  11. 0
    236
      src/electron/scripts/tools/index.js
  12. 0
    114
      src/electron/scripts/tools/paths.js
  13. 0
    80
      src/electron/scripts/tools/shell.js
  14. 85
    68
      src/electron/src/index.js
  15. 3
    4
      src/electron/src/preload.js
  16. 35
    25
      src/electron/src/scripts/error.js
  17. 10
    0
      src/electron/src/scripts/index.js
  18. 6
    9
      src/electron/src/scripts/services/base.js
  19. 12
    0
      src/electron/src/scripts/services/index.js
  20. 9
    9
      src/electron/src/scripts/services/nucleus.js
  21. 42
    15
      src/electron/src/scripts/services/rollbar.js
  22. 13
    16
      src/electron/src/scripts/services/settings.js
  23. 60
    127
      src/electron/src/scripts/tools/fs.js
  24. 6
    8
      src/electron/src/scripts/tools/index.js
  25. 154
    0
      src/electron/src/scripts/tools/nudify.js
  26. 92
    0
      src/electron/src/scripts/tools/paths.js
  27. 56
    0
      src/electron/src/scripts/tools/photo.js
  28. 39
    0
      src/electron/src/scripts/tools/shell.js
  29. 4
    6
      src/electron/src/scripts/tools/system.js
  30. 13
    0
      src/jsconfig.json
  31. 5
    2
      src/modules/file.js
  32. 2
    2
      src/modules/models/photo-job.js
  33. 3
    1
      src/modules/models/photo.js
  34. 2
    0
      src/modules/web-error.js
  35. 2
    3
      src/nuxt.config.js
  36. 32
    12
      src/package.json
  37. 2
    0
      src/plugins/boot.client.js

+ 39
- 0
src/.babelrc View File

@@ -0,0 +1,39 @@
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": "10",
"electron": "7"
}
}
]
],
"plugins": [
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-export-default-from",
"@babel/plugin-proposal-optional-chaining",
[
"transform-inline-environment-variables",
{
"exclude": [
"LOG",
"DEVTOOLS"
]
}
],
[
"module-resolver",
{
"root": [
"./"
],
"alias": {
"~": "./",
"test": "./test"
}
}
]
]
}

+ 0
- 7
src/.env View File

@@ -1,7 +0,0 @@
APP_NAME = DreamTime
APP_VERSION = 1.1.2

SERVER_PORT = 3000
SERVER_HOST = localhost

NUCLEUS_APPID = 5d353cecbe5ccc0133cf90f4

+ 17
- 0
src/.env-cmdrc.js View File

@@ -0,0 +1,17 @@
module.exports = {
"default": {
"SERVER_HOST": "localhost",
"SERVER_PORT": 3000,
"NUCLEUS_APPID": "5d353cecbe5ccc0133cf90f4",
"ROLLBAR_ACCESS_TOKEN": "fa7961b1490d4bcdbff1cda0991529b3"
},
"development": {
"NODE_ENV": "development",
"LOG": "debug",
"DEVTOOLS": true
},
"production": {
"NODE_ENV": "production",
"LOG": "info"
}
}

+ 2
- 1
src/.eslintrc.js View File

@@ -40,9 +40,10 @@ module.exports = {
"import/no-webpack-loader-syntax": "off",
"import/order": "error",
"import/prefer-default-export": "off",
"import/no-extraneous-dependencies": "off",
"linebreak-style": "warn",
"lodash/import-scope": [
"warn",
"off",
"member"
],
"lodash/prefer-constant": "off",

+ 3
- 0
src/.gitignore View File

@@ -69,6 +69,9 @@ typings/
# Nuxt generate
dist

# Electron dist
electron/dist

# vuepress build output
.vuepress/dist


+ 16
- 3
src/.vscode/launch.json View File

@@ -4,15 +4,28 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"name": "electron",
"port": 9222,
"preLaunchTask": "start",
"postDebugTask": "kill",
"skipFiles": [
"<node_internals>/**"
]
},
{
"type": "node",
"request": "launch",
"name": "client: electron",
"name": "electron: launch",
"cwd": "${workspaceRoot}",
"preLaunchTask": "nuxt",
"postDebugTask": "nuxt-kill",
"outputCapture": "std",
"preLaunchTask": "start:nuxt",
"postDebugTask": "kill",
"env": {
"NODE_ENV": "development",
"LOG": "debug",
"DEVTOOLS": "true"
},
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",

+ 60
- 8
src/.vscode/tasks.json View File

@@ -4,27 +4,79 @@
"version": "2.0.0",
"tasks": [
{
"label": "nuxt",
"type": "shell",
"command": "yarn dev:nuxt",
"label": "start:nuxt",
"type": "npm",
"script": "start:nuxt",
"group": "build",
"isBackground": true,
"presentation": {
"reveal": "always",
"clear": true,
"group": "build"
},
"problemMatcher": {
"owner": "nuxt",
"base": "$eslint-stylish",
"background": {
"activeOnStart": true,
"beginsPattern": "Updated",
"endsPattern": "Compiled successfully in",
}
}
},
{
"label": "start:babel",
"type": "npm",
"script": "start:babel",
"group": "build",
"isBackground": true,
"presentation": {
"reveal": "always",
"clear": true,
"group": "build"
},
"problemMatcher": {
"owner": "custom",
"fileLocation": "relative",
"pattern": {
"regexp": "ERROR"
},
"background": {
"activeOnStart": false,
"beginsPattern": "Listening",
"endsPattern": "Compiled successfully in"
"activeOnStart": true,
"beginsPattern": "->",
"endsPattern": "Successfully compiled"
}
}
},
{
"label": "nuxt-kill",
"label": "start:electron",
"type": "npm",
"script": "start:electron",
"isBackground": true,
"presentation": {
"reveal": "silent",
"clear": true
}
},
{
"label": "kill",
"type": "process",
"command": "${command:workbench.action.terminal.kill}"
},
{
"label": "build",
"dependsOn": [
"start:nuxt",
"start:babel"
],
"dependsOrder": "parallel",
},
{
"label": "start",
"dependsOn": [
"build",
"start:electron"
],
"dependsOrder": "parallel"
}
]
}

+ 2
- 0
src/components/Nudity/Upload.vue View File

@@ -81,6 +81,8 @@
</template>

<script>
/* eslint-disable no-param-reassign */
// eslint-disable-next-line lodash/import-scope
import _ from 'lodash'
import swal from 'sweetalert'
import { Photo } from '~/modules/models'

+ 2
- 3
src/components/UI/AppUpdate.vue View File

@@ -51,9 +51,8 @@
export default {
filters: {
progress(value) {
value = (value * 100).toFixed(2)
// value = Math.round(value * 100)
return `${value}%`
const progress = (value * 100).toFixed(2)
return `${progress}%`
},

size(value) {

+ 0
- 6
src/electron/scripts/index.js View File

@@ -1,6 +0,0 @@
const { AppError } = require('./error')

/* eslint-disable global-require */
module.exports = {
AppError,
}

+ 0
- 236
src/electron/scripts/tools/index.js View File

@@ -1,236 +0,0 @@
const _ = require('lodash')
const fs = require('fs')
const { spawn } = require('child_process')
const EventBus = require('js-event-bus')
const gpuInfo = require('gpu-info')
const utils = require('electron-utils')
const deferred = require('deferred')
const semverRegex = require('semver-regex')

const debug = require('debug').default('app:electron:tools')
const { Image } = require('image-js')
// const { Caman } = require('caman')

const paths = require('./paths')
const { system } = require('./system')

/**
* deepTools.
* Offers a communication channel between the GUI and NodeJS to interact with operating system tools
*/
module.exports = {
/**
*
*/
testError() {
Error('tools error!')
},

/**
* Returns a list with information of the graphic cards installed in the computer.
*/
async getGpusList() {
const devices = await gpuInfo()
return _.filter(devices, { AdapterCompatibility: 'NVIDIA' })
},

/**
* This is probably not a good cropper, but it's all I have now...
*
* @param {Photo} photo
* @param {HTMLCanvasElement} canvas
*/
async crop(photo, canvas) {
const image = Image.fromCanvas(canvas)
const savePath = photo.getCroppedFile().getPath()

debug(`Saving cropped photo in ${savePath}`)
await image.save(savePath)

if (!fs.existsSync(savePath)) {
console.warn(
'It seems that the first crop method has failed, trying the legacy method',
)

await this.legacyCrop(photo, canvas)
} else {
photo.getCroppedFile().reload()
}
},

/**
*
* @param {*} photo
* @param {*} canvas
*/
async legacyCrop(photo, canvas) {
const canvasAsDataURL = canvas.toDataURL(
photo.getSourceFile().getMimetype(),
1,
)

await photo.getCroppedFile().writeDataURL(canvasAsDataURL)

if (!fs.existsSync(photo.getCroppedFile().getPath())) {
throw new Error(
'There was a problem trying to save the cropped photo. Please make sure the program has write permissions.',
)
}
},

/**
*
* @param {*} job
*/
transform(job) {
// Independent preferences for the photo
const { preferences } = job

// input
const photoFilepath = job.photo.file.getPath()

// output
const outputFilepath = job.file.getPath()

// CLI Args
const args = ['run', '--input', photoFilepath, '--output', outputFilepath]

if ($settings.processing.usePython) {
// use python script
args.unshift('main.py')
}

// Device preferences
if ($settings.processing.device === 'CPU') {
args.push('--cpu', '--n-cores', $settings.processing.cores)
} else {
for (const id of $settings.processing.gpus) {
args.push('--gpu', id)
}
}

// Advanced preferences
const { scaleMode, useColorTransfer } = preferences.advanced

if (scaleMode === 'cropjs') {
const { crop } = job.photo
args.push('--overlay', `${crop.startX},${crop.startY}:${crop.endX},${crop.endY}`)
} else if (scaleMode !== 'none') {
args.push(`--${scaleMode}`)
}

if (useColorTransfer) {
args.push('--color-transfer')
}

// Body preferences
args.push('--bsize', preferences.body.boobs.size)
args.push('--asize', preferences.body.areola.size)
args.push('--nsize', preferences.body.nipple.size)
args.push('--vsize', preferences.body.vagina.size)
args.push('--hsize', preferences.body.pubicHair.size)

debug('The transformation process has begun!', {
input: photoFilepath,
output: outputFilepath,
preferences,
args,
job,
})

let process
const bus = new EventBus()

if ($settings.processing.usePython) {
// python script
process = spawn('python3', args, {
cwd: paths.getCli(),
})
} else {
process = spawn(paths.getCli('dreampower'), args, {
cwd: paths.getCli(),
})
}

process.on('error', (error) => {
console.error(error)
bus.emit('error', null, error)
})

process.stdout.on('data', (data) => {
console.info(`stdout: ${data}`)
bus.emit('stdout', null, data)
})

process.stderr.on('data', (data) => {
console.warn(`stderr: ${data}`)
bus.emit('stderr', null, data)
})

process.on('close', (code) => {
console.log(`CLI process exited with code ${code}`)
bus.emit('ready', null, code)
})

bus.on('kill', () => {
process.stdin.pause()
process.kill()
})

return bus
},

getPowerVersion() {
const def = deferred()

let process
let response = ''

if ($settings.processing.usePython) {
// python script
process = spawn('python3', ['main.py', '--version'], {
cwd: paths.getCli(),
})
} else {
process = spawn(paths.getCli('dreampower'), ['--version'])
}

process.on('error', () => {
def.resolve('')
})

process.stdout.on('data', (data) => {
response += data
})

process.on('close', () => {
response = semverRegex().exec(response)
response = `v${response[0]}`

def.resolve(response)
})

return def.promise
},

//
// eslint-disable-next-line global-require
fs: require('./fs'),

//
// eslint-disable-next-line global-require
shell: require('./shell'),

//
paths,

/**
*
*/
utils,

/**
*
*/
system,
}

+ 0
- 114
src/electron/scripts/tools/paths.js View File

@@ -1,114 +0,0 @@
/*
* DreamTime | (C) 2019 by Ivan Bravo Bravo <ivan@dreamnet.tech>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License 3.0 as published by
* the Free Software Foundation.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

const fs = require('fs')
const path = require('path')
const utils = require('electron-utils')

module.exports = {
/**
* Returns an absolute path depending on the parameters
*
* @param {string} name Name of the base path: https://electronjs.org/docs/all#appgetpathname
* @param {string} args Series of path segments to join into one path
*/
get(name, ...args) {
const { app } = utils.api
const folderPath = app.getPath(name)

return path.join(folderPath, ...args)
},

/**
*
* @param {...any} args
*/
getGui(...args) {
if (process.platform === 'darwin') {
// /Applications/DreamTime.app/Contents/MacOS/DreamTime
// /Applications/DreamTime.app/Contents
return this.get('exe', '..', '..', ...args)
}

return this.get('exe', '..', ...args)
},

/**
* @param {...any} args
*/
getGuiResources(...args) {
if (process.platform === 'darwin') {
return this.getGui('Resources', ...args)
}

return this.getGui('resources', ...args)
},

/**
*
* @param {...any} args
*/
getCli(...args) {
let folder = $settings.folders.cli

if (!fs.existsSync(folder)) {
folder = this.get('userData', 'dreampower')
}

return path.join(folder, ...args)
},

/**
*
* @param {...any} args
*/
getCheckpoints(...args) {
return this.getCli('checkpoints', ...args)
},

getCropped(...args) {
let folder = $settings.folders.cropped

if (!fs.existsSync(folder)) {
folder = this.get('temp')
}

return path.join(folder, ...args)
},

getModels(...args) {
let folder = $settings.folders.models

if (!fs.existsSync(folder)) {
folder = this.get('userData', 'models')
}

if (!fs.existsSync(folder)) {
folder = this.get('temp')
}

return path.join(folder, ...args)
},

getMasks(...args) {
let folder = $settings.folders.masks

if (!fs.existsSync(folder)) {
folder = this.get('userData', 'masks')
}

if (!fs.existsSync(folder)) {
folder = this.get('temp')
}

return path.join(folder, ...args)
},
}

+ 0
- 80
src/electron/scripts/tools/shell.js View File

@@ -1,80 +0,0 @@
const _ = require('lodash')
const { api, is } = require('electron-utils')
const regedit = require('regedit')
const paths = require('./paths')

// const { download } = require('electron-dl')

module.exports = {
/**
* Open the given file in the desktop's default manner.
* https://electronjs.org/docs/api/shell#shellopenitemfullpath
*
* @param {string} fullPath
*/
openItem(fullPath) {
return api.shell.openItem(fullPath)
},

/**
* Open the given external protocol URL in the desktop's default manner. (For example, mailto: URLs in the user's default mail agent).
* https://electronjs.org/docs/api/shell#shellopenexternalurl-options
*
* @param {string} url
*/
openExternal(url) {
return api.shell.openExternal(url)
},

/**
*
* @param {...any} args
*/
showOpenDialog(...args) {
return api.dialog.showOpenDialogSync(...args)
},

/**
*
* @param {...any} args
*/
showSaveDialog(...args) {
return api.dialog.showSaveDialogSync(...args)
},

/**
*
*/
showMessageBox(...args) {
return api.dialog.showMessageBox(...args)
},

/**
*
*/
hasWindowsMedia() {
if (is.windows && !is.development) {
regedit.setExternalVBSLocation(
paths.getGuiResources('vbs'),
)
}

return new Promise((resolve) => {
if (!is.windows) {
resolve(true)
return
}

const regKey = 'HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\WindowsFeatures'

regedit.list(regKey, (err, result) => {
if (!_.isNil(err)) {
resolve(false)
return
}

resolve(result[regKey].keys.includes('WindowsMediaVersion'))
})
})
},
}

src/electron/index.js → src/electron/src/index.js View File

@@ -7,41 +7,44 @@
//
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019.

const { app, BrowserWindow } = require('electron')
const http = require('http')
const path = require('path')
const fs = require('fs')
const contextMenu = require('electron-context-menu')
const utils = require('electron-utils')
const logger = require('logplease').create('electron')
import { app, BrowserWindow } from 'electron'
import http from 'http'
import path from 'path'
import fs from 'fs-extra'
import contextMenu from 'electron-context-menu'
import { pack, enforceMacOSAppLocation } from 'electron-utils'

import { AppError } from './scripts'
import { settings, nucleus, rollbar } from './scripts/services'
import { system } from './scripts/tools'
import config from '~/nuxt.config'

const { AppError } = require('./scripts')
const { settings, nucleus, rollbar } = require('./scripts/services')
const { system } = require('./scripts/tools')
const config = require('../nuxt.config')
const logger = require('logplease').create('electron')

// NuxtJS root directory
config.rootDir = path.dirname(__dirname)

// copyright

console.log(`
DreamTime.
Copyright (C) DreamNet. All rights reserved.
DreamTime.
Copyright (C) DreamNet. All rights reserved.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License 3.0 as published by
the Free Software Foundation. See <https://www.gnu.org/licenses/gpl-3.0.html>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License 3.0 as published by
the Free Software Founda
tion. See <https://www.gnu.org/licenses/gpl-3.0.html>
`)

logger.info('Starting...')

logger.debug({
env: process.env.NODE_ENV,
isStatic: pack.isStatic(),
paths: {
appPath: app.getAppPath(),
exePath: app.getPath('exe'),
},
isStatic: utils.pack.isStatic(),
})

class DreamApp {
@@ -62,7 +65,19 @@ class DreamApp {
app.setAppUserModelId(process.execPath)

// https://github.com/sindresorhus/electron-util#enforcemacosapplocation-macos
utils.enforceMacOSAppLocation()
enforceMacOSAppLocation()

app.on('activate', () => {
this.createWindow()
})

app.on('will-quit', async (event) => {
event.preventDefault()

await this.shutdown()

app.exit()
})

// system stats.
await system.setup()
@@ -74,10 +89,10 @@ class DreamApp {
await nucleus.setup()

// bug tracking.
rollbar.setup()
await rollbar.setup()

//
this.createModelsDir()
this.createDirs()

//
contextMenu({
@@ -85,11 +100,18 @@ class DreamApp {
})
}

/**
*
*/
static async shutdown() {
await rollbar.shutdown()
}

/**
* Create the program window and load the interface
*/
static createWindow() {
// Create the browser window.
// browser window.
this.window = new BrowserWindow({
width: 1200,
height: 700,
@@ -97,27 +119,26 @@ class DreamApp {
minHeight: 700,
icon: path.join(config.rootDir, 'dist', 'icon.ico'),
webPreferences: {
// Script that offers secure communication to the NodeJS API
preload: path.join(app.getAppPath(), 'electron', 'preload.js'),
},
})

// Disable the default menu
throw new AppError('This is a test.')

// disable menu
this.window.setMenu(null)

// Get the interface location
this.loadURL = this.getNuxtAppLocation()
// ui location
this.uiUrl = this.getUiUrl()

if (config.dev) {
// Development
this.pollServer()
this.pollUi()
} else {
// Production, load the static interface!
this.window.loadFile(this.loadURL)
this.window.loadFile(this.uiUrl)
}

if (process.env.DEVTOOLS) {
// Load the DevTools
// devtools
this.window.webContents.openDevTools()
}
}
@@ -125,30 +146,31 @@ class DreamApp {
/**
* Wait until the NuxtJS server is ready.
*/
static pollServer() {
console.log(`Requesting status from the server: ${this.loadURL}`)
static pollUi() {
logger.debug(`Requesting status from the server: ${this.uiUrl}`)

http
.get(this.loadURL, (response) => {
.get(this.uiUrl, (response) => {
if (response.statusCode === 200) {
console.log('> Server ready, show time!')
this.window.loadURL(this.loadURL)
logger.debug('Server ready, dream time!')
this.window.loadURL(this.uiUrl)
} else {
console.log(
`> The server reported the status code: ${response.statusCode}`,
)
setTimeout(this.pollServer.bind(this), 300)
logger.warn(`The server reported: ${response.statusCode}`)
setTimeout(this.pollUi.bind(this), 300)
}
})
.on('error', () => {
setTimeout(this.pollServer.bind(this), 300)
.on('error', (error) => {
logger.warn('Poll error', error)
setTimeout(this.pollUi.bind(this), 300)
})
}

/**
* Returns the location of the interface
* Returns the url of the user interface
*
* @return {string}
*/
static getNuxtAppLocation() {
static getUiUrl() {
if (!config.dev) {
return path.join(config.rootDir, 'dist', 'index.html')
}
@@ -157,45 +179,40 @@ class DreamApp {
}

/**
* Create the model folder to save the processed photos
* Create required directories.
*/
static createModelsDir() {
static createDirs() {
const modelsPath = path.join(settings.folders.models, 'Uncategorized')

if (!fs.existsSync(modelsPath)) {
fs.mkdirSync(
modelsPath,
{
recursive: true,
},
fs.mkdirSync(modelsPath, { recursive: true },
(error) => {
throw new AppError(
`Trying to create the directory to save the models,
please make sure that the application has permissions to create the directory:\n
${modelsPath}`,
error,
)
},
)
throw new AppError(`Could not create model directory.`, { error })
})
}
}
}

app.on('ready', () => {
process.on('uncaughtException', (err) => {
logger.warn('Unhandled exception!', err)
AppError.handle(err)
return true
})

process.on('unhandledRejection', (err) => {
logger.warn('Unhandled rejection!', err)
AppError.handle(err)
return true
})

app.on('ready', async () => {
try {
DreamApp.start()
await DreamApp.start()
} catch (error) {
rollbar.error(error)
console.error(error)

app.quit()
throw new AppError(error, { title: `Failed to start correctly.` })
}
})

app.on('window-all-closed', () => {
app.quit()
})

app.on('activate', () => {
DreamApp.createWindow()
})

src/electron/preload.js → src/electron/src/preload.js View File

@@ -1,7 +1,6 @@
const {
AppError, settings, nucleus, rollbar,
} = require('./modules')
const tools = require('./tools')
import { AppError } from './scripts'
import { settings, nucleus, rollbar } from './scripts/services'
import * as tools from './scripts/tools'

// Custom Error
window.AppError = AppError

src/electron/scripts/error.js → src/electron/src/scripts/error.js View File

@@ -7,10 +7,11 @@
//
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019.

const _ = require('lodash')
const { api } = require('electron-utils')
import { isError, isString } from 'lodash'
import { api } from 'electron-utils'
import { rollbar } from './services/rollbar'

const logger = require('logplease').create('electron:scripts:error')
const { rollbar } = require('./services/rollbar')

/**
* @typedef {Object} ErrorOptions
@@ -20,26 +21,43 @@ const { rollbar } = require('./services/rollbar')
* @property {Object} extra
*/

class AppError extends Error {
export class AppError extends Error {
options = {
title: null,
error: null,
level: 'error',
}

/**
*
* @param {string} message
* @param {ErrorOptions} options
*/
constructor(message, options = {}) {
super(message)
constructor(input, options = {}) {
if (isString(input)) {
super(input)
} else if (isError(input)) {
super(input.message)

if (input instanceof AppError) {
this.options = {
...this.options,
error: input,
...input.options,
}
}
} else {
super()
}

this.options = {
title: 'A problem has occurred.',
error: undefined,
level: 'error',
extra: {},
...this.options,
...options,
}
}

report() {
const { title, level, extra } = this.options
const { level } = this.options

// logger
logger[level](`๐Ÿ’” ${this.message}`)
@@ -48,14 +66,10 @@ class AppError extends Error {
const error = this.options.error || Error(this.message)

try {
const response = rollbar[level](error, {
title,
message: this.message,
...extra,
})
const response = rollbar[level](this.message, error, this.options)

if (response.uuid) {
this.message += `\nFor more information please report the following:\nhttps://rollbar.com/occurrence/uuid/?uuid=${response.uuid}`
this.message += `\n\nShare this with a developer:\nhttps://rollbar.com/occurrence/uuid/?uuid=${response.uuid}`
}
} catch (err) {
logger.warn('๐Ÿ’” Error trying to report the error!', err)
@@ -64,12 +78,12 @@ class AppError extends Error {

this.show()

api.app.exit()
api.app.quit()
}

show() {
api.dialog.showErrorBox(
this.options.title,
this.options.title || 'A problem has occurred.',
this.message,
)
}
@@ -79,9 +93,9 @@ class AppError extends Error {

if (!(appError instanceof AppError)) {
appError = new AppError(
_.isError(appError) ? error.message : 'The program has detected an unknown error. Sorry!',
isError(appError) ? error.message : 'The program has detected an unknown error. Sorry!',
{
error: _.isError(appError) ? appError : new Error(appError),
error: isError(appError) ? appError : new Error(appError),
},
)
}
@@ -89,7 +103,3 @@ class AppError extends Error {
appError.report()
}
}

module.exports = {
AppError,
}

+ 10
- 0
src/electron/src/scripts/index.js View File

@@ -0,0 +1,10 @@
// DreamTime.
// Copyright (C) DreamNet. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License 3.0 as published by
// the Free Software Foundation. See <https://www.gnu.org/licenses/gpl-3.0.html>
//
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019.

export { AppError } from './error'

src/electron/scripts/services/base.js → src/electron/src/scripts/services/base.js View File

@@ -7,13 +7,14 @@
//
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019.

const {
import {
set, get, isNil, isPlainObject,
} = require('lodash')
const fs = require('fs')
} from 'lodash'
import fs from 'fs'

const logger = require('logplease').create('electron:scripts:services')

class BaseService {
export class BaseService {
/**
* the payload.
* a proxy will be used to get or set this information.
@@ -34,7 +35,7 @@ class BaseService {
*
* @type {Boolean}
*/
enabled: false
enabled = false

/**
* file where to save the payload.
@@ -153,7 +154,3 @@ class BaseService {
this.save()
}
}

module.exports = {
BaseService,
}

+ 12
- 0
src/electron/src/scripts/services/index.js View File

@@ -0,0 +1,12 @@
// DreamTime.
// Copyright (C) DreamNet. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License 3.0 as published by
// the Free Software Foundation. See <https://www.gnu.org/licenses/gpl-3.0.html>
//
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019.

export { settings } from './settings'
export { nucleus } from './nucleus'
export { rollbar } from './rollbar'

src/electron/scripts/services/nucleus.js → src/electron/src/scripts/services/nucleus.js View File

@@ -7,13 +7,14 @@
//
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019.

const { isNil } = require('lodash')
const Nucleus = require('nucleus-nodejs')
const axios = require('axios')
import { isNil } from 'lodash'
import Nucleus from 'nucleus-nodejs'
import axios from 'axios'
import { BaseService } from './base'
import { system } from '../tools'
import { settings } from './settings'

const logger = require('logplease').create('electron:scripts:services:nucleus')
const { BaseService } = require('./base')
const { system } = require('../tools')
const { settings } = require('./settings')

/**
* https://nucleus.sh
@@ -64,6 +65,7 @@ class NucleusService extends BaseService {
this.enabled = true

logger.info('Nucleus enabled!')
logger.debug(this.appId)
} catch (err) {
logger.warn('๐Ÿ’” Error trying to start Nucleus!', err)
}
@@ -80,6 +82,4 @@ class NucleusService extends BaseService {
}
}

module.exports = {
nucleus: NucleusService.make(),
}
export const nucleus = NucleusService.make()

src/electron/scripts/services/rollbar.js → src/electron/src/scripts/services/rollbar.js View File

@@ -7,12 +7,14 @@
//
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019.

const { isNil, isString, get } = require('lodash')
const { Rollbar } = require('rollbar')
import { isNil, isString, get } from 'lodash'
import { execSync } from 'child_process'
import Rollbar from 'rollbar'
import { BaseService } from './base'
import { settings } from './settings'
import { nucleus } from './nucleus'

const logger = require('logplease').create('electron:scripts:services:rollbar')
const { BaseService } = require('./base')
const { settings } = require('./settings')
const { nucleus } = require('./nucleus')

/**
* https://rollbar.com
@@ -30,7 +32,15 @@ class RollbarService extends BaseService {
* @type {boolean}
*/
get can() {
return !isNil(settings.telemetry.enabled) && isString(this.accessToken)
return isString(this.accessToken)
}

get codeVersion() {
try {
return process.env.GIT_SHA || execSync('git rev-parse HEAD').toString().trim()
} catch (err) {
return null
}
}

/**
@@ -39,22 +49,23 @@ class RollbarService extends BaseService {
get config() {
return {
accessToken: this.accessToken,
captureUncaught: true,
captureUnhandledRejections: true,
captureUncaught: false,
captureUnhandledRejections: false,
captureIp: 'anonymize',
enabled: settings.telemetry.enabled,
verbose: process.env.NODE_ENV === 'development',
logLevel: 'info',
nodeSourceMaps: true,
reportLevel: 'warning',
reportLevel: 'error',
payload: {
environment:
process.env.NODE_ENV !== 'development' ? 'production' : 'development',
environment: process.env.NODE_ENV,
person: {
id: settings.user,
},
client: {
javascript: {
source_map_enabled: true,
code_version: process.env.APP_VERSION,
code_version: this.codeVersion,
},
},
settings: settings.payload,
@@ -76,12 +87,28 @@ class RollbarService extends BaseService {
this.enabled = true

logger.info('Rollbar enabled!')
logger.debug(this.accessToken)
} catch (err) {
logger.warn('๐Ÿ’” Error trying to start Rollbar!', err)
}
}
}

module.exports = {
rollbar: RollbarService.make(),
/**
*
*/
shutdown() {
return new Promise((resolve) => {
if (isNil(this._service)) {
resolve()
return
}

// wait until send bug reports.
this._service.wait(() => {
resolve()
})
})
}
}

export const rollbar = RollbarService.make()

src/electron/scripts/services/settings.js → src/electron/src/scripts/services/settings.js View File

@@ -7,16 +7,15 @@
//
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019.

const fs = require('fs')
const {
memoize, isNil, round, cloneDeep,
} = require('lodash')
const uuid = require('uuid')
const { api } = require('electron-utils')
import fs from 'fs'
import {
memoize, round, cloneDeep,
} from 'lodash'
import uuid from 'uuid'
import { BaseService } from './base'
import { paths, system } from '../tools'

const logger = require('logplease').create('electron:scripts:services:settings')
const { BaseService } = require('./base')
const { AppError } = require('../error')
const { paths, system } = require('../tools')

/**
* User settings.
@@ -142,7 +141,7 @@ class SettingsService extends BaseService {
try {
fs.outputFileSync(this.path, JSON.stringify(this._defaults, null, 2))
} catch (error) {
throw new AppError(`Could not create settings file. Please make sure the program has the necessary permissions to write to:\n${this.path}`, { error })
throw new Error(`Settings creation fail. Please make sure the program has the necessary permissions to write to:\n${this.path}`)
}
}

@@ -151,14 +150,14 @@ class SettingsService extends BaseService {
* legacy code :WutFaceW:
*/
async _upgrade() {
const currentVersion = this._settings.version || 1
const currentVersion = this.payload.version || 1
const newVersion = this._default.version

if (newVersion === currentVersion) {
return
}

const currentSettings = this._settings
const currentSettings = this.payload
const newSettings = cloneDeep(currentSettings)

// Upgrade 1 -> 2
@@ -173,7 +172,7 @@ class SettingsService extends BaseService {
nippleSize,
vaginaSize,
pubicHairSize,
} = this._settings.preferences
} = this.payload.preferences

newSettings.preferences.boobs.size = boobsSize
newSettings.preferences.areola.size = areolaSize
@@ -223,6 +222,4 @@ class SettingsService extends BaseService {
}
}

module.exports = {
settings: SettingsService.make(),
}
export const settings = SettingsService.make()

src/electron/scripts/tools/fs.js → src/electron/src/scripts/tools/fs.js View File

@@ -1,46 +1,41 @@
const _ = require('lodash')
const fs = require('fs')
const mime = require('mime-types')
const path = require('path')
const EventBus = require('js-event-bus')
const axios = require('axios')
const { api } = require('electron-utils')
const filesize = require('filesize')
const unzipper = require('unzipper')
const deferred = require('deferred')
const sevenBin = require('7zip-bin')
const { extractFull } = require('node-7z')

const debug = require('debug').default('app:electron:tools:fs')

/**
* Returns the base64 of a dataURL
* @param {*} dataURL
*/
function getBase64Data(dataURL) {
let encoded = dataURL.replace(/^data:(.*;base64,)?/, '')

if (encoded.length % 4 > 0) {
encoded += '='.repeat(4 - (encoded.length % 4))
}

return encoded
}

module.exports = {
import path from 'path'
import fs from 'fs-extra'
import { isNil } from 'lodash'
import mime from 'mime-types'
import EventBus from 'js-event-bus'
import axios from 'axios'
import { api, is, platform } from 'electron-utils'
import filesize from 'filesize'
import unzipper from 'unzipper'
import deferred from 'deferred'
import sevenBin from '7zip-bin'
import { extractFull } from 'node-7z'
import { getAppResources } from './paths'

export default {
/**
*
* @param {string} filePath
* Returns the base64 of a dataURL
* @param {*} dataURL
*/
getInfo(filePath) {
const exists = this.exists(filePath)
const mimetype = mime.lookup(filePath)
const { name, ext, dir } = path.parse(filePath)
getBase64Data: (dataURL) => {
let encoded = dataURL.replace(/^data:(.*;base64,)?/, '')

if (encoded.length % 4 > 0) {
encoded += '='.repeat(4 - (encoded.length % 4))
}

return encoded
},

getInfo: (path) => {
const exists = this.exists(path)
const mimetype = mime.lookup(path)
const { name, ext, dir } = path.parse(path)

let size

if (exists) {
const stats = fs.statSync(filePath)
const stats = fs.statSync(path)
size = stats.size / 1000000.0
}

@@ -54,75 +49,19 @@ module.exports = {
}
},

/**
*
* @param {*} path
*/
async read(path, encoding = 'utf-8') {
return fs.readFileSync(path, { encoding })
},

/**
*
* @param {*} path
*/
readJSON(path, encoding = 'UTF-8') {
return JSON.parse(fs.readFileSync(path, { encoding }))
},
read: (path, encoding = 'utf-8') => fs.readFileSync(path, { encoding }),

/**
*
* @param {*} path
* @param {*} dataURL
*/
async writeDataURL(path, dataURL) {
const data = getBase64Data(dataURL)
writeDataUrl: (path, dataURL) => {
const data = this.getBase64Data(dataURL)
return fs.writeFileSync(path, data, 'base64')
},

/**
*
* @param {*} path
* @param {*} targetPath
*/
async copy(path, targetPath) {
return fs.copyFileSync(path, targetPath)
},

/**
*
*/
async unlink(path) {
return fs.unlinkSync(path)
},

/**
*
* @param {string} filePath
*/
exists(filePath) {
return fs.existsSync(filePath)
},

/**
* @param {string} filePath
*/
stats(filePath) {
return fs.statSync(filePath)
},

/**
*
* @param {string} zipPath
* @param {string} targetPath
* @return {Promise}
*/
extract(zipPath, targetPath) {
extractZip: (path, destinationPath) => {
const def = deferred()

const stream = fs
.createReadStream(zipPath)
.pipe(unzipper.Extract({ path: targetPath }))
.createReadStream(path)
.pipe(unzipper.Extract({ path: destinationPath }))

stream.on('close', () => {
def.resolve()
@@ -135,29 +74,24 @@ module.exports = {
return def.promise
},

/**
*
* @param {string} zipPath
* @param {string} targetPath
*/
extractSeven(zipPath, targetPath) {
extractSeven: (path, destinationPath) => {
const def = deferred()

let pathTo7zip

if ($tools.utils.is.development) {
if (is.development) {
pathTo7zip = sevenBin.path7za
} else {
const binName = $tools.utils.platform({
const binName = platform({
macos: '7za',
windows: '7za.exe',
linux: '7za',
windows: '7za.exe',
})

pathTo7zip = $tools.paths.getGuiResources('7zip-bin', binName)
pathTo7zip = getAppResources('7zip-bin', binName)
}

const seven = extractFull(zipPath, targetPath, {
const seven = extractFull(path, destinationPath, {
$bin: pathTo7zip,
recursive: true,
})
@@ -173,10 +107,7 @@ module.exports = {
return def.promise
},

/**
*
*/
download(url, options = {}) {
download: (url, options = {}) => {
const bus = new EventBus()

// eslint-disable-next-line no-param-reassign
@@ -196,7 +127,7 @@ module.exports = {

const deleteFile = () => {
if (fs.existsSync(filePath)) {
debug(`Deleting file ${filePath}`)
// debug(`Deleting file ${filePath}`)
fs.unlinkSync(filePath)
}
}
@@ -224,12 +155,13 @@ module.exports = {
stream.destroy(err)
deleteFile()

if (!_.isNil(err)) {
if (!isNil(err)) {
console.warn('Download canceled due to an error', err)
bus.emit('error', null, err)
}
}

/*
debug('Downloading file and placing it in a writeStream', {
url,
fileName,
@@ -238,6 +170,7 @@ module.exports = {
mbTotal,
exists: fs.existsSync(filePath),
})
*/

output.on('error', (err) => {
cancel(err)
@@ -288,7 +221,7 @@ module.exports = {
})

bus.on('cancel', () => {
debug('Download canceled!')
// debug('Download canceled!')
cancel()
})

@@ -301,17 +234,17 @@ module.exports = {
return bus
},

downloadAsync(url, options = {}) {
return new Promise((resolve, reject) => {
const bus = this.download(url, options)
downloadAsync: (url, options = {}) => new Promise((resolve, reject) => {
const bus = this.download(url, options)

bus.on('end', (filePath) => {
resolve(filePath)
})
bus.on('end', (filePath) => {
resolve(filePath)
})

bus.on('error', (err) => {
reject(err)
})
bus.on('error', (err) => {
reject(err)
})
},
}),

...fs,
}

src/electron/scripts/services/index.js → src/electron/src/scripts/tools/index.js View File

@@ -7,12 +7,10 @@
//
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019.

const { settings } = require('./settings')
const { nucleus } = require('./nucleus')
const { rollbar } = require('./rollbar')
import * as paths from './paths'

module.exports = {
settings,
nucleus,
rollbar,
}
export fs from './fs'
export shell from './shell'
export { paths }
export utils from 'electron-utils'
export { system } from './system'

+ 154
- 0
src/electron/src/scripts/tools/nudify.js View File

@@ -0,0 +1,154 @@
// DreamTime.
// Copyright (C) DreamNet. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License 3.0 as published by
// the Free Software Foundation. See <https://www.gnu.org/licenses/gpl-3.0.html>
//
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019.

import { spawn } from 'child_process'
import EventBus from 'js-event-bus'
import deferred from 'deferred'
import semverRegex from 'semver-regex'
import paths from './paths'

/**
*
* @param {Object} job
*/
export const transform = (job) => {
// Independent preferences for the photo
const { preferences } = job

// input
const photoFilepath = job.photo.file.getPath()

// output
const outputFilepath = job.file.getPath()

// CLI Args
const args = ['run', '--input', photoFilepath, '--output', outputFilepath]

if ($settings.processing.usePython) {
// use python script
args.unshift('main.py')
}

// Device preferences
if ($settings.processing.device === 'CPU') {
args.push('--cpu', '--n-cores', $settings.processing.cores)
} else {
for (const id of $settings.processing.gpus) {
args.push('--gpu', id)
}
}

// Advanced preferences
const { scaleMode, useColorTransfer } = preferences.advanced

if (scaleMode === 'cropjs') {
const { crop } = job.photo
args.push('--overlay', `${crop.startX},${crop.startY}:${crop.endX},${crop.endY}`)
} else if (scaleMode !== 'none') {
args.push(`--${scaleMode}`)
}

if (useColorTransfer) {
args.push('--color-transfer')
}

// Body preferences
args.push('--bsize', preferences.body.boobs.size)
args.push('--asize', preferences.body.areola.size)
args.push('--nsize', preferences.body.nipple.size)
args.push('--vsize', preferences.body.vagina.size)
args.push('--hsize', preferences.body.pubicHair.size)

/*
debug('The transformation process has begun!', {
input: photoFilepath,
output: outputFilepath,
preferences,
args,
job,
})
*/

let process
const bus = new EventBus()

if ($settings.processing.usePython) {
// python script
process = spawn('python3', args, {
cwd: paths.getCli(),
})
} else {
process = spawn(paths.getCli('dreampower'), args, {
cwd: paths.getCli(),
})
}

process.on('error', (error) => {
console.error(error)
bus.emit('error', null, error)
})

process.stdout.on('data', (data) => {
console.info(`stdout: ${data}`)
bus.emit('stdout', null, data)
})

process.stderr.on('data', (data) => {
console.warn(`stderr: ${data}`)
bus.emit('stderr', null, data)
})

process.on('close', (code) => {
console.log(`CLI process exited with code ${code}`)
bus.emit('ready', null, code)
})

bus.on('kill', () => {
process.stdin.pause()
process.kill()
})

return bus
}

/**
* @return {Promise}
*/
export const getVersion = () => {
const def = deferred()

let process
let response = ''

if ($settings.processing.usePython) {
// python script
process = spawn('python3', ['main.py', '--version'], {
cwd: paths.getCli(),
})
} else {
process = spawn(paths.getCli('dreampower'), ['--version'])
}

process.on('error', () => {
def.resolve('')
})

process.stdout.on('data', (data) => {
response += data
})

process.on('close', () => {
response = semverRegex().exec(response)
response = `v${response[0]}`

def.resolve(response)
})

return def.promise
}

+ 92
- 0
src/electron/src/scripts/tools/paths.js View File

@@ -0,0 +1,92 @@
// DreamTime.
// Copyright (C) DreamNet. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License 3.0 as published by
// the Free Software Foundation. See <https://www.gnu.org/licenses/gpl-3.0.html>
//
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019.

import path from 'path'
import fs from 'fs-extra'
import { api } from 'electron-utils'

/**
* Returns an absolute path depending on the parameters
*
* @param {string} name Name of the base path: https://electronjs.org/docs/all#appgetpathname
* @param {string} args Series of path segments to join into one path
*/
export const get = (name, ...args) => path.join(api.app.getPath(name), ...args)

/**
*
* @param {...any} args
*/
export const getApp = (...args) => {
if (process.platform === 'darwin') {
// /Applications/DreamTime.app/Contents/MacOS/DreamTime
// /Applications/DreamTime.app/Contents
return this.get('exe', '..', '..', ...args)
}

return this.get('exe', '..', ...args)
}

export const getAppResources = (...args) => {
if (process.platform === 'darwin') {
return this.getGui('Resources', ...args)
}

return this.getGui('resources', ...args)
}

export const getPower = (...args) => {
let folder = $settings.folders.cli

if (!fs.existsSync(folder)) {
folder = this.get('userData', 'dreampower')
}

return path.join(folder, ...args)
}

export const getPowerCheckpoints = (...args) => this.getPower('checkpoints', ...args)

export const getCrop = (...args) => {
let folder = $settings.folders.cropped

if (!fs.existsSync(folder)) {
folder = this.get('temp')
}

return path.join(folder, ...args)
}

export const getModels = (...args) => {
let folder = $settings.folders.models

if (!fs.existsSync(folder)) {
folder = this.get('userData', 'models')
}

if (!fs.existsSync(folder)) {
folder = this.get('temp')
}

return path.join(folder, ...args)
}

export const getMasks = (...args) => {
let folder = $settings.folders.masks

if (!fs.existsSync(folder)) {
folder = this.get('userData', 'masks')
}

if (!fs.existsSync(folder)) {
folder = this.get('temp')
}

return path.join(folder, ...args)
}

+ 56
- 0
src/electron/src/scripts/tools/photo.js View File

@@ -0,0 +1,56 @@
// DreamTime.
// Copyright (C) DreamNet. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License 3.0 as published by
// the Free Software Foundation. See <https://www.gnu.org/licenses/gpl-3.0.html>
//
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019.

import fs from 'fs-extra'
import { Image } from 'image-js'
// const { Caman } = require('caman')

/**
* This is probably not a good cropper, but it's all I have now...
*
* @param {Photo} photo
* @param {HTMLCanvasElement} canvas
*/
export const crop = async (photo, canvas) => {
const image = Image.fromCanvas(canvas)
const savePath = photo.getCroppedFile().getPath()

// debug(`Saving cropped photo in ${savePath}`)
await image.save(savePath)

if (!fs.existsSync(savePath)) {
console.warn(
'It seems that the first crop method has failed, trying the legacy method',
)

await this.legacyCrop(photo, canvas)
} else {
photo.getCroppedFile().reload()
}
}

/**
*
* @param {*} photo
* @param {*} canvas
*/
export const legacyCrop = async (photo, canvas) => {
const canvasAsDataURL = canvas.toDataURL(
photo.getSourceFile().getMimetype(),
1,
)

await photo.getCroppedFile().writeDataURL(canvasAsDataURL)

if (!fs.existsSync(photo.getCroppedFile().getPath())) {
throw new Error(
'There was a problem trying to save the cropped photo. Please make sure the program has write permissions.',
)
}
}

+ 39
- 0
src/electron/src/scripts/tools/shell.js View File

@@ -0,0 +1,39 @@
// DreamTime.
// Copyright (C) DreamNet. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License 3.0 as published by
// the Free Software Foundation. See <https://www.gnu.org/licenses/gpl-3.0.html>
//
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019.

import { isNil } from 'lodash'
import { is } from 'electron-utils'
import regedit from 'regedit'
import { getAppResources } from './paths'

export const hasWindowsMedia = () => {
if (is.windows && !is.development) {
regedit.setExternalVBSLocation(
getAppResources('vbs'),
)
}

return new Promise((resolve) => {
if (!is.windows) {
resolve(true)
return
}

const regKey = 'HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\WindowsFeatures'

regedit.list(regKey, (err, result) => {
if (!isNil(err)) {
resolve(false)
return
}

resolve(result[regKey].keys.includes('WindowsMediaVersion'))
})
})
}

src/electron/scripts/tools/system.js → src/electron/src/scripts/tools/system.js View File

@@ -35,13 +35,13 @@ class System {
/**
*
*/
async _setup() {
const {
async setup() {
const [
graphics,
cpu,
mem,
online,
} = await Promise.all([
] = await Promise.all([
si.graphics(),
si.cpu(),
si.mem(),
@@ -76,6 +76,4 @@ class System {
}
}

module.exports = {
system: new System(),
}
export const system = new System()

+ 13
- 0
src/jsconfig.json View File

@@ -0,0 +1,13 @@
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"~": [
"./*"
],
"test/*": [
"test/*"
]
}
}
}

+ 5
- 2
src/modules/file.js View File

@@ -1,3 +1,4 @@
// eslint-disable-next-line lodash/import-scope
import _ from 'lodash'
import path from 'path'

@@ -51,11 +52,13 @@ export default class File {
* @param {*} path
*/
reload(path) {
let filePath = path

if (_.isNil(path)) {
path = this.getPath()
filePath = this.getPath()
}

const info = $tools.fs.getInfo(path)
const info = $tools.fs.getInfo(filePath)

this.name = info.name
this.ext = info.ext

+ 2
- 2
src/modules/models/photo-job.js View File

@@ -220,12 +220,12 @@ export default class PhotoJob {

this.process.on('stdout', (output) => {
// Output generated by the CLI
output = output
const stdout = output
.toString()
.trim()
.split('\n')

output.forEach((text) => {
stdout.forEach((text) => {
this.cli.lines.unshift({
text,
css: {},

+ 3
- 1
src/modules/models/photo.js View File

@@ -84,7 +84,9 @@ export default class Photo {
job.onStart()
})

this.queue.on('task_finish', (jobId, job, stats) => {
this.queue.on('task_finish', (jobId, jb, stats) => {
let job = jb

if (_.isNil(job)) {
job = this.getJobById(jobId)
}

+ 2
- 0
src/modules/web-error.js View File

@@ -17,6 +17,7 @@ class WebError extends Error {
constructor(title, message, opts = {}) {
super(message)

// eslint-disable-next-line no-param-reassign
opts = {
error: undefined,
level: 'error',
@@ -93,6 +94,7 @@ class WebError extends Error {

static handle(error) {
if (!(error instanceof WebError)) {
// eslint-disable-next-line no-param-reassign
error = new WebError(
'An error has occurred!',
'Oops! An unknown error has awakened us from our dreams, we will try to solve it in the next version.',

+ 2
- 3
src/nuxt.config.js View File

@@ -1,5 +1,4 @@
require('dotenv').config()

/* eslint-disable no-param-reassign */
// eslint-disable-next-line nuxt/no-cjs-in-config
module.exports = {
mode: 'spa',
@@ -23,7 +22,7 @@ module.exports = {
** Headers of the page
*/
head: {