Browse Source

Code improvements, optimizations and more QoL.

tags/v1.4.4
Ivan Bravo Bravo 7 months ago
parent
commit
2d0174f169
45 changed files with 986 additions and 455 deletions
  1. 2
    0
      src/.eslintrc.js
  2. 0
    5
      src/assets/css/oldv.scss
  3. 0
    0
      src/assets/css/reset.scss
  4. 3
    3
      src/assets/css/tailwind.scss
  5. 0
    0
      src/assets/images/apps/dreampower.png
  6. 0
    0
      src/assets/images/apps/dreamtime.png
  7. 1
    1
      src/components/Layout/Navbar.vue
  8. 2
    0
      src/components/Layout/Navigation.vue
  9. 60
    50
      src/electron-builder.js
  10. 57
    37
      src/electron/src/index.js
  11. 21
    23
      src/electron/src/modules/app-error.js
  12. 13
    0
      src/electron/src/modules/index.js
  13. 41
    0
      src/electron/src/modules/ngrok.js
  14. 1
    1
      src/electron/src/modules/services/base.js
  15. 77
    41
      src/electron/src/modules/settings.js
  16. 8
    6
      src/electron/src/modules/tools/fs.js
  17. 2
    0
      src/electron/src/provider.js
  18. 2
    2
      src/layouts/default.vue
  19. 51
    0
      src/layouts/wizard.vue
  20. 2
    10
      src/middleware/checks.js
  21. 70
    0
      src/middleware/wizard.js
  22. 102
    56
      src/modules/app-error.js
  23. 1
    1
      src/modules/events.js
  24. 3
    3
      src/modules/file.js
  25. 1
    1
      src/modules/nudify/nudify.js
  26. 2
    2
      src/modules/nudify/photo-run.js
  27. 4
    4
      src/modules/nudify/photo.js
  28. 1
    1
      src/modules/services/base.js
  29. 1
    0
      src/modules/services/index.js
  30. 32
    6
      src/modules/services/logrocket.js
  31. 19
    14
      src/modules/services/rollbar.js
  32. 8
    7
      src/modules/system/requirements.js
  33. 1
    1
      src/modules/updater/dreamtime.js
  34. 88
    12
      src/nuxt.config.js
  35. 0
    155
      src/package.copy.json
  36. 3
    1
      src/package.json
  37. 11
    0
      src/package.min.json
  38. 1
    1
      src/pages/about.vue
  39. 105
    0
      src/pages/wizard/power.vue
  40. 96
    0
      src/pages/wizard/tos.vue
  41. 69
    0
      src/pages/wizard/welcome.vue
  42. 9
    5
      src/plugins/boot.js
  43. 10
    0
      src/plugins/setup.js
  44. 5
    5
      src/scripts/release.js
  45. 1
    1
      src/workers/fs/index.js

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

