Browse Source

More code refactoring and performance improvements.

tags/v1.4.4
Ivan Bravo Bravo 1 year ago
parent
commit
e3c3c151a5

+ 34
- 25
src/.vscode/launch.json View File

@@ -6,37 +6,46 @@
"configurations": [
{
"type": "node",
"request": "attach",
"name": "electron",
"request": "launch",
"name": "Main Process",
"runtimeExecutable": "yarn",
"runtimeArgs": [
"start:electron",
"--remote-debugging-port=9223",
"--inspect-brk=9222"
],
"outputCapture": "std",
"port": 9222,
"preLaunchTask": "start",
"postDebugTask": "kill",
"skipFiles": [
"<node_internals>/**"
]
],
"sourceMaps": true,
"sourceMapPathOverrides": {
"electron/dist/*": "${webRoot}/electron/src/*"
},
//"preLaunchTask": "Build: Electron"
},
{
"type": "node",
"request": "launch",
"name": "electron: launch",
"cwd": "${workspaceRoot}",
"outputCapture": "std",
"preLaunchTask": "start:nuxt",
"postDebugTask": "kill",
"env": {
"NODE_ENV": "development",
"LOG": "debug",
"DEVTOOLS": "true"
},
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/electron",
"windows": {
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd"
"type": "chrome",
"request": "attach",
"name": "Renderer Process",
"port": 9223,
"webRoot": "${workspaceRoot}",
"sourceMaps": true,
"sourceMapPathOverrides": {
"webpack:///./*": "${webRoot}/*",
"webpack:///*": "${webRoot}/*"
},
"runtimeArgs": [
"--remote-debugging-port=9222",
"."
]
//"preLaunchTask": "Build: Nuxt"
}
],
"compounds": []
"compounds": [
{
"name": "Launch",
"configurations": [
"Main Process",
"Renderer Process"
]
}
]
}

+ 7
- 26
src/.vscode/tasks.json View File

@@ -4,7 +4,7 @@
"version": "2.0.0",
"tasks": [
{
"label": "start:nuxt",
"label": "Build: Nuxt",
"type": "npm",
"script": "start:nuxt",
"group": "build",
@@ -19,12 +19,12 @@
"background": {
"activeOnStart": true,
"beginsPattern": "Updated",
"endsPattern": "Compiled successfully in",
"endsPattern": "Compiled",
}
}
},
{
"label": "start:babel",
"label": "Build: Electron",
"type": "npm",
"script": "start:babel",
"group": "build",
@@ -47,36 +47,17 @@
}
}
},
{
"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",
"label": "Build",
"dependsOn": [
"build",
"start:electron"
],
"dependsOrder": "parallel"
"Build: Electron",
"Build: Nuxt"
]
}
]
}

+ 9
- 4
src/electron/src/index.js View File

@@ -15,9 +15,9 @@ 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 { AppError } from './modules/app-error'
import { settings, nucleus, rollbar } from './modules/services'
import { system } from './modules/tools'
import config from '~/nuxt.config'

const logger = require('logplease').create('electron')
@@ -93,6 +93,11 @@ class DreamApp {
// bug tracking.
await rollbar.setup()

// requirements.
await system.scan()

// todo: updates

//
this.createDirs()

@@ -121,7 +126,7 @@ class DreamApp {
minHeight: 700,
icon: path.join(config.rootDir, 'dist', 'icon.ico'),
webPreferences: {
nodeIntegration: true,
nodeIntegration: false,
preload: path.join(app.getAppPath(), 'electron', 'dist', 'provider.js'),
},
})

src/electron/src/scripts/error.js → src/electron/src/modules/app-error.js View File

