2018-03-09 22:59:12 +02:00
const { dialog } = require ( 'electron' )
2018-05-14 12:08:33 +02:00
const { shim } = require ( 'lib/shim' ) ;
2018-03-09 22:59:12 +02:00
const { Logger } = require ( 'lib/logger.js' ) ;
const { _ } = require ( 'lib/locale.js' ) ;
2018-03-14 19:23:19 +02:00
const fetch = require ( 'node-fetch' ) ;
2018-05-14 12:08:33 +02:00
const { fileExtension } = require ( 'lib/path-utils.js' ) ;
2018-03-14 19:23:19 +02:00
const packageInfo = require ( './packageInfo.js' ) ;
const compareVersions = require ( 'compare-versions' ) ;
2018-01-31 00:35:50 +02:00
let autoUpdateLogger _ = new Logger ( ) ;
let checkInBackground _ = false ;
2018-02-16 01:05:04 +02:00
let isCheckingForUpdate _ = false ;
let parentWindow _ = null ;
2018-01-31 00:35:50 +02:00
2018-02-16 01:05:04 +02:00
function showErrorMessageBox ( message ) {
return dialog . showMessageBox ( parentWindow _ , {
2018-03-09 22:59:12 +02:00
type : 'error' ,
2018-02-16 01:05:04 +02:00
message : message ,
} ) ;
}
function onCheckStarted ( ) {
2018-03-09 22:59:12 +02:00
autoUpdateLogger _ . info ( 'checkForUpdates: Starting...' ) ;
2018-02-16 01:05:04 +02:00
isCheckingForUpdate _ = true ;
}
function onCheckEnded ( ) {
2018-03-09 22:59:12 +02:00
autoUpdateLogger _ . info ( 'checkForUpdates: Done.' ) ;
2018-02-16 01:05:04 +02:00
isCheckingForUpdate _ = false ;
}
2019-01-12 01:40:05 +02:00
async function fetchLatestRelease ( options ) {
options = Object . assign ( { } , { includePreReleases : false } , options ) ;
2018-02-16 20:08:02 +02:00
2019-01-12 01:40:05 +02:00
let json = null ;
if ( options . includePreReleases ) {
// This end-point will include all releases, including pre-releases (but not draft), so we take
// whatever is the latest release. It might be the same as releases/latest, or it might be
// a pre-release.
const response = await fetch ( 'https://api.github.com/repos/laurent22/joplin/releases' ) ;
if ( ! response . ok ) {
const responseText = await response . text ( ) ;
throw new Error ( 'Cannot get latest release info: ' + responseText . substr ( 0 , 500 ) ) ;
}
json = await response . json ( ) ;
if ( ! json . length ) throw new Error ( 'Cannot get latest release info: ' + responseText . substr ( 0 , 500 ) ) ;
json = json [ 0 ] ;
} else {
const response = await fetch ( 'https://api.github.com/repos/laurent22/joplin/releases/latest' ) ;
2018-02-16 20:08:02 +02:00
2019-01-12 01:40:05 +02:00
if ( ! response . ok ) {
const responseText = await response . text ( ) ;
throw new Error ( 'Cannot get latest release info: ' + responseText . substr ( 0 , 500 ) ) ;
}
json = await response . json ( ) ;
}
2018-03-14 19:23:19 +02:00
const version = json . tag _name . substr ( 1 ) ;
let downloadUrl = null ;
const platform = process . platform ;
for ( let i = 0 ; i < json . assets . length ; i ++ ) {
const asset = json . assets [ i ] ;
let found = false ;
2018-05-14 12:08:33 +02:00
const ext = fileExtension ( asset . name ) ;
if ( platform === 'win32' && ext === 'exe' ) {
if ( shim . isPortable ( ) ) {
found = asset . name == 'JoplinPortable.exe' ;
} else {
found = ! ! asset . name . match ( /^Joplin-Setup-[\d.]+\.exe$/ ) ;
}
} else if ( platform === 'darwin' && ext === 'dmg' ) {
2018-03-14 19:23:19 +02:00
found = true ;
2018-05-14 12:08:33 +02:00
} else if ( platform === 'linux' && ext === '.AppImage' ) {
2018-03-14 19:23:19 +02:00
found = true ;
}
if ( found ) {
downloadUrl = asset . browser _download _url ;
break ;
}
2018-02-06 15:11:59 +02:00
}
2018-03-14 19:23:19 +02:00
return {
version : version ,
downloadUrl : downloadUrl ,
notes : json . body ,
2018-05-14 13:18:00 +02:00
pageUrl : json . html _url ,
2019-01-12 01:40:05 +02:00
prerelease : json . prerelease ,
2018-03-14 19:23:19 +02:00
} ;
}
2018-01-31 00:35:50 +02:00
2019-01-12 01:40:05 +02:00
function checkForUpdates ( inBackground , window , logFilePath , options ) {
2018-02-16 01:05:04 +02:00
if ( isCheckingForUpdate _ ) {
2018-03-09 22:59:12 +02:00
autoUpdateLogger _ . info ( 'checkForUpdates: Skipping check because it is already running' ) ;
2018-02-16 01:05:04 +02:00
return ;
}
parentWindow _ = window ;
onCheckStarted ( ) ;
2018-01-31 00:35:50 +02:00
if ( logFilePath && ! autoUpdateLogger _ . targets ( ) . length ) {
autoUpdateLogger _ = new Logger ( ) ;
2018-03-09 22:59:12 +02:00
autoUpdateLogger _ . addTarget ( 'file' , { path : logFilePath } ) ;
2018-01-31 00:35:50 +02:00
autoUpdateLogger _ . setLevel ( Logger . LEVEL _DEBUG ) ;
2018-03-09 22:59:12 +02:00
autoUpdateLogger _ . info ( 'checkForUpdates: Initializing...' ) ;
2018-01-31 00:35:50 +02:00
}
checkInBackground _ = inBackground ;
2019-01-12 01:40:05 +02:00
autoUpdateLogger _ . info ( 'checkForUpdates: Checking with options ' + JSON . stringify ( options ) ) ;
fetchLatestRelease ( options ) . then ( release => {
2018-05-14 13:18:00 +02:00
autoUpdateLogger _ . info ( 'Current version: ' + packageInfo . version ) ;
autoUpdateLogger _ . info ( 'Latest version: ' + release . version ) ;
2019-01-12 01:40:05 +02:00
autoUpdateLogger _ . info ( 'Is Pre-release:' , release . prerelease ) ;
2018-05-14 13:18:00 +02:00
2018-03-14 19:23:19 +02:00
if ( compareVersions ( release . version , packageInfo . version ) <= 0 ) {
2019-02-24 12:54:50 +02:00
if ( ! checkInBackground _ ) dialog . showMessageBox ( {
type : 'info' ,
message : _ ( 'Current version is up-to-date.' ) ,
buttons : [ _ ( 'OK' ) ] ,
} )
2018-03-14 19:23:19 +02:00
} else {
const releaseNotes = release . notes . trim ( ) ? "\n\n" + release . notes . trim ( ) : '' ;
2019-01-15 20:17:45 +02:00
const newVersionString = release . prerelease ? _ ( '%s (pre-release)' , release . version ) : release . version ;
2018-03-14 19:23:19 +02:00
const buttonIndex = dialog . showMessageBox ( parentWindow _ , {
type : 'info' ,
2019-01-15 20:17:45 +02:00
message : _ ( 'An update is available, do you want to download it now?' ) + '\n\n' + _ ( 'Your version: v%s' , packageInfo . version ) + '\n' + _ ( 'New version: v%s' , newVersionString ) + releaseNotes ,
2018-03-14 19:23:19 +02:00
buttons : [ _ ( 'Yes' ) , _ ( 'No' ) ]
} ) ;
2018-05-14 13:18:00 +02:00
if ( buttonIndex === 0 ) require ( 'electron' ) . shell . openExternal ( release . downloadUrl ? release . downloadUrl : release . pageUrl ) ;
2018-03-14 19:23:19 +02:00
}
} ) . catch ( error => {
2018-01-31 21:10:45 +02:00
autoUpdateLogger _ . error ( error ) ;
2018-02-16 01:05:04 +02:00
if ( ! checkInBackground _ ) showErrorMessageBox ( error . message ) ;
2018-03-14 19:23:19 +02:00
} ) . then ( ( ) => {
2018-02-16 01:05:04 +02:00
onCheckEnded ( ) ;
2018-03-14 19:23:19 +02:00
} ) ;
2018-01-31 00:35:50 +02:00
}
2018-03-09 22:59:12 +02:00
module . exports . checkForUpdates = checkForUpdates