Skip to content

Commit

Permalink
Remove EMME version input, improve automatic discovery of python inst…
Browse files Browse the repository at this point in the history
…allations
  • Loading branch information
e-halinen committed Feb 5, 2025
1 parent 18f8076 commit f97703c
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 87 deletions.
15 changes: 0 additions & 15 deletions src/renderer/components/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ const App = ({helmetUIVersion, versions, searchEMMEPython}) => {
const [isProjectRunning, setProjectRunning] = useState(false); // whether currently selected Project is running
const [emmePythonPath, setEmmePythonPath] = useState(undefined); // file path to EMME python executable
const [emmePythonEnvs, setEmmePythonEnvs] = useState([]); // List of all discovered python executables
const [emmeVersion, setEmmeVersion] = useState(undefined);
const [helmetScriptsPath, setHelmetScriptsPath] = useState(undefined); // folder path to HELMET model system scripts
const [projectPath, setProjectPath] = useState(undefined); // folder path to scenario configs, default homedir
const [basedataPath, setBasedataPath] = useState(undefined); // folder path to base input data (subdirectories: 2016_zonedata, 2016_basematrices)
Expand Down Expand Up @@ -54,11 +53,6 @@ const App = ({helmetUIVersion, versions, searchEMMEPython}) => {
}
}

const _setEMMEVersion = (newVersion) => {
setEmmeVersion(newVersion);
globalSettingsStore.current.set('emme_version', newVersion);
}