@@ -39,10 +39,13 @@ export class AppError extends Error {
} else if (isError(input)) {
super(input.message)

this.stack = input.stack

this.options.error = input

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

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


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


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


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

@@ -52,7 +52,7 @@ class RollbarService extends BaseService {
captureUncaught: false,
captureUnhandledRejections: false,
captureIp: 'anonymize',
enabled: settings.telemetry.enabled,
enabled: settings.telemetry.enabled && process.env.NODE_ENV !== 'development',
verbose: process.env.NODE_ENV === 'development',
logLevel: 'info',
nodeSourceMaps: true,

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


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


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

@@ -9,9 +9,11 @@

import * as paths from './paths'
import * as shell from './shell'
import * as power from './power'

export fs from './fs'
export { shell }
export { paths }
export { power }
export utils from 'electron-utils'
export { system } from './system'

src/electron/src/scripts/tools/paths.js → src/electron/src/modules/tools/paths.js View File

@@ -10,6 +10,7 @@
import path from 'path'
import fs from 'fs-extra'
import { api } from 'electron-utils'
import { settings } from '../services'

/**
* Returns an absolute path depending on the parameters
@@ -27,65 +28,65 @@ export const getApp = (...args) => {
if (process.platform === 'darwin') {
// /Applications/DreamTime.app/Contents/MacOS/DreamTime
// /Applications/DreamTime.app/Contents
return this.get('exe', '..', '..', ...args)
return get('exe', '..', '..', ...args)
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

src/electron/src/scripts/tools/photo.js → src/electron/src/modules/tools/photo.js View File


src/electron/src/scripts/tools/nudify.js → src/electron/src/modules/tools/power.js View File

@@ -11,7 +11,8 @@ import { spawn } from 'child_process'
import EventBus from 'js-event-bus'
import deferred from 'deferred'
import semverRegex from 'semver-regex'
import paths from './paths'
import { getPower } from './paths'
import { settings } from '../services'

/**
*
@@ -30,16 +31,16 @@ export const transform = (job) => {
// CLI Args
const args = ['run', '--input', photoFilepath, '--output', outputFilepath]

if ($settings.processing.usePython) {
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)
if (settings.processing.device === 'CPU') {
args.push('--cpu', '--n-cores', settings.processing.cores)
} else {
for (const id of $settings.processing.gpus) {
for (const id of settings.processing.gpus) {
args.push('--gpu', id)
}
}
@@ -78,14 +79,14 @@ export const transform = (job) => {
let process
const bus = new EventBus()

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

@@ -126,13 +127,13 @@ export const getVersion = () => {
let process
let response = ''

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

process.on('error', () => {

src/electron/src/scripts/tools/shell.js → src/electron/src/modules/tools/shell.js View File


+ 238
- 0
src/electron/src/modules/tools/system.js View File

@@ -0,0 +1,238 @@
// 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 {
filter, isString, isNil, isArray, toInteger,
} from 'lodash'
import { existsSync, statSync } from 'fs'
import si from 'systeminformation'
import isOnline from 'is-online'
import compareVersions from 'compare-versions'
import filesize from 'filesize'
import { is } from 'electron-utils'
import regedit from 'regedit'
import { nucleus } from '../services'
import { getAppResources, getPower, getPowerCheckpoints } from './paths'
import { getVersion } from './power'

const logger = require('logplease').create('electron:modules:tools:system')

class System {
/**
* @type {si.Systeminformation.OsData}
*/
os

/**
* @type {si.Systeminformation.GraphicsData}
*/
_graphics

/**
* @type {si.Systeminformation.CpuData}
*/
cpu

/**
* @type {si.Systeminformation.MemData}
*/
memory

/**
* @type {boolean}
*/
online

/**
* @type {Object}
*/
requirements = {
all: false,
power: {
installed: false,
compatible: false,
checkpoints: false,
},
windows: {
media: false,
},
ram: {
minimum: false,
recommended: false,
},
}

/**
*
*/
async setup() {
const [
graphics,
os,
cpu,
mem,
online,
] = await Promise.all([
si.graphics(),
si.osInfo(),
si.cpu(),
si.mem(),
isOnline(),
])

this._graphics = graphics
this.os = os
this.cpu = cpu
this.memory = mem
this.online = online

logger.info(`GPU devices: ${this.graphics.length}`)
logger.info(`RAM: ${this.memory.total} bytes.`)
logger.info(`Internet connection: ${this.online}`)
logger.debug(this)
}

/**
*
*/
async scan() {
this.requirements.power.installed = this.hasPower
this.requirements.power.compatible = await this.hasCompatiblePower()
this.requirements.power.checkpoints = this.hasCheckpoints

this.requirements.windows.media = await this.hasWindowsMedia()

this.requirements.ram.recommended = this.memory.total >= 8589934592 // 8 GB
this.requirements.ram.minimum = this.memory.total >= 6442450944 // 6 GB

logger.info('Requirements:', this.requirements)
}

/**
* @return {Array}
*/
get graphics() {
return filter(this._graphics.controllers, { vendor: 'NVIDIA' })
}

get hasPower() {
const dirpath = getPower()

if (!isString(dirpath)) {
// how the fuck?
return false
}

if (!existsSync(dirpath)) {
return false
}

const binaries = [
'main.py',
'dreampower.exe',
'dreampower',
]

for (const bin of binaries) {
if (existsSync(getPower(bin))) {
return true
}
}

return false
}

async hasCompatiblePower() {
if (!this.requirements.power.installed) {
return false
}

const version = await getVersion()
const compatibility = nucleus.compatibility[`v${process.env.npm_package_version}`]

if (!isArray(compatibility)) {
return true
}

for (const conditions of compatibility) {
// v1.2.2 v1.0.0 >= = true
// v1.2.2 v.1.0 <= = false
if (!compareVersions.compare(version, conditions[0], conditions[1])) {
return false
}
}

return true
}

get hasCheckpoints() {
const dirpath = getPowerCheckpoints()

if (!existsSync(dirpath)) {
return false
}

// these files must exist
const files = ['cm.lib', 'mm.lib', 'mn.lib']

for (const file of files) {
const filepath = getPowerCheckpoints(file)

if (!existsSync(filepath)) {
return false
}

const stats = statSync(filepath)
const size = filesize(stats.size, { exponent: 2, output: 'object' })

if (size.value < 690) {
return false
}
}

return true
}

async hasWindowsMedia() {
if (!is.windows) {
return true
}

const version = this.os.release

if (toInteger(version) < 10) {
// no windows 10
return true
}

if (!is.development) {
// regedit commands
regedit.setExternalVBSLocation(
getAppResources('vbs'),
)
}

const value = await new Promise((resolve) => {
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'))
})
})

return value
}
}

