diff --git a/.gitignore b/.gitignore index ec4825f..157495e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ data/apps/*.apk release/ data/*.log logger.lock -logger.lock +null.log +.gitignore diff --git a/app.js b/app.js index 0ddd93d..8fa6c87 100644 --- a/app.js +++ b/app.js @@ -1,3 +1,3 @@ const pages = require('./pages/pages') -pages.mainMenu(); +pages.connectWatch(); diff --git a/buildRelease.sh b/buildRelease.sh index 5673352..820abd6 100644 --- a/buildRelease.sh +++ b/buildRelease.sh @@ -1,22 +1,22 @@ echo What is build number && \ read buildNum && \ pkg package.json && \ -mv miwatchkleaner2-* ./release && \ -mv ./release/miwatchkleaner2-win-* ./release/Windows && \ -mv ./release/miwatchkleaner2-linux-* ./release/Linux && \ -mv ./release/miwatchkleaner2-macos-* ./release/MacOs && \ +mv miwatchkleaner-* ./release && \ +mv ./release/miwatchkleaner-win-* ./release/Windows && \ +mv ./release/miwatchkleaner-linux-* ./release/Linux && \ +mv ./release/miwatchkleaner-macos-* ./release/MacOs && \ cp ./data/xiaomiPackageRemovalList.json ./release/Windows/data/ && \ cp ./data/xiaomiPackageRemovalList.json ./release/MacOS/data/ && \ cp ./data/xiaomiPackageRemovalList.json ./release/Linux/data/ && \ chmod 0777 ./release/**/adb && \ -chmod 0777 ./release/**/miwatchkleaner2-* && \ +chmod 0777 ./release/**/miwatchkleaner-* && \ chmod +x ./release/**/adb && \ -chmod +x ./release/**/miwatchkleaner2-* && \ +chmod +x ./release/**/miwatchkleaner-* && \ cd release/MacOS/ && \ -tar -pcvzf miwatchkleaner.$buildNum-macos.tar.gz adb data/ miwatchkleaner2-macos-x64 && \ +tar -pcvzf miwatchkleaner.$buildNum-macos.tar.gz adb data/ my_apk/ miwatchkleaner-macos-x64 && \ cd .. && \ cd Linux/ && \ -tar -pcvzf miwatchkleaner.$buildNum-Linux.tar.gz adb data/ miwatchkleaner2-linux-x64 && \ +tar -pcvzf miwatchkleaner.$buildNum-Linux.tar.gz adb data/ my_apk/ miwatchkleaner-linux-x64 && \ cd .. && \ cd Windows/ && \ -zip -r miwatchkleaner.$buildNum-win.zip adb.exe AdbWinApi.dll AdbWinUsbApi.dll data/ miwatchkleaner2-win-x86.exe \ No newline at end of file +zip -r miwatchkleaner.$buildNum-win.zip adb.exe AdbWinApi.dll AdbWinUsbApi.dll data/ my_apk/ miwatchkleaner-win-x86.exe \ No newline at end of file diff --git a/data/MiWatch.json b/data/MiWatch.json deleted file mode 100644 index beaa1e9..0000000 --- a/data/MiWatch.json +++ /dev/null @@ -1 +0,0 @@ -{"ipAddress":""} \ No newline at end of file diff --git a/lib/common.js b/lib/common.js index 60c79b7..c187484 100644 --- a/lib/common.js +++ b/lib/common.js @@ -4,7 +4,9 @@ const figlet = require('figlet'); const fs = require('fs') var pjson = require('../package.json'); const fetch = require('node-fetch'); +var shell = require('shelljs'); +const globalVariables = require('../lib/globalVars'); module.exports = { header: (page) => { @@ -25,37 +27,43 @@ module.exports = { ) ) console.log(chalk.blue(page)) - module.exports.ipCheck() + module.exports.connectionCheck() console.log(chalk.red('----------')) }, pause: async (time) => { await new Promise(resolve => setTimeout(resolve, time)); }, - ipCheck: async () => { - const miwatchData = JSON.parse(fs.readFileSync('./data/MiWatch.json', 'utf8')); - if (miwatchData.ipAddress === "") { - console.log(chalk.white('MiWatch IP: ') + chalk.red('Not Connected')) - } else { - console.log(chalk.white('MiWatch IP: ' + chalk.green(miwatchData.ipAddress))) + connectionCheck: async () => { + if (globalVariables.localUSB === "X") { + console.log(chalk.white('MiWatch: ') + chalk.green('Connected via USB')) + } + if (globalVariables.miWatchIpaddress != "") { + console.log(chalk.white('MiWatch: ') + chalk.green('Connected via Wifi - ' + chalk.white(globalVariables.miWatchIpaddress))) + } + if (globalVariables.localUSB === "" && globalVariables.miWatchIpaddress === "") { + console.log(chalk.white('MiWatch: ') + chalk.red('Not Connected')) } }, downloadFile: async (url, path) => { const res = await fetch(url); await new Promise((resolve, reject) => { - const fileStream = fs.createWriteStream(path); - res.body.pipe(fileStream); - res.body.on("error", (err) => { - reject(err); - }); - fileStream.on("finish", function() { - resolve(); - }); + const fileStream = fs.createWriteStream(path); + res.body.pipe(fileStream); + res.body.on("error", (err) => { + reject(err); + }); + fileStream.on("finish", function () { + resolve(); + }); }); }, getCompatibleAppsList: async () => { let settings = { method: "Get" }; const response = await fetch("http://kithub.cf/Karl/MiWatchKleaner-APKs/raw/master/compatibleApps.json", settings) - .then(res => res.json()) - return response + .then(res => res.json()) + return response + }, + clearApkFolder: async () => { + await shell.rm('-rf', './data/apps/*.apk'); }, } \ No newline at end of file diff --git a/lib/files.js b/lib/files.js index b3210f6..dd10bd6 100644 --- a/lib/files.js +++ b/lib/files.js @@ -1,5 +1,7 @@ const fs = require('fs'); const path = require('path'); +const tiny = require("@peterpanhihi/tiny"); +const { resolve } = require('path'); module.exports = { getCurrentDirectoryBase: () => { @@ -14,7 +16,7 @@ module.exports = { ipAddress: value } try { - fs.writeFileSync('./data/MiWatch.json', JSON.stringify(data)) + fs.writeFileSync('./data/options.json', JSON.stringify(data)) } catch (err) { console.log(err) } @@ -26,5 +28,16 @@ module.exports = { } catch (err) { console.log(err) } - }, + }, + renameLocalApk: async (apkList) => { + return new Promise(function (resolve, reject) { + for (let e of apkList) { + a = tiny(e) + fs.rename(e, a, function (err) { + if (err) console.log('ERROR: ' + err); + }); + } + resolve(x / y); + }).catch(err => NaN) + } } \ No newline at end of file diff --git a/lib/globalVars.js b/lib/globalVars.js new file mode 100644 index 0000000..5cce1ae --- /dev/null +++ b/lib/globalVars.js @@ -0,0 +1,7 @@ +class globalVariables { + localUSB = ""; + miWatchIpaddress = ""; + usersList=[]; + } + +module.exports = new globalVariables(); \ No newline at end of file diff --git a/lib/inquirer.js b/lib/inquirer.js index 2c54989..8fa8aca 100644 --- a/lib/inquirer.js +++ b/lib/inquirer.js @@ -11,13 +11,14 @@ module.exports = { name: "mainMenu", message: "What do you want to do?", choices: [ - "Connect to MiWatch via Wifi", + // "Connect to MiWatch", "1-Click Karl0ss Klean", "Remove Xiaomi Apps", "Restore Xiaomi Apps", "Install Compatible Apps", - "Remove Installed Apps", "Restore ANY app", + "Batch Install APKs", + "Batch Remove Installed Apps", "Quit" ], filter: function (val) { @@ -26,6 +27,21 @@ module.exports = { }, ]; return inquirer.prompt(questions); }, + connectionType: () => { + const questions = [{ + type: "list", + name: "connection", + message: "How do you want to connect?", + choices: [ + "USB", + "Wifi" + ], + filter: function (val) { + return val.toLowerCase(); + }, + }, ]; + return inquirer.prompt(questions); + }, connectWifi: () => { const questions = [{ type: "input", diff --git a/my_apk/.gitkeep b/my_apk/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/package-lock.json b/package-lock.json index 41f19a9..dcc7e45 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { - "name": "miwatchkleaner2.0", - "version": "2.0.8", + "name": "miwatchkleaner", + "version": "3.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -40,6 +40,11 @@ "fastq": "^1.6.0" } }, + "@peterpanhihi/tiny": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@peterpanhihi/tiny/-/tiny-2.0.0.tgz", + "integrity": "sha512-usAoksj49559JLAsQXmrE5wOV6A055icErp8jpJDCicfojwEVPaSLk5EZ1EXhcgIuqjSNkzCOXu0gSdm3Std+w==" + }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", @@ -249,6 +254,14 @@ "assert-plus": "^1.0.0" } }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", @@ -867,6 +880,11 @@ "minimist": "^1.2.5" } }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, "multistream": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/multistream/-/multistream-2.1.1.tgz", @@ -1082,6 +1100,14 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" }, + "rename": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/rename/-/rename-1.0.4.tgz", + "integrity": "sha1-oPJQePpBleZQ9zBQx8Esz2ifQws=", + "requires": { + "debug": "^2.5.2" + } + }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", diff --git a/package.json b/package.json index 7fdd06e..7d09ed4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "miwatchkleaner2.0", - "version": "2.0.10", + "name": "miwatchkleaner", + "version": "3.0.0", "description": "MiWatch Cleaning Tool", "main": "app.js", "bin": "app.js", @@ -15,6 +15,7 @@ "author": "Karl Hudgell", "license": "ISC", "dependencies": { + "@peterpanhihi/tiny": "^2.0.0", "chalk": "^4.0.0", "clear": "^0.1.0", "clui": "^0.3.6", diff --git a/pages/pages.js b/pages/pages.js index 2208930..9d029e5 100644 --- a/pages/pages.js +++ b/pages/pages.js @@ -3,12 +3,17 @@ const common = require('../lib/common'); const inquirer = require('../lib/inquirer'); const shellExec = require('shell-exec') const files = require('../lib/files') -const fs = require('fs') const getFilesIn = require('get-files-in') -var shell = require('shelljs'); let logger = require('perfect-logger'); +const globalVariables = require('../lib/globalVars'); -let adbRun + +logger.info(process.platform + " detected") +if (process.platform === 'win32' || process.platform === 'win64') { + adbRun = 'adb' +} else { + adbRun = './adb' +} logger.initialize('RunTIme', { logLevelFile: 0, // Log level for file @@ -68,7 +73,7 @@ module.exports = { const compatibleApps = await common.getCompatibleAppsList() const value = await inquirer.compatibleApps(); - await shell.rm('-rf', './data/apps/*.apk'); + await common.clearApkFolder() for (let element of value.removeAppsList) { for (let element2 of compatibleApps) { @@ -162,31 +167,34 @@ module.exports = { logger.info("Restore Apps Complete") module.exports.mainMenu() }, - connectWifi: async () => { - logger.info("Connect Wifi") - const miwatchData = JSON.parse(fs.readFileSync('./data/MiWatch.json', 'utf8')); - common.header('Connect Wifi') - if (miwatchData.ipAddress !== "") { - await shellExec(adbRun + ' kill-server') - console.log('Trying to connect with stored ipAddress') - shellExec(adbRun + ' connect ' + miwatchData.ipAddress).then(async function (result) { - logger.info("Connect Wifi Result " + result.stdout) - if (result.stdout.includes('already connected') || result.stdout.includes('connected to ')) { - console.log(chalk.green('MiWatch Connected')) + connectWatch: async () => { + logger.info("Connect to watch") + common.header('Connect to watch') + const value = await inquirer.connectionType() + if (value.connection === "usb") { + await shellExec(adbRun + ' kill-server').then(async function (result) { + logger.info('Restarting ADB') + logger.info(result.stdout) + }) + await shellExec(adbRun + ' devices').then(async function (result) { + console.log(result.stdout) + if (result.stdout.includes('device', 15)) { + console.log(chalk.green('MiWatch Connected via USB')) await common.pause(3000) - logger.info("Connect Wifi Complete") + logger.info("MiWatch connected") + globalVariables.localUSB = "X" module.exports.mainMenu() } else { console.log(chalk.red('MiWatch not found')) + logger.info("MiWatch not found") await common.pause(2000) - files.writeIpAddress('') console.log(chalk.white('Try Again')) await common.pause(1000) - module.exports.connectWifi() + module.exports.connectWatch() } - }).catch() - } else { - await shellExec(adbRun + ' kill-server') + }) + } + if (value.connection === "wifi") { const value = await inquirer.connectWifi(); await shellExec(adbRun + ' kill-server').then(async function (result) { logger.info('Restarting ADB') @@ -204,8 +212,10 @@ module.exports = { } else { if (result.stdout.includes('failed to authenticate')) { console.log(chalk.redBright('MiWatch not authenticated')) + logger.info('MiWatch not authenticated') } else { - console.log(chalk.red('MiWatch not found')) + console.log(chalk.red(result.stdout)) + logger.info(result.stdout) } await common.pause(2000) console.log(chalk.white('Try Again')) @@ -235,7 +245,7 @@ module.exports = { logger.info("Remove Complete") logger.info("Compatible Apps") - await shell.rm('-rf', './data/apps/*.apk'); + await common.clearApkFolder() const compatibleApps = await common.getCompatibleAppsList() @@ -289,18 +299,39 @@ module.exports = { logger.info("App Restore Complete") module.exports.mainMenu() }, + batchInstallApks: async () => { + logger.info("Batch Install Apks") + common.header('Batch Install Apks') + + let apkList = await getFilesIn('./my_apk/', matchFiletypes = ['apk'], checkSubDirectories = false) + + await files.renameLocalApk(apkList) + + apkList = await getFilesIn('./my_apk/', matchFiletypes = ['apk'], checkSubDirectories = false) + + for (let element of apkList) { + console.log('Installing ' + element) + logger.info('Installing ' + element) + await shellExec(adbRun + ' install -r ' + element).then(async function (result) { + if (result.stderr != '') { + logger.info('Error ' + result.stderr); + console.log(chalk.redBright(result.stderr)); + } + console.log(element + ' - ' + result.stdout); + logger.info(element + ' - ' + result.stdout); + }); + } + console.log(chalk.green('Batch Install Apks Completed')) + logger.info('Batch Install Apks Completed') + await common.pause(2000) + module.exports.mainMenu() + }, mainMenu: async () => { common.header('Main Menu') - if (process.platform === 'win32' || process.platform === 'win64') { - adbRun = 'adb' - } else { - adbRun = './adb' - } - logger.info(process.platform + " detected") const mainMenuSelection = await inquirer.mainMenu(); switch (mainMenuSelection.mainMenu) { - case 'connect to miwatch via wifi': - module.exports.connectWifi() + case 'connect to miwatch': + module.exports.connectWatch() break; case '1-click karl0ss klean': module.exports.oneClick() @@ -314,12 +345,15 @@ module.exports = { case 'install compatible apps': module.exports.compatibleApps() break; - case 'remove installed apps': + case 'batch remove installed apps': module.exports.removeCompatibleApps() break; case 'restore any app': module.exports.restoreAnyApp() break; + case 'batch install apks': + module.exports.batchInstallApks() + break; case 'quit': break; default: