2021-10-01 11:39:50 +00:00
|
|
|
|
/** Electron / Node.js に由来する機能に関する諸々 */
|
|
|
|
|
/** ブラウザ動作時にもちょびっと対応 */
|
|
|
|
|
'use strict'
|
|
|
|
|
|
2021-10-22 14:33:59 +00:00
|
|
|
|
// 定数
|
2021-10-01 11:39:50 +00:00
|
|
|
|
const ugj_const = {
|
|
|
|
|
app_name: 'ocoge',
|
2022-01-23 06:46:42 +00:00
|
|
|
|
mascot_dirname: 'img',
|
2021-10-01 11:39:50 +00:00
|
|
|
|
mascot_defname: 'tamachee.png',
|
2022-01-23 06:46:42 +00:00
|
|
|
|
library_dirname: 'lib',
|
|
|
|
|
document_root: 'Documents',
|
2023-01-10 12:46:36 +00:00
|
|
|
|
tmp_dir: '.ocogeclub/tmp', //ホームディレクトリからのパス
|
2023-06-25 12:18:33 +00:00
|
|
|
|
executable_path: 'ocogeclub/bin/', //ホームディレクトリからのパス
|
2021-10-01 11:39:50 +00:00
|
|
|
|
localStorage_fname: 'ocoge.json',
|
2021-10-08 13:30:52 +00:00
|
|
|
|
error_ja_all: 'エラーが発生しました。\n『おこげ倶楽部』までお問い合わせください。',
|
2021-10-11 14:40:18 +00:00
|
|
|
|
pig: 'pigpio',
|
2023-08-18 02:16:52 +00:00
|
|
|
|
rg: '@ocoge/rgpio',
|
2021-11-28 02:42:33 +00:00
|
|
|
|
i2c_defbus: '1', // 文字列リテラルで指定
|
2022-07-10 13:04:56 +00:00
|
|
|
|
lang: 'js',
|
2021-10-22 14:33:59 +00:00
|
|
|
|
dev_hash: '4e9205f9b7e571bec1aa52ab7871f420684fcf96149672a4d550a95863d6b072'
|
2021-10-01 11:39:50 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-01-01 13:05:12 +00:00
|
|
|
|
/** クラス appTool ****************************************************************** */
|
2021-10-01 11:39:50 +00:00
|
|
|
|
// Electron 動作用
|
2023-01-01 13:05:12 +00:00
|
|
|
|
class appTool {
|
2021-10-01 11:39:50 +00:00
|
|
|
|
constructor() {
|
2021-10-01 14:33:13 +00:00
|
|
|
|
this.path = require('path') //window.ocogeapi.path
|
|
|
|
|
this.fs = require('fs') //window.ocogeapi.fs
|
|
|
|
|
this.ipcRenderer = require('electron').ipcRenderer //window.ocogeapi.electron_ipcRenderer
|
|
|
|
|
this.shell = require('electron').shell //window.ocogeapi.electron_shell
|
2021-10-01 11:39:50 +00:00
|
|
|
|
this.saveFilepath = null;
|
|
|
|
|
this.wsChanged = false;
|
|
|
|
|
this.children = [];
|
2023-05-09 00:05:48 +00:00
|
|
|
|
this.gpio_lib = ugj_const.rg;
|
2021-10-11 14:40:18 +00:00
|
|
|
|
this.i2c_bus = ugj_const.i2c_defbus;
|
2022-07-10 13:04:56 +00:00
|
|
|
|
this.lang = ugj_const.lang;
|
2022-01-23 06:46:42 +00:00
|
|
|
|
this.doc_root = this.path.join(process.env["HOME"], ugj_const.document_root);
|
|
|
|
|
this.doc_current = this.path.join(process.env["HOME"], ugj_const.document_root);
|
|
|
|
|
this.executable_path = this.path.join(process.env["HOME"], ugj_const.executable_path);
|
2022-07-10 13:04:56 +00:00
|
|
|
|
this.tmp_dir = this.path.join(process.env["HOME"], ugj_const.tmp_dir);
|
2022-03-02 11:25:14 +00:00
|
|
|
|
const EventEmitter = require('events');
|
|
|
|
|
this.ugjEmitter = new EventEmitter();
|
2021-10-01 11:39:50 +00:00
|
|
|
|
}
|
2022-01-23 06:46:42 +00:00
|
|
|
|
// static init = async () => {
|
|
|
|
|
// return new elUtil(await elUtil.get_app_path());
|
|
|
|
|
// }
|
|
|
|
|
// test
|
|
|
|
|
async init() {
|
|
|
|
|
this.app_path = await this.ipcRenderer.invoke('get_app_path');
|
|
|
|
|
this.mascotFilePath = this.path.join(this.app_path, ugj_const.mascot_dirname, ugj_const.mascot_defname);
|
|
|
|
|
this.library_path = this.path.join(this.app_path, ugj_const.library_dirname);
|
2023-01-20 12:21:43 +00:00
|
|
|
|
// this.blocks_dir = this.path.join(this.app_path, ugj_const.blocks_dir);
|
2022-03-02 11:25:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-10-01 11:39:50 +00:00
|
|
|
|
// 0で数値の桁合わせ : NUM=値 LEN=桁数
|
|
|
|
|
zeroPadding(NUM, LEN) {
|
|
|
|
|
return (Array(LEN).join('0') + NUM).slice(-LEN);
|
|
|
|
|
}
|
|
|
|
|
// 現在の日付時刻から workspace フォルダ内のユニークなファイルパスを作成
|
|
|
|
|
getUniqueFilepath() {
|
|
|
|
|
let today = new Date();
|
|
|
|
|
let filename = today.getFullYear() + '-' + this.zeroPadding((today.getMonth() + 1), 2) + '-' + this.zeroPadding(today.getDate(), 2) + '-' + this.zeroPadding(today.getHours(), 2) + '-' + this.zeroPadding(today.getMinutes(), 2) + '-' + this.zeroPadding(today.getSeconds(), 2);
|
2021-11-09 04:32:43 +00:00
|
|
|
|
let filepath = this.path.join(this.doc_current, filename);
|
2021-10-01 11:39:50 +00:00
|
|
|
|
return filepath;
|
|
|
|
|
}
|
|
|
|
|
// リンクを外部ブラウザで開く
|
|
|
|
|
openURL(url) {
|
|
|
|
|
this.shell.openExternal(url);
|
|
|
|
|
}
|
|
|
|
|
// saveFilepath を更新
|
|
|
|
|
// ウィンドウタイトルバーテキストを変更
|
|
|
|
|
setSaveFilepath(filepath) {
|
|
|
|
|
this.saveFilepath = filepath;
|
|
|
|
|
this.setWsChanged(false);
|
|
|
|
|
}
|
|
|
|
|
// ワークスペースが変更された・保存された
|
|
|
|
|
// ウィンドウタイトルバーテキストを変更
|
|
|
|
|
setWsChanged(changed) {
|
|
|
|
|
let title;
|
|
|
|
|
this.wsChanged = changed;
|
|
|
|
|
if (this.saveFilepath) title = this.saveFilepath + ' - ' + ugj_const.app_name;
|
|
|
|
|
else title = ugj_const.app_name;
|
|
|
|
|
if (changed) title = '*' + title;
|
|
|
|
|
this.ipcRenderer.send('set_title', title);
|
|
|
|
|
}
|
|
|
|
|
// 保存ファイルプロパティを更新
|
|
|
|
|
newFile() { this.setSaveFilepath(null); }
|
|
|
|
|
// ワークスペースファイル読み込みの一連の動作のラッパ
|
|
|
|
|
async loadWsFile() {
|
2021-11-09 04:32:43 +00:00
|
|
|
|
let filepath = await this.openFile('xml', this.doc_current);
|
2021-10-01 11:39:50 +00:00
|
|
|
|
if (filepath.length > 0) {
|
|
|
|
|
if (this.saveFilepath === null) {
|
|
|
|
|
this.setSaveFilepath(filepath);
|
2023-01-14 02:13:49 +00:00
|
|
|
|
} //読み込みに失敗してもsaveFilepathが更新されてしまうのはちょっと具合が悪いかも
|
2021-11-09 04:32:43 +00:00
|
|
|
|
this.doc_current = this.path.dirname(filepath);
|
2021-10-01 11:39:50 +00:00
|
|
|
|
return this.readFromFile(filepath);
|
|
|
|
|
} else {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// その他ファイル読み込みの一連の動作のラッパ
|
|
|
|
|
async loadFile(ext) {
|
2021-11-09 04:32:43 +00:00
|
|
|
|
let filepath = await this.openFile(ext, this.doc_current);
|
2021-10-01 11:39:50 +00:00
|
|
|
|
if (filepath.length > 0) {
|
2021-11-09 04:32:43 +00:00
|
|
|
|
this.doc_current = this.path.dirname(filepath);
|
2021-10-01 11:39:50 +00:00
|
|
|
|
return this.readFromFile(filepath);
|
|
|
|
|
} else {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
async selectMascotFile() {
|
|
|
|
|
return await this.openFile('png', ugj_const.mascot_path);
|
|
|
|
|
}
|
|
|
|
|
// オープンファイルダイアログ
|
|
|
|
|
async openFile(ext, dpath) {
|
|
|
|
|
let title = 'Select a file';
|
|
|
|
|
let filter;
|
|
|
|
|
if (ext == 'xml') {
|
|
|
|
|
filter = { name: 'XML - Extensible Markup Language', extensions: ['xml'] };
|
|
|
|
|
} else if (ext == 'js') {
|
|
|
|
|
filter = { name: 'JS - JavaScript', extensions: ['js'] };
|
|
|
|
|
} else if (ext == 'png') {
|
|
|
|
|
filter = { name: 'PNG - Portable Network Graphics', extensions: ['png'] };
|
|
|
|
|
} else {
|
|
|
|
|
filter = { name: 'text file', extensions: ['txt'] };
|
|
|
|
|
}
|
|
|
|
|
let filepaths = await this.ipcRenderer.invoke('open_dialog', title, dpath, filter);
|
|
|
|
|
if (filepaths == undefined) {
|
|
|
|
|
return '';
|
|
|
|
|
} else {
|
|
|
|
|
return filepaths[0];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// ファイルからデータを読み込み
|
|
|
|
|
readFromFile(filepath) {
|
|
|
|
|
let data = '';
|
|
|
|
|
try {
|
|
|
|
|
data = this.fs.readFileSync(filepath, 'utf-8');
|
|
|
|
|
}
|
|
|
|
|
catch (err) {
|
|
|
|
|
console.log(err);
|
|
|
|
|
}
|
|
|
|
|
return data;
|
|
|
|
|
}
|
|
|
|
|
// テキストファイル読み込み: 外部スクリプト動的読み込みに使用
|
|
|
|
|
readTextFile(filepath) {
|
|
|
|
|
return this.readFromFile(filepath);
|
|
|
|
|
}
|
|
|
|
|
// ワークスペースファイル保存の一連の動作のラッパ
|
|
|
|
|
async saveWsFile(data) {
|
|
|
|
|
if (this.saveFilepath === null) {
|
|
|
|
|
let filepath = await this.selectSaveFile('xml');
|
|
|
|
|
if (filepath === undefined) { //キャンセル
|
|
|
|
|
return undefined;
|
|
|
|
|
} else {
|
|
|
|
|
this.setSaveFilepath(filepath);
|
|
|
|
|
} //これも保存が成功したら変更するようにすべきかしら
|
|
|
|
|
} else this.setWsChanged(false);
|
|
|
|
|
return this.writeToFile(this.saveFilepath, data);
|
|
|
|
|
}
|
|
|
|
|
// その他ファイル保存の一連の動作のラッパ
|
|
|
|
|
async saveFile(data, ext) {
|
|
|
|
|
let filepath = await this.selectSaveFile(ext);
|
|
|
|
|
if (filepath === undefined) { //キャンセル
|
|
|
|
|
return undefined;
|
|
|
|
|
}
|
|
|
|
|
return this.writeToFile(filepath, data);
|
|
|
|
|
}
|
|
|
|
|
// ファイル保存ダイアログ
|
|
|
|
|
async selectSaveFile(ext) {
|
|
|
|
|
let title = '保存先を決定してください';
|
|
|
|
|
let filter, filter_name;
|
|
|
|
|
let defName;
|
|
|
|
|
if (ext == 'xml') {
|
|
|
|
|
filter = { name: 'xml file', extensions: ['xml'] };
|
|
|
|
|
defName = this.getUniqueFilepath() + '.xml';
|
|
|
|
|
} else if (ext == 'js' || ext == 'py') {
|
|
|
|
|
if (ext == 'js') filter_name = 'javascript file';
|
|
|
|
|
else filter_name = 'python file'
|
|
|
|
|
filter = { name: filter_name, extensions: [ext] };
|
|
|
|
|
// ワークスペース保存名がある場合、それをベースにファイル名の候補を決める
|
|
|
|
|
if (this.saveFilepath === null) {
|
|
|
|
|
defName = this.getUniqueFilepath() + '.' + ext;
|
|
|
|
|
} else {
|
|
|
|
|
let dirname = this.path.dirname(this.saveFilepath);
|
|
|
|
|
let basename = this.path.basename(this.saveFilepath, '.xml');
|
2022-01-13 11:04:21 +00:00
|
|
|
|
defName = this.path.join(dirname, basename) + '.' + ext;
|
2021-10-01 11:39:50 +00:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
filter = { name: 'text file', extensions: ['txt'] };
|
|
|
|
|
}
|
|
|
|
|
let filename = await this.ipcRenderer.invoke('save_dialog', title, defName, filter);
|
2022-07-26 08:09:53 +00:00
|
|
|
|
if (filename) this.doc_current = this.path.dirname(filename);
|
2021-10-01 11:39:50 +00:00
|
|
|
|
return filename;
|
|
|
|
|
}
|
|
|
|
|
// ファイル書き込み
|
|
|
|
|
writeToFile(filepath, data) {
|
|
|
|
|
try {
|
|
|
|
|
this.fs.writeFileSync(filepath, data);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch (err) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-08 13:30:52 +00:00
|
|
|
|
// GPIO 関連:リロードでGPIOをロックしたままハンドルを失うのを防ぐ
|
|
|
|
|
cleanupGPIO() {
|
2022-03-02 11:25:14 +00:00
|
|
|
|
// this.ugjEmitter.emit('device_stop');//デバイス停止イベント
|
2023-05-13 09:42:06 +00:00
|
|
|
|
require(this.gpio_lib).close_all_handle();
|
2021-10-03 10:04:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-10-01 11:39:50 +00:00
|
|
|
|
// 設定(保存ファイルパスと未保存フラグ)をローカルストレージに保存
|
|
|
|
|
savePrefsToLS() {
|
|
|
|
|
let wc = '0';
|
|
|
|
|
if (this.wsChanged) wc = '1';
|
2022-07-10 13:04:56 +00:00
|
|
|
|
// const ser_port = document.getElementById('dlgPort').value;
|
2021-11-09 04:32:43 +00:00
|
|
|
|
let o = {
|
|
|
|
|
'saveFilepath': this.saveFilepath,
|
|
|
|
|
'wsChanged': wc,
|
|
|
|
|
'mascotFilePath': this.mascotFilePath,
|
2021-11-28 02:42:33 +00:00
|
|
|
|
'doc_current': this.doc_current,
|
2022-07-10 13:04:56 +00:00
|
|
|
|
'i2c_bus': this.i2c_bus,
|
2023-04-11 13:25:50 +00:00
|
|
|
|
'lang': this.lang,
|
2021-11-09 04:32:43 +00:00
|
|
|
|
};
|
2021-10-01 11:39:50 +00:00
|
|
|
|
let s = JSON.stringify(o);
|
2021-11-09 04:32:43 +00:00
|
|
|
|
localStorage.setItem(ugj_const.localStorage_fname, s);
|
2021-10-01 11:39:50 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 設定(保存ファイルパスと未保存フラグ)をローカルストレージからロード
|
|
|
|
|
loadPrefsFromLS() {
|
2021-11-09 04:32:43 +00:00
|
|
|
|
let s = localStorage.getItem(ugj_const.localStorage_fname);
|
2021-10-01 11:39:50 +00:00
|
|
|
|
if (s !== null) {
|
|
|
|
|
let o = JSON.parse(s);
|
|
|
|
|
this.setSaveFilepath(o.saveFilepath);
|
|
|
|
|
if (o.wsChanged == '0') this.setWsChanged(false);
|
|
|
|
|
else this.setWsChanged(true);
|
|
|
|
|
if (o.mascotFilePath) this.setMascotFilePath(o.mascotFilePath);
|
2021-11-09 04:32:43 +00:00
|
|
|
|
if (o.doc_current) this.doc_current = o.doc_current;
|
2022-07-10 13:04:56 +00:00
|
|
|
|
if (o.i2c_bus) {
|
|
|
|
|
this.i2c_bus = o.i2c_bus;
|
|
|
|
|
this.ipcRenderer.send('i2c_check_menu', 'i2c-' + this.i2c_bus);
|
|
|
|
|
}
|
|
|
|
|
if (o.lang) {
|
2023-05-09 00:05:48 +00:00
|
|
|
|
// let l;
|
|
|
|
|
// if (o.lang == 'js' || o.gpio_lib) {
|
|
|
|
|
// l = o.lang + '-' + o.gpio_lib;
|
|
|
|
|
// } else {
|
|
|
|
|
// l = o.lang;
|
|
|
|
|
// }
|
|
|
|
|
this.setLang(o.lang);
|
|
|
|
|
console.log(`lang= ${this.lang}`);
|
|
|
|
|
this.ipcRenderer.send('lang_check_menu', this.lang);
|
2022-07-10 13:04:56 +00:00
|
|
|
|
}
|
2021-10-01 11:39:50 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// マスコット画像パスをプロパティにセット
|
|
|
|
|
setMascotFilePath(fpath) {
|
|
|
|
|
this.mascotFilePath = fpath;
|
|
|
|
|
}
|
|
|
|
|
getMascotFilePath() {
|
|
|
|
|
return this.mascotFilePath;
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-11 14:40:18 +00:00
|
|
|
|
// i2cバス番号変更
|
|
|
|
|
setI2cbusNo(n) {
|
|
|
|
|
this.i2c_bus = n;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-11 13:25:50 +00:00
|
|
|
|
// 言語/GPIOライブラリ変更
|
2022-07-10 13:04:56 +00:00
|
|
|
|
setLang(l) {
|
2023-05-09 00:05:48 +00:00
|
|
|
|
this.lang = l;
|
|
|
|
|
// if (l == 'js-pigpio') {
|
|
|
|
|
// this.lang = 'js';
|
|
|
|
|
// this.gpio_lib = ugj_const.pig;
|
|
|
|
|
// } else if (l == 'js-rgpio') {
|
|
|
|
|
// this.lang = 'js';
|
|
|
|
|
// this.gpio_lib = ugj_const.rg;
|
|
|
|
|
// } else this.lang = 'py';
|
2023-04-11 13:25:50 +00:00
|
|
|
|
|
2022-07-10 13:04:56 +00:00
|
|
|
|
const exp = document.getElementById('dlgExport');
|
2023-04-11 13:25:50 +00:00
|
|
|
|
if (this.lang == 'js') {
|
2022-07-10 13:04:56 +00:00
|
|
|
|
exp.innerText = 'ファイルへ保存';
|
|
|
|
|
exp.title = 'ソースコードをファイルに保存します。';
|
|
|
|
|
} else {
|
|
|
|
|
exp.innerText = 'デプロイ';
|
|
|
|
|
exp.title = 'ソースコードをデバイスに転送します。';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2021-10-01 11:39:50 +00:00
|
|
|
|
|
2022-07-16 13:54:49 +00:00
|
|
|
|
// PyBfm を起動
|
|
|
|
|
launchPyBfm() {
|
2023-01-01 13:05:12 +00:00
|
|
|
|
let script_path = this.path.join(apptool.library_path, 'pybfm.py');
|
2022-07-16 13:54:49 +00:00
|
|
|
|
require('child_process').spawn('python3', [script_path]);
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-01 11:39:50 +00:00
|
|
|
|
// ファイル名にアプリケーションのドキュメントルートまでのパスをつけて返す
|
|
|
|
|
getDocPath(filename) {
|
|
|
|
|
return this.path.join(this.appDocRoot, filename);
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-12 12:59:17 +00:00
|
|
|
|
// Python コードフォーマッタ Black をコール
|
|
|
|
|
pyBeautify = (code) => {
|
|
|
|
|
let formatted = '';
|
|
|
|
|
formatted = require('child_process').spawnSync('python3', ['-m', 'black', '-'], { input: code }).stdout.toString();
|
|
|
|
|
if (!formatted) formatted = code;
|
|
|
|
|
return formatted;
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-18 02:16:52 +00:00
|
|
|
|
// メインプロセス:Node-Canvas 呼び出し:OLED テキスト画像生成
|
|
|
|
|
async textToRGBA(text, font, color, start_x, start_y) {
|
|
|
|
|
return await this.ipcRenderer.invoke('text_to_rgba', text, font, color, start_x, start_y);
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-12 12:59:17 +00:00
|
|
|
|
|
2021-10-01 11:39:50 +00:00
|
|
|
|
}
|
|
|
|
|
// ブラウザ動作用
|
2023-01-01 13:05:12 +00:00
|
|
|
|
class webTool {
|
2021-11-19 13:12:03 +00:00
|
|
|
|
constructor() {
|
|
|
|
|
// GPIOブロックは使えません
|
2023-06-25 12:18:33 +00:00
|
|
|
|
this.gpio_lib = ugj_const.rg;
|
2022-07-10 13:04:56 +00:00
|
|
|
|
this.lang = 'js';
|
2023-01-10 12:46:36 +00:00
|
|
|
|
this.blocks_dir = ugj_const.blocks_dir;
|
2021-11-19 13:12:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-10-01 11:39:50 +00:00
|
|
|
|
// マスコット
|
|
|
|
|
getMascotFilePath() { return `./img/${ugj_const.mascot_defname}`; }
|
|
|
|
|
//ワークスペースのダウンロード
|
|
|
|
|
saveWsFile(xml_text) {
|
|
|
|
|
let blob = new Blob([xml_text], { "type": "text/xml" });
|
|
|
|
|
const downLoadLink = document.createElement("a");
|
|
|
|
|
document.body.appendChild(downLoadLink);
|
|
|
|
|
downLoadLink.download = 'workspace.xml';
|
|
|
|
|
downLoadLink.href = URL.createObjectURL(blob);
|
|
|
|
|
downLoadLink.click();
|
|
|
|
|
downLoadLink.parentElement.removeChild(downLoadLink);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
//ワークスペースのインポート
|
|
|
|
|
loadWsFile() {
|
|
|
|
|
const fileInputEl = document.createElement('input');
|
|
|
|
|
document.body.appendChild(fileInputEl);
|
|
|
|
|
fileInputEl.type = 'file';
|
|
|
|
|
fileInputEl.addEventListener('change', ev => {
|
|
|
|
|
let reader = new FileReader();
|
|
|
|
|
reader.readAsText(ev.target.files[0]);
|
|
|
|
|
reader.addEventListener('load', () => {
|
|
|
|
|
let xml = Blockly.Xml.textToDom(reader.result);
|
|
|
|
|
Blockly.Xml.domToWorkspace(xml, workspace);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
fileInputEl.click();
|
|
|
|
|
fileInputEl.parentElement.removeChild(fileInputEl);
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// index.jsから万一呼ばれても何もしない関数
|
|
|
|
|
openURL() { ; }
|
|
|
|
|
selectMascotFile() { ; }
|
|
|
|
|
setMascotFilePath(fname) { ; }
|
|
|
|
|
saveFile() { ; }
|
|
|
|
|
savePrefsToLS() { ; }
|
|
|
|
|
loadPrefsFromLS() { ; }
|
|
|
|
|
newFile() { ; }
|
|
|
|
|
setWsChanged() { ; }
|
|
|
|
|
killAllChildren() { ; }
|
2021-10-08 13:30:52 +00:00
|
|
|
|
cleanupGPIO() { ; }
|
2023-01-12 12:59:17 +00:00
|
|
|
|
pyBeautify(code) { return code; }
|
2022-03-02 11:25:14 +00:00
|
|
|
|
path = {
|
|
|
|
|
join: function (a = '', b = '', c = '', d = '', e = '') {
|
2023-01-10 12:46:36 +00:00
|
|
|
|
const removeTrailingSlash = path => path.endsWith('/') ? path.substr(0, path.length - 1) : path;
|
|
|
|
|
return removeTrailingSlash(a) +
|
|
|
|
|
(b ? '/' + removeTrailingSlash(b) : '') +
|
|
|
|
|
(c ? '/' + removeTrailingSlash(c) : '') +
|
|
|
|
|
(d ? '/' + removeTrailingSlash(d) : '') +
|
|
|
|
|
(e ? '/' + removeTrailingSlash(e) : '')
|
2022-03-02 11:25:14 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-01-12 12:59:17 +00:00
|
|
|
|
|
2021-10-01 11:39:50 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Electron 動作 / ブラウザ動作自動判別
|
2021-10-01 14:33:13 +00:00
|
|
|
|
// const is_el = (typeof window.ocogeapi !== 'undefined')
|
2023-01-01 13:05:12 +00:00
|
|
|
|
const is_app = (typeof require === 'function');
|
2021-10-01 11:39:50 +00:00
|
|
|
|
|
|
|
|
|
// utilクラスのインスタンスを返す
|
2023-01-01 13:05:12 +00:00
|
|
|
|
const appTool_new = () => {
|
|
|
|
|
if (is_app) {
|
|
|
|
|
let ap = new appTool;
|
|
|
|
|
ap.init();
|
|
|
|
|
return ap;
|
2022-01-23 06:46:42 +00:00
|
|
|
|
}
|
2023-01-01 13:05:12 +00:00
|
|
|
|
else return new webTool;
|
2021-10-01 11:39:50 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-10-01 14:33:13 +00:00
|
|
|
|
// "require" for web browsers if contextIsolation is false && nodeIntegration is true:
|
2023-01-01 13:05:12 +00:00
|
|
|
|
if (!is_app) {
|
2021-10-01 14:33:13 +00:00
|
|
|
|
var require = module_name => {
|
2021-10-01 11:39:50 +00:00
|
|
|
|
let block;
|
|
|
|
|
switch (module_name) {
|
2023-01-01 13:05:12 +00:00
|
|
|
|
case '@tensorflow/tfjs-node':
|
2021-10-03 10:04:38 +00:00
|
|
|
|
block = 'TensorFlow';
|
|
|
|
|
break;
|
2022-03-02 11:25:14 +00:00
|
|
|
|
case '@tensorflow-models/blazeface':
|
|
|
|
|
block = '顔認識';
|
2021-10-03 10:04:38 +00:00
|
|
|
|
break;
|
|
|
|
|
case 'axios':
|
|
|
|
|
block = 'URLを取得';
|
|
|
|
|
break;
|
|
|
|
|
case 'nodemailer':
|
|
|
|
|
block = 'メール送信';
|
|
|
|
|
break;
|
2023-05-13 09:42:06 +00:00
|
|
|
|
case 'pigpio':
|
2021-10-01 11:39:50 +00:00
|
|
|
|
block = 'GPIO';
|
|
|
|
|
break;
|
|
|
|
|
case 'fs':
|
|
|
|
|
block = 'ファイル';
|
|
|
|
|
break;
|
2021-10-31 04:27:59 +00:00
|
|
|
|
case 'path':
|
|
|
|
|
block = 'キャンバス保存';
|
|
|
|
|
break;
|
2021-11-19 13:12:03 +00:00
|
|
|
|
case 'child_process':
|
|
|
|
|
block = '外部プログラム実行';
|
|
|
|
|
break;
|
2021-10-01 11:39:50 +00:00
|
|
|
|
default:
|
|
|
|
|
throw new Error(ugj_const.error_ja_all);
|
|
|
|
|
}
|
|
|
|
|
throw `ブロック「${block}」は、Web体験版ではご利用になれません。\n詳しくは https://ocoge.club/ をご覧ください。`;
|
|
|
|
|
}
|
2023-01-12 12:59:17 +00:00
|
|
|
|
var setscriptlangtopy = () => apptool.lang = 'py';
|
2021-10-01 11:39:50 +00:00
|
|
|
|
}
|