export const system = new System()

+ 5
- 3
src/electron/src/provider.js View File

@@ -1,6 +1,8 @@
import { AppError } from './scripts'
import * as services from './scripts/services'
import * as tools from './scripts/tools'
const { remote } = require('electron')

const { AppError } = remote.require('./modules/app-error')
const services = remote.require('./modules/services')
const tools = remote.require('./modules/tools')

// main process provider
window.$provider = {

+ 0
- 79
src/electron/src/scripts/tools/system.js View File

@@ -1,79 +0,0 @@
// 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.

const { filter } = require('lodash')
const si = require('systeminformation')
const isOnline = require('is-online')

class System {
/**
* @type {si.Systeminformation.GraphicsData}
*/
_graphics

/**
* @type {si.Systeminformation.CpuData}
*/
_cpu

/**
* @type {si.Systeminformation.MemData}
*/
_memory

/**
* @type {boolean}
*/
online

/**
*
*/
async setup() {
const [
graphics,
cpu,
mem,
online,
] = await Promise.all([
si.graphics(),
si.cpu(),
si.mem(),
isOnline(),
])

this._graphics = graphics
this._cpu = cpu
this._memory = mem
this.online = online
}

/**
* @return {Array}
*/
get graphics() {
return filter(this._graphics.controllers, { vendor: 'NVIDIA' })
}

/**
* @return {Number}
*/
get cores() {
return this._cpu.cores
}

/**
* @return {Number}
*/
get memoryTotal() {
return this._memory.total
}
}

export const system = new System()

+ 1
- 1
src/jsconfig.json View File

@@ -3,7 +3,7 @@
"baseUrl": ".",
"paths": {
"~": [
"./*"
"*"
],
"test/*": [
"test/*"

src/electron/src/scripts/index.js → src/modules/errors/index.js View File

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

export { AppError } from './error'
export { AppError } from './app-error'

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

@@ -113,6 +113,8 @@ module.exports = {
** You can extend webpack config here
*/
extend(config, { isClient, isDev }) {
// config.target = 'electron-renderer'

if (isDev) {
config.devtool = isClient ? 'source-map' : 'inline-source-map'


+ 2
- 2
src/package.json View File

@@ -21,7 +21,7 @@
"production": "env-cmd -e default,production --no-override",
"start:nuxt": "yarn development nuxt",
"start:babel": "yarn development babel electron/src --out-dir electron/dist --source-maps --watch --verbose",
"start:electron": "delay 3 && yarn development electron --remote-debugging-port=9222 .",
"start:electron": "yarn development electron .",
"build:nuxt": "yarn production nuxt build",
"build:babel": "yarn production babel electron/src --out-dir electron/dist --minified",
"build:electron": "yarn production electron-builder --publish=never --x64",
@@ -138,4 +138,4 @@
"tailwindcss-alpha": "hacknug/tailwindcss-alpha#feature/tests",
"webpack-cli": "^3.3.10"
}
}
}

+ 15
- 54
src/plugins/boot.js View File

@@ -25,81 +25,42 @@ tippy.setDefaultProps({
})

export default async ({ app }, inject) => {
// provider shortcuts
inject('provider', $provider)
inject('settings', $provider.services.settings)
inject('nucleus', $provider.services.nucleus)

console.log($provider)
// error handlers

/*
//---

// User settings
await $settings.init()
inject('settings', $settings)

// Analytics
// App settings
await $nucleus.init()
inject('nucleus', $nucleus)

// Error reporting
$rollbar.init()

//---

window.addEventListener('error', (error) => {
debug('Error captured', {
error,
type: typeof error,
})
window.addEventListener('error', (err) => {
logger.warn('Web error!', err)
WebError.handle(err)

WebError.handle(error)
return true
})

window.addEventListener('unhandledrejection', (rejection) => {
debug('Unhandled Rejection captured', {
error: rejection.reason,
type: typeof rejection.reason,
})

logger.warn('Web Unhandled rejection!', err)
WebError.handle(rejection.reason)

return true
})

Vue.config.errorHandler = (err) => {
logger.warn('VueJS error!', err)
WebError.handle(err)

throw err
}

//---

// DreamTime information
// dreamtime
dream.init()
window.$dream = dream
app.context.$dream = dream
inject('dream', dream)

// Platform information
await platform.init()
app.context.$platform = platform
inject('platform', platform)

// Updates information
updater.init()
app.context.$updater = updater
inject('updater', updater)

//---

// Nudify process
// nudify process
nudify.init()
app.context.$nudify = nudify
inject('nudify', nudify)

// axios - default headers
// $axios.setHeader('X-Requested-With', 'XMLHttpRequest')

// Debug
debug('The front-end is ready to render!', { app })
*/
// ready
logger.info('The front-end is ready!')
}

+ 50
- 0
src/plugins/setup.js View File

@@ -0,0 +1,50 @@
// 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 { existsSync, mkdirSync } from 'fs-extra'
import { AppError } from '../modules/errors'
import { system, paths } from '../modules/tools'
import { settings, nucleus, rollbar } from '../modules/services'

/**
* Create required directories.
*/
function createDirs() {
const modelsPath = paths.getModels('Uncategorized')

if (!existsSync(modelsPath)) {
mkdirSync(modelsPath, { recursive: true },
(error) => {
throw new AppError(`Models directory creation fail.`, { error })
})
}
}

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

export default async ({ app }, inject) => {
// system stats.
await system.setup()

// user settings.
await settings.setup()

// analytics.
await nucleus.setup()

// bug tracking.
await rollbar.setup()

createDirs()
}

Loading…
Cancel
Save