def saveConfig() -> None: try: with open(configFilePath, "w", encoding="UTF-8") as configFile: json.dump(config, configFile, indent="\t") configFile.write("\n") except: logger.exception("Failed to write to the application's config file.")
def file_watcher(db_wrapper, mitm_mapper, ws_server, webhook_worker): # We're on a 60-second timer. refresh_time_sec = 60 filename = 'configs/mappings.json' while not terminate_mad.is_set(): # Wait (x-1) seconds before refresh, min. 1s. time.sleep(max(1, refresh_time_sec - 1)) try: # Only refresh if the file has changed. current_time_sec = time.time() file_modified_time_sec = os.path.getmtime(filename) time_diff_sec = current_time_sec - file_modified_time_sec # File has changed in the last refresh_time_sec seconds. if time_diff_sec < refresh_time_sec: logger.info( 'Change found in {}. Updating device mappings.', filename) (device_mappings, routemanagers, auths) = load_mappings(db_wrapper) mitm_mapper._device_mappings = device_mappings logger.info('Propagating new mappings to all clients.') ws_server.update_settings( routemanagers, device_mappings, auths) if webhook_worker is not None: webhook_worker.update_settings(routemanagers) else: logger.debug('No change found in {}.', filename) except Exception as e: logger.exception( 'Exception occurred while updating device mappings: {}.', e)
def setKey(key: str, value: Any) -> None: cache[key] = value try: with open(cacheFilePath, "w", encoding="UTF-8") as cacheFile: json.dump(cache, cacheFile, separators=(",", ":")) except: logger.exception("Failed to write to the application's cache file.")
def __file_watcher(self): # We're on a 20-second timer. refresh_time_sec = int(self.__args.auto_reload_delay) filename = self.__args.mappings logger.info('Mappings.json reload delay: {} seconds', refresh_time_sec) while not self.__stop_file_watcher_event.is_set(): # Wait (x-1) seconds before refresh, min. 1s. try: time.sleep(max(1, refresh_time_sec - 1)) except KeyboardInterrupt: logger.info("Mappings.json watch got interrupted, stopping") break try: # Only refresh if the file has changed. current_time_sec = time.time() file_modified_time_sec = os.path.getmtime(filename) time_diff_sec = current_time_sec - file_modified_time_sec # File has changed in the last refresh_time_sec seconds. if time_diff_sec < refresh_time_sec: logger.info( 'Change found in {}. Updating device mappings.', filename) self.update() else: logger.debug('No change found in {}.', filename) except KeyboardInterrupt as e: logger.info("Got interrupt signal, stopping watching mappings.json") break except Exception as e: logger.exception( 'Exception occurred while updating device mappings: {}.', e)
def return_adb_devices(self): if not self._useadb: return [] try: return self._client.devices() except Exception as e: logger.exception( 'MADmin: Exception occurred while getting adb clients: {}.', e) return []
async def read(self) -> Optional[Any]: try: dataBytes = await self.pipeReader.read(1024) data = json.loads(dataBytes[8:].decode("utf-8")) logger.debug("[READ] %s", data) return data except: logger.exception( "An unexpected error occured during a RPC read operation") self.connected = False
def write(self, op: int, payload: Any) -> None: try: logger.debug("[WRITE] %s", payload) payload = json.dumps(payload) self.pipeWriter.write( struct.pack("<ii", op, len(payload)) + payload.encode("utf-8")) except: logger.exception( "An unexpected error occured during a RPC write operation") self.connected = False
def check_adb_status(self, adb): if not self._useadb: return None try: if self._client.device(adb) is not None: self._client.device(adb).shell('echo checkadb') return True except RuntimeError as e: logger.exception( 'MADmin: Exception occurred while checking adb status ({}).', str(adb)) return None
def send_shell_command(self, adb, origin, command): try: device = self._client.device(adb) if device is not None: logger.info( 'MADmin: Using ADB shell command ({})', str(origin)) device.shell(command) return True except Exception as e: logger.exception( 'MADmin: Exception occurred while sending shell command ({}): {}.', str(origin), e) return False
def loadCache() -> None: if os.path.isfile(cacheFilePath): try: with open(cacheFilePath, "r", encoding="UTF-8") as cacheFile: cache.update(json.load(cacheFile)) except: os.rename( cacheFilePath, cacheFilePath.replace(".json", f"-{time.time():.0f}.json")) logger.exception( "Failed to parse the application's cache file. A new one will be created." )
def make_screenclick(self, adb, origin, x, y): try: device = self._client.device(adb) if device is not None: device.shell("input tap " + str(x) + " " + str(y)) logger.info('MADMin ADB Click x:{} y:{} ({})', str(x), str(y), str(origin)) time.sleep(1) return True except Exception as e: logger.exception( 'MADmin: Exception occurred while making screenclick ({}): {}.', str(origin), e) return False
def make_screenshot(self, adb, origin): try: device = self._client.device(adb) if device is not None: logger.info('MADmin: Using ADB ({})', str(origin)) result = device.screencap() with open(os.path.join(self._args.temp_path, 'screenshot%s.png' % str(origin)), "wb") as fp: fp.write(result) return True except Exception as e: logger.exception( 'MADmin: Exception occurred while making screenshot ({}): {}.', str(origin), e) return False
def __create_payload(self): logger.debug("Fetching data changed since {}", self.__last_check) # the payload that is about to be sent full_payload = [] try: # raids raids = self.__prepare_raid_data( self.__db_wrapper.get_raids_changed_since(self.__last_check)) full_payload += raids # quests if self.__args.quest_webhook: quest = self.__prepare_quest_data( self.__db_wrapper.quests_from_db( timestamp=self.__last_check)) full_payload += quest # weather if self.__args.weather_webhook: weather = self.__prepare_weather_data( self.__db_wrapper.get_weather_changed_since( self.__last_check)) full_payload += weather # gyms if self.__args.gym_webhook: gyms = self.__prepare_gyms_data( self.__db_wrapper.get_gyms_changed_since( self.__last_check)) full_payload += gyms # stops if self.__args.pokestop_webhook: pokestops = self.__prepare_stops_data( self.__db_wrapper.get_stops_changed_since( self.__last_check)) full_payload += pokestops # mon if self.__args.pokemon_webhook: mon = self.__prepare_mon_data( self.__db_wrapper.get_mon_changed_since(self.__last_check)) full_payload += mon except Exception: logger.exception("Error while creating webhook payload") logger.debug2("Done fetching data + building payload") return full_payload
def make_screenswipe(self, adb, origin, x, y, xe, ye): try: device = self._client.device(adb) if device is not None: device.shell("input swipe " + str(x) + " " + str(y) + " " + str(xe) + " " + str(ye) + " 100") logger.info('MADMin ADB Swipe x:{} y:{} xe:{} ye:{}({})', str( x), str(y), str(xe), str(ye), str(origin)) time.sleep(1) return True except Exception as e: logger.exception( 'MADmin: Exception occurred while making screenswipe ({}): {}.', str(origin), e) return False
def loadConfig() -> None: if os.path.isfile(configFilePath): try: with open(configFilePath, "r", encoding="UTF-8") as configFile: loadedConfig = json.load(configFile) except: os.rename( configFilePath, configFilePath.replace(".json", f"-{time.time():.0f}.json")) logger.exception( "Failed to parse the application's config file. A new one will be created." ) else: merge(loadedConfig, config) saveConfig()
def push_file(self, adb, origin, filename): try: device = self._client.device(adb) if device is not None: device.shell("adb push " + str(filename) + " /sdcard/Download") logger.info('MADMin ADB Push File {} to {})', str(filename), str(origin)) time.sleep(1) return True except Exception as e: logger.exception( 'MADmin: Exception occurred while making screenswipe ({}): {}.', str(origin), e) return False
async def handshake(self) -> None: try: if isUnix: self.pipeReader, self.pipeWriter = await asyncio.open_unix_connection( self.ipcPipe) # type: ignore else: self.pipeReader = asyncio.StreamReader() self.pipeWriter, _ = await self.loop.create_pipe_connection( lambda: asyncio.StreamReaderProtocol(self.pipeReader), self.ipcPipe) # type: ignore self.write(0, {"v": 1, "client_id": discordClientID}) if await self.read(): self.connected = True except: logger.exception( "An unexpected error occured during a RPC handshake operation")
def uploadImage(url: str) -> Optional[str]: try: data: models.imgur.UploadResponse = requests.post( "https://api.imgur.com/3/image", headers={ "Authorization": f"Client-ID {config['display']['posters']['imgurClientID']}" }, files={ "image": requests.get(url).content }).json() if not data["success"]: raise Exception(data["data"]["error"]) return data["data"]["link"] except: logger.exception( "An unexpected error occured while uploading an image")
def email(item_name, item_url="", subject=None, body=None): email_subject = f"*** ITEM ({item_name}) ADDED TO YOUR CART ***" email_body = f"Item ({item_name}) has been added to your cart. Hurry login to buy it now: https://newegg.com\n\n item url: {item_url}" msg = MIMEText(body or email_body) msg["Subject"] = subject or email_subject msg["From"] = email_sender msg["To"] = ", ".join(email_recipients) try: server = smtplib.SMTP_SSL("smtp.gmail.com", 465) server.ehlo server.login(email_sender, email_password) server.sendmail(from_addr=email_sender, to_addrs=email_recipients, msg=msg.as_string()) server.quit() logger.info( f"Successfully sent out email notification for ({item_name})") except Exception as e: logger.exception("something went wrong trying to send an email...") logger.exception(e) print("something went wrong trying to send an email...")
async def add_item_to_cart(self): existing_btn_elem = await self.existing_element( elem_tag="button", elem_attr="textContent", elem_attr_values=["Add to Cart", "Add to cart"], ) text_content = await self.get_element_text_content("h1", "textContent", "product-title") if text_content != self.item_btn_title: logger.exception(f"Item set title ({self.item['name']}) aren't matching with website title ({text_content})!") await play_quiet_alert() return False if existing_btn_elem: elem_title = f"Add {self.item_btn_title} to cart" elem_title = json.dumps(elem_title) # escapes quotes in item titles element = await self.page.querySelector(f'button[title={elem_title}]') if element: await self.page.evaluate(f"(element) => element.click()", element) logger.info(f"Attempting to add item ({self.item["name"]}) to cart") await asyncio.sleep(1) return True return False
def disconnect(self) -> None: if not self.connected: logger.debug( "Attempt to disconnect Discord IPC Pipe while not connected") return logger.info("Disconnecting Discord IPC Pipe") try: self.pipeWriter.close() except: logger.exception( "An unexpected error occured while closing an IPC pipe writer") try: self.loop.run_until_complete(self.pipeReader.read()) except: logger.exception( "An unexpected error occured while closing an IPC pipe reader") try: self.loop.close() except: logger.exception( "An unexpected error occured while closing an asyncio event loop" ) self.connected = False
def start_update(self): # BACKUP ALL THE THINGS! if we need to update if self._version != current_version: target = '%s.%s.bk' % (self._application_args.mappings, self._version) try: shutil.copy(self._application_args.mappings, target) except IOError: logger.exception('Unable to clone configuration. Exiting') sys.exit(1) if self._version < 1: logger.info('Execute Update for Version 1') # Adding quest_reward for PMSF ALT if self.dbwrapper.check_column_exists('trs_quest', 'quest_reward') == 0: alter_query = ( "ALTER TABLE trs_quest " "ADD quest_reward VARCHAR(500) NULL AFTER quest_condition") try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) # Adding quest_task = ingame quest conditions if self.dbwrapper.check_column_exists('trs_quest', 'quest_task') == 0: alter_query = ( "ALTER TABLE trs_quest " "ADD quest_task VARCHAR(150) NULL AFTER quest_reward") try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) # Adding form column if it doesnt exist if self._application_args.db_method == "rm": alter_query = ("ALTER TABLE raid " "ADD form smallint(6) DEFAULT NULL") column_exist = self.dbwrapper.check_column_exists( 'raid', 'form') else: logger.error("Invalid db_method in config. Exiting") sys.exit(1) if column_exist == 0: try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) if self._version < 2: alter_query = ("ALTER TABLE trs_quest " "CHANGE quest_reward " "quest_reward VARCHAR(1000) NULL DEFAULT NULL") try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) if self._version < 7: alter_query = ("ALTER TABLE trs_status " "ADD lastPogoReboot varchar(50) NULL DEFAULT NULL") column_exist = self.dbwrapper.check_column_exists( 'trs_status', 'lastPogoReboot') if column_exist == 0: try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) alter_query = ("ALTER TABLE trs_status " "ADD globalrebootcount int(11) NULL DEFAULT '0'") column_exist = self.dbwrapper.check_column_exists( 'trs_status', 'globalrebootcount') if column_exist == 0: try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) alter_query = ("ALTER TABLE trs_status " "ADD globalrestartcount int(11) NULL DEFAULT '0'") column_exist = self.dbwrapper.check_column_exists( 'trs_status', 'globalrestartcount') if column_exist == 0: try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) alter_query = ("ALTER TABLE trs_status CHANGE lastPogoRestart " "lastPogoRestart VARCHAR(50) NULL DEFAULT NULL") try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) alter_query = ( "ALTER TABLE trs_status " "CHANGE currentPos currentPos VARCHAR(50) NULL DEFAULT NULL, " "CHANGE lastPos lastPos VARCHAR(50) NULL DEFAULT NULL, " "CHANGE routePos routePos INT(11) NULL DEFAULT NULL, " "CHANGE routeMax routeMax INT(11) NULL DEFAULT NULL, " "CHANGE rebootingOption rebootingOption TEXT NULL, " "CHANGE rebootCounter rebootCounter INT(11) NULL DEFAULT NULL, " "CHANGE routemanager routemanager VARCHAR(255) NULL DEFAULT NULL, " "CHANGE lastProtoDateTime lastProtoDateTime VARCHAR(50), " "CHANGE lastPogoRestart lastPogoRestart VARCHAR(50), " "CHANGE init init TEXT NULL, " "CHANGE restartCounter restartCounter TEXT NULL") try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) if self._version < 8: alter_query = ("ALTER TABLE trs_quest " "ADD quest_template VARCHAR(100) NULL DEFAULT NULL " "AFTER quest_reward") column_exist = self.dbwrapper.check_column_exists( 'trs_quest', 'quest_template') if column_exist == 0: try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) if self._version < 9: alter_query = ( "UPDATE trs_quest " "SET quest_condition=REPLACE(quest_condition,'\\\"','\"')," " quest_reward=REPLACE(quest_reward,'\\\"','\"')") try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) if self._version < 10: query = ("CREATE TABLE IF NOT EXISTS trs_s2cells ( " "id bigint(20) unsigned NOT NULL, " "level int(11) NOT NULL, " "center_latitude double NOT NULL, " "center_longitude double NOT NULL, " "updated int(11) NOT NULL, " "PRIMARY KEY (id)) ") try: self.dbwrapper.execute(query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) if self._version < 11: query = ("ALTER TABLE trs_stats_detect_raw " "ADD is_shiny TINYINT(1) NOT NULL DEFAULT '0' " "AFTER count") column_exist = self.dbwrapper.check_column_exists( 'trs_stats_detect_raw', 'is_shiny') if column_exist == 0: try: self.dbwrapper.execute(query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) if self._version < 12: query = ("ALTER TABLE trs_stats_detect_raw " "ADD INDEX typeworker (worker, type_id)") index_exist = self.dbwrapper.check_index_exists( 'trs_stats_detect_raw', 'typeworker') if index_exist >= 1: query = ( "ALTER TABLE trs_stats_detect_raw DROP INDEX typeworker, ADD INDEX typeworker (worker, type_id)" ) try: self.dbwrapper.execute(query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) query = ("ALTER TABLE trs_stats_detect_raw " "ADD INDEX shiny (is_shiny)") index_exist = self.dbwrapper.check_index_exists( 'trs_stats_detect_raw', 'shiny') if index_exist >= 1: query = ( "ALTER TABLE trs_stats_detect_raw DROP INDEX shiny, ADD INDEX shiny (is_shiny)" ) try: self.dbwrapper.execute(query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) if self._version < 13: # Adding current_sleep for worker status if self.dbwrapper.check_column_exists('trs_status', 'currentSleepTime') == 0: query = ("ALTER TABLE trs_status " "ADD currentSleepTime INT(11) NOT NULL DEFAULT 0") try: self.dbwrapper.execute(query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) if self._version < 14: update_order = [ 'monivlist', 'auth', 'devicesettings', 'areas', 'walker', 'devices' ] old_data = {} new_data = {} cache = {} target = '%s.bk' % (self._application_args.mappings, ) try: shutil.copy(self._application_args.mappings, target) except IOError: logger.exception('Unable to clone configuration. Exiting') sys.exit(1) with open(self._application_args.mappings, 'rb') as fh: old_data = json.load(fh) if "migrated" in old_data and old_data["migrated"] is True: with open(self._application_args.mappings, 'w') as outfile: json.dump(old_data, outfile, indent=4, sort_keys=True) else: walkerarea = 'walkerarea' walkerarea_ind = 0 for key in update_order: try: entries = old_data[key] except Exception: entries = [] cache[key] = {} index = 0 new_data[key] = {'index': index, 'entries': {}} if key == 'walker': new_data[walkerarea] = {'index': index, 'entries': {}} for entry in entries: if key == 'monivlist': cache[key][entry['monlist']] = index if key == 'devicesettings': cache[key][entry['devicepool']] = index elif key == 'areas': cache[key][entry['name']] = index try: mon_list = entry['settings']['mon_ids_iv'] if type(mon_list) is list: monlist_ind = new_data['monivlist'][ 'index'] new_data['monivlist']['entries'][index] = { 'monlist': 'Update List', 'mon_ids_iv': mon_list } entry['settings'][ 'mon_ids_iv'] = '/api/monivlist/%s' % ( monlist_ind) new_data['monivlist']['index'] += 1 else: try: name = mon_list uri = '/api/monivlist/%s' % ( cache['monivlist'][name]) entry['settings']['mon_ids_iv'] = uri except Exception: # No name match. Maybe an old record so lets toss it del entry['settings']['mon_ids_iv'] except KeyError: # Monlist is not defined for the area pass except Exception: # No monlist specified pass elif key == 'walker': cache[key][entry['walkername']] = index valid_areas = [] if 'setup' in entry: for ind, area in enumerate(entry['setup']): try: area['walkerarea'] = '/api/area/%s' % ( cache['areas'][area['walkerarea']], ) except KeyError: # The area no longer exists. Remove from the path pass else: new_data[walkerarea]['entries'][ walkerarea_ind] = area valid_areas.append( '/api/walkerarea/%s' % walkerarea_ind) walkerarea_ind += 1 entry['setup'] = valid_areas new_data[walkerarea]['index'] = walkerarea_ind else: entry['setup'] = [] elif key == 'devices': if 'pool' in entry: try: entry['pool'] = '/api/devicesetting/%s' % ( cache['devicesettings'][entry['pool']], ) except Exception: if entry['pool'] is not None: logger.error( 'DeviceSettings {} is not valid', entry['pool']) del entry['pool'] try: entry['walker'] = '/api/walker/%s' % ( cache['walker'][entry['walker']], ) except Exception: # The walker no longer exists. Skip the device continue new_data[key]['entries'][index] = entry index += 1 new_data[key]['index'] = index new_data['migrated'] = True with open(self._application_args.mappings, 'w') as outfile: json.dump(new_data, outfile, indent=4, sort_keys=True) if self._version < 15: with open(self._application_args.mappings, 'rb') as fh: settings = json.load(fh) self.__convert_to_id(settings) with open(self._application_args.mappings, 'w') as outfile: json.dump(settings, outfile, indent=4, sort_keys=True) if self._version < 15: query = ( "CREATE TABLE IF NOT EXISTS `trs_visited` (" "`pokestop_id` varchar(50) NOT NULL collate utf8mb4_unicode_ci," "`origin` varchar(50) NOT NULL collate utf8mb4_unicode_ci," "PRIMARY KEY (`pokestop_id`,`origin`)" ")") try: self.dbwrapper.execute(query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) self.set_version(current_version)
) config["users"].append({ "token": authCheckResponse["authToken"], "servers": [{ "name": serverName }] }) saveConfig() break time.sleep(5) else: logger.info("Authentication failed.") exit() plexAlertListeners = [ PlexAlertListener(user["token"], server) for user in config["users"] for server in user["servers"] ] if sys.stdin: while True: userInput = input() if userInput in ["exit", "quit"]: raise KeyboardInterrupt else: while True: time.sleep(3600) except KeyboardInterrupt: for plexAlertListener in plexAlertListeners: plexAlertListener.disconnect() except: logger.exception("An unexpected error occured")
def start_update(self): if self._version < 1: logger.info('Execute Update for Version 1') # Adding quest_reward for PMSF ALT if not self._schema_updater.check_column_exists( 'trs_quest', 'quest_reward'): alter_query = ( "ALTER TABLE trs_quest " "ADD quest_reward VARCHAR(500) NULL AFTER quest_condition") try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) # Adding quest_task = ingame quest conditions if not self._schema_updater.check_column_exists( 'trs_quest', 'quest_task'): alter_query = ( "ALTER TABLE trs_quest " "ADD quest_task VARCHAR(150) NULL AFTER quest_reward") try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) # Adding form column if it doesnt exist if self._application_args.db_method == "rm": alter_query = ("ALTER TABLE raid " "ADD form smallint(6) DEFAULT NULL") column_exist = self._schema_updater.check_column_exists( 'raid', 'form') else: logger.error("Invalid db_method in config. Exiting") sys.exit(1) if not column_exist: try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) if self._version < 2: alter_query = ("ALTER TABLE trs_quest " "CHANGE quest_reward " "quest_reward VARCHAR(1000) NULL DEFAULT NULL") try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) if self._version < 7: alter_query = ("ALTER TABLE trs_status " "ADD lastPogoReboot varchar(50) NULL DEFAULT NULL") column_exist = self._schema_updater.check_column_exists( 'trs_status', 'lastPogoReboot') if not column_exist: try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) alter_query = ("ALTER TABLE trs_status " "ADD globalrebootcount int(11) NULL DEFAULT '0'") column_exist = self._schema_updater.check_column_exists( 'trs_status', 'globalrebootcount') if not column_exist: try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) alter_query = ("ALTER TABLE trs_status " "ADD globalrestartcount int(11) NULL DEFAULT '0'") column_exist = self._schema_updater.check_column_exists( 'trs_status', 'globalrestartcount') if not column_exist: try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) alter_query = ("ALTER TABLE trs_status CHANGE lastPogoRestart " "lastPogoRestart VARCHAR(50) NULL DEFAULT NULL") try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) alter_query = ( "ALTER TABLE trs_status " "CHANGE currentPos currentPos VARCHAR(50) NULL DEFAULT NULL, " "CHANGE lastPos lastPos VARCHAR(50) NULL DEFAULT NULL, " "CHANGE routePos routePos INT(11) NULL DEFAULT NULL, " "CHANGE routeMax routeMax INT(11) NULL DEFAULT NULL, " "CHANGE rebootingOption rebootingOption TEXT NULL, " "CHANGE rebootCounter rebootCounter INT(11) NULL DEFAULT NULL, " "CHANGE routemanager routemanager VARCHAR(255) NULL DEFAULT NULL, " "CHANGE lastProtoDateTime lastProtoDateTime VARCHAR(50), " "CHANGE lastPogoRestart lastPogoRestart VARCHAR(50), " "CHANGE init init TEXT NULL, " "CHANGE restartCounter restartCounter TEXT NULL") try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) if self._version < 8: alter_query = ("ALTER TABLE trs_quest " "ADD quest_template VARCHAR(100) NULL DEFAULT NULL " "AFTER quest_reward") column_exist = self._schema_updater.check_column_exists( 'trs_quest', 'quest_template') if not column_exist: try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) if self._version < 9: alter_query = ( "UPDATE trs_quest " "SET quest_condition=REPLACE(quest_condition,'\\\"','\"')," " quest_reward=REPLACE(quest_reward,'\\\"','\"')") try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) if self._version < 10: query = ("CREATE TABLE IF NOT EXISTS trs_s2cells ( " "id bigint(20) unsigned NOT NULL, " "level int(11) NOT NULL, " "center_latitude double NOT NULL, " "center_longitude double NOT NULL, " "updated int(11) NOT NULL, " "PRIMARY KEY (id)) ") try: self.dbwrapper.execute(query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) if self._version < 11: query = ("ALTER TABLE trs_stats_detect_raw " "ADD is_shiny TINYINT(1) NOT NULL DEFAULT '0' " "AFTER count") column_exist = self._schema_updater.check_column_exists( 'trs_stats_detect_raw', 'is_shiny') if not column_exist: try: self.dbwrapper.execute(query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) if self._version < 12: if self._schema_updater.check_index_exists('trs_stats_detect_raw', 'typeworker'): query = ("ALTER TABLE trs_stats_detect_raw " "DROP INDEX typeworker, " "ADD INDEX typeworker (worker, type_id)") else: query = ("ALTER TABLE trs_stats_detect_raw " "ADD INDEX typeworker (worker, type_id)") try: self.dbwrapper.execute(query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) if self._schema_updater.check_index_exists('trs_stats_detect_raw', 'shiny'): query = ("ALTER TABLE trs_stats_detect_raw " "DROP INDEX shiny, " "ADD INDEX shiny (is_shiny)") else: query = ("ALTER TABLE trs_stats_detect_raw " "ADD INDEX shiny (is_shiny)") try: self.dbwrapper.execute(query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) if self._version < 13: # Adding current_sleep for worker status if not self._schema_updater.check_column_exists( 'trs_status', 'currentSleepTime'): query = ("ALTER TABLE trs_status " "ADD currentSleepTime INT(11) NOT NULL DEFAULT 0") try: self.dbwrapper.execute(query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) if self._version < 14: update_order = [ 'monivlist', 'auth', 'devicesettings', 'areas', 'walker', 'devices' ] old_data = {} new_data = {} cache = {} try: target = '%s.bk' % (self._application_args.mappings, ) shutil.copy(self._application_args.mappings, target) with open(self._application_args.mappings, 'rb') as fh: old_data = json.load(fh) if ("migrated" in old_data and old_data["migrated"] is True): with open(self._application_args.mappings, 'w') as outfile: json.dump(old_data, outfile, indent=4, sort_keys=True) else: walkerarea = 'walkerarea' walkerarea_ind = 0 for key in update_order: try: entries = old_data[key] except Exception: entries = [] cache[key] = {} index = 0 new_data[key] = {'index': index, 'entries': {}} if key == 'walker': new_data[walkerarea] = { 'index': index, 'entries': {} } for entry in entries: if key == 'monivlist': cache[key][entry['monlist']] = index if key == 'devicesettings': cache[key][entry['devicepool']] = index elif key == 'areas': cache[key][entry['name']] = index try: mon_list = entry['settings']['mon_ids_iv'] if type(mon_list) is list: monlist_ind = new_data['monivlist'][ 'index'] new_data['monivlist']['entries'][ index] = { 'monlist': 'Update List', 'mon_ids_iv': mon_list } entry['settings'][ 'mon_ids_iv'] = '/api/monivlist/%s' % ( monlist_ind) new_data['monivlist']['index'] += 1 else: try: name = mon_list uri = '/api/monivlist/%s' % ( cache['monivlist'][name]) entry['settings'][ 'mon_ids_iv'] = uri except Exception: # No name match. Maybe an old record so lets toss it del entry['settings']['mon_ids_iv'] except KeyError: # Monlist is not defined for the area pass except Exception: # No monlist specified pass elif key == 'walker': cache[key][entry['walkername']] = index valid_areas = [] if 'setup' in entry: for ind, area in enumerate(entry['setup']): try: area[ 'walkerarea'] = '/api/area/%s' % ( cache['areas'][ area['walkerarea']], ) except KeyError: # The area no longer exists. Remove from the path pass else: new_data[walkerarea]['entries'][ walkerarea_ind] = area valid_areas.append( '/api/walkerarea/%s' % walkerarea_ind) walkerarea_ind += 1 entry['setup'] = valid_areas new_data[walkerarea][ 'index'] = walkerarea_ind else: entry['setup'] = [] elif key == 'devices': if 'pool' in entry: try: entry[ 'pool'] = '/api/devicesetting/%s' % ( cache['devicesettings'][ entry['pool']], ) except Exception: if entry['pool'] is not None: logger.error( 'DeviceSettings {} is not valid', entry['pool']) del entry['pool'] try: entry['walker'] = '/api/walker/%s' % ( cache['walker'][entry['walker']], ) except Exception: # The walker no longer exists. Skip the device continue new_data[key]['entries'][index] = entry index += 1 new_data[key]['index'] = index new_data['migrated'] = True with open(self._application_args.mappings, 'w') as outfile: json.dump(new_data, outfile, indent=4, sort_keys=True) except IOError: pass except Exception as err: logger.exception('Unknown issue during migration. Exiting') sys.exit(1) if self._version < 15: try: with open(self._application_args.mappings, 'rb') as fh: settings = json.load(fh) self.__convert_to_id(settings) with open(self._application_args.mappings, 'w') as outfile: json.dump(settings, outfile, indent=4, sort_keys=True) except IOError: pass except Exception as err: logger.exception('Unknown issue during migration. Exiting') sys.exit(1) if self._version < 16: query = ( "CREATE TABLE IF NOT EXISTS `trs_visited` (" "`pokestop_id` varchar(50) NOT NULL collate utf8mb4_unicode_ci," "`origin` varchar(50) NOT NULL collate utf8mb4_unicode_ci," "PRIMARY KEY (`pokestop_id`,`origin`)" ")") try: self.dbwrapper.execute(query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) if self._version < 17: try: # Goodbye mappings.json, it was nice knowing ya! update_order = [ 'monivlist', 'auth', 'devicesettings', 'areas', 'walkerarea', 'walker', 'devices' ] with open(self._application_args.mappings, 'rb') as fh: config_file = json.load(fh) geofences = {} routecalcs = {} conversion_issues = [] # A wonderful decision that I made was to start at ID 0 on the previous conversion which causes an issue # with primary keys in MySQL / MariaDB. Make the required changes to ID's and save the file in-case the # conversion is re-run. We do not want dupe data in the database cache = {} for section in update_order: for elem_id, elem in config_file[section]['entries'].items( ): if section == 'areas': try: if int(elem['settings']['mon_ids_iv']) == 0: elem['settings']['mon_ids_iv'] = cache[ 'monivlist'] except KeyError: pass elif section == 'devices': if int(elem['walker']) == 0: elem['walker'] = cache['walker'] if 'pool' in elem and elem[ 'pool'] is not None and int( elem['pool']) == 0: elem['pool'] = cache['devicesettings'] elif section == 'walkerarea': if int(elem['walkerarea']) == 0: elem['walkerarea'] = cache['areas'] elif section == 'walker': setup = [] for walkerarea_id in elem['setup']: if int(walkerarea_id) != 0: setup.append(walkerarea_id) continue setup.append(cache['walkerarea']) elem['setup'] = setup entry = None try: entry = config_file[section]['entries']["0"] except KeyError: continue cache[section] = str(config_file[section]['index']) config_file[section]['entries'][cache[section]] = entry del config_file[section]['entries']["0"] config_file[section]['index'] += 1 if cache: logger.info('One or more resources with ID 0 found. Converting them off 0 and updating the '\ 'mappings.json file. {}', cache) with open(self._application_args.mappings, 'w') as outfile: json.dump(config_file, outfile, indent=4, sort_keys=True) # For multi-instance we do not want to re-use IDs. If and ID is reused we need to adjust it and all # foreign keys generate_new_ids = {} for section in update_order: dm_section = section if section == 'areas': dm_section = 'area' elif section == 'devices': dm_section = 'device' elif section == 'devicesettings': dm_section = 'devicepool' for elem_id, elem in config_file[section]['entries'].items( ): try: mode = elem['mode'] except: mode = None resource_def = self.data_manager.get_resource_def( dm_section, mode=mode) sql = "SELECT `%s` FROM `%s` WHERE `%s` = %%s AND `instance_id` != %%s" sql_args = (resource_def.primary_key, resource_def.table, resource_def.primary_key) sql_format_args = (elem_id, self.data_manager.instance_id) exists = self.dbwrapper.autofetch_value( sql % sql_args, args=sql_format_args) if not exists: continue logger.info( '{} {} already exists and a new ID will be generated', dm_section, elem_id) if dm_section not in generate_new_ids: generate_new_ids[dm_section] = {} generate_new_ids[dm_section][elem_id] = None # Load the elements into their resources and save to DB for section in update_order: dm_section = section if section == 'areas': dm_section = 'area' elif section == 'devices': dm_section = 'device' elif section == 'devicesettings': dm_section = 'devicepool' for key, elem in copy.deepcopy( config_file[section]['entries']).items(): save_elem = copy.deepcopy(elem) logger.debug('Converting {} {}', section, key) tmp_mode = None if section == 'areas': mode = elem['mode'] tmp_mode = mode del elem['mode'] resource = utils.data_manager.modules.MAPPINGS[ 'area'](self.data_manager, mode=mode) geofence_sections = [ 'geofence_included', 'geofence_excluded' ] for geofence_section in geofence_sections: try: geofence = elem[geofence_section] if type(geofence) is int: continue if geofence and geofence not in geofences: try: geo_id = self.__convert_geofence( geofence) geofences[geofence] = geo_id elem[geofence_section] = geofences[ geofence] except utils.data_manager.dm_exceptions.UpdateIssue as err: conversion_issues.append( (section, elem_id, err.issues)) else: elem[geofence_section] = geofences[ geofence] except KeyError: pass route = '%s.calc' % (elem['routecalc'], ) if type(elem['routecalc']) is str: if route not in routecalcs: route_path = os.path.join( self._application_args.file_path, route) route_resource = self.data_manager.get_resource( 'routecalc') stripped_data = [] try: with open(route_path, 'rb') as fh: for line in fh: stripped = line.strip() if type(stripped) != str: stripped = stripped.decode( 'utf-8') stripped_data.append(stripped) except IOError as err: conversion_issues.append( (section, elem_id, err)) logger.warning( 'Unable to open %s. Using empty route' % (route)) route_resource['routefile'] = stripped_data route_resource.save(force_insert=True) routecalcs[ route] = route_resource.identifier if route in routecalcs: elem['routecalc'] = routecalcs[route] else: resource = utils.data_manager.modules.MAPPINGS[ dm_section](self.data_manager) # Settings made it into some configs where it should not be. lets clear those out now if 'settings' in elem and 'settings' not in resource.configuration: del elem['settings'] # Update any IDs that have been converted. There are no required updates for monivlist, auth, # or devicesettings as they are not dependent on other resources # ['monivlist', 'auth', 'devicesettings', 'areas', 'walkerarea', 'walker', 'devices'] if dm_section == 'area': try: monlist = elem['settings']['mon_ids_iv'] elem['settings'][ 'mon_ids_iv'] = generate_new_ids[ 'monivlist'][monlist] save_elem['settings']['mon_ids_iv'] = str( generate_new_ids['monivlist'][monlist]) logger.info('Updating monivlist from {} to {}', key, elem['settings']['mon_ids_iv']) except KeyError: pass elif dm_section == 'device': try: pool_id = elem['pool'] elem['pool'] = generate_new_ids['devicepool'][ pool_id] save_elem['pool'] = str( generate_new_ids['devicepool'][pool_id]) logger.info( 'Updating device pool from {} to {}', pool_id, elem['pool']) except KeyError: pass try: walker_id = elem['walker'] elem['walker'] = generate_new_ids['walker'][ walker_id] save_elem['walker'] = str( generate_new_ids['walker'][walker_id]) logger.info( 'Updating device walker from {} to {}', walker_id, elem['walker']) except KeyError: pass elif dm_section == 'walker': new_list = [] for walkerarea_id in elem['setup']: try: new_list.append( str(generate_new_ids['walkerarea'] [walkerarea_id])) logger.info( 'Updating walker-walkerarea from {} to {}', walkerarea_id, new_list[-1]) except KeyError: new_list.append(walkerarea_id) elem['setup'] = new_list save_elem['setup'] = new_list elif dm_section == 'walkerarea': try: area_id = elem['walkerarea'] elem['walkerarea'] = generate_new_ids['area'][ area_id] save_elem['walkerarea'] = str( generate_new_ids['area'][area_id]) logger.info( 'Updating walkerarea from {} to {}', area_id, elem['walkerarea']) except KeyError: pass save_new_id = False try: generate_new_ids[dm_section][key] save_new_id = True except: resource.identifier = key resource.update(elem) try: resource.save(force_insert=True, ignore_issues=['unknown']) except utils.data_manager.dm_exceptions.UpdateIssue as err: conversion_issues.append( (section, key, err.issues)) except Exception as err: conversion_issues.append((section, key, err)) else: if save_new_id: generate_new_ids[dm_section][ key] = resource.identifier config_file[section]['entries'][str( resource.identifier)] = save_elem del config_file[section]['entries'][key] if resource.identifier >= int( config_file[section]['index']): config_file[section][ 'index'] = resource.identifier + 1 if conversion_issues: logger.error('The configuration was not partially moved to the database. The following resources '\ 'were not converted.') for (section, identifier, issue) in conversion_issues: logger.error('{} {}: {}', section, identifier, issue) if generate_new_ids: with open(self._application_args.mappings, 'w') as outfile: json.dump(config_file, outfile, indent=4, sort_keys=True) except IOError: pass except Exception as err: logger.exception('Unknown issue during migration. Exiting') sys.exit(1) if self._version < 18: query = ( "ALTER TABLE `trs_status` CHANGE `instance` `instance` VARCHAR(50) CHARACTER " "SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;") try: self.dbwrapper.execute(query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) if self._version < 19: # Non-instanced devices in trs_status will cause the upgrade to fail. Since these entries are prior # to bfbadcd we can remove them sql = "SELECT `origin` FROM `trs_status` WHERE `instance` = ''" bad_devs = self.dbwrapper.autofetch_column(sql) if bad_devs: logger.warning('Found devices that have no instance. These will be removed from the table. '\ '{}', bad_devs) del_data = {'instance': ''} self.dbwrapper.autoexec_delete('trs_status', del_data) sql = "SELECT `DATA_TYPE`\n"\ "FROM `INFORMATION_SCHEMA`.`COLUMNS`\n"\ "WHERE `TABLE_NAME` = 'trs_status' AND `COLUMN_NAME` = 'instance'" res = self.dbwrapper.autofetch_value(sql) if res: instances = { self._application_args.status_name: self.instance_id } # We dont want to mess with collations so just pull in and compare sql = "SELECT `instance`, `origin` FROM `trs_status`" try: devs = self.dbwrapper.autofetch_all(sql) if devs is None: devs = [] except: devs = [] for dev in devs: if dev['instance'] not in instances: tmp_instance = self.dbwrapper.get_instance_id( instance_name=dev['instance']) instances[dev['instance']] = tmp_instance update_data = {'instance_id': instances[dev['instance']]} self.dbwrapper.autoexec_update('trs_status', update_data, where_keyvals=dev) # Drop the old column alter_query = ("ALTER TABLE trs_status " "DROP instance") try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) self.set_version(current_version)
def start_update(self): if self._version < 1: logger.info('Execute Update for Version 1') # Adding quest_reward for PMSF ALT if self.dbwrapper.check_column_exists('trs_quest', 'quest_reward') == 0: alter_query = ( "ALTER TABLE trs_quest " "ADD quest_reward VARCHAR(500) NULL AFTER quest_condition" ) try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) # Adding quest_task = ingame quest conditions if self.dbwrapper.check_column_exists('trs_quest', 'quest_task') == 0: alter_query = ( "ALTER TABLE trs_quest " "ADD quest_task VARCHAR(150) NULL AFTER quest_reward" ) try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) # Adding form column for rm / monocle if not exists if self._application_args.db_method == "rm": alter_query = ( "ALTER TABLE raid " "ADD form smallint(6) DEFAULT NULL" ) column_exist = self.dbwrapper.check_column_exists( 'raid', 'form') elif self._application_args.db_method == "monocle": alter_query = ( "ALTER TABLE raids " "ADD form smallint(6) DEFAULT NULL" ) column_exist = self.dbwrapper.check_column_exists( 'raids', 'form') else: logger.error("Invalid db_method in config. Exiting") sys.exit(1) if column_exist == 0: try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) if self._version < 2: alter_query = ( "ALTER TABLE trs_quest " "CHANGE quest_reward " "quest_reward VARCHAR(1000) NULL DEFAULT NULL" ) try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) if self._version < 3: if self._application_args.db_method == "monocle": # Add Weather Index alter_query = ( "ALTER TABLE weather ADD UNIQUE s2_cell_id (s2_cell_id) USING BTREE" ) try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) # Change Mon Unique Index alter_query = ( "ALTER TABLE sightings DROP INDEX timestamp_encounter_id_unique" ) try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) alter_query = ( "ALTER TABLE sightings DROP INDEX encounter_id;" ) try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) alter_query = ( "CREATE TABLE sightings_temp LIKE sightings;" ) try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) alter_query = ( "ALTER TABLE sightings_temp ADD UNIQUE(encounter_id);" ) try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) alter_query = ( "INSERT IGNORE INTO sightings_temp SELECT * FROM sightings ORDER BY id;" ) try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) alter_query = ( "RENAME TABLE sightings TO backup_sightings, sightings_temp TO sightings;" ) try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) alter_query = ( "DROP TABLE backup_sightings;" ) try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) if self._version < 7: alter_query = ( "ALTER TABLE trs_status " "ADD lastPogoReboot varchar(50) NULL DEFAULT NULL" ) column_exist = self.dbwrapper.check_column_exists( 'trs_status', 'lastPogoReboot') if column_exist == 0: try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) alter_query = ( "ALTER TABLE trs_status " "ADD globalrebootcount int(11) NULL DEFAULT '0'" ) column_exist = self.dbwrapper.check_column_exists( 'trs_status', 'globalrebootcount') if column_exist == 0: try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) alter_query = ( "ALTER TABLE trs_status " "ADD globalrestartcount int(11) NULL DEFAULT '0'" ) column_exist = self.dbwrapper.check_column_exists( 'trs_status', 'globalrestartcount') if column_exist == 0: try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) alter_query = ( "ALTER TABLE trs_status CHANGE lastPogoRestart " "lastPogoRestart VARCHAR(50) NULL DEFAULT NULL" ) try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) if self._application_args.db_method == "monocle": alter_query = ( "alter table sightings add column costume smallint(6) default 0" ) column_exist = self.dbwrapper.check_column_exists( 'sightings', 'costume') if column_exist == 0: try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) alter_query = ( "ALTER TABLE trs_status " "CHANGE currentPos currentPos VARCHAR(50) NULL DEFAULT NULL, " "CHANGE lastPos lastPos VARCHAR(50) NULL DEFAULT NULL, " "CHANGE routePos routePos INT(11) NULL DEFAULT NULL, " "CHANGE routeMax routeMax INT(11) NULL DEFAULT NULL, " "CHANGE rebootingOption rebootingOption TEXT NULL, " "CHANGE rebootCounter rebootCounter INT(11) NULL DEFAULT NULL, " "CHANGE routemanager routemanager VARCHAR(255) NULL DEFAULT NULL, " "CHANGE lastProtoDateTime lastProtoDateTime VARCHAR(50), " "CHANGE lastPogoRestart lastPogoRestart VARCHAR(50), " "CHANGE init init TEXT NULL, " "CHANGE restartCounter restartCounter TEXT NULL" ) try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) if self._version < 8: alter_query = ( "ALTER TABLE trs_quest " "ADD quest_template VARCHAR(100) NULL DEFAULT NULL " "AFTER quest_reward" ) try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) if self._version < 9: alter_query = ( "UPDATE trs_quest " "SET quest_condition=REPLACE(quest_condition,'\\\"','\"')," " quest_reward=REPLACE(quest_reward,'\\\"','\"')" ) try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) if self._version < 10: query = ( "CREATE TABLE IF NOT EXISTS trs_s2cells ( " "id bigint(20) unsigned NOT NULL, " "level int(11) NOT NULL, " "center_latitude double NOT NULL, " "center_longitude double NOT NULL, " "updated int(11) NOT NULL, " "PRIMARY KEY (id)) " ) try: self.dbwrapper.execute(query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) self.set_version(current_version)
def convert_mappings(): try: with open(mapping_file) as f: __raw_json = json.load(f) walker = [] walkersetup = [] if "walker" not in __raw_json: logger.info("Unconverted mapping file found") logger.info("Saving current file") shutil.copy(mapping_file, save_mapping_file) __raw_json['walker'] = [] count = 0 walker = [] exist = {} for dev in __raw_json['devices']: logger.info("Converting device {}", str(dev['origin'])) walkersetup = [] daytime_area = dev.get('daytime_area', False) nightime_area = dev.get('nighttime_area', False) walkername = str(daytime_area) timer_invert = "" if nightime_area: if (dev.get('switch', False)): timer_old = dev.get('switch_interval', "['0:00','23:59']") walkername = walkername + '-' + str(nightime_area) timer_normal = str(timer_old[0]) + '-' + str( timer_old[1]) timer_invert = str(timer_old[1]) + '-' + str( timer_old[0]) del __raw_json['devices'][count]['switch_interval'] del __raw_json['devices'][count]['switch'] if len(timer_invert) > 0: walkersetup.append({ 'walkerarea': daytime_area, "walkertype": "period", "walkervalue": timer_invert }) walkersetup.append({ 'walkerarea': nightime_area, "walkertype": "period", "walkervalue": timer_normal }) else: walkersetup.append({ 'walkerarea': daytime_area, "walkertype": "coords", "walkervalue": "" }) if walkername not in exist: walker.append({ 'walkername': walkername, "setup": walkersetup }) exist[walkername] = True del __raw_json['devices'][count]['daytime_area'] del __raw_json['devices'][count]['nighttime_area'] __raw_json['devices'][count]['walker'] = str(walkername) count += 1 __raw_json['walker'] = walker with open(mapping_file, 'w') as outfile: json.dump(__raw_json, outfile, indent=4, sort_keys=True) logger.info('Finished converting mapping file') except IOError: pass except Exception as err: logger.exception('Unknown issue during migration. Exiting') sys.exit(1)
def start_update(self): if self._version < 1: logger.info('Execute Update for Version 1') # Adding quest_reward for PMSF ALT if self.dbwrapper.check_column_exists('trs_quest', 'quest_reward') == 0: alter_query = ( "ALTER TABLE trs_quest " "ADD quest_reward VARCHAR(500) NULL AFTER quest_condition") try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) # Adding quest_task = ingame quest conditions if self.dbwrapper.check_column_exists('trs_quest', 'quest_task') == 0: alter_query = ( "ALTER TABLE trs_quest " "ADD quest_task VARCHAR(150) NULL AFTER quest_reward") try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) # Adding form column if it doesnt exist if self._application_args.db_method == "rm": alter_query = ("ALTER TABLE raid " "ADD form smallint(6) DEFAULT NULL") column_exist = self.dbwrapper.check_column_exists( 'raid', 'form') else: logger.error("Invalid db_method in config. Exiting") sys.exit(1) if column_exist == 0: try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) if self._version < 2: alter_query = ("ALTER TABLE trs_quest " "CHANGE quest_reward " "quest_reward VARCHAR(1000) NULL DEFAULT NULL") try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) if self._version < 7: alter_query = ("ALTER TABLE trs_status " "ADD lastPogoReboot varchar(50) NULL DEFAULT NULL") column_exist = self.dbwrapper.check_column_exists( 'trs_status', 'lastPogoReboot') if column_exist == 0: try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) alter_query = ("ALTER TABLE trs_status " "ADD globalrebootcount int(11) NULL DEFAULT '0'") column_exist = self.dbwrapper.check_column_exists( 'trs_status', 'globalrebootcount') if column_exist == 0: try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) alter_query = ("ALTER TABLE trs_status " "ADD globalrestartcount int(11) NULL DEFAULT '0'") column_exist = self.dbwrapper.check_column_exists( 'trs_status', 'globalrestartcount') if column_exist == 0: try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) alter_query = ("ALTER TABLE trs_status CHANGE lastPogoRestart " "lastPogoRestart VARCHAR(50) NULL DEFAULT NULL") try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) alter_query = ( "ALTER TABLE trs_status " "CHANGE currentPos currentPos VARCHAR(50) NULL DEFAULT NULL, " "CHANGE lastPos lastPos VARCHAR(50) NULL DEFAULT NULL, " "CHANGE routePos routePos INT(11) NULL DEFAULT NULL, " "CHANGE routeMax routeMax INT(11) NULL DEFAULT NULL, " "CHANGE rebootingOption rebootingOption TEXT NULL, " "CHANGE rebootCounter rebootCounter INT(11) NULL DEFAULT NULL, " "CHANGE routemanager routemanager VARCHAR(255) NULL DEFAULT NULL, " "CHANGE lastProtoDateTime lastProtoDateTime VARCHAR(50), " "CHANGE lastPogoRestart lastPogoRestart VARCHAR(50), " "CHANGE init init TEXT NULL, " "CHANGE restartCounter restartCounter TEXT NULL") try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.info("Unexpected error: {}", e) if self._version < 8: alter_query = ("ALTER TABLE trs_quest " "ADD quest_template VARCHAR(100) NULL DEFAULT NULL " "AFTER quest_reward") column_exist = self.dbwrapper.check_column_exists( 'trs_quest', 'quest_template') if column_exist == 0: try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) if self._version < 9: alter_query = ( "UPDATE trs_quest " "SET quest_condition=REPLACE(quest_condition,'\\\"','\"')," " quest_reward=REPLACE(quest_reward,'\\\"','\"')") try: self.dbwrapper.execute(alter_query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) if self._version < 10: query = ("CREATE TABLE IF NOT EXISTS trs_s2cells ( " "id bigint(20) unsigned NOT NULL, " "level int(11) NOT NULL, " "center_latitude double NOT NULL, " "center_longitude double NOT NULL, " "updated int(11) NOT NULL, " "PRIMARY KEY (id)) ") try: self.dbwrapper.execute(query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) if self._version < 11: query = ("ALTER TABLE trs_stats_detect_raw " "ADD is_shiny TINYINT(1) NOT NULL DEFAULT '0' " "AFTER count") column_exist = self.dbwrapper.check_column_exists( 'trs_stats_detect_raw', 'is_shiny') if column_exist == 0: try: self.dbwrapper.execute(query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) if self._version < 12: query = ("ALTER TABLE trs_stats_detect_raw " "ADD INDEX typeworker (worker, type_id)") index_exist = self.dbwrapper.check_index_exists( 'trs_stats_detect_raw', 'typeworker') if index_exist >= 1: query = ( "ALTER TABLE trs_stats_detect_raw DROP INDEX typeworker, ADD INDEX typeworker (worker, type_id)" ) try: self.dbwrapper.execute(query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) query = ("ALTER TABLE trs_stats_detect_raw " "ADD INDEX shiny (is_shiny)") index_exist = self.dbwrapper.check_index_exists( 'trs_stats_detect_raw', 'shiny') if index_exist >= 1: query = ( "ALTER TABLE trs_stats_detect_raw DROP INDEX shiny, ADD INDEX shiny (is_shiny)" ) try: self.dbwrapper.execute(query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) if self._version < 13: # Adding current_sleep for worker status if self.dbwrapper.check_column_exists('trs_status', 'currentSleepTime') == 0: query = ("ALTER TABLE trs_status " "ADD currentSleepTime INT(11) NOT NULL DEFAULT 0") try: self.dbwrapper.execute(query, commit=True) except Exception as e: logger.exception("Unexpected error: {}", e) self.set_version(current_version)
def handle_error(self, error): self.is_dirty_workspace = True logger.exception('GitCurator')