def __init__(self, db_wrapper: DbWrapper, args, mapping_manager: MappingManager, websocket, logger, app, deviceUpdater): self._db: DbWrapper = db_wrapper self._args = args if self._args.madmin_time == "12": self._datetimeformat = '%Y-%m-%d %I:%M:%S %p' else: self._datetimeformat = '%Y-%m-%d %H:%M:%S' self._adb_connect = ADBConnect(self._args) self._device_updater = deviceUpdater self.research_trigger_queue = Queue() self._mapping_manager: MappingManager = mapping_manager self._ws_server = websocket self._ws_connected_phones: list = [] self._logger = logger self._app = app self.add_route() self.trigger_thread = None self.trigger_thread = Thread(name='research_trigger', target=self.research_trigger) self.trigger_thread.daemon = True self.trigger_thread.start()
def __init__(self, db, args, logger, app): self._db = db self._args = args if self._args.madmin_time == "12": self._datetimeformat = '%Y-%m-%d %I:%M:%S %p' else: self._datetimeformat = '%Y-%m-%d %H:%M:%S' self._adb_connect = ADBConnect(self._args) self._ws_connected_phones: list = [] self._logger = logger self._app = app self.add_route()
def __init__(self, db, args, mapping_parser, websocket, logger, app): self._db = db self._args = args if self._args.madmin_time == "12": self._datetimeformat = '%Y-%m-%d %I:%M:%S %p' else: self._datetimeformat = '%Y-%m-%d %H:%M:%S' self._adb_connect = ADBConnect(self._args) self._mapping_parser = mapping_parser self._device_mapping = self._mapping_parser.get_devicemappings() self._ws_server = websocket self._ws_connected_phones: list = [] self._logger = logger self._app = app self.add_route()
def __init__(self, db_wrapper: DbWrapper, args, mapping_manager: MappingManager, websocket, logger, app, deviceUpdater): self._db: DbWrapper = db_wrapper self._args = args if self._args.madmin_time == "12": self._datetimeformat = '%Y-%m-%d %I:%M:%S %p' else: self._datetimeformat = '%Y-%m-%d %H:%M:%S' self._adb_connect = ADBConnect(self._args) self._device_updater = deviceUpdater self._mapping_manager: MappingManager = mapping_manager self._ws_server = websocket self._ws_connected_phones: list = [] self._logger = logger self._app = app self.add_route()
def __init__(self, db, args, logger, app, mapping_manager: MappingManager, data_manager): self._db = db self._args = args if self._args.madmin_time == "12": self._datetimeformat = '%Y-%m-%d %I:%M:%S %p' else: self._datetimeformat = '%Y-%m-%d %H:%M:%S' self._adb_connect = ADBConnect(self._args) self._ws_connected_phones: list = [] self._logger = logger self._data_manager = data_manager self._app = app self._app.config["TEMPLATES_AUTO_RELOAD"] = True cache.init_app(self._app) self._mapping_mananger = mapping_manager self.add_route()
class control(object): def __init__(self, db_wrapper: DbWrapper, args, mapping_manager: MappingManager, websocket, logger, app, deviceUpdater): self._db: DbWrapper = db_wrapper self._args = args if self._args.madmin_time == "12": self._datetimeformat = '%Y-%m-%d %I:%M:%S %p' else: self._datetimeformat = '%Y-%m-%d %H:%M:%S' self._adb_connect = ADBConnect(self._args) self._device_updater = deviceUpdater self._mapping_manager: MappingManager = mapping_manager self._ws_server = websocket self._ws_connected_phones: list = [] self._logger = logger self._app = app self.add_route() def add_route(self): routes = [ ("/devicecontrol", self.get_phonescreens), ("/take_screenshot", self.take_screenshot), ("/click_screenshot", self.click_screenshot), ("/swipe_screenshot", self.swipe_screenshot), ("/quit_pogo", self.quit_pogo), ("/restart_phone", self.restart_phone), ("/clear_game_data", self.clear_game_data), ("/send_gps", self.send_gps), ("/send_text", self.send_text), ("/upload", self.upload), ("/send_command", self.send_command), ("/get_uploaded_files", self.get_uploaded_files), ("/uploaded_files", self.uploaded_files), ("/delete_file", self.delete_file), ("/install_file", self.install_file), ("/get_install_log", self.get_install_log), ("/delete_log_entry", self.delete_log_entry), ("/install_status", self.install_status), ("/install_file_all_devices", self.install_file_all_devices), ("/restart_job", self.restart_job), ("/delete_log", self.delete_log), ("/get_all_workers", self.get_all_workers), ("/job_for_worker", self.job_for_worker), ("/reload_jobs", self.reload_jobs), ] for route, view_func in routes: self._app.route(route, methods=['GET', 'POST'])(view_func) @auth_required @nocache @logger.catch() def get_phonescreens(self): if not os.path.exists(os.path.join(self._args.temp_path, "madmin")): os.makedirs(os.path.join(self._args.temp_path, "madmin")) screens_phone = [] ws_connected_phones = [] if self._ws_server is not None: phones = self._ws_server.get_reg_origins().copy() else: phones = [] devicemappings = self._mapping_manager.get_all_devicemappings() # Sort devices by name. phones = sorted(phones) for phonename in phones: ws_connected_phones.append(phonename) add_text = "" adb_option = False adb = devicemappings.get(phonename, {}).get('adb', False) if adb is not None and self._adb_connect.check_adb_status( adb) is not None: self._ws_connected_phones.append(adb) adb_option = True add_text = '<b>ADB</b>' else: self._ws_connected_phones.append(adb) filename = generate_device_screenshot_path(phonename, devicemappings, self._args) try: screenshot_ending: str = ".jpg" image_resize(filename, os.path.join(self._args.temp_path, "madmin"), width=250) screen = "screenshot/madmin/screenshot_" + str( phonename) + screenshot_ending screens_phone.append( generate_phones(phonename, add_text, adb_option, screen, filename, self._datetimeformat, dummy=False)) except IOError: screen = "static/dummy.png" screens_phone.append( generate_phones(phonename, add_text, adb_option, screen, filename, self._datetimeformat, dummy=True)) try: os.remove(filename) self._logger.info( "Screenshot {} was corrupted and has been deleted", filename) except: pass for phonename in self._adb_connect.return_adb_devices(): if phonename.serial not in self._ws_connected_phones: devicemappings = self._mapping_manager.get_all_devicemappings() for pho in devicemappings: if phonename.serial == devicemappings[pho].get( 'adb', False): adb_option = True add_text = '<b>ADB - no WS<img src="/static/warning.png" width="20px" ' \ 'alt="NO websocket connection!"></b>' filename = generate_device_screenshot_path( pho, devicemappings, self._args) if os.path.isfile(filename): image_resize(filename, os.path.join(self._args.temp_path, "madmin"), width=250) screenshot_ending: str = ".jpg" screen = "screenshot/madmin/screenshot_" + str( pho) + screenshot_ending screens_phone.append( generate_phones(pho, add_text, adb_option, screen, filename, self._datetimeformat, dummy=False)) else: screen = "static/dummy.png" screens_phone.append( generate_phones(pho, add_text, adb_option, screen, filename, self._datetimeformat, dummy=True)) return render_template('phonescreens.html', editform=screens_phone, header="Device control", title="Device control") @auth_required def take_screenshot(self, origin=None, adb=False): origin = request.args.get('origin') useadb = request.args.get('adb', False) self._logger.info('MADmin: Making screenshot ({})', str(origin)) devicemappings = self._mapping_manager.get_all_devicemappings() adb = devicemappings.get(origin, {}).get('adb', False) filename = generate_device_screenshot_path(origin, devicemappings, self._args) if useadb == 'True' and self._adb_connect.make_screenshot( adb, origin, "jpg"): self._logger.info('MADMin: ADB screenshot successfully ({})', str(origin)) else: self.generate_screenshot(origin) creationdate = datetime.datetime.fromtimestamp( creation_date(filename)).strftime(self._datetimeformat) return creationdate def generate_screenshot(self, origin): devicemappings = self._mapping_manager.get_all_devicemappings() screenshot_type: ScreenshotType = ScreenshotType.JPEG if devicemappings.get(origin, {}).get("screenshot_type", "jpeg") == "png": screenshot_type = ScreenshotType.PNG screenshot_quality: int = devicemappings.get(origin, {}).get( "screenshot_quality", 80) temp_comm = self._ws_server.get_origin_communicator(origin) temp_comm.get_screenshot( generate_device_screenshot_path(origin, devicemappings, self._args), screenshot_quality, screenshot_type) filename = generate_device_screenshot_path(origin, devicemappings, self._args) image_resize(filename, os.path.join(self._args.temp_path, "madmin"), width=250) return @auth_required def click_screenshot(self): origin = request.args.get('origin') click_x = request.args.get('clickx') click_y = request.args.get('clicky') useadb = request.args.get('adb') devicemappings = self._mapping_manager.get_all_devicemappings() filename = generate_device_screenshot_path(origin, devicemappings, self._args) with Image.open(filename) as screenshot: width, height = screenshot.size real_click_x = int(width / float(click_x)) real_click_y = int(height / float(click_y)) adb = devicemappings.get(origin, {}).get('adb', False) if useadb == 'True' and self._adb_connect.make_screenclick( adb, origin, real_click_x, real_click_y): self._logger.info('MADMin: ADB screenclick successfully ({})', str(origin)) else: self._logger.info('MADMin WS Click x:{} y:{} ({})', str(real_click_x), str(real_click_y), str(origin)) temp_comm = self._ws_server.get_origin_communicator(origin) temp_comm.click(int(real_click_x), int(real_click_y)) time.sleep(2) return self.take_screenshot(origin, useadb) @auth_required def swipe_screenshot(self): origin = request.args.get('origin') click_x = request.args.get('clickx') click_y = request.args.get('clicky') click_xe = request.args.get('clickxe') click_ye = request.args.get('clickye') useadb = request.args.get('adb') devicemappings = self._mapping_manager.get_all_devicemappings() filename = generate_device_screenshot_path(origin, devicemappings, self._args) with Image.open(filename) as screenshot: width, height = screenshot.size real_click_x = int(width / float(click_x)) real_click_y = int(height / float(click_y)) real_click_xe = int(width / float(click_xe)) real_click_ye = int(height / float(click_ye)) adb = devicemappings.get(origin, {}).get('adb', False) if useadb == 'True' and self._adb_connect.make_screenswipe( adb, origin, real_click_x, real_click_y, real_click_xe, real_click_ye): self._logger.info('MADMin: ADB screenswipe successfully ({})', str(origin)) else: self._logger.info('MADMin WS Swipe x:{} y:{} xe:{} ye:{} ({})', str(real_click_x), str(real_click_y), str(real_click_xe), str(real_click_ye), str(origin)) temp_comm = self._ws_server.get_origin_communicator(origin) temp_comm.touchandhold(int(real_click_x), int(real_click_y), int(real_click_xe), int(real_click_ye)) time.sleep(2) return self.take_screenshot(origin, useadb) @auth_required def quit_pogo(self): origin = request.args.get('origin') useadb = request.args.get('adb') restart = request.args.get('restart') devicemappings = self._mapping_manager.get_all_devicemappings() adb = devicemappings.get(origin, {}).get('adb', False) self._logger.info('MADmin: Restart Pogo ({})', str(origin)) if useadb == 'True' and \ self._adb_connect.send_shell_command(adb, origin, "am force-stop com.nianticlabs.pokemongo"): self._logger.info( 'MADMin: ADB shell force-stop game command successfully ({})', str(origin)) if restart: time.sleep(1) started = self._adb_connect.send_shell_command( adb, origin, "am start com.nianticlabs.pokemongo") if started: self._logger.info( 'MADMin: ADB shell start game command successfully ({})', str(origin)) else: self._logger.error( 'MADMin: ADB shell start game command failed ({})', str(origin)) else: temp_comm = self._ws_server.get_origin_communicator(origin) if restart: self._logger.info('MADMin: trying to restart game on {}', str(origin)) temp_comm.restartApp("com.nianticlabs.pokemongo") time.sleep(1) else: self._logger.info('MADMin: trying to stop game on {}', str(origin)) temp_comm.stopApp("com.nianticlabs.pokemongo") self._logger.info('MADMin: WS command successfully ({})', str(origin)) time.sleep(2) return self.take_screenshot(origin, useadb) @auth_required def restart_phone(self): origin = request.args.get('origin') useadb = request.args.get('adb') devicemappings = self._mapping_manager.get_all_devicemappings() adb = devicemappings.get(origin, {}).get('adb', False) self._logger.info('MADmin: Restart device ({})', str(origin)) if (useadb == 'True' and self._adb_connect.send_shell_command( adb, origin, "am broadcast -a android.intent.action.BOOT_COMPLETED")): self._logger.info('MADMin: ADB shell command successfully ({})', str(origin)) else: temp_comm = self._ws_server.get_origin_communicator(origin) temp_comm.reboot() self._ws_server.force_disconnect(origin) return redirect(url_for('get_phonescreens'), code=302) @auth_required def clear_game_data(self): origin = request.args.get('origin') useadb = request.args.get('adb') devicemappings = self._mapping_manager.get_all_devicemappings() adb = devicemappings.get(origin, {}).get('adb', False) self._logger.info('MADmin: Clear game data for device ({})', str(origin)) if (useadb == 'True' and self._adb_connect.send_shell_command( adb, origin, "pm clear com.nianticlabs.pokemongo")): self._logger.info('MADMin: ADB shell command successfully ({})', str(origin)) else: temp_comm = self._ws_server.get_origin_communicator(origin) temp_comm.resetAppdata("com.nianticlabs.pokemongo") return redirect(url_for('get_phonescreens'), code=302) @auth_required def send_gps(self): origin = request.args.get('origin') devicemappings = self._mapping_manager.get_all_devicemappings() useadb = request.args.get('adb') if useadb is None: useadb = devicemappings.get(origin, {}).get('adb', False) coords = request.args.get('coords').replace(' ', '').split(',') sleeptime = request.args.get('sleeptime', "0") if len(coords) < 2: return 'Wrong Format!' self._logger.info('MADmin: Set GPS Coords {}, {} - WS Mode only! ({})', str(coords[0]), str(coords[1]), str(origin)) try: temp_comm = self._ws_server.get_origin_communicator(origin) temp_comm.setLocation(coords[0], coords[1], 0) if int(sleeptime) > 0: self._logger.info("MADmin: Set additional sleeptime: {} ({})", str(sleeptime), str(origin)) self._ws_server.set_geofix_sleeptime_worker(origin, sleeptime) except Exception as e: self._logger.exception( 'MADmin: Exception occurred while set gps coords: {}.', e) time.sleep(2) return self.take_screenshot(origin, useadb) @auth_required def send_text(self): origin = request.args.get('origin') useadb = request.args.get('adb') text = request.args.get('text') devicemappings = self._mapping_manager.get_all_devicemappings() adb = devicemappings.get(origin, {}).get('adb', False) if len(text) == 0: return 'Empty text' self._logger.info('MADmin: Send text ({})', str(origin)) if useadb == 'True' and self._adb_connect.send_shell_command( adb, origin, 'input text "' + text + '"'): self._logger.info('MADMin: Send text successfully ({})', str(origin)) else: temp_comm = self._ws_server.get_origin_communicator(origin) temp_comm.sendText(text) time.sleep(2) return self.take_screenshot(origin, useadb) @auth_required def send_command(self): origin = request.args.get('origin') useadb = request.args.get('adb') command = request.args.get('command') devicemappings = self._mapping_manager.get_all_devicemappings() adb = devicemappings.get(origin, {}).get('adb', False) self._logger.info('MADmin: Sending Command ({})', str(origin)) if command == 'home': cmd = "input keyevent 3" elif command == 'back': cmd = "input keyevent 4" if useadb == 'True' and self._adb_connect.send_shell_command( adb, origin, cmd): self._logger.info('MADMin: ADB shell command successfully ({})', str(origin)) else: temp_comm = self._ws_server.get_origin_communicator(origin) if command == 'home': temp_comm.homeButton() elif command == 'back': temp_comm.backButton() time.sleep(2) return self.take_screenshot(origin, useadb) @auth_required @logger.catch def upload(self): if request.method == 'POST': # check if the post request has the file part if 'file' not in request.files: flash('No file part') return redirect(url_for('upload'), code=302) file = request.files['file'] if file.filename == '': flash('No file selected for uploading') return redirect(url_for('upload'), code=302) if file and allowed_file(file.filename): filename = secure_filename(file.filename) file.save(os.path.join(self._args.upload_path, filename)) flash('File uploaded successfully') return redirect(url_for('uploaded_files'), code=302) else: flash('Allowed file type is apk only!') return redirect(url_for('upload'), code=302) return render_template('upload.html', header="File Upload", title="File Upload") @auth_required def get_uploaded_files(self): return jsonify( uploaded_files(self._datetimeformat, self._device_updater.return_commands())) @auth_required def uploaded_files(self): origin = request.args.get('origin', False) useadb = request.args.get('adb', False) return render_template('uploaded_files.html', responsive=str( self._args.madmin_noresponsive).lower(), title="Uploaded Files", origin=origin, adb=useadb) @auth_required def delete_file(self): filename = request.args.get('filename') if os.path.exists(os.path.join(self._args.upload_path, filename)): os.remove(os.path.join(self._args.upload_path, filename)) flash('File deleted successfully') return redirect(url_for('uploaded_files'), code=302) @auth_required @logger.catch def install_file(self): jobname = request.args.get('jobname') origin = request.args.get('origin') useadb = request.args.get('adb', False) type_ = request.args.get('type', None) devicemappings = self._mapping_manager.get_all_devicemappings() adb = devicemappings.get(origin, {}).get('adb', False) if os.path.exists(os.path.join(self._args.upload_path, jobname)): if useadb == 'True': if self._adb_connect.push_file(adb, origin, os.path.join(self._args.upload_path, jobname)) and \ self._adb_connect.send_shell_command( adb, origin, "pm install -r /sdcard/Download/" + str(jobname)): flash('File installed successfully') else: flash('File could not be installed successfully :(') else: self._device_updater.preadd_job(origin=origin, job=jobname, id_=int(time.time()), type=type_) flash('File successfully queued --> See Job Status') elif type_ != jobType.INSTALLATION: self._device_updater.preadd_job(origin=origin, job=jobname, id_=int(time.time()), type=type_) flash('Job successfully queued --> See Job Status') return redirect(url_for('uploaded_files', origin=str(origin), adb=useadb), code=302) @auth_required def reload_jobs(self): logger.info("Reload existing jobs") self._device_updater.init_jobs() return redirect(url_for('uploaded_files'), code=302) @auth_required @logger.catch def get_install_log(self): withautojobs = request.args.get('withautojobs', False) return_log = [] log = self._device_updater.get_log(withautojobs=withautojobs) for entry in log: if 'jobname' not in entry: entry['jobname'] = entry.get('file', 'Unknown Name') return_log.append(entry) return jsonify(return_log) @auth_required @logger.catch() def delete_log_entry(self): id_ = request.args.get('id') if self._device_updater.delete_log_id(id_): flash('Job deleted successfully') else: flash('Job could not be deleted successfully') return redirect(url_for('install_status'), code=302) @auth_required @logger.catch def install_status(self): withautojobs = request.args.get('withautojobs', False) return render_template('installation_status.html', responsive=str( self._args.madmin_noresponsive).lower(), title="Installation Status", withautojobs=withautojobs) @auth_required @logger.catch() def install_file_all_devices(self): jobname = request.args.get('jobname', None) type_ = request.args.get('type', None) if jobname is None or type_ is None: flash('No File or Type selected') return redirect(url_for('install_status'), code=302) devices = self._mapping_manager.get_all_devices() for device in devices: self._device_updater.preadd_job(origin=device, job=jobname, id_=int(time.time()), type=type_) time.sleep(1) flash('Job successfully queued') return redirect(url_for('install_status'), code=302) @auth_required @logger.catch() def restart_job(self): id: int = request.args.get('id', None) if id is not None: self._device_updater.restart_job(id) flash('Job requeued') return redirect(url_for('install_status'), code=302) flash('unknown id - restart failed') return redirect(url_for('install_status'), code=302) @auth_required @logger.catch() def delete_log(self): onlysuccess = request.args.get('only_success', False) self._device_updater.delete_log(onlysuccess=onlysuccess) return redirect(url_for('install_status'), code=302) @auth_required def get_all_workers(self): devices = self._mapping_manager.get_all_devices() devicesreturn = [] for device in devices: devicesreturn.append({'worker': device}) return jsonify(devicesreturn) @auth_required def job_for_worker(self): jobname = request.args.get('jobname', None) type_ = request.args.get('type', None) devices = request.args.getlist('device[]') for device in devices: self._device_updater.preadd_job(origin=device, job=jobname, id_=int(time.time()), type=type_) time.sleep(1) flash('Job successfully queued') return redirect(url_for('install_status'), code=302)
class control(object): def __init__(self, db, args, mapping_parser, websocket, logger, app): self._db = db self._args = args if self._args.madmin_time == "12": self._datetimeformat = '%Y-%m-%d %I:%M:%S %p' else: self._datetimeformat = '%Y-%m-%d %H:%M:%S' self._adb_connect = ADBConnect(self._args) self._mapping_parser = mapping_parser self._device_mapping = self._mapping_parser.get_devicemappings() self._ws_server = websocket self._ws_connected_phones: list = [] self._logger = logger self._app = app self.add_route() def add_route(self): routes = [("/phonecontrol", self.get_phonescreens), ("/take_screenshot", self.take_screenshot), ("/click_screenshot", self.click_screenshot), ("/swipe_screenshot", self.swipe_screenshot), ("/quit_pogo", self.quit_pogo), ("/restart_phone", self.restart_phone), ("/send_gps", self.send_gps), ("/send_text", self.send_text), ("/send_command", self.send_command)] for route, view_func in routes: self._app.route(route)(view_func) @auth_required @nocache def get_phonescreens(self): if not os.path.exists(os.path.join(self._args.temp_path, "madmin")): os.makedirs(os.path.join(self._args.temp_path, "madmin")) screens_phone = [] ws_connected_phones = [] if self._ws_server is not None: phones = self._ws_server.get_reg_origins().copy() else: phones = [] for phonename in phones: ws_connected_phones.append(phonename) add_text = "" adb_option = False adb = self._device_mapping[phonename].get('adb', False) if adb is not None and self._adb_connect.check_adb_status( adb) is not None: self._ws_connected_phones.append(adb) adb_option = True add_text = '<b>ADB</b>' else: self._ws_connected_phones.append(adb) filename = generate_device_screenshot_path(phonename, self._device_mapping, self._args) if os.path.isfile(filename): screenshot_ending: str = ".jpg" image_resize(filename, os.path.join(self._args.temp_path, "madmin"), width=250) screen = "screenshot/madmin/screenshot_" + str( phonename) + screenshot_ending screens_phone.append( generate_phones(phonename, add_text, adb_option, screen, filename, self._datetimeformat, dummy=False)) else: screen = "static/dummy.png" screens_phone.append( generate_phones(phonename, add_text, adb_option, screen, filename, self._datetimeformat, dummy=True)) for phonename in self._adb_connect.return_adb_devices(): if phonename.serial not in self._ws_connected_phones: for pho in self._device_mapping: if phonename.serial == self._device_mapping[pho].get( 'adb', False): adb_option = True add_text = '<b>ADB - no WS<img src="/static/warning.png" width="20px" ' \ 'alt="NO websocket connection!"></b>' filename = generate_device_screenshot_path( pho, self._device_mapping, self._args) if os.path.isfile(filename): image_resize(filename, os.path.join(self._args.temp_path, "madmin"), width=250) screenshot_ending: str = ".jpg" screen = "screenshot/madmin/screenshot_" + str( pho) + screenshot_ending screens_phone.append( generate_phones(pho, add_text, adb_option, screen, filename, self._datetimeformat, dummy=False)) else: screen = "static/dummy.png" screens_phone.append( generate_phones(pho, add_text, adb_option, screen, filename, self._datetimeformat, dummy=True)) return render_template('phonescreens.html', editform=screens_phone, header="Phonecontrol", title="Phonecontrol", running_ocr=(self._args.only_ocr)) @auth_required def take_screenshot(self, origin=None, adb=False): origin = request.args.get('origin') useadb = request.args.get('adb', False) self._logger.info('MADmin: Making screenshot ({})', str(origin)) adb = self._device_mapping[origin].get('adb', False) if useadb == 'True' and self._adb_connect.make_screenshot( adb, origin, "jpg"): self._logger.info('MADMin: ADB screenshot successfully ({})', str(origin)) else: screenshot_type: ScreenshotType = ScreenshotType.JPEG if self._device_mapping[origin].get("screenshot_type", "jpeg") == "png": screenshot_type = ScreenshotType.PNG screenshot_quality: int = self._device_mapping[origin].get( "screenshot_quality", 80) temp_comm = self._ws_server.get_origin_communicator(origin) temp_comm.get_screenshot( generate_device_screenshot_path(origin, self._device_mapping, self._args), screenshot_quality, screenshot_type) filename = generate_device_screenshot_path(origin, self._device_mapping, self._args) image_resize(filename, os.path.join(self._args.temp_path, "madmin"), width=250) creationdate = datetime.datetime.fromtimestamp( creation_date(filename)).strftime(self._datetimeformat) return creationdate @auth_required def click_screenshot(self): origin = request.args.get('origin') click_x = request.args.get('clickx') click_y = request.args.get('clicky') useadb = request.args.get('adb') filename = generate_device_screenshot_path(origin, self._device_mapping, self._args) img = cv2.imread(filename, 0) height, width = img.shape[:2] real_click_x = int(width / float(click_x)) real_click_y = int(height / float(click_y)) adb = self._device_mapping[origin].get('adb', False) if useadb == 'True' and self._adb_connect.make_screenclick( adb, origin, real_click_x, real_click_y): self._logger.info('MADMin: ADB screenclick successfully ({})', str(origin)) else: self._logger.info('MADMin WS Click x:{} y:{} ({})', str(real_click_x), str(real_click_y), str(origin)) temp_comm = self._ws_server.get_origin_communicator(origin) temp_comm.click(int(real_click_x), int(real_click_y)) time.sleep(2) return self.take_screenshot(origin, useadb) @auth_required def swipe_screenshot(self): origin = request.args.get('origin') click_x = request.args.get('clickx') click_y = request.args.get('clicky') click_xe = request.args.get('clickxe') click_ye = request.args.get('clickye') useadb = request.args.get('adb') filename = generate_device_screenshot_path(origin, self._device_mapping, self._args) img = cv2.imread(filename, 0) height, width = img.shape[:2] real_click_x = int(width / float(click_x)) real_click_y = int(height / float(click_y)) real_click_xe = int(width / float(click_xe)) real_click_ye = int(height / float(click_ye)) adb = self._device_mapping[origin].get('adb', False) if useadb == 'True' and self._adb_connect.make_screenswipe( adb, origin, real_click_x, real_click_y, real_click_xe, real_click_ye): self._logger.info('MADMin: ADB screenswipe successfully ({})', str(origin)) else: self._logger.info('MADMin WS Swipe x:{} y:{} xe:{} ye:{} ({})', str(real_click_x), str(real_click_y), str(real_click_xe), str(real_click_ye), str(origin)) temp_comm = self._ws_server.get_origin_communicator(origin) temp_comm.touchandhold(int(real_click_x), int(real_click_y), int(real_click_xe), int(real_click_ye)) time.sleep(2) return self.take_screenshot(origin, useadb) @auth_required def quit_pogo(self): origin = request.args.get('origin') useadb = request.args.get('adb') adb = self._device_mapping[origin].get('adb', False) self._logger.info('MADmin: Restart Pogo ({})', str(origin)) if useadb == 'True' and self._adb_connect.send_shell_command( adb, origin, "am force-stop com.nianticlabs.pokemongo"): self._logger.info('MADMin: ADB shell command successfully ({})', str(origin)) else: temp_comm = self._ws_server.get_origin_communicator(origin) temp_comm.stopApp("com.nianticlabs.pokemongo") self._logger.info('MADMin: WS command successfully ({})', str(origin)) time.sleep(2) return self.take_screenshot(origin, useadb) @auth_required def restart_phone(self): origin = request.args.get('origin') useadb = request.args.get('adb') adb = self._device_mapping[origin].get('adb', False) self._logger.info('MADmin: Restart Phone ({})', str(origin)) if useadb == 'True' and self._adb_connect.send_shell_command( adb, origin, "am broadcast -a android.intent.action.BOOT_COMPLETED"): self._logger.info('MADMin: ADB shell command successfully ({})', str(origin)) else: temp_comm = self._ws_server.get_origin_communicator(origin) temp_comm.reboot() return redirect(getBasePath(request) + '/phonecontrol') @auth_required def send_gps(self): origin = request.args.get('origin') useadb = request.args.get('adb') if useadb is None: useadb = self._device_mapping[origin].get('adb', False) coords = request.args.get('coords').replace(' ', '').split(',') sleeptime = request.args.get('sleeptime', "0") if len(coords) < 2: return 'Wrong Format!' self._logger.info('MADmin: Set GPS Coords {}, {} - WS Mode only! ({})', str(coords[0]), str(coords[1]), str(origin)) try: temp_comm = self._ws_server.get_origin_communicator(origin) temp_comm.setLocation(coords[0], coords[1], 0) if int(sleeptime) > 0: self._logger.info("MADmin: Set additional sleeptime: {} ({})", str(sleeptime), str(origin)) self._ws_server.set_geofix_sleeptime_worker(origin, sleeptime) except Exception as e: self._logger.exception( 'MADmin: Exception occurred while set gps coords: {}.', e) time.sleep(2) return self.take_screenshot(origin, useadb) @auth_required def send_text(self): origin = request.args.get('origin') useadb = request.args.get('adb') text = request.args.get('text') adb = self._device_mapping[origin].get('adb', False) if len(text) == 0: return 'Empty text' self._logger.info('MADmin: Send text ({})', str(origin)) if useadb == 'True' and self._adb_connect.send_shell_command( adb, origin, 'input text "' + text + '"'): self._logger.info('MADMin: Send text successfully ({})', str(origin)) else: temp_comm = self._ws_server.get_origin_communicator(origin) temp_comm.sendText(text) time.sleep(2) return self.take_screenshot(origin, useadb) @auth_required def send_command(self): origin = request.args.get('origin') useadb = request.args.get('adb') command = request.args.get('command') adb = self._device_mapping[origin].get('adb', False) self._logger.info('MADmin: Sending Command ({})', str(origin)) if command == 'home': cmd = "input keyevent 3" elif command == 'back': cmd = "input keyevent 4" if useadb == 'True' and self._adb_connect.send_shell_command( adb, origin, cmd): self._logger.info('MADMin: ADB shell command successfully ({})', str(origin)) else: temp_comm = self._ws_server.get_origin_communicator(origin) if command == 'home': temp_comm.homeButton() elif command == 'back': temp_comm.backButton() time.sleep(2) return self.take_screenshot(origin, useadb)
class config(object): def __init__(self, db, args, logger, app): self._db = db self._args = args if self._args.madmin_time == "12": self._datetimeformat = '%Y-%m-%d %I:%M:%S %p' else: self._datetimeformat = '%Y-%m-%d %H:%M:%S' self._adb_connect = ADBConnect(self._args) self._ws_connected_phones: list = [] self._logger = logger self._app = app self.add_route() def add_route(self): routes = [ ("/addwalker", self.addwalker), ("/savesortwalker", self.savesortwalker), ("/delwalker", self.delwalker), ("/config", self.config), ("/delsetting", self.delsetting), ("/addnew", self.addnew), ("/showmonsidpicker", self.showmonsidpicker), ("/addedit", self.addedit), ("/showsettings", self.showsettings) ] for route, view_func in routes: self._app.route(route, methods=['GET', 'POST'])(view_func) @auth_required def addwalker(self): fieldwebsite = [] walkervalue = "" walkerposition = "" walkermax = "" walkertext = "" edit = request.args.get('edit') walker = request.args.get('walker') add = request.args.get('add') walkernr = request.args.get('walkernr') with open('configs/mappings.json') as f: mapping = json.load(f) if 'walker' not in mapping: mapping['walker'] = [] if add: walkerarea = request.args.get('walkerarea') walkertype = request.args.get('walkertype') walkervalue = request.args.get('walkervalue') walkernr = request.args.get('walkernr') walkermax = request.args.get('walkermax') walkertext = request.args.get('walkertext').replace(' ', '_') walkerposition = request.args.get('walkerposition', False) if not walkerposition: walkerposition = False oldwalkerposition = request.args.get('oldwalkerposition') edit = request.args.get('edit') walkerlist = {'walkerarea': walkerarea, 'walkertype': walkertype, 'walkervalue': walkervalue, 'walkermax': walkermax, 'walkertext': walkertext} if 'setup' not in mapping['walker'][int(walkernr)]: mapping['walker'][int(walkernr)]['setup'] = [] if edit: if int(walkerposition) == int(oldwalkerposition): mapping['walker'][int(walkernr)]['setup'][int( walkerposition)] = walkerlist else: del mapping['walker'][int( walkernr)]['setup'][int(oldwalkerposition)] if walkerposition: mapping['walker'][int(walkernr)]['setup'].insert( int(walkerposition), walkerlist) else: mapping['walker'][int(walkernr)]['setup'].insert( 999, walkerlist) else: if walkerposition: mapping['walker'][int(walkernr)]['setup'].insert( int(walkerposition), walkerlist) else: mapping['walker'][int(walkernr)]['setup'].insert( 999, walkerlist) with open('configs/mappings.json', 'w') as outfile: json.dump(mapping, outfile, indent=4, sort_keys=True) return redirect(getBasePath(request) + "/config?type=walker&area=walker&block=fields&edit=" + str(walker), code=302) if walker and edit: walkerposition = request.args.get('walkerposition') _walkerval = mapping['walker'][int( walkernr)]['setup'][int(walkerposition)] walkerarea = _walkerval['walkerarea'] walkertype = _walkerval['walkertype'] walkervalue = _walkerval['walkervalue'] walkermax = _walkerval.get('walkermax', '') walkertext = _walkerval.get('walkertext', '').replace(' ', '_') if walkermax is None: walkermax = '' edit = True fieldwebsite.append('<form action="addwalker" id="settings">') fieldwebsite.append( '<input type="hidden" name="walker" value="' + walker + '">') fieldwebsite.append('<input type="hidden" name="add" value=True>') if walker and edit: fieldwebsite.append( '<input type="hidden" name="oldwalkerposition" value=' + str(walkerposition) + '>') fieldwebsite.append('<input type="hidden" name="edit" value=True>') fieldwebsite.append( '<input type="hidden" name="walkernr" value=' + str(walkernr) + '>') req = "required" # lockvalue = 'readonly' lockvalue = '' _temp = '<div class="form-group"><label>Area</label><br /><small class="form-text text-muted">Select the Area' \ '</small><select class="form-control" name="walkerarea" ' + \ lockvalue + ' ' + req + '>' with open('configs/mappings.json') as f: mapping = json.load(f) if 'walker' not in mapping: mapping['walker'] = [] mapping['areas'].append({'name': None}) for option in mapping['areas']: sel = '' if edit: if str(walkerarea).lower() == str(option['name']).lower(): sel = 'selected' _temp = _temp + '<option value="' + str(option['name']) + '" ' + sel + '>' + str( option['name']) + '</option>' sel = '' _temp = _temp + '</select></div>' fieldwebsite.append(str(_temp)) req = "required" _temp = '<div class="form-group"><label>Walkermode</label><br /><small class="form-text text-muted">' \ 'Choose the way to end the route:<br>' \ '<b>countdown</b>: Kill worker after X seconds<br>' \ '<b>timer</b>: Kill worker after X:XX o´clock (Format: 24h f.e. 21:30 -> 9:30 pm)<br>' \ '<b>round</b>: Kill worker after X rounds<br>' \ '<b>period</b>: Kill worker if outside the period (Format: 24h f.e. 7:00-21:00)<br>' \ '<b>coords*</b>: Kill worker if no more coords are present<br>' \ '<b>idle*</b>: Idle worker and close Pogo till time or in period (check sleepmode of phone - ' \ 'display must be on in this time!)<br>' \ '<b>*Additionally for coords/idle (walkervalue):</b><br>' \ '- Kill worker after X:XX o´clock (Format: 24h)<br>' \ '- Kill worker if outside of a period (Format: 24h f.e. 7:00-21:00)<br>' \ '</small>' \ '<select class="form-control" name="walkertype" ' + lockvalue + ' ' + req + '>' _options = ('countdown#timer#round#period#coords#idle').split('#') for option in _options: if edit: if str(walkertype).lower() in str(option).lower(): sel = 'selected' _temp = _temp + '<option value="' + \ str(option) + '" ' + sel + '>' + str(option) + '</option>' sel = '' _temp = _temp + '</select></div>' fieldwebsite.append(str(_temp)) fieldwebsite.append('<div class="form-group"><label>Value for Walkermode</label><br />' '<small class="form-text text-muted"></small>' '<input type="text" name="walkervalue" value="' + str( walkervalue) + '" data-rule-validatewalkervalue="true"></div>') fieldwebsite.append('<div class="form-group"><label>Max. Walker in Area</label><br />' '<small class="form-text text-muted">Empty = infinitely</small>' '<input type="text" name="walkermax" value="' + str(walkermax) + '"></div>') fieldwebsite.append('<div class="form-group"><label>Description</label><br />' '<small class="form-text text-muted"></small>' '<input type="text" name="walkertext" value="' + str(walkertext).replace('_', ' ') + '"></div>') fieldwebsite.append('<div class="form-group"><label>Position in Walker</label><br />' '<small class="form-text text-muted">Set position in walker (0=first / empty=append on list)' '</small>' '<input type="text" name="walkerposition" value="' + str(walkerposition) + '"></div>') fieldwebsite.append( '<button type="submit" class="btn btn-primary">Save</button></form>') if edit: header = "Edit " + walkerarea + " (" + walker + ")" else: header = "Add new " + walker return render_template('parser.html', editform=fieldwebsite, header=header, title="edit settings", running_ocr=(self._args.only_ocr)) @auth_required def savesortwalker(self): walkernr = request.args.get('walkernr') data = request.args.getlist('position[]') edit = request.args.get('edit') datavalue = [] with open('configs/mappings.json') as f: mapping = json.load(f) if 'walker' not in mapping: mapping['walker'] = [] for ase in data: _temp = ase.split("|") walkerlist = {'walkerarea': _temp[0], 'walkertype': _temp[1], 'walkervalue': _temp[2], 'walkermax': _temp[3], 'walkertext': _temp[4]} datavalue.append(walkerlist) mapping['walker'][int(walkernr)]['setup'] = datavalue with open('configs/mappings.json', 'w') as outfile: json.dump(mapping, outfile, indent=4, sort_keys=True) return redirect(getBasePath(request) + "/config?type=walker&area=walker&block=fields&edit=" + str(edit), code=302) @auth_required def delwalker(self): walker = request.args.get('walker') walkernr = request.args.get('walkernr') walkerposition = request.args.get('walkerposition') with open('configs/mappings.json') as f: mapping = json.load(f) if 'walker' not in mapping: mapping['walker'] = [] del mapping['walker'][int(walkernr)]['setup'][int(walkerposition)] with open('configs/mappings.json', 'w') as outfile: json.dump(mapping, outfile, indent=4, sort_keys=True) return redirect(getBasePath(request) + "/config?type=walker&area=walker&block=fields&edit=" + str(walker), code=302) @auth_required def config(self): fieldwebsite = [] oldvalues = [] sel = '' _walkernr = 0 edit = False edit = request.args.get('edit') type = request.args.get('type') block = request.args.get('block') area = request.args.get('area') fieldwebsite.append('<form action="addedit" id="settings" method="post">') fieldwebsite.append( '<input type="hidden" name="block" value="' + block + '" />') fieldwebsite.append( '<input type="hidden" name="mode" value="' + type + '" />') fieldwebsite.append( '<input type="hidden" name="area" value="' + area + '" />') if edit: fieldwebsite.append( '<input type="hidden" name="edit" value="' + edit + '" />') with open('configs/mappings.json') as f: mapping = json.load(f) if 'walker' not in mapping: mapping['walker'] = [] if 'devicesettings' not in mapping: mapping['devicesettings'] = [] nr = 0 for oldfields in mapping[area]: if 'name' in oldfields: if oldfields['name'] == edit: oldvalues = oldfields _checkfield = 'name' if 'origin' in oldfields: if oldfields['origin'] == edit: oldvalues = oldfields _checkfield = 'origin' if 'username' in oldfields: if oldfields['username'] == edit: oldvalues = oldfields _checkfield = 'username' if 'devicepool' in oldfields: if oldfields['devicepool'] == edit: oldvalues = oldfields _checkfield = 'devicepool' if 'walkername' in oldfields: if oldfields['walkername'] == edit: oldvalues = oldfields _checkfield = 'walker' _walkernr = nr nr += 1 with open('madmin/static/vars/vars_parser.json') as f: vars = json.load(f) for area in vars[area]: if 'name' in area: if area['name'] == type: _name = area['name'] compfields = area if 'origin' in area: if area['origin'] == type: _name = area['origin'] compfields = area if 'username' in area: if area['username'] == type: _name = area['username'] compfields = area if 'walker' in area: if area['walker'] == type: _name = area['walker'] compfields = area if 'devicesettings' in area: if area['devicesettings'] == type: _name = area['devicesettings'] compfields = area for field in compfields[block]: lock = field['settings'].get("lockonedit", False) showmonsidpicker = field['settings'].get("showmonsidpicker", False) lockvalue = 'readonly' if lock and edit else '' req = 'required' if field['settings'].get( 'require', 'false') == 'true' else '' if field['settings']['type'] == 'text' or field['settings']['type'] == 'textarea': val = '' if edit: if block == 'settings': if field['name'] in oldvalues['settings'] and str(oldvalues['settings'][field['name']]) != str( 'None'): val = str(oldvalues['settings'][field['name']]) else: if field['name'] in oldvalues and str(oldvalues[field['name']]) != str('None'): val = str(oldvalues[field['name']]) formStr = '<div class="form-group">' formStr += '<label>' + str(field['name']) + '</label><br /><small class="form-text text-muted">' + str( field['settings']['description']) + '</small>' # No idea how/where to put that link, ended with this one if showmonsidpicker: monsidpicker_link = '<a href=showmonsidpicker?edit=' + str(edit) + '&type=' + str( type) + '>[BETA ID Picker]</a>' formStr += monsidpicker_link if field['settings']['type'] == 'text': formStr += '<input type="text" name="' + \ str(field['name']) + '" value="' + val + \ '" ' + lockvalue + ' ' + req + '>' if field['settings']['type'] == 'textarea': formStr += '<textarea rows="10" name="' + \ str(field['name']) + '" ' + lockvalue + \ ' ' + req + '>' + val + '</textarea>' formStr += '</div>' fieldwebsite.append(formStr) if field['settings']['type'] == 'list': if edit: val = '' fieldwebsite.append('<div class="form-group"><label>' + str( field['name']) + '</label><br /><small class="form-text text-muted">' + str( field['settings']['description']) + '</small></div>') fieldwebsite.append('<table class="table">') fieldwebsite.append( '<tr><th></th><th>Nr.</th><th>Area<br>Description</th><th>Walkermode</th><th>Setting</th>' '<th>Max. Devices</th><th></th></tr><tbody class="row_position">') if block != 'settings': if field['name'] in oldvalues and str(oldvalues[field['name']]) != str('None'): val = list(oldvalues[field['name']]) i = 0 while i < len(val): fieldwebsite.append('<tr id=' + str(val[i]['walkerarea']) + '|' + str( val[i]['walkertype']) + '|' + str(val[i]['walkervalue']) + '|' + str( val[i].get('walkermax', '')) + '|' + str(val[i].get('walkertext', '')).replace(' ', '_') + '>' '<td ><img src="static/sort.png" class="handle"></td><td>' + str( i) + '</td><td><b>' + str(val[i]['walkerarea']) + '</b><br>' + str( val[i].get('walkertext', '')).replace('_', ' ') + '</td><td>' + str( val[i]['walkertype']) + '</td><td>' + str( val[i]['walkervalue']) + '</td><td>' + str( val[i].get('walkermax', '')) + '</td><td>' '<a href="delwalker?walker=' + str( edit) + '&walkernr=' + str( _walkernr) + '&walkerposition=' + str(i) + '">Delete</a><br>' '<a href="addwalker?walker=' + str( edit) + '&walkernr=' + str(_walkernr) + '&walkerposition=' + str( i) + '&edit=True">Edit</a></form></td></tr>') i += 1 fieldwebsite.append('</tbody></table>') fieldwebsite.append( '<div class="form-group"><a href="addwalker?walker=' + str(edit) + '&walkernr=' + str( _walkernr) + '">Add Area</a></div>') if field['settings']['type'] == 'option': _temp = '<div class="form-group"><label>' + str( field['name']) + '</label><br /><small class="form-text text-muted">' + str( field['settings']['description']) + '</small><select class="form-control" name="' + str( field['name']) + '" ' + lockvalue + ' ' + req + '>' _options = field['settings']['values'].split('|') for option in _options: if edit: if block == 'settings': if field['name'] in oldvalues['settings']: if str(oldvalues['settings'][field['name']]).lower() in str(option).lower(): sel = 'selected' else: if field['name'] in oldvalues: if str(oldvalues[field['name']]).lower() in str(option).lower(): sel = 'selected' _temp = _temp + '<option value="' + \ str(option) + '" ' + sel + '>' + str(option) + '</option>' sel = '' _temp = _temp + '</select></div>' fieldwebsite.append(str(_temp)) if field['settings']['type'] == 'areaselect': _temp = '<div class="form-group"><label>' + str( field['name']) + '</label><br /><small class="form-text text-muted">' + str( field['settings']['description']) + '</small><select class="form-control" name="' + str( field['name']) + '" ' + lockvalue + ' ' + req + '>' with open('configs/mappings.json') as f: mapping = json.load(f) if 'walker' not in mapping: mapping['walker'] = [] mapping['areas'].append({'name': None}) for option in mapping['areas']: if edit: if block == "settings": if str(oldvalues[field['settings']['name']]).lower() == str(option['name']).lower(): sel = 'selected' else: if oldvalues[field['settings']['name']] == '': sel = 'selected' else: if field['name'] in oldvalues: if str(oldvalues[field['name']]).lower() == str(option['name']).lower(): sel = 'selected' else: if not option['name']: sel = 'selected' _temp = _temp + '<option value="' + \ str(option['name']) + '" ' + sel + '>' + \ str(option['name']) + '</option>' sel = '' _temp = _temp + '</select></div>' fieldwebsite.append(str(_temp)) if field['settings']['type'] == 'adbselect': devices = self._adb_connect.return_adb_devices() _temp = '<div class="form-group"><label>' + str( field['name']) + '</label><br /><small class="form-text text-muted">' + str( field['settings']['description']) + '</small><select class="form-control" name="' + str( field['name']) + '" ' + lockvalue + ' ' + req + '>' adb = {} adb['serial'] = [] adb['serial'].append({'name': None}) for device in devices: adb['serial'].append({'name': device.serial}) for option in adb['serial']: if edit: if block == "settings": if str(oldvalues[field['settings']['name']]).lower() == str(option['name']).lower(): sel = 'selected' else: if oldvalues[field['settings']['name']] == '': sel = 'selected' else: if field['name'] in oldvalues: if str(oldvalues[field['name']]).lower() == str(option['name']).lower(): sel = 'selected' else: if not option['name']: sel = 'selected' _temp = _temp + '<option value="' + \ str(option['name']) + '" ' + sel + '>' + \ str(option['name']) + '</option>' sel = '' _temp = _temp + '</select></div>' fieldwebsite.append(str(_temp)) if field['settings']['type'] == 'walkerselect': _temp = '<div class="form-group"><label>' + str( field['name']) + '</label><br /><small class="form-text text-muted">' + str( field['settings']['description']) + '</small><select class="form-control" name="' + str( field['name']) + '" ' + lockvalue + ' ' + req + '>' with open('configs/mappings.json') as f: mapping = json.load(f) if 'walker' not in mapping: mapping['walker'] = [] for option in mapping['walker']: if edit: if field['name'] in oldvalues: if str(oldvalues[field['name']]).lower() == str(option['walkername']).lower(): sel = 'selected' else: if not option['walkername']: sel = 'selected' _temp = _temp + '<option value="' + \ str(option['walkername']) + '" ' + sel + '>' + \ str(option['walkername']) + '</option>' sel = '' _temp = _temp + '</select></div>' fieldwebsite.append(str(_temp)) if field['settings']['type'] == 'poolselect': _temp = '<div class="form-group"><label>' + str( field['name']) + '</label><br /><small class="form-text text-muted">' + str( field['settings']['description']) + '</small><select class="form-control" name="' + str( field['name']) + '" ' + lockvalue + ' ' + req + '>' with open('configs/mappings.json') as f: mapping = json.load(f) if 'devicesettings' not in mapping: mapping['devicesettings'] = [] mapping['devicesettings'].append({'devicepool': None}) for option in mapping['devicesettings']: if edit: if field['name'] in oldvalues: if str(oldvalues[field['name']]).lower() == str(option['devicepool']).lower(): sel = 'selected' else: if not option['devicepool']: sel = 'selected' _temp = _temp + '<option value="' + \ str(option['devicepool']) + '" ' + sel + '>' + \ str(option['devicepool']) + '</option>' sel = '' _temp = _temp + '</select></div>' fieldwebsite.append(str(_temp)) if field['settings']['type'] == 'areaoption': _temp = '<div class="form-group"><label>' + str( field['name']) + '</label><br /><small class="form-text text-muted">' + str( field['settings']['description']) + '</small><select class="form-control" name="' + str( field['name']) + '" ' + lockvalue + ' ' + req + ' size=10 multiple=multiple>' with open('configs/mappings.json') as f: mapping = json.load(f) if 'walker' not in mapping: mapping['walker'] = [] mapping['areas'].append({'name': None}) oldvalues_split = [] if edit: if block == "settings": if oldvalues[field['settings']['name']] is not None: oldvalues_split = oldvalues[field['settings']['name']].replace( " ", "").split(",") else: if oldvalues[field['name']] is not None: oldvalues_split = oldvalues[field['name']].replace( " ", "").split(",") for option in mapping['areas']: if edit: for old_value in oldvalues_split: if block == "settings": if str(old_value).lower() == str(option['name']).lower(): sel = 'selected' else: if old_value == '': sel = 'selected' else: if field['name'] in oldvalues: if str(old_value).lower() == str(option['name']).lower(): sel = 'selected' else: if not option['name']: sel = 'selected' _temp = _temp + '<option value="' + \ str(option['name']) + '" ' + sel + '>' + \ str(option['name']) + '</option>' sel = '' _temp = _temp + '</select></div>' fieldwebsite.append(str(_temp)) if edit: header = "Edit " + edit + " (" + type + ")" else: header = "Add new " + type if (type == 'walker' and edit is None) or (type != 'walker' and edit is not None) \ or (type != 'walker' and edit is None): fieldwebsite.append( '<button type="submit" class="btn btn-primary">Save</button></form>') return render_template('parser.html', editform=fieldwebsite, header=header, title="edit settings", walkernr=_walkernr, edit=edit, running_ocr=(self._args.only_ocr)) @auth_required def delsetting(self): global device_mappings, areas edit = request.args.get('edit') area = request.args.get('area') with open('configs/mappings.json') as f: mapping = json.load(f) if 'walker' not in mapping: mapping['walker'] = [] for key, entry in enumerate(mapping[area]): if 'name' in entry: _checkfield = 'name' if 'origin' in entry: _checkfield = 'origin' if 'username' in entry: _checkfield = 'username' if 'walkername' in entry: _checkfield = 'walkername' if 'devicepool' in entry: _checkfield = 'devicepool' if str(edit) == str(entry[_checkfield]): del mapping[area][key] with open('configs/mappings.json', 'w') as outfile: json.dump(mapping, outfile, indent=4, sort_keys=True) return redirect(getBasePath(request) + "/showsettings", code=302) def check_float(self, number): try: float(number) return True except ValueError: return False @auth_required def addedit(self): data = request.form.to_dict(flat=False) datavalue = {} for ase in data: key = ','.join(data[ase]) datavalue[ase] = key edit = datavalue.get("edit", False) block = datavalue.get("block", False) area = datavalue.get("area", False) mode = datavalue.get("mode", False) with open('configs/mappings.json') as f: mapping = json.load(f) if 'walker' not in mapping: mapping['walker'] = [] if 'devicesettings' not in mapping: mapping['devicesettings'] = [] with open('madmin/static/vars/settings.json') as f: settings = json.load(f) if edit: for entry in mapping[area]: if 'name' in entry: _checkfield = 'name' if 'origin' in entry: _checkfield = 'origin' if 'username' in entry: _checkfield = 'username' if 'walkername' in entry: _checkfield = 'walkername' if 'devicepool' in entry: _checkfield = 'devicepool' if str(edit) == str(entry[_checkfield]): if str(block) == str("settings"): for key, value in datavalue.items(): if value == '' or value == 'None': if key in entry['settings']: del entry['settings'][key] elif value in area: continue else: if str(key) not in ('block', 'area', 'type', 'edit', 'mode'): entry['settings'][key] = self.match_type(value) else: for key, value in datavalue.items(): if value == '': if key in entry: del entry[key] elif value in area: continue else: if str(key) in ('geofence'): entry[key] = value elif str(key) not in ('block', 'area', 'type', 'edit'): entry[key] = self.match_type(value) else: new = {} for key, value in datavalue.items(): if value != '' and value not in area: if str(key) in ('geofence'): new[key] = value elif str(key) not in ('block', 'area', 'type', 'edit'): new[key] = self.match_type(value) if str(block) == str("settings"): mapping[area]['settings'].append(new) else: if settings[area]['has_settings'] == 'true': new['settings'] = {} mapping[area].append(new) with open('configs/mappings.json', 'w') as outfile: json.dump(mapping, outfile, indent=4, sort_keys=True) return redirect(getBasePath(request) + "/showsettings", code=302) def match_type(self, value): if '[' in value and ']' in value: if ':' in value: tempvalue = [] valuearray = value.replace('[', '').replace(']', '').replace( ' ', '').replace("'", '').split(',') for k in valuearray: tempvalue.append(str(k)) value = tempvalue else: value = list(value.replace('[', '').replace(']', '').split(',')) value = [int(i) for i in value] elif value in 'true': value = bool(True) elif value in 'false': value = bool(False) elif value.isdigit(): value = int(value) elif self.check_float(value): value = float(value) elif value == "None": value = None else: value = value.replace(' ', '_') return value @auth_required def showsettings(self): table = '' with open('configs/mappings.json') as f: mapping = json.load(f) if 'walker' not in mapping: mapping['walker'] = [] if 'devicesettings' not in mapping: mapping['devicesettings'] = [] with open('madmin/static/vars/settings.json') as f: settings = json.load(f) with open('madmin/static/vars/vars_parser.json') as f: vars = json.load(f) globalheader = '<thead><tr><th><b>Type</b></th><th>Basedata</th><th>Settings</th><th>Delete</th></tr></thead>' for var in vars: line, quickadd, quickline = '', '', '' header = '<tr><td colspan="4" class="header"><b>' + (var.upper()) + '</b> <a href="addnew?area=' + var + \ '">[Add new]</a></td><td style="display: none;"></td><td style="display: none;"></td><td style="display: none;"></td></tr>' subheader = '<tr><td colspan="4">' + \ settings[var]['description'] + \ '</td><td style="display: none;"></td><td style="display: none;"></td><td style="display: none;"></td></tr>' edit = '<td></td>' editsettings = '<td></td>' _typearea = var _field = settings[var]['field'] _quick = settings[var].get('quickview', False) _quicksett = settings[var].get('quickview_settings', False) for output in mapping[var]: quickadd, quickline = '', '' mode = output.get('mode', _typearea) if settings[var]['could_edit']: edit = '<td><a href="config?type=' + str(mode) + '&area=' + str( _typearea) + '&block=fields&edit=' + str(output[_field]) + '">[Edit]</a></td>' else: edit = '<td></td>' if settings[var]['has_settings'] in ('true'): editsettings = '<td><a href="config?type=' + str(mode) + '&area=' + str( _typearea) + '&block=settings&edit=' + str(output[_field]) + '">[Edit Settings]</a></td>' else: editsettings = '<td></td>' delete = '<td><a href="delsetting?type=' + str(mode) + '&area=' + str( _typearea) + '&block=settings&edit=' + str(output[_field]) + '&del=true">[Delete]</a></td>' line = line + '<tr><td><b>' + \ str(output[_field]) + '</b></td>' + str(edit) + \ str(editsettings) + str(delete) + '</tr>' if _quick == 'setup': quickadd = 'Assigned areas: ' + \ str(len(output.get('setup', []))) + '<br />Areas: ' for area in output.get('setup', []): quickadd = quickadd + area.get('walkerarea') + ' | ' quickline = quickline + '<tr><td></td><td colspan="3" class="quick">' + \ str( quickadd) + ' </td><td style="display: none;"></td><td style="display: none;"></td><td style="display: none;"></td>' elif _quick: for quickfield in _quick.split('|'): if output.get(quickfield, False): quickadd = quickadd + \ str(quickfield) + ': ' + \ str(output.get(quickfield, '')).split( '\n')[0] + '<br>' quickline = quickline + '<tr><td></td><td class="quick">' + \ str(quickadd) + '</td>' quickadd = '' if _quicksett: for quickfield in _quicksett.split('|'): if output['settings'].get(quickfield, False): quickadd = quickadd + \ str(quickfield) + ': ' + \ str(output['settings'].get( quickfield, '')) + '<br>' quickline = quickline + '<td colspan="2" class="quick">' + \ str(quickadd) + '</td><td style="display: none;"></td></tr>' line = line + quickline table = table + header + subheader + line return render_template('settings.html', settings='<table>' + globalheader + '<tbody>' + table + '</tbody></table>', title="Mapping Editor", responsive=str(self._args.madmin_noresponsive).lower(), running_ocr=(self._args.only_ocr)) @auth_required def addnew(self): area = request.args.get('area') line = '' with open('madmin/static/vars/vars_parser.json') as f: settings = json.load(f) if (len(settings[area])) == 1: return redirect(getBasePath(request) + '/config?type=' + area + '&area=' + area + '&block=fields', code=302) for output in settings[area]: line = line + '<h3><a href="config?type=' + str(output['name']) + '&area=' + str( area) + '&block=fields">' + str(output['name']) + '</a></h3><h5>' + str( output['description']) + '</h5><hr>' return render_template('sel_type.html', line=line, title="Type selector", running_ocr=(self._args.only_ocr)) @auth_required def showmonsidpicker(self): edit = request.args.get('edit') type = request.args.get('type') header = "" title = "" if request.method == 'GET' and (not edit or not type): return render_template('showmonsidpicker.html', error_msg="How did you end up here? Missing params.", header=header, title=title) with open('configs/mappings.json') as f: mapping = json.load(f) if "areas" not in mapping: return render_template('showmonsidpicker.html', error_msg="No areas defined at all, please configure first.", header=header, title=title) this_area = None this_area_index = -1 for t_area in mapping["areas"]: this_area_index += 1 if t_area["name"] == edit and t_area["mode"] == type: this_area = t_area break if this_area == None: return render_template('showmonsidpicker.html', error_msg="No area (" + edit + " with mode: " + type + ") found in mappings, add it first.", header=header, title=title) title = "Mons ID Picker for " + edit header = "Editing area " + edit + " (" + type + ")" backurl = "config?type=" + type + "&area=areas&block=settings&edit=" + edit if "settings" not in this_area: return render_template('showmonsidpicker.html', error_msg="No settings key found for area " + edit + "(" + type + "). Configure it first.", header=header, title=title) if request.method == 'POST': new_mons_list = request.form.get('current_mons_list') if not new_mons_list: return redirect("/showsettings", code=302) mapping["areas"][this_area_index]["settings"]["mon_ids_iv"] = ast.literal_eval(new_mons_list) with open('configs/mappings.json', 'w') as outfile: json.dump(mapping, outfile, indent=4, sort_keys=True) return redirect(backurl, code=302) if "mon_ids_iv" not in this_area["settings"]: current_mons = [] else: current_mons = this_area["settings"]["mon_ids_iv"] mondata = open_json_file('pokemon') current_mons_list = [] for mon_id in current_mons: try: mon_name = i8ln(mondata[str(mon_id)]["name"]) except KeyError: mon_name = "No-name-in-file-please-fix" current_mons_list.append({"mon_name": mon_name, "mon_id": str(mon_id)}) # Why o.O stripped_mondata = {} for mon_id in mondata: stripped_mondata[mondata[str(mon_id)]["name"]] = mon_id if os.environ['LANGUAGE'] != "en": try: localized_name = i8ln(mondata[str(mon_id)]["name"]) stripped_mondata[localized_name] = mon_id except KeyError: pass formhiddeninput = '<form action="showmonsidpicker?edit=' + edit + '&type=' + type + '" id="showmonsidpicker" method="post">' formhiddeninput += '<input type="hidden" id="current_mons_list" name="current_mons_list" value="' + str( current_mons) + '">' formhiddeninput += '<button type="submit" class="btn btn-success">Save</button></form>' return render_template('showmonsidpicker.html', backurl=backurl, formhiddeninput=formhiddeninput, current_mons_list=current_mons_list, stripped_mondata=stripped_mondata, header=header, title=title)