const _setHelmetScriptsPath = (newPath) => {
// Cannot use state variable since it'd be undefined at times
const pythonPath = globalSettingsStore.current.get('emme_python_path');
Expand Down Expand Up @@ -164,13 +158,6 @@ const App = ({helmetUIVersion, versions, searchEMMEPython}) => {
setEmmePythonEnvs([]);
}

//If Emme version is uninitialized, fetch version from config file
if(existingEmmeVersion === undefined) {
_setEMMEVersion(versions.emme_system);
} else {
_setEMMEVersion(existingEmmeVersion);
}

// If project path is the initial (un-set), set it to homedir. Remember: state updates async so refer to existing.
if (!existingProjectPath) {
_setProjectPath(homedir);
Expand Down Expand Up @@ -220,8 +207,6 @@ const App = ({helmetUIVersion, versions, searchEMMEPython}) => {
setBasedataPath={_setBasedataPath}
setResultsPath={_setResultsPath}
promptModelSystemDownload={_promptModelSystemDownload}
emmeVersion={emmeVersion}
setEmmeVersion={_setEMMEVersion}
/>
</div>

Expand Down
56 changes: 4 additions & 52 deletions src/renderer/components/Settings/Settings.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,39 +17,6 @@ const EnvironmentOption = ({
)
}

const EmmeVersionEdit = ({
emmeVersion, setEmmeVersion, closeEditing
}) => {

const [savingDisabled, setSavingDisabled] = useState(true);
const [newEmmeVersion, setNewEmmeVersion] = useState('');
const VERSION_NUMBER_REGEX = RegExp(/^(\d+\.)?(\d+\.)?(\*|\d+)$/);
const validateVersionNumber = (e) => {
const regExpResults = e.target.value.match(VERSION_NUMBER_REGEX);
return regExpResults !== null;
}

return (
<div className='Settings__emme_input'>
<span className="Settings__pseudo-label">Syötä uusi EMME versio: </span>
<input type='text' defaultValue={emmeVersion} placeholder='esim. 4.5.0' onChange={(e) => {

setNewEmmeVersion(e.target.value);
const validationPasses = validateVersionNumber(e);
setSavingDisabled(!validationPasses);
}}></input>
<button className={classNames('Settings__emme_edit_save_btn', { 'Settings__btn_disabled': savingDisabled})}
disabled={savingDisabled}
onClick={() => {
closeEditing();
setEmmeVersion(newEmmeVersion);
}}>
Tallenna
</button>
</div>
)
};

const PathOptionDivider = () => <div className='Settings__env_option_divider' />

const Settings = ({
Expand All @@ -59,11 +26,9 @@ const Settings = ({
basedataPath, setBasedataPath,
resultsPath, setResultsPath,
closeSettings,
promptModelSystemDownload, emmeVersion, setEmmeVersion,
promptModelSystemDownload,
}) => {

const [showEmmeDialog, setShowEmmeDialog] = useState(false);

return (
<div className="Settings">

Expand All @@ -75,19 +40,6 @@ const Settings = ({

<div className="Settings__dialog-heading">Projektin asetukset</div>

<div className="Settings__emme_version_group">
<span className="Settings__pseudo-label">{`EMME-versio: ${emmeVersion}`}</span>
<button className='Settings__emme_edit_btn'
onClick={() => {
setShowEmmeDialog(!showEmmeDialog);
}}
>
{showEmmeDialog ? 'Peruuta' : 'Muokkaa'}
</button>
</div>
{ showEmmeDialog && <EmmeVersionEdit emmeVersion={emmeVersion}
setEmmeVersion={setEmmeVersion}
closeEditing={() => setShowEmmeDialog(false)} /> }
<div className="Settings__dialog-input-group">
<span className="Settings__pseudo-label">Käytettävät Python-ympäristöt:</span>
{ Array.isArray(emmePythonEnvs) && emmePythonEnvs.length > 0 && (emmePythonEnvs.map((env, index) => { return (
Expand Down Expand Up @@ -117,12 +69,12 @@ const Settings = ({
</button>
<button className="Settings__python-env-input-btn"
onClick={(e) => {
const [found, pythonPaths] = listEMMEPythonPaths(emmeVersion);
const [found, pythonPaths] = listEMMEPythonPaths();
if (found) {
alert(`Python-ympäristöjä löytyi. Valitse listasta oikea EMME Python-ympäristö ja ota sen jälkeen käyttöön ${pythonPaths}`)
alert(`Python-ympäristöjä löytyi. Valitse listasta haluamasi EMME Python-ympäristö ja ota se käyttöön`)
setEMMEPythonEnvs(pythonPaths);
} else {
alert(`Emme ${versions.emme_system} ja Python ${versions.emme_python} eivät löytyneet oletetusta sijainnista.\n\nSyötä Pythonin polku manuaalisesti.`);
alert(`Python-asennukset ${versions.emme_major_versions.toString()} eivät löytyneet oletetusta sijainnista.\n\nLisää Python-asennus manuaalisesti.`);
}}}
>
Etsi Python-ympäristöjä
Expand Down
60 changes: 40 additions & 20 deletions src/renderer/search_emme_pythonpath.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const searchEMMEPython = () => {
}
};

const listEMMEPythonPaths = (emmeVersion) => {
const listEMMEPythonPaths = () => {
// Set Windows' python exe path postfix (e.g. Python27\python.exe)
const p = getVersion(versions.emme_python);
const pythonPathPostfix = `Python${p.major}${p.minor}\\python.exe`;
Expand All @@ -54,17 +54,23 @@ const listEMMEPythonPaths = (emmeVersion) => {
}

// Not found based on EMMEPATH, try guessing some common locations on Windows
const e = getVersion(emmeVersion);
const pythonVersion = getVersion(versions.emme_python);
const commonEmmePath = `INRO\\Emme\\Emme ${e.major}\\Emme-${e.semver}`;

const commonEmmePaths = []
versions.emme_major_versions.forEach(majorVersion => { commonEmmePaths.push(`INRO\\Emme\\Emme ${majorVersion}`) })

const drives = ['C:', 'D:', 'E:', 'F:', 'G:', 'H:', 'I:', 'J:', '/'];
const paths = [
`\\Program Files\\${commonEmmePath}`,
`\\Program Files (x86)\\${commonEmmePath}`,
`\\${commonEmmePath}`,
`usr/bin/python${pythonVersion.major}`, // mainly for developers on Mac & Linux
`Users/erkki/testi`
];
const paths = []
commonEmmePaths.forEach(commonEmmePath => {
paths.push(
`\\Program Files\\${commonEmmePath}`,
`\\Program Files (x86)\\${commonEmmePath}`,
`\\${commonEmmePath}`,
)
})
paths.push(`usr/bin/python${pythonVersion.major}`); // mainly for developers on Mac & Linux
paths.push(`Users/erkki/testi`);

const allPathCombinations = drives.reduce(
(accumulator, d) => {
// Combine each (d)rive to all (p)aths, and merge results via reduce
Expand All @@ -74,7 +80,7 @@ const listEMMEPythonPaths = (emmeVersion) => {
allPathCombinations.forEach((pathCombination) => {
const foundPythonEnv = hasPythonEnv(pathCombination);
if (foundPythonEnv !== null) {
pythonInstallations.push(foundPythonEnv);
pythonInstallations.push(...foundPythonEnv);
}
});
if (pythonInstallations.length > 0) {
Expand All @@ -99,22 +105,36 @@ function getVersion(semver) {

function hasPythonEnv(basePath) {
const pathExists = fs.existsSync(basePath) && fs.lstatSync(basePath).isDirectory();
let exePath = null;
let exePaths = [];
if (pathExists) {
const subPaths = fs.readdirSync(basePath)
subPaths.forEach(path => {
if(path.startsWith("Python")) {
// Go through the subdirectory and look for a python executable
const subPathFiles = fs.readdirSync(`${basePath}${getDirSeparator()}${path}`);
subPathFiles.forEach(fileName => {
if(fileName === 'python.exe') {
exePath = `${basePath}${getDirSeparator()}${path}${getDirSeparator()}${fileName}`;
}
if(path.startsWith("Emme ")) {
const majorVersionFolderPath = `${basePath}${getDirSeparator()}${path}`;
const majorVersionFolderPathFiles = fs.readdirSync(majorVersionFolderPath);

// Filter away every folder except possible Emme installation folders
const subVersionFolders = majorVersionFolderPathFiles.filter(file => file.startsWith("Emme-"));
subVersionFolders.forEach(subVersionFolder => {
// Go through the subdirectory and look for a python executable, should be in Emme-x.xx.xx.xx/Python/python.exe on Windows machines.
const emmeFolderFilesPath = majorVersionFolderPath.concat(getDirSeparator(), subVersionFolder);
const emmeFolderFiles = fs.readdirSync(emmeFolderFilesPath);
emmeFolderFiles.forEach(folderPath => {
if(folderPath.startsWith("Python")) {
const pythonFolderPath = emmeFolderFilesPath.concat(getDirSeparator(), folderPath);
const pythonPathFiles = fs.readdirSync(pythonFolderPath);
pythonPathFiles.forEach(fileName => {
if(fileName === 'python.exe') {
exePaths.push(pythonFolderPath.concat(getDirSeparator(), fileName));
}
})
}
})
})
}
})
}
return exePath;
return exePaths;
}

function getDirSeparator() {
Expand Down
1 change: 1 addition & 0 deletions src/versions.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module.exports = {
emme_system: '4.5.0',
emme_python: '3.7',
emme_major_versions: [23, 4],
};

0 comments on commit f97703c

Please sign in to comment.