@@ -32,7 +32,9 @@ module.exports = {
],
root: true,
rules: {
"no-param-reassign": "off",
"class-methods-use-this": "off",
"no-trailing-spaces": "warn",
"comma-dangle": "warn",
"global-require": "off",
"import/default": "warn",

+ 0
- 5
src/assets/css/oldv.scss View File

@@ -1,5 +0,0 @@
// tippy.js
@import 'tippy.js/index.css';
@import 'tippy.js/themes/light.css';

@import '~cropperjs/src/css/cropper';

src/assets/css/base/_reset.scss → src/assets/css/reset.scss View File


+ 3
- 3
src/assets/css/tailwind.scss View File

@@ -1,6 +1,6 @@
@tailwind base;
@import './base/reset';
// @import './base/reset';
@tailwind components;
@import './components/all';
//@import './components/all';
@tailwind utilities;
@import './utilities/all';
//@import './utilities/all';

src/static/assets/images/dreampower.png → src/assets/images/apps/dreampower.png View File


src/static/assets/images/dreamtime.png → src/assets/images/apps/dreamtime.png View File


+ 1
- 1
src/components/Layout/Navbar.vue View File

@@ -55,7 +55,7 @@ export default {

methods: {
createError() {
throw new Error('UI test error.')
throw new Error('User Interface test error.')
},
},
}

+ 2
- 0
src/components/Layout/Navigation.vue View File

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

<script>
import { requirements } from '~/modules/system'

const { settings } = $provider

export default {

+ 60
- 50
src/electron-builder.js View File

@@ -1,40 +1,8 @@
/* eslint-disable no-template-curly-in-string */

const pkg = require('./package.json')

module.exports = {
appId: 'com.dreamnet.dreamtime',
productName: process.env.npm_package_displayName,
copyright: 'Copyright (C) DreamNet. All rights reserved.',
directories: {
output: '../dist',
},
files: [
'!**/node_modules/*/{CHANGELOG.md,README.md,README,readme.md,readme}',
'!**/node_modules/*/{test,__tests__,tests,powered-test,example,examples}',
'!**/node_modules/*.d.ts',
'!**/node_modules/.bin',
'!**/*.{iml,o,hprof,orig,pyc,pyo,rbc,swp,csproj,sln,xproj,vscode,env.example,eslintrc.json,prettierrc,tgz}',
'!.editorconfig',
'!**/._*',
'!**/{.DS_Store,.git,.hg,.svn,CVS,RCS,SCCS,.gitignore,.gitattributes}',
'!**/{__pycache__,thumbs.db,.flowconfig,.idea,.vs,.nyc_output}',
'!**/{appveyor.yml,.travis.yml,circle.yml}',
'!**/{npm-debug.log,yarn.lock,.yarn-integrity,.yarn-metadata.json}',
'!**/{jsconfig.json,electron-builder.js,.eslintrc.js,.env-cmdrc.js,.codeclimate.yml,.babelrc,tailwind.config.js,nucleus.json}',
'!{components,cli,layouts,middleware,mixins,pages,patches,plugins,scripts,store,third,coverage,.nuxt,test,workers}',
'!{static,assets}',
'!**/electron/src',
],
extraFiles: [
{
from: '.env',
to: '.env',
},
{
from: 'package.copy.json',
to: 'package.json',
},
],
const windows = {
win: {
target: 'nsis',
extraResources: [
@@ -48,6 +16,19 @@ module.exports = {
},
],
},
nsis: {
oneClick: false,
perMachine: false,
allowToChangeInstallationDirectory: true,
uninstallDisplayName: '${productName}',
deleteAppDataOnUninstall: true,
displayLanguageSelector: true,
menuCategory: true,
artifactName: '${productName}-v${version}-windows.${ext}',
},
}

const linux = {
linux: {
target: 'snap',
executableName: process.env.npm_package_name,
@@ -60,6 +41,12 @@ module.exports = {
},
],
},
snap: {
artifactName: '${productName}-v${version}-ubuntu.${ext}',
},
}

const macos = {
mac: {
target: 'dmg',
darkModeSupport: true,
@@ -78,25 +65,48 @@ module.exports = {
},
],
},
nsis: {
oneClick: false,
perMachine: false,
allowToChangeInstallationDirectory: true,
uninstallDisplayName: '${productName}',
deleteAppDataOnUninstall: true,
displayLanguageSelector: true,
menuCategory: true,
artifactName: '${productName}-v${version}-windows.${ext}',
},
snap: {
plugs: ['default', {
'personal-files': { read: ['$HOME'], write: ['$HOME'] },
}],
artifactName: '${productName}-v${version}-ubuntu.${ext}',
},
dmg: {
title: '${productName}',
artifactName: '${productName}-v${version}-macos.${ext}',
backgroundColor: '#000',
},
}

module.exports = {
appId: 'com.dreamnet.dreamtime',
productName: process.env.npm_package_displayName,
copyright: 'Copyright (C) DreamNet. All rights reserved.',
directories: {
output: '../dist',
},
files: [
'!**/node_modules/*/{CHANGELOG.md,README.md,README,readme.md,readme}',
'!**/node_modules/*/{test,__tests__,tests,powered-test,example,examples}',
'!**/node_modules/*.d.ts',
'!**/node_modules/.bin',
'!**/*.{iml,o,hprof,orig,pyc,pyo,rbc,swp,csproj,sln,xproj,vscode,env.example,eslintrc.json,prettierrc,tgz}',
'!.editorconfig',
'!**/._*',
'!**/{.DS_Store,.git,.hg,.svn,CVS,RCS,SCCS,.gitignore,.gitattributes}',
'!**/{__pycache__,thumbs.db,.flowconfig,.idea,.vs,.nyc_output}',
'!**/{appveyor.yml,.travis.yml,circle.yml}',
'!**/{npm-debug.log,yarn.lock,.yarn-integrity,.yarn-metadata.json}',
'!**/{jsconfig.json,electron-builder.js,.eslintrc.js,.env-cmdrc.js,.codeclimate.yml,.babelrc,tailwind.config.js,nucleus.json}',
'!{components,cli,layouts,middleware,mixins,pages,patches,plugins,scripts,store,third,coverage,.nuxt,test,workers}',
'!{static,assets}',
'!**/electron/src',
],
extraFiles: [
{
from: '.env',
to: '.env',
},
{
from: 'package.min.json',
to: 'package.json',
},
],
...windows,
...linux,
...macos,
}

+ 57
- 37
src/electron/src/index.js View File

@@ -9,17 +9,13 @@

import { startsWith } from 'lodash'
import { app, BrowserWindow, shell } from 'electron'
import http from 'http'
import { dirname, join } from 'path'
import { URL } from 'url'
import contextMenu from 'electron-context-menu'
import { dirname, resolve } from 'path'
import Logger from 'logplease'
import { enforceMacOSAppLocation } from 'electron-util'
import fs from 'fs-extra'
import { AppError } from './modules/app-error'
import { system } from './modules/tools/system'
import { existsSync, mkdirSync } from './modules/tools/fs'
import { getPath } from './modules/tools/paths'
import { settings } from './modules/settings'
import { settings, ngrok } from './modules'
import config from '~/nuxt.config'

const logger = Logger.create('electron')
@@ -27,7 +23,8 @@ const logger = Logger.create('electron')
// NuxtJS root directory
config.rootDir = dirname(dirname(__dirname))

if (process.env.NODE_ENV === 'production') {
if (process.env.name === 'production') {
// make sure that the working directory is where the executable is
process.chdir(getPath('exe', '..'))
}

@@ -37,20 +34,21 @@ class DreamApp {
*/
window


/**
*
*/
static async boot() {
// logger setup
Logger.setLogLevel(process.env.LOG || 'info')
Logger.setLogfile(getPath('userData', 'dreamtime.log'))
Logger.setOptions({
filename: getPath('userData', 'dreamtime.main.log'),
logLevel: process.env.LOG || 'debug',
})

logger.info('Booting...')

logger.debug({
env: process.env.name,
paths: {
appPath: app.getAppPath(),
exePath: app.getPath('exe'),
},
})
logger.debug(`Enviroment: ${process.env.name}`)
logger.debug(`App Path: ${app.getAppPath()}`)
logger.debug(`Exe Path: ${app.getPath('exe')}`)

// catch errors
process.on('uncaughtException', (err) => {
@@ -74,9 +72,10 @@ class DreamApp {
app.commandLine.appendSwitch('disable-renderer-backgrounding')

// user settings.
await settings.initialSetup()
await settings.boot()

if (settings.app ?.disableHardwareAcceleration) {
// this may increase performance on some systems.
if (settings.app?.disableHardwareAcceleration) {
app.disableHardwareAcceleration()
}
}
@@ -96,8 +95,12 @@ class DreamApp {
* Prepare the application.
*/
static async setup() {
// https://github.com/sindresorhus/electron-util#enforcemacosapplocation-macos
enforceMacOSAppLocation()
if (process.platform === 'darwin') {
const { enforceMacOSAppLocation } = require('electron-util')

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

// application exit.
app.on('will-quit', async (event) => {
@@ -110,13 +113,15 @@ class DreamApp {
app.exit()
})

// windows closed, no more to do.
// windows closed, exit.
app.on('window-all-closed', () => {
app.quit()
})

app.on('web-contents-created', (e, contents) => {
contents.on('will-navigate', (event, navigationUrl) => {
const { URL } = require('url')

const url = new URL(navigationUrl)

const host = process.env.SERVER_HOST
@@ -149,6 +154,8 @@ class DreamApp {
})
})

const contextMenu = require('electron-context-menu')

// allow save image option
contextMenu({
showSaveImageAs: true,
@@ -158,18 +165,25 @@ class DreamApp {
await system.setup()

// user settings.
await settings.initialSetup()
await settings.setup()

//
this.createDirs()

if (process.env.name === 'development') {
const address = await ngrok.connect()
logger.debug(`Proxy for debugging: ${address}`)
}
}

/**
*
*/
// eslint-disable-next-line no-empty-function
static async shutdown() {

if (process.env.name === 'development') {
await ngrok.disconnect()
}
}

/**
@@ -185,11 +199,11 @@ class DreamApp {
minWidth: 1200,
minHeight: 700,
frame: false,
icon: join(config.rootDir, 'dist', 'icon.ico'),
icon: resolve(config.rootDir, 'dist', 'icon.ico'),
webPreferences: {
nodeIntegration: true,
nodeIntegrationInWorker: true,
preload: join(app.getAppPath(), 'electron', 'dist', 'provider.js'),
preload: resolve(app.getAppPath(), 'electron', 'dist', 'provider.js'),
},
})

@@ -221,6 +235,8 @@ class DreamApp {
static pollUi() {
logger.debug(`Requesting status from the server: ${this.uiUrl}`)

const http = require('http')

http
.get(this.uiUrl, (response) => {
if (response.statusCode === 200) {
@@ -244,7 +260,7 @@ class DreamApp {
*/
static getUiUrl() {
if (!config.dev) {
return join(config.rootDir, 'dist', 'index.html')
return resolve(config.rootDir, 'dist', 'index.html')
}

return `http://localhost:${config.server.port}`
@@ -254,14 +270,18 @@ class DreamApp {
* Create required directories.
*/
static createDirs() {
const modelsPath = join(settings.folders.models, 'Uncategorized')

if (!existsSync(modelsPath)) {
mkdirSync(modelsPath, { recursive: true },
(error) => {
throw new AppError(`Models directory creation fail.`, { error })
})
}
const dirs = [
resolve(settings.folders.models, 'Uncategorized'),
settings.folders.masks,
]

dirs.forEach((dir) => {
try {
fs.ensureDirSync(dir)
} catch (error) {
throw new AppError(`Could not create the directory:\n${dir}`, { error })
}
})
}
}

@@ -269,7 +289,7 @@ app.on('ready', async () => {
try {
await DreamApp.start()
} catch (error) {
throw new AppError(error, { title: `Failed to start correctly.`, fatal: true })
throw new AppError(error, { title: `Failed to start correctly.`, level: 'error' })
}
})


+ 21
- 23
src/electron/src/modules/app-error.js View File

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

import {
isError, isString, isObject, isArray,
isError, isString, isObject, isArray, attempt,
} from 'lodash'
import { app, dialog } from 'electron'

const logger = require('logplease').create('app-error:main')
const logger = require('logplease').create('error:main')

/**
* @typedef {Object} ErrorOptions
@@ -32,9 +32,8 @@ export class AppError extends Error {
*/
options = {
title: null,
level: 'error',
level: 'warn',
error: null,
fatal: false,
quiet: false,
}

@@ -76,25 +75,24 @@ export class AppError extends Error {
show() {
dialog.showErrorBox(
this.options.title || 'A problem has occurred.',
this.message,
`${this.message}\n\n<code>${this.options.error?.message}</code>`,
)
}

handle() {
const {
level, quiet, fatal, error,
level, quiet, error,
} = this.options

// logger
logger[level](this.message, {
error,
})
attempt(() => {
logger[level](this.message, { error })

if (!quiet) {
this.show()
}
if (!quiet) {
this.show()
}
})

if (fatal) {
if (level === 'error') {
app.quit()
}
}
@@ -103,21 +101,21 @@ export class AppError extends Error {
let appError = error

if (!(error instanceof AppError)) {
let reportError
let exception

if (isError(error)) {
reportError = error
exception = error
} else if (isObject(error) || isArray(error)) {
reportError = new Error(JSON.stringify(error))
exception = attempt(() => new Error(JSON.stringify(error)))
} else {
reportError = new Error(error)
exception = new Error(error)
}

appError = new AppError(`The application has encountered an unexpected error:\n<code>${reportError?.message}</code>`,
{
error: reportError,
title: 'Unexpected error!',
})
appError = new AppError(`The application has encountered an unexpected error.`, {
error: exception,
title: 'Unexpected error!',
level: 'error',
})
}

appError.handle()

+ 13
- 0
src/electron/src/modules/index.js View File

@@ -0,0 +1,13 @@
// 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 * as ngrok from './ngrok'

export { settings } from './settings'
export { ngrok }

+ 41
- 0
src/electron/src/modules/ngrok.js View File

@@ -0,0 +1,41 @@
// 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'

let address

export async function connect() {
if (process.env.name !== 'development') {
return null
}

if (!isNil(address)) {
return address
}

const ngrok = require('ngrok')

if (process.env.NGROK_ACCESS_TOKEN) {
await ngrok.authtoken(process.env.NGROK_ACCESS_TOKEN)
}

address = await ngrok.connect(process.env.SERVER_PORT)

return address
}

export function disconnect() {
const ngrok = require('ngrok')
return ngrok.disconnect()
}

export function getAddress() {
return address
}

+ 1
- 1
src/electron/src/modules/services/base.js View File

@@ -92,7 +92,7 @@ export class BaseService {
static make(obj) {
if (!obj) {
// eslint-disable-next-line no-param-reassign
obj = new this()
obj = new this
}

return makeServiceProxy(obj)

+ 77
- 41
src/electron/src/modules/settings.js View File

@@ -11,7 +11,7 @@ import fs from 'fs-extra'
import {
round, cloneDeep, isNil, isEmpty, isPlainObject, get, set,
} from 'lodash'
import uuid from 'uuid'
import { AppError } from './app-error'
import { paths, system } from './tools'

const logger = require('logplease').create('electron:scripts:services:settings')
@@ -50,12 +50,12 @@ class Settings {
return
}

if (!fs.existsSync(this.path)) {
return
try {
this.payload = fs.readJsonSync(this.path)
logger.debug('Settings:', this.payload)
} catch (error) {
console.error(error)
}

this.payload = fs.readJsonSync(this.path)
logger.debug(this.payload)
}

/**
@@ -63,7 +63,7 @@ class Settings {
* This function is called automatically if you set a first level variable.
*/
async save() {
fs.writeJsonSync(this.path, this.payload)
fs.writeJsonSync(this.path, this.payload, { spaces: 2 })
}

/**
@@ -102,23 +102,53 @@ class Settings {
/**
*
*/
async initialSetup() {
this._loadInitital()
async boot() {
this._loadDefault()
await this.load()
}

_loadInitital() {
/**
* Load the default configuration (and the current version)
*/
_loadDefault() {
const hasGPU = system.graphics.length > 0
const cores = round(system.cores / 2) || 4
const cores = round(system.cores / 2) || 1

const uuid = require('uuid')

this.payload = {
version: 5,
welcome: true,
version: 6,
user: uuid(),

wizard: {
welcome: false,
tos: false,
user: false,
telemetry: false,
},

app: {
disableHardwareAcceleration: true,
uploadMode: 'add-queue',
uploadMode: 'none',
},

notifications: {
run: false,
allRuns: true,
update: true,
},

folders: {
cropped: paths.getPath('temp'),
models: paths.getPath('pictures', 'DreamTime'),
masks: paths.getPath('temp'),
cli: paths.getPath('userData', 'dreampower'),
},

telemetry: {
bugs: true,
dom: true,
domPrivate: false,
},

processing: {
@@ -166,36 +196,19 @@ class Settings {
},

advanced: {
scaleMode: 'auto-rescale',
scaleMode: 'auto-resize',
transformMode: 'normal',
useColorTransfer: false,
useWaifu: false,
},
},

notifications: {
run: false,
allRuns: true,
update: true,
},

folders: {
cropped: paths.getPath('temp'),
models: paths.getPath('userData', 'models'),
masks: paths.getPath('temp'),
cli: paths.getPath('userData', 'dreampower'),
},

telemetry: {
enabled: true,
},
}

this._default = cloneDeep(this.payload)
}

/**
* Create the settings file if it does not exist
* Create the settings file if it does not exist.
*/
async _create() {
if (fs.existsSync(this.path)) {
@@ -205,13 +218,12 @@ class Settings {
try {
fs.outputFileSync(this.path, JSON.stringify(this._default, null, 2))
} catch (error) {
throw new Error(`Settings creation fail. Please make sure the program has the necessary permissions to write to:\n${this.path}\n\n${error}`)
throw new AppError(`Could not create settings file. Please make sure the program has the necessary permissions to write to:\n${this.path}`, { fatal: true, error })
}
}

/**
* Check if it is necessary to update the settings file.
* legacy code :WutFaceW:
* Upgrade the settings file.
*/
async _upgrade() {
if (this.payload?.version === this._default.version) {
@@ -222,7 +234,7 @@ class Settings {

const currentSettings = cloneDeep(this.payload)

// Upgrade 1 -> 2
// 1 -> 2
if (this.payload?.version === 1 && this._default.version >= 2) {
this.payload.version = 2
this.payload.preferences = this._default.preferences
@@ -243,7 +255,7 @@ class Settings {
this.payload.preferences.pubicHair.size = pubicHairSize
}

// Upgrade 2 -> 3
// 2 -> 3
if (this.payload?.version === 2 && this._default.version >= 3) {
const { processing, preferences } = currentSettings

@@ -280,7 +292,7 @@ class Settings {
}
}

// Upgrade 3 -> 4
// 3 -> 4
if (this.payload?.version === 3 && this._default.version >= 4) {
this.payload.version = 4
this.payload.app = {
@@ -289,6 +301,32 @@ class Settings {
}
}

// 4 -> 5
if (this.payload?.version === 4 && this._default.version === 5) {
this.payload.version = 5
this.payload.preferences.advanced.transformMode = 'normal'
}

// 5 -> 6
if (this.payload?.version === 5 && this._default.version === 6) {
this.payload.version = 6

delete this.payload.welcome

this.payload.wizard = {
welcome: false,
tos: false,
user: false,
telemetry: false,
}

this.payload.telemetry = {
bugs: this.payload.enabled,
dom: true,
domPrivate: false,
}
}

this.save()
}
}
@@ -312,7 +350,6 @@ export function make(obj) {
return undefined
},

/* eslint-disable no-param-reassign */
set: (obj, prop, value) => {
if (!isNil(obj.payload)) {
if (prop in obj.payload) {
@@ -326,7 +363,6 @@ export function make(obj) {
obj[prop] = value
return true
},
/* eslint-enable no-param-reassign */
})
}


+ 8
- 6
src/electron/src/modules/tools/fs.js View File

@@ -5,13 +5,8 @@ import {
createWriteStream, createReadStream,
} from 'fs-extra'
import { app, dialog } from 'electron'
import { is, platform } from 'electron-util'
import EventBus from 'js-event-bus'
import axios from 'axios'
import unzipper from 'unzipper'
import deferred from 'deferred'
import sevenBin from '7zip-bin'
import { extractFull } from 'node-7z'
import { getAppResourcesPath } from './paths'
import { AppError } from '../app-error'

@@ -59,6 +54,8 @@ export function writeDataURL(path, dataURL) {
* @param {string} destinationPath
*/
export function extractZip(path, destinationPath) {
const unzipper = require('unzipper')

const def = deferred()

const stream = createReadStream(path).pipe(unzipper.Extract({ path: destinationPath }))
@@ -80,11 +77,15 @@ export function extractZip(path, destinationPath) {
* @param {string} destinationPath
*/
export function extractSeven(path, destinationPath) {
const { is, platform } = require('electron-util')
const { extractFull } = require('node-7z')

const def = deferred()

let pathTo7zip

if (is.development) {
const sevenBin = require('7zip-bin')
pathTo7zip = sevenBin.path7za
} else {
const binName = platform({
@@ -118,7 +119,8 @@ export function extractSeven(path, destinationPath) {
* @param {Object} [options]
*/
export function download(url, options = {}) {
const bus = new EventBus()
const EventBus = require('js-event-bus')
const bus = new EventBus

// eslint-disable-next-line no-param-reassign
options = {

+ 2
- 0
src/electron/src/provider.js View File

@@ -4,12 +4,14 @@ const { make } = require('./modules/settings')
const util = remote.require('electron-util')
const { settingsRaw } = remote.require('./modules/settings')
const tools = remote.require('./modules/tools')
const ngrok = remote.require('./modules/ngrok')

// tools provider
window.$provider = {
...tools,

settings: make(settingsRaw),
ngrok,

api: util.api,
util,

+ 2
- 2
src/layouts/default.vue View File

@@ -16,11 +16,11 @@

<script>
export default {
middleware: ['checks'],
middleware: ['wizard'],
}
</script>

<style lang="scss">
<style lang="scss" scoped>
.layout {
@apply h-full;


+ 51
- 0
src/layouts/wizard.vue View File

@@ -0,0 +1,51 @@
<template>
<div class="layout">
<layout-topbar />

<div id="layout-content" class="layout__content">
<nuxt />
</div>
</div>
</template>

<script>


export default {

}
</script>

<style lang="scss" scoped>
.layout {
@apply h-full;

display: grid;
grid-template-columns: 100%;
grid-template-rows: 30px 1fr;
grid-template-areas: "topbar" "content";

.layout__topbar {
grid-area: topbar;
}

.layout__content {
@apply relative overflow-hidden overflow-y-auto;
@apply p-6;
grid-area: content;
height: calc(100vh - 30px);
}
}
</style>

<style lang="scss">
.layout__header {
@apply flex justify-center items-center;
@apply text-3xl font-semibold mb-6;
height: 60px;

h1 {
@apply text-xl text-white;
}
}
</style>

+ 2
- 10
src/middleware/checks.js View File

@@ -9,23 +9,14 @@

import { requirements } from '~/modules/system'

const { system, settings } = $provider

/**
* Detects if the user has what it takes to run the program,
* otherwise redirects him to the appropriate page.
*/
export default function ({ route, redirect }) {
/*
window.$redirect = redirect

if (settings.welcome) {
// First time execution!
if (route.path !== '/welcome') {
redirect('/welcome')
}

return
}

if (!requirements.power.installed || !requirements.power.compatible) {
// DreamPower is missing
@@ -45,4 +36,5 @@ export default function ({ route, redirect }) {
redirect('/about#checkpoints')
}
}
*/
}

+ 70
- 0
src/middleware/wizard.js View File

@@ -0,0 +1,70 @@
// 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 { requirements } from '~/modules/system'

const { wizard } = $provider.settings

export default function ({ route, redirect }) {
window.$redirect = redirect

if (!wizard.welcome) {
if (route.path !== '/wizard/welcome') {
redirect('/wizard/welcome')
}

return
}

if (!wizard.tos) {
if (route.path !== '/wizard/tos') {
redirect('/wizard/tos')
}

return
}

if (!requirements.power.installed) {
if (route.path !== '/wizard/power') {
redirect('/wizard/power')
}

return
}

if (!requirements.power.checkpoints) {
if (route.path !== '/wizard/checkpoints') {
redirect('/wizard/checkpoints')
}

return
}

if (!wizard.telemetry) {
if (route.path !== '/wizard/telemetry') {
redirect('/wizard/telemetry')
}

return
}

if (!wizard.user) {
if (route.path !== '/wizard/user') {
redirect('/wizard/user')
}

return
}

if (!wizard.telemetry) {
if (route.path !== '/wizard/telemetry') {
redirect('/wizard/telemetry')
}
}
}

+ 102
- 56
src/modules/app-error.js View File

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

import {
isError, isString, isObject, isArray, pick,
isError, isString, isObject, isArray, attempt,
} from 'lodash'
import { mapStackTrace } from 'sourcemapped-stacktrace'
import Swal from 'sweetalert2'
import { logrocket } from '~/modules/services'
import { logrocket, rollbar } from '~/modules/services'

const logger = require('logplease').create('app-error:renderer')
const logger = require('logplease').create('error:renderer')

const { app } = $provider.api

@@ -32,6 +33,7 @@ export class AppError extends Error {
*/
options = {
title: null,
message: null,
level: 'error',
error: null,
fatal: false,
@@ -48,22 +50,25 @@ export class AppError extends Error {
* @param {string} message
* @param {ErrorOptions} options
*/
constructor(input, options = {}) {
if (isString(input)) {
super(input)
} else if (isError(input)) {
super(input.message)
constructor(message, options = {}) {
if (isError(message)) {
// that's better.
options.error = message
message = message.message
}

this.stack = input.stack
const { error } = options

this.options.error = input
if (isError(error)) {
// we want this error to be the closest to the original
super(error.message)

if (input.options) {
this.options = {
...this.options,
...input.options,
}
if (error.options) {
// inherit error options.
this.options = error.options
}
} else if (isString(message)) {
super(message)
} else {
super()
}
@@ -71,42 +76,81 @@ export class AppError extends Error {
this.options = {
...this.options,
...options,
message,
}

if (this.options.level === 'warning') {
// warning does not exist in logger.
this.options.level = 'warn'
}
}

report() {
/*
if (process.env.NODE_ENV === 'development') {
this.reportUrl = `https://rollbar.com/occurrence/uuid/?uuid={EXAMPLE}`
/**
* Copy the original error information.
*/
async copyError() {
const { error } = this.options

if (!isError(error)) {
return
}
*/

const { level } = this.options
// transform the original stack to the source-map stack.
const getStack = () => new Promise((resolve) => {
mapStackTrace(error.stack, (stack) => {
resolve(`${error.message}\n${stack.join('\n')}`)
}, { cacheGlobally: true })
})

if (!logrocket.enabled || level !== 'error') {
return
}
// copy pasta
this.name = error.name
this.stack = await getStack()
}

try {
const error = this.options.error || this
/**
* Report the error to the logger, bug and session tracking services.
*/
report() {
const { level, error } = this.options
let rollbarResponse

console.log(logrocket)
// logger.
logger[level](this)

logrocket.captureException(error, {
extra: this.options,
})
// bug tracking.
if (rollbar.enabled && level === 'error') {
try {
rollbarResponse = rollbar[level](this, {
...this.options,
sessionURL: logrocket.sessionURL,
})

this.reported = true
} catch (err) {
logger.warn('Rollbar report fail!', err)
}
}

// session tracking.
if (logrocket.enabled && level === 'error') {
try {
logrocket.captureException(error || this, {
extra: {
...this.options,
rollbarURL: `https://rollbar.com/occurrence/uuid/?uuid=${rollbarResponse?.uuid}`,
},
})

this.reported = true
} catch (err) {
logger.warn('LogRocket report fail!', err)
this.reported = true
} catch (err) {
logger.warn('LogRocket report fail!', err)
}
}
}

/**
* Show the error to the user.
*/
show() {
let icon = 'error'

@@ -120,52 +164,54 @@ export class AppError extends Error {

Swal.fire({
title: this.options.title,
html: this.message,
html: `${this.options.message}<br><br><pre>${this.message}</pre>`,
icon,
footer: this.reported ? `<code>This problem has been reported to the developers.</code>` : null,
footer: this.reported ? `<code>๐Ÿž This problem has been reported to DreamNet.<br>It will be fixed as soon as possible.</code>` : null,
})
}

handle() {
const {
level, quiet, fatal, error,
} = this.options
/**
*
*/
async handle() {
const { quiet, fatal, error } = this.options

// logger
logger[level](this.message, {
error,
})
await this.copyError(error)

this.report()
attempt(() => {
this.report()

if (!quiet) {
this.show()
}
if (!quiet) {
this.show()
}
})

if (fatal) {
app.quit()
}
}

/**
*
*/
static handle(error) {
let appError = error

if (!(error instanceof AppError)) {
let reportError
let exception

if (isError(error)) {
reportError = error
exception = error
} else if (isObject(error) || isArray(error)) {
reportError = new Error(JSON.stringify(error))
exception = new Error(JSON.stringify(error))
} else {
reportError = new Error(error)
exception = new Error(error)
}

appError = new AppError(`The application has encountered an unexpected error:\n<pre>${reportError?.message}</pre>`,
{
error: reportError,
title: 'Unexpected error!',
})
appError = new AppError(`Woah! An error has occurred and we do not know why.<br>Please try again.`, {
error: exception,
title: 'Unexpected error!',
})
}

appError.handle()

+ 1
- 1
src/modules/events.js View File

@@ -9,4 +9,4 @@

import EventBus from 'js-event-bus'

export const events = new EventBus()
export const events = new EventBus

+ 3
- 3
src/modules/file.js View File

@@ -36,7 +36,7 @@ export class File {
* @param {*} filepath
*/
static fromPath(filepath) {
const file = new this()
const file = new this
return file.open(filepath)
}

@@ -48,7 +48,7 @@ export class File {
directory: getPath('temp'),
})

const file = new this()
const file = new this
await file.open(filepath)

return file
@@ -58,7 +58,7 @@ export class File {
*
*/
static fromMetadata(metadata) {
const file = new this()
const file = new this
return file.setMetadata(metadata)
}


+ 1
- 1
src/modules/nudify/nudify.js View File

@@ -83,7 +83,7 @@ export class Nudify {
afterProcessDelay: 500,
batchSize: 1,
concurrent: 1,
store: new MemoryStore(),
store: new MemoryStore,
})

this.queue.on('task_queued', (photoId, photo) => {

+ 2
- 2
src/modules/nudify/photo-run.js View File

@@ -67,7 +67,7 @@ export class PhotoRun {
/**
* @type {Timer}
*/
timer = new Timer()
timer = new Timer

/**
* @type {Object}
@@ -130,7 +130,7 @@ export class PhotoRun {
this.status = 'pending'
this.failed = false

this.timer = new Timer()
this.timer = new Timer
}

toObject() {

+ 4
- 4
src/modules/nudify/photo.js View File

@@ -47,7 +47,7 @@ export class Photo {
/**
* @type {EventBus}
*/
events = new EventBus()
events = new EventBus

/**
* @type {string}
@@ -86,7 +86,7 @@ export class Photo {
/**
* @type {Timer}
*/
timer = new Timer()
timer = new Timer

/**
* @type {require('cropperjs').default}
@@ -309,7 +309,7 @@ export class Photo {
afterProcessDelay: 500,
batchSize: 1,
concurrent: 1,
store: new MemoryStore(),
store: new MemoryStore,
})

this.queue.on('drain', () => {
@@ -356,7 +356,7 @@ export class Photo {
reset() {
this.status = 'pending'

this.timer = new Timer()
this.timer = new Timer

this.runs = []
}

+ 1
- 1
src/modules/services/base.js View File

@@ -36,7 +36,7 @@ export class BaseService {
* @return {BaseService}
*/
static make() {
return new Proxy(new this(), {
return new Proxy(new this, {
get: (obj, prop) => {
if (prop in obj) {
return obj[prop]

+ 1
- 0
src/modules/services/index.js View File

@@ -9,3 +9,4 @@

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

+ 32
- 6
src/modules/services/logrocket.js View File

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

import { isString, get } from 'lodash'
import { isString, endsWith } from 'lodash'
import LogRocket from 'logrocket'
import { BaseService } from './base'
import { nucleus } from './nucleus'

const { settings, system } = $provider
const { telemetry } = settings

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

const privateExtensions = ['.jpg', '.jpeg', '.png', '.gif']

/**
* https://logrocket.com/
* Session tracking.
*/
class LogRocketService extends BaseService {
/**
* @type {string}
@@ -31,6 +38,9 @@ class LogRocketService extends BaseService {
return isString(this.accessToken)
}

/**
* @type {string}
*/
get release() {
return process.env.GITHUB_SHA || process.env.npm_package_version
}
@@ -42,9 +52,26 @@ class LogRocketService extends BaseService {
return {
release: this.release,
shouldCaptureIP: false,
/*dom: {
baseHref: nucleus.urls?.internal?.cdn || '',
}, */
network: {
requestSanitizer(request) {
if (!telemetry.domPrivate) {
// the user does not want to send private dom.
privateExtensions.forEach((extension) => {
if (endsWith(request.url.toLowerCase(), extension)) {
// scrub web address photo.
request.url = '[private-photo]'
}
})
}
},
responseSanitizer(request) {
console.log(request)
},
},
dom: {
isEnabled: telemetry.dom,
baseHref: $provider.ngrok.getAddress() || nucleus.urls?.internal?.cdn || null,
},
}
}

@@ -54,10 +81,9 @@ class LogRocketService extends BaseService {
}

try {
LogRocket.init(this.accessToken)
LogRocket.init(this.accessToken, this.config)
LogRocket.identify(settings.user || 'unknown', {
settings: settings.payload,

})

this.service = LogRocket

+ 19
- 14
src/modules/services/rollbar.js View File

@@ -8,27 +8,28 @@
// Written by Ivan Bravo Bravo <ivan@dreamnet.tech>, 2019.

import {
isNil, isString, get,
isNil, isString,
} from 'lodash'
import { execSync } from 'child_process'
import Rollbar from 'rollbar'
import { remote } from 'electron'
import { BaseService } from './base'
import { settings } from './settings'
import { nucleus } from './nucleus'
import { system } from '../tools/system'

const { settings, system } = $provider
const { execSync } = remote.require('child_process')

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

/**
* https://rollbar.com
* Bug tracking service.
* Bug tracking.
*/
class RollbarService extends BaseService {
/**
* @type {string}
*/
get accessToken() {
return process.env.ROLLBAR_ACCESS_TOKEN || get(nucleus, 'keys.rollbar')
return process.env.ROLLBAR_ACCESS_TOKEN || nucleus.keys?.rollbar
}

/**
@@ -41,7 +42,7 @@ class RollbarService extends BaseService {
/**
* @type {string}
*/
get codeVersion() {
get release() {
try {
return process.env.GITHUB_SHA || execSync('git rev-parse HEAD').toString().trim()
} catch (err) {
@@ -58,20 +59,24 @@ class RollbarService extends BaseService {
captureUncaught: false,
captureUnhandledRejections: false,
captureIp: 'anonymize',
enabled: settings.telemetry.enabled,
verbose: process.env.NODE_ENV === 'development',
enabled: settings.telemetry.bugs,
verbose: process.env.name === 'development',
logLevel: 'info',
nodeSourceMaps: true,
reportLevel: 'error',
reportLevel: 'warning',
payload: {
environment: process.env.NODE_ENV,
environment: process.env.name,
person: {
id: settings.user,
},
server: {
root: 'webpack:///',
},
client: {
javascript: {
source_map_enabled: true,
code_version: this.codeVersion,
guess_uncaught_frames: true,
code_version: this.release,
},
},
settings: settings.payload,
@@ -93,10 +98,10 @@ class RollbarService extends BaseService {
}

try {
this._service = new Rollbar(this.config)
this.service = new Rollbar(this.config)
this.enabled = true

logger.info('Rollbar enabled!')
logger.info('Rollbar started!')
logger.debug(this.accessToken)
} catch (err) {
logger.warn('Rollbar setup failed!', err)

+ 8
- 7
src/modules/system/requirements.js View File

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

import { isNil, isString, toInteger } from 'lodash'
import { isNil, startsWith } from 'lodash'
import { remote } from 'electron'
import { nucleus } from '../services'

const logger = require('logplease').create('app:system:requirements')

const { system, fs } = $provider
const { is } = $provider.util
const { remote } = $provider.api
const { getVersion, isInstalled } = $provider.power
const { getAppResourcesPath, getPowerPath, getCheckpointsPath } = $provider.paths
const { getAppResourcesPath, getCheckpointsPath } = $provider.paths

export const requirements = {
power: {
@@ -74,9 +74,10 @@ export const requirements = {
}

const compareVersions = require('compare-versions')
let version

try {
const version = await getVersion()
version = await getVersion()
const currentVersion = process.env.npm_package_version

const minimum = nucleus.v1?.projects?.dreamtime?.releases[`v${currentVersion}`]?.dreampower?.minimum || 'v0.0.1'
@@ -92,7 +93,7 @@ export const requirements = {

return true
} catch (err) {
logger.warn('An error occurred while verifying the version of DreamPower.', err)
logger.warn(`DreamPower version verification failed. (${version}).`, err)
return false
}
},
@@ -140,8 +141,8 @@ export const requirements = {

const version = system.os.release

if (toInteger(version) < 10) {
// no windows 10
if (!startsWith(version, '10')) {
// no windows 10.
return true
}


+ 1
- 1
src/modules/updater/dreamtime.js View File

@@ -68,4 +68,4 @@ class DreamTimeUpdater extends BaseUpdater {
}
}

export const dreamtime = new DreamTimeUpdater()
export const dreamtime = new DreamTimeUpdater

+ 88
- 12
src/nuxt.config.js View File

@@ -32,9 +32,70 @@ module.exports = {
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
// { 'http-equiv': 'Content-Security-Policy', content: 'default-src \'self\'; script-src \'self\' \'unsafe-inline\' https://cdn.logrocket.io https://cdn.lr-ingest.io; worker-src \'self\' \'unsafe-inline\' data: blob:; object-src \'none\'; style-src \'self\' \'unsafe-inline\' https://fonts.googleapis.com; img-src \'self\' data:; media-src \'self\' data:; frame-src \'self\' https://*.dreamnet.tech; font-src *; connect-src \'self\' http://localhost:* https://*.dreamnet.tech wss://app.nucleus.sh https://nucleus.sh https://*.logrocket.io https://r.lr-ingest.io https://*.github.com' },
],
},

/**
*
*/
render: {
csp: {
hashAlgorithm: 'sha256',
policies: {
'default-src': [
'self',
],
'script-src': [
'self',
'unsafe-inline',
'https://cdn.logrocket.io',
'https://cdn.lr-ingest.io',
],
'worker-src': [
'self',
'unsafe-inline',
'data:',
'blob:',
],
'object-src': [
'none',
],
'style-src': [
'self',
'unsafe-inline',
'https://fonts.googleapis.com',
],
'img-src': [
'self',
'data:',
],
'media-src': [
'self',
'data:',
],
'frame-src': [
'self',
'https://*.dreamnet.tech',
],
'font-src': [
'*',
],
'connect-src': [
'self',
'http://localhost:*',
'https://*.dreamnet.tech',
'wss://app.nucleus.sh',
'https://nucleus.sh',
'https://*.logrocket.io',
'https://r.lr-ingest.io',
'https://*.github.com',
],
},
addMeta: true,
},
},

/*
** Customize the progress-bar color
*/
@@ -48,14 +109,23 @@ module.exports = {
'cropperjs/dist/cropper.css',
'tui-image-editor/dist/tui-image-editor.css',
'tui-color-picker/dist/tui-color-picker.css',

'~/assets/css/tailwind.scss',
'~/assets/css/reset.scss',
'~/assets/css/components/_all.scss',
'~/assets/css/utilities/_all.scss',
'~/assets/css/fonts.scss',
],

/*
** Plugins to load before mounting the App
*/
plugins: ['~/plugins/boot.js', '~/plugins/setup.js', '~/plugins/fontawesome.js', '~/components'],
plugins: [
'~/plugins/boot.js',
'~/plugins/setup.js',
'~/plugins/fontawesome.js',
'~/components',
],

/*
** Nuxt.js dev-modules
@@ -63,6 +133,8 @@ module.exports = {
buildModules: [
// Doc: https://github.com/nuxt-community/eslint-module
'@nuxtjs/eslint-module',
// Doc: https://github.com/Developmint/nuxt-purgecss
'nuxt-purgecss',
// Doc: https://github.com/nuxt-community/nuxt-tailwindcss
'@nuxtjs/tailwindcss',
],
@@ -83,7 +155,8 @@ module.exports = {
*
*/
purgeCSS: {
whitelistPatterns: [/tippy/, /cropper/, /tui/, /color-picker/],
enabled: !dev,
whitelistPatterns: [/tippy/, /cropper/, /tui/, /color-picker/, /swal2/, /text-/, /nuxt/, /pre/, /svg/],
},

/**
@@ -104,11 +177,11 @@ module.exports = {
build: {
parallel: true,

hardSource: dev,
hardSource: false,

cache: dev,
cache: false,

extractCSS: !dev,
extractCSS: true,

/**
*
@@ -154,11 +227,14 @@ module.exports = {
*/
optimization: {
splitChunks: {
// minSize: 30000,
// maxSize: 3000000,
cacheGroups: {
commons: {
vendors: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
reuseExistingChunk: true,
},
},
},
@@ -168,6 +244,8 @@ module.exports = {
** You can extend webpack config here
*/
extend(config, { isDev }) {
const webpack = require('webpack')

config.target = 'electron-renderer'

config.module.rules.push({
@@ -176,15 +254,13 @@ module.exports = {
exclude: /(node_modules)/,
})

// eslint-disable-next-line no-useless-escape
config.plugins.push(new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en/))

if (isDev) {
config.devtool = 'source-map'
config.devtool = 'inline-source-map'
} else {
config.output.publicPath = './_nuxt/'

const webpack = require('webpack')

// eslint-disable-next-line no-useless-escape
config.plugins.push(new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en/))
}
},
},

+ 0
- 155
src/package.copy.json View File

@@ -1,155 +0,0 @@
{
"name": "dreamtime",
"displayName": "DreamTime",
"description": "DreamTime allows you to nudify photos of people.",
"author": "DreamNet",
"homepage": "https://time.dreamnet.tech",
"version": "1.2.0",
"main": "electron/dist/index.js",
"license": "GPL-3.0-only",
"private": true,
"repository": {
"type": "git",
"url": "git+https://github.com/dreamnettech/dreamtime.git"
},
"bugs": {
"url": "https://github.com/dreamnettech/dreamtime/issues"
},
"scripts": {
"lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
"development": "env-cmd -e default,development --no-override",
"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": "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",
"build": "yarn build:nuxt && yarn build:babel && yarn build:electron",
"preview:electron": "env-cmd -e default,production,preview --no-override electron .",
"preview": "yarn build:nuxt && yarn build:babel && yarn preview:electron"
},
"lint-staged": {
"*.{js,vue}": "eslint"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"engines": {
"node": ">=10.0.0"
},
"os": [
"win32",
"darwin",
"linux"
],
"cpu": [
"x64"
],
"dependencies": {
"7zip-bin": "^5.0.3",
"@fortawesome/fontawesome-svg-core": "^1.2.25",
"@fortawesome/free-brands-svg-icons": "^5.11.2",
"@fortawesome/free-regular-svg-icons": "^5.11.2",
"@fortawesome/free-solid-svg-icons": "^5.11.2",
"@fortawesome/vue-fontawesome": "^0.1.8",
"@nuxtjs/dotenv": "^1.4.1",
"@nuxtjs/pwa": "^2.6.0",
"axios": "^0.19.0",
"better-queue": "^3.8.10",
"better-queue-memory": "^1.0.4",
"clipboard": "^2.0.4",
"compare-versions": "^3.5.1",
"cropperjs": "^1.5.6",
"cryptr": "^6.0.1",
"debug": "^4.1.1",
"deferred": "^0.7.11",
"delay": "^4.3.0",
"electron-context-menu": "^0.15.1",
"electron-util": "^0.13.0",
"filesize": "^6.0.1",
"form-data": "^3.0.0",
"fs-extra": "^8.1.0",
"gpu-info": "^0.0.1",
"gsap": "^3.0.1",
"image-js": "^0.21.8",
"instagram-save": "^1.3.2",
"is-online": "^8.2.0",
"izitoast": "^1.4.0",
"js-event-bus": "^1.0.0",
"lodash": "^4.17.15",
"logplease": "^1.2.15",
"markdown": "^0.5.0",
"md5": "^2.2.1",
"md5-file": "^4.0.0",
"mime-types": "^2.1.25",
"moment": "^2.24.0",
"node-7z": "^2.0.3",
"node-graceful-shutdown": "^1.0.3",
"nucleus-nodejs": "^3.0.1",
"nuxt": "^2.10.2",
"p-queue": "^6.2.1",
"patch-package": "^6.2.0",
"popmotion": "^8.7.1",
"postinstall-postinstall": "^2.0.0",
"randomcolor": "^0.5.4",
"randomstring": "^1.1.5",
"raw-loader": "^3.1.0",
"regedit": "^3.0.3",
"rollbar": "^2.14.4",
"semver-regex": "^3.1.0",
"supports-color": "^7.1.0",
"sweetalert2": "^9.4.0",
"systeminformation": "^4.15.3",
"tippy.js": "^5.1.1",
"unzipper": "^0.10.5",
"uuid": "^3.3.3",
"webpack-node-externals": "^1.7.2"
},
"devDependencies": {
"electron": "^7.1.1",
"@babel/cli": "^7.7.0",
"@babel/core": "^7.7.2",
"@babel/plugin-proposal-class-properties": "^7.7.0",
"@babel/plugin-proposal-export-default-from": "^7.5.2",
"@babel/plugin-proposal-optional-chaining": "^7.6.0",
"@nuxtjs/eslint-config": "^1.1.2",
"@nuxtjs/eslint-module": "^1.1.0",
"@nuxtjs/tailwindcss": "^1.2.0",
"@octokit/rest": "^16.35.0",
"babel-eslint": "^10.0.3",
"babel-plugin-module-resolver": "^3.2.0",
"babel-plugin-transform-inline-environment-variables": "^0.4.3",
"babel-watch": "^7.0.0",
"cross-env": "^6.0.3",
"delay-cli": "^1.1.0",
"electron-builder": "^22.1.0",
"electron-devtools-installer": "^2.2.4",
"electron-rebuild": "^1.8.6",
"env-cmd": "^10.0.1",
"eslint": "^6.6.0",
"eslint-config-airbnb-base": "^14.0.0",
"eslint-config-standard": ">=14.1.0",
"eslint-import-resolver-nuxt": "^0.1.5",
"eslint-plugin-import": ">=2.18.2",
"eslint-plugin-jest": ">=23.0.4",
"eslint-plugin-lodash": "^6.0.0",
"eslint-plugin-node": ">=10.0.0",
"eslint-plugin-nuxt": ">=0.5.0",
"eslint-plugin-promise": ">=4.2.1",
"eslint-plugin-standard": ">=4.0.1",
"eslint-plugin-vue": "^6.0.1",
"husky": "^3.0.9",
"lint-staged": "^9.4.3",
"node-sass": "^4.13.0",
"nodemon": "^1.19.4",
"nuxtjs-electron": "^0.1.10",
"rollbar-sourcemap-webpack-plugin": "^2.5.1",
"sass-loader": "^8.0.0",
"tailwindcss": "^1.1.3",
"tailwindcss-alpha": "hacknug/tailwindcss-alpha#feature/tests",
"webpack-cli": "^3.3.10"
}
}

+ 3
- 1
src/package.json View File

@@ -4,7 +4,7 @@
"description": "DreamTime allows you to nudify photos of people.",
"author": "DreamNet",
"homepage": "https://time.dreamnet.tech",
"version": "1.3.0",
"version": "1.3.1",
"main": "electron/dist/index.js",
"license": "GPL-3.0-only",
"private": true,
@@ -93,6 +93,7 @@
"regedit": "^3.0.3",
"rollbar": "^2.14.4",
"semver-regex": "^3.1.0",
"sourcemapped-stacktrace": "^1.1.11",
"sweetalert2": "^9.4.0",
"systeminformation": "^4.15.3",
"tippy.js": "^5.1.1",
@@ -141,6 +142,7 @@
"lint-staged": "^9.4.3",
"mocha": "^6.2.2",
"modclean": "^3.0.0-beta.1",
"ngrok": "^3.2.7",
"nodemon": "^1.19.4",
"nyc": "^14.1.1",
"rollbar-sourcemap-webpack-plugin": "^2.5.1",

+ 11
- 0
src/package.min.json View File

@@ -0,0 +1,11 @@
{
"name": "dreamtime",
"displayName": "DreamTime",
"description": "DreamTime allows you to nudify photos of people.",
"author": "DreamNet",
"homepage": "https://time.dreamnet.tech",
"version": "1.3.1",
"main": "electron/dist/index.js",
"license": "GPL-3.0-only",
"private": true
}

+ 1
- 1
src/pages/about.vue View File

@@ -21,7 +21,7 @@

<box-item
label="DreamPower"
description="DreamPower is not installed or the installed version is not compatible.">
:description="`DreamPower is not installed or the installed version is not compatible. ${$settings.processing.usePython ? '<b class=\'text-warning\'>Python enabled!</b>' : ''}`">
<template slot="icon">
<span v-if="requirements.power.installed && requirements.power.compatible" class="item__icon">โœ”</span>
<span v-else class="item__icon">โŒ</span>

+ 105
- 0
src/pages/wizard/power.vue View File

@@ -0,0 +1,105 @@
<template>
<div class="power">
<div class="layout__header">
<h1>Setup Wizard - {{ power.title }}.</h1>
</div>

<div class="power__content">
<div class="power__overview">
<figure>
<img src="~/assets/images/apps/dreampower.png">
</figure>

<h1>{{ power.title }}</h1>
<h2>{{ power.description }}</h2>

<div class="power__navigation">
<a v-for="(item, index) in power.navigation" :key="index" :href="item.href" target="_blank" class="button">{{ item.label }}</a>
</div>
</div>

<div class="power__description">
<p>To make your dreams come true, it is necessary for {{ $dream.name }} to download and install {{ power.title }}, the algorithm/AI that will handle the entire nudification process.</p>
<p>Keep in mind that the download of {{ power.title }} can be up to <strong>1 GB</strong>! (Depending on your system)</p>
<p>In case the download cannot be done automatically, please click on the "Mirrors" button to see a list of links where you can download it manually.</p>
</div>
</div>

<div class="power__installation" />
</div>
</template>

<script>
import { nucleus } from '~/modules/services'

export default {
layout: 'wizard',

computed: {
power() {
return nucleus.v1?.projects?.dreampower.about || {
title: 'DreamPower',
description: 'Deep Learning algorithm for nudify photos.',
navigation: [
{
href: 'https://power.dreamnet.tech',
label: 'Website',
},
{
href: 'https://github.com/dreamnettech/dreampower',
label: 'GitHub',
},
{
href: 'https://www.patreon.com/dreampower',
label: 'Patreon',
},
],
}
},
},
}
</script>

<style lang="scss" scoped>
.power__content {
@apply flex;

.power__overview {
@apply flex-1 flex flex-col justify-center items-center;

figure {
@apply mb-6;