Skip to content

Commit

Permalink
Merge pull request #480 from highperformancecoder/patreon-upgrade
Browse files Browse the repository at this point in the history
Patreon upgrade
  • Loading branch information
highperformancecoder committed Apr 29, 2024
2 parents 8382b5f + c6e0ff4 commit b841183
Show file tree
Hide file tree
Showing 11 changed files with 173 additions and 13 deletions.
15 changes: 15 additions & 0 deletions gui-js/apps/minsky-electron/src/app/app.ts
Expand Up @@ -46,6 +46,21 @@ export default class App {
backend('minsky.pushFlags');
await HelpFilesManager.initialize(helpFilesFolder);
App.initMainWindow();
let ravelPlugin=StoreManager.store.get('ravelPlugin');
if (ravelPlugin) {
// if this is set (after a full reinstall of Minsky, kick off updating the Ravel plugin)
App.mainWindow.webContents.downloadURL(ravelPlugin);
App.mainWindow.webContents.session.on('will-download',CommandsManager.downloadRavel);
StoreManager.store.set('ravelPlugin','');
}
// check if ravel is approaching its expiry date, and nag user to upgrade if so
let daysLeft=await minsky.daysUntilRavelExpires();
if (await minsky.ravelVersion()!=="unavailable" && daysLeft<30) {
dialog.showMessageBoxSync(WindowManager.getMainWindow(),{
message: `The Ravel plugin is expiring in ${daysLeft} days,\nplease update the plugin using the File>Upgrade menu`,
type: 'info',
});
}
await App.initMenu();
App.loadMainWindow();
backend('minsky.popFlags');
Expand Down
Expand Up @@ -81,7 +81,7 @@ export class ApplicationMenuManager {
label: 'File',
submenu: [
{
label: 'About Minsky',
label: 'About',
click() {
setInterval(()=> {
console.log(process.memoryUsage())
Expand All @@ -98,9 +98,7 @@ export class ApplicationMenuManager {
},
{
label: 'Upgrade',
click() {
shell.openExternal('https://www.patreon.com/hpcoder');
},
click() {CommandsManager.upgrade();},
},
{
label: 'New System',
Expand Down
147 changes: 145 additions & 2 deletions gui-js/apps/minsky-electron/src/app/managers/CommandsManager.ts
Expand Up @@ -9,14 +9,17 @@ import {
importCSVvariableName,
minsky, GodleyIcon, Group, IntOp, Item, Lock, Ravel, VariableBase, Wire, Utility
} from '@minsky/shared';
import { dialog, ipcMain, Menu, MenuItem, SaveDialogOptions } from 'electron';
import { app, dialog, ipcMain, Menu, MenuItem, SaveDialogOptions,} from 'electron';
import { existsSync, unlinkSync } from 'fs';
import JSON5 from 'json5';
import { join } from 'path';
import { join, dirname } from 'path';
import { tmpdir } from 'os';
import { HelpFilesManager } from './HelpFilesManager';
import { WindowManager } from './WindowManager';
import { StoreManager } from './StoreManager';
import { RecentFilesManager } from './RecentFilesManager';
import ProgressBar from 'electron-progressbar';
import {spawn} from 'child_process';

export class CommandsManager {
static activeGodleyWindowItems = new Map<string, CanvasItem>();
Expand Down Expand Up @@ -1111,5 +1114,145 @@ export class CommandsManager {
minsky.numBackups(numBackups);
RecentFilesManager.updateNumberOfRecentFilesToDisplay();
}

// handler for downloading Ravel and installing it
static downloadRavel(event,item,webContents) {
switch (process.platform) {
case 'win32':
item.setSavePath(dirname(process.execPath)+'/libravel.dll');
break;
default:
// nothing to do - TODO implement handlers for MacOS and Linux
}
// handler for when download completed
item.once('done', (event,state)=>{
if (state==='completed') {
dialog.showMessageBoxSync(WindowManager.getMainWindow(),{
message: 'Ravel plugin updated successfully - restart Ravel to use',
type: 'info',
});
app.relaunch();
app.quit();
} else {
dialog.showMessageBoxSync(WindowManager.getMainWindow(),{
message: `Ravel plugin update failed: ${state}`,
type: 'error',
});
webContents.close();
}
});
}

// handler for downloading Minsky
static downloadMinsky(event,item,webContents) {
item.setSavePath(join(tmpdir(),item.getFilename()));

let progress=new ProgressBar({text:"Downloading Ravel application",value: 0, indeterminate:false, closeOnComplete: true,});

// handler for when download completed
item.once('done', (event,state)=>{
if (state==='completed') {
switch (process.platform) {
case 'win32':
spawn(item.getSavePath(),{detached: true, stdio: 'ignore'});
app.quit();
break;
default:
webContents.close();
break;
}
} else {
dialog.showMessageBoxSync(WindowManager.getMainWindow(),{
message: `Ravel update failed: ${state}`,
type: 'error',
});
webContents.close();
}
});

// handler for updating progress bar
item.on('updated',(event,state)=>{
switch (state) {
case 'progressing':
if (!progress?.isCompleted())
progress.value=100*item.getReceivedBytes()/item.getTotalBytes();
break;
case 'interrupted':
//item.resume();
break;
}
});
}

static upgrade() {
let window=WindowManager.createWindow({
width: 500,
height: 700,
title: '',
modal: false,
});

// handler for when user has logged in to initiate upgrades.
window.webContents.on('did-navigate',async ()=>{
const urlString=window.webContents.getURL();
if (urlString=='https://www.patreon.com/')
// user has logged out
window.close()
});
window.webContents.on('did-redirect-navigation', async (event)=>{
const installables=await window.webContents.executeJavaScript('document.getElementById("installables")?.innerText');
if (installables) {
let params=new URLSearchParams(installables);
let minskyFile=params.get('minsky-asset');
let ravelFile=params.get('ravel-asset');
if (minskyFile) {
let minskyVersionRE=/(\d+)\.(\d+)\.(\d+)([.-])/;
let [all,major,minor,patch]=minskyVersionRE.exec(minskyFile);
let [currAll,currMajor,currMinor,currPatch,terminator]=minskyVersionRE.exec(await minsky.minskyVersion());
if (major>currMajor || major===currMajor &&
(minor>currMinor || minor===currMinor && patch>currPatch) ||
terminator==='-' && // currently a beta release, so install if release nos match (since betas precede releases)
major===currMajor && minor===currMinor && patch==currPatch
) {
if (ravelFile) { // stash ravel upgrade to be installed on next startup
StoreManager.store.set('ravelPlugin',ravelFile);
}
window.webContents.session.on('will-download',this.downloadMinsky);
window.webContents.downloadURL(minskyFile);
} else if (ravelFile) {
// currently on latest, so reinstall ravel
window.webContents.session.on('will-download',this.downloadRavel);
window.webContents.downloadURL(ravelFile);
}
else {
dialog.showMessageBoxSync(WindowManager.getMainWindow(),{
message: "Everything's up to date, nothing to do",
type: 'info',
});
window.close();
}
}
}
});

let clientId='abf9j0FWQTj-etln2BbRlUhJnjv11kaL9lH1nprj23NLSq3l6ELxUGkLJKIfWsKt';
// need to pass what platform we are
switch (process.platform) {
case 'win32': var system='windows'; break;
//case 'darwin': var system='macos'; break;
//case 'linux': var system='linux'; break;
// TODO consult /etc/os-release to figure out which distro
default:
dialog.showMessageBoxSync(WindowManager.getMainWindow(),{
message: `In app update is not available for your operating system yet, please check back later`,
type: 'error',
});
window.close();
return;
break;
}
// load patreon's login page
window.loadURL(`https://www.patreon.com/oauth2/authorize?response_type=code&client_id=${clientId}&redirect_uri=https://ravelation.hpcoders.com.au/ravel-downloader.cgi&state=${system}`);
}

}
2 changes: 2 additions & 0 deletions gui-js/apps/minsky-electron/src/app/managers/StoreManager.ts
Expand Up @@ -16,6 +16,7 @@ interface MinskyStore {
recentFiles: Array<string>;
backgroundColor: string;
preferences: MinskyPreferences;
ravelPlugin: string; // used for post installation installation of Ravel
}

class StoreManager {
Expand All @@ -34,6 +35,7 @@ class StoreManager {
// focusFollowsMouse: false,
numBackups: 1,
},
ravelPlugin: '',
},
});
}
Expand Down
Expand Up @@ -172,7 +172,7 @@ export class WindowManager {
return window;
}

private static createWindow(
static createWindow(
payload: CreateWindowPayload,
onCloseCallback?: (ev : Electron.Event) => void
) {
Expand Down
1 change: 1 addition & 0 deletions gui-js/libs/shared/src/lib/backend/minsky.ts
Expand Up @@ -1351,6 +1351,7 @@ export class Minsky extends CppClass {
async copy(): Promise<void> {return this.$callMethod('copy');}
async cut(): Promise<void> {return this.$callMethod('cut');}
async cycleCheck(): Promise<boolean> {return this.$callMethod('cycleCheck');}
async daysUntilRavelExpires(): Promise<number> {return this.$callMethod('daysUntilRavelExpires');}
async defaultFont(...args: any[]): Promise<string> {return this.$callMethod('defaultFont',...args);}
async definingVar(a1: string): Promise<object> {return this.$callMethod('definingVar',a1);}
async deleteAllUnits(): Promise<void> {return this.$callMethod('deleteAllUnits');}
Expand Down
2 changes: 1 addition & 1 deletion gui-js/libs/shared/src/lib/constants/version.ts
@@ -1 +1 @@
export const version="3.4.0-alpha.14";
export const version="3.4.0-alpha.15";
4 changes: 2 additions & 2 deletions gui-js/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion gui-js/package.json
@@ -1,6 +1,6 @@
{
"name": "minsky",
"version":"3.4.0-alpha.14",
"version":"3.4.0-alpha.15",
"author": "High Performance Coders",
"description": "Graphical dynamical systems simulator oriented towards economics",
"build": {
Expand Down
2 changes: 1 addition & 1 deletion minskyVersion.h
@@ -1 +1 @@
#define MINSKY_VERSION "3.4.0-alpha.14"
#define MINSKY_VERSION "3.4.0-alpha.15"
3 changes: 2 additions & 1 deletion model/minsky.h
Expand Up @@ -335,7 +335,8 @@ namespace minsky
else return "unavailable";
}
static bool ravelExpired() {return ravel::Ravel::available() && ravel::Ravel::daysUntilExpired()<0;}

static int daysUntilRavelExpires() {return ravel::Ravel::daysUntilExpired();}

std::string fileVersion; ///< Minsky version file was saved under

unsigned maxHistory{100}; ///< maximum no. of history states to save
Expand Down

0 comments on commit b841183

Please sign in to comment.